Files
maplecontest/docs/superpowers/plans/2026-06-12-rogue-map.md
gahusb 67e8b4c848 docs(rogue-map): P8 구현 계획
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 08:03:34 +09:00

6.9 KiB
Raw Permalink Blame History

P8 — 로그라이크 절차 생성 맵·층 시스템·유물 방 구현 계획

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 막마다 8층×4열 맵을 Lua 런타임 절차 생성, 층별 타입 규칙·점선 맵 UI·유물 방(상자 연출) 추가.

Architecture: data/map.json 정적 주입 제거 → GenerateMap Lua 메서드(StS 경로-걷기 4개) + JS 미러(tools/map/rogue-map.mjs, node:test). MapHud는 정적 그리드(28노드+보스+도트 192)로 재작성, RenderMap이 런타임 토글. TreasureHud 신설(타이머 체인 흔들림 + RUID 교체).

Tech Stack: Node.js 생성기, MSW Lua, mulberry32(JS 테스트 전용 — Lua는 math.random).

설계: docs/superpowers/specs/2026-06-12-rogue-map-design.md (사용자 승인 완료)


Task 1: JS 미러 + 단위 테스트 (TDD)

Files: Create tools/map/rogue-map.mjs, Create tools/map/rogue-map.test.mjs

  • Step 1: 테스트 먼저 작성 — generateMap(rng) import, 케이스: ①동일 시드 결정성 ②모든 노드가 시작점에서 BFS 도달 + 모든 노드에서 boss 도달 ③1~2행 combat만 ④elite·treasure는 4행부터 ⑤간선은 row+1·|Δcol|≤1 (boss 제외) ⑥elite 부모를 가진 노드는 elite 아님 ⑦boss는 row8 단일·7행 노드 전부 boss로 연결 ⑧MapStart ≥ 2개
  • Step 2: node --test tools/map/rogue-map.test.mjs → FAIL 확인
  • Step 3: rogue-map.mjs 구현 — 설계 알고리즘 그대로 (시작열 셔플 앞2 + 랜덤2, 경로 4개 걷기, 행 오름차순 가중 타입 배정·elite 부모 금지). 가중치 표는 설계 문서와 동일. ⚠️ 주석에 "Lua GenerateMap과 동기화 유지" 명시
  • Step 4: 테스트 PASS → 커밋 feat(rogue-map): 절차 생성 알고리즘 JS 미러 + 테스트

Task 2: 생성기 — 정적 맵 제거 + GenerateMap(Lua) + 층 시스템

Files: Modify tools/deck/gen-slaydeck.mjs, Delete data/map.json

  • Step 1: MAP 로드(16행)·MAX_ROW(26행)·luaMapNodesTable·luaStartArray 제거. StartRun${luaMapNodesTable(...)}/${luaStartArray(...)}self:GenerateMap() 호출로 교체. data/map.json 삭제 (git rm)
  • Step 2: props 추가 — prop('number', 'Depth', '0'), prop('any', 'VisitedNodes')
  • Step 3: GenerateMap 메서드 신설 (설계 알고리즘의 Lua 구현 — MapNodes/MapStart/VisitedNodes/Depth 리셋, 경로 4개, 행 3~7 가중 타입 배정+elite 부모 금지, boss 노드)
  • Step 4: PickNodeVisitedNodes 추가·Depth = node.row·RenderRun()·treasure → ShowTreasure 분기·self.CurrentEnemyId = node.enemy""
  • Step 5: RenderRun의 Floor 텍스트 → "막 F/3 · D층" (self.Depth)
  • Step 6: CheckCombatEnd 보스 클리어 분기에 self:GenerateMap() 추가 (Floor++ 후, TeleportToActMap 전)
  • Step 7: BindButtonsmapNodeIds 정적 배열 → 그리드 28개+boss 루프 생성으로 교체
  • Step 8: 커밋 feat(rogue-map): GenerateMap 런타임 절차 생성 + 층 시스템 (생성기)

Task 3: 생성기 — MapHud 그리드·점선 UI + RenderMap 재작성

