"○○ 게임 만들어줘" 요청이 들어오면 이 저장소의 도구로 엔트리 편집기에서 바로 실행되는
.ent 파일을 생성한다. 이 문서는 그 자동화 파이프라인을 설명한다.
자연어 요청 → DSL
.mjs(또는 JSON) spec →.ent(tar.gz) → 편집기에서 로드·실행
| 분류 | 섹션 |
|---|---|
| AI 에이전트 지침 | CLAUDE.md — "○○ 만들어줘" 요청 시 표준 절차·검증 사다리·절대 규칙 |
| 환경 구성·설치 | 🚀 빠른 시작 · 엔트리 원본(entryjs) — 순정 + 호스트 적응 · 처음 설치(상세) · 명령어 치트시트 |
| 게임 제작 파이프라인 | 무엇을 하는가 · 파이프라인 · ① 게임 설계 · ② spec 작성(DSL/JSON) · ③ make-ent 내부 · ⑤ 검증 |
| 레퍼런스·문제해결 | 실전 예시 카탈로그 · 문제 발생 시 · 외부 사용자용 요약 |
| 심화 위키 | knowledge/README.md — .ent 포맷·블록·런타임 함정·디자인 패턴 정본 |
새로 시작한다면:
🚀 빠른 시작→엔트리 원본(entryjs)순으로 읽으면 환경이 선다. 게임을 만든다면:파이프라인이후를 따라간다.
"이 저장소로 ○○ 게임 만들어줘" 를 받은 사람(또는 AI)이 처음 해야 할 것. 우리가 작업한 환경(오프라인 엔트리 편집기 + 헤드리스 검증)을 그대로 재현한다.
- Node 18+, git (git 은 entryjs 등 자동 클론에 필요)
- 헤드리스 테스트(
verify:runtime/test:e2e)를 돌리려면 Playwright Chromium:npx playwright install chromium
git clone https://github.com/205sla/entry-vibe-coding
cd entry-vibe-coding
npm install
npm run setup # 엔트리 원본·외부 모듈·vendor 자동 구성 (아래 표) — 한 번만, idempotent
npm start # → http://localhost:3000http://localhost:3000 이 곧 엔트리 "만들기" 페이지(오프라인 편집기) — 생성한 .ent 를
로드·실행(▶)·수정·저장한다. 헤드리스 검증 스크립트도 이 서버에 붙어 동작한다.
이 저장소에는 엔트리 원본 엔진이 포함돼 있지 않다. setup 이 아래를 끌어와 public/lib/ 를 채운다
(scripts/setup.mjs). 어떤 것도 컴파일하지 않는다 — 전부 prebuilt 아티팩트.
| 의존성 | 콜드 클론에서의 출처 | setup 동작 |
|---|---|---|
| entryjs dist·extern·images (엔진·만들기 페이지) | npm @entrylabs/entry (prebuilt dist 포함, 버전 핀) |
형제 ../entryjs 에 빌드된 dist 가 있으면 그걸 사용(개발 머신), 없으면 npm 아티팩트 자동 다운로드(~87MB) → dist·extern·images 복사. webpack 빌드는 어떤 경우에도 불필요 |
entryjs 소스 (src/) |
github.com/entrylabs/entryjs | 선택사항 — node scripts/setup.mjs --with-entryjs-src 로만 클론. build:registry·소스 ground-truth 인용에만 필요, 편집기 동작엔 불필요 |
| entry-tool | entrylabs 공개 repo | dist/develop 브랜치 자동 클론 (실패 시 정적 파일 다운로드 폴백) |
| entry-paint · entry-lms · sound-editor · legacy-video | playentry.org · code.205.kr 정적 서빙 | 빌드가 공개 repo/npm 에 없는 패키지들 — 형제 ../MYentry 있으면 링크, 없으면 편집기가 로드하는 빌드 파일만 자동 다운로드 (legacy-video 의 GitHub repo 는 소스만 있어 클론으로는 부팅 불가) |
| vendor (jQuery·jQuery-UI·lodash·CreateJS·Velocity·CodeMirror·React·socket.io) | npm | 임시 설치 후 dist 파일만 public/lib/vendor/ 로 복사 + preload-js 패치 |
| mascot 이미지·커서 | repo 에 커밋됨 | 형제 ../MYentry 있으면 최신으로 갱신만 |
✅ 순수 외부 클론(형제 저장소 없음)도 편집기 완전 부팅 + 헤드리스 검증까지 동작한다.
필요한 건 인터넷 연결뿐. setup 마지막의 verify editor boot files 단계가 부팅 필수 파일
전부를 점검하므로, 이 단계가 OK 면 환경은 완성이다.
node tools/make-ent.mjs tests/fixtures/spec-bounce-ball.mjs --check # ① 정적 검증 < 1초
node tools/make-ent.mjs tests/fixtures/spec-bounce-ball.mjs --out tests/fixtures/x.ent # ② 빌드
node tools/run-all-verify.mjs --filter bounce-ball # ③ 헤드리스 런타임 검증
# 전체: npm run verify (smoke + links + e2e + runtime)
# ⚠️ PowerShell 에선 `npm run x -- --flag` 의 `--` 가 삼켜진다 — 인자 필요하면 node 직접 호출편집기에서 눈으로 보려면 npm start 후 브라우저에서 생성한 .ent 를 불러온다. 상세 파이프라인·검증 레이어는 아래에.
엔트리 엔진(entrylabs/entryjs) 은 순정을 그대로 쓴다 — 엔진
소스·dist 를 고치지 않으며, 직접 빌드하지도 않는다. dist 는 entrylabs 가 npm 에 배포하는
@entrylabs/entry 공식 prebuilt 아티팩트 (또는 개발 머신의 형제 ../entryjs 빌드) 를 그대로 복사한다.
순정을 그대로 드롭인하면 오프라인 부팅·.ent 로드·헤드리스 테스트가 안 되므로, 엔진은 건드리지 않고
호스트 레이어(이 저장소)에서만 아래 적응을 적용한다. 새 entryjs 로 교체하거나 직접 세팅할 때
아래 A·B 지점만 맞추면 .ent 생성·테스트가 돌아간다.
| 적응 | 위치 | 왜 필요한가 |
|---|---|---|
window.PUBLIC_PATH_FOR_ENTRYJS = 'lib/entry-js/dist/' |
public/js/editor.js |
entry.min.js 가 async chunk(522.*.js 등) 를 찾는 경로 지정 |
Entry.init(el, { type:'workspace', hardwareEnable:false, textCodingEnable:false, libDir:'', entryDir:'' }) |
editor.js initEntry |
HW 동반앱(localhost:23518 WebSocket) 연결 시도 차단(콘솔 에러 폭주 방지) + 텍스트코딩 비활성 |
SoundJS _parsePath 방어 래핑 |
editor.js patchCreateJSSoundParsePath |
npm soundjs 1.x 가 src=undefined 사운드에서 toString throw(실제 playentry 0.6.0 은 무시) → 가드 |
preload-js 말미 ;module.exports=window.createjs; 제거 |
scripts/setup.mjs patchPreloadjs |
브라우저에서 module is not defined 방지 |
| 적응 | 위치 | 왜 필요한가 |
|---|---|---|
.ent 로드 전 Entry.clearProject() 선행 후 Entry.loadProject(json) |
editor.js loadEntFile / tools/lib/editor-harness.mjs |
loadProject 는 덮어쓰지 않고 append → starter 봇 잔존 + scene id 충돌 → addChildAt(undefined) crash 방지. (부수효과: scene id 자유) |
/api/load(.ent→project JSON) · /api/export(project→.ent) · /api/ent-asset/:sid/* |
server.js |
편집기 ↔ 파일 왕복, tar 내부 에셋 서빙 |
window.__myentryReady Promise (Entry 준비 신호) |
editor.js | 헤드리스 테스트가 "Entry 로드 완료" 를 await |
키 이벤트 document + event.code, 클릭 Entry.dispatchEvent('entityClick', e) 로 주입 |
tools/lib/verify-harness.mjs |
playwright 로 실제 입력 시뮬 → 게임 플레이 검증 |
⚠️ 위 적응은 전부 호스트 코드(editor.js · setup.mjs · server.js · tools/lib) — entryjs 엔진 소스 패치는 0 (검증:upstream/entryjs의 src 와dist/entry.min.js가 순정과 동일). entryjs 버전 업 시 이 A·B 지점만 확인하면 된다. 향후 어떤 테스트가 엔진 소스 패치를 요구하면 →scripts/setup.mjs패치 단계로 추가하고 이 표에 순정 대비 diff 한 줄 기록.
| 구성요소 | 역할 |
|---|---|
tools/make-ent.mjs |
핵심 생성기 — spec (DSL .mjs 또는 JSON) 을 받아 .ent 파일을 만든다. --check 로 빌드 없이 < 1 초 정적 검증 |
tools/lib/spec-dsl.mjs |
DSL — setVar, when.run, obj, if_, repeat 등 fluent helper. 8 단 중첩 JSON 회피, paramCount/슬롯 wrap 자동 |
tools/lib/sprite-gen.mjs |
SVG primitive 생성 — circle, rect, ring, regularPolygon, star, heart, shadedBall 등 inline SVG 생성 |
tools/lib/game-assets.mjs |
정적 자산 카탈로그 — assets('ball-blue') 등 의미 있는 이름 → fileurl. 콘텐츠 해시 dedup |
tools/block-registry.json |
274 개 엔트리 블록의 type·params·statements 메타데이터 (entryjs 소스에서 AST 자동 추출) |
public/ |
오프라인 엔트리 편집기 — 생성된 .ent를 로드·수정·저장 |
server.js |
편집기 백엔드 (/api/load, /api/export, /api/ent-asset/:sid/*) |
knowledge/ |
.ent 포맷·블록·편집기·런타임 quirks·디자인 패턴·해결한 함정 위키 (README) |
tests/fixtures/spec-*.{mjs,json} |
21 개 예시 spec (empty ~ frontier-guard 디펜스 게임). DSL 우선 권장 |
tests/smoke.test.js |
23 fixture 의 구조 검증 (tar/JSON 파싱, 블록 type 유효성, 자산 일치) |
tools/verify-*.mjs |
14 fixture 의 런타임 동작 검증 (playwright + chromium): 변수 변화, 클론 카운트, 픽셀 색상, 실제 click hit-test |
tools/run-all-verify.mjs |
모든 verify 일괄 실행 |
tests/e2e.spec.js |
편집기 부트 + 모든 fixture 로드 시 console error 0 확인 |
사용자 자연어 요청
│
▼
┌────────────────────┐
│ ① 게임 설계 │ 변수 / 오브젝트 / 스크립트 구조 결정
│ (Claude 작업) │ → knowledge/ 참조해 패턴 고름
└────────────────────┘ → 비슷한 fixture 부터 복제 시작
│
▼
┌────────────────────┐
│ ② DSL spec 작성 │ tests/fixtures/spec-<name>.mjs (DSL 권장)
│ (.mjs 우선) │ setVar(...), when.run(), obj(...), if_(...) 등
└────────────────────┘ → JSON spec 도 가능 (legacy fixture 들)
│
▼
┌────────────────────┐
│ ③ --check 정적 검증 │ node tools/make-ent.mjs spec.mjs --check
│ (< 1 초) │ paramCount, 슬롯 wrap, unknown type 즉시 에러
└────────────────────┘ → 통과하면 빌드, 실패하면 ② 로
│
▼
┌────────────────────┐
│ ④ make-ent 빌드 │ node tools/make-ent.mjs spec.mjs --out out.ent
│ → .ent 파일 │ · 이미지 rasterize (sharp), 콘텐츠 해시 dedup
└────────────────────┘ · block params 를 Entry JSON shape 로 정규화
│ · script 필드 JSON.stringify (이중 직렬화)
│ · tar(ustar portable) + gzip(memLevel: 6)
▼
┌────────────────────┐
│ ⑤ 다층 검증 │ smoke: tar 파싱 / 블록 type 유효성 (5 초)
│ │ e2e: 편집기 부트 + console error 0
│ │ verify-runtime: 실제 게임 플레이 (playwright)
│ │ - 변수 변화, 클론 카운트, 픽셀 색상
│ │ - dispatchEvent (핸들러 로직) + mouse.click (hit-test)
│ │ screenshot: 시각 확인 (선택)
└────────────────────┘
│
▼
사용자에게 .ent 파일 경로 + 설명 전달
각 단계에서 참고하는 지식 문서 (knowledge/README.md 의 canonical matrix 도 참조):
| 단계 | 참고 |
|---|---|
| ① 설계 | knowledge/04-script-and-blocks.md — 카테고리별 블록·params + 설계 패턴 (클론, direction-as-id, 빌드 슬롯, 빔 시각화 등 25+ 패턴), knowledge/07-runtime-quirks.md — Entry 엔진 함정 (60fps 틱, message fan-out, pixelPerfect, 좌표 변환 등) |
| ② spec 작성 | DSL: tools/lib/spec-dsl.mjs — fluent helpers + JSDoc. JSON: knowledge/02-project-json.md, knowledge/03-objects-and-assets.md |
| ③ --check | make-ent.mjs 의 normalizeBlock + registry (tools/block-registry.json) 기반 즉시 검증 |
| ④ 빌드 | knowledge/01-binary-format.md — tar/gzip 포맷, knowledge/03-objects-and-assets.md — 자산 dedup |
| ⑤ 검증 | 실패 시 knowledge/lessons.md (과거 해결 이슈 1줄 회귀 가드) + knowledge/07-runtime-quirks.md (엔진 동작) |
요청을 받으면 다음 순서로 설계한다:
- 싱글 플레이어: 1 오브젝트만 (예:
circle-recursive,healthbar-brush) - 플레이어 + 적: 2 오브젝트 (예:
chase-hp) - 플레이어 + 생성되는 장애물: 원본 + 클론 (예:
bullethell) — 원본visible: false로 숨기고create_clone("self")+when_clone_start - 진행자만 (키 입력 + 내러티브): 1 오브젝트 + 여러 thread (예:
memory-ranking)
- 상태: HP, 점수, 레벨, "듣는중" 같은 플래그
- 자료구조: 리스트 — 패턴 저장, 랭킹, 인벤토리
- 공유 리스트 (
isCloud: true): 랭킹처럼 여러 세션 공유하고 싶을 때
한 오브젝트 안에서 병렬 실행되는 thread:
when_run_button_click— ▶ 버튼 시 1회when_some_key_pressed(키코드)— 키 눌릴 때마다 새 threadwhen_object_click— 오브젝트 클릭when_message_cast(msg_id)— 신호 받을 때when_clone_start— 클론 생성 시
원칙: 블로킹(wait_second, ask_and_wait, repeat_inf)이 포함된 로직은 독립 thread로 분리.
예: HP 깎임 + 무적 프레임(wait_second(0.1))을 이동 loop과 같은 thread에 두면 이동이 멈춘다 →
별도 thread로.
tools/block-registry.json에서 이름으로 검색해 param 구조 확인:
node -e "const r=require('./tools/block-registry.json').blocks;
console.log(JSON.stringify(r['move_direction'], null, 2))"자주 쓰는 블록은 knowledge/04-script-and-blocks.md에 카테고리별로 정리돼 있다.
신규 fixture 는 DSL 우선. 8 단 중첩 JSON 회피 + 슬롯 wrap 자동 + IDE 자동완성 + 5× 코드 압축 (Fibonacci 기준 163 줄 → 76 줄).
// tests/fixtures/spec-my-game.mjs
import {
when, repeat, if_, cmp, getVar, setVar, calc, wait,
obj, locateXY, moveX, sendMessage,
scene as makeScene,
} from '../../tools/lib/spec-dsl.mjs';
import { assets } from '../../tools/lib/game-assets.mjs';
export default {
name: '내 게임',
scenes: [ makeScene('play', '게임 화면') ],
variables: [{ id: 'hp', name: '체력', value: '5', visible: true, x: -210, y: 110 }],
objects: [
obj('player', '플레이어', {
scene: 'play',
picture: assets('ball-blue'),
entity: { x: 0, y: 0, scaleX: 0.4, scaleY: 0.4, direction: 90 },
script: [
when.sceneStart(),
repeat.inf([
moveX(2),
if_(cmp(getVar('hp'), '<=', 0), [
sendMessage('lose'),
]),
]),
],
}),
],
};DSL 의 모든 helper 는 tools/lib/spec-dsl.mjs 상단 주석 + JSDoc 으로 문서화. SVG 그래픽이 필요하면 sprite-gen.mjs 의 circle, rect, ring, star, heart, shadedBall 등 inline 생성 가능.
검증된 DSL fixture (작동 reference):
spec-fibonacci.mjs— 사용자 정의 함수 (fn.value,fn.normal)spec-name-loop.mjs— textBox + ask_and_wait 루프spec-bounce-ball.mjs— Breakout (패들·공·벽돌·클론)spec-fruit-hunt.mjs— 3×3 클론 grid + 붓 타이머spec-bullet-circle.mjs— 3 장면 + 클라우드 랭킹 + 함수spec-frontier-guard.mjs— 종합 reference: 디펜스 게임 (다중 scene, 클론 슬롯, 메뉴, 골드, 업그레이드, brush 빔, multi-type 적, 데이터 주도 웨이브)
spec-frontier-guard.mjs 는 25+ 패턴 + 8 함정 회피가 한 spec 에 모여 있어 새 게임 시작 시 가장 좋은 출발점.
기존 JSON spec fixture 들도 여전히 작동. JSON 직접 작성 시:
| spec에 쓰면 | .ent에 들어가는 형태 |
|---|---|
params: [10] |
params: [{type:"number", params:["10"]}] |
params: ["hi"] |
params: [{type:"text", params:["hi"]}] |
params: [true] |
params: [{type:"True", params:[]}] |
params: [{"__field":"mouse"}] |
params: ["mouse"] ← bare string (Dropdown 필드용) |
fileurl: "/images/foo.svg" |
SVG → PNG rasterize → temp/aa/bb/image/<hash>.png 번들 |
scenes 생략 |
[{id: <shortId>, name: "장면 1"}] 자동 (랜덤 4자 id) |
interface 생략 |
{canvasWidth: 640, menuWidth: 280, object: <첫 object id>} 자동 |
블록의 params 슬롯은 두 종류:
- Block 슬롯 (값을 반환하는 중첩 블록 받음):
{"type":"number","params":["10"]}또는 다른 블록 - Field 슬롯 (드롭다운 문자열 바로 받음):
"mouse","player","EQUAL","speak"등
Field 슬롯에 {"type":"text",...}로 감싸면 엔진이 "text 블록의 결과값"으로 취급해서
드롭다운 매칭 실패. 반드시 {"__field":"<값>"} sentinel로 감싸 wrapParam이 언래핑하게.
tools/make-ent.mjs 주요 단계:
resolveLocalPath:{fileurl: "/images/..."}→public/images/...절대경로bundleOne(absPath, kind): 이미지면sharp(buf).png()로 rasterize, 96px 썸네일 생성, tar payload 추가normalizeBlock: spec block의 params 정규화. leaf 블록(number/text/get_variable등)은 재귀하지 않고 그대로 반환 (이중 래핑 방지)wrapParam: primitive 값을 리터럴 블록으로 감싸거나__fieldsentinel 언래핑buildProject(spec): 최상위 project 객체 조립 — scenes, variables, objects, interface, learningtarHeader+makeTar: ustar portable 포맷 (mode 000755/000644, uid/gid/mtime NUL 등). 공식 npmtar.c({portable:true})와 동일 바이트 출력zlib.gzipSync(tar, {memLevel: 6}): 공식 엔트리 문서 명시 설정
자산 해시는 공식 알고리즘 uid(8) + puid.generate() (npm uid + puid 패키지).
4 레이어로 누적 검증. 빠른 → 느린 순. LLM 의 자기 수정 루프 핵심.
- 모든 블록 type 이
block-registry.json에 존재 params.length === paramCount(registry 와 일치)- 슬롯 wrap 검증 (Field 슬롯에 Block 들어가는지 등)
빌드 없이 스펙 작성 직후 즉시 실행. LLM 이 수십 번 반복해도 부담 없음.
각 .ent fixture (총 23) 에 대해:
- gunzip + tar 파싱 성공
temp/project.json존재 + JSON 파싱- 필수 top-level 키 (
objects,scenes,variables) - 모든
object.script가 문자열 + 파싱 가능한 2 차원 배열 - 모든 블록
type이block-registry.json에 존재 (primitive 화이트리스트 예외) - 모든 picture
fileurl이 tar 안 또는 public/ 아래에 실재 selectedPictureId가 그 object 의 pictures[*].id 와 매칭object.scene이 scenes[*].id 와 매칭
- 편집기 부트스트랩 시
pageErrors === [] && consoleErrors === [], 외부 요청 0 - 각 fixture 를
/api/load→Entry.clearProject()→Entry.loadProject(json)로 로드 Entry.container.objects_.length > 0,Entry.scene.scenes_.length > 0- 2 초 대기 후
_warningBlock가 한 개도 없는지 (블록 type·params 형태가 유효) - round-trip export (Entry →
/api/export→ gzip 마법 숫자 확인)
각 게임 fixture 에 대응하는 tools/verify-*.mjs 스크립트 (총 14) 가 playwright + headless chromium 으로 실제 게임 플레이 검증:
- 변수 / 리스트 변화 (점수 증가, 클론 카운트, hp drop 등)
- 메시지 발화 + 핸들러 동작 (race condition 회귀 가드)
- 픽셀 색상 검증 (
findColoredPixels— 빔, 깜빡임, 그래픽) - 클릭 hit-test —
Entry.dispatchEvent('entityClick', e)(핸들러 로직) +page.mouse.click(px, py)(pixel hit-test) - 좌표 변환 검증 (stage 논리 480×270 ↔ canvas 렌더 픽셀)
tools/run-all-verify.mjs 가 전체 일괄 실행 + 서버 자동 라이프사이클. --filter <name> 로 일부만.
knowledge/ 의 13 markdown 파일 간 cross-ref 검증 (300+ 링크). 깨진 앵커/경로 잡기.
npm run verify # smoke + verify:links + e2e + verify:runtime 순차tools/screenshot-*.mjs 스타일: fixture 로드 후 단계별 스크린샷 + 변수/리스트 dump 출력. 디버깅용.
tests/fixtures/ 의 spec/.ent 짝 (21 spec, 23 fixture). 전체 색인은 tests/fixtures/README.md 참조.
| fixture | 시연 패턴 |
|---|---|
empty |
최소 자가완결 .ent |
move / variable |
기본 블록 + 변수 + 반복 |
chase-hp |
방향키 + 추적 + reach_something 충돌 + HP + 게임 오버 |
memory-ranking |
message_cast + 공유 리스트 + ask_and_wait + insertion sort |
platformer |
시차 스크롤 + reach_something 발판 충돌 |
bullethell |
3 장면 게임 (메뉴 → 플레이 → 결과) + 클론 탄막 + 메시지 |
healthbar-brush |
붓 + slide 변수 + 매 프레임 erase+redraw |
circle-recursive |
재귀로 매 프레임 60-segment 원 그리기 + 방향키 |
recursion |
꼬리재귀 vs 반복 성능 비교 + 지수재귀 budget |
repeat-timing |
60fps 암묵 틱 측정 (180회 = 3.0s) |
scene-custom-id |
scene id 가 "7dwq" 아니어도 OK 회귀 가드 |
| fixture | 시연 패턴 |
|---|---|
spec-fibonacci.mjs |
사용자 정의 함수 (function_create_value), 꼬리 재귀 |
spec-name-loop.mjs |
textBox + ask_and_wait 반복 (이름 입력 → 출력) |
spec-textbox-click.mjs |
textBox 클릭 영역 회귀 가드 (투명 vs hex bgColor) |
spec-media-art.mjs |
생김새 17 블록 종합 — 효과·모양·크기·뒤집기·z-order 동시 |
spec-bounce-ball.mjs |
Breakout (패들·공·18 벽돌 클론 + 메시지 충돌 반사) |
spec-fruit-hunt.mjs |
3×3 클론 grid + 붓 타이머 + 점수/콤보/레벨 + 좌표로 클론 정체 판정 |
spec-bullet-circle.mjs |
3 장면 + 클라우드 랭킹 + 함수 + 동적 배경 (10 객체 종합 데모) |
spec-frontier-guard.mjs |
디펜스 게임 종합 reference — 다중 scene + 빌드 슬롯 + 골드 + 업그레이드 + brush 빔 + multi-type 적 + splash AOE + 데이터 주도 웨이브 + direction-as-id + 25+ 패턴 + 8 함정 회피 |
신규 게임은 가장 비슷한 것부터 복사해 수정하면 빠르다. 복합 게임은 spec-frontier-guard.mjs 가 좋은 출발점.
설치 명령은 위 🚀 빠른 시작 참고. setup (scripts/setup.mjs) 은 재실행 안전(idempotent):
- entryjs dist·extern·images — 형제
../entryjs에 빌드된 dist 가 있으면 그걸 복사(개발 머신). 없으면 npm@entrylabs/entry(버전 핀, setup.mjs 의ENTRY_NPM_VERSION_DEFAULT) 를npm pack으로 받아.setup-cache/에 풀고 복사. 소스만 있는../entryjs는 빌드 대상이 아니라 무시 대상 — 이때도 npm 아티팩트를 쓴다. - entryjs 소스 (선택) —
node scripts/setup.mjs --with-entryjs-src일 때만.setup-cache/entryjs로 클론 후../entryjs링크.build:registry·knowledge 문서의 소스 인용(../entryjs/src/...)에만 필요. - External modules (entry-tool / entry-paint / entry-lms / sound-editor / legacy-video) —
../MYentry/public/lib/*우선 링크 → entry-tool·legacy-video 는 공개 GitHubdist/develop클론 → entry-paint·entry-lms·sound-editor 는 playentry.org / code.205.kr 정적 파일 다운로드 (편집기가 로드하는 빌드 파일만:entry-paint.js,app.js+app.css,sound-editor.js). - Mascot 이미지 + 커서 — repo 에 커밋돼 있음. 형제
../MYentry있으면 최신으로 덮어쓰기만. - Vendor npm 패키지 — jQuery / jQuery-UI / lodash / Velocity / CodeMirror / React / CreateJS 등을
임시 설치 후 dist 파일만
public/lib/vendor/로. - preload-js 패치 —
;module.exports=window.createjs;제거 (module is not defined방지). - 부팅 파일 검사 —
editor.html이 로드하는 필수 파일 전부 존재 확인. 여기가 OK 면 부팅 보장.
벤더만 스킵: node scripts/setup.mjs --skip-vendor. entryjs 버전 핀을 올렸으면
node scripts/setup.mjs --with-entryjs-src 후 npm run build:registry 로 레지스트리 재생성.
(node scripts/setup.mjs 직접 호출 — PowerShell 은 npm run setup -- --flag 의 인자를 삼킨다.)
verify:runtime·test:e2e 는 Playwright + Chromium 으로 실제 편집기를 띄워 검증:
npx playwright install chromium # 한 번만순수 외부 클론(형제 저장소 없음)도 npm install + npm run setup 만으로 편집기 완전 부팅 +
4 레이어 검증 전부 동작한다. 전제와 한계:
- 인터넷 연결 — setup 이 npm 아티팩트(~87MB)·entry-tool GitHub·playentry.org/code.205.kr
정적 파일을 받는다. 한 번 받으면
.setup-cache/에 남아 재실행은 오프라인도 가능. - entryjs 버전 핀 — setup 은
@entrylabs/entry를 고정 버전으로 받는다(재현성). 핀을 올려 블록 API 가 어긋나면node scripts/setup.mjs --with-entryjs-src후npm run build:registry. - Playwright Chromium — 헤드리스 테스트용 (위
npx playwright install chromium). - 미지원 — AI Learning · 하드웨어 · 확장 블록은 playentry.org 서버 필요 → 이 편집기에선 비활성.
- AI 에이전트로 작업한다면 — CLAUDE.md 의 표준 절차·검증 사다리를 따른다.
# 의존성
npm install
npm run setup # prebuilt 아티팩트 자동 구성 — 빌드 없음
node scripts/setup.mjs --with-entryjs-src # + entryjs 소스 클론 (build:registry 용)
npm run build:registry # entryjs 업데이트 시 블록 레지스트리 재생성 (소스 필요)
npm run build:assets # public/images/game/*.svg + manifest.json 재생성
# 개발 서버 (편집기)
npm start # http://localhost:3000
# spec → .ent
node tools/make-ent.mjs tests/fixtures/spec-foo.mjs --check # 정적 검증만 (< 1 초)
node tools/make-ent.mjs tests/fixtures/spec-foo.mjs --out tests/fixtures/foo.ent
# 검증 (4 레이어)
npm run test:smoke # Node 스모크 (~ 5 초, 23 fixture)
npm run test:e2e # Playwright e2e (~ 30 초)
npm run verify:runtime # playwright + chromium 게임 플레이 (~ 4 분, 14 fixture)
npm run verify:links # knowledge md 간 링크 검증 (< 1 초)
npm run verify # 위 4 개 모두
# 일부만
node tools/run-all-verify.mjs --filter frontier-guard --keep-server
node tools/verify-frontier-guard.mjs
# Spec 트리 보기 (디버깅)
node tools/show-spec.mjs tests/fixtures/spec-foo.mjs [--object id] [--func id]- 과거 해결한 버그 (가드 링크): knowledge/lessons.md
- Entry 엔진 고유 동작: knowledge/07-runtime-quirks.md
- 공식 문서 매핑: knowledge/00-official-sources.md (entrylabs/docs)
- 각 블록의 정확한 스펙:
entryjs/src/playground/blocks/block_*.js직접 확인 또는block-registry.json - 엔진 동작의 ground truth:
entryjs/src/class/(project.js, container.js, object.js, utils.js) - 바이너리 포맷: knowledge/01-binary-format.md
- 호스팅 (편집기) 문제: knowledge/05-host-editor.md
- 이력: knowledge/CHANGELOG.md
사용자가 다음 중 하나를 요청하면 이 저장소가 소화 가능:
- "무작위로 움직이는 오브젝트 있는 게임"
- "키보드로 조작하는 캐릭터"
- "마우스 따라오는 것"
- "체력/점수가 있는 게임"
- "장애물 피하기 (클론 사용)"
- "패턴 기억 게임 / 반응속도 테스트"
- "랭킹 시스템 (닉네임 입력 + 공유 리스트)"
- "게임 오버 / 다이얼로그 / 효과음"
- 3 장면 게임 (메뉴 → 플레이 → 결과) —
start_scene+when_scene_start - 사용자 정의 함수 —
function_create_value(값 반환) /function_create(절차) - Breakout / 벽돌깨기 류 — 패들 + 공 + 클론 벽돌
- 3×3 클론 격자 + 클릭 정답 판정 + 시간제 + 점수/콤보
- 타워 디펜스 — 빌드 슬롯, 골드 경제, 업그레이드, 다중 웨이브, 공격 시각화 (
spec-frontier-guard.mjs) - 미디어 아트 / 생김새 효과 — 색·밝기·투명도 + 모양 순환 + 크기 펄스 + 뒤집기
복잡한 게임은 비슷한 reference fixture 부터 복제 시작 권장. 25+ 디자인 패턴은 knowledge/04-script-and-blocks.md + 8 catastrophic 함정은 knowledge/07-runtime-quirks.md 정리.
미지원:
- AI Learning / 하드웨어 / 확장 블록: 현재 MYentry-game 편집기에선 꺼둠 (공식 playentry.org 서버 필요)
생성된 .ent는 자가완결 (이미지 · 사운드 tar 내부 번들). 어떤 엔트리 편집기에
가져가도 동작 — 이 저장소 서버 밖 (playentry.org 포함) 에서도 이미지가 깨지지 않는다.
{ "name": "내 게임", "messages": [ // 선택 { "id": "round_start", "name": "라운드시작" } ], "variables": [ // 선택 { "id": "hp", "name": "체력", "variableType": "variable", "value": "100", "visible": true, "x": -220, "y": 120 } ], "lists": [ // 변수 중 list 축약형 { "id": "ranking", "name": "🏆 랭킹", "isCloud": true, "visible": true } ], "learning": "<ai-model-id>", // 선택 (AI Learning) "interface": { ... }, // 선택 (기본값 자동) "speed": 60, // 선택 (기본 60 fps) "objects": [ { "id": "player", // 선택 (자동 4자 id) "name": "플레이어", "objectType": "sprite", // sprite | textBox "pictures": [ { "id": "pic1", "name": "player", "fileurl": "/images/mascot/bot205-hello.svg", "imageType": "svg", "dimension": { "width": 200, "height": 240 } } ], "sounds": [ ... ], // 선택 "entity": { "x": 0, "y": -100, "scaleX": 0.4, "scaleY": 0.4 }, "scene": "ab12", // 선택 (scenes[*].id 중 하나, 생략 시 첫 번째) "script": [ [ // thread 1 { "type": "when_run_button_click" }, { "type": "move_direction", "params": [10] } ], [ ... ] // thread 2 (병렬) ] } ] }