feedback4: a sleeping enemy cannot be blocked and takes no block slot — 沉睡 = 无法行动+无敌+不可阻挡 (GitHub #140; the owner's decision of 2026-10-06)

- GitHub #140: a player tested 瑕光's S2 in the official mode — she slept 4 enemies and still blocked the next ones,
  after the skill no more were (「被沉睡的敌人是不占用阻挡数的」). PRTS 异常效果: SLEEPING 沉睡 = 「无法行动+无敌+不可阻挡」,
  BLOCK_FREE 不可阻挡 = 「无法阻挡/被阻挡,自动解除阻挡」. Until now an enemy that fell asleep while blocked stayed blocked
  and kept its blocker's slot.
- Battle.applyStatus releases an enemy that falls asleep (as for 浮空 / 恐惧 / 不可阻挡), Battle._checkBlock never blocks a
  sleeper, and ai.js updateEnemy lets a plain-buff sleeper go on its next update. The sleeper stays put; awake, it is
  blocked again only by a blocker with a free slot, else it walks on. A stun, a freeze or a refused sleep keeps the
  block; sleeping operators are unchanged.
- Readers of the block follow: Battle.blockedTargets (blocked-first targeting, the DEFAULT trigger, hitAllBlocked)
  drops the sleeper — of the hitSleep attackers only 瑕光 blocks, and her 仁慈 reads her range; a 要塞 holding only a
  sleeper no longer stalls; “庞贝”'s self-blast clock restarts when a sleep ends its block [ASSUMED]; the snapshot's
  blocked bit follows.
- Tests: new test/sim/feedback4-sleep-unblock.test.js (5 cases, each fails without the change: the slot frees and the
  next enemy is blocked, the sleeper stays put; awake with no room it walks on; never blocked while asleep, re-blocked
  on waking beside a free blocker; a plain-buff sleep; the real 瑕光 S2). 1274 targeted tests (blocking, statuses,
  小满 / 瑕光 / 缇缇 kits, garrisons, professions, enemies, kits t1–t6), docs-consistency and GOLDEN_FULL pass.
- Docs: DESIGN §24.9 (and the §24 intro, §5.5 Blocking, §22.8's release list), SIM.md (Blocking, the `sleep` row,
  plain buffs), the buffs.js / Battle.js / ai.js / 瑕光 kit comments.
- Golden (every moved scenario sleeps blocked enemies; DESIGN §24.9 gives each move): roster-003 / roster-005 (小满 S2:
  82 kills instead of 83 / cleared at 136.73 s instead of the 140 s timeout), roster-013 (缇缇 S3: only the blocked
  count and the snapshot hashes), roster-032 (缇缇 S1: 7 knock-outs instead of 5), roster-038 (elite 缇缇 S2: ends at
  197.43 s), roster-039 (瑕光 S2 normal + elite: 41 of 52 killed instead of 47 — the sleepers walk on when they wake),
  roster-042 (缇缇 S2: ends at 161.17 s instead of 166.97 s), bond-maniShip-high (小满: only the blocked count and the
  snapshot hashes), coop4-FUNNY-6 (ai_0's 缇缇: layers and boss damage from round 9), coop4-ABYSS-7 (ai_2's 小满:
  rounds 11–12), coop2-NORMAL-8-serverrun (ai_1's 缇缇: one more leak in round 10, the team eliminated in round 13
  instead of winning). fields unchanged.
This commit is contained in:
sganggs committed 2026-10-06 16:57:55 +08:00
1 parent 30e7acea42
commit bbe59b9a5f
10 files changed
+460 -222

No files matched your search

+9 -5
View File
@@ -218,8 +218,11 @@ ground enemy (PRTS 围墙 / 围栏 地形机制 "部署在其中的单位,若
unit; it walks on from there (found while checking community report F4 after 0.1.0, 深巡 on a fenced tile: 薄绿 S2 held
the enemies she dragged against the fence; test/sim/feedback1f-fence.test.js). Air blocking (blockFly against flyers)
stays [ASSUMED: PRTS restricts the rule to 地面阻挡], and a unit on a fenced tile still attacks whatever stands on its
range tiles. It is checked every tick for every unblocked enemy, moving or
not: an enemy that overlaps an operator when its blocker dies / is withdrawn / is stunned, or when the operator's
range tiles. Never blocked: an enemy holding 不可阻挡 (PRTS 异常效果 BLOCK_FREE 「无法阻挡/被阻挡,自动解除阻挡」) —
the `unblockable` flag (恐惧, 诱导 and many enemy abilities carry it), 浮空, and 沉睡 (SLEEPING = 无法行动+无敌+不可阻挡: an
enemy falling asleep is released at once, its slot freeing for the next enemy, and stays where it is; once awake it is
blocked again only by a blocker with room, else it walks on — DESIGN §24.9). It is checked every tick for every
unblocked enemy, moving or not: an enemy that overlaps an operator when its blocker dies / is withdrawn / is stunned, or when the operator's
blocked enemy dies, is taken over at once; an enemy that finds no room walks on (pass-through). Several blockers in
contact → the nearest [ASSUMED]. A head-on enemy therefore stops at contact, ~0.71 tile from the blocker's centre, on the
tile in front of it (PRTS 作战机制: a blocked enemy's collider does not enter the blocker's tile; the official few
@@ -424,7 +427,7 @@ Guarantees content can rely on (pinned by `test/sim/robustness.test.js`):
- **Runaway content.** At most `MAX_ALIVE_ENEMIES` (600) living enemies per field (`spawnEnemy` returns **null** beyond —
content must handle it); a SpawnSpec `count` is capped the same way and `time: Infinity` spawns are never scheduled.
- **Movement.** Route legs outside the rect are clamped onto it (h07_01's extra fly route runs along row 6, outside the
boss rect: without the clamp the flyer hovered at the border forever). An enemy that gains `unblockable`/`levitate`
boss rect: without the clamp the flyer hovered at the border forever). An enemy that gains `unblockable`/`levitate`/`sleep`
through a plain buff is released by its blocker on its next update.
- **Listener hygiene.** When a unit is removed for good (enemy killed/leaked, token expired or dead, device destroyed,
permanent retreat) its hooks and periodic `every` timers registered with `{ owner: unit }` are dropped at the end of
@@ -571,7 +574,7 @@ of coverage per 3 s), kept because the current wording no longer says so (feedba
| `stun` | cannot act / move; **a stunned operator blocks nothing** (its blocked enemies are released: taken over by another operator in contact with room, else they walk on — §1.2 Blocking) | – |
| `freeze` | stun; **enemies** also RES −15 | – |
| `cold` | ASPD −30; a 2nd cold while cold ⇒ `freeze` for max(remaining cold, the incoming cold after 抵抗) — PRTS 术语释义 寒冷 「持续时间取双方之中最高」 (`COLD_FREEZE_DURATION` 3 s only when neither side has a duration; unless frozen-immune). [ASSUMED] the one catalogue cold uses that 友方 sentence for an enemy-applied cold too | – |
| `sleep` | 无敌且无法行动: inactive, untargetable, **takes no damage** (unless the attacker profile has `hitSleep` or the damage `ignoreSleep`), blocks nothing | – |
| `sleep` | 无敌且无法行动: inactive, untargetable, **takes no damage** (unless the attacker profile has `hitSleep` or the damage `ignoreSleep`), blocks nothing; PRTS 异常效果 SLEEPING = 无法行动+无敌+**不可阻挡**: an enemy asleep **cannot be blocked and takes no block slot** — its blocker lets go at once (the slot frees for the next enemy), it stays where it is, and when it wakes it is blocked again only by a blocker with room, else it walks on (DESIGN §24.9) | – |
| `slow` | moveMul 1 − value (*strongest*) | default 0.5 |
| `sluggish` (停顿) | moveMul 0.2 | – |
| `bind` (束缚) | cannot move | – |
@@ -593,7 +596,8 @@ of coverage per 3 s), kept because the current wording no longer says so (feedba
| `defDown` / `resDown` | defMul 1 − value / RES −value (*strongest*) | 0.3 / 20 |
Unknown keys become a flag buff `{ [key]: true }`. Flags `noBlock` (blocks nothing) and `tremble` exist for custom buffs;
a custom buff with `flags.sleep` also blocks nothing and is untargetable/invulnerable like the status.
a custom buff with `flags.sleep` also blocks nothing, is untargetable/invulnerable and, on an enemy, cannot be blocked
(its blocker lets go on the enemy's next update: `ai.js updateEnemy`) like the status.
**Element gauges** (`unit.elem = {burn, neural, apoptosis, erosion, necrosis}`; capacity `unit.gaugeMax` = 1000, enemy
leaders (rank BOSS / boss units) 2000): deal `{ type:'element', element, amount }` (fires `elementHit` first; the gauge