데이터 파일 규격
03 만드는 법
이 문서 안에서
저작 문서(오브젝트·맵·캐릭터·요리·패치 노트)의 위치·스키마·런타임 연결을 정합니다. 화면 정의는 UI 선언 시스템, 번역은 다국어 텍스트, 캐릭터 아트는 아트와 LPC 캐릭터, 편집 도구는 개발 도구를 봅니다.
한 줄 요약 — 저작 문서 496개 중 게임이 읽는 것은
objects/monster/138개뿐입니다.
저작 트리의 두 반쪽
탭 폴더 6개는 프로젝트 루트, 나머지는 assets/ 안입니다. 첫 세그먼트가 탭 폴더면 루트, 아니면 assets/(tooling/assets-store.ts).
| 탭 폴더 | 파일 수 | 내용 | 규격 문서 |
|---|---|---|---|
objects/ | 496 (*.) | 스프라이트 오브젝트 정의 | 이 문서 |
data/ | 73 | 최상위 22 · 캐릭터 50 · 요리 1 | 이 문서 |
maps/ | 0 (.) | 타일맵 | 이 문서 |
ui/ | 25 (*.) | 화면 정의 | UI 선언 시스템 |
i18n/ | 6 | ko/en/ja × common/_meta | 다국어 텍스트 |
samples/ | 7 | 한 장짜리 데모 4 · 능력치 실험대 3 | 개발 도구 |
런타임 연결
| 파일 | 개수 | 읽는가 | 코드 |
|---|---|---|---|
objects/ | 138 | 예 | src/ (glob eager) |
data/ | 3건 | 예 | src/ (정적 import) |
data/ | 49 | 예 | src/ (장비 22는 equipment.ts에서 파생) |
data/ | 30 | 예 | src/ |
ui/ | 25 | 예 | 화면별 개별 import |
i18n/ | 3 | 예 | src/ |
objects/ 나머지 | 358 | 아니오 | — |
data/ | 34종 | 아니오 | — |
data/ | 50 | 간접(pnpm lpc:) | — |
objects/ — 스키마
파일명 <id>.obj.json, 타입 ObjectDefinition(src/shared/types/scene.ts).
| 필드 | 타입 | 규칙 |
|---|---|---|
id | string | 비어 있으면 안 됨. 맵 ref 대상 |
name | string | 비어 있으면 안 됨 |
category | string? | 있으면 비어 있으면 안 됨. 자유 텍스트 |
sprite. | string | assets/ 기준 상대 경로 |
sprite./frameHeight | number | 양수 |
defaultScale | number | 양수 |
animations | Record | 이름→{ frames, frameRate, loop } |
states | Record | 이름→{ animation } |
collision. | Vec2 | 양수 {x,y} |
collision. | Vec2? | 유한수 {x,y} |
frames: 0 이상 정수 배열(최소 1), frameRate 양수, loop boolean. 예약 사전 키(__proto__·prototype·constructor + Object.prototype 키)는 금지. 애니메이션 없는 상태는 거부됩니다.
폴더별 구성
| 폴더 | 파일 수 | 시트 | category |
|---|---|---|---|
| 직속 | 2 | castle·cottage | Buildings |
fish/ | 144 | sprites/ | Fish |
foods/ | 75 | sprites/ | Food |
fruit/ | 70 | sprites/ | 7종 |
ingredients/ | 40 | sprites/ | 11종 |
extras/ | 14 | sprites/ | Vegetable 10 등 |
production/ | 13 | production- 등 | 11개는 필드 없음 |
monster/ | 138 | 몬스터별 개별 PNG | 팩 15종 |
소비재 343개는 전부 32×32, idle 1프레임, 충돌 28×28 offset 2×2. 게임플레이 정보 없음(제작, 인벤토리와 판매).
시트의 어느 칸인가
sprite.image는 폴더 전체가 공유하는 아틀라스 한 장을 가리키고, 자기 칸을 말하는 것은 `animations.idle.frames`입니다. 한 줄에 몇 칸인지는 아무 파일에도 적혀 있지 않습니다 — 시트의 폭을 frameWidth로 나눈 값입니다(foods.png 320÷32 = 10칸).
기획서가 이 그림들을 경로로 적지 않는 이유는 읽는 법에 있습니다: 위 칸은 전부 {{<id>#sprite.image|frame=idle}} 한 줄이고, 아틀라스가 다시 구워져 칸이 옮겨 가면 그 파일의 frames 하나만 고치면 문서 열두 곳이 함께 따라옵니다.
production/ 13개는 이 규칙으로 세울 수 없습니다. 11개가 production-buildings.png(512×128)의 0번 칸을 가리키면서 frameWidth만 48·64·80·96으로 다릅니다 — 그래서 열한 개가 전부 시트 왼쪽 위 모서리를 서로 다른 크기로 오려 낸 것이 됩니다. 시트에 건물이 나란히 놓여 있는데 아무 파일도 몇 번째인지 적어 두지 않았습니다:
셋이 다른 건물인데 같은 자리를 가리킵니다. 고칠 것은 이 문서가 아니라 그 열한 파일의 frames입니다.
objects/monster/ — 런타임 필드
읽는 필드: sprite.frameWidth/Height, animations.idle/attack/hurt, defaultScale. 방어 규칙: idle 8장 초과→앞 6장 / frameRate 0→idle 6·attack 10·hurt 10 대체 / 배율 min(0.7, 48/max(fw,fh)) × defaultScale. id 중복 5건(castle·cottage·corn·watermelon·cucumber).
data/ — 세 종류
data/characters/*.json (50개)
키 6개: id, name, description, bodyType(male·female·teen·child·muscular·pregnant), animations, layers(비어 있으면 안 됨). 실재 확인은 pnpm lpc:bake 가 합니다.
data/cooking/recipes.json (34종, 미연결)
Record<id, Recipe>. name(≤80자), produces, amount(양의 정수), ingredients(최소 1), time(초), station(stove 21·furnace 8·null 5). 참조 무결성 OK(누락 0). stove id 오브젝트는 없음.
data/patch-notes.json (게임이 읽음)
{ notes: PatchNote[] }. id(유일), version, date(YYYY-MM-DD), title/summary/body({ko,en,ja} 문자열). 빈 문자열 허용. 현재 3건.
maps/ — 파일 0개, 규격만 존재
파일명 <id>.map.json. 필드: id/name, grid(width/height 양의 정수), tileSize(양수), tileset(image/tileWidth/tileHeight/columns), layers(최소 1, data는 격자 일치), objects, camera(target/zoom), backgroundColor. 기본값: 20×15, 32px, tilesets/terrain.png columns 8, ground(1)+objects(0), 카메라 {10,7.5} zoom 1, #1d2b53.
검증이 도는 지점
| 지점 | 역할 |
|---|---|
| 게임 로드 시 | decodeObjectDefinition |
| 계약 테스트 | 타입별 parse 함수 |
tests/ | 합성 픽스처 22건 |
게임 런타임은 검증기를 쓰지 않습니다. tests/assets-contracts.test.ts는 저작 폴더가 루트로 옮겨진 뒤 사실상 비어 있습니다.
설계안 — 아직 구현되지 않음
오브젝트에 production 블록을 추가해 생산 건물·가공 시설을 데이터로 기술하는 설계(docs/ingredient-content.md). 읽는 코드 없음.
| 단계 | 범위 | 상태 |
|---|---|---|
| P0 | 레시피 카탈로그 + 검증 | 완료 |
| P1–P6 | 인벤토리·제작 UI·생산 건물·채집·상점 | 미기록 |
P1·P2는 이 설계와 다른 축으로 구현됨(인벤토리와 판매, 제작). 작업대 매칭은 오브젝트 id 기준.
이어서 읽기
- UI 선언 시스템 —
ui/*.ui.json문법과 렌더러 - 다국어 텍스트 —
i18n/열쇠 규칙과 3개 언어 계약 - 아트와 LPC 캐릭터 —
data/characters/50개가 시트가 되기까지 - 개발 도구 — 어느 도구가 어느 폴더를 고치는가
- 던전과 몬스터 — 런타임에 닿는 몬스터 138개