๊ฒ์ ๊ธธ ๋ค์ ๋ฏธ๋ก์ ์ถ๊ฒฉ์๋ ๊ฒ์ ๊ตฌํ ๋ชธ์ฒดยท๋ณด๋ผ ์ค๋ผยท๋ฐ์ ์ค์ ์ฝ์ด๋ฅผ ๊ฐ์ง ์ ๋ณ๋ ์บ๋ฆญํฐ๋ค.192ร192 RGBA ํ ์ฅยท์ค์ฌ ํผ๋ฒ96,96์ ์๋ ์ด๋์ํค๋ฉฐ, ์ธ๊ณฝ ์ค๋ผ๋ ๊ธธ์ ๋ฐํ๊ฑฐ๋ ์ถฉ๋ํ์ง ์๋๋ค. ์๋ณธยทํ๋กฌํํธยท์ํ/ํฌ๊ธฐ ์ฒ๋ฆฌ๋ ์ถ๊ฒฉ์ ์์ฐ ๊ณ์ฝ, ๋ฒฝ ํต๊ณผ ์ถ๊ฒฉยท์ ์ด ์ฌ์๋ยทํ๋ณต ์๊ณผ ๋ง์ง๋ง ๋ซํ ๋ฌธ์ ์ถ๊ฒฉ ์ฝํฐ๋ฅผ ๋ฐ๋ฅธ๋ค.
๊ธฐ์กด ๋๋ฃ ์ํธยทํ์ ํฌ๊ธฐ๋ ์ ์งํ๋ค. ๋ก๋น์ ์ ์ ์์ ๋ฐฐ์น์ ์์ ํ ๋ณดํ์ ๋๋ฌธ ์ฝํฐ, ๊ฑฐ์ ์ด์ ๋ฐ์ฌ์ยทFrom Now On ์ ํยท10๋จ๊ณ ์นด๋ฉ๋ผ๋ ๊ฑฐ์ ์ฝํฐ๊ฐ ์ต์ ์ด๋ค. ๊ฒ์ ๊ธธ์ ์ด๋80px ๊ฐ๊ฒฉ์ ๋์ ํ๋๋ง์ผ๋ก ๊ธธ์ ๋๋ฌ๋ธ๋ค. ์๋318์ ๋น ๋์ฐฉ ๋งต ๋ฒ์๋ ์ด๋ฒ ์ถ๊ฒฉ ๋ฏธ๋กยท์์ ๋ฐฉ์ผ๋ก ํ์ฅ๋์ผ๋ฉฐ, ๊ฒ์ฆ๊ณผ ๋ฐฐํฌ ์ฌ๋ถ๋ STATE์์ ๋ถ๋ฆฌํ๋ค.
์์ชฝ ๊ตฌ์ฒด ํ์ฑํ ๋ค ๋๋ฃ๋ค๊ณผ ์ค์ ๋ฌธ์ ์ฌ๋ ํ์ ์ฐ์ถ์ด ์ด์ด์ง๋ค. ์๋316/311์ โ๋๋ฌธ์ ์์ง ๋ซํโ์ ๋น์ ์งํ ๊ธฐ๋ก์ด๋ฉฐ318์ด ๋์ฒดํ๋ค. ์ด๋ฆฐ ๋ฌธ์ ๊ธฐ์กด320ร384 ๋ฌธํ๊ณผ ๋์ผํ ์บ๋ฒ์คยทํผ๋ฒ์ ์ ์งํ ๋ณ๋ ์์ฑ ์ํ์ด๋ค. ์๋ณธยทํ๋กฌํํธยท์ํ ๋ณด์กด ๋ด๋ณด๋ด๊ธฐ๋ ์ด๋ฆฐ ๋๋ฌธ ์์ฐ ๊ณ์ฝ์ ๋ฐ๋ฅธ๋ค. ๊ธธ์ ์์ ๊ฒ์ ์ด๋ฉฐ ๋ฐ๊ฑธ์ ํ๋์ด ์ค์ ๊ธธ ๊ฒฝ๊ณ์์ ๋๊ฒจ ์โ์ค๋ฅธ์ชฝโ์์ ๋ฐฉํฅ์ ์ฐพ๋๋ค. ๊ธฐ์กด ์ผ๊ตดยท์ค๋ธ์ ๋ฐ์๋ฆฌ๋ฅผ ์ฌ์ฌ์ฉํ๊ณ ์ ์บ๋ฆญํฐ ๋์์ธ์ ๋ง๋ค์ง ์๋๋ค.
BUILD317 ํ์ ๊ต์ : ์๋ณธ PNGยทํ๋ ์ยทํผ๋ฒ์ ๋ณด์กดํ๊ณ ๋๋ ์ฅ๋ฉด ๋ฐฐ์จ์1.3, ๊ฑฐ์๊ณผ ๋ฐํ ์ํด๋1.5๋ฐฐ(๊ฑฐ์ ์ค์ฒด ์ฝ330px)๋ก ํต์ผํ๋ค. ์๋0.88/220px๋ ์ ์ ๋น์ ๊ท๊ฒฉ์ด๋ค. ํํฌ๊ฐ๋์ธ์ ๋ผ์ด์ง์ ๊ฐ์ ์ธํํ park_guardian_costume2.22, ๋์ธ๋ผ๋ ttuulla1.79๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค. ์ต์ ๊ตฌ๋ยท๋ฐ๊ธฐ ์ ํ์ DESIGN์ ๋ฐ๋ฅธ๋ค.
๋๋์ญ์ ์์ ๊ธฐ์์ ๋ค ํ์ ๊ฑฐ๋ํ ์ค์ธ์ ๊ฐ์ฌ๋งจ์ ์๊ฒฝยท๋ ๋ยท๋์ ๋ณผยทํฐ ์ฝ, ํ์ฒญ/๋จน์ ์ด๋ ํ๋ ํธ๋ฅผ ๊ฒฐํฉํ๋ค.384px์ 2ร2ยท๋ฐ ํผ๋ฒ192,360ยท์ฅ๋ฉด ๋ฐฐ์จ0.88์ด๋ฉฐ ๋ฐ๊ธฐ ๋ ํฌ์ฆยทํฌํจยท๋ฐ๋ ค๋จ์ ๊ตฌ๋ถํ๋ค. ์๋ณธ๊ณผ ๋ชจ์ ๊ท๊ฒฉ์ ๋ฐ๋ฅธ๋ค. ์ฅฐํฌ๋ ๊ธฐ์กด ๋ถํ ๋ชธยทํ๋ ๋ยทํฐ ์ฝยท์งง์ ํ๋ค๋ฆฌ๋ฅผ ์ ์งํ ๋ณ๋ ์์ ๋ฐ๊ธฐ4ํฌ์ฆ๋ก,128px์ ยท๋ฐ64,120ยท์ ์ ์ด๋ฉดx112ยท๋ชจ์ ๋ฐฐ์จ0.5๋ค. ๊ธฐ์กด ๊ฑท๊ธฐ/์์์ ๋ฐ๊พธ์ง ์๋๋ค. ์ฅฐํฌ ๊ท๊ฒฉ.
๊ฑฐ์์ ์ค์ 220px ์ง๋ฆ์ด๋ฉฐ ๊ตด๋ฌ๊ฐ๋ ๊ทธ๋ฆผ๊ณผ ๋ฒฝ์ ๋ฐํ ๊ทธ๋ฆผ์ ํฌ๊ธฐยท์ ์ ์ ๊ฐ๊ฒ ์ฐ๊ฒฐํ๋ค. ๊ฑฐ์/๋ฒฝ ์์ฐ ๊ณ์ฝ์ ๋ฐ๋ฅด๊ณ ์ํ ์์ฑ๊ธฐ์ ์ค๊ฐ ์ถ๋ ฅ์ผ๋ก ์ต์ข PNG๋ฅผ ๋ฎ์ด์ฐ์ง ์๋๋ค. ์ฌ์ฏ ๋น์ยทํ๋ ๋ฐ๊ธฐยท์ผ์ชฝ ๋ด์ธ๊น์ง์ ์งํ์ ์ฝํฐ, ๊ฒ์ฆยท๋ฐฐํฌ ์ํ๋ STATE ๊ธฐ์ค์ด๋ค. ์ผ์ชฝ ๊ตฌ์ฒด ์ ๋ฑ ํ์๋ ์ค์ ๋๋ฌธ์ ์์ง ์ด์ง ์๋๋ค.
๋ง์ํ์ญ ๋์ฐฉ ๋งต ๋ถ์ชฝ ๋ฌธ์ ๊ฒ์ ๋จ์ผ ํ๋ฉด ๋ฐฉ์ผ๋ก ์ด์ด์ง๋ค. ์ค์ ๊ตฌ์ฒด๋128ร128ยท์ค์ฌ64,64์ ๋ณ๋ ์์ฑ ์ํ์ด๋ฉฐ ๋ณด๋ผ ์ค๋ผยท๋ฐ๋ฅ ๊ด์ยท์ํ๋ ์ค๋ฃจ์ฃ ๊ทธ๋ฆผ์๋ฅผ ๋ฐํ์์์ ๋ํ๋ค. ์๋ณธ/์ต์ข ์์ฐ ๊ณ์ฝ์ ๋ฐ๋ฅด๊ณ ์ค๊ฐ ์ฒ๋ฆฌ๋ฌผ์ ์ต์ข PNG ๋์ ์ฐ์ง ์๋๋ค. ์ ์ด ํ ๋๋ฌธ ์ค๋ฅธ์ชฝ ๋ด์ธ๋ง ์ผ์ง๋ ์ฐ์ถ๊ณผ ์๋ฃ ์ ์ฅ ๊ณ์ฝ์ ๊ตฌ์ฒด ๋ฐฉ ๊ธฐํ์ ๋ฐ๋ฅธ๋ค. ์ผ์ชฝ ๋ด์ธ๊ณผ ๋๋ฌธ์ ์์ง ๋ซํ ์๋ค.
๋ง์ํ์ญ์ ์ฌ์ฉ์ ์๋ณธ์ ๋พฐ์กฑํ ์์ฃผ์ ํ๋ยท์ฒญ๋ก ๋ณด์ ์ธ ๊ฐยท๊ฒ์ ์๊ฒฝยท์ฒญ๋ก ๋ ๋ ๊ฐยท๋์ ๋ณผยทํฐ ์ฝยท์
์ ๊ฐ๋ฆฐ ๋ชฉ๋๋ฆฌยท์ง์ ์กฐ๋ผ์ ํ๋ฆฌ์ฒ์ ์ ์งํ๋ค. ๊ฐ์ฌ๋งจ ์๋ณธ ์ํธ๋ฅผ ๋์ ์ฐ์ง ์๋๋ค. ๊ฒ์ ์ค๋ผ๋ ๋ณธ์ฒด ๋ค์ ๋๋ฉฐ ์ผ๊ตด์ ๊ฐ๋ฆฌ์ง ์๋๋ค. ๊ณต์ค ๋๊ธฐ/์์ /๋์ง/ํผ๊ฒฉ์ ๊ฐ๊ฐ128px์
2ร2 ์ํธยท์ค์ฌ ํผ๋ฒ64,64์ด๊ณ , ๊ณตํ์ถฉ์64px์
ยท์ค์ฌ32,32๋ค. ์๋ณธยท์ ํํ ์์ฑ ํ๋กฌํํธยท์ต์ข
์ํธ ๊ณ์ฝ์ ๋ฃจํธ PNG๋ง ์ฌ์ฉํ๋ฉฐ ์ค๊ฐ sheet-transparent.png๋ก ๋ฎ์ด์ฐ์ง ์๋๋ค.
๋จผ ๋ฐฐ๊ฒฝ ์ ํฌ์ ์ ์ ๊ฐ์ฌ๋งจ์ ๋์ ๋ณผยทํฐ ์ฝยท์๊ฒฝยท๋ ๋๊ณผ ์์
์ ๋๋/๋ฐํฑ, ์ด์ฆ๋ฆฌ์ผ์ ๊ธ๋ฐ/๋ง๋ฒ ์ฅ๊ฐ, ์ผ์ค์ค์ ๋ฌถ์ ๋จธ๋ฆฌ/๊ฒ, ์์นผ๋ฆฌ์ ๋์๋ณต/๋ซ์ ์์ ๋ณ๋ ๋ค ์บ๋ฆญํฐ๋ค. ์ผ๊ตด์ ์ฝํ๊ฒ ๋๊ณ ํ์ฒญ์ยท๋จน์ ๊ณ์ด์ ์์ ์ฑํผ์ธ ๊ตฌ๋ถ์์ ๋จ๊ธด๋ค.96px์
2ร2์ ์์๋ ๋๊ธฐโ์ค๋นโ๊ณต๊ฒฉโํผ๊ฒฉ์ด๋ฉฐ ๋ง์ง๋ง ์
์ ํ๋ณต/๋๊ธฐ ํฌ์ฆ๊ฐ ์๋๋ค. ์ ๋ฐฐ๊ฒฝ ์ํธ์ ๊ทผ์ ๋ณด์ค ์ํธ์ ํ์ ํฌ๊ธฐ๋ฅผ ์๋ก ๋ณต์ฌํ์ง ์๋๋ค. ์ ์ ์๋ณธ๊ณผ ๋ฐ ์ ๋ ฌ, ์ค์ ์ฐ๊ฒฐ์ src/battle/modes/malzahar-background.js๊ฐ ์์ ํ๋ค.
๋ณด๋ผ ํ ๋ฆฌ์ด๋ ๊ธฐ์กด ํ๋ ํ ๋ฆฌ์ด์ ๋ชจ์ยท๋ถ๋ฆฌ ๋ ์ด์ดยท์ํค๋ฅผ ์ ์งํ ์์ ๋ณํ์ด๋ค. ํ๋ ํธ ์์ฑ๊ณผ ๊ธฐ๊ณ์ ์ฌ์์ ๊ธฐ๋ก, ์ฐ์ ๋ฌ๋ฆฌ๊ธฐ ์ ํฌ ๊ณ์ฝ, ๊ฒ์ฆยท๋ฐฐํฌ ์ฌ๋ถ๋ STATE๋ฅผ ๋ฐ๋ฅธ๋ค. ์ด ๊ตฌ๊ฐ์ ๊ธฐ๋ณธ ์ด๋/์ ํ/๋ฒ ๊ธฐ๋ ๊ธฐ์กด runner๋ฅผ ์ฌ์ฌ์ฉํ๋ค.
์ญ๋ฃจํ ยท์ง๋ขฐ์ญยท์ฐ๋๋ฅด์ญ์ ๊ฐ์ฌ๋งจ gajaeman_shadow.png์ฒ๋ผ ์ ์ ์ ์ด๋ ์ ํ์ ๋ฐ์ ํ์ฒญ์ ํผ๋ถยท๋จน์/๋จ์ ์์์ผ๋ก ํ์ํ๋ค. ์๋308์ ๋ฐ์ ์์์ ์ด๊ธฐ ์ ์ฒด์ฑ ๊ธฐ๋ก์ด๋ฉฐ ์ต์ ํ๋ ํธ๋309๊ฐ ์ฐ์ ํ๋ค. ์ผ๊ตด ํํยท๋ ๊ฐ์ยท์๊ฒฝ ์ ๋ฌดยท์ฝยท์์ ์ค๋ฃจ์ฃยท๊ณต๊ฒฉ ํฌ์ฆ๋ ์ ์งํ๊ณ ๊ธฐ์กด ๊ตฌ๋ถ์์ ๋ฎ์ ์ฑ๋์ ์์ ํ์์ผ๋ก ๋จ๊ธด๋ค. ํ๋ ์ค๋ฆฝ๊ณผ ์ ํฌ ์์ , ์ง๋ขฐ์ญ ๊ฑฐ๋ฏธ์ค ๋ท๋ชจ์ต๋ ๊ฐ์ ์ ๊ณ์ด์ด๋ค. ์๋ณธ ํธ์งยทํ๋กฌํํธยท๋น๊ตยท๊ท๊ฒฉ์ assets/source/memory309/<id>/README.md๋ฅผ ๋ฐ๋ฅธ๋ค.
์ธ ์ ์ ์ธํ์ ์์ ํ ๋ assets/references/memory308-<id>.png์ ์๋ ์์ฐ ๊ณ์ฝ์ ํจ๊ป ํ์ธํ๋ค. ํ๋์ ์ ํฌ๋ ๊ฐ์ ์ผ๊ตดยท์์ยท์ผ์ชฝ ์๋3/4 ์์ ์ ์ ์งํ๋ฉฐ, ์์ ์ด๋์ด ๊ธฐ์ด์ ์ผ๊ตด ๋ค์ ๋๋ค.
| ์บ๋ฆญํฐ | ๊ณ ์ ์ธํ | ์๋ณธยท๋ฐํ์ ๊ณ์ฝ |
|---|---|---|
์ญ๋ฃจํ (seobruto) |
๋ ธ๋ ๋จธ๋ฆฌ, ๋๋ญ์ ๋จธ๋ฆฌ๋ , ๋ฅ๊ทผ ์๊ฒฝ๊ณผ ๋ ๋, ๋์ ๋ณผยทํฐ U์ ์ฝ, ๋ณ๋ ์ ์์, ์ฃผํฉ/๋จ์ ๋์์ท | ์ญ๋ฃจํ |
์ง๋ขฐ์ญ (jiroesub) |
๊ฒ์ /๋ถํ ์๊ฐ๋์ ๋ฆฌ๋ณธ, ์๊ฒฝ ์๋ ๋ ๋ยทํฐ U์ ์ฝยท๋ณ๋ ์ ์์, ๋ถํ ํ๋ฆด, ๊ฒ์ ์น๋ง/๋ถ์ธ , ์บ๊ณผ ์ฟ ๋ก๋ฏธ ๊ฐ๋ฐฉ | ์ง๋ขฐ์ญ |
์ฐ๋๋ฅด์ญ (udyrsub) |
๊ธด ๊ฐ์ ๋จธ๋ฆฌ์ ์์ผ, ํ๋ ๋จธ๋ฆฌ ๊ฐ๋ฅ, ์๊ฒฝ๊ณผ ๋ ๋ยทํฐ U์ ์ฝ, ๋ฌธ์ ํ ์์ฒด, ์ฃผํฉ ๊ตฌ์ฌยทํฐ ๋ถ๋ยท๊ฐ์ฃฝ ์น๋ง | ์ฐ๋๋ฅด์ญ |
์ธ ๋ชธ์ฒด๋128px์
ยทํผ๋ฒ64,120์4ํฌ์ฆ ์ ํฌ ์ํธ์ ์ค๋ฆฝ ์
์ ํ๋ ์ ์ง ๊ทธ๋ฆผ์ ์ฌ์ฉํ๋ค. ๊ธฐ์ต์ ๋ฐฉ ๋ฌธยท๊ฒ์ ์์ฌยท๊ธฐ๋ฅ ์๊ฒฝ์ ์์ ํ ๋๋ BUILD308 ํ๊ฒฝ ๊ณ์ฝ์ ์ ์ฉํ๋ค. ํ์ฌ ์์ฐ์ ๊ธฐ์กด castle307_* ๋ฐํ์ ํ์ผ์ ๊ฐฑ์ ํ๋ฏ๋ก ๊ณผ๊ฑฐ307 ์์ฑ๊ธฐ๋ก ๋ฎ์ด์ฐ์ง ์๋๋ค. ์กฐ์ฐยท๋์ฌยท์งํ ๋ฒ์๋ ๊ธฐ์ต์ ๋ฐฉ ์ฝํฐ, ํตํฉ ๊ฒ์ฆยท๋ฉ์ธยท๋ฐฐํฌ ์ํ๋ STATE๋ฅผ ๋ฐ๋ฅธ๋ค.
๋๋ชฉ ํ์ ๊ธฐ๋ฅ์ ํ์ ๋ ๋ฒ ์๋ณธยท๊ท๊ฒฉ์ ๋ฐ๋ฅธ๋ค.32ร48 ๋๊ธฐ/๋น๊น2ํฌ์ฆ, ๊ณตํต ๋ฐ๋ฅ ํผ๋ฒ16,48์ด๋ฉฐ ๊ธฐ์กด ์บ๋ฆญํฐ๋ ๋๋ชฉ ๊ทธ๋ฆผ์ ๋ฐ๊พธ์ง ์๋๋ค.
BUILD306 ์ฑ ๋ถ์ชฝ ๊ธธ์ ์ธ๋ถ๊ฐ ์๋๋ผ ๊ฒ์ ์๋ฒฝยท๊ธฐ๋ฅยท์์น์ ๋ณด๋ผ ์ด๋ผ๊ฐ ์๋ ์ฑ ๋ด๋ถ ์ง์ ํ์ด๋ค. 32px ๋ฐ๋ฅ4์ข ยท๊ฑฐ๋ ์ฑ๋ฌธยท์ค๋ด ๋ฐฐ๊ฒฝ์ ์ฑ ๋ด๋ถ ์์ฐ ๊ณ์ฝ, ๊ธฐ๋ ์ฌ์ง์ ํ๊ฐ ์นด๋ฉ๋ผ ์ํ์ ์นด๋ฉ๋ผ ๊ณ์ฝ์ ๋ฐ๋ฅธ๋ค. ๊ธฐ์กด ์บ๋ฆญํฐ ์ธํ์ ๋ฐ๊พธ์ง ์๋๋ค. ์ด๊ธฐ ์ธ๋ถ ์ฑ ์ ๊ฒฝ์ ๋ฏธ์ฑํ ์ด์์ผ๋ก ๋ณด์กดํ๋ฉฐ ๋ฐํ์์ ๋ค์ ์ฐ๊ฒฐํ์ง ์๋๋ค.
BUILD305 ์ถ์ ์ฐ์ถ์ ์ฃผ๋จน ์๋ต์ ๊ธฐ์กด ์ํ๋ยท๊ฒฝ์ญยท๋น ๋งจ์ ์ผ๊ตด๊ณผ ์์์ ์ ์งํ ๋ฌด๊ธฐ ์๋4ํ๋ ์์ด๋ค. assets/sprites/*-deck-fist.png๋512ร128, ์
128ร128ยท๋ฐ ํผ๋ฒ64,120ยท๋ฐฐ์จ0.5์ด๋ฉฐ ์๋ ๊ฑท๊ธฐ ๋์ด์ ๋ง์ถ๋ค. ์์ฑ ์๋ณธ/์ ํํ ํ๋กฌํํธ/NEARESTยท์ํ ๋ณด์กด ์ฒ๋ฆฌ ๊ธฐ๋ก์ ๊ฐํ ๋ชจ์
, ์ฑ ์
๊ตฌ์32px ๋ณด๋ผ ์์ฌ4์ข
์ ํ์ผ ๊ธฐ๋ก์ ์๋ค. ๋ด์ฅ ์ด๋ฏธ์ง ์์ฑ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๊ณ ๊ธฐ์กด ๊ฑท๊ธฐยท์ ํฌยท์ด์ํ๋ ๋ณ๊ฒฝํ์ง ์์๋ค.
๋ธํ๋ฃฌ ์คํ์ผ ํ๋ค์ด ๋ํธ ์คํ ๋ฆฌ ์ด๋๋ฒค์ฒ. ์น์์ ๋ฐ๋ก ์คํ, ๋น๋ ์์(ES ๋ชจ๋), ๋งตยท์ํธ๋ ํ์ด์ฌ ์์ฑ๊ธฐ๋ก ๋ฝ๊ณ ์ค๋์ค๋ mp3(์ถ์ฒ design/audio/references.md).
./dev.sh # ์บ์ ๋ ๊ฐ๋ฐ ์๋ฒ ์ฌ๊ธฐ๋ โ http://localhost:8000 (์์
ํธ๋ฆฌ๋ฅผ ๊ทธ๋๋ก ์๋น โ ์๋ '์์
๊ท์จ')
tools/dev/check.sh # ๋ฌธ๋ฒ + ๋จ์ ํ
์คํธ + ๋งต ์์ฑ๊ธฐ ๋๊ธฐํ (์ปค๋ฐ ์ , pre-commit ์ด --quick ์ ๊ฐ์ )
tests/playtest/run.sh battle teal5 # ํค๋๋ฆฌ์ค ํ๋ ์ดํ
์คํธ(Playwright, ์คํฌ๋ฆฐ์ท tests/playtest/shots/)QA ๋ฐ๋ก๊ฐ๊ธฐ: ํ์ดํ์์ Q ๋๋ ?qa=<id> (๋ชฉ๋ก src/core/story.js QA_POINTS). ์ํ๋ docs/STATE.md, ๊ท์น์ CLAUDE.md.
์ต๋ฏธ์ค๋ ๊ธฐ๋ณธ ๋ชจ์ต์ ํฐ ์์น ๋จธ๋ฆฌยท๊ฒ์ ๋์นยท์ฌ๊ฐ ์๊ฒฝยท๊ธด ์ฝยท๋ณ๋ ์น์ ์ ยท๋ณผ ์ ์ ์ ์งํ๋ค. ๋์ ๋ ๊ฐ๋ก ์ฝํ์ผ ํ๋ฉฐ ์๊ฒฝ ๋ฐ์ฌ๋ ๋์น์ ์ธ ๋ฒ์งธ ๋์ฒ๋ผ ๊ทธ๋ฆฌ์ง ์๋๋ค. ์ ํฌํผ์ ์ด์ ํ๋ฉด ํค์ ์ฝ1.4๋ฐฐ์ธ ๊ธธ๊ณ ๊ฐ๋ ์ฒดํ์ด๋ฉฐ, ์ผ๊ตด์ ์ธ๋ก๋ก ๋์ฌ ํค๋ฅผ ๋ง์ถ์ง ์๋๋ค. ๋ณ์ ํ ํ๋ํผ๋ ๊ฐ์ ๊ธด ์ฒดํยท์ผ๊ตด ์ ์ฒด์ฑ์ผ๋ก ์ด์ด์ง๋ฉฐ ๋งํ ๋ ์ ํฌ ์ง์ ์์ ํผ์น๋ค. ๋ณ์ ์ ๋ฑ๋ฑํ ๊ธฐ๋ณธ ์ต๋ฏธ์ค๋ ๊ทธ๋๋ก๋ค. ํ๋4๋ฐฉํฅ ์๋ณธยท๊ท๊ฒฉ.
๋งํ ๋๊ธฐยท์ ์ฌ๋ฆผยท์ตธ์ ๊ณต๊ฒฉ์ ์ต์ ์์ฑ ์๋ณธ, ์ค์ ํ๋กฌํํธ, ํ๋ ์ ์๊ฐ, ๊ณตํต ํผ๋ฒ๊ณผ ํฌ๊ธฐ ๋น๊ต๋ cape301 ์์ฐ ๊ณ์ฝ์ ๋ฐ๋ฅธ๋ค. ํ์ฌ160px์ ยทํผ๋ฒ72,152ยท๊ท ๋ฑ ๋ฐฐ์จ0.714๋ก ๋๊ธฐ ํค99.96px๋ค. ํ์ด๋์ ์ถ๊ฐ6ํ๋ ์ ๋งํ ํ๋๋ฅด๊ธฐ๋ finale304 ๊ณ์ฝ์ ๋ฐ๋ฅธ๋ค. ๋ชธ ํฌ๊ธฐ๋ ์ ์งํ๋ฉฐ ๋์ ๋งํ ๋ง ์์ฉํ๋๋ก224ร192์ ยทํผ๋ฒ136,180์ ์ด๋ค. ์ฅ๋ฉด๋ณ ์ฐ๊ฒฐ๊ณผ ์ต์ ํ๋ ์ด ๊ท์น์ DESIGN, ์ต์ข ๊ฒ์ยท๋ฉ์ธยท๋ฐฐํฌ ์ฌ๋ถ๋ STATE์์ ๊ตฌ๋ถํ๋ค.
- JS ์์ ์
tools/dev/patch.py src/a.js <<'PY' โฆ PYโ ์์ ์ฌ๋ณธ์ ์ ์ฉํดnode --check๋ฅผ ํต๊ณผํ ๊ฒ๋ง ์๋ณธ์ผ๋ก ์ฎ๊ธด๋ค(์๋ฒ๊ฐ ์์ ํธ๋ฆฌ๋ฅผ ์๋นํ๋ฏ๋ก ๊นจ์ง ์ค๊ฐ ์ํ ๊ธ์ง). - ํ ์ค ๋ฌธ์ฅ ๋
//์ฃผ์ ๊ธ์ง. ์ปท์ ์ขํ๋rel:๊ธฐ์ค. ์ปค๋ฐ ์ tools/dev/check.sh.
| ์กฐ์ | ํค |
|---|---|
| ์ด๋ | ๋ฐฉํฅํค / WASD (๊ฒ์ํจ๋ D-pad/์คํฑ) |
| ํ์ธ ยท ๋ง ๊ฑธ๊ธฐ ยท ๋์ฌ ๋๊ธฐ๊ธฐ | C (Enter/Z, ํจ๋ A) |
| ์ทจ์ ยท ๋์ฌ ์ฆ์ ํ์ ยท ๋ฌ๋ฆฌ๊ธฐ(ํ๋) | X (Esc/Shift, ํจ๋ B) |
| ๋ฉ๋ด | V (Tab) |
| ๋๋ฒ๊ทธ(ํํธ๋ฐ์ค/ํ๋๊ทธ) | F1 |
index.html ์บ๋ฒ์ค (์ค๋์ค๋ ์ฒซ ํค ์
๋ ฅ์์ ์ธ๋ฝ)
src/ui/title.js ํ์ดํ ํ๋ฉด: ๋ธ๋ก ๋ก๊ณ "subtArune"(GLYPHS), C๋ก ์์
src/main.js Game: ์ํ(field/dialogue/menu), ๋งต ์ ํ ํ์ด๋, ๋ฉ๋ด, ๋ฃจํ
src/core/input.js ํค๋ณด๋+๊ฒ์ํจ๋ โ ์ก์
(up/down/left/right/confirm/cancel/menu)
src/core/audio.js mp3 ๋ธ๊ธ/ํจ๊ณผ์/๋ชฉ์๋ฆฌ ๋ก๋(preloadBgmยทplayBgmยทsfxยทblip) + WebAudio ํฉ์ฑ ํด๋ฐฑ
src/core/gfx.js ๋ฌธ์์ด ๋ํธ์ํธ โ ์บ๋ฒ์ค, ๋ฐ์ค/ํํธ, PNG ์ค๋ฒ๋ผ์ด๋ ๋ก๋
src/ui/cutscene.js ์ปท์ ๋ช
๋ น(move/face/camera/fade/shake/spawn/map/parallel) โ /cutscene ์คํฌ ์ฐธ๊ณ
src/data/cutscenes/ ์ปท์ ๋ฐ์ดํฐ (opening.js โฆ teal5_river.js, _template.js)
src/battle/ ํด์ ์ ํฌ(battle.js ์ํ ๊ธฐ๊ณ, bullets.js ํ๋ง), ์ ๋ฐ์ดํฐ src/data/enemies.js, ์์ดํ
src/data/items.js
src/core/story.js ์คํ ๋ฆฌ ๋จ๊ณยทQA ์ง์ / src/core/party.js ํํฐ ์ ๊ทํ(๊ฑท๋ ์์ ํ์ญโ๊ฒฝ์ญโ๋น ๋งจ)
tools/maps/*.py ๋งต ์์ฑ๊ธฐ โ assets/maps/*.json (--check ๋ก ๋๊ธฐํ ๊ฒ์ฌ) ยท tools/art/*_set.py ํ์ผยท์ํ ํ์ธํฐ
tools/dev/ patch.py(์์ ํจ์น) ยท check.sh(ํ ๋ฒ์ ๊ฒ์ฌ)
src/ui/dialogue.js TextBox(ํ์๊ธฐยทํ๊ทธยทํ์ด์งยท์ด์ํยท์ ํ์ง) + ScriptRunner(๋ผ๋ฒจ/๋ถ๊ธฐ/ํ๋๊ทธ)
src/world/tiles.js ํ์ผ ๋ ์ง์คํธ๋ฆฌ (registerTile)
src/world/world.js TileMap / Camera / Entity ์ข
๋ฅ (registerEntity)
src/data/art.js ๋ํธ ์ํธ ์๋ณธ + ํ๋ ํธ (์ฌ๊ธธ ๊ณ ์น๋ฉด ๊ทธ๋ฆผ์ด ๋ฐ๋)
src/data/maps.js ์ฝ๋ ๋งต(๋ฐฉยท๊ฑฐ์ค ์ด๋ฏธ์ง ๋งต). ์ง์
ํ ๋งต์ assets/maps/*.json ๊ณผ ํ์ํ ๊ทธ๋ฆผ์ ์ค๋นํ ๋ค ๊ต์ฒดํ๋ค
src/data/scripts.js ๋์ฌ ์คํฌ๋ฆฝํธ (ํ๊ธ)
src/data/locale/ko.js ์์คํ
UI ๋ฌธ์์ด
assets/ PNG๋ฅผ ๋ฃ์ผ๋ฉด ์๋ ๊ต์ฒด (์๋ ๊ท๊ฒฉ)
design/gdd/ ๊ธฐํ ๋ฌธ์ ยท .claude/ ๊ฒ์ ์คํ๋์ค ์์ด์ ํธ(49) + ์คํฌ
tests/unit node:test โ ๋งต ๊ฐ์ฌยท์ํ ํคยท์ปท์ โ๋งต ์ ํฉยท์์ดํ
ยท์ ๋ฌธ๊ตฌยทํํฐยทQA ์ง์ โฆ
tests/playtest Playwright ์๋๋ฆฌ์ค(run.sh ๋ก ์คํ) โ ๋งต๋ง๋ค ํ๋, ์คํฌ๋ฆฐ์ท์ ๋์ผ๋ก ํ์ธ
NPC ํ๋ ์ถ๊ฐ โ src/data/maps.js ์ entities ์ ํ ์ค:
{ type: 'npc', id: 'baker', sprite: 'merchant', ...at(5, 5), facing: 'down', wander: 16, script: 'baker' },src/data/scripts.js ์ ๋์ฌ:
baker: [
{ speaker: '๋นต์ง ์ฃผ์ธ', portrait: 'merchant', voice: 'low', text: '* ๊ฐ ๊ตฌ์ด ๋นต์ด์ผ.{w=0.4} {c=yellow}๋จน์๋?{/c}',
choice: { options: [{ label: '์', goto: 'eat' }, { label: '์๋', goto: 'no' }], cancel: 1 } },
{ label: 'eat' }, { text: '* ๋ง์๋ค.', voice: 'narrator' }, { set: { ate_bread: true } }, { end: true },
{ label: 'no' }, { text: '* ๋ค์์ ๋จน์.', voice: 'narrator' },
],๋์ฌ ํ๊ทธ: {s=2} ๋น ๋ฅด๊ฒ ยท {s=0.5} ๋๋ฆฌ๊ฒ ยท {/s} ๋ณต๊ท ยท {w=0.5} 0.5์ด ๋ฉ์ถค ยท {c=red}โฆ{/c} ์ ยท {shake}โฆ{/shake} ยท {wave}โฆ{/wave} ยท {n} ์ค๋ฐ๊ฟ
์คํฌ๋ฆฝํธ ๋
ธ๋: text / choice / label / goto / if:(flags)=>bool, goto / set:{} / action:(game)=>{} / end
ํ์ ์์: src/core/audio.js VOICES ์ ํ๋ฆฌ์
์ถ๊ฐ (freq/wave/dur/jitter)
์ ๋งต: ์ด๋ฏธ์ง ๋งต MAPS.xxx = { image:'assets/maps/xxx.png', walkable:[[x,y,w,h]], solids:[[...]], spawns:{}, entities:[] } ๋๋ ํ์ผ ๋งต { rows:[...] }
์ ํ์ผ: registerTile('X', { name, solid, art | draw }) ์ ์ํฐํฐ ์ข
๋ฅ: class Foo extends Entity + registerEntity('foo', Foo)
| ํ์ผ | ๊ท๊ฒฉ |
|---|---|
assets/sprites/<id>.png (์ฃผ์ธ๊ณต hyungsub, NPC๋ sprite: ์ด๋ฆ) |
4์ด ๊ฑท๊ธฐ ํ๋ ์ ร 4ํ [down, up, left, right]. ์ ํฌ๊ธฐ๋ PNG ํญ/4 ร ๋์ด/4, ๊ฒ์์ฉ 2x ํด์๋์ด๋ฉฐ ์บ๋ฆญํฐ๋ง๋ค ๋ค๋ฆ |
assets/tiles/<ํ์ผ name>.png |
16ร16 (grass, wall, tree, doorโฆ) |
assets/portraits/<์ด๋ฆ>.png |
์์ฑ ํ์ผ 96ร96, ๊ฒ์ ๋ํ์ฐฝ์์ 48ร48๋ก ํ์ |
ํ์ผ์ด ์์ผ๋ฉด src/data/art.js ์ ๋ฌธ์ ๋ํธ์ํธ๋ฅผ ์ (์ฝ์์ 404๋ ์ด ํ์ ๋๋ฌธ โ ์ ์).
/cutscene <์ด๋ฆ> <ํ ์ค ์ค๋ช
> ์คํฌ์ ์ฐ๊ฑฐ๋, src/data/cutscenes/_template.js ๋ณต์ฌ โ scripts.js ๋ฑ๋ก โ ๋งต์ ํธ๋ฆฌ๊ฑฐ.
๊ฒ์ ํ๋ฉด ๋๋ ์ด์
์ { style:'narration', voice:'none', speed:0.6, text:'...' }. ๋
ธ๋ ์ ์ฒด ๋ชฉ๋ก์ .claude/skills/cutscene/SKILL.md.
์ฌ์ ํ์ธ: node tests/playtest/cutscene.mjs <์ด๋ฆ>
http://localhost:8000/?map=test (๋๋ ํ์ดํ์์ T). ์๋ด/ํ
์คํธ ํจ๊ณผ/์ ํ์ง/ํ๋ ์ด์ด ์คํ๋ผ์ดํธ ๊ต์ฒด/์ ํฌ ๋ชจ์
ํป๋ง, ์์, ํ์ญยท๊ฒฝ์ญยท๋น ๋งจ NPC, ๋ฌ๊ทธ ๋ฐ์ผ๋ฉด ์ปท์ ๋ฐ๋ชจ.
?map=<๋งต>&spawn=<์คํฐ>&sprite=<์บ๋ฆญํฐ> ๋ก ํ์ดํยท์คํ๋ ๊ฑด๋๋ฐ๊ณ ๋ฐ๋ก ์ง์
.
์ฒญ๋ก์ฒ2(?qa=teal2)๋ ์ฅฐํฌ๋ฅผ ๋ฎ์ ๋ชฉ์กฐ ๋์ 6์ข
์ ์ฌ์ฉํ๋ค. ๊ธฐ์กด ๋์ 13๊ฐ์ ์์นยท์ถฉ๋ยท๋์ฌ๋ ์ ์งํ๊ณ ํฌ์ฆ๋ง ๋๋ ๋ฐฐ์นํ๋ค. ๋์ ์ํธ๋ assets/props/statue_junhee_<pose>.png์ด๋ฉฐ, ๋งต ๋ฐฐ์น๋ tools/maps/teal.py --check๋ก ํ์ธํ ์ ์๋ค.
์ ํฌ ์์คํ ์ ๋ ๋/๋ธ๋ฃจ ๋ฏธ๋์ธ์ด๋ ์ด๋ฆฐ ๋ฌด๊ธฐ ์์ ์ด๋ฏธ์ง๋ฅผ ์ฐ๊ฒฐํ ๋๋ ์ ํฌ ์์ ์ ๋ฌ ๊ฐ์ด๋๋ฅผ ๋จผ์ ํ์ธํ๋ค. ๋จ์ผ ํ๋ ์ PNGยท๋ฐฉํฅยทpivot๊ณผ ๊ธฐ์กด 4ร4 ํ๋ ์ํธ์ ์ฐจ์ด๋ฅผ ์ ๋ฆฌํ๋ค. ์ด๋ฏธ์ง ์ ๋ฌ์ฉ์ด๋ฉฐ ๋ฐํ์ ์๋ ์ ์ฉ์ ์๋๋ค.
http://localhost:8000/?map=test&battle=1 ๋๋ ํ
์คํธ๋ฃธ์ ์ ํฌ ๋ชจ์
ํป๋ง์์ ์ฐ๋ค. ์ข์ฐ๋ก ์บ๋ฆญํฐ ์ ํ, C๋ก ๋ฌด๊ธฐ๋ฅผ ๋ค๊ณ ๊ณต๊ฒฉ ์ง์ ๊น์ง ๋ฌ๋ฆฌ๊ธฐ โ ๊ณต๊ฒฉ โ ์์์น ๋ณต๊ท, X๋ก ์๋ ํ๋ ๋ณต๊ท, Esc๋ก ํ์ดํ ์ด๋. ๋์ ์ค์๋ ์บ๋ฆญํฐ ์ ํ๊ณผ ์ถ๊ฐ ๊ณต๊ฒฉ์ ์ ๊ทธ๋ฉฐ, ์ทจ์ํ๋ฉด ๋ชจ๋ ์์์น๋ก ์ด๊ธฐํํ๋ค. ๊ฒ์ํจ๋๋ ๊ธฐ์กด ์ ํ/ํ์ธ/์ทจ์ ์ก์
์ ์ฌ์ฉํ๋ค.
ํ์ญ์ ์นผ(๋ชจ๋ ํ๋ ์ ์ ์์), ๊ฒฝ์ญ์ ์์๋๋ผ, ๋น ๋งจ์ ํ๋ ๊ตฌ์ฌ์ด ๋ฌ๋ฆฐ ํ์ ๋ง๋ฒ๋ด์ ์ฌ์ฉํ๋ค. ์บ๋ฆญํฐ๋ง๋ค ๋๊ธฐ 4์ฅ๊ณผ ๊ณต๊ฒฉ 4์ฅ์ด ์์ผ๋ฉฐ, ๊ณต๊ฒฉ ์ค ์ฌ์ ๋ ฅ์ ๋ฌด์ํ๊ณ ํ ๋ฒ ์ฌ์ํ ๋ค ๋๊ธฐ๋ก ๋์๊ฐ๋ค.
์๋ณธ๊ณผ ์์ฑ ํ๋กฌํํธ๋ assets/battle/, ํ๋ ์ ์์ญยท๋ฐ ๊ธฐ์ค์ ยท์๋๋ src/data/battle-sprites.js, ์ง์ฐ ๋ก๋ฉ๊ณผ ์ฌ์์ src/ui/battle-preview.js์ ์๋ค. ๋ง์ ํ RGB ์๋ณธ์ ๋ณด์กดํ๊ณ , ๊ธฐ๋ณธ ์ธ ์บ๋ฆญํฐ๋ ๋์ผ ํฝ์
์ ํฌ๋ช
๋ฐํ์ ์ํ๋ผ์ค๋ฅผ ์ฌ์ฉํ๋ค(assets/battle/RUNTIME.md). ์ ์ฒด ์ํธ๋ฅผ ๊ท ๋ฑ ๋ถํ ํ๋ฉด ๋ฌด๊ธฐ๊ฐ ์๋ฆฌ๋ฏ๋ก ๋ฉํ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ค.
ํ์ฌ๋ ์์ง ์์ ๋ชจ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์ด๋ฉฐ ์ค์ ์ ํฌ ์์คํ ์ ์๋๋ค. ์ ยทHPยทํดยทํผํด ํ์ ยท์คํ ๋ฆฌ ์ ํฌ ์ง์ ์ ๊ตฌํํ์ง ์์๋ค. ๊ธฐ์กด ์ด๋ ์คํ๋ผ์ดํธ์ ์ธ์ด๋ธ๋ ๋ณ๊ฒฝํ์ง ์๋๋ค. ์์ฑ์ ์ฌ์ฉ์ ์น์ธ์ ๋ฐ๋ฅธ ๋ด์ฅ ์ด๋ฏธ์ง ๋๊ตฌ์ด๋ฉฐ ํน์ GPT Image 2.5 ๋ชจ๋ธ๋ก ๊ณ ์ ํ ๊ฒฐ๊ณผ๋ ์๋๋ค.
๊ฒ์ฆ: node --test tests/unit/battle-preview.test.mjs, BASE_URL=http://localhost:8000 node tests/playtest/battle-preview.mjs (๊ธฐ์กด Playwright ์คํ ํ๊ฒฝ ํ์).
AI ์์ฑ ์ํธ(๋ณด๋ผ ๋ฐฐ๊ฒฝ, ์บ๋ฆญํฐ๋น 4์ด ร 4ํ[์ ๋ฉด/์ผ์ชฝ/์ค๋ฅธ์ชฝ/๋ท๋ชจ์ต]) โ ๊ฒ์ ์ํธ + ์ด์ํ:
pip install pillow numpy
python3 tools/sprites/slice_sheet.py sheet.png hyungsub gyeongsub ppaman # โ assets/sprites/*.png, assets/portraits/*.png์ ์บ๋ฆญํฐ๋ src/data/characters.js ์ ํ ์ค ์ถ๊ฐ. ํฐํธ๋ src/ui/font.js FONT_PRESET ํ ์ค (๊ธฐ๋ณธ ๋ค์ค๋ฅ๊ทผ๋ชจ). ๊ธฐ์กด ํฐํธ ํ์ผ์ assets/fonts/์์ ์์ฒด ์ ๊ณตํ๋ฉฐ ์ธ๋ถ CDN์ ๊ธฐ๋ค๋ฆฌ์ง ์๋๋ค. ์ถ์ฒยท๋ฐฐํฌ ๋ผ์ด์ ์ค๋ assets/source/fonts253/์ ์๋ค.
์ฌ์ด๋ ํ์ผ์ assets/audio/sfx/<์ด๋ฆ>.mp3 ๋ฅผ ๋ฃ์ผ๋ฉด ํฉ์ฑ์ ๋์ ์ฌ์ (design/audio/references.md).
node --test 'tests/unit/*.test.mjs' # ๋์ฌ ํ์/๋ ์ด์์/์ถฉ๋
node tests/playtest/smoke.mjs # ํค๋๋ฆฌ์ค ์๋ ํ๋ ์ด + ์คํฌ๋ฆฐ์ท (์๋ฒ 8765 ํ์)claude-code-game-studios ํ
ํ๋ฆฟ์ด ์ค์น๋์ด ์๋ค.
์์ง์ "์์ฒด Canvas 2D / JS" ๋ก ์ค์ ๋จ (CLAUDE.md, .claude/docs/technical-preferences.md).
/brainstorm โ /design-system โ /create-stories โ /dev-story โ /code-review ์์ผ๋ก ์ฐ๋ฉด ๋๋ค.
- ๋ธ๋์น:
main์ ํญ์ ์คํ ๊ฐ๋ฅ. ๊ธฐ๋ฅ์feat/<์ด๋ฆ>, ์ปท์ ์scene/<์ด๋ฆ>๋ธ๋์น โ ์ค๋ชจํฌ ํต๊ณผ ํ main. - ์ปค๋ฐ:
type(scope): ์์ฝโfeat(dialogue),fix(world),art(sprites),scene(opening),docs,test. ํ ์ปค๋ฐ = ํ ์๋. - ์ด๋์ ๋ญ ์ฐ๋: ์์ง ๋ก์ง
src/core|world|uiยท ์ฝํ ์ธ (๋งต/๋์ฌ/์ปท์ /์บ๋ฆญํฐ)src/dataยท ๊ทธ๋ฆผ/์๋ฆฌassetsยท ๊ธฐํdesignยท ์คํฌ.claude/skills - ์ฝํ
์ธ ์ถ๊ฐ๋ ์ฝ๋ ์์ ์์ด: ์บ๋ฆญํฐ=์ํธ ๋ณํ+
characters.jsํ ์ค, ์ปท์ =cutscenes/*.js, ์ฌ์ด๋=assets/audio/sfx/<name>.mp3 - ์ปค๋ฐ ์ ์ฒดํฌ:
node --test 'tests/unit/*.test.mjs'+node tests/playtest/smoke.mjsํต๊ณผ, ์ฝ์ warn 0 - ์์ฑ๋ฌผ(
assets/sprites,assets/portraits)์ ์ปค๋ฐํ๋ค. ์๋ณธ AI ์ํธ๋assets/source/์ ๋๊ณ ๋๊ตฌ๋ก ์ฌ์์ฑ.
ํ์ฌ ํ์ญยท๊ฒฝ์ญยท๋น ๋งจ์ ๊ฑท๊ธฐ ์ด๋ฏธ์ง๋ 2026-09-10 ์ฌ์์ฑํ walk-v3๋ค. ๊ฐ 4๋ฐฉํฅร4์ด ์๋ณธ๊ณผ ํ๋กฌํํธ, ํ๋ ์ ํฌ๊ธฐ ๋ฐ ์ฐ๊ฒฐ ๋์ด๋ assets/source/walk-v3/manifest.json์ ๋ฐ๋ฅธ๋ค. ํ์ฌ ๋ฒ์ ์ ์ฌ์ถ์ถํ๋ ค๋ฉด ์๋ ๋ช
๋ น์ ์ฌ์ฉํ๋ค. --sprites-only๋ ๊ธฐ์กด ๋ํ์ฐฝ ์ด์ํ๋ฅผ ๋ฎ์ด์ฐ์ง ์๋๋ค.
๊ฒฝ์ญ์ ๊ธฐ๋ณธ ์ด๋ ์ ๋ฉด 4ํ๋ ์์ ๋๋งค๋ฅผ ํธ์ํ๊ฒ ์ํํ๋ค. ์์ฑ ์์ ์์ ๋ ์ฃผ๋ณ๋ง ๊ธฐ์กด ์๋ณธ์ ๋ฐ์ํ์ผ๋ฉฐ, ์ยท๋ท๋ชจ์ต๊ณผ ๊ฑท๋ ์์ธยท์ด์ํยท์ ํฌ ์ด๋ฏธ์ง๋ ์ ์งํ๋ค.
uv run --with pillow --with numpy -- python tools/sprites/slice_sheet.py --sprites-only assets/source/walk-v3/hyungsub.png hyungsub
uv run --with pillow --with numpy -- python tools/sprites/slice_sheet.py --sprites-only assets/source/walk-v3/gyeongsub.png gyeongsub
uv run --with pillow --with numpy -- python tools/sprites/slice_sheet.py --sprites-only assets/source/walk-v3/ppaman.png ppaman์ธ ์บ๋ฆญํฐ ๋ชจ๋ ์ ์ค๋ฆฝ ์์ฒด์ ์ ์๋ณธ ํ์ฒด A/B๋ฅผ ๋ถ์ฌ ๊ธฐ๋ณธโ๋ฐ Aโ๊ธฐ๋ณธโ๋ฐ B๋ก ๊ฑท๋๋ค. characters.js sideWalk์ ์ฐ๊ฒฐ ๋์ด๋ ํ์ญ/๊ฒฝ์ญ 76px, ๋น ๋งจ 82px๋ค. ์ฅฐํฌ์ ๊ธฐ์กด ๋ฐ ์์น ์ด๋ ๋ฐฉ์์ ์ ์งํ๋ค. ์ด์ ์๋ณธ๊ณผ ์ด์ํ๋ ๋ณด์กดํ์ผ๋ฉฐ, ์๋์ 3์ธ ํตํฉ ์ํธ ๋ช
๋ นยทํฝ์
์์ ๊ธฐ๋ก์ ๊ณผ๊ฑฐ ๋ฒ์ ๋ณต์์ฉ์ด๋ค. ๊ทธ ๋ช
๋ น์ผ๋ก ํ์ฌ v3๋ฅผ ๋ฎ์ด์ฐ์ง ์๋๋ค.
์๋ณธ 3์ธ ์ํธ์ ์ผ์ชฝโ์ค๋ฅธ์ชฝ์ **ํ์ญ(hyungsub) ยท ๊ฒฝ์ญ(gyeongsub) ยท ๋น ๋งจ(ppaman)**์ด๋ค. ๋ถํ ๋ผ์ง๋ ๊ฒ์์์ **์ฅฐํฌ(junhee)**๋ฅผ ์ฌ์ฉํ๋ค. ์๋ณธ ํ ์์(์ ๋ฉด/์ผ์ชฝ/์ค๋ฅธ์ชฝ/๋ค)๋ ๋ณํ๊ธฐ๊ฐ ์์ง ์์(์ ๋ฉด/๋ค/์ผ์ชฝ/์ค๋ฅธ์ชฝ)๋ก ์ฌ๋ฐฐ์ดํ๋ค. ์์ฑ PNG๋ฅผ ๋ค์ ๋ณํ๊ธฐ์ ๋ฃ์ง ์๋๋ค.
python3 tools/sprites/slice_sheet.py assets/source/sheet_hyungsub_gyeongsub_ppaman.png hyungsub gyeongsub ppaman
python3 tools/sprites/slice_sheet.py assets/source/sheet_junhee.png junhee
uv run --with pillow --with numpy --with pytest pytest tests/sprites -q
node tests/playtest/sprites.mjs # ์๋ฒ 8765, playwright-core ํ์. SHOT_DIR๋ก ์บก์ฒ ์์น ์ง์ ๋ฐฐ๊ฒฝ์ ์
๊ฐ์ฅ์๋ฆฌ์ ์ฐ๊ฒฐ๋ ๋ฐฐ๊ฒฝ์๋ง ํฌ๋ช
ํํ๋ค. ์ธ๊ณฝ์ ์นจ์ยท์ ํ๊ท ยทํ๋ ํธ ์์ํ๋ฅผ ํ์ง ์๋๋ค. ์๋ณธ ํ์ผ์ ๋ณด์กดํ๊ณ , ๊ธฐ์กด ์์ง์ฉ ํฌ๊ธฐ ๋ณํ์๋ ์ต๊ทผ์ ํฝ์
๋ง ์ฌ์ฉํ๋ค. ์ด์ํ๋ ๊ฐ์ ์ ๋ฉด ํ๋ ์์์ ์ถ์ถํ๋ค. ํ์ญ์ ์ธํธ๋ก ๋์ฌ๋ HS()๋ก ์ด๋ฆยท์ด์ํยท๋ชฉ์๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ , ๋ณด๋ผ๋งต ์ดํ์๋ ๋๋ ์ด์
์ผ๋ก ์ฒ๋ฆฌํ๋ค(docs/STATE.md ์ฐธ์กฐ).
๊ฑท๊ธฐ ํ๋ ์์ ๊ฐ์ ๋ฐฉํฅ์ 4์ฅ์ ๊ณตํต ์์ญ์ผ๋ก ์๋ฅด๊ณ ๊ฐ์ ์ถ์ ๊ฒฉ์์ ์ ๋ ฌํ๋ค. ํ ์ฅ์ฉ ๋ชธ์ ๋ฑ ๋ง์ถฐ ์๋ฅธ ๋ค ๋ฐ์ ๋ฐ๋ฅ์ ๋ถ์ด๋ฉด, ๋ค๋ฆฐ ๋ฐ ๋๋ฌธ์ ๋จธ๋ฆฌ๊น์ง ์์๋๋ก ํ๋ค๋ฆฐ๋ค. ์ ํ ๋๋ฆฌ๋ฅผ ์ผ๊ด ์ญ์ ํ๋ ์ฒ๋ฆฌ๋ ์ ๋ฐ์ ์๋ฅด๋ฏ๋ก ๊ธ์งํ๋ค.
์๊ฑท๊ธฐ๋ ๊ธฐ๋ณธ ์์ธยทํ์ชฝ ๋ฐ ์์ผ๋กยท๋ฐ๋์ชฝ ๋ฐ ์์ผ๋ก, ์ด 3ํฌ์ฆ๋ง ์ฌ์ฉํ๋ค. ๊ธฐ๋ณธ โ ๋ฐ A โ ๊ธฐ๋ณธ โ ๋ฐ B์ 4๋ฐ์๋ก ๋ฐ๋ณตํ๋ฉฐ ๋ฉ์ถ๋ฉด ๊ธฐ๋ณธ ์์ธ๋ก ๋์๊ฐ๋ค. ํ์ญ์ ๋ ์์ฐ์ค๋ฌ์ด ๋ณดํ์ ์ํด ์ค๋ฆฝ ์์ฒด์ ์๋ณธ ํ์ฒด A/B๋ฅผ ์ฐ๊ฒฐํ๋ค. ๋ค๋ฅธ PNG ์บ๋ฆญํฐ๋ ๊ฐ ์๋ฐฉํฅ ์ฒซ ํ๋ ์์ ์์ฒด๋ฅผ ๊ณ ์ ํ๊ณ ๋ฐ ์์ญ๋ง ์ ์ ํฝ์
๋ก ์ด๋ํ๋ค. src/data/characters.js์ sideWalk๊ฐ ์๋ณธ ํ์ฒด ํ๋ ์ยท์ฐ๊ฒฐ ๋์ด ๋๋ ๋ฐ ์์ญยท๋ณดํญ์ ์ง์ ํ๋ค. ์ต์ด ๋ก๋ ์ Canvas์ ๊ตฌ์ ๋๋ฉฐ, ๋์ฒด ๋ฌธ์ ๋ํธ ์บ๋ฆญํฐ๋ ๊ธฐ์กด TORSO + 3์ข
LEGS ์กฐํฉ์ผ๋ก ๊ฐ์ ์์๋ฅผ ๋ฐ๋ฅธ๋ค.
์ด ๊ท์น์ ํ์ญยท๊ฒฝ์ญยท๋น ๋งจยท์ฅฐํฌ์ ๋์ฒด ์บ๋ฆญํฐ ๋ชจ๋์ ์ ์ฉํ๋ค. ์๋ณธ ๋ฐ ๊ฒ์์ฉ PNG ์์ฒด๋ ๋ฐ๊พธ์ง ์์ผ๋ฉฐ ์ ๋ฉด/๋ท๋ฉด์ ๊ธฐ์กด 4ํ๋ ์๋ ๊ทธ๋๋ก๋ค. PNG๋ง ๋ค๋ฅธ ๋๊ตฌ์ ๋๊ธฐ๋ฉด ์ด ๋ฐํ์ ์กฐํฉ์ ํฌํจ๋์ง ์์ผ๋ฏ๋ก sideWalk ์ค์ ๊ณผ ๊ฒ์ ๋ก๋๋ฅผ ํจ๊ป ์ฐธ๊ณ ํ๋ค. ์ด์ ํ์ญ ์ ์ฉ walkFrameOrder ์ค์ ์ ์ด 3ํฌ์ฆ ๋ฐฉ์์ผ๋ก ๋์ฒดํ๋ค.
ํ์ญ์ ๋ชจ๋ ๋ฐฉํฅ์์ ์
์์ด ์ฝ๋ง ๋จ๊ธด๋ค. ์๋ณธ์ ๋จ์ ์๋ชจ์ต ์
์ ์ ์ง์ ํฝ์
ํธ์ง์ผ๋ก ์ ๊ฑฐํ์ผ๋ฉฐ assets/source/hyungsub-mouth-retouch.json์ ๋ฒ์๋ฅผ ๊ธฐ๋กํ๋ค. ๊ฒฝ์ญ์ ์
์ ์ ๊ฑฐ ๋์์ด ์๋๋ค.
ํ๋ฉด ํ์๋ ๋ชจ๋ํฐ DPR์ ๋ฐ์ํ์ฌ ์บ๋ฒ์ค ํฝ์
์ ์ ์๋ฐฐ๋ก ๋ง์ถ๋ค. ์ผ๋ถ ์ฐฝ ํฌ๊ธฐ์์๋ ์ฌ๋ฐฑ์ด ๋์ด๋๋ฉฐ, ์บ๋ฒ์ค๊ฐ ๋ค์ด๊ฐ์ง ์๋ ์์ ํ๋ฉด์์๋ ์ ์ฒด ํ๋ฉด ๋ง์ถค ์ถ์๋ฅผ ์ฌ์ฉํ๋ค. ์๋ณธ PNG์ ์ฌ์ฉ์ ์ง์ ์บ๋ฆญํฐ ํฌ๊ธฐ 1.43๋ฐฐ๋ ์ ์งํ๋ค. ์๋ณธ ๋ํธ ์์ฒด๋ฅผ ๋ค์ ์์ฑํ ๊ฒ์ ์๋๋ฉฐ, ๋ด๋ถ 1.43๋ฐฐ ๋น์จ์ ๋น๊ท ๋ฑ ํฝ์
๊น์ง ์ ๊ฑฐํ๋ค๋ ์๋ฏธ๋ ์๋๋ค. ์์ธํ ๋ฒ์๋ DESIGN.md ์ฐธ์กฐ.
๋ง์คํฐ์ด์ญยท์ ๋๋ผ์ญยทํ๋ฆฌ์ผ์ญยท์์ฐ์์ญ์ ๊ธฐ์กด ๊ธฐ์ต์ ๋ฐฉ ๊ฐ์ฌ๋งจ ๊ณ์ด์ ๋์ ๋ณผ, ํฐ ์ฝ, ๊ฒ์ ์๊ฒฝ, ๋ ๋๊ณผ ์ด๋์ด ํ์ฒญ์ ์ผ๊ตด์ ์ ์งํ๋ค. ๋ง์คํฐ ์ด์ ๋ค์ค ๋ ์ฆ/๊ฒ, ์ ๋๋ผ์ ์๊ด/์๋น ๋จธ๋ฆฌ, ํ๋ฆฌ์ผ์ ๋ฐ์ ์ง์กฐ ์์/์ค์นดํ, ์์ฐ์์ ๋ฟ/๊ฐ๊ธด ๋ณ๋น ์ฉ ๋ชธ์ผ๋ก ๊ตฌ๋ถํ๋ค. ๋ณ๋ ์ ์ ์ ์๋ค.
๊ฐ ์ ํฌ ์ํธ๋256ร256,128px์
2ร2์ด๋ฉฐ ์ค๋ฆฝโ์ค๋นโ๊ณต๊ฒฉ/์์ โํผ๊ฒฉ ์์, ํผ๋ฒ64,120์ด๋ค. ํ๋๋ ์ ํํ ์ค๋ฆฝ ์
128px๋ค. ๋ง์คํฐ์ด/์ ๋๋ผ ์ค๋ฆฝ ํค98px, ํ๋ฆฌ์ผ97px, ๊ฐ๊ธด ์ฉ์ธ ์์ฐ์90px๋ค. ์์ฑ ์๋ณธยท์ ํํ ํ๋กฌํํธยท๊ธฐ๊ณ์ ํฌ๋ช
ํ/์ต๊ทผ์ ํฌ๊ธฐ/๊ณตํต์ถ ์ฌํ์ assets/source/regret315/<id>/์ ๋ณด์กดํ๋ค. ๊ธฐ์กด ์ด๋ฏธ์ง์ ๋จ์ ์ด๋ฆ ๋ฐ๊พธ๊ธฐ๋ ์ฝ๋๋ก ๊ทธ๋ฆฐ ๋ชธ์ฒด๊ฐ ์๋๋ค.
ํ๋์๋ ๋ง์คํฐ์ด์ญ, ์ ๋๋ผ์ญ, ํ๋ฆฌ์ผ์ญ๋ง ๋ฐฐ์นํ๋ค. ํ๋ฆฌ์ผ์ญ์ ์์ฐ์์ญ๊ณผ ํจ๊ป ๋ฑ์ฅํ๋ ๋ํ ์กฐ์ฐ์ด๋ฉฐ ์ด3์ ํฌ, ๊ฐ๊ฐHP45๋ค. ์ธํ ์ ์ ์๋ฃ์ ์ฌ์ฉ์์ ์ต์ข ๋ฏธ์ ํ์ ์ ๊ตฌ๋ณํ๋ค. ๊ตฌ๊ฐ ๊ณ์ฝ.
./dev.sh # http://localhost:8000/editor.html- ๋ผ์ด๋ธ๋ฌ๋ฆฌ:
assets/library/deltarune/sprites/๋ธํ๋ฃฌ ์บ๋ฆญํฐยท์ค๋ธ์ ํธ ์คํ๋ผ์ดํธ 1963์ฅ(ch1~4, UTDRSpriteWeb),assets/library/deltarune/maps/์ค์ ์ง์ญ ๋งต/์คํฌ๋ฆฐ์ท 34์ฅ(Hometown ์ ์ฒด ์ง๋, ํ๊ต, ํ ๋ฆฌ์ ์ง 1ยท2์ธต, ํ๋ฆฌ๋ฐ์ด ์ ํ, ๊ตํ, ๋ ธ์ ๋ฐฉ โฆ). - ์ ๋งต: "+ ์ ๋งต" โ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ง์ญ ์ด๋ฏธ์ง์์ ๋๋๊ทธ๋ก ์๋ผ ๋ฐฐ๊ฒฝ์ผ๋ก (1440ร1080 ์คํฌ๋ฆฐ์ท์ ๋ฐฐ์จ 2.25๋ก ์๋ ์ถ์ โ ๊ฒ์ ์๋ณธ ํฌ๊ธฐ).
- ๋๊ตฌ: ๊ฑท๋ ์์ญ(W) / ๋งํ(S) / ํธ๋ฆฌ๊ฑฐ(T,
to+spawn๋ฃ์ผ๋ฉด ๋ฌธ) / ์ํธ์์ฉ(I, ์คํฌ๋ฆฝํธ ์ด๋ฆ) / ์คํฐ(P) / NPC(N) / ์ํ(B, ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๊ณ ๋ฅธ ์คํ๋ผ์ดํธ ๋ฐฐ์น, y-์ ๋ ฌยท๋งํยท์ํธ์์ฉ). - ์ ์ฅ(โS) โ
assets/maps/<id>.json(+index.json). ๊ฒ์์ด ์์ํ ๋ JSON ๋งต์ ์ฝ๋ ๋งต๋ณด๋ค ์ฐ์ ๋ก๋. โถ ํ๋ ์ด ๋ก ๋ฐ๋ก ํ์ธ. - ๋์ฌ๋ ์ฌ์ ํ
src/data/scripts.jsโ ์ํธ์์ฉ/ํธ๋ฆฌ๊ฑฐ์script์ ๊ทธ ํค๋ฅผ ์ ๋๋ค.