writeCodeblocks의 메서드 161개를 연속구간별 cb/*.mjs 모듈로 분리(바이트 동일). prop 103개는 오케스트레이터 유지. 헬퍼+공유상수는 lib/codeblock.mjs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.4 KiB
5.4 KiB
Phase 1b — codeblock 메서드 모듈화 설계
작성일: 2026-06-16
브랜치: feature/cb-modularization (Phase 1 feature/gen-modularization/PR #70 위에 스택)
목표
Phase 1에서 UI emit을 모듈화한 데 이어, gen-slaydeck.mjs의 **codeblock 메서드 161개(~3,200줄)**를 기능별 모듈로 분리한다. 출력 RootDesk/MyDesk/SlayDeckController.codeblock은 바이트 동일(순수 소스 리팩터·무위험). 하이브리드 UI 로드맵 (a) 유지보수 정리의 완결.
현재 구조 (조사 결과)
writeCodeblocks()(현gen-slaydeck.mjs:291)가 단일 호출로 codeblock을 만든다:const combat = codeblock('SlayDeckController', 'SlayDeckController', [<prop 103개>], [<method 161개>])(:301~:3617, ~3,300줄).- 헬퍼:
prop()·method()·codeblock()(현:240~:290부근, 오케스트레이터 잔류분). writeCodeblocks지역 상수:RUN_LENGTH·GOLD_PER_WIN·CARD_PRICE·REST_HEAL·RELIC_PRICE·ACT_COUNT·ACT_MAPS·LOBBY_MAP·LOBBY_SPAWN등 — 메서드 Lua 문자열 보간에 쓰임.- 메서드 본문은 Lua 문자열. JS 보간(
${RUN_LENGTH}·${luaCardsTable(CARDS.cards)}·${CAM.zoomRatio}등)은 모듈 로드 시점에 평가됨 → 모듈은 보간에 쓰는 상수/데이터/헬퍼를 import해야 한다. - 161 메서드 이름(순서): OnBeginPlay → [ascension 10종] → HideGameHud·ShowState·ShowMainMenu·BindMenuButtons·ShowLobby… → [soul 12종] → [character/job] → StartRun·StartCombat·[combat 다수] → [deck/hand] → [deckview] → [motion] → [relics/potions] → [tooltip] → [reward] → [map] → [shop/rest/treasure]. 자연스러운 **연속 런(run)**으로 묶임.
상세 설계
핵심 제약: 바이트 동일 → 메서드 순서 보존
codeblock의 methods 배열은 순서가 직렬화에 반영된다. 따라서 모듈은 "기능 버킷"이 아니라 원본 161-메서드 시퀀스의 연속 구간으로 나눈다(구간을 그 테마로 명명). writeCodeblocks가 모듈 배열을 원본 순서대로 concat → 바이트 동일. (Phase 1 HUD 분리와 동일 원리: HUD도 upsertUi 내 연속이었음.)
목표 파일 구조
tools/deck/
gen-slaydeck.mjs # 오케스트레이터: writeCodeblocks()가 codeblock(…, [props], [...m1, ...m2, …]) concat
lib/
codeblock.mjs # 신설 — prop()·method()·codeblock() 헬퍼 + writeCodeblocks 지역 상수
# (RUN_LENGTH·GOLD_PER_WIN·CARD_PRICE·REST_HEAL·RELIC_PRICE·ACT_COUNT·ACT_MAPS·LOBBY_MAP·LOBBY_SPAWN …)
cb/ # 신설 — 메서드 연속구간 모듈 (각 `export const xMethods = [ method(...), … ]`)
state.mjs ascension.mjs soul.mjs jobs.mjs run.mjs combat.mjs
deck.mjs deckview.mjs motion.mjs items.mjs tooltip.mjs reward.mjs shop.mjs … (~12-14, 실제 런 경계로 확정)
모듈 계약
- 각
cb/<name>.mjs:export const <name>Methods = [ method('A', \…`, …), method('B', …), … ];` — 메서드 호출 verbatim 이동. - import:
lib/codeblock.mjs(method·prop·codeblock·상수),lib/data.mjs(CARDS·luaCardsTable·luaStr·CAM 등 보간용). UI 헬퍼는 메서드 보간에 거의 안 쓰임(필요 구간만lib/ui-helpers.mjs). writeCodeblocks()(오케스트레이터):codeblock('SlayDeckController','SlayDeckController', [ ...props ], [ ...stateMethods, ...ascensionMethods, … ])— concat 순서 = 원본 순서.
범위/결정
- 메서드 161개만 모듈화. prop 103개는 오케스트레이터에 단일 리스트로 유지 — 한 줄짜리라 분리 가치 낮고 prop↔feature 매핑 모호(추후 필요시 별도). 게임 로직·Lua 무변경(순수 소스 리팩터).
- 공유 헬퍼(method/prop/codeblock) + writeCodeblocks 지역 상수 →
lib/codeblock.mjs. (이 상수들이 메서드 모듈 보간에 필요하므로 lib로.)
검증 (안전망)
- 구간 추출마다
node tools/deck/gen-slaydeck.mjs→node tools/verify/diffcheck.mjs→SlayDeckController.codeblockIDENTICAL(ui·common무영향이나 함께 확인). 증분(구간 1~2개씩) + 커밋. - 미러 테스트
sim-balance·rogue-map무영향(회귀 확인차 실행). - 전투규칙·맵생성 Lua 미변경 → 미러 동기화 불필요.
미러/하네스
- RULES §1의 gen-slaydeck 단일소스에
cb/·lib/codeblock.mjs추가 반영.
범위 밖
- prop 모듈화(추후).
- Phase 2(메이커 UIGroup 파일럿).
- 게임 동작·데이터 변경.
리스크
- 메서드가 writeCodeblocks 지역변수/다른 메서드 정의를 JS레벨로 참조하면(드묾 — 대부분 Lua 문자열 내
self:Method()런타임 호출이라 JS-무관) 추출 시 undefined → diffcheck/throw로 즉시 노출 → 그 구간만 인자/상수 조정. - 모듈 import는 ui-helpers처럼 export 이름 자동 파생로 누락 방지. 단방향 의존 orchestrator→cb→lib(순환 없음).
변경 파일 요약
| 파일 | 변경 |
|---|---|
tools/deck/lib/codeblock.mjs |
신설 — prop/method/codeblock 헬퍼 + 공유 상수 |
tools/deck/cb/*.mjs (~12-14) |
신설 — 메서드 연속구간 모듈 |
tools/deck/gen-slaydeck.mjs |
writeCodeblocks를 import+concat로 축소(메서드 본문 → 모듈) |
RULES.md |
§1에 cb/·lib/codeblock 반영 |
SlayDeckController.codeblock·ui·common |
무변경(바이트 동일이 합격 기준) |