소리와 에셋 파이프라인
03 만드는 법
이 문서 안에서
소리·그림 파일의 위치·규격·빌드 경로·재생 규칙을 정합니다. 캐릭터 스프라이트는 아트와 LPC 캐릭터, 오브젝트 스키마는 데이터 파일 규격, 화면 문법은 UI 선언 시스템을 봅니다.
한 줄 요약 — 게임에 실리는 에셋은 glob 으로 집어 온 것과
public/에 놓인 것 둘뿐이고, 나머지는 원본·보관물입니다.
에셋이 사는 두 곳
| 폴더 | 크기 | 내용 | 빌드 |
|---|---|---|---|
assets/ | 9.71 MB | 배경음 2곡 | 예 |
assets/ | 487 KB | 효과음 35개 | 예 |
assets/ | 44.1 MB | 미사용 음원 1,807개 | 아니오 |
assets/ | 2.33 MB | 구워진 LPC 시트 | 예 |
assets/ | 1.08 MB | 몬스터 시트 138장 | 예 |
assets/ | 64.0 MB | 전투 배경 30장 | 예 |
assets/ | 34.6 MB | 직업·광산 배경 18장 | 예 (15장) |
assets/ | 191 KB | 아틀라스 8장 | 아니오 |
assets/ | 20 KB | rpg_+라이선스 | 아니오 |
assets/ | 6.36 MB | 배경+프롬프트+대본 | 아니오 |
assets/ | 139 MB | LPC 원본 | 아니오 |
assets/ | 17.4 MB | 스토어 이미지 | 아니오 |
assets/ | 83.6 MB | 원본 zip·음원 팩 | 아니오 |
public/: ui/icons/(66개), intro/(6장), PWA 아이콘, manifest.json, app-ads.txt(광고와 한정 오퍼).
오디오 카탈로그
id↔파일명: src/game/audio/catalog.ts 단일 출처.
배경음 2곡
| id | 파일 | 크기 | 길이 | 시점 |
|---|---|---|---|---|
intro | parchment- | 2.90 MB | 125초 | 인트로 컷씬 |
hub | parchment- | 6.81 MB | 280초 | 게임 화면 |
효과음 35종
| id | 파일 | id | 파일 |
|---|---|---|---|
ui. | ui_ | spell | spell.mp3 |
ui. | ui_ | craft | craft.mp3 |
ui. | ui_ | splash | splash.mp3 |
ui. | ui_ | monster.hit | monster_ |
ui. | ui_ | monster. | monster_ |
ui. | ui_ | levelup | levelup.mp3 |
ui. | ui_ | victory | victory.mp3 |
ui.tab | ui_ | reward | reward.mp3 |
ui. | ui_ | notify | notify.mp3 |
coin | coin.mp3 | impact | impact.mp3 |
coin. | coin_ | unsheathe | unsheathe.mp3 |
chop | chop.mp3 | book | book.mp3 |
equip | equip.mp3 | door. | door_ |
unequip | unequip.mp3 | door. | door_ |
hit | hit.mp3 | collect | collect.mp3 |
hit. | hit2.mp3 | sell | sell.mp3 |
swing | swing.mp3 | recruit | recruit.mp3 |
chat. | chat_ |
실제 재생 27종. 미사용 8종: hit.heavy·spell·monster.growl·notify·unsheathe·book·door.open·door.close.
재생 관리
DOM Audio+AudioContext(src/game/audio/manager.ts). 볼륨 기본 music/sfx 0.7. 첫 제스처에서 AudioContext resume. 배경음 수동 루프(페이드 min(2500,max(400,ms/4)) smoothstep). 백그라운드 전환 시 정지·resume(tests/audio-background.test.ts 6케이스).
빌드
glob 6개로 에셋을 번들에 넣습니다: assets/audio/sfx/*.{ogg,mp3}, assets/audio/bgm/*.{ogg,mp3}(src/game/audio/manager.ts), assets/sprites/characters/*.{png,json}(src/game/characters/registry.ts), assets/sprites/monsters/**/*.png, assets/sprites/battle-backgrounds/*.png(src/game/data/monster-runtime.ts). 직접 import: 직업·광산 배경 17장 — 파일로 나가는 15장과 인라인되는 임시 2장(bg-market.png 한 장은 아무도 import 하지 않아 번들에 아예 없습니다). public/ 은 복사. assetsInlineLimit 4,096 B(오디오 6개 인라인).
배경 45장(전투 30 + 직업·광산 15)은 산출물에서만 WebP q85로 다시 굽습니다 — dist 87.0 MB → 8.4 MB, 전체 110 MB → 33 MB. 1536×1024 알파 없는 풀컬러 그림은 PNG 압축이 걸리지 않아 이 45장이 안드로이드 번들의 5분의 4였습니다. 임시 배경 2장(bg-workshop.png·bg-thicket.png)은 여기 없습니다 — 224×120 도형 그림이라 각각 2 KB 남짓이고, assetsInlineLimit(4,096 B) 아래라 파일이 되지 않고 비네트 청크 안 data URI 로 인라인됩니다. 가축 우리의 임시 배경 3장과 오두막 시트가 같은 길로 갑니다. 저작 원본은 PNG 그대로고(lpc:bake·개발 서버·작업대 모두 PNG를 씁니다), 바뀌는 것은 pnpm build 가 쓴 파일과 그 파일을 가리키는 URL 문자열뿐입니다. 픽셀아트 시트·아이콘은 손실 압축이 윤곽을 흐리고 이득도 적어 대상에서 뺐습니다. 같은 플러그인 짝이 public/ 에서 딸려온 .DS_Store 류도 산출물에서 지웁니다.
아이콘 생성
스크립트 (python3 scripts/<이름>, PIL 필요)
| 출력 |
|---|
복사 7+코드 9 → ui/+public/ |
| fish·bread·stew·brick·chat 5종 |
인장 재료 5종 → icons/ |
상점 14종 크로마키 → icons/ (numpy) |
| 돋보기 1종 — 광장 주민 이름표의 상세 보기 버튼 |
왕궁 외형 5단계 — AI 원본 매지enta 크로마키 → assets/ (64×80) |
치장 테마별 왕궁 5단계 — 위 5장을 팔레트 그레이딩 → assets/ (64×80) |
치장 미리보기 = 테마의 하늘·땅·왕궁 합성 → icons/ (64×64) |
AI 원본 처리 — 그린 스크린 키링·회색조 → 행사 스프라이트 4장(assets/)·비네트 배경 2장(backgrounds/·bg-). 원본은 assets/ |
| 환경 조각 5개 |
두 폴더(ui/icons/·public/ui/icons/)에 동일 파일을 써야 합니다.
kingdom.png(왕국 탭)은 스크립트 산출물이 아닙니다. CC0 타일셋(16x16 Puny World Tileset, Shade)에서 32×16 두 조각을 붙여 만든 32×32 아이콘이고, 출처와 크롭 좌표는 CREDITS.md 에 적혀 있습니다. generate_icons.py 는 이 파일을 건드리지 않습니다.
규격
| 계열 | 크기 | 경로 |
|---|---|---|
| UI·자원 | 32×32 RGBA | / |
| 인장 재료 | 32×32 RGBA | / |
| 전리품 | 64×64 RGBA | / |
| 상점 | 64×64 RGBA | / |
팔레트 PALETTE_SDV 15색(generate_icons.py): deepnavy(26,26,46), darkblue(34,40,68), medblue(46,55,90), accent(94,100,140), light(160,165,190), vlight(200,205,220), warmgold(255,200,50), brightgold(255,215,80), red(220,60,60), green(80,180,80), brown(140,90,50), tan(210,170,110), gray(120,120,130), white(220,220,230), darkgray(60,60,70).
스토어 아이콘 — pnpm market:icons
iOS 마스터 1024에서 생성. appstore-icon 1024 알파제거, play-icon 512 알파강제, ha-icon 190(92,160 B 예산), promo-graphic 180×120.
알림 아이콘 — pnpm notif:icon
24×24 왕관 SVG → 밀도별(24/36/48/72/96 px) 래스터화. 출력 drawable-<버킷>/ic_stat_notification.png. 완전 불투명이면 예외.
원본과 저작권 보관
| 파일 | 내용 |
|---|---|
CREDITS.md (680줄) | LPC 자동 블록+타일셋+배경·아이콘 선언 |
assets/ | 오디오 팩 9건 출처·라이선스 |
assets/ | 참고 원본 4건+오디오 요약 |
| 팩 | 라이선스 | 주의 |
|---|---|---|
| artisticdude RPG Sound Pack | CC0 | — |
| Kenney 3종 | CC0 | — |
| Juhani Junkala Essential Retro SFX 512 | CC0 | — |
| mc2d_lts 탭·팝업 큐 | 출처만 기록 | — |
| Boolean SFX Complete Bundle (977) | 로열티프리 | 재판매 금지 |
| Sonniss GDC 2026 Game Audio Bundle | 로열티프리 | AI/ML 학습 금지 |
| Suno 배경음 2곡 | 프로젝트 소유 | — |
에셋 추가 절차
효과음
- mp3 →
assets/audio/sfx/(소문자+언더스코어) SfxId유니온에 점 표기 id,SFX_FILES에 매핑playSfx("id", { volume })호출assets/audio/CREDITS.txt에 출처 기록- 4 KB 이하면 인라인됨 인지
아이콘
- 32×32 RGBA(전리품·상점 64×64), 알파 필수
ui/icons/+public/ui/icons/두 곳에 동일 파일- 참조는
/ui/icons/<이름>.pngURL - 코드 생성이면
scripts/generate_*.py등록, 손그림이면assets/raw/보관 - 제3자면
CREDITS.md기재
그림 에셋
- glob 대상 폴더면 자동, 아니면 직접 import 또는
public/ - import 없이
assets/에 두면 저장소 용량만 차지 - 오브젝트 문자열 경로는 저작 도구 전용
- 배경 1장 ≈ 2 MB(PNG). 번들에는 WebP로 들어가 200 KB 안팎
광장·왕실 배경은 색으로 칠해 두었습니다
배경 그림을 쓸 자리가 두 곳 있는데 둘 다 PNG 가 아닙니다. 배경을 그림으로 넣으면 해상도별로 여러 장을 관리해야 하고 세로 비율에 맞춰 자르는 규칙이 새로 필요해서, 색과 그라디언트로 칠했습니다.
| 자리 | 지금 | 어디 |
|---|---|---|
| 광장 하늘 | 두 띠 skyTop·skyBottom (테마마다 다름) | KINGDOM_ — src/ |
| 광장 땅 | 8px 줄무늬 grass·grassAlt (테마마다 다름) | 같은 파일 |
| 가축 마당 땅 | 7px 줄무늬 yardGround·yardGroundAlt (테마마다 다름) | 같은 파일 |
| 왕실 벽 | CHAMBER_ 색 4종 (회벽·참나무·태피스트리·금박) + 테마 마감 | src/ · kingdom- |
| 왕실 바닥 | CHAMBER_ 색 4종 (나무·석재·융단·대리석) + 테마 마감 | 같은 두 파일 |
광장의 여섯 색이 씬의 상수에서 테마 카탈로그로 옮겨간 것이 치장 테마입니다. 씬에 남은 색은 칠이 아니라 상호작용의 가구입니다 — 칸 외곽선, 드롭 표시(초록/빨강), 이름표 잉크, 울타리. 그것들은 어느 테마에서나 같아야 합니다: 프로스트 팔레트에서 "여기 놓을 수 있다"는 초록이 파랗게 변하면 테마가 광장의 의미를 바꾼 것이지 겉모습을 바꾼 것이 아닙니다. CSS 16진 문자열로 authored 하고 Phaser 가 필요한 한 곳에서만 cssHexToInt 로 숫자가 됩니다 — 그래야 왕실(DOM background)과 광장(Phaser fillStyle)이 같은 철자의 색을 읽습니다.
벽·바닥을 타일 8종(각 32×32, 반복 가능)으로 바꾸기로 하면 FinishDef.color 를 타일 경로로 바꾸고 kingdom-chamber.ts 의 background 대입을 background-image: url(...) 로 두면 그대로 대체됩니다. 색으로 먼저 만든 이유가 이것입니다 — 반쯤 그린 패턴은 버려야 하지만, 이름 붙인 색은 타일이 도착하면 그 이름을 그대로 물려받습니다.
이어서 읽기
- 아트와 LPC 캐릭터 — 캐릭터 시트 파이프라인
- 데이터 파일 규격 — 오브젝트가 그림을 문자열로 가리키는 방식
- 개발 도구 — 무엇이 저작을 하는가
- 빌드와 테스트 — 빌드 엔트리와 품질 게이트