{"version":1,"kind":"hwanse-battle-effect-runner-binding-review","source":"tools/build_battle_effect_runner_binding_review.py","inputs":["out/battle_effect_animation_pattern_review.json","web/engine/battle/animation.js","web/battle_skill_timeline_review.html","web/battle_formula_calculator.html","web/battle_simulator.html"],"status":"runner-binding-reviewed","summary":{"effectSkillRows":156,"skillsWithEffectFrames":92,"skillsWithReviewFlags":0,"skillsWithExecutionRequirements":52,"requirementBuckets":4,"engineChecksPassed":6,"engineChecksTotal":6,"pageChecksPassed":30,"pageChecksTotal":30,"pagesUsingPlaybackEffectFrames":3,"pagesRenderingHelperEffectLayer":3,"pagesWithGenericResultEffectsOnly":0},"engineChecks":{"helperEffectFrames exported":true,"helper effect end extends actor hold":true,"direct/frameScript/init/nested visual merge":true,"transform offsets and motion carried":true,"helper position/motion VM projection":true,"shared playback builder exported":true},"pageChecks":[{"page":"web/battle_skill_timeline_review.html","loadsCanonicalTimeline":true,"loadsHelperSync":true,"loadsHelperVisual":true,"loadsHelperPositionMotion":true,"usesSharedPlayback":true,"passesHelperSyncIndex":true,"passesHelperVisualIndex":true,"passesHelperPositionIndex":true,"delegatesHelperFrames":true,"usesSharedProjection":true,"usesPlaybackEffectFrames":true,"rendersHelperEffectLayer":true,"hasOnlyGenericResultEffects":false},{"page":"web/battle_formula_calculator.html","loadsCanonicalTimeline":true,"loadsHelperSync":true,"loadsHelperVisual":true,"loadsHelperPositionMotion":true,"usesSharedPlayback":true,"passesHelperSyncIndex":true,"passesHelperVisualIndex":true,"passesHelperPositionIndex":true,"delegatesHelperFrames":true,"usesSharedProjection":true,"usesPlaybackEffectFrames":true,"rendersHelperEffectLayer":true,"hasOnlyGenericResultEffects":false},{"page":"web/battle_simulator.html","loadsCanonicalTimeline":true,"loadsHelperSync":true,"loadsHelperVisual":true,"loadsHelperPositionMotion":true,"usesSharedPlayback":true,"passesHelperSyncIndex":true,"passesHelperVisualIndex":true,"passesHelperPositionIndex":true,"delegatesHelperFrames":true,"usesSharedProjection":true,"usesPlaybackEffectFrames":true,"rendersHelperEffectLayer":true,"hasOnlyGenericResultEffects":false}],"requirements":[{"requirement":"child motion loop present","count":5,"owners":{"린샹":4,"스마슈":1},"samples":[{"owner":"린샹","skill":"암각·영상승룡파","skillIdHex":"0x17","levelOrFixed":3,"helperIds":[97]},{"owner":"린샹","skill":"암각·영상승룡파","skillIdHex":"0x18","levelOrFixed":4,"helperIds":[98]},{"owner":"린샹","skill":"흑영권","skillIdHex":"0x1a","levelOrFixed":null,"helperIds":[70,77]},{"owner":"린샹","skill":"환영각","skillIdHex":"0x2d","levelOrFixed":null,"helperIds":[70,77]},{"owner":"스마슈","skill":"투신의 춤","skillIdHex":"0x22","levelOrFixed":null,"helperIds":[70,77]}],"runnerStatus":"motion-fields-carried-preview-sensitive","evidence":"Nested/direct effect frames carry motionX/motionY, motionBasis, and helper VM projection metadata.","remaining":"The page renderer applies motion during the gate, but exact child loop integration and draw-order parity remain review targets."},{"requirement":"palette transform effect; no CNS frame stream","count":1,"owners":{"스마슈":1},"samples":[{"owner":"스마슈","skill":"열시섬","skillIdHex":"0x20","levelOrFixed":null,"helperIds":[83,17]}],"runnerStatus":"classified-separately-no-cns-frame-stream","evidence":"Static pattern marks palette transform as an effect requirement without a CNS frame stream.","remaining":"Renderer needs a palette/flash branch; it should not invent CNS frames."},{"requirement":"random placement/range present","count":46,"owners":{"린샹":22,"스마슈":7,"아타호":17},"samples":[{"owner":"아타호","skill":"비기·맹호광파참","skillIdHex":"0x1b","levelOrFixed":2,"helperIds":[27,20]},{"owner":"아타호","skill":"비기·맹호광파참","skillIdHex":"0x1d","levelOrFixed":4,"helperIds":[28,126]},{"owner":"아타호","skill":"염가열소","skillIdHex":"0x21","levelOrFixed":null,"helperIds":[62]},{"owner":"아타호","skill":"호포권","skillIdHex":"0x2c","levelOrFixed":2,"helperIds":[27,67]},{"owner":"아타호","skill":"호포권","skillIdHex":"0x2e","levelOrFixed":4,"helperIds":[28,69]},{"owner":"아타호","skill":"비기·맹호유성각","skillIdHex":"0x33","levelOrFixed":1,"helperIds":[79]},{"owner":"아타호","skill":"비기·맹호유성각","skillIdHex":"0x34","levelOrFixed":2,"helperIds":[79]},{"owner":"아타호","skill":"비기·맹호유성각","skillIdHex":"0x35","levelOrFixed":3,"helperIds":[79]},{"owner":"아타호","skill":"비기·맹호유성각","skillIdHex":"0x36","levelOrFixed":4,"helperIds":[79]},{"owner":"아타호","skill":"취호염무","skillIdHex":"0x38","levelOrFixed":null,"helperIds":[63]},{"owner":"아타호","skill":"노익장 대폭발","skillIdHex":"0x39","levelOrFixed":null,"helperIds":[11,40,41,123,57,38]},{"owner":"아타호","skill":"기합일발","skillIdHex":"0x3c","levelOrFixed":null,"helperIds":[32]}],"runnerStatus":"shared-engine-vm-projected-preview","evidence":"BattleAnimation now consumes battle_helper_position_motion_review and projects display.x/y, target-cache, delta, and originAnchor.","remaining":"Exact original RNG seed is not required; visual parity still depends on per-helper spawn cadence and child draw order."},{"requirement":"runner must instantiate child objects over time","count":28,"owners":{"린샹":17,"스마슈":9,"아타호":2},"samples":[{"owner":"아타호","skill":"염가열소","skillIdHex":"0x21","levelOrFixed":null,"helperIds":[62]},{"owner":"아타호","skill":"취호염무","skillIdHex":"0x38","levelOrFixed":null,"helperIds":[63]},{"owner":"린샹","skill":"열화폭염권","skillIdHex":"0x11","levelOrFixed":1,"helperIds":[55]},{"owner":"린샹","skill":"열화폭염권","skillIdHex":"0x12","levelOrFixed":2,"helperIds":[56,55]},{"owner":"린샹","skill":"열화폭염권","skillIdHex":"0x13","levelOrFixed":3,"helperIds":[56,56,55]},{"owner":"린샹","skill":"열화폭염권","skillIdHex":"0x14","levelOrFixed":4,"helperIds":[56,56,56,56,55]},{"owner":"린샹","skill":"암각·영상승룡파","skillIdHex":"0x15","levelOrFixed":1,"helperIds":[95]},{"owner":"린샹","skill":"암각·영상승룡파","skillIdHex":"0x16","levelOrFixed":2,"helperIds":[96]},{"owner":"린샹","skill":"암각·영상승룡파","skillIdHex":"0x17","levelOrFixed":3,"helperIds":[97]},{"owner":"린샹","skill":"암각·영상승룡파","skillIdHex":"0x18","levelOrFixed":4,"helperIds":[98]},{"owner":"린샹","skill":"빙조권","skillIdHex":"0x19","levelOrFixed":null,"helperIds":[95]},{"owner":"린샹","skill":"흑영권","skillIdHex":"0x1a","levelOrFixed":null,"helperIds":[70,77]}],"runnerStatus":"effect-frame-stream-present-needs-per-helper-parity-review","evidence":"helperEffectFrames merges direct spawn, frameScript, init frames, and nested spawn tree frames.","remaining":"The renderer must keep every spawned child as an independent object over its lifetime. This is implemented for timeline preview, but complex burst skills still need visual review."}],"notes":["This report separates EXE-confirmed effect requirements from web runner visual completeness.","Runtime is not used here; all requirement rows come from static EXE-derived helper reports.","A passing binding check means the pages are wired to shared helper data, not that every visual effect is pixel-perfect.","Only pages that use playback.effectFrames and draw an effect layer are full helper-effect visual previews. Other pages may intentionally use actor-only animation plus damage/miss/heal overlays."]}