13 KiB
Tool_Left 버그 유무 점검 보고서 (#58)
PD 지시 #58 "#57-C는 툴 버그 유무를 개발팀에 지시해서 점검하도록 해" 집행. 원인 조사가 아닌 툴 버그 유무 명확 판정이 목표.
§1. 점검 방법
1-1. 점검 환경 (실측 기반)
- Unity 프로젝트 루트:
D:/NerdNavis/FilGoodBandits/DeckBuilding(git repo 확인) - 원격 대비 최신 상태 (
git fetch origin후git statusclean, 변경은 IDE 생성 파일뿐) - HEAD:
24578499a 몬스터 오류 수정(= #57 A 집행 커밋, IngameStageData.Init 자동 복구 28줄 추가)
1-2. 점검 대상 코드 (Read 실측)
| 파일 | 줄수 | 핵심 역할 |
|---|---|---|
Assets/Tool/Script/Tool_Left.cs |
190 | CreateStageAppearMonster 정의 + Add_Stage 진입점 |
Assets/Tool/Script/ToolStageCard.cs |
160 | OnValueChange_MapConfig → CreateStageAppearMonster 호출 (mapconfig 변경 시) |
Assets/Tool/Script/Tool_Right.cs |
227 | 노드 저장 전 validation (Mob/Boss 노드 존재 시 list_MobData/list_BossMobData 비어있는지 체크) |
Assets/Tool/Script/ToolMain.cs |
572+ | SaveToJson / LoadToJson — ToolData.json 직렬화·역직렬화 + 로드 시 테이블 존재 안 하는 몹 정리 루프 |
Assets/Editor/MyEditorUtil.cs |
514+ | Tools/ToolStageBossSetting 메뉴 — 기존 저장분 일괄 복구 기능 |
Assets/Script/InGame/Stage/IngameStageData.cs |
149 | 런타임 자료구조 · Init() 내 #57 A 자동 복구 로직 |
1-3. ToolData.json 실측
- 파일:
Assets/Resources/ToolData.json(796,235 bytes, 2026-04-14 생성) - 전수 파싱으로
list_MobData·list_BossMobData상태 통계 집계 (Python JSON parser)
§2. 3축 점검 결과
2-1. 축 1 — Tool_Left의 CreateStageAppearMonster 호출 경로
호출부 전수 탐지 결과:
| 호출 위치 | 트리거 | 분배 대상 |
|---|---|---|
Tool_Left.Add_Stage() (119행) |
[+] 버튼으로 스테이지 신규 추가 |
해당 신규 스테이지에만 |
ToolStageCard.OnValueChange_MapConfig() (89행) |
카드 dropdown으로 mapConfigID 변경 | 해당 스테이지에만 |
분배 로직 (Tool_Left.cs 125~152):
public void CreateStageAppearMonster(IngameStageData isdata, CreateMapConfigTableData mapconfig)
{
isdata.list_MobData = new List<StageMonsterData>(); // 반드시 새 리스트로 초기화
isdata.list_BossMobData = new List<StageMonsterData>(); // 반드시 새 리스트로 초기화
var createstagemobdatas = table_ApprearMonsterPattern.Ins.Get_DataList(mapconfig.n_AppearMonsterGroup);
if (createstagemobdatas != null)
for (int i = 0; i < createstagemobdatas.Count; i++) { /* list_MobData 추가 */ }
var createstagebossdatas = table_ApprearMonsterPattern.Ins.Get_DataList(mapconfig.n_AppearBossGroup);
if (createstagebossdatas != null)
for (int i = 0; i < createstagebossdatas.Count; i++) { /* list_BossMobData 추가 */ }
if (isdata.list_BossMobData.Count == 0)
Popup.Ins.Set("보스 몬스터가 설정되지 않았습니다 ..."); // 경고 팝업
}
판정: 호출 경로·분배 로직 모두 정상. 신규 추가·mapConfig 변경 시 모두 테이블에서 몬스터를 읽어 정상 분배. 표 조회가 null이면 빈 리스트 유지(방어 코드 정상). n_AppearBossGroup 결과 비면 Popup 경고까지 띄움.
잠재 이슈: CreateStageAppearMonster는 신규 추가 or mapconfig 변경 시에만 호출. 기존에 이미 저장된 스테이지가 같은 mapconfig로 유지되는 동안은 본 메서드가 호출되지 않음 → 구 스키마 시절 데이터가 누적된 경우 자동 복구 트리거 없음. 이는 버그가 아니라 설계 의도(불필요 재생성 방지).
2-2. 축 2 — Newtonsoft.Json 직렬화 시 List<StageMonsterData> 필드 유실 여부
점검 방법:
IngameStageData필드 속성 검사:[JsonIgnore]·[NonSerialized]0건 (모든 public 필드 직렬화 대상)ToolMain.SaveToJson기본 설정:JsonConvert.SerializeObject(td)— 기본 설정(default NullValueHandling, 빈 컬렉션 포함)- 실제 ToolData.json 전수 파싱 (125개 스테이지, 24개 챕터)
실측 결과 (125 스테이지 전수):
| 항목 | 건수 | 비율 |
|---|---|---|
list_MobData 필드 자체 누락 (JSON key 부재) |
0건 | 0% |
list_BossMobData 필드 자체 누락 (JSON key 부재) |
0건 | 0% |
list_MobData 필드는 있으나 빈 배열 [] |
123건 | 98.4% |
list_BossMobData 필드는 있으나 빈 배열 [] |
124건 | 99.2% |
| 두 필드 모두 빈 배열 | 122건 | 97.6% |
샘플 케이스 (Stage 1 / mapConfig Stage1_1):
{ "m_Stage": 1, "mapConfigID": "Stage1_1",
"list_MobData": [],
"list_BossMobData": [{"m_Index":0, "m_MobID":10003, "m_Weight":100}] }
판정: JSON 직렬화·역직렬화 자체는 완전 정상. 모든 필드가 예외 없이 직렬화·저장됨. 문제는 **"빈 리스트 그대로 저장된 데이터가 존재"**라는 것이지 직렬화 유실이 아님.
2-3. 축 3 — JSON 스키마 마이그레이션 이력 추적
핵심 커밋 발견: 686a25a30 (2026-04-08, Ino 작성자)
- 제목: "CreateMapConfig 테이블에 보스 몬스터 패턴을 설정해두었지만 맵툴에는 보스 몬스터가 설정되지 않는 문제 수정 바랍니다"
- 변경:
Tool_Left.cs26줄 재작성 +MyEditorUtil.cs56줄 신규(Tools/ToolStageBossSetting메뉴) + 기타 4개 파일
스키마 변경 내용:
| 시점 | 분배 방식 |
|---|---|
| 변경 전 (커밋 이전) | 단일 테이블 n_AppearMonsterGroup에서 몬스터 읽고 tdata.IsBoss()로 list_MobData/list_BossMobData 자체 분기 |
| 변경 후 (현재) | 두 테이블 개별 조회: n_AppearMonsterGroup → list_MobData · n_AppearBossGroup → list_BossMobData |
CreateMapConfig 테이블 스키마에 n_AppearBossGroup 컬럼이 신규 추가됐고, 이에 맞춰 CreateStageAppearMonster 재구성. 동일 커밋에서 MyEditorUtil.cs의 Tools/ToolStageBossSetting 일괄 복구 메뉴를 추가한 것은 기존 저장분 중 list_BossMobData가 비어있는 스테이지를 신 스키마 기준으로 재채우기 위함 (명시적으로 "맵툴 실행 상태에서 실행" + "모든 보스가 없는 스테이지의 경우 테이블에서 읽어서 다시 세팅").
이후 커밋 이력 관찰:
045ed3176 맵툴 데이터 추가·a2dde619b 임시 작업물 업데이트— ToolData.json 단순 업데이트 커밋 다수410504a9a 몬스터 등장 패턴 구성 관련 요청— 기획팀 테이블 요청 대응24578499a 몬스터 오류 수정(#57 A) — 런타임 Init()에 같은 자동 복구 로직을 편입
즉 #57 A는 과거 Editor 메뉴(ToolStageBossSetting)가 했던 복구를 런타임 진입 시점에 자동 실행하도록 이관한 조치입니다. 툴 측은 2026-04-08 시점에 이미 복구 경로가 존재했으나, 실행자가 메뉴를 직접 누르지 않으면 기존 저장분은 그대로 유지되는 구조.
§3. 버그 유/무 최종 판정
3-1. 판정 결과: 툴 버그 없음 (3축 모두 정상)
| 축 | 기대 버그 | 실측 결과 | 판정 |
|---|---|---|---|
| 1 | Tool_Left가 신규 추가/mapConfig 변경 시 CreateStageAppearMonster 호출 누락 |
2곳 호출·분배 로직 정상 동작 | 버그 없음 |
| 2 | Newtonsoft.Json이 List<StageMonsterData> 필드 유실 |
필드 자체 누락 0건. 모든 스테이지에 필드 존재 | 버그 없음 |
| 3 | JSON 스키마 마이그레이션 누락 | 2026-04-08 686a25a30에서 로직 이전 + 일괄 복구 메뉴 동시 제공 완료 |
버그 없음 |
3-2. 그럼 왜 125 스테이지 중 122건(97.6%)이 빈 배열인가
가설 (증거 기반 해석):
- 스키마 마이그레이션 시점 데이터가 주원인: 2026-04-08 이전에 만들어진 스테이지 데이터는 구 분배 방식의 산물. 이후 스키마 변경 시
Tools/ToolStageBossSetting메뉴를 수동 실행하지 않으면 자동 재채워지지 않음. 기획·개발 파트에서 메뉴를 실행한 스테이지(Stage 1의 list_BossMobData 등 일부 존재)만 갱신됐고 나머지는 미실행. - PD님 언급 일치: PD님이 #57-B 재export 보류 사유로 "해당 스테이지는 임시 데이터"라 말씀. 실제로 125 스테이지 중 거의 전부가 빈 몬스터 배열 → "미완성 임시 데이터" 성격.
- 기획·테이블 운영 방식 영향 가능: 빈 배열 상태는 Popup 경고도 띄우지 않음(
Count == 0은list_BossMobData만 경고. 비어있는list_MobData는 경고 없음). 기획 단계에서 노드 생성 직전에야 Tool_Right 검증 다이얼로그로 경고가 뜸 — "나중에 채워도 된다"는 운영 패턴 허용 구조.
3-3. 기존 조직 자산 확인 (C31-E 준수)
본 건은 #57 A에서 이미 런타임 자동 복구 로직을 투입하여 "빈 배열이어도 게임 실행 시 자동 채움" 구조로 전환된 상태. 현재 정상 동작 중이며 추가 툴 버그 수정은 필요하지 않음.
§4. 수정 제안 (버그는 없지만 운영 개선 여지)
버그는 없지만, PD님 결정을 돕기 위해 발견된 설계·운영상 관찰점을 4가지 옵션으로 제시합니다. 선택적 개선안이며 현 시점 즉각 집행 대상 아님 (PD 결정 영역).
4-1. 관찰점 (현 상태 유지도 무방)
list_MobData.Count == 0상태에 경고 누락:CreateStageAppearMonster가list_BossMobData.Count == 0일 때만 Popup으로 경고하고,list_MobData가 비면 경고 없음. 기획자가 인지 못 한 채 스테이지 저장 가능 → Tool_Right.cs 저장 직전 validation에서 걸러지긴 함.ToolStageBossSetting메뉴의 대칭 메뉴 없음: Boss 일괄 복구 메뉴는 있으나 일반 몬스터 일괄 복구 메뉴는 부재. 위 데이터 98.4% 비어있는 주 원인.- 런타임 Init() 자동 복구(#57 A)와 툴 저장 상태의 gap: 런타임에선 자동 채워지나 ToolData.json 자체는 여전히 빈 배열 → 기획팀 툴 화면에서는 여전히 "0건"으로 표시(ToolStageCard.cs:31~32) → 기획 파악 혼선 가능성.
4-2. 개선 옵션 (PD 판단 영역 — 본 Task 범위 외)
| # | 옵션 | 비용 | 효과 |
|---|---|---|---|
| A | 현 상태 유지 (#57 A 런타임 복구로 충분) | 0 | 런타임 안전. 툴 표시만 "0건"으로 남음 |
| B | MyEditorUtil.cs에 "list_MobData 일괄 복구 메뉴" 추가 + 한 번 수동 실행 |
소규모 | ToolData.json 실제 데이터 정상화 (1회성) |
| C | ToolMain.LoadToJson 시점에 IngameStageData.Init() 자동 호출 → 저장까지 연동 |
중규모 | 툴 로드 즉시 자동 복구 + 저장 (사용자 개입 불요) |
| D | CreateStageAppearMonster에 list_MobData.Count == 0 경고도 추가 + 기획 가이드 문서화 |
소규모 | 신규 추가 시 누락 예방 |
권장 순서: A 유지 → 장기적으로 C 검토 (C는 "자동 복구" 설계를 툴 영역까지 일관 확장하는 근본 개선).
§5. 후속 권고
5-1. 수정 범위 판정
- 본 Task(#58) 범위: 점검만. 수정 집행 없음. (지시 명시 사항)
- 추가 수정 필요 시: §4-2 옵션 중 PD님 선택에 따라 별도 지시로 집행. 개발팀 자율 집행은 C36 관점에서 방향·원칙 수준 아닌 구현 수준이므로 PM 재량 가능하나 현 상태에서 필요성 낮음
5-2. 기획팀 협업 필요 여부
- 불필요: 런타임 동작은 #57 A로 이미 안전. 기획팀 추가 확인 사항 없음
- 선택적 공유: 기획팀이 툴 화면에서 "0건" 표시를 이상하게 느낀다면 §4-1의 3번 관찰점을 공유하여 인지 제공 정도
5-3. 조직 기억 축적
- feedback 메모리 신설 불요: 본 건은 PD님 직접 지시 완료 집행이므로 #58 자체가 조직 기억. 별도 feedback 불필요
- 대화로그 기록: 개발팀 대화로그에 본 점검 결과 1줄 엔트리 추가 (PM이 별도 집행)
5-4. PM에게 전달 요지 (1문장)
Tool_Left 3축 모두 정상 동작, 툴 버그 없음 판정. 빈 배열 저장분은 2026-04-08 스키마 변경 시점에 수동 복구 메뉴 미실행으로 남은 잔재이며 #57 A 런타임 자동 복구로 실질 영향 해소됨. §4-2 개선 옵션은 PD 결정 영역으로 제출.
참조
- PD 지시 #57 (완료):
공유/소통/완료/2026-04-20_몬스터_미등장_A_집행완료.md - 본 보고 매니페스트:
$HOME/.claude/nerdnavis-audit/manifest/active/2026-04-20_58_툴버그점검.md - Unity 프로젝트 HEAD:
24578499a(2026-04-20 #57 A 집행) - 스키마 마이그레이션 커밋:
686a25a30(2026-04-08)