Skip to content

Repository files navigation

MYentry-game — 엔트리 .ent 작품 자동 생성기

"○○ 게임 만들어줘" 요청이 들어오면 이 저장소의 도구로 엔트리 편집기에서 바로 실행되는 .ent 파일을 생성한다. 이 문서는 그 자동화 파이프라인을 설명한다.

자연어 요청 → DSL .mjs (또는 JSON) spec → .ent (tar.gz) → 편집기에서 로드·실행


📑 문서 구성

분류 섹션
AI 에이전트 지침 CLAUDE.md — "○○ 만들어줘" 요청 시 표준 절차·검증 사다리·절대 규칙
환경 구성·설치 🚀 빠른 시작 · 엔트리 원본(entryjs) — 순정 + 호스트 적응 · 처음 설치(상세) · 명령어 치트시트
게임 제작 파이프라인 무엇을 하는가 · 파이프라인 · ① 게임 설계 · ② spec 작성(DSL/JSON) · ③ make-ent 내부 · ⑤ 검증
레퍼런스·문제해결 실전 예시 카탈로그 · 문제 발생 시 · 외부 사용자용 요약
심화 위키 knowledge/README.md.ent 포맷·블록·런타임 함정·디자인 패턴 정본

새로 시작한다면: 🚀 빠른 시작엔트리 원본(entryjs) 순으로 읽으면 환경이 선다. 게임을 만든다면: 파이프라인 이후를 따라간다.


🚀 빠른 시작 — 엔트리 "만들기" 편집기 구성 → 첫 게임 → 테스트

"이 저장소로 ○○ 게임 만들어줘" 를 받은 사람(또는 AI)이 처음 해야 할 것. 우리가 작업한 환경(오프라인 엔트리 편집기 + 헤드리스 검증)을 그대로 재현한다.

0. 전제

  • Node 18+, git (git 은 entryjs 등 자동 클론에 필요)
  • 헤드리스 테스트(verify:runtime/test:e2e)를 돌리려면 Playwright Chromium:
    npx playwright install chromium

1. 설치 + 편집기 띄우기

git clone https://github.com/205sla/entry-vibe-coding
cd entry-vibe-coding
npm install
npm run setup        # 엔트리 원본·외부 모듈·vendor 자동 구성 (아래 표) — 한 번만, idempotent
npm start            # → http://localhost:3000

http://localhost:3000 이 곧 엔트리 "만들기" 페이지(오프라인 편집기) — 생성한 .ent 를 로드·실행(▶)·수정·저장한다. 헤드리스 검증 스크립트도 이 서버에 붙어 동작한다.

2. 필수 외부 의존성 — npm run setup 이 가져오는 것

이 저장소에는 엔트리 원본 엔진이 포함돼 있지 않다. 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 면 환경은 완성이다.

3. 작업 사이클 (spec → .ent → 테스트)

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 를 불러온다. 상세 파이프라인·검증 레이어는 아래에.


엔트리 원본(entryjs) — 순정 그대로 사용 (테스트용 적응은 호스트 레이어)

엔트리 엔진(entrylabs/entryjs) 은 순정을 그대로 쓴다 — 엔진 소스·dist 를 고치지 않으며, 직접 빌드하지도 않는다. dist 는 entrylabs 가 npm 에 배포하는 @entrylabs/entry 공식 prebuilt 아티팩트 (또는 개발 머신의 형제 ../entryjs 빌드) 를 그대로 복사한다. 순정을 그대로 드롭인하면 오프라인 부팅·.ent 로드·헤드리스 테스트가 안 되므로, 엔진은 건드리지 않고 호스트 레이어(이 저장소)에서만 아래 적응을 적용한다. 새 entryjs 로 교체하거나 직접 세팅할 때 아래 A·B 지점만 맞추면 .ent 생성·테스트가 돌아간다.

A. 부팅 적응 — 없으면 편집기가 안 뜬다

적응 위치 왜 필요한가
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 방지

B. 로드·테스트 적응 — .ent 왕복 + 헤드리스 검증

