From 81acdc67ef24e28adcec66696f53f55bba7dbef3 Mon Sep 17 00:00:00 2001 From: sganggs Date: Sat, 3 Oct 2026 07:56:15 +0800 Subject: [PATCH] feedback1f WU: fence-block docs - correct provenance, mark air blocking [ASSUMED] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SIM.md Blocking: the 薄绿 S2 drag case was found while checking community report F4 (深巡 on a fenced tile), not reported by players; the passage now says so, keeps the surrounding base lines untouched and wraps to the file's width. The air-blocking reading (blockFly units on a fenced tile still block flyers) is marked [ASSUMED: PRTS restricts the rule to 地面阻挡] in SIM.md, Battle._blockerFor and the test file; the _blockerFor doc also states that the gate reads ground passability (on the stages the fenced tiles are the only low tiles ground units cannot pass). No behaviour change. --- docs/SIM.md | 22 ++++++++++++---------- server/sim/Battle.js | 7 ++++--- test/sim/feedback1f-fence.test.js | 4 +++- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/docs/SIM.md b/docs/SIM.md index a63aad21..c0b86ea8 100644 --- a/docs/SIM.md +++ b/docs/SIM.md @@ -177,16 +177,18 @@ user playtest #5 item 4): an unblocked, blockable enemy is blocked by an ally (o block radius of the enemy's position — `constants.js BLOCK_RADIUS`: ground 0.7071 (compared as d² < 0.49999037, the tile's circumscribed circle), air 0.8944 (blockFly units against flyers), devices 0.4472 — while that blocker has free capacity for the enemy's `blockWeight` (data `blockCnt`). A unit standing on a tile ground units cannot pass — the -fenced 围墙 / 围栏 tiles (`b`: low, deployable, flyers only) — blocks no ground enemy (PRTS 围墙 / 围栏 地形机制 "部署在 -其中的单位,若当前阻挡类型为'地面阻挡'则无法阻挡敌人"; `Battle._blockerFor`): nothing walks onto those tiles, but a push or -pull leaves an enemy at the fence edge, 0.5 from the unit — it walks on (community report F4 after 0.1.0: 薄绿 S2 on a -fenced tile held the dragged enemies there; test/sim/feedback1f-fence.test.js); air blocking (blockFly against flyers) -stays; 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 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 hundredths of a tile of deceleration are not modelled), and **every blocker** — melee units (要塞 / 领主 / 哨戒铁卫 +fenced 围墙 / 围栏 tiles (`b`: low, deployable, flyers only; the only low tiles of that kind on the stages) — blocks no +ground enemy (PRTS 围墙 / 围栏 地形机制 "部署在其中的单位,若当前阻挡类型为'地面阻挡'则无法阻挡敌人"; +`Battle._blockerFor`). Nothing walks onto those tiles, but a push or pull stops an enemy at the fence edge, 0.5 from the +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 +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 +hundredths of a tile of deceleration are not modelled), and **every blocker** — melee units (要塞 / 领主 / 哨戒铁卫 included), summons (流形's melee copy) and a ranged operator standing on a melee tile alike — 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 diff --git a/server/sim/Battle.js b/server/sim/Battle.js index 7eebc335..0af742aa 100644 --- a/server/sim/Battle.js +++ b/server/sim/Battle.js @@ -1118,9 +1118,10 @@ export class Battle { * Can ally/device `u` block enemy `e` (block weight `w`) right now — everything but the contact distance. A unit on a * tile ground units cannot pass blocks no ground enemy: the fenced tiles (围墙 tile_fence_bound / 围栏 tile_fence — * low ground, deployable, passable to flyers only) — PRTS 围墙 / 围栏 地形机制 "部署在其中的单位,若当前阻挡类型为'地面 - * 阻挡'则无法阻挡敌人". Air blocking (blockFly against flyers) is not ground blocking and stays. Nothing walks onto such - * a tile, so it matters for an enemy pushed or pulled against the fence (Battle.displace stops it at the tile edge, - * 0.5 from the fenced unit — inside the ground block radius). + * 阻挡'则无法阻挡敌人". The gate reads the tile's ground passability; on the stages the fenced tiles are the only low + * tiles ground units cannot pass. Air blocking (blockFly against flyers) stays [ASSUMED: PRTS restricts the rule to + * 地面阻挡]. Nothing walks onto such a tile, so it matters for an enemy pushed or pulled against the fence + * (Battle.displace stops it at the tile edge, 0.5 from the fenced unit — inside the ground block radius). */ _blockerFor(u, e, w) { if (!u.alive || !u.deployed || u.hidden || u.s.flags.noBlock || u.s.flags.sleep) return false; diff --git a/test/sim/feedback1f-fence.test.js b/test/sim/feedback1f-fence.test.js index 87585fc0..3ca259d2 100644 --- a/test/sim/feedback1f-fence.test.js +++ b/test/sim/feedback1f-fence.test.js @@ -12,7 +12,8 @@ // Nearby rule fixed: PRTS 围墙 / 围栏 地形机制 "部署在其中的单位,若当前阻挡类型为'地面阻挡'则无法阻挡敌人" — a unit on a fenced // tile blocks no ground enemy (Battle._blockerFor). Nothing walks onto such a tile, but a push / pull stops an enemy at // the tile edge, 0.5 from the fenced unit — inside the ground block radius 0.7071 — and 0.1.0 let the fenced unit block -// it there. Air blocking (blockFly against flyers) is not ground blocking and stays. +// it there (found while checking F4, with 薄绿 S2). Air blocking (blockFly against flyers) stays [ASSUMED: PRTS restricts +// the rule to 地面阻挡]. import { test } from 'node:test'; import assert from 'node:assert/strict'; @@ -152,6 +153,7 @@ test('fix, real kit: 薄绿 on a 围墙 tile drags enemies against the fence and }); test('fix: air blocking stays — a blockFly unit on a fenced tile blocks a flyer over the fence', () => { + // [ASSUMED] PRTS's rule names only 地面阻挡 ("若当前阻挡类型为'地面阻挡'则无法阻挡敌人"), so air blocking is kept const h = makeBattle({ stageId: 'act1autochess_m01', units: [{ chessId: UDFLOW, row: 11, col: 7, dir: 'RIGHT' }], autoFinish: false, timeLimit: 60, seed: 3 }); h.step(1); const u = h.unit(UDFLOW);