feedback5: merge feedback4 (7ee815e) — W4D ported: a sleeping enemy cannot be blocked and takes no block slot (_checkBlock in server/sim/battle/blocking.js, the applyStatus release in battle/status.js, the plain-buff release re-applied to ai.js updateEnemy's cannot-act branch after WE1's swing cut, 瑕光's comment in kits/ops/chess_char_3_12-blemsh.js, buffs.js; 酒神's 迷狂牢笼 skips a sleeper too); golden: roster-003 / 005 / 013 / 032 / 038 / 039 / 042, bond-maniShip-high, solo-FUNNY-1, coop4-FUNNY-6, coop4-ABYSS-7, coop2-NORMAL-8-serverrun, coop2-NORMAL-70-diy, diy-131 / 132 moved

New on feedback4 since the last merge: W4D (bbe59b9, merged as 7ee815e) and the 0.1.4 version commit (30e7ace).
feedback5 keeps its own package.json / package-lock.json / APP_VERSION / README / DEPLOY version lines (0.2.0 sets
its own version later) and takes feedback4's CHANGELOG 0.1.4 entry, with W4D's line in it.

- Port (PRTS 异常效果 SLEEPING 沉睡 = 无法行动+无敌+不可阻挡; GitHub #140; the owner's decision of 2026-10-06):
  `_checkBlock` refuses `flags.sleep` (battle/blocking.js) and `applyStatus` releases an enemy that falls asleep
  (battle/status.js). Battle.js stays feedback5's façade, and tier3.js stays deleted (the 瑕光 comment is in her kits/ops
  file). ai.js: WE1 (89f730d) cuts a swing before enemyAttack on a stun / freeze / sleep. The cannot-act branch is still
  there, and a plain-buff `flags.sleep` still makes the enemy `stun` (units.js), so the plain-buff release stays in that
  branch, after the cut, with its comment rewritten for the new order.
- New on feedback5: 酒神's 迷狂牢笼 (kits/ops/op-phatm2.js cageBlock, O22) duplicated the old three-flag 不可阻挡 check.
  It now skips a sleeper too. No golden scenario spawns a 牢笼 over a sleeper: the corpus is identical with that line
  reverted. 予愿安洁莉娜's S3 helper is unchanged, since canTargetEnemy already drops sleepers.
- Readers that follow without code: blockedTargets (blocked-first targeting, the DEFAULT trigger, hitAllBlocked), the 要塞
  branch of acquireTargets (u.blocking), “庞贝”'s clock (blockedBy), the snapshot's UF.BLOCKED and the client's block
  marker (render/units.js). 死芒 S2 折朽 (自选) lets go a linked enemy that her 悲叹的仆役 held.