적응 위치 왜 필요한가
.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 DSLsetVar, 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.mjsnormalizeBlock + 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 (엔진 동작)

① 게임 설계 — Claude가 하는 판단

요청을 받으면 다음 순서로 설계한다:

1-1. 오브젝트 개수·역할 정하기

  • 싱글 플레이어: 1 오브젝트만 (예: circle-recursive, healthbar-brush)
  • 플레이어 + 적: 2 오브젝트 (예: chase-hp)
  • 플레이어 + 생성되는 장애물: 원본 + 클론 (예: bullethell) — 원본 visible: false로 숨기고 create_clone("self") + when_clone_start
  • 진행자만 (키 입력 + 내러티브): 1 오브젝트 + 여러 thread (예: memory-ranking)

1-2. 변수·리스트 식별

  • 상태: HP, 점수, 레벨, "듣는중" 같은 플래그
  • 자료구조: 리스트 — 패턴 저장, 랭킹, 인벤토리
  • 공유 리스트 (isCloud: true): 랭킹처럼 여러 세션 공유하고 싶을 때

1-3. Thread 구조 설계

한 오브젝트 안에서 병렬 실행되는 thread:

  • when_run_button_click — ▶ 버튼 시 1회
  • when_some_key_pressed(키코드) — 키 눌릴 때마다 새 thread
  • when_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로.

1-4. 블록 선택

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에 카테고리별로 정리돼 있다.


② spec 작성 — DSL .mjs 권장

캐릭터·아이템·배경은 외부 이미지 생성 도구 없이도 제작할 수 있다. 이미지 생성 도구가 없는 Claude Code 등의 환경에서는 기존 assets()·sprite-gen.mjs와 직접 작성한 SVG를 사용한다. SVG 제작 절차를 따른다. 이미지 생성 도구가 제공되는 환경에서는 일러스트를 직접 생성해 spec에서 사용할 수도 있다. 투명 배경 생성·배경 제거·실제 알파 검사·프로젝트 등록은 AI 이미지 에셋 절차를 따른다. node tools/import-image-asset.mjs --help로 PNG 가져오기 명령을 확인할 수 있다.

신규 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', '게임 화면') ],
    messages: [{ id: 'lose', name: '패배' }],
    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.mjscircle, 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 에 모여 있어 새 게임 시작 시 가장 좋은 출발점.

② (legacy) spec JSON — 직접 입력 형식

기존 JSON spec fixture 들도 여전히 작동. JSON 직접 작성 시:

{
  "name": "내 게임",
  "scenes": [{ "id": "ab12", "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 (병렬)
      ]
    }
  ]
}

입력 편의 문법 — make-ent가 자동 변환

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>} 자동

필드(field) vs 블록(block) 슬롯 — 중요한 차이

블록의 params 슬롯은 두 종류:

  • Block 슬롯 (값을 반환하는 중첩 블록 받음): {"type":"number","params":["10"]} 또는 다른 블록
  • Field 슬롯 (드롭다운 문자열 바로 받음): "mouse", "player", "EQUAL", "speak"

Field 슬롯에 {"type":"text",...}로 감싸면 엔진이 "text 블록의 결과값"으로 취급해서 드롭다운 매칭 실패. 반드시 {"__field":"<값>"} sentinel로 감싸 wrapParam이 언래핑하게.


③ make-ent.mjs 내부 — 어떻게 .ent가 만들어지나

tools/make-ent.mjs 주요 단계:

  1. resolveLocalPath: {fileurl: "/images/..."}public/images/... 절대경로
  2. bundleOne(absPath, kind): 이미지면 sharp(buf).png()로 rasterize, 96px 썸네일 생성, tar payload 추가
  3. normalizeBlock: spec block의 params 정규화. leaf 블록(number/text/get_variable 등)은 재귀하지 않고 그대로 반환 (이중 래핑 방지)
  4. wrapParam: primitive 값을 리터럴 블록으로 감싸거나 __field sentinel 언래핑
  5. buildProject(spec): 최상위 project 객체 조립 — scenes, variables, objects, interface, learning
  6. tarHeader + makeTar: ustar portable 포맷 (mode 000755/000644, uid/gid/mtime NUL 등). 공식 npm tar.c({portable:true})와 동일 바이트 출력
  7. zlib.gzipSync(tar, {memLevel: 6}): 공식 엔트리 문서 명시 설정

