{
  "version": 1,
  "kind": "hwanse-battle-analysis-summary",
  "source": "out/battle_*.json",
  "updatedAt": "2026-07-05T14:32:37.325470+00:00",
  "policy": {
    "canonicalEvidence": "JSON files are retained as raw structured evidence.",
    "removedDerivedFiles": "Per-topic out/battle*.html and out/battle*.md are regeneratable and should not be linked from the home page.",
    "userEntry": "web/battle_analysis.html"
  },
  "metrics": {
    "jsonFiles": 93,
    "groupCount": 6,
    "groupedJsonFiles": 93
  },
  "highlights": [
    {
      "title": "전투 계산 파이프라인",
      "body": "hit unit 8바이트 schema, target scope, result-family dispatch, HP/MP apply, 상태 성공 gate, critical/guard/miss branch를 모두 분리했다.",
      "json": "battle_damage_formula_trace_review.json"
    },
    {
      "title": "상태/모드/취기",
      "body": "+0x2a 자세/상태, +0x65 취기, +0x18 주량, +0x1a 주량 경험치, +0x69 곤드레만드레 pending flag까지 정리했다.",
      "json": "battle_status_transition_review.json"
    },
    {
      "title": "Support/Status 전투 행",
      "body": "도주, 방어, 회복, 술, 도발, 눈요기, 수경은 공격 애니메이션 누락이 아니라 result-family/status 정책 행으로 분리했다.",
      "json": "battle_support_status_policy_review.json"
    },
    {
      "title": "결과 표시와 소리",
      "body": "MISS/guard/normal/critical 표시 분기, 데미지 숫자 btl_etc selector, WLK 결과음/시전음 역할을 분리했다.",
      "json": "battle_result_display_branch_review.json"
    },
    {
      "title": "전투 액션/이펙트 VM",
      "body": "phase display table, frame gate, helper child script, spawn-tree, caster position/motion opcode를 전투 러너가 참고할 수 있는 수준으로 색인화했다.",
      "json": "battle_display_vm_static_decode.json"
    },
    {
      "title": "전투 기술 구현 gap 해소",
      "body": "전투 기술 unresolved flag는 0으로 정리했다. 도주/방어/회복/술/도발/눈요기/수경 같은 support/status 25행은 gap이 아니라 별도 정책 행으로 complete pattern에서 관리한다.",
      "json": "battle_skill_implementation_gap_review.json"
    },
    {
      "title": "몬스터/공용 기술 페이로드",
      "body": "몬스터/공용 기술은 actor +0x59 shared action id에서 payload/result-family로 이어지고, actor +0x5a는 몬스터 CNS local display slot으로 분리된다.",
      "json": "battle_monster_shared_action_effect_review.json"
    },
    {
      "title": "몬스터 행동 선택자",
      "body": "몬스터 행동 선택자는 descriptor/vtable VM script의 opcode 0x10 pair로 확정됐다. `10 c0 59 xx`가 shared action id, `10 c0 5a yy`가 visible slot을 세팅하고, 공유 descriptor의 조건부 action id는 actor id 분기로 해소된다.",
      "json": "battle_monster_action_selection_review.json"
    },
    {
      "title": "몬스터 액션 카탈로그",
      "body": "선택자(+0x59/+0x5a), 공용 payload, CNS local display slot을 결합해 몬스터별 행동 RNG 가중치와 프레임/사운드/이동 슬롯을 한 파일로 묶었다.",
      "json": "battle_monster_action_catalog.json"
    },
    {
      "title": "몬스터 행동 표시/이펙트",
      "body": "몬스터 행동의 local frame, helper call, effect/result WLK, repeat loop, movement를 정적 카탈로그로 재집계했고 helper graph/frameScript preview까지 연결했다.",
      "json": "battle_monster_action_effect_review.json"
    }
  ],
  "formulas": [
    {
      "title": "Normal damage",
      "code": "atk = floor(attacker.attack * attacker.attackCoef * skillDamageCoef / 10000)\ndef = floor(target.defense * target.defenseCoef / 100)\nbase = floor((atk * 2 - def) / 3) + rand(floor(attacker.level / 2)) - rand(floor(target.level / 2))\ndamage = floor(base * target.familyResistance[damageFamily] / 100)\nif damage < 3: damage = rand(3) + 1"
    },
    {
      "title": "Critical / alternate damage",
      "code": "base = floor((atk * 2 - def) / 2) + rand(floor(attacker.level / 2)) - rand(floor(target.level / 2))\ndamage = floor(base * target.familyResistance[damageFamily] / 100)\nif damage < 3: damage = rand(5) + 1\ncritical is presented by flash + dedicated WLK + higher damage, not by text"
    },
    {
      "title": "Ataho drunk hazard",
      "code": "after alcohol-family result: 취기 += inc, 주량경험치 += inc\nif 주량경험치 > 100 and 주량 < 100: 주량 += 1; 주량경험치 = 0\nstatus by 취기: >0 얼근히, >33 만취, >66 정신없이, >100 대호\npost-action cleanup: if rand(100) + 주량 < 취기 then 곤드레만드레"
    }
  ],
  "groups": [
    {
      "id": "core-data",
      "title": "핵심 데이터/레코드",
      "desc": "기술 payload, actor 스탯 레이아웃, 대상 선택, result-family 스키마처럼 전투 계산과 직접 연결되는 근거.",
      "files": [
        "battle_action_mapping",
        "battle_monster_shared_action_effect_review",
        "battle_monster_action_selection_review",
        "battle_monster_action_catalog",
        "battle_skill_records",
        "battle_actor_stat_layout_review",
        "battle_player_actor_stat_layout_review",
        "battle_selected_target_latch_review",
        "battle_result_family_dispatch_review",
        "battle_mode_coefficient_review"
      ],
      "entries": [
        {
          "stem": "battle_action_mapping",
          "json": "battle_action_mapping.json",
          "exists": true,
          "title": "hwanse-battle-action-mapping",
          "kind": "hwanse-battle-action-mapping",
          "status": "player-skill-payload-table-grounded-phase-formula-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 264059
        },
        {
          "stem": "battle_monster_shared_action_effect_review",
          "json": "battle_monster_shared_action_effect_review.json",
          "exists": true,
          "title": "hwanse-battle-monster-shared-action-effect-review",
          "kind": "hwanse-battle-monster-shared-action-effect-review",
          "status": "static-shared-monster-action-payload-and-result-family-grounded",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "sharedActionRows: 125; sharedHitUnits: 177; targetScopeDistribution: [{'value': 10, 'valueHex': '0x0a', 'label': '적 1명', 'count': 105}, {'value': 6, 'valueHex': '0x06', 'label': '적 전체', 'count': 61}, {'value': 1, 'valueHex': '0x01', 'label': '자기/준비', 'count': 11}]; resultFamilyDistribution: [{'value': 16, 'valueHex': '0x10', 'label': '', 'count': 60, 'class': 'damage', 'classLabel': '공격/상태 판정', 'dispatchRole': 'common damage/status formula path', 'functionVaHex': '0x0043414d'}, {'value': 18, 'va",
          "size": 216905
        },
        {
          "stem": "battle_monster_action_selection_review",
          "json": "battle_monster_action_selection_review.json",
          "exists": true,
          "title": "몬스터 행동 선택 정적 분석",
          "kind": "hwanse-battle-monster-action-selection-review",
          "status": "static-vm-script-producer-grounded",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "confirmed: ['몬스터/공용 기술 실행은 actor +0x59 shared action id -> 0x004d2494 shared action payload -> hit unit -> result-family dispatch로 이어진다.', 'enemy 표시 단계는 actor +0x5a + 0x0a를 display selector로 사용한다. 즉 +0x59 payload id와 +0x5a visual slot은 별도 필드다.', '0x433402/0x433545 target selector는 이미 설정된 actor +0x59를 소비한다. monster action id를 생산하지 않는다.', '직접 field-write 스캔에서 actor +0x59를 생산하는 경로는 player/menu selector, player skill growth, manual/player execution 쪽뿐이다.', 'generic VM opcode 0x10은 active object([ctx",
          "size": 1767695
        },
        {
          "stem": "battle_monster_action_catalog",
          "json": "battle_monster_action_catalog.json",
          "exists": true,
          "title": "Static monster action catalog",
          "kind": "hwanse-battle-monster-action-catalog",
          "status": "static-monster-action-selection-and-display-slot-joined",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "Descriptor script3 VM bytecode selects both shared action id (+0x59) and local visible slot (+0x5a).; The visible slot is joined to the monster CNS display table through display phase = 0x0a + slot.; Opcode 0x2b/0x0a confirms script3 choice tables as RNG jump tables; repeated pointers are exact table weights.; Slot-first conditional blocks are resolved by active object +0x05 actor-table-id checks, so shared CNS descriptors can select actor-specific action ids.",
          "size": 2337359
        },
        {
          "stem": "battle_skill_records",
          "json": "battle_skill_records.json",
          "exists": true,
          "title": "battle skill records",
          "kind": "",
          "status": "battle-action-payload-grounded-monster-binding-resolved-by-action-catalog",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 134944
        },
        {
          "stem": "battle_actor_stat_layout_review",
          "json": "battle_actor_stat_layout_review.json",
          "exists": true,
          "title": "hwanse-battle-actor-stat-layout-review",
          "kind": "hwanse-battle-actor-stat-layout-review",
          "status": "actor-stat-layout-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "전투 actor 초기화 루틴은 0x00457c60 기반 0x38-byte row prefix 8바이트를 actor +0x00으로 복사한다.; HP view로 내보낸 out/enemy_stat_table row는 actual actor row +0x08에서 시작한다. 따라서 exported +0x06은 actor +0x1c attack, exported +0x0a는 actor +0x20 defense처럼 8바이트 보정이 필요하다.; exported +0x34 name id는 current actor row 내부가 아니라 다음 actual row prefix의 +0x04 marker다. 이름 anchor로는 유효하지만 current actor struct 필드는 아니다.; 플레이어 row 장비/레벨업 루틴 대조로 actor +0x26은 운 축으로 승격됐다. +0x28은 상태창/장비 운 보정 대상이 아니며 0x4343db critical/alternate 판정과 0x4344ab 상태 성공",
          "size": 112348
        },
        {
          "stem": "battle_player_actor_stat_layout_review",
          "json": "battle_player_actor_stat_layout_review.json",
          "exists": true,
          "title": "hwanse-battle-player-actor-stat-layout-review",
          "kind": "hwanse-battle-player-actor-stat-layout-review",
          "status": "player-actor-exp-luck-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "플레이어 전투 actor 초기화는 파티 slot -> character index -> 0x00457750 + index*0xd8 row를 찾아 첫 0x48바이트를 actor로 복사한다.; player row/actor +0x14는 현재 EXP다. 승리 보상 루프가 0x42157b 산출값을 살아있는 player actor +0x14에 더한다.; row +0x48/+0x49는 현재 무기/방어구 내부 id이고, 장비 포인터 테이블 0x0048b1dc[id]를 통해 장비 상세 레코드를 읽는다.; 장비 상세 레코드 +0x10..+0x14는 공격/방어/기술/순발/운 보정이며, player base +0xbe/+0xc2/+0xc4/+0xc6/+0xc8에 더해 actor +0x1c/+0x20/+0x22/+0x24/+0x26에 기록된다.",
          "size": 14741
        },
        {
          "stem": "battle_selected_target_latch_review",
          "json": "battle_selected_target_latch_review.json",
          "exists": true,
          "title": "hwanse-battle-selected-target-latch-review",
          "kind": "hwanse-battle-selected-target-latch-review",
          "status": "battle-selected-target-latch-resolved",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "0x0059e347 자체의 직접 producer는 0x0040fb1c/0x0040fb21 한 곳으로 닫힌다.; 그 producer는 0x0059e33e current actor/object index를 0x0059e347에 복사한다.; 이 복사는 target-scope bit 0x08이 없는 경로, 즉 nested target-selection UI가 필요 없는 기본 대상 경로에서만 수행된다.; target-scope bit 0x08이 있으면 0x0040fa6d는 e347을 쓰지 않고 stream +4 nested selection script로 들어간다.",
          "size": 32110
        },
        {
          "stem": "battle_result_family_dispatch_review",
          "json": "battle_result_family_dispatch_review.json",
          "exists": true,
          "title": "전투 result-family dispatch",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "8-byte hit unit의 byte[5]는 result-family id다. 0x00433f0e가 이를 target actor +0x6b에 복사한 뒤 0x00546970[id]를 호출한다.; byte[3]은 현재 추출된 452개 hit unit에서 전부 0x00이므로 reserved/unused로 둔다.; byte[4]는 action payload의 target scope id다. 현재 값은 0x01 self/setup, 0x05 all allies, 0x06 all enemies, 0x09 one ally, 0x0a one enemy로만 갈라진다.; byte[4]는 0x00433649에서 직접 읽히고 0x00433545/0x004335c6에서 actor +0x67 target selector로 복사된다.",
          "size": 255952
        },
        {
          "stem": "battle_mode_coefficient_review",
          "json": "battle_mode_coefficient_review.json",
          "exists": true,
          "title": "battle mode coefficient review",
          "kind": "",
          "status": "mode-coefficients-grounded-tail-metadata",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "전투 자세/상태 이름과 6개 계수 byte는 0x0048bcaa 포인터 테이블에서 확정적으로 읽힌다.; 기본 자세 5개는 보통/돌격/방어/선제/반격이며, 사용자 설명과 EXE 수치가 일치한다.; 돌격은 공격 115, 방어 90, 명중 110, 회피 80이다. 방어는 공격 80, 방어 150이다.; 선제는 행동순서 계수 120, 반격은 행동순서 계수 10이라 turn order 설명과 맞는다.",
          "size": 21934
        }
      ]
    },
    {
      "id": "formula-status",
      "title": "데미지/회복/상태 변화",
      "desc": "HP/MP 적용, 자세/상태 계수, 명중/회피/크리티컬/상태 성공, 회복 아이템, 전투 종료 보상.",
      "files": [
        "battle_damage_formula_trace_review",
        "battle_stat_flag_status_semantics_review",
        "battle_support_status_policy_review",
        "battle_status_transition_review",
        "battle_recovery_item_effect_review",
        "battle_end_reward_review",
        "battle_per_hit_result_flag_review",
        "battle_result_flag_lifecycle_review",
        "battle_one_turn_flag_review",
        "battle_timed_lock_flag_review",
        "battle_knockout_inactive_flag_review",
        "battle_sukyeong_element_guard_review"
      ],
      "entries": [
        {
          "stem": "battle_damage_formula_trace_review",
          "json": "battle_damage_formula_trace_review.json",
          "exists": true,
          "title": "hwanse-battle-damage-formula-trace-review",
          "kind": "hwanse-battle-damage-formula-trace-review",
          "status": "partial-formula-trace",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "confirmed: ['0x433f0e가 hit unit payload를 선택하고 unit byte 0..2/5/7을 전투 결과 필드로 넘기는 지점이다.', 'hit unit byte[3]은 현재 추출된 모든 unit에서 0x00으로 고정되어 reserved/unused로 둔다.', 'hit unit byte[4]는 target scope id다. 0x01 self/setup, 0x05 all allies, 0x06 all enemies, 0x09 one ally, 0x0a one enemy로 분리된다.', '0x433649는 payload hit-unit byte[4]를 읽고, 0x433545/0x4335c6은 이를 runtime actor +0x67 target selector에 쓴다.', '0x40fa6d는 target scope bit 0x08로 selected-target branch를 가르고, 0x40f57c action setup은 selected target latch",
          "size": 77896
        },
        {
          "stem": "battle_stat_flag_status_semantics_review",
          "json": "battle_stat_flag_status_semantics_review.json",
          "exists": true,
          "title": "hwanse-battle-stat-flag-status-semantics-review",
          "kind": "hwanse-battle-stat-flag-status-semantics-review",
          "status": "stat-flag-semantics-grounded-critical-presentation-supported",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "+0x08/+0x0a/+0x0e/+0x10/+0x59/+0x62/+0x6b/+0x6c/+0x6d/+0x6e는 동작 기준으로 확정.; +0x14는 플레이어 현재 EXP / 적 EXP reward base로 확정. 승리 루프는 KO 적의 +0x14를 공식에 넣고 살아있는 플레이어 +0x14에 결과를 더한다.; +0x1c/+0x20/+0x22/+0x24/+0x26은 플레이어 장비/레벨업 루틴과 전투 공식 사용처가 맞물려 공격력/방어력/기술력/순발력/운으로 확정.; +0x28은 대부분 100인 별도 기본 계수라 운으로 단정하지 않는다. 상태창에 표시되지 않는 숨은 attacker-side 상태/크리티컬 발동률 계수로 확정한다.",
          "size": 26175
        },
        {
          "stem": "battle_support_status_policy_review",
          "json": "battle_support_status_policy_review.json",
          "exists": true,
          "title": "hwanse-battle-support-status-policy-review",
          "kind": "hwanse-battle-support-status-policy-review",
          "status": "confirmed",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "rows: 25; owners: {'아타호': 13, '린샹': 7, '스마슈': 5}; policyClasses: {'아타호 술 상태': 10, '전투 흐름': 3, '자세/명령': 4, '회복': 9, '린샹 고유 상태': 1, '상태 해제': 1, '원소 방어': 1, '스마슈 고유 상태': 1}; families: {'0x26': 1, '0x28': 2, '0x29': 2, '0x2a': 1, '0x2c': 1, '0x01': 3, '0x02': 3, '0x20': 4, '0x21': 4, '0x24': 1, '0x25': 1, '0x23': 1, '0x27': 1, '0x2e': 1, '0x22': 1, '0x2f': 1, '0x2d': 1, '0x03': 1}",
          "size": 42120
        },
        {
          "stem": "battle_status_transition_review",
          "json": "battle_status_transition_review.json",
          "exists": true,
          "title": "battle status transition review",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "actor +0x2a는 전투 자세와 상태이상을 모두 담는 확정 필드다.; 1..5는 플레이어가 전투 중 PgUp/PgDn으로 순환시키는 자세다.; 6..20은 공격 부가효과가 아니라 아타호 술취함, 스마슈 눈요기, 린샹 도발 전용 루틴이 직접 쓰는 캐릭터 고유 상태다.; 21..27은 일반 상태이상/행동불가 계열이다. 이 중 21..26은 +0x6c 공격 부가효과에서 올 수 있고, 27 기절은 HP 0 경로에서 온다.",
          "size": 48706
        },
        {
          "stem": "battle_recovery_item_effect_review",
          "json": "battle_recovery_item_effect_review.json",
          "exists": true,
          "title": "battle-recovery-item-effect-review",
          "kind": "battle-recovery-item-effect-review",
          "status": "confirmed consumable effect dispatch and revive flag clear",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "소모품 전투 효과는 actor +0x59를 index로 삼아 0x00546a38 함수 포인터 테이블을 호출한다.; index 1..6은 약초/해독초/리프레시 워터/마법의 물약/고급한방약/마수석과 일치한다.; 리프레시 워터와 마수석은 target +0x62 bit 0x80을 검사한 뒤 +0x62=0x01로 덮어써 bit 0x40/0x80을 동시에 해제한다.; 따라서 기절 HP0에서 세워진 0x40과 표시/비활성 전환에서 세워진 0x80은 부활 아이템 효과 함수에서 해제되는 것으로 볼 수 있다.",
          "size": 19547
        },
        {
          "stem": "battle_end_reward_review",
          "json": "battle_end_reward_review.json",
          "exists": true,
          "title": "hwanse-battle-end-reward-review",
          "kind": "hwanse-battle-end-reward-review",
          "status": "battle-end-exp-gold-grounded-item-drop-handler-grounded-inactive",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "전투 종료 보상은 KO된 enemy actor 기준으로 돌아간다. +0x62 bit 0x40이 KO 플래그다.; 경험치는 KO enemy마다 살아있는 player actor에게 fan-out된다. +0x62 bit 0x80 actor는 보상 fan-out에서 제외된다.; 경험치 공식은 적 EXP base(+0x14), player/enemy level(+0x06) 차이, 장비/아이템 class penalty를 사용하며 최종 보상은 1 미만으로 떨어지지 않는다.; 골드는 enemy actor +0x44에서 읽어 global money 0x4576e0에 더하고 999999로 cap한다.",
          "size": 10889
        },
        {
          "stem": "battle_per_hit_result_flag_review",
          "json": "battle_per_hit_result_flag_review.json",
          "exists": true,
          "title": "Battle Per-Hit Result Flag Review",
          "kind": "",
          "status": "per-hit-result-flags-grounded-critical-presentation-supported",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "Bits 0x08/0x10/0x20 are per-hit result bits cleared at hit-unit reset by +0x62 &= 0xc3.; 0x20 is the strongest conclusion: target full miss / HP-apply skip. 0x4340ae returns before HP/recovery apply.; 0x08 is a guard/glancing chip-damage target result: the normal formula is skipped and attacker +0x6e becomes random(3)+1.; 0x10 belongs to the attacker and selects the critical/alternate damage path and alternate result sound/effect; the result layer clears it after consumption.",
          "size": 17647
        },
        {
          "stem": "battle_result_flag_lifecycle_review",
          "json": "battle_result_flag_lifecycle_review.json",
          "exists": true,
          "title": "전투 결과 플래그 생명주기",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "actor +0x62는 상태이상 전용 필드가 아니라 long-lived actor flags와 per-hit result flags가 섞인 바이트다.; hit-unit setup의 &=0xc3 마스크가 핵심이다. 0x01/0x02/0x40/0x80은 보존되고, 0x04/0x08/0x10/0x20은 매 hit마다 지워진다.; 따라서 전투 러너/엔진에서는 0x08/0x10/0x20을 데미지/사운드/결과 표시의 1타성 플래그로 취급하고, 0x01/0x02/0x40/0x80은 actor 상태 생명주기로 별도 관리해야 한다.; 0x10은 MISS처럼 텍스트를 띄우는 경로가 아니라 alternate damage, 전용 결과음/helper, 섬광성 presentation으로 소비되는 critical branch로 승격됐다.",
          "size": 32639
        },
        {
          "stem": "battle_one_turn_flag_review",
          "json": "battle_one_turn_flag_review.json",
          "exists": true,
          "title": "Battle One-Turn Actor Flag Review",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "actor +0x62 bit 0x01 is a short-lived actor latch, not a damage/critical bit.; It is produced by one-turn status results, paralysis cure, and revive consumables.; The action-script gate at 0x40db36 tests mask 0x83, so 0x01 shares skip/branch behavior with timed lock 0x02 and inactive/display-skip 0x80.; The battle-order cleanup at 0x40d95b clears 0x01 after restoring +0x2a from +0x66 and clearing +0x64/+0x66.",
          "size": 15116
        },
        {
          "stem": "battle_timed_lock_flag_review",
          "json": "battle_timed_lock_flag_review.json",
          "exists": true,
          "title": "Battle Timed Lock Actor Flag Review",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "actor +0x62 bit 0x02 is a timed command/action lock flag.; Most 0x02 producers pair it with +0x64 timer and +0x66 prior-status backup.; The common recovery path at 0x43512e decrements +0x64 and clears only bit 0x02 with &=0xfd after timer/random recovery.; The action-script gate at 0x40db36 tests mask 0x83, so 0x02 actors branch away from the normal action stream like 0x01 and 0x80 actors.",
          "size": 12967
        },
        {
          "stem": "battle_knockout_inactive_flag_review",
          "json": "battle_knockout_inactive_flag_review.json",
          "exists": true,
          "title": "Battle Knockout / Inactive Actor Flag Review",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "actor +0x62 bit 0x40 is the HP-zero / knockout state.; actor +0x62 bit 0x80 is not the HP-zero state itself; it is the inactive/display-wait skip state set after phase-4 knockout display scheduling.; The display transition checks (+0x62 & 0xc0)==0x40, schedules +0x5b=1/+0x5c=0x20/+0x60=4, then ORs bit 0x80.; 0x80 actors are skipped by display wait, action gate, battle-order cleanup, and fan-out paths.",
          "size": 21558
        },
        {
          "stem": "battle_sukyeong_element_guard_review",
          "json": "battle_sukyeong_element_guard_review.json",
          "exists": true,
          "title": "전투 수경 element-guard byte 검토",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "result-family 0x2f는 수경 레코드에서만 사용된다.; 0x00546970[0x2f]는 0x00434e29 루틴을 가리킨다.; 0x00434e29는 target actor +0x2f, +0x30, +0x31을 각각 0으로 clear한다.; damage formula는 target actor +0x1c + hitUnit.family를 가변 index로 읽는다. 따라서 family 0x13/0x14/0x15는 각각 actor +0x2f/+0x30/+0x31에 대응한다.",
          "size": 26702
        }
      ]
    },
    {
      "id": "presentation",
      "title": "표시/사운드/결과 연출",
      "desc": "데미지 숫자, MISS/guard/critical 표시, 결과음, actor 표시 상태와 wait/slot 생명주기.",
      "files": [
        "battle_result_display_branch_review",
        "battle_result_helper_label_review",
        "battle_damage_digit_display_review",
        "battle_critical_presentation_review",
        "battle_status_success_sound_review",
        "battle_sound_role_review",
        "battle_sound_effect_review",
        "battle_actor_display_state_review",
        "battle_actor_display_wait_semantics_review",
        "battle_actor_display_slot_lifecycle_review"
      ],
      "entries": [
        {
          "stem": "battle_result_display_branch_review",
          "json": "battle_result_display_branch_review.json",
          "exists": true,
          "title": "battle-result-display-branch-review",
          "kind": "battle-result-display-branch-review",
          "status": "target-result-display-branches-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "Target result object script 0x00454578 tests actor sideFlags(+0x62) bit 0x20 first, then bit 0x08.; The 0x20 branch selects WLK id 12, helper operand 0x05(dec 5), and target frame 0. This is the display/sound branch paired with the full miss / HP-apply skip bit.; The 0x08 branch selects WLK id 11, helper operand 0x16(dec 22), and target frame 0. This is the display/sound branch paired with the guard/glancing chip-damage bit.; The normal branch falls through to helper operand 0x02(dec 2) and targ",
          "size": 11304
        },
        {
          "stem": "battle_result_helper_label_review",
          "json": "battle_result_helper_label_review.json",
          "exists": true,
          "title": "battle-result-helper-label-review",
          "kind": "battle-result-helper-label-review",
          "status": "result-helper-special-branch-visuals-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "reviewedHelpers: 3; helperOperands: ['0x02', '0x05', '0x16']; helperDecimalIds: [2, 5, 22]; promotedFrameScripts: 1",
          "size": 23790
        },
        {
          "stem": "battle_damage_digit_display_review",
          "json": "battle_damage_digit_display_review.json",
          "exists": true,
          "title": "battle-damage-digit-display-review",
          "kind": "battle-damage-digit-display-review",
          "status": "damage-digit-display-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "Damage values are rendered through function 0x0042119b.; For damage-number mode, 0x0042129f adds frame base 0x36 and 0x004212a2 adds selector sprite base 0x00100000, producing selector base 0x00100036.; The render loop divides the value by 10, uses the remainder as digit, and calls render primitive 0x004175d3 with selector base + digit.; The selector range 0x00100036..0x0010003f maps to btl_etc frames 54..63, rectangles x=192..264 y=64, 8x16.",
          "size": 18853
        },
        {
          "stem": "battle_critical_presentation_review",
          "json": "battle_critical_presentation_review.json",
          "exists": true,
          "title": "hwanse-battle-critical-presentation-review",
          "kind": "hwanse-battle-critical-presentation-review",
          "status": "critical-palette-flash-script-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 13148
        },
        {
          "stem": "battle_status_success_sound_review",
          "json": "battle_status_success_sound_review.json",
          "exists": true,
          "title": "hwanse-battle-status-success-sound-review",
          "kind": "hwanse-battle-status-success-sound-review",
          "status": "no-dedicated-status-success-sound-in-status-routines",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "routineCount: 3; callCount: 13; audioCallCount: 0; displaySpawnCallCount: 0",
          "size": 28764
        },
        {
          "stem": "battle_sound_role_review",
          "json": "battle_sound_role_review.json",
          "exists": true,
          "title": "hwanse-battle-sound-role-review",
          "kind": "hwanse-battle-sound-role-review",
          "status": "sound-roles-separated-by-opcode-and-result-operands",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "skillRows: 156; uniqueBattleWlkNos: 26; effectCueCalls0x24: 218; resultNormalCalls0xc2: 230",
          "size": 260763
        },
        {
          "stem": "battle_sound_effect_review",
          "json": "battle_sound_effect_review.json",
          "exists": true,
          "title": "hwanse-battle-sound-effect-review",
          "kind": "hwanse-battle-sound-effect-review",
          "status": "separates-0x24-effect-sound-from-0xc2-raw-result-sound",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "decodedSkillRows: 156; rowsWithEffectSoundOpcode24: 94; rowsWithRawSoundOpcodeC2: 133; rowsWithAltResultSoundRows: 100",
          "size": 416649
        },
        {
          "stem": "battle_actor_display_state_review",
          "json": "battle_actor_display_state_review.json",
          "exists": true,
          "title": "battle actor display state review",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 30745
        },
        {
          "stem": "battle_actor_display_wait_semantics_review",
          "json": "battle_actor_display_wait_semantics_review.json",
          "exists": true,
          "title": "hwanse-battle-actor-display-wait-semantics-review",
          "kind": "hwanse-battle-actor-display-wait-semantics-review",
          "status": "actor-display-wait-loop-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "waitRows: 4; slotFieldRows: 9; bitRows: 4; evidenceBlocks: 6",
          "size": 26692
        },
        {
          "stem": "battle_actor_display_slot_lifecycle_review",
          "json": "battle_actor_display_slot_lifecycle_review.json",
          "exists": true,
          "title": "battle actor display slot lifecycle review",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 21261
        }
      ]
    },
    {
      "id": "animation-vm",
      "title": "액션/애니메이션 VM",
      "desc": "display VM, frame gate, helper opcode/body/child/frameScript, 이펙트 spawn-tree와 위치/이동 규칙.",
      "files": [
        "battle_display_vm_static_decode",
        "battle_fallback_record_review",
        "battle_monster_action_frame_probe",
        "battle_monster_action_effect_review",
        "battle_skill_pattern_review",
        "battle_movement_pattern_review",
        "battle_caster_position_rule_review",
        "battle_frame_gate_review",
        "battle_display_wait_opcode_review",
        "battle_display_opcode_semantics_review",
        "battle_hit_window_gap_review",
        "battle_action_event_timeline_review",
        "battle_effect_object_review",
        "battle_effect_semantics_review",
        "battle_helper_opcode_review",
        "battle_helper_body_review",
        "battle_helper_child_script_review",
        "battle_helper_frame_script_review",
        "battle_helper_effect_runtime_review",
        "battle_helper_sync_timing_review",
        "battle_helper_resource_flow_review",
        "battle_helper_position_motion_review",
        "battle_helper_transform_solver_review",
        "battle_helper_spawn_tree_review",
        "battle_helper_visual_behavior_review",
        "battle_skill_implementation_gap_review"
      ],
      "entries": [
        {
          "stem": "battle_display_vm_static_decode",
          "json": "battle_display_vm_static_decode.json",
          "exists": true,
          "title": "hwanse-battle-display-vm-static-decode",
          "kind": "hwanse-battle-display-vm-static-decode",
          "status": "static-vm-walk-for-promoted-and-phase-table-player-actions",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 2183708
        },
        {
          "stem": "battle_fallback_record_review",
          "json": "battle_fallback_record_review.json",
          "exists": true,
          "title": "hwanse-battle-fallback-record-review",
          "kind": "hwanse-battle-fallback-record-review",
          "status": "payload-only-fallback-rows-promoted-through-phase-display-table",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "rows: 55; allHaveDisplayTablePointer: True; idleEndRows: 55; unknownStopRows: 0",
          "size": 45630
        },
        {
          "stem": "battle_monster_action_frame_probe",
          "json": "battle_monster_action_frame_probe.json",
          "exists": true,
          "title": "hwanse-battle-monster-action-frame-probe",
          "kind": "hwanse-battle-monster-action-frame-probe",
          "status": "static-monster-local-slot-reader-with-vm-script-producer",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 2571371
        },
        {
          "stem": "battle_monster_action_effect_review",
          "json": "battle_monster_action_effect_review.json",
          "exists": true,
          "title": "몬스터 행동 표시/이펙트 정적 리뷰",
          "kind": "hwanse-battle-monster-action-effect-review",
          "status": "static-monster-action-presentation-effect-coverage",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "actionRows: 294; presentationClassCounts: [{'value': 'local-frame-ready', 'count': 140}, {'value': 'damage-helper-effect-static-decoded', 'count': 74}, {'value': 'local-frame-motion-ready', 'count': 52}, {'value': 'local-frame-repeat-ready', 'count': 19}, {'value': 'support-helper-effect-static-decoded', 'count': 6}, {'value': 'recovery-no-local-frame', 'count': 3}]; visualClassCounts: [{'value': 'simple-frame', 'count': 92}, {'value': 'multi-frame', 'count': 61}, {'value': 'movement', 'count': ",
          "size": 1765886
        },
        {
          "stem": "battle_skill_pattern_review",
          "json": "battle_skill_pattern_review.json",
          "exists": true,
          "title": "hwanse-battle-skill-pattern-review",
          "kind": "hwanse-battle-skill-pattern-review",
          "status": "classifies-hit-count-speed-and-visual-scaling-patterns",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "decodedSkillRows: 156; familyGroups: 28; classificationCounts: {'visual-scaling': 9, 'constant-fixed-family': 5, 'hit-count-scaling': 10, 'mixed-fixed-family': 2, 'speed-scaling': 2}; cautionGroupCount: 15",
          "size": 352716
        },
        {
          "stem": "battle_movement_pattern_review",
          "json": "battle_movement_pattern_review.json",
          "exists": true,
          "title": "hwanse-battle-movement-pattern-review",
          "kind": "hwanse-battle-movement-pattern-review",
          "status": "scope-plus-display-vm-movement-patterns",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "decodedActionRows: 156; targetClassCounts: {'enemy-single': 69, 'self': 22, 'self-then-enemy-single': 5, 'enemy-all': 54, 'self-then-enemy-all': 3, 'ally-single': 2, 'ally-all': 1}; positionClassCounts: {'single-target-front-basic-implicit': 5, 'target-front-direct-placement': 21, 'self-support': 22, 'single-target-ranged-caster-effect': 5, 'target-approach-motion': 7, 'single-target-front-local-combo-inferred': 15, 'target-pierce-motion': 5, 'single-target-ranged-engine-effect': 11, 'self-prep-",
          "size": 624496
        },
        {
          "stem": "battle_caster_position_rule_review",
          "json": "battle_caster_position_rule_review.json",
          "exists": true,
          "title": "hwanse-battle-caster-position-rule-review",
          "kind": "hwanse-battle-caster-position-rule-review",
          "status": "per-skill-caster-position-rules",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "ruleRows: 156; familyGroups: 74; casterRuleCounts: {'target-front-basic-implicit': 5, 'target-front-direct': 19, 'self-support': 21, 'target-front-implicit-local-combo': 20, 'home-approach-target': 7, 'target-front-then-pierce': 3, 'target-fixed-side-direct': 5, 'self-prep-target-front-local-combo': 2, 'caster-local-all-target-action': 24, 'screen-or-ranged-all-target-effect': 22, 'self-prep-screen-all-target-effect': 3, 'caster-ranged-effect': 7, 'all-target-no-promoted-position': 1, 'clone-spr",
          "size": 246597
        },
        {
          "stem": "battle_frame_gate_review",
          "json": "battle_frame_gate_review.json",
          "exists": true,
          "title": "hwanse-battle-frame-gate-review",
          "kind": "hwanse-battle-frame-gate-review",
          "status": "actor-repeat-gates-expanded-helper-gates-indexed",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "rows: 156; rowsWithRepeatLoopExpansion: 18; rowsWithEngineWaitBarrier: 144; rowsWithHelperFrameScript: 52",
          "size": 707145
        },
        {
          "stem": "battle_display_wait_opcode_review",
          "json": "battle_display_wait_opcode_review.json",
          "exists": true,
          "title": "hwanse-battle-display-wait-opcode-review",
          "kind": "hwanse-battle-display-wait-opcode-review",
          "status": "static-display-wait-opcodes-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "waitRows: 276; opcodeCounts: {'0xbf': 217, '0xc1': 59}; semanticClassCounts: {'actor-flag-barrier': 24, 'actor-flag-busy-barrier': 44, 'inverse-actor-flag-barrier': 4, 'pierce-motion-actor-flag-barrier': 8, 'pre-result-actor-flag-barrier': 23, 'result-reaction-barrier': 173}; c1ModeCounts: {'0': 55, '1': 4}",
          "size": 503474
        },
        {
          "stem": "battle_display_opcode_semantics_review",
          "json": "battle_display_opcode_semantics_review.json",
          "exists": true,
          "title": "hwanse-battle-display-opcode-semantics-review",
          "kind": "hwanse-battle-display-opcode-semantics-review",
          "status": "remaining-display-opcodes-audited",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "auditedOpcodes: 8; grounded: 8; partiallyGrounded: 0; decodedRows: 4016",
          "size": 6037
        },
        {
          "stem": "battle_hit_window_gap_review",
          "json": "battle_hit_window_gap_review.json",
          "exists": true,
          "title": "hwanse-battle-hit-window-gap-review",
          "kind": "hwanse-battle-hit-window-gap-review",
          "status": "main-actor-hit-window-coverage-and-sound-only-gaps",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "rows: 156; hitEvents: 230; confirmedHitEvents: 230; resultSoundOnlyEvents: 0",
          "size": 191145
        },
        {
          "stem": "battle_action_event_timeline_review",
          "json": "battle_action_event_timeline_review.json",
          "exists": true,
          "title": "hwanse-battle-action-event-timeline-review",
          "kind": "hwanse-battle-action-event-timeline-review",
          "status": "main-actor-vm-gate-order-hit-sound-helper-timeline",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "rows: 156; rowsWithResultSound: 133; rowsWithEffectSound: 94; rowsWithHelperCall: 96",
          "size": 1512757
        },
        {
          "stem": "battle_effect_object_review",
          "json": "battle_effect_object_review.json",
          "exists": true,
          "title": "hwanse-battle-effect-object-review",
          "kind": "hwanse-battle-effect-object-review",
          "status": "helper-child-spawn-frameScript-anchor-review",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "helpers: 85; helpersWithDirectFrameScript: 20; helpersWithSpawnTree: 55; helpersWithRandomRange: 38",
          "size": 1399612
        },
        {
          "stem": "battle_effect_semantics_review",
          "json": "battle_effect_semantics_review.json",
          "exists": true,
          "title": "hwanse-battle-effect-semantics-review",
          "kind": "hwanse-battle-effect-semantics-review",
          "status": "effect-render-track-classification",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "rows: 156; renderTrackCounts: {'actor-melee-or-dash': 55, 'support-or-status': 25, 'ranged-projectile-or-beam': 16, 'self-prep-actor-hit': 2, 'caster-action-screen-hit': 24, 'screen-wide-effect': 23, 'spawned-child-display-flow': 9, 'simple-screen-hit': 1, 'display-list-cleanup-flow': 1}; implementationStateCounts: {'actor-frame-inferred': 5, 'actor-frame-mostly-promoted': 49, 'needs-ui/status-effect-policy': 25, 'needs-child-helper-script-runner': 34, 'actor-frame-self-prep': 2, 'actor-frame-pl",
          "size": 160543
        },
        {
          "stem": "battle_helper_opcode_review",
          "json": "battle_helper_opcode_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-opcode-review",
          "kind": "hwanse-battle-helper-opcode-review",
          "status": "groups-helper-like-battle-vm-opcodes",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "decodedRows: 156; rowsWithHelperId0xbd: 96; uniqueHelperIds0xbd: 69; rowsWithEffectWlk0x24: 94",
          "size": 222116
        },
        {
          "stem": "battle_helper_body_review",
          "json": "battle_helper_body_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-body-review",
          "kind": "hwanse-battle-helper-body-review",
          "status": "0xbd-dispatch-table-and-function-body-evidence",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "usedHelperIds: 85; playerHelperIds: 69; monsterHelperIds: 42; uniqueFunctionBodies: 38",
          "size": 249344
        },
        {
          "stem": "battle_helper_child_script_review",
          "json": "battle_helper_child_script_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-child-script-review",
          "kind": "hwanse-battle-helper-child-script-review",
          "status": "child-display-script-static-decode",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "helperRows: 85; helpersWithDecodedChildScript: 85; helpersWithAnyFrameWrite: 25; helpersWithRandomRange: 31",
          "size": 1430973
        },
        {
          "stem": "battle_helper_frame_script_review",
          "json": "battle_helper_frame_script_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-frame-script-review",
          "kind": "hwanse-battle-helper-frame-script-review",
          "status": "helper-frame-script-static-decode",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "frameScriptTargets: 24; helpersWithFrameScriptTargets: 20; skillsWithFrameScriptTargets: 51; targetsWithFrameWrites: 24",
          "size": 148818
        },
        {
          "stem": "battle_helper_effect_runtime_review",
          "json": "battle_helper_effect_runtime_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-effect-runtime-review",
          "kind": "hwanse-battle-helper-effect-runtime-review",
          "status": "confirmed-helper-static-facts",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "helpers: 77; skillsIndexed: 61; helpersWithRandomRange: 27; helpersWithFrameScript: 18",
          "size": 230421
        },
        {
          "stem": "battle_helper_sync_timing_review",
          "json": "battle_helper_sync_timing_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-sync-timing-review",
          "kind": "hwanse-battle-helper-sync-timing-review",
          "status": "confirmed-gate-order-sync",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "helpers: 85; helpersWithFrameScriptTimeline: 20; helpersWithCombinedActorFlags: 70; helpersWithChildActorFlags: 55",
          "size": 818717
        },
        {
          "stem": "battle_helper_resource_flow_review",
          "json": "battle_helper_resource_flow_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-random-motion-control-review",
          "kind": "hwanse-battle-helper-random-motion-control-review",
          "status": "random-motion-control-flow-static-review",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "helperRows: 77; helpersWithRandomRange: 27; helpersWithMotionStep: 18; helpersWithClearDisplayList: 11",
          "size": 491991
        },
        {
          "stem": "battle_helper_position_motion_review",
          "json": "battle_helper_position_motion_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-position-motion-review",
          "kind": "hwanse-battle-helper-position-motion-review",
          "status": "helper-position-motion-field-review",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "helpers: 85; helpersWithPositionOrMotion: 84; helpersWithMotionStep: 34; fieldWriteCounts: {'0x1c': 217, '0x20': 219, '0x68': 17, '0x6c': 31, '0x74': 80, '0x80': 68, '0x84': 113, '0x88': 24, '0x8c': 121, '0x8e': 47, '0x90': 110, '0x92': 63, '0x94': 64, '0x96': 76, '0xa8': 155}",
          "size": 1071256
        },
        {
          "stem": "battle_helper_transform_solver_review",
          "json": "battle_helper_transform_solver_review.json",
          "exists": true,
          "title": "전투 helper parent-child transform 정적 해석",
          "kind": "hwanse-battle-helper-transform-solver-review",
          "status": "static-helper-transform-coverage",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "monsterActionRows: 294; helperCalls: 139; helperCallsWithPreviewScript: 102; previewScripts: 219",
          "size": 573545
        },
        {
          "stem": "battle_helper_spawn_tree_review",
          "json": "battle_helper_spawn_tree_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-spawn-tree-review",
          "kind": "hwanse-battle-helper-spawn-tree-review",
          "status": "spawn-tree-helper-decode",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "helpersWithSpawnTree: 55; spawnNodes: 124; uniqueSpawnTargets: 42; uniqueSpawnLocalFrameScriptTargets: 21",
          "size": 794940
        },
        {
          "stem": "battle_helper_visual_behavior_review",
          "json": "battle_helper_visual_behavior_review.json",
          "exists": true,
          "title": "hwanse-battle-helper-visual-behavior-review",
          "kind": "hwanse-battle-helper-visual-behavior-review",
          "status": "exe-derived-helper-visual-behavior",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "helpers: 85; helpersWithVisualEvidence: 85; behaviorClassCounts: {'actor-flag-sync': 10, 'multi-frameScript-effect': 16, 'init-frame-effect': 7, 'direct-frame-spawn': 21, 'randomized-child-spawn-stream': 21, 'nested-frameScript-spawn-effect': 5, 'single-frameScript-flash': 2, 'repeated-direct-frame-spawn': 3}; helpersWithBlinkFlag: 0",
          "size": 1528229
        },
        {
          "stem": "battle_skill_implementation_gap_review",
          "json": "battle_skill_implementation_gap_review.json",
          "exists": true,
          "title": "hwanse-battle-skill-implementation-gap-review",
          "kind": "hwanse-battle-skill-implementation-gap-review",
          "status": "no-unresolved-implementation-gaps",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "rowsWithFlags: 0; supportPolicyRowsOutsideGap: 25; presentationPolicyRows: 0; runnerImplementationGapRows: 0",
          "size": 1687
        }
      ]
    },
    {
      "id": "resources",
      "title": "전투 리소스/후보 데이터",
      "desc": "전투 배경, 적 스프라이트 후보, 이벤트 후보, 브라우저 smoke 결과처럼 계산식과 직접 무관한 보조 데이터.",
      "files": [
        "battle_backgrounds",
        "battle_enemy_candidates",
        "battle_event_candidates",
        "battle_action_handler_context",
        "battle_background_review_browser_smoke"
      ],
      "entries": [
        {
          "stem": "battle_backgrounds",
          "json": "battle_backgrounds.json",
          "exists": true,
          "title": "battle backgrounds",
          "kind": "",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 116859
        },
        {
          "stem": "battle_enemy_candidates",
          "json": "battle_enemy_candidates.json",
          "exists": true,
          "title": "battle enemy candidates",
          "kind": "",
          "status": "sprite-proximity-candidate-not-enemy-row",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 274431
        },
        {
          "stem": "battle_event_candidates",
          "json": "battle_event_candidates.json",
          "exists": true,
          "title": "battle event candidates",
          "kind": "",
          "status": "Battle-like event dialogue blocks with btl_* resources.",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 22405
        },
        {
          "stem": "battle_action_handler_context",
          "json": "battle_action_handler_context.json",
          "exists": true,
          "title": "battle action handler context",
          "kind": "",
          "status": "battle-action-handler-grounded-entry-dispatch-missing",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 7529
        },
        {
          "stem": "battle_background_review_browser_smoke",
          "json": "battle_background_review_browser_smoke.json",
          "exists": true,
          "title": "battle background review browser smoke",
          "kind": "",
          "status": "passed",
          "runtimeUsed": null,
          "evidence": "browser-smoke",
          "summary": "",
          "size": 5337
        }
      ]
    },
    {
      "id": "other-json",
      "title": "기타 JSON 근거",
      "desc": "통합 그룹에 직접 배치하지 않은 남은 전투 JSON 근거.",
      "files": [
        "battle_analysis_summary",
        "battle_bakuten_effect_review",
        "battle_child_lifecycle_draw_order_review",
        "battle_child_spawn_stream_review",
        "battle_child_target_renderer_gap_review",
        "battle_child_target_renderer_plan_review",
        "battle_child_target_script_expansion_review",
        "battle_dragon_effect_motion_review",
        "battle_effect_animation_pattern_review",
        "battle_effect_capture_checklist",
        "battle_effect_pixel_compare_report",
        "battle_effect_pixel_oracle_plan",
        "battle_effect_runner_binding_review",
        "battle_effect_visual_assertion_review",
        "battle_formula_calculator_notes",
        "battle_hishokaku_effect_review",
        "battle_hogyeok_effect_review",
        "battle_monster_movement_pattern_review",
        "battle_motion_boundary_loop_review",
        "battle_mouko_special_sparkle_review",
        "battle_player_display_start_audit",
        "battle_result_layer_trace_review",
        "battle_roar_effect_review",
        "battle_skill_complete_pattern_review",
        "battle_skill_goal_audit",
        "battle_skill_timeline_browser_smoke",
        "battle_skill_timeline_browser_summary",
        "battle_skill_timeline_canonical",
        "battle_skill_timeline_status",
        "battle_sparkle_motion_review"
      ],
      "entries": [
        {
          "stem": "battle_analysis_summary",
          "json": "battle_analysis_summary.json",
          "exists": true,
          "title": "hwanse-battle-analysis-summary",
          "kind": "hwanse-battle-analysis-summary",
          "status": "",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 74377
        },
        {
          "stem": "battle_bakuten_effect_review",
          "json": "battle_bakuten_effect_review.json",
          "exists": true,
          "title": "hwanse-battle-bakuten-effect-review",
          "kind": "hwanse-battle-bakuten-effect-review",
          "status": "static-exe-proof-for-bakuten-blade-helper-motion",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "levels: 4; levelsWithHelper: 3; effectFrame: btl_efc#179; effectRect: {'x': 192, 'y': 224, 'w': 48, 'h': 64, 'index': 179, 'asset': 'btl_efc', 'frame': 179}",
          "size": 6698
        },
        {
          "stem": "battle_child_lifecycle_draw_order_review",
          "json": "battle_child_lifecycle_draw_order_review.json",
          "exists": true,
          "title": "hwanse-battle-child-lifecycle-draw-order-review",
          "kind": "hwanse-battle-child-lifecycle-draw-order-review",
          "status": "static-child-lifecycle-reviewed",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "skillRows: 58; helpersWithDirectSpawn: 63; totalDirectSpawnEvents: 279; rendererReadinessCounts: {'renderer-needs-lifecycle-work': 93}",
          "size": 273528
        },
        {
          "stem": "battle_child_spawn_stream_review",
          "json": "battle_child_spawn_stream_review.json",
          "exists": true,
          "title": "hwanse-battle-child-spawn-stream-review",
          "kind": "hwanse-battle-child-spawn-stream-review",
          "status": "static-child-spawn-stream-reviewed",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "reviewRows: 59; uniqueHelpers: 49; ownerCounts: {'린샹': 22, '스마슈': 17, '아타호': 20}; requirementCounts: {'child motion loop present': 5, 'palette transform effect; no CNS frame stream': 1, 'random placement/range present': 46, 'runner must instantiate child objects over time': 28}",
          "size": 129715
        },
        {
          "stem": "battle_child_target_renderer_gap_review",
          "json": "battle_child_target_renderer_gap_review.json",
          "exists": true,
          "title": "hwanse-battle-child-target-renderer-gap-review",
          "kind": "hwanse-battle-child-target-renderer-gap-review",
          "status": "renderer-plan-consumed-with-partial-motion-semantics",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "targetRendererPlanRows: 11; rendererPlanClassCounts: {'counter-held-direct-frame': 3, 'motion-boundary-loop': 7, 'nested-child-spawner': 1}; implementationRequirementCounts: {'apply-boundary-loop-lifetime': 7, 'apply-counter-held-lifetime': 3, 'apply-motion-step-until-branch': 7, 'apply-nested-repeat-counter': 1, 'consume-target-renderer-plan-json': 11, 'recursive-child-spawn-lifetime': 1}; fulfilledRequirementCounts: {'apply-boundary-loop-lifetime': 7, 'apply-counter-held-lifetime': 3, 'apply-m",
          "size": 13362
        },
        {
          "stem": "battle_child_target_renderer_plan_review",
          "json": "battle_child_target_renderer_plan_review.json",
          "exists": true,
          "title": "hwanse-battle-child-target-renderer-plan-review",
          "kind": "hwanse-battle-child-target-renderer-plan-review",
          "status": "renderer-parameter-plan-static",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "uniqueHelperTargetPlans: 11; rendererPlanClassCounts: {'counter-held-direct-frame': 3, 'motion-boundary-loop': 7, 'nested-child-spawner': 1}; helperCounts: {'105': 1, '106': 1, '107': 1, '79': 1, '95': 1, '96': 2, '97': 2, '98': 2}; unresolvedRendererActions: 0",
          "size": 51447
        },
        {
          "stem": "battle_child_target_script_expansion_review",
          "json": "battle_child_target_script_expansion_review.json",
          "exists": true,
          "title": "hwanse-battle-child-target-script-expansion-review",
          "kind": "hwanse-battle-child-target-script-expansion-review",
          "status": "static-target-script-expanded",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "targetScriptStopReasonEvents: 79; promotedTargetScriptEvents: 79; remainingUnclassifiedEvents: 0; targetScriptClassCounts: {'counter-held-direct-frame': 12, 'motion-boundary-loop': 63, 'nested-child-spawner': 4}",
          "size": 117030
        },
        {
          "stem": "battle_dragon_effect_motion_review",
          "json": "battle_dragon_effect_motion_review.json",
          "exists": true,
          "title": "battle-dragon-effect-motion-review",
          "kind": "battle-dragon-effect-motion-review",
          "status": "static-exe-dragon-child-spawn-stream-confirmed",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "helperIds: [95, 96, 97, 98]; levels: [1, 2, 3, 4]; spawnCountsByLevel: [{'level': 1, 'skillIdHex': '0x15', 'helperId': 95, 'directSpawnCount': 17, 'frameTimeline': ['186@0', '186@2', '186@4', '186@6', '186@8', '186@10', '186@12', '186@14', '186@16', '186@18', '186@20', '186@22', '186@24', '186@26', '186@28', '186@30', '186@32']}, {'level': 2, 'skillIdHex': '0x16', 'helperId': 96, 'directSpawnCount': 7, 'frameTimeline': ['184@0', '186@1', '186@2', '186@3', '186@4', '186@5', '186@6']}, {'level': 3",
          "size": 48000
        },
        {
          "stem": "battle_effect_animation_pattern_review",
          "json": "battle_effect_animation_pattern_review.json",
          "exists": true,
          "title": "hwanse-battle-effect-animation-pattern-review",
          "kind": "hwanse-battle-effect-animation-pattern-review",
          "status": "effect-helper-animation-patterns-joined-by-skill",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "skillRows: 156; helperRows: 85; skillsWithHelpers: 96; skillsWithEffectFrames: 92",
          "size": 1225985
        },
        {
          "stem": "battle_effect_capture_checklist",
          "json": "battle_effect_capture_checklist.json",
          "exists": true,
          "title": "hwanse-battle-effect-capture-checklist",
          "kind": "hwanse-battle-effect-capture-checklist",
          "status": "waiting-for-captures",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "manifestPath: data/battle_effect_capture_manifest.json; manifestExists: False; firstPassRows: 8; firstPassReady: 0",
          "size": 52819
        },
        {
          "stem": "battle_effect_pixel_compare_report",
          "json": "battle_effect_pixel_compare_report.json",
          "exists": true,
          "title": "hwanse-battle-effect-pixel-compare-report",
          "kind": "hwanse-battle-effect-pixel-compare-report",
          "status": "waiting-for-captures",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "manifestExists: False; manifestEntries: 0; firstPassRowsExpected: 8; firstPassRowsCompared: 0",
          "size": 498
        },
        {
          "stem": "battle_effect_pixel_oracle_plan",
          "json": "battle_effect_pixel_oracle_plan.json",
          "exists": true,
          "title": "hwanse-battle-effect-pixel-oracle-plan",
          "kind": "hwanse-battle-effect-pixel-oracle-plan",
          "status": "capture-oracle-not-built",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "remainingGap: original-runtime pixel/particle choreography oracle; webVisualAssertionStatus: visual-assertions-pass; webVisualAssertionRows: 52; requiredFullOracleRows: 52",
          "size": 67314
        },
        {
          "stem": "battle_effect_runner_binding_review",
          "json": "battle_effect_runner_binding_review.json",
          "exists": true,
          "title": "hwanse-battle-effect-runner-binding-review",
          "kind": "hwanse-battle-effect-runner-binding-review",
          "status": "runner-binding-reviewed",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "effectSkillRows: 156; skillsWithEffectFrames: 92; skillsWithReviewFlags: 0; skillsWithExecutionRequirements: 52",
          "size": 7729
        },
        {
          "stem": "battle_effect_visual_assertion_review",
          "json": "battle_effect_visual_assertion_review.json",
          "exists": true,
          "title": "hwanse-battle-effect-visual-assertion-review",
          "kind": "hwanse-battle-effect-visual-assertion-review",
          "status": "visual-assertions-pass",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "requirementRows: 52; representativeEffectRows: 13; requirementGroups: 4; effectClassGroups: 3",
          "size": 31102
        },
        {
          "stem": "battle_formula_calculator_notes",
          "json": "battle_formula_calculator_notes.json",
          "exists": true,
          "title": "hwanse-battle-formula-calculator-notes",
          "kind": "hwanse-battle-formula-calculator-notes",
          "status": "calculator-facing-evidence",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 3272
        },
        {
          "stem": "battle_hishokaku_effect_review",
          "json": "battle_hishokaku_effect_review.json",
          "exists": true,
          "title": "hwanse-battle-hishokaku-motion-effect-review",
          "kind": "hwanse-battle-hishokaku-motion-effect-review",
          "status": "static-exe-proof-for-hishokaku-dash-and-0xbc-child-effect",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "levels: 4; levelsWithHelper: 0; levelsWithDustProjection: 2; levelsWithGroundedEffectFrameStream: 2",
          "size": 246668
        },
        {
          "stem": "battle_hogyeok_effect_review",
          "json": "battle_hogyeok_effect_review.json",
          "exists": true,
          "title": "hwanse-battle-hogyeok-effect-review",
          "kind": "hwanse-battle-hogyeok-effect-review",
          "status": "static-exe-proof-for-hogyeok-target-overlaid-effect",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "levels: 4; levelsWithVisualHelper: 3; levelsWithBlink: 0; targetOverlayProofRows: 3",
          "size": 6918
        },
        {
          "stem": "battle_monster_movement_pattern_review",
          "json": "battle_monster_movement_pattern_review.json",
          "exists": true,
          "title": "몬스터 행동 이동 패턴 정적 리뷰",
          "kind": "hwanse-battle-monster-movement-pattern-review",
          "status": "static-monster-movement-patterns-grounded",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "actionRows: 294; movementClassCounts: [{'value': 'stationary-local-frame', 'count': 163}, {'value': 'stationary-helper-effect', 'count': 64}, {'value': 'dash-or-charge-then-return', 'count': 30}, {'value': 'direct-placement-local', 'count': 17}, {'value': 'local-offset-pose', 'count': 11}, {'value': 'direct-placement-helper-effect', 'count': 5}, {'value': 'nonzero-motion-other-window', 'count': 4}]; topMovementSignatures: [{'value': '-', 'count': 220}, {'value': 'pre-result:direct-placement/m0/s",
          "size": 542386
        },
        {
          "stem": "battle_motion_boundary_loop_review",
          "json": "battle_motion_boundary_loop_review.json",
          "exists": true,
          "title": "hwanse-battle-motion-boundary-loop-review",
          "kind": "hwanse-battle-motion-boundary-loop-review",
          "status": "motion-boundary-loop-semantics-grounded",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "motionBoundaryRows: 7; helpers: [95, 96, 97, 98]; helperRowCounts: {'95': 1, '96': 2, '97': 2, '98': 2}; motionModeCounts: {'0x09': 7}",
          "size": 43934
        },
        {
          "stem": "battle_mouko_special_sparkle_review",
          "json": "battle_mouko_special_sparkle_review.json",
          "exists": true,
          "title": "battle-mouko-special-sparkle-review",
          "kind": "battle-mouko-special-sparkle-review",
          "status": "static-exe-proof-for-0xbc-mode4-sparkle-child-effect",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "mode4CallCount: 2; moukoSpecialCall: {'ownerKey': 'ataho', 'ownerName': '아타호', 'skillName': '맹호스페셜', 'skillIdHex': '0x19', 'level': 4, 'key': 'ataho:0x19:4', 'tick': 60, 'movementOpcode': {'tick': 60, 'kind': 'movement', 'vaHex': '0x004d69cc', 'opcode': '0xbc', 'summary': 'interpolated child motion mode=4, selector=2, stepDivisor=4: one target-side edge placement; side depends on actor kind.', 'selector': 2, 'divisor': 4, 'movementMode': 4}, 'resultSoundAtSameTick': {'tick': 60, 'kind': 'result-",
          "size": 196996
        },
        {
          "stem": "battle_player_display_start_audit",
          "json": "battle_player_display_start_audit.json",
          "exists": true,
          "title": "hwanse-battle-player-display-start-audit",
          "kind": "hwanse-battle-player-display-start-audit",
          "status": "strict-player-display-start-audit",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "playerRows: 156; evidenceClassCounts: {'phase-table direct': 53, 'branch-family override': 103}; startSourceCounts: {'display-table-phase-pointer': 53, 'entry-spec-family-start': 97, 'display-start-override': 6}; findingCounts: {}",
          "size": 571796
        },
        {
          "stem": "battle_result_layer_trace_review",
          "json": "battle_result_layer_trace_review.json",
          "exists": true,
          "title": "hwanse-battle-result-layer-trace-review",
          "kind": "hwanse-battle-result-layer-trace-review",
          "status": "target-result-layer-static-grounded",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "targetScriptRows: 31; targetBlocks: 7; runtimeResultRows: 0; targetDamageRows: 0",
          "size": 42306
        },
        {
          "stem": "battle_roar_effect_review",
          "json": "battle_roar_effect_review.json",
          "exists": true,
          "title": "hwanse-battle-roar-effect-review",
          "kind": "hwanse-battle-roar-effect-review",
          "status": "static-exe-proof-for-mengho-roar-effect",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "levels: 4; levelsWithVisualHelper: 3; levelsWithBlink: 0; btlEfcFrame190Rect: {'x': 480, 'y': 208, 'w': 80, 'h': 80, 'frame': 190, 'asset': 'btl_efc'}",
          "size": 4079
        },
        {
          "stem": "battle_skill_complete_pattern_review",
          "json": "battle_skill_complete_pattern_review.json",
          "exists": true,
          "title": "hwanse-battle-skill-complete-pattern-review",
          "kind": "hwanse-battle-skill-complete-pattern-review",
          "status": "aggregated-skill-pattern-evidence",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "rows: 156; rowsWithHelper: 96; rowsWithHelperLifecycle: 60; rowsWithChildMotionLoop: 5",
          "size": 1852314
        },
        {
          "stem": "battle_skill_goal_audit",
          "json": "battle_skill_goal_audit.json",
          "exists": true,
          "title": "hwanse-battle-skill-goal-audit",
          "kind": "hwanse-battle-skill-goal-audit",
          "status": "complete",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "criteria: 4; complete: 4; notComplete: 0; missingOrIncomplete: []",
          "size": 8422
        },
        {
          "stem": "battle_skill_timeline_browser_smoke",
          "json": "battle_skill_timeline_browser_smoke.json",
          "exists": true,
          "title": "hwanse-battle-skill-timeline-browser-smoke",
          "kind": "hwanse-battle-skill-timeline-browser-smoke",
          "status": "ok",
          "runtimeUsed": null,
          "evidence": "browser-smoke",
          "summary": "",
          "size": 193079
        },
        {
          "stem": "battle_skill_timeline_browser_summary",
          "json": "battle_skill_timeline_browser_summary.json",
          "exists": true,
          "title": "hwanse-battle-skill-timeline-browser-summary",
          "kind": "hwanse-battle-skill-timeline-browser-summary",
          "status": "ready",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "",
          "size": 12119
        },
        {
          "stem": "battle_skill_timeline_canonical",
          "json": "battle_skill_timeline_canonical.json",
          "exists": true,
          "title": "hwanse-battle-skill-timeline-canonical",
          "kind": "hwanse-battle-skill-timeline-canonical",
          "status": "canonical-exe-evidence-bundle",
          "runtimeUsed": false,
          "evidence": "static",
          "summary": "playerRows: 156; monsterRows: 294; totalRows: 450; alignmentCounts: {'start-confirmed': 53, 'visual-confirmed': 397}",
          "size": 4511157
        },
        {
          "stem": "battle_skill_timeline_status",
          "json": "battle_skill_timeline_status.json",
          "exists": true,
          "title": "hwanse-battle-skill-timeline-status",
          "kind": "hwanse-battle-skill-timeline-status",
          "status": "player-skill-timeline-confirmation",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "playerRows: 156; statusCounts: {'confirmed': 156}; visualAlignmentCounts: {'phase-table-start-confirmed': 53, 'family-start-confirmed': 97, 'display-start-corrected': 6}; reasonCounts: {}",
          "size": 141124
        },
        {
          "stem": "battle_sparkle_motion_review",
          "json": "battle_sparkle_motion_review.json",
          "exists": true,
          "title": "battle-sparkle-motion-review",
          "kind": "battle-sparkle-motion-review",
          "status": "static-exe-sparkle-loop-count-and-shared-child-frame-script",
          "runtimeUsed": null,
          "evidence": "static-inferred",
          "summary": "mode4ChildSpawnTotalCount: 4; qaejinHelperStepCounts: [{'skillIdHex': '0x0a', 'level': 2, 'helperId': 29, 'stepCount': 1}, {'skillIdHex': '0x0b', 'level': 3, 'helperId': 30, 'stepCount': 2}, {'skillIdHex': '0x0c', 'level': 4, 'helperId': 31, 'stepCount': 10}]; sharedSparkleFrames: [30, 31, 32, 33, 34, 35, 36, 37]; sharedSparkleGates: [2, 2, 2, 2, 2, 2, 2, 2]",
          "size": 19154
        }
      ]
    }
  ]
}