feedback5 WAA: the 孤岛风云 prisoners leave the gate confined and change model as their official prefabs do — grey while 【禁锢】, the blinking orange warning before the last confined attack, red once freed; the 4th attack already hits freed (community report of 2026-10-06 「囚徒类敌人出门就是已解放的模型」)

- Cause, client: the prisoner skeletons carry three clip sets whose collar light is grey, blinking orange
  and red. The official battle prefabs (local client battle/enm_pfb_6.ab: the Graphic component's anim key
  -> clip table, the modes' replace pairs, the clip the Spine starts on) draw mode Default (【禁锢】) on the
  grey set, mode R (the warning) on the orange set and mode L (【解放】) on the red one. The name-based role
  resolver gave 普通囚犯 / 老练囚犯 their unnumbered set — the red one — so they came out of the gate freed;
  no FORMS entry existed, so no prisoner ever changed (强壮囚犯 / 拳师囚犯 / 重犯 / 传奇重犯 stayed grey).
- Cause, sim: buff_template_data enemy_confinement[atk_cnt] spends a charge ON_BEFORE_ATTACK (not while
  麻痹) and switches to mode R when one is left; enemy_liberty_listener[warning] switches to mode L before
  the next attack (PRTS "进行第4次攻击前,切换至解放状态"). archetypes.js prisoner() counted on the 'attack'
  hook, after the damage, so the 4th attack still hit confined, and it sent no form.
- Now: prisoner() counts in `before` (an attack 麻痹 interrupts never gets there, PRTS 拳师囚犯), setForm
  'warning' (fx 'phase', drawn silently: kinds.js SILENT_PHASES) before attack times-1 and 'liberty' (fx
  'liberate') before attack times; 重犯's free-all and 杰斯顿's KO switch the freed ones too.
  render/units.js FORMS maps 'warning' / 'liberty' for the six skeletons (普通 / 老练囚犯 *2 / unnumbered,
  强壮囚犯 *2 / *3, 拳师囚犯 / 重犯 / 传奇重犯 *_orange / *_red). tools/assets/spine.mjs PREFAB_SPINE_ROLES gives
  普通囚犯 / 老练囚犯 their grey *3 set; data/assets.json regenerated (fetch-assets --offline --add-only, JSON
  compare: only those two anims and the hash), data/enemies.json too (build-data --offline: only their
  attackAnim.clip Attack -> Attack3, same length and strike frame). The 3D board draws the same Pixi views.
- Docs: ASSETS.md (PREFAB_SPINE_ROLES, the prisoner forms), SIM.md (the form fx), design/client.md (FORMS).
- Tests: test/content/feedback5-prisoners.test.js (the six: warning before attack 3, attack 4 hits with
  ATK +50 %, the forms reach the client and UnitInfo; free-all; 麻痹), test/render/feedback5-prisoners.test.js
  (manifest = the prefab's grey set, FORMS sets, view clips, PREFAB_SPINE_ROLES = the committed manifest) —
  both fail on the parent but the 麻痹 pin; test/render/feedback5-prisoners.browser.test.js (RENDER_E2E=1:
  three prisoners on the 2D and the 3D board, each model's set follows its sim form).
- Golden: 28 scenarios. Only the warning's new 'phase' fx (the prisoner fell before its 4th attack):
  roster-001, roster-003, roster-007, roster-024, roster-033, bond-miraShip-low. The 4th attack now hits
  freed, one attack earlier than before, so the fight after it moves: roster-004, roster-022, roster-026,
  bond-kazimierzShip-low, bond-raidShip-low, bond-soloShip-low, bond-victoriaShip-low, bond-visiShip-low,
  standin-01, diy-024, diy-061, diy-065, diy-066, diy-094, diy-097, diy-104, diy-105, diy-127; only the
  per-second snapshots besides the fx: roster-021, diy-017; and the bot matches whose battles field
  prisoners: solo-ABYSS-2, solo-HARD-9-boosted.
This commit is contained in:
sganggs committed 2026-10-06 21:57:51 +08:00
1 parent e1ffcd1b07
commit 6372f2892b
18 files changed
+788 -352

No files matched your search

+1 -1
View File
@@ -1 +1 @@
{"version":1,"hash":"026eaf9ff08e","generator":"tools/fetch-assets.mjs","stats":{"files":7972,"bytes":485093753,"chars":209,"charsWithBack":206,"enemies":252,"enemiesWithSpine":251,"tokens":58,"tokensWithSpine":13,"spineModels":671,"bonds":23,"items":59,"bands":40,"skills":522,"modules":131,"ui":602,"sfxUnits":483,"voiceChars":191},"chars":{"char_003_kalts":{"avatar":"/assets/char/avatar/char_003_kalts.png","avatarE2":"/assets/char/avatar/char_003_kalts_2.png","portrait":"/assets/char/portrait/char_003_kalts_1.png","portraitE2":"/assets/char/portrait/char_003_kalts_2.png","spine":{"front":{"skel":"/assets/spine/op/char_003_kalts/front/char_003_kalts.skel","atlas":"/assets/spine/op/char_003_kalts/front/char_003_kalts.atlas","textures":["/assets/spine/op/char_003_kalts/front/char_003_kalts.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"die":"Die","move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"1":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":1,"idle":null},"2":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":2,"idle":null}}},"animations":{"Attack":1,"Default":0,"Die":1,"Idle":9,"Start":1},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433]},"bounds":{"x":-227.579,"y":-138.244,"width":532.04,"height":551.479}},"back":{"skel":"/assets/spine/op/char_003_kalts/back/char_003_kalts.skel","atlas":"/assets/spine/op/char_003_kalts/back/char_003_kalts.atlas","textures":["/assets/spine/op/char_003_kalts/back/char_003_kalts.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"die":null,"move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"1":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":1,"idle":null},"2":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":2,"idle":null}}},"animations":{"Attack":1,"Default":0,"Idle":9,"Start":1},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433]},"bounds":{"x":410.785,"y":-2.26,"width":531.785,"height":416.492}}}},"char_010_chen":{"avatar":"/assets/char/avatar/char_010_chen.png","avatarE2":"/assets/char/avatar/char_010_chen_2.png","portrait":"/assets/char/portrait/char_010_chen_1.png","portraitE2":"/assets/char/portrait/char_010_chen_2.png","spine":{"front":{"skel":"/assets/spine/op/char_010_chen/front/char_010_chen.skel","atlas":"/assets/spine/op/char_010_chen/front/char_010_chen.atlas","textures":["/assets/spine/op/char_010_chen/front/char_010_chen.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"die":"Die","move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"1":{"begin":null,"loop":"Skill_2","end":null,"index":1,"idle":null},"2":{"begin":null,"loop":"Skill_3","end":null,"index":2,"idle":null}}},"animations":{"Attack":1.5,"Attack_End":0.6,"Attack_Pre":0.6,"Default":0,"Die":1,"Idle":2,"Skill":1,"Skill_2":1.167,"Skill_3":2.933,"Skill_End":0.6,"Skill_End_2":0.6,"Skill_End_3":0.3,"Start":0.833},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433,1],"Skill":[0.467],"Skill_2":[0.467],"Skill_3":[0.6,0.8,1,1.2,1.4,1.6,1.8,2,2.2,2.833,2.933]},"bounds":{"x":-322.335,"y":-109.274,"width":663.549,"height":524.806}},"back":{"skel":"/assets/spine/op/char_010_chen/back/char_010_chen.skel","atlas":"/assets/spine/op/char_010_chen/back/char_010_chen.atlas","textures":["/assets/spine/op/char_010_chen/back/char_010_chen.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"die":null,"move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"1":{"begin":null,"loop":"Skill","end":"Skill_End","index":1,"idle":null},"2":{"begin":null,"loop":"Skill","end":"Skill_End","index":2,"idle":null}}},"animations":{"Attack":1.5,"Attack_End":0.6,"Attack_Pre":0.6,"Default":0,"Idle":2,"Skill":1,"Skill_End":0.6,"Start":0.833},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433,1],"Skill":[0.467]},"bounds":{"x":-173.082,"y":-13.829,"width":315.887,"height":404.623}}}},"char_017_huang":{"avatar":"/assets/char/avatar/char_017_huang.png","avatarE2":"/assets/char/avatar/char_017_huang_2.png","portrait":"/assets/char/portrait/char_017_huang_1.png","portraitE2":"/assets/char/portrait/char_017_huang_2.png","spine":{"front":{"skel":"/assets/spine/op/char_017_huang/front/char_017_huang.skelLine truncated
{"version":1,"hash":"65d6d7dc722e","generator":"tools/fetch-assets.mjs","stats":{"files":7972,"bytes":485093753,"chars":209,"charsWithBack":206,"enemies":252,"enemiesWithSpine":251,"tokens":58,"tokensWithSpine":13,"spineModels":671,"bonds":23,"items":59,"bands":40,"skills":522,"modules":131,"ui":602,"sfxUnits":483,"voiceChars":191},"chars":{"char_003_kalts":{"avatar":"/assets/char/avatar/char_003_kalts.png","avatarE2":"/assets/char/avatar/char_003_kalts_2.png","portrait":"/assets/char/portrait/char_003_kalts_1.png","portraitE2":"/assets/char/portrait/char_003_kalts_2.png","spine":{"front":{"skel":"/assets/spine/op/char_003_kalts/front/char_003_kalts.skel","atlas":"/assets/spine/op/char_003_kalts/front/char_003_kalts.atlas","textures":["/assets/spine/op/char_003_kalts/front/char_003_kalts.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"die":"Die","move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"1":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":1,"idle":null},"2":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":2,"idle":null}}},"animations":{"Attack":1,"Default":0,"Die":1,"Idle":9,"Start":1},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433]},"bounds":{"x":-227.579,"y":-138.244,"width":532.04,"height":551.479}},"back":{"skel":"/assets/spine/op/char_003_kalts/back/char_003_kalts.skel","atlas":"/assets/spine/op/char_003_kalts/back/char_003_kalts.atlas","textures":["/assets/spine/op/char_003_kalts/back/char_003_kalts.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"die":null,"move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"1":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":1,"idle":null},"2":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":2,"idle":null}}},"animations":{"Attack":1,"Default":0,"Idle":9,"Start":1},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433]},"bounds":{"x":410.785,"y":-2.26,"width":531.785,"height":416.492}}}},"char_010_chen":{"avatar":"/assets/char/avatar/char_010_chen.png","avatarE2":"/assets/char/avatar/char_010_chen_2.png","portrait":"/assets/char/portrait/char_010_chen_1.png","portraitE2":"/assets/char/portrait/char_010_chen_2.png","spine":{"front":{"skel":"/assets/spine/op/char_010_chen/front/char_010_chen.skel","atlas":"/assets/spine/op/char_010_chen/front/char_010_chen.atlas","textures":["/assets/spine/op/char_010_chen/front/char_010_chen.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"die":"Die","move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"1":{"begin":null,"loop":"Skill_2","end":null,"index":1,"idle":null},"2":{"begin":null,"loop":"Skill_3","end":null,"index":2,"idle":null}}},"animations":{"Attack":1.5,"Attack_End":0.6,"Attack_Pre":0.6,"Default":0,"Die":1,"Idle":2,"Skill":1,"Skill_2":1.167,"Skill_3":2.933,"Skill_End":0.6,"Skill_End_2":0.6,"Skill_End_3":0.3,"Start":0.833},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433,1],"Skill":[0.467],"Skill_2":[0.467],"Skill_3":[0.6,0.8,1,1.2,1.4,1.6,1.8,2,2.2,2.833,2.933]},"bounds":{"x":-322.335,"y":-109.274,"width":663.549,"height":524.806}},"back":{"skel":"/assets/spine/op/char_010_chen/back/char_010_chen.skel","atlas":"/assets/spine/op/char_010_chen/back/char_010_chen.atlas","textures":["/assets/spine/op/char_010_chen/back/char_010_chen.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"die":null,"move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"1":{"begin":null,"loop":"Skill","end":"Skill_End","index":1,"idle":null},"2":{"begin":null,"loop":"Skill","end":"Skill_End","index":2,"idle":null}}},"animations":{"Attack":1.5,"Attack_End":0.6,"Attack_Pre":0.6,"Default":0,"Idle":2,"Skill":1,"Skill_End":0.6,"Start":0.833},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433,1],"Skill":[0.467]},"bounds":{"x":-173.082,"y":-13.829,"width":315.887,"height":404.623}}}},"char_017_huang":{"avatar":"/assets/char/avatar/char_017_huang.png","avatarE2":"/assets/char/avatar/char_017_huang_2.png","portrait":"/assets/char/portrait/char_017_huang_1.png","portraitE2":"/assets/char/portrait/char_017_huang_2.png","spine":{"front":{"skel":"/assets/spine/op/char_017_huang/front/char_017_huang.skelLine truncated