feedback5 R19E: an enemy finishes its attack clip after its block ends — the 鸭爵 swap's 流泪小子 no longer walks on the tick its strike stuns its blocker (community report of 2026-10-07 「哭狗瞬间隐匿没有后摇」, GitHub #214 by @FrogThai); golden: 216 scenarios move
ai.js enemyAttack set the post-strike stand only for an unblocked ranged enemy (`!e.blockedBy && radius > 0`), so a
melee enemy released by its own strike walked on that very tick. 流泪小子 (enemy_2034_sythef_2, the strategy's version;
「泪眼汪汪」 / 「哭狗」 in the reports) stuns its blocker with every hit, the stunned blocker lets it go and its 隐匿 is
back 0 s later: on 0255afd it walked off the tick of each strike (four non-attacking walls in a lane: 8 stuns, 19.8 s
隐匿 / 9.0 s revealed, leaked at 28.9 s). PRTS 状态机: an enemy's ATTACK state 「每帧检查异常状态…攻击结束后回退到MOVE状态」
and COMBAT 「逻辑同ATTACK」 — only a character's COMBAT 「检测到不存在阻挡对象时强行切回IDLE状态」 — so an enemy finishes its
attack when its blocker goes. Now every enemy stands for the rest of its clip after a strike (attackStand; a blocked one
never walks, so it shows only when the block ends meanwhile: its blocker stunned or knocked out by that strike, or
gone); a stun / freeze / sleep / 浮空, leaving the field and, new, a displacement (失衡, Battle.displace) end the stand.
流泪小子 now stands 0.8 s (its 1.567 s clip, strike at 0.767), 隐匿, and a blocker whose stun ended often takes it over
again: the same lane 13 stuns, 29.1 s 隐匿 / 12.8 s revealed, leaked at 42.0 s.
Checked and official, unchanged: a stunned operator blocks nothing (gamedata_const ba.stun 「无法移动、阻挡、攻击及使用技能」,
PRTS 异常效果 STUNNED 「无法攻击、释放技能、阻挡敌人类单位」 — the keeps-blocking hypothesis is wrong); 隐匿 back 0 s after a
block (PRTS 流泪小子); moveSpeed 0.8 × the level's moveMultiplier 0.5, interval 2.0 s, stun 3.5 s, MELEE (enemy_database;
PRTS 盟约记录 鸭爵 备注: 4500 HP, 3.5 s stun, 隐匿 kept); the cooldown runs on the walk, so a new blocker sees the swing at
once and the strike after the 0.767 s wind-up; a bot teammate's 鸭爵 swaps into a human's battles, the Final Assault and
the Hidden Core too (「你和队友遭遇的部分敌人」), on the replaced enemy's route.
Golden — traced in lockstep against a copy of the parent: in each of the 199 battle scenarios the first differing tick is
an enemy standing out its clip after a strike where the parent walked on; every moved match has such stands in an
earlier or the same round. roster 41 of 49 (all but -003, -005, -009, -018, -019, -025, -035, -049); bonds 21
(deputShip-low, emptyShip-low / -high, indomShip-low / -high, investShip-low, kazimierzShip-low / -high,
kjeragShip-high, lateranoShip-high, miraShip-high, raidShip-low, sargonShip-high, siracusaShip-low, soloShip-low /
-high, suntShip-low / -high, swiftShip-high, visiShip-low, yanShip-low); fields 13 (all but boss-boss_1-solo,
boss-boss_2-pair / -solo, boss-boss_6-solo, boss-boss_7-pair / -solo, hidden-boss_8-solo, hidden-boss_10-solo,
unite-1); matches 17 (all but solo-HARD-9-boosted); standins 10 of 10; diy 114 of 138 (all but -011, -012, -018, -020,
-025, -027, -029, -031, -033, -047, -053, -077, -080 … -082, -086 … -088, -091 … -093, -098, -108, -123). The
displacement rule alone moves one roster scenario.
Tests: test/sim/feedback5-attack-clip-rest.test.js (5; the four behaviour tests fail on the parent, the data pin passes
on both); test/sim (745), test/content + feedback1-ducklord (2030), test/match (593) pass. Docs: CHANGELOG 0.2.0 规则
(按官方) and 核实后不是问题, docs/history/0.2.0.md §25.22.6, docs/SIM.md, design/engine.md, DATA.md.
This commit is contained in:
1 parent
0255afd12b
commit
ef25c03525
14 files changed
+3934
-3726
No files matched your search
+1
-1
@@ -370,7 +370,7 @@ blackboards (transitively). Level = `randomEnemyAttributeDict[key].level` (0 for
|
||||
| `modelScale` | `0.5926` (`enemy_1005_yokai_3` 威龙) | official drawn size of the enemy's Spine model relative to the standard (user playtest #6): the battle prefab's transform scale down to its Spine renderer (Graphic × FaceSwitcher × Spine; SkeletonDataAsset.scale is 0.01 for every enemy skeleton) ÷ 0.27, the standard of 1454 of the client's 2147 enemy prefabs (2080 have exactly one Spine renderer) and of the operators' battle skins. The renderer multiplies `UNIT.modelScale` by it (render/units.js `enemyModelScale`). 125 keys (122 prefabs) carry one, from 0.5926 (威龙 0.16; 妖怪 0.7407, 寒霜 0.6667) to 2.2222 (青铜镜 / 青瓷茶器 0.6); absent = 1. Not in the game tables: `tools/build-data.mjs MODEL_SCALES` by `prefabKey`, read from the local client by `tools/local-extract/enemy_scales.py` |
|
||||
| `modelScaleY` | `1.263` (`enemy_1112_emppnt` 帝国炮火先兆者) | **vertically stretched models only** (2 keys, the 先兆者 pair): the official prefab's `Graphic` scale sy ÷ sx — 1.263 because the pair's scale is (0.19, 0.24, 0.24), i.e. the game draws them 26 % taller than `modelScale` (which only carries the horizontal product) implies. The renderer multiplies the skeleton's **Y** scale (and the bar height) by it (render/units.js `enemyModelScaleY`). Not in the game tables: `tools/build-data.mjs MODEL_STRETCH_Y`, read from the local client by `tools/local-extract/enemy_model_offsets.py` (a sweep of all 242 readable enemy prefabs found no other non-uniform one), docs/research/12 §3.1 (PR #211 by @xcdoge; the owner's decision of 2026-10-06) |
|
||||
| `mirrorX` | `true` (`enemy_1196_msfyin` 木制瑞印) | **mirrored models only** (1 key): the official prefab's `Graphic` X scale is negative (−0.4), so the game draws the authored model flipped; the size pipeline takes `abs(sx)`, and the renderer flips this model on top of the usual direction flip (render/units.js `mirrorX`). Same extraction as `modelScaleY` (`tools/build-data.mjs MIRRORED_PREFABS`) |
|
||||
| `attackAnim` | `{"clip":"Attack","dur":1,"hit":0.533}` (`enemy_1019_jshoot` 隐形弩手) | the enemy's attack clip — the one the client plays for its attacks (data/assets.json `anims.attack.loop` of its model, not an Idle stand-in) —, its length (s) and first strike frame (`hits`, the OnAttack event; absent when the clip has none). An unblocked ranged enemy stands for this clip at each attack (sim/ai.js `attackStand`, GitHub #58), and every enemy attack strikes at `hit` after its swing starts — a stun before it cuts the swing (sim/ai.js `attackWindup`, 0.2.0). 213 keys; absent = no attack clip known (御4, 寒霜, the 岁 relics …: the sim keeps `ATTACK_PAUSE`). Not in the game tables: `tools/build-data.mjs enemyAttackAnim` reads the committed asset manifest (tools/fetch-assets.mjs, from the Spine skeletons) |
|
||||
| `attackAnim` | `{"clip":"Attack","dur":1,"hit":0.533}` (`enemy_1019_jshoot` 隐形弩手) | the enemy's attack clip — the one the client plays for its attacks (data/assets.json `anims.attack.loop` of its model, not an Idle stand-in) —, its length (s) and first strike frame (`hits`, the OnAttack event; absent when the clip has none). An unblocked ranged enemy stands for this clip at each attack (sim/ai.js `attackStand`, GitHub #58) — any enemy for the rest of it after a strike once its block ends meanwhile (0.2.0) —, and every enemy attack strikes at `hit` after its swing starts — a stun before it cuts the swing (sim/ai.js `attackWindup`, 0.2.0). 213 keys; absent = no attack clip known (御4, 寒霜, the 岁 relics …: the sim keeps `ATTACK_PAUSE`). Not in the game tables: `tools/build-data.mjs enemyAttackAnim` reads the committed asset manifest (tools/fetch-assets.mjs, from the Spine skeletons) |
|
||||
| `attackMoves` | `true` | **「不停止移动」 attackers only**: the handbook ability text says it attacks on the move (“十字路口”量产型's 四向攻击) — it never stops to attack (sim/ai.js `attackStand`). No enemy of the mode has it (build-data `attacksOnTheMove`) |
|
||||
|
||||
## 10. `factions.json` — special enemies (特训敌人)
|
||||
|
||||
Reference in new issue
Block a user