자산 해시는 공식 알고리즘 uid(8) + puid.generate() (npm uid + puid 패키지).


⑤ 검증 — 무엇을 체크하나

4 레이어로 누적 검증. 빠른 → 느린 순. LLM 의 자기 수정 루프 핵심.

Layer 1. --check 정적 검증 (node tools/make-ent.mjs spec.mjs --check, < 1 초)

  • 모든 블록 type 이 block-registry.json 에 존재
  • params.length === paramCount (registry 와 일치)
  • 슬롯 wrap 검증 (Field 슬롯에 Block 들어가는지 등)
  • 선언된 변수·리스트·함수·메시지·장면 참조, 오브젝트 전용 변수의 소유자, 종류별 ID 중복
  • 로컬 모양·소리 파일 존재와 script/content의 2차원 배열 구조(문자열 JSON 포함)

빌드 없이 스펙 작성 직후 실행한다. buildProject/writeEnt도 같은 검사를 자동 실행하고 오류가 있으면 출력 전에 중단한다. 동적으로 계산되는 참조는 정적으로 확정하지 않으며, 외부 HTTP/data 에셋은 경고와 함께 그대로 유지한다(다운로드·내용 검증은 하지 않음).

Layer 2. smoke (npm run test:smoke, ~ 5 초)

.ent fixture (총 23) 에 대해:

  • gunzip + tar 파싱 성공
  • temp/project.json 존재 + JSON 파싱
  • 필수 top-level 키 (objects, scenes, variables)
  • 모든 object.script 가 문자열 + 파싱 가능한 2 차원 배열
  • 모든 블록 typeblock-registry.json 에 존재 (primitive 화이트리스트 예외)
  • 모든 picture fileurl 이 tar 안 또는 public/ 아래에 실재
  • selectedPictureId 가 그 object 의 pictures[*].id 와 매칭
  • object.scene 이 scenes[*].id 와 매칭

tests/hardening.test.js는 장시간 편집 후 에셋 보존, 누락 에셋 저장 거부, 명세 오류 차단, fixture 소스 전체의 메모리 재빌드, 게임 검증 탐색·실패·시간 초과도 확인한다.

Layer 3. e2e (npm run test:e2e, ~ 30 초)

  • 편집기 부트스트랩 시 pageErrors === [] && consoleErrors === [], 외부 요청 0
  • 각 fixture 를 /api/loadEntry.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 마법 숫자 확인)

Layer 4. verify-runtime (npm run verify:runtime)

tools/verify-*.mjsgames/**/verify.mjs·verify-*.mjs를 자동 탐색해 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 렌더 픽셀)

node tools/run-all-verify.mjs --list로 서버 없이 목록을 확인한다. --filter <name>으로 일부만, --timeout-ms 600000으로 스크립트별 제한 시간을 지정한다(기본 10분). 실패·시간 초과는 전체 실패로 집계하며 직접 띄운 서버는 종료한다. --keep-server는 서버를 유지한다. 개인 원본 인자가 필요한 verify-case-study-evidence.mjs는 사유를 출력하고 제외한다. 실행 전에 브라우저 설치 여부를 한 번 확인한다.

Layer 5. knowledge links (npm run verify:links, < 1 초)

knowledge/ 의 13 markdown 파일 간 cross-ref 검증 (300+ 링크). 깨진 앵커/경로 잡기.

npm run verify — 전체

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 참조.

기초 (JSON spec)

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 회귀 가드

DSL 기반 게임 (.mjs)

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 가 좋은 출발점.


처음 설치 (상세) — npm run setup 이 하는 일