Files: Modify tools/deck/gen-slaydeck.mjs (MapHud 섹션 ~1449행, RenderMap ~3492행)

  • Step 1: MapHud 섹션 재작성 — 기존 MAP.nodes 루프 삭제, 정적 생성:
    • Node_r{r}c{c} (r=1..7, c=1..4): 56×56 uisprite+button, pos x=-270+(c-1)*180, y=-330+(r-1)*105, 기본 enable=false, Label 자식(타입명, fontSize 16)
    • Node_boss: 72×72, pos (0, 405), Label "보스"
    • 도트: r=1..6, c=1..4, c'∈{c-1,c,c+1}∩[1,4] → Dot_r{r}c{c}_{c'}_{k} k=1..3 (8×8 uisprite, 노드 중심 보간 t=k/4, enable=false) + r=7 → Dot_r7c{c}_b_{k} (boss로)
    • guid('map') 인덱스는 결정적 루프 순서로 재배정 (섹션 전체 교체라 충돌 없음)
  • Step 2: RenderMap 재작성 — 타입색 헬퍼(전투/엘리트/상점/휴식/보물/보스), 상태 4단(현재=골드·방문=어둡게·도달가능=타입색+버튼 활성·잠김=45% 어둡게+비활성), 도트 토글(간선 존재)·현재 노드 발신 간선 골드
  • Step 3: node tools/deck/gen-slaydeck.mjs 성공 확인 → 커밋 feat(rogue-map): 맵 그리드·점선 도트 UI + RenderMap 상태 4단 (생성기)

Task 4: 상자 RUID 선별 + TreasureHud + 메소 표기

Files: Modify tools/deck/gen-slaydeck.mjs

  • Step 1: asset_search_resources("보물상자"/"상자", source=maplestory) → 메이커 격자 미리보기(기존 패턴) → 닫힘/열림 RUID 2종 확정. 생성기 상수 CHEST_CLOSED_RUID/CHEST_OPEN_RUID
  • Step 2: guid 맵에 'trs': 0xe3 추가, TreasureHud 섹션 신설 — root(hidden 패널)·Title("보물 상자")·Chest(160×160 uisprite+button, 닫힘 RUID, y=40)·Reward 텍스트(hidden, y=-120)·Leave 버튼(y=-260). emit('TreasureHud', ...)
  • Step 3: HideGameHud에 TreasureHud 추가, ShowStateelseif state == "treasure" 분기
  • Step 4: 메서드 — ShowTreasure(ChestOpened 리셋·닫힘 RUID·Reward 숨김·ShowState), OpenChest(1회 가드 → 흔들림 타이머 체인 ±8px 0.08s×6 → 0.55s 후 열림 RUID + 메소 40+random(0..20) + PickNewRelic 유물/소진 시 메소+30 + Reward 표시), prop ChestOpened
  • Step 5: BindButtons — Chest 클릭→OpenChest, TreasureHud/Leave→LeaveNode
  • Step 6: 메소 표기 — 표시 문자열 전수 교체: TopBar/ShopHud "골드 N"→"메소 N", 가격 "N 골드"→"N 메소", PickNewRelic 토스트 "골드 +25"→"메소 +25" (내부 prop Gold 유지)
  • Step 7: 커밋 feat(rogue-map): 유물 방 상자 연출·TreasureHud·메소 표기 (생성기)

Task 5: 재생성·검증·푸시·PR·머지

  • Step 1: node tools/deck/gen-slaydeck.mjs + node --test tools/map/rogue-map.test.mjs tools/balance/sim-balance.test.mjs 전체 PASS
  • Step 2: 커밋 feat(rogue-map): 산출물 재생성 → 메이커 refresh → 빌드 0에러 → 플레이테스트: 맵 생성(점선·상태색)·노드 진행(층 증가)·유물 방(흔들림→열림→보상)·보스 → 다음 막 새 맵, 스크린샷 확보
  • Step 3: push → Gitea API PR(종합 메시지) → 머지 → main pull → 메모리 갱신

Self-Review 결과

  • 설계 전 항목 매핑: 절차 생성(T1/T2)·층 시스템(T2)·점선 UI+상태 4단(T3)·유물 방+상자 모션(T4)·메소(T4) ✓
  • 이름 일관성: GenerateMap/Depth/VisitedNodes/ShowTreasure/OpenChest/ChestOpened/Dot_<fid>_<c'>_<k> 통일 ✓
  • 리스크: MapHud 섹션 전체 교체로 guid('map') 재배정 — 섹션 단위 emit이라 안전. RenderMap pairs 순회 제거(그리드 고정 루프) ✓