- Docs: DESIGN §24.9, its §24 intro entry, the §5.5 Blocking sentence (on feedback5's 阻挡半径倍率 text) and §22.8's
  "(since §24.9)", all as on feedback4; SIM.md as on feedback4 (the plain-buff sentence merged with feedback5's
  noNewBlock / undying text).
- Golden: a probe (counting successful sleeps on a blocked enemy, plain-buff sleeps and 牢笼 spawns over sleepers) ran
  over all 283 scenarios. Every scenario that moved sleeps blocked enemies; the counts are in brackets:
  roster-003 (小满 S2 [5]: same fight, blocked 27 → 29, snapshot hashes); roster-005 (elite 小满 S2 [3]: the 140 s
  timeout with 83 kills and 1 leak, where it used to clear at 135.43 s with 84); roster-013 (缇缇 S3 [11]: same kills,
  blocked 22 → 33); roster-032 (缇缇 S1 [10]: 71 kills instead of 68, 8 leaks instead of 11, 4 knock-outs instead of 8,
  萨尔贡 layers 41 → 35); roster-038 (elite 缇缇 S2 [1]: ends at 197.40 s instead of 197.27 s); roster-039 (瑕光 S2
  normal + elite [31 + 12]: same kills and counted leaks, the 窃贼 gets away, blocked 53 → 87); roster-042 (缇缇 S2 [3]:
  ends at 168.77 s instead of 166.93 s); bond-maniShip-high (小满 [1]: blocked 29 → 30, snapshot hashes); solo-FUNNY-1
  (ai_0's 缇缇 [3]: only ai_0's damage dealt); coop4-FUNNY-6 (ai_0's 缇缇 [15 + 56]: from round 9 ai_0's 精准 / 萨尔贡
  layers and boss damage move, ai_1 loses no LP from round 11, team LP 124 → 130); coop4-ABYSS-7 (ai_2's 小满 [18]: ai_2
  one kill fewer, ai_0 one more LP lost in round 9); coop2-NORMAL-8-serverrun (ai_1's 缇缇 [83]: only ai_1's damage dealt;
  WE1 had already turned this match into a loss); coop2-NORMAL-70-diy (the 自选 seat h_0's 缇缇 [171], ai_0's 缇缇 [74]
  and 小满 [19 + 21]: h_0's layers move from round 4, then its AI 托管 buys differently (boards from round 7); ai_0 246
  kills instead of 233, same end); diy-131 (死芒 S2 at tiers 5 and 6 [1 + 1]: snapshot hashes only); diy-132 (elite
  死芒 S2 [2]: ends at 199.50 s instead of 198.13 s, same kills). One scenario sleeps a blocked enemy and did not move:
  coop2-HARD-4 [1]. ai_1's 小满 lets go the enemy it holds; another enemy takes the slot; the sleeper wakes with no room
  and is blocked further on by 2_16_a. The match digest has no snapshot hashes, and its kills, leaks, damage and funds
  are identical. fields and standins did not move. Most outcomes differ from feedback4's list because feedback5's
  baselines differ (WE1's damage frame, etc.).
- Tests: test/sim/feedback4-sleep-unblock.test.js (from feedback4) passes 5/5 on the split layout. Every case fails with
  the three sim hunks reverted, and case 3 (plain buff) fails with only the ai.js release reverted. Targeted sim tests
  pass 184/184 (blocking, block targets, enemy swing, feedback2-enemy-attack-stand, combat / statuses, robustness,
  stun SP, professions, healers, fidelity …). Content tests plus kits_layout and docs-consistency pass 658/658 (kits
  t1t2 / t3 / t5 and alt t2 / t3 / t5 for 小满 / 瑕光 / 缇缇, 酒神, 死芒, garrisons, bosses, items). Stealth / liftoff /
  enemies pass 36/36. npm run golden: all 283 match. GOLDEN_FULL=1 test/golden.test.js passes 9/9 (no stored engine
  error). lint 0 errors, check:imports and typecheck clean.
This commit is contained in:
sganggs committed 2026-10-06 17:49:10 +08:00
commit ac6454d171
14 files changed
+558 -261

No files matched your search

+64 -3
View File
@@ -292,7 +292,7 @@ Engine helpers (content must use these, never touch internals): `battle.dealDama
- **Initial deployment** at t=0, free: operators by column — the left column first, top to bottom within a column (right-side boss player: from its own left, the highest field column) — then the summons (PRTS 卫戍协议/帮助 "按从上到下>从左到右的顺序部署。优先部署干员,随后为召唤物", read as a scan: down each column, the columns left to right — the order PRTS gives the 阿戈尔 devour, "更靠左和靠上"; row-major until 0.1.3, §23.23; `aggroSeq` ranks every start-of-battle summon after all operators) — a skill's placed summon (赫默 医疗探机, 巫恋 诅咒娃娃) included, once and free ("所有手动部署的召唤物,无视所属干员的持有状态…作战开始时立即部署一次"; afterwards it re-appears on its tile each time the owner's skill gives one, §20.1); on a shared field (联防, boss) the players' i-th operators deploy together [ASSUMED]. Deploy effects fire (`deploy` with `initial: true`). Then operators carried into 联防 knocked out (`carryState.down`) are forced out (`FORCED_EXIT`, HP 0, §19.3). Then `battleStart`, after which the forced-out operators' timers are re-read (redeploy-time effects that start with the battle, e.g. 机变 征召, cover them too).
- **DP**: per player, start 10, +1/s, cap 99; used only for auto-redeploy (dead op: after `respawnTime`, if the tile it lies on is free and DP ≥ cost ⇒ redeploy there with full HP, SP = initSp). A knocked-out operator (and, since 0.1.2, one forced out by its own effects, §22.15) stays **down** on the tile it fell on — its own home when it fell on another board piece's home (that piece on the field or not) and its home is free — until it redeploys there, and no ally deploys or moves onto that tile meanwhile (PRTS 卫戍协议/帮助 §作战阶段 单位部署; `Battle.downOn` / `restTile` / `_layBody`, §21.24; b.snap `down`, §18.3: counting / waiting for DP / its tile taken, a safeguard) — also one that entered 联防 knocked out (`FORCED_EXIT`, its full redeploy timer — confirmed by the user — with the battle-start redeploy effects, §19.3); summons, devices and enemies leave at once.
- **Blocking** (contact radius, PRTS 游戏数据基础 §阻挡半径 / 作战机制 "中点判定…案例:阻挡"; `constants.js BLOCK_RADIUS`, `Battle._checkBlock`, §19.2): an operator with free capacity blocks an unblocked, blockable enemy whose position lies within its block radius of its centre — ground 0.7071 (squared 0.49999037), 0.8944 × the blocker's 阻挡半径倍率 for blockFly units vs flyers (起飞; mod `blockRadiusScale` = 倍率 − 1 — PRTS 游戏数据基础 "飞行阻挡半径 = 0.8944 × 阻挡半径倍率", 凯尔希·思衡托 +0.23), devices 0.4472 (阻隔工事 / 障碍物); air units (FLY, 近地悬浮, 浮空) only by blockFly units. A ground enemy is never blocked by a unit standing on a tile ground units cannot pass (围墙 / 围栏: PRTS 地形机制 "部署在其中的单位,若当前阻挡类型为'地面阻挡'则无法阻挡敌人" — an enemy pushed or pulled against the fence walks on; air blocking there stays [ASSUMED], §21.23) nor by an airborne (起飞) unit, which blocks flyers only (§21.22). The nearest such operator wins (ties: scan order [ASSUMED]). It is re-checked every tick, moving or not, so another operator in contact with room takes the enemy over when its blocker dies, is withdrawn or is stunned, and an operator whose capacity frees up grabs an overlapping enemy; one that finds no room walks on. A head-on enemy stops at contact (≈ 0.71 tile), outside the blocker's tile. Enemy uses `blockCnt` capacity (default 1). Blocked enemies stop moving and attack their blocker if melee (or anyone in range if ranged, blocker first). **Every blocker** — melee units (重装要塞 / 领主 / 哨戒铁卫 included), summons and a ranged operator on a melee tile alike — whose attack hits enemies may always target the enemies it blocks, in range or not, whatever its facing, and targets them first ("可以选择且优先选择阻挡单位", PRTS 选择器; the user's rule after playtest #6, "阻挡了就一定要能打到": officially the collision pushes a blocked enemy to its blocker's front; `Battle.blockedTargets`, `targeting.js sortEnemyTargets`; §20.3 — it replaces the playtest #5 QA's melee-only restriction of §19.2). A healer (dmgType `heal`, or a skill attack turned into a heal) selects injured allies only and keeps healing while it blocks (PRTS 卫戍协议/帮助 "对于医疗干员(咒愈师分支除外),攻击目标为需要治疗的单位"; §21.17); 咒愈师 follow the blocker rule. The huge leaders are 自缚 + unblockable (§7).
- **Blocking** (contact radius, PRTS 游戏数据基础 §阻挡半径 / 作战机制 "中点判定…案例:阻挡"; `constants.js BLOCK_RADIUS`, `Battle._checkBlock`, §19.2): an operator with free capacity blocks an unblocked, blockable enemy whose position lies within its block radius of its centre — ground 0.7071 (squared 0.49999037), 0.8944 × the blocker's 阻挡半径倍率 for blockFly units vs flyers (起飞; mod `blockRadiusScale` = 倍率 − 1 — PRTS 游戏数据基础 "飞行阻挡半径 = 0.8944 × 阻挡半径倍率", 凯尔希·思衡托 +0.23), devices 0.4472 (阻隔工事 / 障碍物); air units (FLY, 近地悬浮, 浮空) only by blockFly units. A ground enemy is never blocked by a unit standing on a tile ground units cannot pass (围墙 / 围栏: PRTS 地形机制 "部署在其中的单位,若当前阻挡类型为'地面阻挡'则无法阻挡敌人" — an enemy pushed or pulled against the fence walks on; air blocking there stays [ASSUMED], §21.23) nor by an airborne (起飞) unit, which blocks flyers only (§21.22). An enemy holding 不可阻挡 (PRTS 异常效果 BLOCK_FREE 「无法阻挡/被阻挡,自动解除阻挡」) — `unblockable` (恐惧, 诱导, enemy abilities), 浮空, and 沉睡 (SLEEPING = 无法行动+无敌+不可阻挡) — is never blocked and is released at once: a sleeping enemy frees its blocker's slot, stays where it is and, once awake, is blocked again only by a blocker with room (§24.9). The nearest such operator wins (ties: scan order [ASSUMED]). It is re-checked every tick, moving or not, so another operator in contact with room takes the enemy over when its blocker dies, is withdrawn or is stunned, and an operator whose capacity frees up grabs an overlapping enemy; one that finds no room walks on. A head-on enemy stops at contact (≈ 0.71 tile), outside the blocker's tile. Enemy uses `blockCnt` capacity (default 1). Blocked enemies stop moving and attack their blocker if melee (or anyone in range if ranged, blocker first). **Every blocker** — melee units (重装要塞 / 领主 / 哨戒铁卫 included), summons and a ranged operator on a melee tile alike — whose attack hits enemies may always target the enemies it blocks, in range or not, whatever its facing, and targets them first ("可以选择且优先选择阻挡单位", PRTS 选择器; the user's rule after playtest #6, "阻挡了就一定要能打到": officially the collision pushes a blocked enemy to its blocker's front; `Battle.blockedTargets`, `targeting.js sortEnemyTargets`; §20.3 — it replaces the playtest #5 QA's melee-only restriction of §19.2). A healer (dmgType `heal`, or a skill attack turned into a heal) selects injured allies only and keeps healing while it blocks (PRTS 卫戍协议/帮助 "对于医疗干员(咒愈师分支除外),攻击目标为需要治疗的单位"; §21.17); 咒愈师 follow the blocker rule. The huge leaders are 自缚 + unblockable (§7).
- **Operator attacks**: every `interval` s if a valid target exists; targets = up to `maxTargets` (default 1) from `unitsInGrid(rangeGrid)` (a `rangeAoe` profile — 阵法术师, 轰击术师 — takes every selectable enemy in range, §21.18; 「同时攻击阻挡的所有敌人」 — 强攻手 / 重剑手 / 推击手 and the skills worded so, `hitAllBlocked` — up to the block count, never fewer than 1, since 0.2.0: PRTS 分支特性信息 "普通攻击最大目标数等于阻挡数(不会低于1)"), priority: (1) the enemies it blocks (every blocker, in range or not, §20.3), (2) profession/trait priorities (e.g. fly-first snipers, `trait` text parsed by build-data into `targetPriority`), (3) enemy with the **least remaining path distance** to its goal, ties → earliest spawned. Melee (no ranged trait) and ground-only attacks cannot hit air units (`Unit.isFlying`: FLY, or a 近地悬浮 / 浮空 enemy — PRTS "算作空中单位", §19.1). Stealthed enemies can't be targeted unless blocked or revealed — or within 3 s of a block's end (§22.8). Ranged ops fire projectiles (speed ~12 tiles/s, instant for melee/arts-beam classes as data indicates); damage applies on impact; a 锁定攻击范围 AoE (`rangeAoe`) strikes every selectable enemy on its range at once with instant hits (§21.18).
- **Healers** (`dmgType heal`): target the ally in range with the lowest HP% below 100%, never a 禁疗 / 孤立 unit (tokens.json `abnormal`, `noHeal`; §20.3; 史尔特尔 during 余烬, §22.7), and never the enemies they block — also while blocking (§21.17); do nothing otherwise (SP still regenerates).
- **Enemy AI**: follow the route (checkpoints; WALK paths recomputed on the grid when devices change); when blocked stop & fight (`dmgType 'none'` enemies never attack unless content arms them through `e.profile` — 转译基底's armed forms, §21.4); ranged enemies (`rangeRadius > 0`) attack ops whose 0.25 collider touches their radius (centre distance ≤ `rangeRadius` + 0.25, §3, §20.4): the enemy's own target rule filters the candidates first (`profile.canTarget`: 只攻击地面单位 …), then priority blocker → special priority → highest taunt → **latest deployed** (`aggroSeq`) — PRTS 索敌 "阻挡→特殊优先级→仇恨值→最早出现"; a stealthed ally is attacked only by the enemy it blocks (§19.1), and an enemy's area effects — splash, blasts, area skills, zones, jumps — and buff auras skip it unless it blocks that enemy, while 迷彩 does not protect from splash and the other area effects (`targeting.js areaSelectable` / `auraSelectable`, §22.12); an airborne (起飞) ally is never a ground enemy's selection — picks, area damage, zones and statuses skip it, while 无视无法选择 abilities, direct picks, debuff ticks and flying units still reach it (§21.22); unblocked, they stand for each attack's clip (enemies.json `attackAnim`: its wind-up before the strike and the rest of the clip after it, shortened when the attacks come quicker than the clip; `ATTACK_PAUSE = 0.35 s` after the strike when no clip is known; a 「不停止移动」 attacker never stops; §22.14). Every enemy attack strikes at its clip's damage frame after its swing starts — the first one of a contact too —, and a stun / freeze / sleep / 浮空, hiding, 缴械, 恐惧 or 战栗 (blocked) before that frame cuts the swing: no strike, the next swing starts from its wind-up (0.2.0, `ai.js attackWindup`; PRTS 状态机 / 异常效果 STUNNED; no clip known: no wind-up). FLY enemies ignore ground obstacles (only blockFly units block them) and follow their checkpoint route. A feared enemy runs between random 恐惧可达地块 away from the source (PRTS 诱发移动; `fear.js`); 恐惧 outranks 诱导; the 恐惧 / 诱导 walks re-plan from where the enemy stands after a push or an obstacle change, and the route re-plans when they end (§20.4).
@@ -1616,7 +1616,7 @@ Withdrawn in 0.1.3 (§23.35): only elite 歌蕾蒂娅 carrying HOK-Y may use a
- **Seen**: §21.4 left "隐匿 returns at once after a block (PRTS: 3 s)" [ASSUMED]; v0.1.1 hid an enemy again one tick after its block ended (a 潜伏者 whose blocker falls: untargetable 0.03 s later). Players reported (via the owner) that the 深池逐火 "stealth monster revives forever and can't be killed": a warrior knocked out while blocked releases its block through the 重生's 无法阻挡, its blocker takes the next warrior at once, and when the 重生 ends the ember is not blocked again — 隐匿, out of reach of ranged operators and operator splash — walks on and stands up with full HP 10 s later.
- **Official** (checked on PRTS 2026-10-03): 作战机制 §隐匿 "对于绝大部分可隐匿的敌人而言,在被我方单位阻挡后会解除隐匿,不被阻挡的3秒后重新进入隐匿。这是敌方单位的隐匿所拥有的特殊机制,我方干员并不会因为阻挡而解除隐匿" and "少部分的隐匿表现上与我方干员相同…可能不具有这样的特殊机制"; §隐匿与Buff的关系 "在被阻挡时开关会被关掉从而失去隐匿,阻挡状态解除后3s开关重新被开启而恢复隐匿"; 异常效果 隐匿 "与'阻挡时解除'没有直接关系,该机制通常由其他效果实现". The enemy pages' 天赋 "隐匿(解除阻挡N秒后恢复)" (PRTS text search): 0 s on 21 enemies — here 业余竞演者, 节日爵士乐手, 假想敌:骨刺, 流泪小子 (both), 访问团强攻冠军, and the veil of 清明 / 堂皇 ("获得隐匿(解除阻挡0秒后恢复)"); 1 s on 家族灭迹人 / 家族暗影灭迹人; no page names another time. Every other stealthy enemy here has a plain 隐匿: 潜伏者, 隐形弩手 (+组长), 隐形术师, 山海众头目 / 秘使, 重弩突袭者, 架桥船工 / 扶桥老手, 深池伙友影刃精英, 潜水员 (in water), 锏's second form and the 深池逐火 embers (PRTS 深池逐火战士 / 精锐战士 / 护卫 "获得隐匿、缴械"). 山海众头目 / 秘使 天赋 "该隐匿每次生效后自身获得强击标记(不可叠加)", 技能 破隐一击 "仅持有强击标记且被阻挡时可触发…技能开始时消耗强击标记".
- **Cause**: `targeting.js canTargetEnemy`, `snapshot.js flagsOf` and `Battle.foesInRadius` read `blockedBy` live, so the 隐匿 came back with the block's end.
- **Now**: every block release — `Battle._unblock`, `releaseBlocked`, `ai.js enforceBlockCapacity` (a blocker's death, retreat or stun, a block-count drop, a push, 无法阻挡 / 浮空 / 恐惧, a teleport) — calls `Battle._stealthSwitch(e)`: each 隐匿 source buff the enemy holds gets a `stealthOff:<source key>` buff for its restore time, `constants.js STEALTH_RESTORE` (3 s) or the source's `data.stealthRestore` (`content/enemies.js STEALTH_RESTORE_BY_KEY`: the 0 s / 1 s enemies above; the veil 0 s). `targeting.js enemyStealthed(e)` — 隐匿 flag, not revealed (反隐), not blocked, and some source not switched off — is the one test for ally targeting (`canTargetEnemy`), operator area damage (`foesInRadius`), the b.snap stealth bit (drawn solid meanwhile), 节日爵士乐手 (attacks only without its 隐匿), 假想敌:骨刺 (3 targets only in 隐匿) and 山海众头目 (the mark comes at the spawn and whenever its 隐匿 turns on again, the next blocked attack spends it: a new block inside the 3 s gives no second ×2 hit — until 0.1.2 every block did). A new block inside the window lifts the 隐匿 again and its end restarts the window; a 反隐 that ends outside a window hides it at once, as before; a veiled 潜伏者 hides as soon as its block ends (the veil) and, if the veil runs out inside its own 3 s, is revealed until they end. Our operators' 隐匿 / 迷彩 are untouched (allies get no switch).
- **Now**: every block release — `Battle._unblock`, `releaseBlocked`, `ai.js enforceBlockCapacity` (a blocker's death, retreat or stun, a block-count drop, a push, 无法阻挡 / 浮空 / 恐惧 / 沉睡 (since §24.9), a teleport) — calls `Battle._stealthSwitch(e)`: each 隐匿 source buff the enemy holds gets a `stealthOff:<source key>` buff for its restore time, `constants.js STEALTH_RESTORE` (3 s) or the source's `data.stealthRestore` (`content/enemies.js STEALTH_RESTORE_BY_KEY`: the 0 s / 1 s enemies above; the veil 0 s). `targeting.js enemyStealthed(e)` — 隐匿 flag, not revealed (反隐), not blocked, and some source not switched off — is the one test for ally targeting (`canTargetEnemy`), operator area damage (`foesInRadius`), the b.snap stealth bit (drawn solid meanwhile), 节日爵士乐手 (attacks only without its 隐匿), 假想敌:骨刺 (3 targets only in 隐匿) and 山海众头目 (the mark comes at the spawn and whenever its 隐匿 turns on again, the next blocked attack spends it: a new block inside the 3 s gives no second ×2 hit — until 0.1.2 every block did). A new block inside the window lifts the 隐匿 again and its end restarts the window; a 反隐 that ends outside a window hides it at once, as before; a veiled 潜伏者 hides as soon as its block ends (the veil) and, if the veil runs out inside its own 3 s, is revealed until they end. Our operators' 隐匿 / 迷彩 are untouched (allies get no switch).
- **The 深池逐火 embers** (all three, `husk()` with `stealthy`): the knock-out releases the warrior's block at once (`_unblock` right after the 重生's 无法阻挡, as `applyStatus` does for a status) once the ember's 隐匿 is on, so the ember is revealed until 3 s after the knock-out — the 1 s 重生 stays 无敌 and untargetable, then about 2 s in which ranged operators and operator splash can hit it even though its blocker took the next warrior. An ember knocked out while not blocked is 隐匿 as soon as its 重生 ends (the switch only follows a block).
- **Measured** (before = the v0.1.1 sim, after = this change; the flat stage with its row-9 lane, and real rounds on 战场#01 built like the match — an official wave with the TIMES pick, full content): the integrator's seven lineups (艾丝黛尔 / 角峰 / 隐现 / 幽灵鲨 against 1–4 战士 or 护卫): identical — 艾丝黛尔 alone against four 战士 2 s apart stays 0 / 4 because only one warrior is ever knocked out, and no lineup there knocks out a 护卫. 28 runs of a blocker + 2–3 ranged / splash operators against 4–6 战士 / 精锐战士 0.5–3 s apart: 81 → 84 of 126 killed, stand-ups 12 → 7 (23 runs unchanged, 4 one more kill, 1 one fewer — its blocker fell in the changed fight). Real rounds (R3 / R5 精锐战士 pick, R9 / R11 护卫 pick, three lineups up to the tier-4 four of §21.4's test): unchanged (R3 7 / 7, R5 5 / 16, R9 0 / 18, R11 0 / 28 for the tier-4 lineup; 0–1 for the weak ones). Why so little: in real rounds most knock-outs happen while the warrior is NOT blocked — ranged operators finish it on the way after it passed a full blocker (R5, tier-4 lineup: 10 of its 18 knock-outs, and 10 of the 13 embers that stood up again) — so its ember is 隐匿 at once, which is official; an ember freed by its own knock-out gets about 2 s after the 重生 and still needs 5 separate hits (火灰 10). What beats embers, officially: a free block slot where they walk (a second blocker behind the first), 反隐 (银灰 鹰眼视觉, 伊内丝 影哨, the SPT-X modules, 信仰搅拌机's module), or many fast hits.
- [ASSUMED]: at the knock-out the 重生's cleanse comes first, then the ember's 隐匿 with the block-end switch, which outlasts the 重生 (PRTS documents neither the order nor whether the switch survives a 重生); 深池伙友影刃精英 and 锏's second form (PRTS writes their 隐匿 as the plain 异常效果 with no restore note) follow the general 3 s, not the "表现上与我方干员相同" kind; one switch per 隐匿 source — with several sources the enemy hides as soon as any is back on; a push or a teleport (DISAPPEAR) ends a block like any other release; a warrior released by its blocker less than 3 s before its knock-out leaves an ember that is 隐匿 straight after its 重生 (the window is opened by the knock-out's own release only — 4 of 55 knock-outs in the measured rounds, no outcome changed when prototyped).
@@ -2172,7 +2172,7 @@ Decisions of the owner, 2026-10-04: a 联防 devour counts members who enter alr
## 24. Community reports after 0.1.3
Reports after the 0.1.3 release. Each was checked against the official data and PRTS; anything with no source is marked [ASSUMED]. Where each is handled: a skill clip with no Begin and no own Idle plays once (德克萨斯 S2 剑雨) → §24.1; 高台 for every melee chess whose trait reads 「可以放置于远程位」 (GitHub #153, PR #69) → §24.2; the 5-阿戈尔 revives go to the first 3 members knocked out (GitHub #105, #140) → §24.3; 联防 阿戈尔 devours the operator in front whoever owns it (GitHub #140) → §24.4; a special terrain tile explains itself on a tap (GitHub #184, PR #185) → §24.5; 活性源石 was two different materials on the two boards (GitHub #184, PR #185) → §24.6; 阿戈尔's devoured base ATK is a 最终加算 and a fallen marker's marks still resolve (GitHub #165, PR #176) → §24.7; 缇缇 S2's sleep pulses count for her trait (GitHub #162) → §24.8. Merged pull requests keep their own notes where they changed the rules: deploy-timed skills as duration skills (PR #109, §5 skill contract), the teammate's hand / temp / equipment in prep scouting (PR #129), 灵巧's knocked-out aura and the hidden-layer bonds (PR #66, research 02).
Reports after the 0.1.3 release. Each was checked against the official data and PRTS; anything with no source is marked [ASSUMED]. Where each is handled: a skill clip with no Begin and no own Idle plays once (德克萨斯 S2 剑雨) → §24.1; 高台 for every melee chess whose trait reads 「可以放置于远程位」 (GitHub #153, PR #69) → §24.2; the 5-阿戈尔 revives go to the first 3 members knocked out (GitHub #105, #140) → §24.3; 联防 阿戈尔 devours the operator in front whoever owns it (GitHub #140) → §24.4; a special terrain tile explains itself on a tap (GitHub #184, PR #185) → §24.5; 活性源石 was two different materials on the two boards (GitHub #184, PR #185) → §24.6; 阿戈尔's devoured base ATK is a 最终加算 and a fallen marker's marks still resolve (GitHub #165, PR #176) → §24.7; 缇缇 S2's sleep pulses count for her trait (GitHub #162) → §24.8; a sleeping enemy cannot be blocked and takes no block slot (GitHub #140) → §24.9. Merged pull requests keep their own notes where they changed the rules: deploy-timed skills as duration skills (PR #109, §5 skill contract), the teammate's hand / temp / equipment in prep scouting (PR #129), 灵巧's knocked-out aura and the hidden-layer bonds (PR #66, research 02).
### 24.1 A skill clip with no Begin and no own Idle plays once — 德克萨斯 S2 剑雨 (player report) — `render/spine.js SpineActor.setSkill / update` (`SKILL_CLIP_MIN`, `skillClipOnce`, `skillEndPending`)
@@ -2440,3 +2440,64 @@ Reports after the 0.1.3 release. Each was checked against the official data and
elite, S2 cast: an enemy at her back sleeps through 8 s of pulses and adds nothing beyond the ward's two operators; an
enemy in range beside both wards — one entry per pulse — takes the trait to 24 / 48 within 6.5 s; fails on 0.1.3's
code). The 125 test (a stun refresh is not an entry) and `kits_alt_t5`'s S2 test pass unchanged.
### 24.9 A sleeping enemy cannot be blocked: 沉睡 frees the block slot (GitHub #140; the owner's decision of 2026-10-06) — `sim/Battle.js _checkBlock / applyStatus`, `sim/ai.js updateEnemy`, `sim/buffs.js` (`sleep`), `kits/tier3.js` (瑕光 S2)
- **Seen**: GitHub #140 — a player tested 瑕光's S2 in the official mode (the 爱国者 stage): she put 4 enemies to sleep,
the hounds that came next were still blocked, and after the skill no more were — 「被沉睡的敌人是不占用阻挡数的」. In the
remake an enemy that fell asleep while blocked stayed blocked and kept its blocker's slot, so 瑕光 S2's sleepers filled
her 3 block for the whole skill and the next enemies walked past her (the owner's first reply on #140 had kept that
reading).
- **Official**: PRTS 异常效果 — the 异常组合 SLEEPING 沉睡 = 「无法行动+无敌+不可阻挡」, and the 异常效果 BLOCK_FREE 不可阻挡 =
「无法阻挡/被阻挡,自动解除阻挡」. 小睡 (DOZE) and 闭锁 (SHELTERING, 泥岩 S3) hold 不可阻挡 too — on operators, outside this
change.
- **Decision**: the owner's decision of 2026-10-06, as PRTS and the report say: a sleeping enemy cannot be blocked and
takes no block slot.
- **Cause**: 沉睡 was in neither block check. `Battle._checkBlock` refused `unblockable` / `levitate` / `fear` only, the
release in `Battle.applyStatus` fired for those three flags, and `ai.js updateEnemy` returns early for an enemy that
cannot act (a sleeper is `stun` too: `units.js`) before its own release check. The sleep template's `noBlock` only
stops a sleeping operator from blocking.
- **Now**: 沉睡 is one of the 不可阻挡 states. `applyStatus(enemy, 'sleep')` releases the enemy at once (`_unblock`: the
blocker's slot frees for the next enemy; a 隐匿 enemy's block-end window starts, §22.8); `_checkBlock` never blocks a
sleeper; a sleep added as a plain buff (`flags.sleep`) is let go on the enemy's next update (the cannot-act branch of
`updateEnemy`). The sleeper stays where it fell asleep — overlapping its former blocker and whatever that blocker takes
next — and when it wakes it is checked like any unblocked enemy: blocked again where it stands by a blocker in contact
with a free slot (usually the same one), else it walks on through the full blocker. 瑕光 S2 (the ground enemies on her
tile and the enemies she blocks): the sleepers free her 3 slots, she blocks the next 3 during the skill, and when S2
ends the sleepers wake beside her and, her slots full, walk on — the report. A stun, a freeze or a refused sleep (23
enemies are 沉睡免疫) keeps the block as before; sleeping operators are unchanged (they already released what they block).
- **Other readers of the block** (checked): `Battle.blockedTargets` — blocked-first targeting, the DEFAULT trigger, the
强攻手 / 重剑手 / 推击手 attack on every blocked enemy — no longer lists a sleeper. Only `hitSleep` attackers could target
one, and of those only 瑕光 blocks: her 仁慈 (sleepers in her range first, ×atk_scale) reads her range, so a sleeper she
let go in front of her is still her first target and one behind her is out of reach. A 要塞 that blocked nothing but a
sleeper stalled (its melee branch found no target); it now fires its ranged splash. The "while blocking" effects
(`unit.blocking`) do not count a sleeper; “庞贝”'s self-blast clock restarts when a sleep ends its block (as a 浮空
already did); the snapshot's blocked bit (`UF.BLOCKED`, the client's block marker) follows. 荒芜拉普兰德 S1's 「非移动敌人」
reads the sleep itself.
- [ASSUMED]: a woken sleeper is re-blocked in the enemy update order (an enemy that reaches the blocker earlier in the
same tick takes the slot first; PRTS gives no order) and where it stands, never pulled back to the blocker's front;
“庞贝”'s clock restarts although its talent lists 沉睡 among the pauses — the 不可阻挡 ends the block, and
「解除阻挡时重置计时」.
- Golden: every moved scenario fields one of the three kits that sleep enemies (小满 S2, 瑕光 S2, 缇缇) and sleeps enemies
that were blocked (counted with a probe): `roster-003` (小满 S2, 6 such sleeps: 82 kills instead of 83, 3 leaks instead
of 2 at the 110 s timeout); `roster-005` (elite 小满 S2, 3: cleared at 136.73 s with 83 kills and 1 leak instead of the
140 s timeout with 82 and 2); `roster-013` (缇缇 S3, 13: the same fight — only the `blocked` count, 23 → 34 with the
woken sleepers held again, and the snapshot hashes, the blocked bit, move); `roster-032` (缇缇 S1, 4: 7 knock-outs
instead of 5, 缇缇 among them, and 24 萨尔贡 layers instead of 34; same kills and leaks); `roster-038` (elite 缇缇 S2, 2:
ends at 197.43 s instead of 197.27 s, 4 knock-outs instead of 3); `roster-039` (瑕光 S2, normal and elite, 32 + 22: the
enemies they hold and put to sleep walk on when they wake with both blocks full — 41 of 52 killed instead of 47, 11
leaks instead of 5 at the 170 s timeout); `roster-042` (缇缇 S2, 4: ends at 161.17 s instead of §24.8's 166.97 s);
`bond-maniShip-high` (小满 S2 among the members, 1: only the `blocked` count, 29 → 30, and the snapshot hashes);
`coop4-FUNNY-6` (ai_0's 缇缇: from round 9 her trait's 萨尔贡 / 精准 layers and ai_0 / ai_2's boss damage move);
`coop4-ABYSS-7` (ai_2's 小满: rounds 11–12, one more kill and one fewer leak in round 11, four more kills in round 12);
`coop2-NORMAL-8-serverrun` (ai_1's 缇缇: from round 10 its battles move — one more leak in round 10 — and the team is
eliminated in round 13 instead of winning after round 14). `fields` did not move.
- Tests: `test/sim/feedback4-sleep-unblock.test.js` (new; every case fails without this change) — a block-1 operator
holding A: A falls asleep → released at once, the slot frees and B is blocked, A stays put; A wakes while B holds the
slot → not blocked, it walks on; B knocked out while A sleeps → A stays unblocked beside the free operator and is
blocked again the moment it wakes, never having moved; a plain-buff sleep is let go on the next update, a stun or a
refused sleep keeps the block; `blockedTargets` drops the sleeper and takes B; the real 瑕光 S2 — her 3 blocked enemies
sleep and are let go, she blocks the next 3 during S2, and when it ends the sleepers wake with no room and walk on.
`playtest5_blocking` (its 瑕光 S2 test included), `combat`, `engine-requests`, `kits_t1t2` / `kits_alt_t2` (小满),
`kits_t3` / `kits_alt_t3` (瑕光), `kits_t5` / `kits_alt_t5` / `garrisons_battle` (缇缇) and the other sleep and block
suites pass unchanged.