설치 명령은 위 🚀 빠른 시작 참고. setup (scripts/setup.mjs) 은 재실행 안전(idempotent):

  1. entryjs dist·extern·images — 형제 ../entryjs빌드된 dist 가 있으면 그걸 복사(개발 머신). 없으면 npm @entrylabs/entry (버전 핀, setup.mjsENTRY_NPM_VERSION_DEFAULT) 를 npm pack 으로 받아 .setup-cache/ 에 풀고 복사. 소스만 있는 ../entryjs 는 빌드 대상이 아니라 무시 대상 — 이때도 npm 아티팩트를 쓴다.
  2. entryjs 소스 (선택)node scripts/setup.mjs --with-entryjs-src 일 때만 .setup-cache/entryjs 로 클론 후 ../entryjs 링크. build:registry·knowledge 문서의 소스 인용(../entryjs/src/...)에만 필요.
  3. External modules (entry-tool / entry-paint / entry-lms / sound-editor / legacy-video) — ../MYentry/public/lib/* 우선 링크 → entry-tool·legacy-video 는 공개 GitHub dist/develop 클론 → entry-paint·entry-lms·sound-editor 는 playentry.org / code.205.kr 정적 파일 다운로드 (편집기가 로드하는 빌드 파일만: entry-paint.js, app.js+app.css, sound-editor.js).
  4. Mascot 이미지 + 커서 — repo 에 커밋돼 있음. 형제 ../MYentry 있으면 최신으로 덮어쓰기만.
  5. Vendor npm 패키지 — jQuery / jQuery-UI / lodash / Velocity / CodeMirror / React / CreateJS 등을 임시 설치 후 dist 파일만 public/lib/vendor/ 로.
  6. preload-js 패치;module.exports=window.createjs; 제거 (module is not defined 방지).
  7. 부팅 파일 검사editor.html 이 로드하는 필수 파일 전부 존재 확인. 여기가 OK 면 부팅 보장.

벤더만 스킵: node scripts/setup.mjs --skip-vendor. entryjs 버전 핀을 올렸으면 node scripts/setup.mjs --with-entryjs-srcnpm run build:registry 로 레지스트리 재생성. (⚠️ setup 에 플래그를 줄 땐 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 레이어 검증 전부 동작한다. 전제와 한계:

  1. 인터넷 연결 — setup 이 npm 아티팩트(~87MB)·entry-tool GitHub·playentry.org/code.205.kr 정적 파일을 받는다. 한 번 받으면 .setup-cache/ 에 남아 재실행은 오프라인도 가능.
  2. entryjs 버전 핀 — setup 은 @entrylabs/entry 를 고정 버전으로 받는다(재현성). 핀을 올려 블록 API 가 어긋나면 node scripts/setup.mjs --with-entryjs-srcnpm run build:registry.
  3. Playwright Chromium — 헤드리스 테스트용 (위 npx playwright install chromium).
  4. 미지원 — AI Learning · 하드웨어 · 확장 블록은 playentry.org 서버 필요 → 이 편집기에선 비활성.
  5. 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            # tools/ + games/ 검증; 실행 시간은 대상별로 다름
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]

문제 발생 시 어디를 보나

  1. 과거 해결한 버그 (가드 링크): knowledge/lessons.md
  2. Entry 엔진 고유 동작: knowledge/07-runtime-quirks.md
  3. 공식 문서 매핑: knowledge/00-official-sources.md (entrylabs/docs)
  4. 각 블록의 정확한 스펙: entryjs/src/playground/blocks/block_*.js 직접 확인 또는 block-registry.json
  5. 엔진 동작의 ground truth: entryjs/src/class/ (project.js, container.js, object.js, utils.js)
  6. 바이너리 포맷: knowledge/01-binary-format.md
  7. 호스팅 (편집기) 문제: knowledge/05-host-editor.md
  8. 이력: 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 포함) 에서도 이미지가 깨지지 않는다.

About

엔트리(playentry.org) .ent 작품 자동 생성 파이프라인 + 오프라인 편집기

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages