모듈화 점검 기록¶
2026-09-01 위키 접근성·자유 스킬 배치 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 물리 키 계약 | 통과 | KeyMappingService는 InputMap·22개 물리 입력·충돌 교환·JSON만 소유 |
| 스킬 위치 계약 | 통과 | SkillBindingProfile/Service는 skill_id→허용 Action 9개 배치·교환·별도 JSON만 소유 |
| 전투 소비자 | 통과 | CombatSkillSystem은 제공자의 현재 Action을 읽고 HUD는 동일 상태 Signal을 구독 |
| UI 경계 | 통과 | K 패널은 두 서비스의 공개 명령·스냅샷만 사용하며 스킬 정의나 저장 파일을 직접 수정하지 않음 |
| 선택적 비활성화 | 통과 | skill_binding_enabled=false이면 자유 배치만 제거되고 기존 물리 키 설정은 유지 |
| 위키 상호작용 | 수정 후 통과 | CSS 장식은 포인터를 받지 않고 JS 재렌더링 뒤 포커스를 복원하며 루트는 비활성 버튼이 아닌 정보 노드 |
| 데이터 공급선 | 유지 | 이번 작업은 신규 아이템 목록이 없어 Sheet를 확장하지 않았고 기존 실시간 Sheet→확정 CSV 구조를 변경하지 않음 |
| 성능 회귀 | 통과 | 대형 방 34기·전기 효과 3개에서 평균 6.869ms, 피크 8.830ms, Node 1,809개로 60 FPS CPU 예산 유지 |
| Scene 격리 | 통과 | 조립은 동적 Scene 경로로 수행하며 사용자 소유 game/scenes/game.tscn 변경을 수정·스테이징하지 않음 |
판단 결과, Profile → Service → CombatSkillSystem/HUD의 단방향 의존이 유지됩니다. 다음 P4 전리품 목록이 필요해질 때는 Google Sheet의 해당 탭을 먼저 확장하고 동일 스키마의 확정 CSV 제공자를 통해 런타임에 공급합니다.
2026-09-01 모바일 위키 반응형 E2E 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 콘텐츠·표현 경계 | 통과 | Markdown은 역할·문서 의미, extra.css는 뷰포트·터치·표시 밀도, 세 JavaScript는 검색·플레이·노드 상태만 소유 |
| 배포 루트 | 수정 후 통과 | 검색 데이터·플레이·노드 링크가 현재 페이지의 상대 base 대신 각 스크립트의 고정 URL에서 /SFH/ 루트를 계산 |
| 모바일 검색 | 수정 후 통과 | 접혀 있던 6px 출력 패널을 100dvh 전체 높이와 독립 스크롤로 복구하고 입력 전 추천·입력 후 결과를 실브라우저에서 판정 |
| 역할 탐색 | 통과 | PLAN · DEV · QA · DOCS는 기존 진행도·모듈·품질·노드 문서를 연결할 뿐 도메인 내용을 복제하지 않음 |
| 문서 완전성 | 통과 | MkDocs·JSON·Markdown의 56개 문서가 일치하며 새 E2E 문서도 품질 그룹에 한 번만 배치 |
| 반응형 표현 | 통과 | 320·390·768·1440px에서 홈, 표·코드, 검색, 노드맵을 같은 콘텐츠로 재배치하며 별도 모바일 문서를 만들지 않음 |
| 빌드 게이트 | 통과 | 검색·플레이 루트, 역할 링크, dvh·safe-area·44px 터치·4개 뷰포트 계약을 check-wiki-responsive.ps1로 분리 검증 |
| 게임 Scene 격리 | 통과 | 위키와 배포 검사만 변경하고 사용자 작업 중인 game/scenes/game.tscn은 수정·스테이징하지 않음 |
판단 결과, 모바일 전용 콘텐츠 복제나 게임 코드 결합은 없습니다. 기획·개발 문서는 하나의 Markdown 원본을 유지하고 CSS가 화면 폭에 맞춰 표현만 바꾸며, 검색·플레이·노드 링크는 각 전역 스크립트가 독립적으로 안정 주소를 제공합니다.
2026-08-31 방 진입 핵앤슬래시 무리 재감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 진입 트리거 | 통과 | RoomEncounterSystem만 플레이어 위치와 맵의 get_visibility_region()을 조합하며 실제 E2E는 last_trigger_source=room_entry를 요구 |
| 수량 정책 분리 | 통과 | 소·중·대형 최소·최대 12~18 / 18~26 / 24~34는 RoomEncounterConfig Resource에만 존재하고 Game·맵·적 Scene에는 복제하지 않음 |
| 최소 무리 보장 | 통과 | 남은 총 예산과 배치 가능 위치가 최소치보다 작으면 문을 잠그거나 부분 교전을 시작하지 않으며 공개 스냅샷으로 판정 |
| 생성 경로 재사용 | 통과 | 모든 방 적은 EnemySpawner.spawn_enemy_at()을 사용해 장갑·체력·Signal·군중 분리·유한 생성 예산 계약을 그대로 적용 |
| 맵 내부 캡슐화 | 통과 | 방 시스템은 rooms·타일·장애물 배열을 읽지 않고 복사된 방 스냅샷과 위치 요청만 사용 |
| 교체·비활성화 | 통과 | Manifest 토글을 끄면 방 트리거·봉쇄·보상 Node가 설치되지 않고 기존 전역 증원 모드가 복구됨 |
| 실제 플레이 검증 | 통과 | 일반 방 중앙으로 플레이어를 이동시켜 자동 생성·최소 무리·문 봉쇄·전멸·보상·경험치까지 한 인과 흐름으로 확인 |
| 연쇄 레벨업 회귀 | 수정 후 통과 | 늘어난 방 적 경험치로 여러 증강이 대기하면 Selector가 한 장씩 이어 열고 E2E는 대기열 소진 뒤 전투 복귀를 확인 |
| 성능 예산 | 통과 | 대형 방 최대 34기와 전기 효과 3개에서 평균 6.887ms, 피크 8.714ms, Node 1,774개로 60 FPS CPU·6,000 Node 예산 유지 |
| Scene 충돌 회피 | 통과 | 기존 로컬 game.tscn 변경은 수정·스테이징하지 않고 Resource·독립 시스템·판정기만 변경 |
판단 결과, 이번 변경에서 새 비모듈 결합은 발견되지 않았습니다. 수량은 설정 Resource, 방 진입과 교전 수명은 RoomEncounterSystem, 실제 적 생성과 총량 제한은 EnemySpawner, 배치 가능 좌표는 맵 제공자가 각각 소유합니다. 최소 수량이나 티어 밸런스를 다시 바꿀 때 .tres만 교체하면 되며, 방 봉쇄·보상·HUD 코드는 수정할 필요가 없습니다.
2026-08-31 위키 4단계 문서 노드맵 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 문서 완전성 | 통과 | MkDocs 내비게이션 55개와 JSON 세부 노드 55개가 정확히 일치하며 누락·중복·잘못된 경로를 빌드 전에 차단 |
| 계층 계약 | 통과 | L1 SFH → L2 7개 대영역 → L3 17개 소그룹 → L4 실제 문서의 고정 4단계 데이터 계약 유지 |
| 콘텐츠·표현 분리 | 통과 | knowledge-map.json은 분류·요약·경로만, knowledge-map.js는 상태·탐색만, extra.css는 표현만 소유 |
| 전역 설치 | 통과 | MkDocs extra_javascript 한 번으로 55개 렌더링 문서의 본문 최하단에 동일 HUD를 설치 |
| 현재 문서 인식 | 통과 | 실제 URL을 노드 route와 비교해 L2·L3 선택과 L4 YOU·aria-current를 자동 적용 |
| 탐색 접근성 | 통과 | 클릭·터치·Tab과 상하좌우 키, 검색 입력, aria-label·aria-live 경로를 지원 |
| 반응형 밀도 | 통과 | 4열 데스크톱·2열 태블릿·1열 모바일로 재배치하고 긴 세부 목록만 내부 스크롤 |
| 즉시 탐색 호환 | 통과 | Material document$ 전환마다 새 본문에 한 번만 삽입하며 기존 검색·플레이 버튼과 상태를 공유하지 않음 |
노드맵은 문서 본문을 수정하거나 Markdown에 반복 HTML을 삽입하지 않습니다. 새 문서는 JSON 분류와 MkDocs 내비게이션을 함께 추가해야만 빌드되므로, 문서 수가 늘어나도 전체 구조에서 고립된 페이지가 생기지 않습니다.
2026-08-31 내부 증강 카드 UI 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 규칙·표현 경계 | 통과 | RunBuffSystem은 후보·중첩·효과 적용만 소유하고 RunBuffChoiceCard는 전달받은 선택 스냅샷만 표시 |
| 카드 교체성 | 통과 | 카드가 configure()와 Button pressed 계약만 제공해 다른 Scene·스킨으로 교체해도 버프 계산은 유지 |
| 데이터 확장성 | 통과 | 이름·설명·최대 중첩·외부 계열은 기존 Google Sheets/CSV 카탈로그를 그대로 사용하며 신규 ID는 기본 AUG 식별자로 안전 표시 |
| 입력 분리 | 통과 | 선택기가 1·2·3 즉시 선택과 A/D·방향키 포커스만 해석하고 실제 적용은 buff_selected를 받은 Game 조립 지점이 수행 |
| 모달 배타성 | 통과 | 열릴 때 기존 전투 HUD를 숨기고 닫힐 때 직전 가시 상태·일시정지를 복원하며 다른 I/U/E/K 모달과 같은 그룹 계약 사용 |
| 반응형 경계 | 통과 | 1280×720에서 3장 세로 카드·헤더·안내가 모두 화면 안에 있고 첫 카드 포커스를 E2E로 검사 |
| 플레이어 인식 | 통과 | 계열·작전 한정·이름·중첩·효과·선택 키를 보이는 문자열로 판정하고 실제 2 입력 뒤 적용·전투 복귀 확인 |
| 외부 이미지 의존 | 통과 | 참조 이미지의 세로 카드 정보 구조만 반영하고 프레임·코어·레일은 Godot 코드 드로잉으로 제작 |
표시 계층을 제거해도 내부 레벨업, HP 회복, 선택 후보, 한 판 효과와 외부 경험치 정산은 유지됩니다. 반대로 카드 프레임과 색을 바꿀 때 성장 CSV나 RunBuffDefinition을 수정할 필요가 없습니다.
2026-08-31 이동 체감 피드백 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 이동 규칙 경계 | 통과 | PlayerMovementFeedback은 완성된 velocity와 공개 이동 스냅샷만 읽고 가속·제동·충돌·쿨타임을 계산하지 않음 |
| 출발·정지·선회 | 통과 | Body·Heading의 위치·축별 크기와 코드 드로잉 신호만 짧게 변경하며 원본 이동 속도는 유지 |
| 카메라 방향 리드 | 통과 | Camera2D 로컬 위치만 최대 30px 보간하고 플레이어 월드 좌표·시야 판정에는 접근하지 않음 |
| 대시 궤적 | 통과 | 런타임 Line2D 하나에 최대 10점만 재사용해 대시마다 Node나 텍스처를 생성하지 않음 |
| 성능 예산 | 통과 | 대형 작전 평균 7.086ms, 피크 18.860ms, Node 1,499개로 표현 추가 뒤에도 CPU·Node 예산 유지 |
| 비활성화 | 통과 | set_feedback_enabled(false)가 Body·Heading·Camera를 기본 Transform으로 복원하고 이동은 계속 작동 |
| 플레이어 인식 E2E | 통과 | 실제 Space 입력 뒤 표현 강도 0.55+, 궤적 2점+, 카메라 리드 8px+와 쿨타임 HUD 변화를 함께 검사 |
| Scene 충돌 회피 | 통과 | 사용자 편집 중인 game.tscn은 수정하지 않고 독립 스크립트와 Player 하위 Node만 추가 |
이 모듈은 “수치상 즉각적이지만 티가 나지 않던” 문제만 해결합니다. 다른 캐릭터 표현으로 교체할 때 MovementFeedback Node를 제거하거나 같은 advance_feedback()·get_feedback_snapshot() 계약을 구현하면 이동·장비·맵 코드는 바뀌지 않습니다.
2026-08-31 플레이어 인식 단위 E2E 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 인식 판정기 | 통과 | PlayerPerceptionJudge가 실제로 표시된 Label·Button 문자열만 읽고 게임 상태나 UI를 변경하지 않음 |
| 실제 입력 증거 | 통과 | K·I·U·E·Q·1·Space·F 입력 직후 화면 문구·수치·위치의 전후 차이를 함께 검사 |
| 상태 판정 분리 | 통과 | UIStateJudge의 경계·겹침·배타성 21상태와 인식 판정 19체크포인트를 독립 계약으로 유지 |
| 인식 범위 | 통과 | 방향 인지·선택·결정·한눈 정보·행동 피드백·자원 피드백·상태 피드백·결과 이해·연속성의 9단위를 검증 |
| 전투 행동 | 통과 | 실제 점멸의 이동·에너지·쿨타임과 실제 대시의 궤적·카메라 리드·표현 강도·READY 전환을 확인 |
| 경제·탈출 | 통과 | 파밍 후 휴대 크레딧 증가와 탈출 시작·일시정지·재개·성공·실패 결과 문구를 플레이어 관점으로 확인 |
| 가시 피드백 보완 | 수정 후 통과 | 거점 Q 교체 결과를 항상 보이는 조작 안내에 추가하고 대시 HUD의 고정 키 표기를 키 독립 문구로 교체 |
| 검수 공백 공개 | 부분 통과 | 기본기 타격→처치, 방 봉쇄→보상, 전장의 안개 전환, 10분 세션, 실기 성능·해상도는 후속 자동·수동 항목으로 분리 |
| Scene 충돌 회피 | 통과 | 사용자 편집 중인 game.tscn은 수정하지 않고 판정기·E2E·표현 문구만 변경 |
판정기는 기능 클래스의 존재를 완료 증거로 사용하지 않습니다. 플레이어가 행동의 원인과 결과를 화면에서 구분할 수 있을 때만 통과하며, 상세 범위와 남은 우선순위는 플레이어 인식 단위 E2E 감사에 기록합니다.
2026-08-31 핵심 게임플레이 인과 E2E 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 좌클릭 전투 사슬 | 통과 | 물리 마우스 이벤트 뒤 AutoWeapon 발사체, HitFeedbackDirector 타격·치명 타격, Game 처치, CombatResourceSystem 드랍 스냅샷이 모두 증가해야 통과 |
| 물리 안전 드랍 | 수정 후 통과 | 발사체 충돌 안에서는 처치 Signal만 처리하고 경험치·자원 Area 생성은 다음 안전 프레임으로 지연해 PhysicsServer flush 오류 제거 |
| 방 전투 사슬 | 통과 | RoomEncounterSystem이 적·문·활성 보상·누적 생성/회수를 공개 스냅샷으로 제공하고 E2E는 방 진입부터 내부 경험치 증가까지 판정 |
| 경험치 인과 계약 | 통과 | ProgressionSystem의 누적 획득량으로 레벨업 시 현재 경험치가 차감되어도 방 보상 유입을 안정적으로 판정 |
| 상태 피드백 우선순위 | 수정 후 통과 | CombatHudPresenter가 봉쇄·확보·보상 문구의 우선순위와 유지시간만 담당하며 드랍·방 규칙에는 접근하지 않음 |
| 10분 세션 | 통과 | 중형·대형 모두 데이터상 600초이며 Game의 논리 시계를 599초/600초로 나눠 탈출 잠금·개방과 HUD를 검증 |
| 전장의 안개 | 통과 | BattlefieldFogOfWar가 room/leaving_room/corridor/entering_room 상태, 다른 방 차폐와 미니맵 독립 여부를 읽기 전용으로 공개 |
| 판정기 분리 | 통과 | GameplayFlowJudge는 상태를 변경하지 않고 5개 인과 흐름의 증거 Dictionary만 비교하므로 기능 교체 시 공개 스냅샷 계약만 유지하면 됨 |
| Scene 충돌 회피 | 통과 | 사용자 편집 중인 game.tscn은 이번 변경에서 수정·스테이징하지 않음 |
기존 기능 스모크는 개별 규칙과 선택 비활성 폴백을, 실제 플레이 E2E는 입력부터 결과까지의 연결을 소유합니다. 따라서 “무기는 발사 가능하지만 처치 드랍에서 런타임 오류가 나는” 종류의 조립 결함도 배포 전에 차단합니다.
2026-08-31 사이버펑크 표현 테마 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 공통 Theme | 통과 | cyberpunk_theme.tres가 색·폰트·기본 Control 스타일만 제공하고 게임 상태에 접근하지 않음 |
| 화면 효과 | 통과 | CyberpunkScreenFX가 정적 스캔라인·결정론적 노이즈·프레임만 그리고 입력은 항상 통과 |
| 점멸·스캔 | 통과 | Overlay가 5px 상태 점 투명도와 2px 스캔 바 위치만 갱신하며 전체 화면 재드로우 없음 |
| 선택 비활성화 | 통과 | Manifest의 cyberpunk_theme_enabled를 끄면 표현 CanvasLayer가 설치되지 않고 플레이는 유지됨 |
| 세부 효과 토글 | 통과 | cyberpunk_motion_enabled, cyberpunk_noise_enabled로 움직임·노이즈를 독립 제거 가능 |
| UI 회귀 | 통과 | Galmuri 적용 뒤 작전 브리핑·임무 추적기·미니맵 폭을 교정하고 21개 실제 입력 상태·비겹침 통과 |
| 성능 예산 | 통과 | 대형 작전 평균 7.086ms, 피크 18.860ms, Node 1,499개로 CPU·Node 예산 유지 |
| 라이선스 | 통과 | Galmuri OFL 1.1 원문·공식 커밋·TTF/WOFF2 해시를 게임·위키 배포 경계에 보존 |
이 모듈은 시각 표현만 소유합니다. 플레이어 체력, 스킬 쿨타임, 장비 장착, 작전 계약의 색상 의미나 수치를 계산하지 않으므로 다른 테마 Scene으로 교체하거나 효과만 비활성화할 수 있습니다.
2026-08-31 총기 파츠 UI 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 무기 도식 | 통과 | WeaponPartsBoard가 minor_tag에 따라 코드로 실루엣만 그리고 외부 총기 이미지나 전투 Scene에 의존하지 않음 |
| 소켓 지도 | 통과 | 무기 정의의 part_socket_ids와 현재 installed_parts를 읽어 빈 슬롯·장착 슬롯을 표시 |
| 선택 연결 | 통과 | 보드는 socket_selected(socket_id)만 방출하고 Workbench가 기존 선택·필터 계약으로 변환 |
| 장착 규칙 | 통과 | 소분류 호환·소켓 중복·가방 소비·교체 복구는 기존 EquipmentItemState·EquipmentSystem이 소유 |
| 비무기 상태 | 통과 | 방어구는 파츠 미지원 안내만 표시하며 장착 API 또는 데이터에 접근하지 않음 |
| 반응형 밀도 | 통과 | 296×122px 보드와 소총 3소켓이 1280×720 E 모달 경계 안에 있는지 실제 입력 E2E로 검사 |
| Scene 충돌 회피 | 통과 | 사용자 편집 중인 game.tscn 없이 독립 Control Script와 Workbench Scene만 변경 |
표현 보드를 제거해도 숨겨진 기존 파츠 카드와 장착·강화 API는 유지됩니다. 총기별 전용 일러스트가 준비되면 보드의 도식 구현만 교체할 수 있고, 소켓 및 인벤토리 계약은 바뀌지 않습니다.
2026-08-31 모듈 UI 참조 재설계 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 표현 어댑터 | 통과 | EquipmentModuleUIPresenter가 카드 문구·합산 표시·정렬 키만 만들고 장착 상태를 변경하지 않음 |
| 호환 판정 | 통과 | UI는 기존 _can_install_entry()와 EquipmentItemState 결과를 카드의 장착 가능 상태로 투영 |
| 코스트 표시 | 통과 | 장착 카드는 effective_module_cost(), 보유 카드는 정의의 현재 기본 코스트만 읽고 공식을 복제하지 않음 |
| 적용 수치 | 통과 | 장착 정의의 stat_modifiers를 읽기 전용 합산하며 실제 플레이 스탯 적용은 EquipmentSystem에 유지 |
| 필터·정렬 | 통과 | 전체·모듈·파츠 필터와 추천·코스트 정렬은 인벤토리 원본 배열을 변경하지 않고 표시 사본만 정렬 |
| 화면 밀도 | 통과 | 1280×720에서 326px 장착 보드, 4열 138×92px 후보 카드와 모달 화면 경계를 E2E로 검사 |
| Scene 충돌 회피 | 통과 | 사용자 편집 중인 game.tscn은 제외하고 독립 Workbench Scene과 표시 스크립트만 변경 |
참조 화면의 세팅 카드·적용 수치·하단 보유 목록 구조만 차용하고, 아직 존재하지 않는 프리셋·등급·캐릭터 모델 기능은 UI에 위조하지 않았습니다. Presenter를 제거해도 장비 장착·강화·가방 상태는 유지되며 다른 표시 구현으로 교체할 수 있습니다.
2026-08-31 타격 피드백 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 피해 계산 분리 | 통과 | hit_context는 방향·출처·표현 강도만 전달하고 체력·방어력 공식은 기존 액터가 소유 |
| 액터 반응 | 통과 | HitReaction2D가 공개 react()·advance()로 섬광·국소 경직·넉백만 합성 |
| 월드 표현 | 통과 | Director가 damaged Signal만 구독해 코드 드로잉 충격 링과 Camera2D offset 적용 |
| 공격 확장 | 통과 | 기본기·점멸·자기장·적 접촉이 같은 선택형 Dictionary 계약을 사용하며 기존 1인자 호출 유지 |
| 성능 상한 | 통과 | 타격별 Node 생성 없이 Director 하나가 동시 충격 기록 최대 32개만 그리도록 제한 |
| 기능 비활성화 | 통과 | Manifest에서 끄면 Director 미설치, 플레이어·적의 HitReaction2D.enabled도 false |
| Scene 충돌 회피 | 통과 | 사용자 편집 중인 game.tscn은 수정하지 않고 독립 기능 Scene·액터 하위 구성 요소만 변경 |
Game은 Player Camera와 피드백 프로필을 Director에 주입하고 새 적을 등록하는 조립만 담당합니다. 피드백 폴더를 다른 구현으로 교체해도 무기, 스킬, 체력, 방어력과 적 생성 규칙은 유지됩니다.
2026-08-31 저점유 반응형 인터페이스 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 지속 정보 예산 | 통과 | Presenter의 임무·생존·수치·행동·스킬·대시 면적과 미니맵을 합산해 1280×720 화면의 20% 초과 시 UI 상태 E2E 실패 |
| 상황별 상세 | 통과 | 장비·무기 Signal은 reveal_detail()만 요청하고 독립 one-shot Timer가 1.8초 뒤 숨김 |
| 상호작용 초점 | 통과 | F 가능 여부만 받아 임무·행동 도크 투명도를 조절하며 상호작용 실행·거리 판정에는 접근하지 않음 |
| 생존 초점 | 통과 | 공개 체력 비율만 받아 35% 이하에서 생존 패널을 강조하며 피해·회복 계산은 기존 체력 모듈 유지 |
| 미니맵 축약 | 통과 | 제목·범례·그림자만 제거하고 기존 전체 지도 ImageTexture·플레이어·탈출 마커를 유지 |
| 다중 폭 계약 | 통과 | 1100px HUD, 900px 미니맵 분기와 800px 주입 테스트에서 상세 제거·가장자리 배치 확인 |
| 모달 배타성 | 통과 | I/U/E/K·증강·결과 중에는 기존 HUD 가시성 스냅샷 계약으로 전투 레이어 전체를 숨김 |
| Scene 충돌 회피 | 통과 | 사용자 game.tscn 변경은 제외하고 Presenter·미니맵·조립 콜백·테스트만 수정 |
반응형 표현은 도메인 상태를 복제하지 않습니다. Game 조립부가 기존 Signal에서 “무엇이 방금 바뀌었는가”와 체력 비율만 Presenter에 전달하며, Presenter와 미니맵은 위치·투명도·일시 표시만 소유합니다.
2026-08-31 반응형 아이콘 HUD 재구성 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 아이콘 표현 | 통과 | TacticalHudIcon이 12종 도형을 코드 드로잉하며 이모지·외부 텍스처·게임 상태를 참조하지 않음 |
| 데이터 재사용 | 통과 | 기존 체력·XP·레벨·처치·크레딧·장비·무기 Label과 ProgressBar의 Signal 연결을 유지한 채 부모만 재배치 |
| 정보 분할 | 통과 | Presenter가 임무·전투 수치·생존·장비·무기·행동 도크를 독립 Panel로 만들고 계산 모듈에는 접근하지 않음 |
| 반응형 계약 | 통과 | 1100px 이상 player_orbit, 미만 compact_edge로 전환하며 좁은 화면에서는 상세 장비·무기만 숨김 |
| 키 재매핑 | 통과 | 행동 도크는 KeyMappingService가 전달한 8개 현재 바인딩 문자열만 소비하며 InputMap을 직접 변경하지 않음 |
| Web 안전 | 통과 | 상태 상징은 벡터 도형, 텍스트는 포함 폰트의 한글·영문·숫자로 제한해 브라우저 이모지 누락을 회피 |
| 플레이어 인식 | 통과 | 16개 아이콘·8개 행동, 툴팁 의미·수치 변화와 UI 상태 23개·인식 체크포인트 23개를 자동 판정 |
| Scene 충돌 회피 | 통과 | 사용자 game.tscn 변경은 건드리지 않고 Presenter·독립 HUD Scene·테스트만 변경 |
CombatHudPresenter는 배치와 표시 밀도만 소유합니다. 체력·무기·스킬·대시 모듈은 기존 공개 Signal과 스냅샷을 그대로 제공하므로 아이콘 세트나 화면 배치를 제거·교체해도 전투 규칙은 유지됩니다.
2026-08-31 전투 HUD 시선권 재구성 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 임무 추적기 | 통과 | 기존 맵·상태·시간 Label을 재배치할 뿐 방·탈출 상태를 다시 계산하지 않음 |
| 플레이어 주변 생존 코어 | 통과 | 체력·경험치·장비·무기 Label과 ProgressBar를 재사용하며 원본 Signal 연결 유지 |
| 스킬·대시 결합 | 통과 | 각 모듈의 공개 HUD Control 위치만 조정하고 쿨타임·에너지·이동 제공자에는 접근하지 않음 |
| 화면 경계 | 통과 | 338×108 임무, 224×86 생존, 104×267 이하 세로 스킬, 166×62 대시와 상호 교차를 1280×720에서 검사 |
| 상호작용 가시성 | 통과 | 프롬프트를 하단 코어 위 독립 영역에 두어 코어·스킬과 겹치지 않음 |
| Web 안전 문자 | 통과 | 새 게임 HUD 식별자는 영문·한글과 폰트 포함 문자만 사용하고 이모지에 의존하지 않음 |
| Scene 충돌 회피 | 통과 | 사용자 편집 중인 game.tscn은 수정하지 않고 Presenter와 독립 스킬 HUD 코드만 변경 |
CombatHudPresenter.attach_runtime_layers()는 UI 레이어가 설치된 뒤 화면 배치만 결합하는 조립 계약입니다. Presenter를 제거하면 원래 Scene 배치로 돌아가며 체력, 작전 목표, 스킬, 대시 계산에는 영향이 없습니다.
2026-08-31 작전 브리핑·전술 HUD 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 작전 브리핑 표현 | 통과 | OperationSetupPresenter가 기존 Control을 재배치하고 계약·맵·생성·프로필 스냅샷만 읽음 |
| 규모 선택·투입 확정 | 통과 | 규모 선택은 selected_map_size만 갱신하고 별도 Launch Signal에서 기존 start_run() 계약 호출 |
| 전술 프리뷰 | 통과 | 에셋과 맵 내부 배열 없이 지역·규모·난이도 ID만 받아 코드 드로잉 표현 |
| 전투 HUD 표현 | 통과 | CombatHudPresenter가 기존 Label·ProgressBar를 재사용하고 체력·경험치·전투 계산에는 접근하지 않음 |
| Scene 충돌 회피 | 통과 | 사용자 편집 중인 game.tscn을 수정하지 않고 Presenter 파일과 조립 코드만 추가 |
| 화면 경계 | 통과 | 1180×660 브리핑, 양쪽 500px 이상 열과 투입 버튼 포함 여부를 자동 검사 |
| 회귀 | 통과 | 소·중·대형 선택→확정, 실제 입력 E2E 21상태, HUD 비겹침·정산 복귀 계약 유지 |
Presenter는 도메인 결과를 새로 계산하지 않습니다. 비용·배율·보스·위험은 기존 서비스가 만들고 Presenter는 전달된 사본만 표시합니다. 따라서 작전 진입 화면이나 HUD를 다른 테마로 교체해도 계약·경제·맵·전투 모듈은 변경되지 않습니다.
2026-08-31 UI 상태 판정 E2E 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 상태 규칙 | 통과 | UIStateJudge가 거점·설정·전투·모달·결과 계약을 데이터 표로 소유하고 게임 로직을 호출하지 않음 |
| 실제 입력 결합 | 통과 | 기존 플레이 E2E가 K/I/U/E/F/Q와 성공·실패 흐름을 실행한 직후 판정기 공개 메서드만 호출 |
| 모달 배타성 | 통과 | 거점·전투 모두 표시 모달 1개와 배경 HUD 숨김·일시정지를 함께 검사 |
| 화면 경계·겹침 | 통과 | 유효 전역 Rect를 사용해 1280×720 이탈과 미니맵·스킬·대시 교차를 상태별 검사 |
| 결과 정산 격리 | 수정 후 통과 | E2E가 발견한 전투 HUD 4종 누수를 _hide_active_run_ui() 조립 경계에서 일괄 종료 |
| 성공·실패 복귀 | 통과 | 한 프로세스의 21개 전환에서 성공 결과·거점 복귀·재투입·실패 결과·거점 복귀를 연속 판정 |
| CI 배포 게이트 | 통과 | 21개 상태 계약·경계·모달·비겹침 성공 토큰이 없으면 Web 내보내기와 Pages 배포 중단 |
판정기는 UI를 직접 열거나 게임 상태를 수정하지 않는 테스트 전용 읽기 모듈입니다. 플레이 흐름은 E2E 러너, 화면 상태 규칙은 판정기, 실제 표시 전환은 Game 조립부가 각각 소유하므로 새 화면을 추가할 때 규칙 행만 확장할 수 있습니다. 이번 감사에서 결과 화면의 활성 전투 UI 종료 누수를 수정했으며 그 밖의 새 비모듈 도메인 접근은 발견되지 않았습니다.
2026-08-31 키 설정·상업 VFX 반입 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| Action 카탈로그 | 통과 | 21개 ID·표시명·분류를 KeyMappingCatalog Resource가 소유하고 UI는 목록을 하드코딩하지 않음 |
| 입력 적용·저장 | 통과 | KeyMappingService만 InputMap·중복 교환·JSON I/O를 담당하며 이동·전투·메뉴는 기존 Action만 소비 |
| 실제 이동 반영 | 통과 | PlayerMovement의 물리 WASD/Space 조회를 제거하고 이동 4축·대시 Action으로 완전 전환 |
| UI 교체·비활성화 | 통과 | KeyMappingPanel은 서비스 공개 계약만 사용하고 Manifest 한 항목으로 서비스와 화면을 함께 제거 가능 |
| 안전 닫기 | 통과 | ESC 재지정을 거부하고 입력 대기 취소·모달 닫기 경로를 항상 보존 |
| 상업 에셋 추적 | 통과 | Kenney CC0 원문·원본 커밋·선별 파일 SHA-256을 자산 폴더와 위키 원장에 보존 |
| Web 성능 경계 | 통과 | 기존 선분 예산에 프로필별 텍스처 강조를 추가하되 효과당 최대 16개, 동시 효과 3개 제한 유지 |
| 자동 검증 | 통과 | 기본 스모크가 21 Action·ESC·중복 교환·저장·CC0·드로우 예산을, E2E가 실제 K/ESC 화면 흐름을 검사 |
키 설정 로직을 플레이어·스킬·각 패널에 복제하지 않았습니다. Game은 서비스와 표현을 조립하고 현재 바인딩으로 안내 문구만 갱신하며, 입력 정책·저장 형식·충돌 규칙은 독립 모듈에 남습니다. 외부 VFX도 스킬 코드에 경로를 박지 않고 ElectricEffectProfile이 선택 텍스처와 강조 수를 주입하므로 CC0 자산을 제거하거나 다른 승인 자산으로 교체할 수 있습니다.
2026-08-31 기획 우선순위 10개 통합 감사¶
| 점검 대상 | 결과 | 독립성·교체 근거 |
|---|---|---|
| 좌클릭·1~9 입력 | 통과 | project.godot Action과 CombatSkillLoadout.slot_capacity를 실행기에서 소비하며 슬롯 재설정은 공개 메서드로 한정 |
| 스마트 타게팅 | 통과 | 하나의 resolve(mode, context) 정책이 적 스냅샷만 읽고 무기·스킬은 정책 ID만 소유 |
| 탈출 일시정지 | 통과 | ExtractionZone이 남은 시간과 Signal만 소유하고 정산·적 생성·UI는 내부 타이머를 읽지 않음 |
| 사망 로드아웃 손실 | 통과 | 세션 조립부가 장비 준비 상태 공개 계약만 호출하고 인벤토리 슬롯 배열을 직접 수정하지 않음 |
| 투자·보스·드랍 | 통과 | 계약 Resource가 비용·보스·등급·지역 드랍 결과를 계산하고 생성기·정산기는 결과 사본만 소비 |
| 영구 상점 등록 | 통과 | 프로필은 등록 ID만 저장하고 가격·조건·구매 결과는 HubEconomyConfig와 시스템에 유지 |
| 태그·등급·상태 연계 | 통과 | 장비는 태그·수정자 조회, 적은 상태 저장, 효과는 부여·소비 규칙만 각각 담당 |
| 페널티 적용 | 통과 | 회복·시야·탈출 최종 배율을 각 모듈 공개 setter로 전달하며 페널티 시스템이 내부 Node를 참조하지 않음 |
| 조건부 3종 랭킹 | 통과 | 정책이 종목·정렬·최소 점수를 소유하고 저장 시스템은 조건별 사다리만 관리 |
| 선택 비활성화·회귀 | 통과 | 기존 Manifest 폴백과 모듈별 기본값을 유지하고 스모크 테스트에서 입력·계약·정산·저장 경계를 검증 |
| 대형 작전 성능 | 통과 | 1280×720, 방 적 14명, CC0 강조 포함 전기 효과 3개 조건에서 평균 6.888ms·최대 7.952ms·Node 1,435 |
새 규칙을 Game의 계산식으로 합치지 않았습니다. Game은 계약 생성, 제공자 주입과 Signal 연결만 담당하고 비용·대상·스킬 호환·드랍·페널티·랭킹 계산은 각 기능 폴더에 남습니다. 현재 감사에서 새로 발견된 비모듈 도메인 접근은 없습니다. 사용자 키 설정 저장은 후속 구현으로 완료됐고, 영구 상점 전용 UI와 서버 랭킹은 완성된 공개 계약 위에 제공자를 추가하는 후속 범위입니다.
2026-08-30 전투 자원·드랍 회복·레벨업 회복 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 공용 에너지 | 통과 | 최대량·시작량을 CombatResourceConfig가 소유하고 스킬 실행기는 제공자의 조회·소비 계약만 호출 |
| 슬롯별 충전 | 통과 | 최대 충전과 복구 시간은 각 CombatSkillDefinition에 남겨 스킬별 독립 교체 가능 |
| 적 처치 드랍 | 통과 | 적은 사망 위치만 Signal로 전달하고 에너지·체력 드랍률·수량·최소 보정은 자원 시스템에 격리 |
| 체력 적용 | 통과 | 결정과 레벨업 모두 플레이어의 heal() 계약을 사용하고 HP 계산을 복제하지 않음 |
| 레벨업 회복 | 통과 | ProgressionSystem이 레벨당 HP 12를 소유해 임시 버프 UI 활성 여부와 무관하게 정확히 한 번 적용 |
| 선택 비활성화 | 통과 | combat_resources_enabled=false에서 결정·에너지 HUD만 제거되고 쿨타임 전용 세 스킬 유지 |
| 자동 검증 | 통과 | 소비·부족 차단·충전 복구·2종 드랍 수집·레벨업 회복·HUD·비활성 폴백 검사 |
전투 자원을 스킬 효과나 적 스크립트에 넣지 않고 CombatResourceSystem이라는 정책·상태 제공자로 분리했습니다. 체력 결정과 경험치 결정은 각각 독립 Scene이며, 한 모듈을 끄거나 드랍 표현을 교체해도 적 생성·피해·경험치·스킬 효과가 유지됩니다.
대형 방·적 14명·전기 효과 3개·전투 자원 활성 조건에서 평균 6.889ms, 최대 8.435ms, Node 1,291개로 성능 예산을 통과했습니다.
2026-08-30 적 군중 분리·생성 간격 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 생성 겹침 방지 | 통과 | 생성기가 기존 적과 40px 이상 떨어진 걸을 수 있는 후보만 승인하며 후보가 없으면 요청을 취소 |
| 이동 중 분리 | 통과 | 적은 주입된 get_separation_vector() 계약만 사용하고 생성기 목록이나 SceneTree 그룹을 직접 읽지 않음 |
| 좁은 통로 흐름 | 통과 | 적끼리 강체 충돌을 추가하지 않고 추적 벡터에 분리 조향만 합성해 상호 봉쇄를 피함 |
| 정책 교체·비활성화 | 통과 | 반경·강도·간격·이웃 수·갱신 간격을 EnemyCrowdConfig에 격리하고 enabled=false 폴백 검증 |
| 계산량 제한 | 통과 | 적별 0.08초 분산 갱신과 가까운 이웃 최대 8명 제한, 대형 방 성능 게이트 유지 |
| 자동 검증 | 통과 | 동일 좌표 2회 생성 간격, 완전 중첩 시 반대 벡터, 실제 이동 분리와 정책 비활성화를 검사 |
적의 체력·피해·길찾기에는 군중 규칙을 추가하지 않고 선택 제공자와 설정 Resource만 주입했습니다. Game은 생성기 공개 계약을 확인할 뿐 분리 계산을 수행하지 않으며, 방 전투와 전역 증원은 같은 생성 간격 정책을 공유합니다.
대형 맵·방 적 14명·전기 효과 3개 조건에서 평균 6.894ms, 최대 8.134ms, Node 1,280개로 기존 성능 예산을 통과했습니다.
2026-08-30 방·통로 안개 문턱 전환 감사¶
| 점검 대상 | 결과 | 독립성·검증 근거 |
|---|---|---|
| 방/통로 상태 전환 | 통과 | 안개 모듈이 입장 0.22초·퇴장 0.32초 혼합값만 소유하고 맵 판정 계약은 변경하지 않음 |
| 문턱 마스크 | 통과 | 전환 중인 방만 차단 예외로 전달하며 나머지 방은 기존 Shader 마스크로 계속 차단 |
| 렌더러 분리 | 통과 | 인라인 Shader를 fog_of_war.gdshader로 분리해 상태기계와 픽셀 표현을 독립 교체 가능 |
| 미니맵 격리 | 통과 | 월드 안개만 변경하고 전체 지형 미니맵 스냅샷·렌더링에는 접근하지 않음 |
| 자동 검증 | 통과 | 방 완전 공개, 퇴장 중간값, 통로 완전 전환, 입장 중간값과 재공개를 모두 검사 |
| 성능 예산 | 통과 | 대형 맵·적 72명에서 평균 6.893ms, 최대 10.303ms, Node 1,510개 |
방 경계에서 즉시 모드를 바꾸던 시각적 끊김을 시간 기반 크로스페이드로 교체했습니다. 조절 수치는 안개 Scene의 export 값이며 Game, 맵 생성기, 플레이어에 전환 규칙을 복제하지 않았습니다.
2026-08-30 작전·영구 경제·정책 시스템 전체 감사¶
| 모듈 | 결과 | 독립 비활성화·교체 근거 |
|---|---|---|
| 탈출 방어전 | 통과 | ExtractionZone이 카운트다운·구역 유지와 Signal만 소유하고 시간은 ExtractionDefenseConfig로 주입하며 토글 해제 시 즉시 탈출 |
| 결과 정산 | 통과 | OperationResultService가 프로필·랭킹 공개 계약만 사용하고 도면·고철 정책은 OperationResultConfig로 분리 |
| 작전 계약 | 통과 | 지역·난이도 비용·적·회수 배율을 OperationContractConfig에 분리 |
| 영구 프로필 | 통과 | 크레딧·해금·창고·소모품·도면·제작품 저장만 담당하고 가격·전투 규칙을 모름 |
| 상점·창고 | 통과 | HubEconomySystem이 카탈로그 가격과 프로필 소비 계약만 조정 |
| 스마트 타게팅 | 통과 | SmartTargetingPolicy Resource를 자동 무기에 주입, 해제 시 최근접 폴백 |
| 도면 제작 | 통과 | 제작식·옵션 풀 Resource와 프로필 재료 계약 분리, 장비 슬롯 직접 접근 없음 |
| 페널티 변형 | 통과 | 선택·합성·보상 배율만 공개하고 적 인스턴스에는 최종 수정자 사본만 전달 |
| 조건부 랭킹 | 통과 | 문자열 조건 키별 제출·조회·저장을 격리하고 점수·보관 개수는 ConditionalRankingPolicy로 주입 |
| 선택 모듈 조합 | 통과 | 8개 신규 토글을 모두 끈 게임이 기존 최근접 공격·즉시 탈출·기본 작전을 유지 |
| 자동 검증 | 통과 | 비용 173 C, 회수 ×2.325, 장갑 ×1.875, 소모품·제작·랭킹·방어 카운트다운 확인 |
영구 상태를 중앙 Game이나 런타임 CreditLedger에 추가하지 않고 전투 세션 밖의 PersistentProfile로 옮겼습니다. Game은 선택값을 서비스 사이에 전달하고 결과 문자열을 조립할 뿐 가격, 점수, 랜덤 옵션, 적 배율을 다시 계산하지 않습니다.
대형 맵·스마트 타게팅·적 72명 조건의 성능 회귀는 평균 6.890ms, 최대 10.327ms, Node 1,480개로 기존 예산을 통과했습니다.
2026-08-30 전기 스킬·엄격 성능 예산 재점검¶
| 점검 대상 | 결과 | 교체·최적화 근거 |
|---|---|---|
| 전기 표현 교체 | 통과 | 공용 ElectricArcEffect가 렌더링만 담당하고 각 스킬은 독립 ElectricEffectProfile Resource를 주입 |
| 스킬 규칙 분리 | 통과 | 점멸 이동·경로 피해, 자기장 피해, 가속 스탯 규칙은 전기 프로필의 패턴·색·밀도를 모름 |
| 점멸 피해 교체 | 통과 | 피해량 12·경로 폭 80px·최대 24명은 독립 PathDamagePolicy Resource이며 제거 시 이동 전용 폴백 |
| 이펙트 연산 예산 | 통과 | 프로필당 최대 128 선분, 10~20Hz 형상 재생성, 기본 동시 효과 3개로 제한 |
| HUD 부하 | 통과 | 쿨타임 상태 Signal을 10Hz로 제한하고 발동·준비 완료만 즉시 전송 |
| 지속 효과 부하 | 통과 | 가속 해제를 per-frame Node 대신 one-shot Timer로 전환 |
| 범위·경로 부하 | 통과 | 자기장 임시 배열 제거, 점멸 경로 판정은 발동 순간·최대 24타격 제한, 적 A* 0.7초 분산 갱신 적용 |
| 맵 Node 부하 | 통과 | 인접 벽·설비 셀 충돌체 병합으로 대형 맵 774개, 원시 셀 대비 6.7% 달성 |
| 엄격 자동 검증 | 통과 | 대형 맵·적 72명에서 평균 6.887ms, 최대 10.328ms, Node 1,490개, 전기 효과 3개 |
전기 효과는 스킬 정의가 소유하는 별도 데이터이므로 특정 효과만 비활성화하거나 다른 시각 렌더러로 바꿔도 이동·피해·버프·쿨타임은 유지됩니다. 맵 충돌체 병합과 적 경로 캐시는 각각 맵 생성기와 적 모듈 내부 최적화이며 Game 조립부나 다른 기능에 성능 정책을 복제하지 않았습니다.
측정값은 Ryzen AI Z2 Extreme 개발 환경의 헤드리스 CPU 회귀 결과입니다. 실제 최소 사양 인증은 별도 저사양 GPU에서 수행해야 하며, 임시 목표와 출시 전 절차는 최소·권장 사양과 성능 예산을 따릅니다.
2026-08-30 전투 스킬·쿨타임 HUD 점검¶
| 점검 대상 | 결과 | 근거 |
|---|---|---|
| 효과 교체 가능성 | 통과 | 점멸·자기장·가속을 각각 독립 CombatSkillEffect Resource로 구현하고 점멸 피해 정책도 별도 주입 |
| 입력·쿨타임 분리 | 통과 | 실행기는 정의의 입력 Action과 재사용 시간만 읽고 효과 세부 동작을 모름 |
| HUD 분리 | 통과 | HUD는 skill_states_changed와 get_skill_states()만 소비하며 비용 표기는 Web-safe EN으로 제한 |
| 기존 스탯 조합 | 통과 | 가속은 플레이어 수정자 출처 계약을 사용해 장비·버프와 곱연산으로 합성 |
| 적 결합 제거 | 통과 | 자기장과 점멸 정책은 컨테이너에서 take_damage() 계약을 제공하는 대상만 호출 |
| 선택 비활성화 | 통과 | Manifest에서 끄면 실행기·HUD가 모두 사라지고 기존 자동 공격은 유지 |
| 자동 검증 | 통과 | 숫자키, 점멸 거리·경로 안/밖 피해·쿨타임, 자기장 피해, 55% 가속, Web-safe HUD와 비활성 폴백 확인 |
장비의 스킬 호환성 정의와 이번 전투 효과 정의는 의도적으로 분리했습니다. 현재는 기본 세 효과를 직접 검증하고, 후속 작업에서 장비 스킬 ID를 전투 정의 ID에 매핑합니다. 이 연결 전에도 장비·자동 무기·내부 성장 기능은 전투 스킬 모듈 없이 독립 실행됩니다.
2026-08-30 시작 거점·전투 세션 전환 점검¶
| 점검 대상 | 결과 | 교체·확장 근거 |
|---|---|---|
| 큰 단일 방 | 통과 | StartHub가 1800×1040px 방 크기, 경계 충돌과 스폰 위치를 독립 소유 |
| 작전 게이트 | 통과 | F 입력·거리 판정 뒤 operation_requested Signal만 발생하며 전장 등급을 모름 |
| UI 분리 | 통과 | 거점 HUD와 세션 구성 UI는 선택값만 Game.start_run()에 전달 |
| 전투 진입 | 통과 | 거점 Node를 제거한 뒤 기존 맵·전투 모듈을 새로 조립 |
| 거점 복귀 | 통과 | 결과 정산 후 전투용 World·Modules·동적 UI만 해제하고 거점을 재설치 |
| 선택 기능 폴백 | 통과 | start_hub_enabled를 끄면 기존 선택 화면, run_setup_enabled를 끄면 기본 작전으로 즉시 진입 |
| 자동 검증 | 통과 | 방 1개·화면 이상 크기, 게이트 F, UI ESC, 전투 진입과 결과 후 거점 복귀 확인 |
거점은 맵 생성기나 전투 서비스를 참조하지 않습니다. 반대로 전투 맵은 거점의 방 크기·게이트를 알지 못합니다. Game에 남은 결합은 두 세션의 설치·해제 순서를 관리하는 조립 책임이며 게임 규칙 계산은 포함하지 않습니다.
2026-08-30 성장 밸런스 Google Sheets 연동 점검¶
| 점검 대상 | 결과 | 교체·확장 근거 |
|---|---|---|
| 내부 성장 선택지 | 통과 | RunBuff CSV를 RunBuffCatalog로 변환하고 RunBuffSystem.set_catalog() 계약으로 교체 |
| 무기·방어구 레벨 효과 | 통과 | 장비 ID·레벨별 수정자만 제공하고 실제 스탯 집계와 발사는 기존 장비·무기 모듈이 담당 |
| 모듈 장착·강화 | 통과 | 모듈 ID·현재 레벨로 장착 코스트와 다음 강화 견적을 조회하며 인벤토리·크레딧 소비 계약은 유지 |
| 실시간/확정 모드 | 통과 | 공개 CSV 3초 갱신, 마지막 정상값 유지, 확정 CSV 폴백과 배포 기본값 분리 |
| 독립 비활성화 | 통과 | growth_balance_enabled를 끄면 기존 RunBuff Resource와 강화 비용 Resource로 복귀 |
| 자동 검증 | 통과 | 5개 버프·25개 강화 행, 무기·방어구·모듈 수치와 잘못된 갱신 보존을 검사 |
GrowthBalanceService는 RunBuffSystem, EquipmentSystem, AutoWeapon, EquipmentUpgradeService의 내부 Node나 저장 구조에 접근하지 않습니다. Game은 기능 설치와 제공자 주입만 담당하며 시트 값 계산을 복제하지 않습니다. 성장 시트를 제거하거나 다른 데이터 서비스로 바꿔도 기존 Resource 폴백이 유지되므로 현재 발견된 비모듈 결합은 없습니다.
2026-08-30 회수 범위·유한 증원·동적 이동 재점검¶
| 점검 대상 | 결과 | 교체·확장 근거 |
|---|---|---|
| 회수 배수 범위 | 통과 | 2.5·5.0을 LootTierConfig의 최소·최대 필드로 분리해 코드 변경 없이 축소·확장 가능 |
| 정확한 목표 총액 | 통과 | LootSpawner가 선택 배수와 가능한 지점 수를 계산하고 개별 값을 상·하향해 목표와 일치 |
| 적 재생성 한계 | 통과 | 등급별 maximum_total_spawns가 최초 배치와 모든 증원을 함께 제한 |
| 생성 종료 사건 | 통과 | 남은 예산·소진 상태를 스냅샷으로, 최초 소진을 spawn_budget_exhausted Signal로 공개 |
| 핵앤슬래시 이동 | 통과 | 초동·선회·역선회·회피 종료 관성을 PlayerMovement export 값과 순수 계산 메서드로 격리 |
| 조립부 경계 | 통과 | Game은 Resource 전달과 Signal 계약 검사만 수행하며 경제·생성·속도 계산을 복제하지 않음 |
| 자동 검증 | 통과 | 세 등급 2.5~5배 수용량·정확한 총액, 2회 한계 뒤 무스폰, 이동 응답 단계를 확인 |
이번 임시 밸런스 값은 기능별 Resource에만 존재합니다. 회수 배수를 바꿀 때는 회수 지점의 수용량만 함께 확인하면 되며 맵·크레딧 원장·탈출 코드는 수정하지 않습니다. 총 적 생성량을 바꿀 때도 적 능력치나 자동 무기를 수정하지 않습니다. 이동 계산은 물리 충돌과 장비 스탯 적용으로부터 분리되어 다른 캐릭터용 설정이나 구현으로 교체할 수 있습니다.
2026-08-30 방·통로 방향성 시야 점검¶
| 점검 대상 | 결과 | 근거 |
|---|---|---|
| 플레이어 정면 방향 | 통과 | 화면용 Heading 내부 Node 대신 get_facing_direction() 계약 사용 |
| 방 전체 공개 | 통과 | 현재 좌표의 방 경계 복사본만 Shader에 전달하고 방 배열은 비공개 유지 |
| 통로 방향 시야 | 통과 | 170px 주변 시야와 정면 780px·반각 62도 원뿔을 안개 모듈에서 계산 |
| 다른 방 차단 | 통과 | 통로 Shader가 화면과 겹치는 방 사각형만 선별해 내부를 시야에서 제외 |
| 미니맵 독립성 | 통과 | 안개 CanvasLayer와 전체 지형 미니맵 데이터·UI 레이어 분리 유지 |
| 자동·실제 렌더 검증 | 통과 | 세 등급 방/통로 판정과 1280×720 방·통로 화면을 각각 확인 |
맵은 get_visibility_region()과 get_visibility_room_rects()만 추가했으며 안개 Shader나 플레이어 방향을 알지 않습니다. 안개는 맵의 rooms, floor_cells, A* 객체에 접근하지 않고 복사된 Rect2만 화면 좌표로 변환합니다. 맵 제공자가 없으면 통로 원뿔 시야 폴백을 유지합니다.
2026-08-30 증원 전투·배치 가치·전체 결합 재점검¶
| 점검 대상 | 발견 내용 | 조치 | 결과 |
|---|---|---|---|
| 적 수량 계산 | SceneTree 전체 enemies 그룹을 직접 집계 |
생성기가 자신이 만든 인스턴스만 추적하고 스냅샷으로 공개 | 통과 |
| 생성 밸런스 | 최대 수량·간격이 Scene export 상수에 고정 | 등급별 EnemySpawnTierConfig Resource로 이동 |
통과 |
| 자동 무기 대상 | 자동 무기가 전역 적 그룹을 직접 검색 | 생성기의 get_active_targets() 제공자 계약을 주입 |
통과 |
| 플레이어 체력 초기화 | 조립부가 current_health 내부 필드를 읽음 |
get_health_snapshot() 공개 계약 사용 |
통과 |
| 파밍 맵 계약 | 검사 메서드와 실제 호출 메서드가 달랐음 | get_loot_spawn_points()로 계약을 단일화 |
통과 |
| 배치 경제 | 무작위 총액이 투입 코스트보다 낮을 수 있었음 | LootTierConfig의 2.5배 정책과 부족분 분배·스냅샷 추가 |
통과 |
| 선택 기능 폴백 | 맵·장비·밸런스·성장 기능 비활성화 조합 | 기존 자동 테스트 유지, 맵 없이도 증원 정책은 원형 스폰으로 동작 | 통과 |
현재 구현된 기능에서 발견된 숨은 전역 집계와 내부 필드 접근은 제거했습니다. Game은 기능별 _install_*() 함수에서 Scene을 지연 로딩하고 공개 메서드·Signal을 검사한 뒤 제공자를 연결하는 조립부만 담당합니다. 수량 정책, 가치 보정, 전투 실행은 각 기능 폴더 안에 남습니다.
game_modal_panel 그룹은 I/U 창이 서로를 닫기 위한 명시적 UI 조정 프로토콜이며 도메인 상태를 읽지 않습니다. 자동 무기의 fallback_target_group은 Scene 단독 실행용 공개 폴백이고, 실제 게임 조립에서는 적 생성 제공자가 주입됩니다.
2026-08-30 화면 크기 방·전장의 안개·자원 회수 점검¶
| 점검 대상 | 결과 | 근거 |
|---|---|---|
| 화면 한 장급 방 | 통과 | 세 등급의 최소 방이 모두 40×23셀을 넘고 32px 타일 기준 1280×720 이상 |
| 실내 장애물 구조 | 통과 | 문 있는 긴 칸막이, 넓은 설비 블록, 다중 기둥을 방별 패턴으로 생성 |
| 전장의 안개 분리 | 통과 | 별도 Scene·Manifest 토글이며 추적 Node2D와 시야 설정만 소비 |
| 전체 미니맵 유지 | 통과 | 안개는 월드 layer 0에만 렌더링하고 미니맵은 전체 지형 스냅샷 크기를 유지 |
| 자원 배치 다양성 | 통과 | 맵은 위치·방향·유형 힌트, 파밍은 외형·문구·보상과 1회성 회수를 담당 |
| 자동·시각 검증 | 통과 | 세 등급 구조·경로·회수 유형, 안개 추적·전체 지도와 1280×720 렌더를 확인 |
전장의 안개는 맵 배열과 미니맵 텍스처에 접근하지 않으며, 파밍 오브젝트는 맵의 방·A* 내부 상태를 읽지 않습니다. 넓어진 방과 실내 패턴은 기존 MapTierConfig·맵 생성기 경계 안에 남아 있어 각 기능을 독립적으로 비활성화하거나 교체할 수 있습니다.
2026-08-30 장비·모듈 UI 재설계 점검¶
| 점검 대상 | 결과 | 근거 |
|---|---|---|
| U 화면 교체 가능성 | 통과 | UI Scene과 스크립트가 equipment, inventory, upgrade 제공자의 공개 메서드만 소비 |
| 장비 직접 선택 | 통과 | 가방 스냅샷의 instance_id를 선택하고 장비 승인 뒤에만 take_item() 호출 |
| 모듈·파츠 규칙 위임 | 통과 | UI는 can_install_module, can_install_part 결과만 표현하고 규칙을 복제하지 않음 |
| 강화 경제 분리 | 통과 | 선택 카드의 견적·강화는 EquipmentUpgradeService 계약으로 위임 |
| 표시 순서 | 통과 | 패널이 열릴 때 UI 형제 중 앞으로 이동해 미니맵·HUD와 겹치지 않음 |
| 자동 검증 | 통과 | 전체 화면 크기, 장비 카드, 모듈 카드, 장착 슬롯과 U 패널 계약을 스모크 테스트에서 확인 |
카드 색상·배치·필터는 표현 계층에만 있고 장비 장착, 소켓, 모듈 코스트, 강화 비용의 진실은 기존 상태·서비스 모듈에 남아 있습니다. 따라서 U 화면을 제거해도 기본 로드아웃과 I 가방은 유지되며, 동일 공개 계약을 구현한 다른 UI로 교체할 수 있습니다.
2026-08-30 맵·페이싱·이동·회복 점검¶
| 점검 대상 | 결과 | 근거 |
|---|---|---|
| 맵 규모 데이터 | 통과 | 세 등급의 방 수·면적·목표 시간·탈출 개방 시간을 MapTierConfig Resource로 관리 |
| 약 10분 런 페이싱 | 통과 | 소형 9분·중형/대형 10분 목표와 같은 시각의 탈출 잠금 해제를 데이터로 검증 |
| 탈출 시간 잠금 | 통과 | 탈출 Scene은 set_locked() 계약만 받고 등급 Resource나 Game 타이머를 모름 |
| 반응형 이동 | 통과 | PlayerMovement.step_velocity()가 가속·제동·역선회·회피 상태를 독립 계산 |
| 부분 체력 회복 | 통과 | 별도 Scene·설정 Resource·Manifest 토글, 체력 Signal과 공개 메서드만 소비 |
| 자동 검증 | 통과 | 세 맵 상향 기준, 이동 응답, 회피 속도, 회복 지연·65% 상한, 조기 탈출 거부를 확인 |
이동은 플레이어의 물리 충돌을 구현하지 않고 결과 속도만 반환합니다. 회복 모듈은 플레이어의 current_health 내부 필드나 장비를 직접 참조하지 않습니다. 따라서 이동 계산이나 회복 정책을 교체해도 맵·전투·장비 모듈은 유지됩니다.
2026-08-30 플랫포머형 이동 응답 재점검¶
| 점검 대상 | 결과 | 근거 |
|---|---|---|
| 즉시 출발·정지 | 통과 | 초동 비율·일반 가속·제동·정지 스냅을 PlayerMovement export 값으로 독립 조정 |
| 90도·180도 방향 전환 | 통과 | 횡방향 그립과 반전 속도 보존율을 충돌·애니메이션과 분리한 순수 속도 계산으로 적용 |
| 회피 종료 제어 | 통과 | 종료 배율과 지속시간을 기존 대시 상태 계약 안에서 축소하며 스킬·장비를 참조하지 않음 |
| 카메라 응답 | 통과 | Camera2D의 표현 설정만 조정하고 이동 결과나 월드 좌표 계약은 변경하지 않음 |
| 자동 검증 | 통과 | 16ms 초동·완전 정지·역선회·횡미끄러짐 상한·대시와 종료 속도를 스모크 테스트에서 확인 |
PlayerCharacter는 여전히 PlayerMovement.get_velocity()가 반환한 속도만 적용합니다. 새 그립·스냅·반전 정책은 맵, 전투, 장비 또는 카메라에 접근하지 않으므로 값 변경이나 이동 컴포넌트 교체가 다른 기능의 수정으로 번지지 않습니다.
2026-08-30 전체 기능 재점검¶
현재 개발된 기능은 FeatureManifest로 선택 가능하고 공개 메서드·Signal·Resource 경계가 드러난 모듈 구조입니다. 이번 점검에서 내부 경험치, 임시 버프, 외부 성장, 장비 강화 경제를 각각 별도 폴더와 토글로 추가했으며, 강화 서비스가 크레딧 내부 변수를 직접 읽던 지점도 get_snapshot() 공개 계약으로 교체했습니다.
| 점검 대상 | 결과 | 독립 비활성화·교체 근거 |
|---|---|---|
| 기존 맵·전투·장비·인벤토리·경제 | 통과 | 기존 토글·폴백 스모크 테스트 유지 |
| 내부 XP와 레벨 | 통과 | experience, leveling 토글과 ProgressionSystem으로 분리 |
| 한 판 임시 버프 | 통과 | run_buffs 토글, 카탈로그 Resource, 플레이어·무기 수정자 출처 계약 사용 |
| 외부 성장·저장 | 통과 | meta_progression 토글, 세 계열 스냅샷과 JSON 저장을 독립 담당 |
| 모듈·고유 파츠 강화 경제 | 통과 | 비용 정책, 인벤토리 소비, 크레딧 소비, 장비 상태 변경을 네 계약으로 분리 |
| 선택 모듈 조합 | 통과 | 성장 3개 모듈과 강화 경제를 끈 상태에서도 기본 경험치·장비 루프 유지 |
| 자동 검증 | 통과 | 버프 선택·중첩·외부 정산·세 계열 효과·재료/크레딧 소비를 스모크 테스트로 확인 |
Game은 설치 순서를 아는 중앙 조립 지점이며 기능별 _install_*() 함수와 계약 검사로 구획되어 있습니다. 이는 의도된 결합이고 기능 구현은 포함하지 않습니다. 현재 기능을 끄거나 교체하는 데 막히는 숨은 Node 경로 의존성은 발견되지 않았습니다.
2026-08-29 랜덤 맵 모듈¶
결론은 MVP 단계에서 교체 가능한 선택 모듈로 분리되어 있음입니다. 맵의 생성 알고리즘과 등급 데이터는 한 기능 폴더 안에 있고, 플레이어·적·무기 모듈은 MapTierConfig나 방 배열을 직접 알지 않습니다.
다만 현재 구조는 Godot 애드온 수준의 완전한 플러그인 시스템은 아닙니다. 최상위 Game이 기능 경로와 공개 계약을 알고 조립하는 경량 모듈 구조입니다.
점검표¶
| 항목 | 결과 | 근거 |
|---|---|---|
| 기능 폴더 응집도 | 통과 | 생성기, Scene, 등급 Resource가 game/features/map_generation/에 모여 있음 |
| 정적 의존성 격리 | 통과 | 다른 기능은 MapTierConfig와 맵 내부 Node 경로를 참조하지 않음 |
| 런타임 선택 로딩 | 통과 | map_generation_enabled가 켜진 경우에만 문자열 경로로 Scene을 로드함 |
| 비활성화 폴백 | 통과 | 맵을 끄면 원점 스폰, 원형 적 스폰, 직선 추적으로 복귀함 |
| 대체 구현 계약 검사 | 통과 | Game과 EnemySpawner가 필요한 Signal·메서드 존재 여부를 검사함 |
| 데이터 분리 | 통과 | 비용, 방 수, 방 크기는 소·중·대형 .tres Resource에서 변경 가능 |
| 자동 검증 | 통과 | 세 등급 연결성 및 맵 비활성화 조립을 스모크 테스트로 확인함 |
| 하위 기능 토글 | 통과 | 방해물, 작전 선택, 탈출을 각각 Manifest에서 비활성화할 수 있음 |
| 전투 상태 분리 | 통과 | 적 이동 코드와 체력·방어력·상태바 컴포넌트를 분리함 |
| 파밍 데이터 분리 | 통과 | 맵 Resource가 아닌 LootTierConfig가 상자 수와 보상을 소유함 |
| 1회성·회수 검증 | 통과 | 같은 상자의 중복 획득 차단과 탈출 회수까지 자동 테스트함 |
| 미니맵 경계 | 통과 | 미니맵은 맵 내부 객체 대신 복사된 지형 스냅샷만 소비함 |
| 전체 티어 진입 | 통과 | 소·중·대형 버튼 입력부터 플레이어·맵·탈출·미니맵 설치까지 자동 검증함 |
| 장비 데이터 분리 | 통과 | 무기·스킬·방어구·로드아웃을 독립 Resource로 정의함 |
| 무기 태그 확장성 | 통과 | enum 대신 3단계 StringName ID를 사용해 새 분류를 데이터로 추가함 |
| 스킬 호환성 | 통과 | 슬롯과 대·중·소분류가 모두 맞는 경우만 활성화하며 0~10개 제한을 검증함 |
| 방어구 스탯 확장성 | 통과 | 범용 stat_id와 더하기·곱하기 수정자를 집계함 |
| 장비 비활성화 | 통과 | 장비를 끄면 시스템·HUD·스탯 적용 없이 플레이어 기본값을 유지함 |
| 격자 인벤토리 경계 | 통과 | 가변 크기 아이템의 경계·겹침·이동과 모듈 1×1 규칙을 독립 테스트함 |
| 장비 슬롯 규칙 | 통과 | 메인·보조·신체·신발 슬롯이 태그와 방어구 위치를 검사함 |
| 고유 파츠 격리 | 통과 | 무기 소분류와 소켓이 모두 맞는 경우만 파츠를 허용하고 방어구는 거부함 |
| 모듈 코스트·강화 | 통과 | 슬롯·코스트 초과 거부와 강화 단계별 코스트 감소를 검증함 |
| 최고 레벨 개조 | 통과 | 최고 레벨에서만 태그를 부여하고 일치 모듈 코스트를 50%로 계산함 |
| 장비 개조 의존성 | 통과 | equipment_customization이 equipment, inventory를 요구함 |
| 활성 무기 상태 분리 | 통과 | 장비는 main/secondary 슬롯과 weapon_id만 공개하고 발사 로직을 모름 |
| 밸런스 데이터 분리 | 통과 | weapon_balance/가 2행 설명을 포함한 Google Sheets·확정 CSV 로드와 검증만 담당함 |
| 실시간 실패 폴백 | 통과 | 잘못된 외부 CSV가 마지막 정상값을 덮지 않으며 확정 CSV로 복구 가능 |
| 무기 특색 실행 | 통과 | AutoWeapon이 버스트·다중 투사체를, Projectile이 관통·유지율을 담당함 |
| Q 교체 자동 검증 | 통과 | 장비 슬롯, 자동 공격 런타임, HUD가 같은 보조 권총 상태로 전환됨 |
맵 모듈 공개 계약¶
대체 맵 Scene도 아래 계약만 제공하면 소비자 코드를 유지할 수 있습니다.
| 종류 | 이름 | 소비자 |
|---|---|---|
| Signal | map_generated(display_name, entry_cost, room_count, maximum_rooms, used_seed) |
HUD |
| Method | configure_obstacles(is_enabled) |
방해물 기능 토글 전달 |
| Method | generate(config, requested_seed) |
Game 조립부 |
| Method | get_player_spawn_position() |
플레이어 배치 |
| Method | get_extraction_position() |
탈출 모듈 배치 |
| Method | get_enemy_spawn_position(origin, minimum_distance) |
적 생성기 |
| Method | get_visibility_region(world_position) |
방·통로 안개 모드 |
| Method | get_visibility_room_rects() |
다른 방 차단 마스크 |
| Method | get_loot_spawn_points(count) |
파밍 위치·벽 방향·배치 유형 제공 |
| Method | get_world_path(from_world, to_world) |
적 이동 |
| Method | get_minimap_snapshot() |
전술 미니맵 조립부 |
소비자는 구체 클래스 대신 Node와 위 메서드의 존재 여부를 사용합니다. 따라서 다른 알고리즘으로 맵 생성기를 교체할 때도 계약만 유지하면 됩니다.
적 생성·대상 제공 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 생성 정책 | 최소·최대 동시 수량, 증원 묶음·간격·반경 | EnemySpawner |
| 적 생성기 | configure, get_snapshot |
Game, 자동 테스트 |
| 적 생성기 | get_active_targets |
자동 무기 |
| 적 생성기 | enemy_spawned, reinforcement_dispatched |
전투 조립·향후 증원 연출 |
| 자동 무기 | set_target_provider |
Game 조립부 |
생성기는 맵 등급의 문자열 ID로 정책 Resource만 선택하며 맵 방 배열을 읽지 않습니다. 자동 무기는 생성기 내부 추적 배열이 아닌 복사된 대상 목록만 받습니다.
탈출 모듈 공개 계약¶
| 종류 | 이름 | 소비자 |
|---|---|---|
| Signal | extraction_completed(actor) |
작전 결과 처리 |
| Signal | interaction_availability_changed(available, prompt) |
HUD F 안내 |
| Method | configure(world_position) |
탈출 위치 배치 |
| Method | request_extraction(actor) |
범위와 플레이어 검사 |
| Method | set_locked(is_locked, prompt) |
조립부에서 시간 잠금 상태 전달 |
탈출 모듈은 맵의 내부 자료구조 대신 월드 좌표 하나만 전달받습니다.
플레이어 이동·회복 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 이동 | step_velocity(current, input, delta, dash_pressed) |
플레이어 물리 이동·자동 테스트 |
| 이동 | get_movement_snapshot() |
플레이어·향후 이동 HUD |
| 플레이어 | health_changed, get_health_snapshot(), heal() |
부분 회복 모듈 |
| 부분 회복 | configure, advance, get_snapshot |
Game 조립부·자동 테스트 |
파밍과 크레딧 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 맵 | get_loot_spawn_points(count) |
LootSpawner |
| 회수 지점 | configure(amount, kind, facing), credits_collected |
LootSpawner |
| 파밍 | credits_looted(amount, world_position) |
Game 조립부 |
| 파밍 | get_spawn_snapshot() |
조립부·자동 테스트 |
| 원장 | add_carried, secure_carried, lose_carried |
Game 조립부 |
맵은 파밍 보상 수치를 알지 않고, 파밍 모듈은 맵의 방 배열과 A* 자료구조를 알지 않습니다.
전장의 안개 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 안개 | configure(tracked_actor, visibility_provider) |
Game 조립부 |
| 안개 | get_snapshot() |
자동 테스트·향후 옵션 UI |
| 플레이어 | Node2D 화면 좌표, get_facing_direction() |
안개 Shader 초점·정면 방향 |
| 맵 | get_visibility_region, get_visibility_room_rects |
방 전체 공개·다른 방 차단 |
안개는 CanvasLayer 0, HUD·미니맵은 별도 UI CanvasLayer에 있어 방·통로 월드 시야 제한이 전체 미니맵 데이터나 모달 UI를 가리지 않습니다.
미니맵 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 맵 | get_minimap_snapshot() |
Game 조립부 |
| 미니맵 | configure(snapshot, tracked_actor, display_name) |
Game 조립부 |
| 미니맵 | set_warp_targets, warp_requested |
RoomWarpSystem 조립 연결 |
| 방 워프 | get_warp_targets, request_warp, get_snapshot |
미니맵·E2E |
스냅샷에는 셀 경계, 셀 크기, 바닥·방해물 좌표, 시작·탈출 위치와 방별 4방향 연결 사본만 들어갑니다. 미니맵은 맵의 방 배열, 길찾기 객체, 구체 클래스에 접근하지 않으며 워프 가능 여부도 계산하지 않습니다.
캐릭터 장비 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 장비 | configure(loadout, stats_target, weapons, skills, armor) |
Game 조립부 |
| 장비 | get_active_skill_ids, get_inactive_skill_ids |
HUD와 향후 스킬 실행기 |
| 장비 | get_stat_modifiers, get_summary |
HUD와 테스트 |
| 장비 | can_equip_definition, equip_definition |
U 장비 화면 |
| 장비 | install_part, install_module, upgrade_module |
U 파츠·모듈 화면 |
| 장비 | level_up_equipment, grant_module_tag |
성장·개조 UI와 향후 경제 모듈 |
| 장비 | equipment_changed(summary) |
HUD |
| 장비 | customization_changed(snapshot) |
U 장비 상태 표시 |
| 장비 | get_active_weapon, switch_active_weapon |
Q 입력과 자동 무기 |
| 장비 | active_weapon_changed(slot, definition) |
자동 무기와 HUD |
| 플레이어 | apply_equipment_modifiers(modifiers) |
장비 모듈 |
장비 모듈은 플레이어의 내부 Node 경로나 구체 클래스를 참조하지 않습니다. 스탯 적용 대상이 공개 메서드 하나를 구현하면 플레이어 이외의 캐릭터에도 같은 방어구 집계를 사용할 수 있습니다.
무기 밸런스 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 밸런스 | configure(config), get_weapon_balance(weapon_id) |
Game, AutoWeapon |
| 밸런스 | balance_updated(snapshot, source_label) |
자동 무기 런타임 갱신 |
| 밸런스 | balance_error(message) |
경고와 확정 CSV 폴백 |
| 자동 무기 | configure(projectiles, equipment, balance) |
Game 조립부 |
| 자동 무기 | weapon_runtime_changed(snapshot) |
HUD |
밸런스 서비스는 장비 Resource나 투사체 Scene을 참조하지 않습니다. 자동 무기는 weapon_id로 행을 조회할 뿐 Google Sheets URL·CSV 파일 경로를 알지 않으며, 투사체는 발사 순간 전달된 속도·피해·관통 값만 사용합니다.
무기 태그와 스킬 요구 태그는 WeaponTagProfile 값 비교만 수행합니다. 스킬 효과는 activation_payload에 보관하되 현재 장비 시스템이 실행하지 않으므로, 향후 스킬 실행기와 작전 투입 비용 정책을 별도 모듈로 붙일 수 있습니다.
격자 인벤토리 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 가방 | configure(catalog) |
Game 조립부 |
| 가방 | can_place, move_item, find_first_space |
격자 UI와 향후 드래그 조작 |
| 가방 | add_item, take_item, get_items_by_type |
파밍·장비·소비 시스템 |
| 가방 | get_snapshot, inventory_changed(snapshot) |
I 가방 UI와 U 장비 UI |
| I/U 패널 | configure, open_panel, close_panel |
Game과 모달 전환 |
가방은 장비 클래스나 태그를 모르며 InventoryItemDefinition.linked_resource를 보존하기만 합니다. 장착 성공 여부와 아이템 제거 순서는 U 화면이 공개 계약을 통해 조정합니다.
로그라이크 성장 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 내부 레벨 | level_gained, get_run_snapshot |
Game, 버프 선택 흐름 |
| 임시 버프 | prepare_choices, select_buff, get_snapshot |
선택 UI와 조립부 |
| 임시 버프 | get_meta_experience_breakdown |
외부 성장 |
| 플레이어 | set_runtime_modifier_source(source, modifiers) |
장비·임시 버프·외부 캐릭터 성장 |
| 자동 무기 | set_runtime_modifiers(source, modifiers) |
임시 버프·외부 무기 성장 |
| 외부 성장 | settle_run, apply_to_targets, get_snapshot |
작전 종료 조립부 |
| 장비 | set_external_armor_level(level) |
외부 방어구 성장 |
버프와 외부 성장은 서로의 구체 클래스를 참조하지 않습니다. 선택 수량을 { character, weapon, armor } 스냅샷으로 넘기며, 효과는 출처 ID별 수정자로 합산됩니다.
장비 강화 경제 공개 계약¶
| 제공자 | 계약 | 소비자 |
|---|---|---|
| 장비 | get_upgrade_context, upgrade_module, upgrade_part |
강화 서비스 |
| 인벤토리 | find_instance_ids_by_resource, consume_linked_resource |
강화 서비스 |
| 크레딧 | get_snapshot, can_spend_carried, spend_carried |
강화 서비스 |
| 비용 정책 | quote, validation_errors |
강화 서비스 |
| 강화 서비스 | quote_upgrade, upgrade |
U 장비 화면 |
장비는 가격이나 가방을 모르고, 가방은 강화 단계나 장비 슬롯을 모릅니다. 따라서 비용표·재화 종류·재료 정책을 교체해도 장비 상태 모델을 유지할 수 있습니다.
지속 자기장·방 전투 재감사 (2026-08-30)¶
| 검사 항목 | 결과 | 근거 |
|---|---|---|
| 스킬 수명 분리 | 통과 | 정의 Resource는 반경·지속·틱 수치만 소유하고 PersistentMagneticField가 추적·피해 주기를 관리 |
| 방 내부 캡슐화 | 통과 | 방 전투는 맵의 rooms, floor_cells, obstacle_cells 대신 공개 스냅샷과 위치 요청만 사용 |
| 적 생성 경로 재사용 | 통과 | 위치 지정 생성도 EnemySpawner.spawn_enemy_at()의 동일 configure·Signal·총 예산 경로 사용 |
| 문 봉쇄 교체성 | 통과 | RoomDoorBarrier가 충돌·표현을 독립 소유하며 전투 시스템은 공개 configure만 호출 |
| 보상 경제 분리 | 통과 | 기존 2.5~5배 크레딧 목표를 바꾸지 않고 별도 내부 경험치 보상으로 제공 |
| 선택 제거 | 통과 | room_encounters_enabled=false에서 실행기 미설치와 전역 증원 재개를 자동 검증 |
| 성능 예산 | 통과 | 대형 방 적 14기·전기 효과 3개에서 평균 6.884ms, 최대 8.385ms, Node 1,292개 |
숨겨진 비모듈 결합은 발견되지 않았습니다. Game은 설치 순서와 Signal 연결만 소유하고, 방 판정·수량·문 수명·전멸 판정·보상 생성은 game/features/room_encounters/ 안에 유지됩니다.
거점 로드아웃 편집·반환·세션 보존 재감사 (2026-08-30)¶
| 검사 항목 | 결과 | 근거 |
|---|---|---|
| UI 재사용 | 통과 | 거점과 작전이 같은 GridInventoryWindow, EquipmentWorkbench Scene 사용 |
| 거점 변경 권한 | 통과 | 시작 거점은 같은 Workbench에 편집 모드를 주입하고 장착·교체·해제·강화 계약 사용 |
| 무손실 반환 | 통과 | 장비는 EquipmentItemState, 모듈·파츠는 강화 단계 payload로 가방에 반환 |
| 공간 선검사·롤백 | 통과 | 후보가 비울 칸까지 고려해 반환 공간을 먼저 검사하고 실패 시 원래 장착 상태 복구 |
| 수명 분리·상태 보존 | 통과 | 제공자 Node는 세션마다 교체하되 export/restore_runtime_state로 준비 상태만 전달 |
| 입력 계약 | 통과 | I, U/E 열기와 ESC 닫기, Q 전환, 편집 상태의 출격·귀환 유지를 자동 검증 |
| 성능 예산 | 통과 | 대형 방 적 14기·전기 효과 3개에서 평균 6.889ms, 최대 7.880ms, Node 1,295개 |
거점은 장비나 가방 내부 Dictionary를 직접 수정하지 않습니다. Workbench가 장비·가방의 공개 반출입 계약을 조정하고, Game은 세션 경계에서 불투명 스냅샷을 전달할 뿐입니다. 따라서 향후 JSON 영구 저장이나 창고 기반 준비 화면을 추가해도 장착 규칙과 격자 배치를 재사용할 수 있습니다.
I·U·E 고밀도 UI 재감사 (2026-08-30)¶
| 검사 항목 | 결과 | 근거 |
|---|---|---|
| 상태·표현 분리 | 통과 | 12×8 배치 상태는 GridInventory, 셀·용량·상세 표현은 GridInventoryWindow와 InventoryGridView가 소유 |
| 장비 규칙 분리 | 통과 | 카드 크기·열 수·슬롯 레일 폭 변경이 EquipmentItemState, 태그, 코스트, 강화 서비스에 진입하지 않음 |
| 입력 라우팅 | 통과 | U는 장비 탭, E는 모듈·파츠 탭을 직접 선택하며 ESC와 현재 탭 재입력은 기존 닫기 계약을 재사용 |
| Scene 재사용 | 통과 | 거점과 작전이 동일한 I 창과 U/E Workbench Scene을 설치 |
| 자동 회귀 | 통과 | 42px 12×8 격자, 300px 상세 패널, 200px 슬롯 레일, 3열 후보 카드와 U↔E 탭 전환을 검사 |
고밀도 화면은 제공자 스냅샷을 읽는 소비자입니다. 새 UI가 가방·장비 내부 Dictionary를 소유하거나 직접 수정하지 않으므로, 향후 드래그 배치나 창고 화면을 별도 Scene으로 추가해도 기존 상태 모듈을 교체할 필요가 없습니다.
플레이 UI 점유·겹침 재감사 (2026-08-30)¶
| 검사 항목 | 결과 | 근거 |
|---|---|---|
| 전투 영역 분리 | 통과 | 상단 HUD 162px, 미니맵 214×168px, 하단 스킬바 660×104px 이하로 제한하고 전역 사각형 비겹침 검사 |
| 대시 상태 분리 | 통과 | 왼쪽 아래 190×68px 카드가 get_movement_snapshot()만 15Hz로 읽고 스킬바와 전역 사각형이 겹치면 자동 실패 |
| 에너지 판독성 | 통과 | 스킬 HUD가 기존 자원 스냅샷으로 13px 게이지·현재/최대·백분율·LOW/CRITICAL 상태만 표현 |
| 상호작용 가시성 | 통과 | F 안내 영역을 스킬바 위에 고정하고 두 사각형의 교차를 자동 거부 |
| 모달 배타 표시 | 통과 | 가방·장비 패널이 공개 panel_visibility_changed Signal만 발행하고 Game 조립부가 이전 HUD 표시 상태를 캡처·복원 |
| 작전 구성 상태 | 통과 | 작전 구성 중 거점 HUD를 숨기고 ESC 종료 시 거점 HUD만 복원 |
| 표현·상태 분리 | 통과 | 크기·여백·폰트 수정은 UI Scene과 HUD 표현 스크립트에 한정되며 전투·장비·가방 데이터 계약은 변경 없음 |
모달 패널은 어떤 HUD가 존재하는지 알지 않습니다. 열림·닫힘 Signal만 제공하고 조립부가 설치된 선택 기능의 표시 상태를 관리하므로 인벤토리, 장비, 미니맵, 스킬·대시 HUD 모듈을 제거해도 패널 내부 로직을 수정할 필요가 없습니다. 대시 HUD 역시 PlayerMovement 타입이나 하위 Node 대신 플레이어의 공개 이동 스냅샷 계약만 사용합니다.
Web 작전 시작·위키 플레이 진입 재감사 (2026-08-30)¶
| 검사 항목 | 결과 | 근거 |
|---|---|---|
| 원인 분리 | 통과 | Web PCK에는 CSV가 포함됐지만 브라우저 런타임의 FileAccess.open()이 비-Resource CSV 스트림을 제공하지 않아 GrowthBalanceService.configure()가 실패하고 조립 롤백이 거점을 복구했음을 배포 아티팩트 콘솔로 재현 |
| 데이터 패키징 | 통과 | 무기·내부 성장·장비 강화 CSV 3종을 Web 프리셋에 포함하고, Web-safe EmbeddedCsvPayload 미러를 설정 Resource로 주입 |
| 자동 회귀 | 통과 | 동기화 스크립트와 게임 스모크가 세 CSV의 실제 존재, Web 내보내기 목록, 내장 미러의 원문·원본 경로 일치를 함께 검사 |
| 플레이 링크 단일화 | 통과 | 홈 실행 카드와 전역 고정 도크가 모두 배포 루트 기준 /play/를 계산 |
| 즉시 탐색 호환 | 통과 | 전역 도크는 Material document$ 재탐색마다 기존 요소를 재사용하고 링크만 갱신 |
밸런스 서비스는 계속 확정 CSV 또는 실시간 Google Sheets 제공자만 소비합니다. 로컬·에디터에서는 FileAccess.open()으로 CSV를 우선 읽고, 브라우저에서 그 스트림을 얻지 못할 때만 설정 Resource에 주입된 동일 원문의 EmbeddedCsvPayload를 사용합니다. Google Sheets 동기화 스크립트가 CSV 저장과 미러 생성을 하나의 작업으로 처리하고 --check가 불일치를 거부하므로 두 데이터 경로가 별도 기준으로 갈라지지 않습니다.
실제 입력 E2E·U/E 계약 재감사 (2026-08-31)¶
| 검사 항목 | 결과 | 근거 |
|---|---|---|
| 입력 Action 분리 | 통과 | toggle_equipment=U, toggle_modification=E가 독립 등록되고 Workbench는 물리 키 값을 재해석하지 않음 |
| Web 입력 안정성 | 통과 | 열린 U 화면에서 E가 닫기 토글로 소비되지 않고 모듈·파츠 탭을 선택하는 실제 키 이벤트 회귀 추가 |
| 표시 의미 분리 | 통과 | 장비 화면은 발동 스킬 수가 아닌 장비 태그 호환 수임을 명시하고 상태 계산 계약은 변경하지 않음 |
| 조립부 경계 | 통과 | Game은 입력·HUD·세션 설치와 반환만 조정하고 가방·장비·탈출 내부 상태를 직접 수정하지 않음 |
| 세션 E2E | 통과 | 거점 이동, I/U/E/Q/F, 작전 진입, 파밍, 탈출 일시정지·성공, 사망, 두 차례 거점 복귀를 실제 입력으로 검증 |
| CI 회귀 | 통과 | 기본 계약 스모크와 별도 e2e_play_session_test.gd를 Pages 배포 전 모두 실행 |
E2E 실행기는 기능 내부 구현을 복제하지 않습니다. 실제 InputMap 이벤트와 공개 상호작용·정산 계약을 통해 모듈을 연결하며, 특정 기능의 규칙 검증은 기존 단위형 스모크에 남깁니다. 이 분리로 세부 모듈 교체와 플레이 흐름 회귀를 서로 다른 실패 메시지로 진단할 수 있습니다.
조기 탈출·M 방 워프·크레딧 보상 재감사 (2026-09-01)¶
| 검사 항목 | 결과 | 근거 |
|---|---|---|
| 지도 토폴로지 캡슐화 | 통과 | 맵은 방 배열 대신 open_directions, is_four_way, 중심·경계 사본만 공개 |
| 표시·이동 분리 | 통과 | TacticalMinimap은 확대·표식·클릭 Signal만, RoomWarpSystem은 허용 조건과 실제 이동만 소유 |
| 방 진행도 분리 | 통과 | 워프 서비스는 is_room_completed()·get_snapshot() 공개 계약만 사용하고 완료 Dictionary에 접근하지 않음 |
| 전투 안전 | 통과 | 활성 봉쇄 방이 있으면 시작·끝을 포함한 모든 워프 요청을 재검증해 거부 |
| 보상 수치 데이터화 | 통과 | 박스 1~5개, 크기·난수 보정, 티어별 크레딧 범위를 RoomEncounterConfig Resource가 소유 |
| 경제 연결 | 통과 | 보상 박스는 크레딧 Signal만 발행하고 Game 조립부가 공개 CreditLedger.add_carried()로 전달 |
| 탈출 원인 분리 | 통과 | 시간과 전투 방 완주가 공통 _unlock_extraction()을 호출하며 탈출 구역은 개방 원인을 모름 |
| 선택 제거 | 통과 | room_warp_enabled=false에서 방 전투·미니맵은 유지되고 워프 서비스만 미설치됨 |
| 실제 입력 회귀 | 통과 | 물리 M→확장→후보 클릭→워프→자동 축소, 미클리어 거부, 조기 탈출과 F 보상 회수를 E2E 검증 |
| 성능 예산 | 통과 | 대형 34기·전기 효과 3개에서 평균 6.894ms, 피크 8.948ms, Node 최대 1,773개 |
기존 RoomRewardPickup은 제거했습니다. 방 교전 내부 경험치라는 별도 경제 경로가 남지 않고, 로컬 RoomCreditRewardBox가 일반 파밍과 같은 F 상호작용 Signal 계약만 구현합니다. 따라서 loot 폴더의 Scene을 직접 참조하지 않습니다. 입력 카탈로그는 toggle_map을 추가해 22개 Action이 되었으며 M 역시 K 화면에서 변경·저장할 수 있습니다.
보호된 이중 배포 감사 (2026-09-01)¶
| 검사 항목 | 결과 | 근거 |
|---|---|---|
| main 변경 경계 | 통과 | PR·대화 해결과 export-game, build, e2e를 요구하고 승인 0명, 강제 푸시·삭제 금지, 우회 없음으로 설정 |
| 공급망 경계 | 통과 | 워크플로의 GitHub Action 7종을 실제 태그 커밋 SHA로 고정하고 저장소 허용 목록도 동일 SHA만 수락 |
| 산출물 단일성 | 통과 | Cloudflare 작업은 game-web, wiki-site, SFH-Windows-x64-v0.1.0 검증 산출물을 내려받기만 하며 재빌드하지 않음 |
| 원자적 게임 전환 | 통과 | R2 game/releases/<commit>/에 모든 파일과 manifest를 먼저 업로드한 뒤 Worker의 RELEASE_PREFIX를 변경 |
| 위키·게임 분리 | 통과 | MkDocs 정적 파일만 기존 sfh-dev-wiki Pages에 Direct Upload하고 39MiB WASM·PCK는 R2 결합 Worker가 제공 |
| 다운로드 무결성 | 통과 | /downloads/<version>/에서 ZIP과 SHA-256을 함께 제공하고 Cloudflare E2E가 다시 내려받아 검증 |
| Web 런타임 헤더 | 통과 | Worker가 COOP·COEP·CORP, MIME, ETag, Range 206과 캐시 정책을 중앙 관리 |
| 무중단 폴백 | 통과 | Cloudflare E2E와 링크 전환이 끝날 때까지 기존 GitHub Pages 배포를 병렬 유지 |
Worker는 R2 객체 읽기와 HTTP 전달만 소유하고 게임 코드를 알지 않습니다. 업로더는 빌드 산출물의 키·MIME·해시 manifest만 소유하며 활성 Worker 설정을 바꾸지 않습니다. CI 조립부가 업로드 성공 뒤 Worker, 그 뒤 Pages, 마지막 E2E 순서를 소유하므로 저장소·스토리지·서빙 책임을 개별 모듈로 교체할 수 있습니다.
의도된 결합¶
Game은 모듈 Scene의 문자열 경로와 조립 순서를 압니다.EnemySpawner는 기본 적 Scene을 참조합니다. 이는spawning → enemies선언 의존성입니다.RoomEncounterSystem은 맵·적 생성·크레딧의 공개 계약만 사용합니다. 이는 Manifest에 선언된room_encounters → map_generation, spawning, credits의존성입니다.RoomWarpSystem은 맵·방 진행도 공개 계약만 사용합니다. 이는room_warp → room_encounters, minimap선언 의존성입니다.Game은 기본 장비 Scene과 선택된 로드아웃 Resource 경로를 알고, 장비는 플레이어의 스탯 적용 공개 메서드만 압니다.Game은 인벤토리 카탈로그와 I/U 패널 Scene 경로를 알고, 가방과 장비 시스템은 서로의 내부 Node 경로를 참조하지 않습니다.Game은 장비, 밸런스, 자동 무기의 조립 순서를 알지만 각 모듈은 서로의 내부 Node 경로를 참조하지 않습니다.Game은 내부 레벨 → 버프 선택 → 외부 정산 순서와 장비 → 가방·원장 → 강화 서비스 순서를 압니다.- 플레이어, 적, 투사체는 생성 벽용 충돌 레이어
16을 공유합니다. - 맵 전용 스모크 테스트는 맵 기능 경로를 참조합니다. 맵 기능을 완전히 삭제하면 해당 테스트도 함께 제거하거나 교체해야 합니다.
이 결합은 숨겨진 의존성이 아니라 조립부, Manifest 검사, 문서에 드러난 계약으로 관리합니다.
다시 점검하는 방법¶
성공하면 출력에 persistent_magnetic_field, room_triggered_encounter, room_door_lock, room_credit_boxes_1_5, room_encounters_optional, room_warp_optional, minimap_expanded_warp, early_extraction, finite_spawn_budget, dynamic_hack_slash_movement, fog_of_war, minimap_full_map, target_provider, run_buffs, meta_experience, modular_progression이 기존 검증 항목과 함께 포함됩니다.
다음 개선 시점¶
조립부가 파일 단위 유지보수 한계를 넘을 때 _install_*() 함수들을 별도 설치 객체로 이동할 수 있습니다. 이는 현재 모듈 교체를 막는 결함이 아니라 코드 크기 관리 단계이며, 이동하더라도 문자열 지연 로딩과 명시적 메서드 검사는 유지합니다.
검색 별칭¶
모듈 감사, 의존성 검사, 플러그인 구조, 기능 제거, 기능 교체, 맵 인터페이스, 선택 모듈, 결합도, 인벤토리 계약, 장비 개조 계약