Project Plateau
Project Plateau๋ ๋ค ๊ฐ์ ์ ๋ฆฌํ๊ณผ ํ๋์ ์ด์์๋ ๊ณ๊ณก, ์บ ํ๋ก ๋์๊ฐ๋ ๊ธธ์ ์๋ฏธ
๐ฏ ์ค์น ์์ด ๋ธ๋ผ์ฐ์ ์์ ๋ฐ๋ก ํ๋ 5๋5 ํ ํ์ด๋ก ์ํฐ โ ๊ฑฐ์ ์ ๋ นยท์จ๋ผ์ธ ๋์ ยท๋ด์ , three.js + Node.js ๊ถ์ ์๋ฒ ๋ท์ฝ๋(์์ธกยท๋ณด๊ฐยท์ง์ฐ ๋ณด์), Blender๋ก ์ ์ฐจ ์์ฑํ ์ค๋ฆฌ์ง๋ ์ ์
๊ฒ์GitHub @jeiel85์จ๋ผ์ธ์ด์์ ๋ฏธํ์ธ
์จ ๋ณด์ จ์ด์? ํ ๋ฒ๋ง ๋๋ฌ ์ฃผ์ธ์. ๋ก๊ทธ์ธ์ ํ์ ์์ด์.
์ ์ฅ์ ์ ๋ณด๋ ์์ง ์์งํ์ง ์์์ต๋๋ค.
์์ง ๊ฐ์ง๋ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๋ค. GitHub ๋ฆด๋ฆฌ์ค๊ฐ ๋์ค๋ฉด ์ฌ๊ธฐ์ ๋ณด์ ๋๋ค.
๋ก๊ทธ์ธ ์ํ๋ฅผ ํ์ธํ๋ ์ค์ ๋๋ค.
๋๊ธ์ ๋ถ๋ฌ์ค๋ ์ค์ ๋๋ค.
๋ฉ์ด์ปค๊ฐ ์ด ์๊ฐ๋ ์์ ํ ์ค์ด ์ ๋ถ์ ๋๋ค. ๋ ์์ธํ ๋ด์ฉ์ ์ ์ฅ์ README์์ ์ฝ์ ์ ์์ต๋๋ค. ์ ์ฅ์ README โ
README ์ ์ฒด๋ฅผ ๋ถ๋ฌ์ค๋ ์ค์ ๋๋ค.
README ์ ๋ฌธ ๋ณด๊ธฐ โ์ค์น ์์ด ๋ธ๋ผ์ฐ์ ์์ ๋ฐ๋ก ํ๋ 5๋5 ํ ํ์ด๋ก ์ํฐ ์ค์ ๊ฑฐ์ ์ ์ฐจ์งํ๊ณ , ์งํค๊ณ , ๋จผ์ 100%๋ฅผ ์ฑ์ฐ๋ ํ์ด ์ด๊น๋๋ค.
๐ ๋ผ์ด๋ธ ๋ฐ๋ชจ ํ๋ ์ดํ๊ธฐ โ jeiel85.github.io/riftline ๋ฐ๋ชจ ํ์ด์ง๋ ๊ฒ์ ์๋ฒ ์์ด ๋ธ๋ผ์ฐ์ ์์์ ๋ด๊ณผ ๋์ ํฉ๋๋ค. ์น๊ตฌ์ ์จ๋ผ์ธ ๋์ ์ ์๋ฒ๋ฅผ ์ง์ ์คํํ์ธ์.
| ํ์ด๋ก | ์ฒด๋ ฅ | ๋ฌด๊ธฐ (๋ง์ฐ์ค ์ผ์ชฝ) | ์ด๋๊ธฐ (Shift) | ์คํฌ (E) | ๊ถ๊ทน๊ธฐ (Q) |
|---|---|---|---|---|---|
| ์ฝ๋์ | 450 | ์คํฌ๋ฉ ์บ๋ ยท ๊ทผ๊ฑฐ๋ฆฌ ์ฐํ | ๋์ง ยท ๋ถ๋ชํ ์ ์๊ฒ ํผํด, ๋ฐ์น๊ธฐ | ๋ฐฉ๋ฒฝ ์ฅ๊ฐ ยท 3์ด๊ฐ ๋ฐ๋ ํผํด 50% ๊ฐ์ | ์ง์ง ๊ฐํ ยท ๋์ฝ ํ ๋ด๋ ค์ฐ์ด ๊ด์ญ ํผํด, ๋์ฐ๊ธฐ |
| ๋ฒก์ค | 200 | ํ์ค ๋ผ์ดํ ยท ์ฐ์ฌ, ํค๋์ท 2๋ฐฐ | ์์ ๋์ ยท ์ด๋ ๋ฐฉํฅ ์๊ฐ ๋์ง | ์ผํฌ ์ง๋ขฐ ยท ์ ๊ทผํ ์ ์๊ฒ ํผํด, ๋ํ | ์ค๋ฒ๋๋ผ์ด๋ธ ยท 6์ด๊ฐ ์ฐ์ฌ 2๋ฐฐ, ์ด์ 30%โ, ํ์ฝ ๋ฌดํ |
| ์ ๋ฒ | 225 | ํ๋ผ์ฆ๋ง ๋ฐ์ฒ ยท ํญ๋ฐํ, ๋ก์ผ ์ ํ | ์ ํธ ๋ถ์คํธ ยท ์์ง ์์น | ๋ค์ดํ ์บ๋์คํฐ ยท 4์ด๊ฐ ํ์ผ ์ง๋ | ์ ์ฑ ๋ํ ยท ์กฐ์ค ์ง์ญ ์ฐ์ ํญ๊ฒฉ |
| ๋ฃจํฌ | 175 | ๋ ์ผ๊ฑด ยท ์ ๊ฒฉ, ํค๋์ท 2.5๋ฐฐ, ์กฐ์ค๊ฒฝ | ๊ทธ๋ํ ์ ํ ยท ๋ค์ชฝ ์๋ก ๋์ฝ | ์ผํธ๋ฆฌ ๋๋ก ยท 15์ด๊ฐ ์๋ ์ฌ๊ฒฉ | ์ ์ฐฐ ํ์ค ยท 8์ด๊ฐ ํ ์ ์ฒด ๋ฒฝ ํฌ์, ํผํด 30%โ |
| ์ | 225 | ๋ฐ์ด์ค ๊ตฌ์ฌ ยท ์๊ตฐ ์น์ / ์ ํผํด | ๊ธ๋ผ์ด๋ ์คํ ยท ๋ฏธ๋๋ฌ์ง๋ฏ ์ด๋ | ํ๋ณต ํ๋ ยท ์ฃผ๋ณ 8m ์๊ตฐ 80 ํ๋ณต | ์ฑ์ญ ยท 6์ด๊ฐ ์น์ ยทํผํด ๊ฐ์ ๋ |
๋ชจ๋ ์์น๋ shared/heroes.js ํ ๊ณณ์์ ๊ด๋ฆฌํฉ๋๋ค.
๋์ ํ๊ฐ์ด๋ฐ ํ๋ฌผ ์ผ๋. ์์ชฝ ์คํฐ๋ฃธ์์ ๋์ ์ค์ ๊ฑฐ์ A๋ฅผ ๋๊ณ ์ธ์๋๋ค. ํ ํ๋ง ๊ฑฐ์ ์์ ์์ผ๋ฉด 8์ด(์ธ์์ด ๋ง์์๋ก ๋นจ๋ผ์ง) ๋ง์ ์ ๋ นํ๊ณ , ๊ฑฐ์ ์ ๊ฐ์ง ๋์ ๊ทธ ํ ์ ์๊ฐ ์ค๋ฆ ๋๋ค. ๋จผ์ 100% ์ ๋ฟ์ผ๋ฉด ์น๋ฆฌํ์ง๋ง, ๊ทธ ์๊ฐ ์๋๊ฐ ๊ฑฐ์ ์์ ์์ผ๋ฉด 99%์์ ๋ฉ์ถฐ ์ถ๊ฐ ์๊ฐ์ด ์ด์ด์ง๋๋ค. ๊ณ ์ง๋ ํ๋ซํผยท๊ณ๋จยท๋ค๋ฆฌยท์ํ๋ฌผยท์ฒด๋ ฅ ํฉ์ด ์ข์ฐ ๋์นญ์ผ๋ก ๋์ฌ ์์ต๋๋ค.
| ์ ๋ ฅ | ๋์ | ์ ๋ ฅ | ๋์ |
|---|---|---|---|
| WASD | ์ด๋ | Shift | ์ด๋๊ธฐ |
| Space | ์ ํ | E | ์คํฌ |
| ๋ง์ฐ์ค ์ผ์ชฝ | ์ฌ๊ฒฉ | Q | ๊ถ๊ทน๊ธฐ |
| ๋ง์ฐ์ค ์ค๋ฅธ์ชฝ | ์กฐ์ค๊ฒฝ (๋ฃจํฌ) | R | ์ฌ์ฅ์ |
| Tab | ์ ์ํ | H | ํ์ด๋ก ๋ณ๊ฒฝ (์คํฐ๋ฃธยท์ฌ๋ง ์ค ์ฆ์, ๊ทธ ๋ฐ์ ๋ค์ ๋ถํ ๋) |
| Enter | ์ฑํ | Esc | ์ผ์์ ์ง (๊ฐ๋ยท์์ผ๊ฐยท์๋, ๋๊ฐ๊ธฐ) |
ํค๋ณด๋์ ๋ง์ฐ์ค๊ฐ ์๋ ๋ฐ์คํฌํฑ ๋ธ๋ผ์ฐ์ (ChromeยทEdgeยทFirefox ์ต์ )๋ฅผ ๊ธฐ์ค์ผ๋ก ํฉ๋๋ค. ํฐ์น ์กฐ์์ ์์ต๋๋ค.
| ๋ฐฉ๋ฒ | ํ ์ ์๋ ๊ฒ | ํ์ํ ๊ฒ |
|---|---|---|
| ๐ ๋ผ์ด๋ธ ๋ฐ๋ชจ | ํผ์ ๋ด๊ณผ ๋์ | ๋ธ๋ผ์ฐ์ |
| ๐ฅ๏ธ ์๋ฒ ์ง์ ์คํ | ๊ฐ์ ๋ฐฉ ์ฝ๋๋ก ์น๊ตฌ์ ์จ๋ผ์ธ ๋์ + ๋ด | Node.js 22 ์ด์ |
git clone https://github.com/jeiel85/riftline.git
cd riftline
npm install
npm start
๋ธ๋ผ์ฐ์ ์์ http://localhost:8080 ์ ์ด๊ณ ๋๋ค์๊ณผ ๋ฐฉ ์ฝ๋๋ฅผ ๋ฃ์ผ๋ฉด ์
์ฅํฉ๋๋ค. ์๋ฒ ์ฝ์์ ๊ฐ์ ๋คํธ์ํฌ์ฉ ์ฃผ์(http://192.168.x.x:8080)๋ ํจ๊ป ์ถ๋ ฅ๋๋ ์น๊ตฌ์๊ฒ ์๋ ค ์ฃผ์ธ์. ์ฒ์ ์คํํ ๋ Windows ๋ฐฉํ๋ฒฝ์ด Node.js ์ ๋คํธ์ํฌ ์ ๊ทผ์ ๋ฌผ์ผ๋ฉด ๊ฐ์ธ ๋คํธ์ํฌ๋ฅผ ํ์ฉํด์ผ ๋ค๋ฅธ PC ์์ ๋ค์ด์ฌ ์ ์์ต๋๋ค.
| ํ๊ฒฝ ๋ณ์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|
PORT | 8080 | HTTPยทWebSocket ํฌํธ |
HOST | 0.0.0.0 | ๋ฐ์ธ๋ฉ ์ฃผ์(127.0.0.1 ์ด๋ฉด ์ด PC ์์๋ง ์ ์) |
์๋ฒ ํ๋๊ฐ ์ ์ ํ์ผ๊ณผ WebSocket(/ws)์ ๊ฐ์ ํฌํธ๋ก ์ ๊ณตํ๋ฏ๋ก ์๋ ์ค ํ๋๋ฉด ๋ฉ๋๋ค.
8080 ํฌํธ๋ฅผ ์ด๊ณ http://<๊ณต์ธ IP>:8080 ์ ์๋ ค ์ค๋๋ค.wss:// ๋ก ์ ์ํฉ๋๋ค.[!WARNING] ์๋ฒ์๋ ๊ณ์ ยท์ธ์ฆ์ด ์์ด์ ๋ฐฉ ์ฝ๋๋ง ์๋ฉด ๋๊ตฌ๋ ๋ค์ด์ฌ ์ ์์ต๋๋ค. ๊ณต๊ฐ ์ธํฐ๋ท์ ์ด๊ธฐ ์ ์ ํ๋๋ ํ๋ณด ์ด์๋ฅผ ํ์ธํ์ธ์.
flowchart LR
subgraph Browser["๋ธ๋ผ์ฐ์ ยท three.js"]
UI["main.js<br/>๋ฉ๋ด ยท ํ์ด๋ก ์ ํ"] --> G["game.js<br/>์์ธก ยท ๋ณด๊ฐ ยท ๋ ๋"]
G <--> N["net.js"]
end
N <-->|"WebSocket /ws<br/>์จ๋ผ์ธ ๋์ "| S["Node ์๋ฒ<br/>server/index.js"]
N <-->|"postMessage<br/>์คํ๋ผ์ธ ๋ด์ "| W["Web Worker<br/>local-server.js"]
S --> L["Lobby ยท Room<br/>60Hz ๊ถ์ ์๋ฎฌ๋ ์ด์
<br/>๋ด AI ยท A* ๊ธธ์ฐพ๊ธฐ"]
W --> L
L -.-> SH[("shared/<br/>๋ฌผ๋ฆฌ ยท ํ์ ยท ๋งต ยท ํ์ด๋ก")]
G -.-> SH
LobbyยทRoom ์ฝ๋๋ฅผ Web Worker ์์ ๋๋ฆฌ๊ณ , WebSocket ๋์ postMessage ๋ก ๊ฐ์ ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ์ต๋๋ค.server/ index.js(HTTPยทWebSocket) lobby.js(๋ฐฉยท์ ์) room.js(๊ถ์ ์๋ฎฌ๋ ์ด์
) bot.js(๋ด AI) nav.js(๊ธธ์ฐพ๊ธฐ)
shared/ ์๋ฒยทํด๋ผ์ด์ธํธ ๊ณต์ฉ: ์์, ํ์ด๋ก, ๋งต ๋ฐ์ดํฐ, ์ด๋ ๋ฌผ๋ฆฌ, ๊ด์ ํ์ , ํ๋กํ ์ฝ ๊ฒ์ฆ
client/ index.html, main.js(ํ๋ฉด ํ๋ฆ) net.js game.js world.js effects.js characters.js hud.js audio.js local-server.js
assets/ blender/build_assets.py(์ ์
์์ฑ) blender/render_promo.py(README ์ด๋ฏธ์ง) models/*.glb
tools/ gen-map.mjs build-assets.mjs check-assets.mjs smoke-test.mjs build-pages.mjs
test/ ๋ฌผ๋ฆฌยทํ์ ยท๋ฐฉยท๋ก๋น ๋จ์ ํ
์คํธ
docs/ ASSETS.md(์ ์
๊ท๊ฒฉ) images/
์ค๊ณ ๊ฒฐ์ ๊ณผ ๊ทธ ์ด์ ๋ DECISIONS.md ์ ์์ต๋๋ค.
| ๋ช ๋ น | ํ๋ ์ผ |
|---|---|
npm test | ๋ฌผ๋ฆฌยทํ์ ยท๋ฐฉยท๋ก๋น ๋จ์ ํ ์คํธ |
npm run smoke | ์ค์ ์๋ฒ๋ฅผ ๋์ WebSocket ํด๋ผ์ด์ธํธ๋ก ์ ์ยท์ ๋ ฅยท์ฑํ ยท์ ์ฑ ์ ๋ ฅยท์ ์ ํ์ผ ๊ฒฝ๋ก ํ์ธ |
npm run check:assets | GLB ์ ์ ์ด ๊ท๊ฒฉ(๋ ธ๋ ์ด๋ฆยท๋ฐ์ด๋ฉยท์ผ๊ฐํ ์)์ ์งํค๋์ง ๊ฒ์ฌ |
npm run build:pages | GitHub Pages ์ฉ ์ ์ ๋น๋(dist/). main ์ ํธ์ํ๋ฉด CI ๊ฐ ์๋ ๋ฐฐํฌ |
npm run gen:map | ๋งต ๋ ์ด์์ tools/gen-map.mjs โ shared/map-data.json |
npm run build:assets | Blender 5.2 ํค๋๋ฆฌ์ค๋ก GLB ๋ค์ ์์ฑ(BLENDER_PATH ๋ก ๊ฒฝ๋ก ์ง์ ๊ฐ๋ฅ) |
blender -b --factory-startup --python assets/blender/render_promo.py | README ๋ฐฐ๋ยทํ์ด๋ก ์นด๋ยท๋งต ์ด๋ฏธ์ง(docs/images/) ๋ค์ ๋ ๋ |
์ถฉ๋ ํ์ ๊ณผ Blender ๋น์ฃผ์ผ์ ๋ชจ๋ shared/map-data.json ์ ๋ฐ๋ฆ
๋๋ค. ์ฃผ์์ ?debug ๋ฅผ ๋ถ์ด๋ฉด ๋ธ๋ผ์ฐ์ ์ฝ์์์ window.riftline ์ผ๋ก ๊ฒ์ ์ํ(game, input, net)๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
MIT. ํ์ด๋กยท๋งตยท๋ก๊ณ ๋ฅผ ํฌํจํ ๋ชจ๋ ์บ๋ฆญํฐ์ ์ ์ ์ ์ด ํ๋ก์ ํธ๋ฅผ ์ํด ์๋ก ๋ง๋ ์ค๋ฆฌ์ง๋ ๋์์ธ์ ๋๋ค. ๊ธฐ์กด ์์ฉ ๊ฒ์์ ์บ๋ฆญํฐยท๋ช ์นญยท๋์์ธ์ ์ฐ์ง ์์ต๋๋ค.