2 Commits
Author SHA1 Message Date
xcdoge b4bc89ad4e feedback7 UIBACK: the top-bar capsule counts like the official — resolved = killed + leaked among the enemies the round scheduled (opening 0/3, a leak 1/3, a kill 2/3, the splitter 3/3); a split child, a summon and a boss summon are in neither number but still cost LP and break 完美作战 (PR #308 by @xcdoge, the capsule half of PR #157 — authored by them: the sim / protocol / HUD hunks applied as reviewed): inTotal / killedInTotal / leakedInTotal / resolved, b.snap / BattleResult / b.progress (optional field) / m.public progress carry resolved, killed may exceed total (validation bounds it by the content-spawn allowance); dropped the PR's stray design-doc line — it had replaced the S→C b.end bullet of docs/design/network.md, which is back; the 联防 live-counter change mark follows the enemy list now that a spawn no longer moves total (uniteLeftMark + test); golden: only total / players.*.total / snaps move, outcomes bit-identical — roster 23 (roster-002 003 007 008 009 010 011 012 013 015 017 018 020 023 024 025 026 027 037 045 047 048 049), bonds 2 (bond-maniShip-low, bond-soloShip-high), fields 11 (boss-boss_1 3 5 pair+solo, boss-boss_6-solo, hidden-boss_8 10 pair+solo), diy 11 (diy-036 040 056 062 068 073 083 091 095 114 115), matches 12 (solo-FUNNY-1 NORMAL-1 HARD-1 ABYSS-1 ABYSS-2, coop2-NORMAL-3 coop2-HARD-4 coop3-ABYSS-5 coop4-ABYSS-7 coop2-NORMAL-8-serverrun solo-HARD-9-boosted coop2-NORMAL-70-diy: the total column of 36 round rows), standins unchanged 2026-10-08 19:30:36 +08:00
xcdoge 2669b6ab57 feedback7 R22-RENDER: a pushed / pulled enemy slides to where the sim put it, a dying flyer keeps its lift through the Die clip, a long Die clip plays whole (PR #380 by @xcdoge); golden: unchanged
The sim displaces at once (battle/displacement.js), so the snapshots only show the destination: a ≤ 2.5-tile push was
lerped over one snapshot interval (3 frames, 0.58 tiles in one frame — frame-loop repro over a real battle), a longer
pull snapped. render/app.js now starts UnitView.slideTo as soon as the interval it samples ends on the snapshot that
carries the destination (a `displace` fx still queued up to SnapshotBuffer.nextSnapT); the view holds where it stood
until that snapshot is shown, then eases into the sampled position under a constant deceleration (v0 = 2D/T, a = v0/T,
T = 0.14·√D in 0.12–0.45 s — ours, [ASSUMED]: no source gives the official timing; docs/research/13 has the official
impulse-and-friction classes). A unit that dies on the way finishes the slide and lies where the push put it.
Death: DIE_CLIP_MAX 1.6 → 8 s (data/assets.json: 234 enemy Die clips, the longest 7.97 s, 25 over 1.6 s), and a
flyer holds FLY_HOVER until the fade tail (DIE_FADE_TAIL 0.55 s).

Substantially @xcdoge's code (PR #380: the slide, the death timing, research 13 / 14, most tests), authored as theirs.
Changed on review: the corpse no longer goes back to where it stood (the PR's test asserted that; the sim's body is at
the destination); the PR's pre-pass scanned (renderT − 0.5, renderT] after processEvents had taken those events, so
it never fired and the slide started a frame before landing — it now looks ahead to the next snapshot and holds the
view until then; the slide eases into the live sample instead of the fixed destination (no jump back onto an enemy
that walked on); each step uses its mean velocity (the end-of-step speed ran 9 % short, then jumped); the constants'
comments say the timing is ours; research 14 no longer cites a sweep script and a data guard that were not in the PR.

Golden: unchanged (client only).

Tests: test/render/unitview.test.js 35/35 (slide: deceleration, idempotence, facing, snapshots in flight, friction,
√D, corpse lies where pushed, hold-then-ease without a landing jump, a never-shown slide handed back; the app.js frame
order over a real battle: a 1.7-tile push over ≥ 8 frames with every step < 0.35 tiles, a push-kill's body staying at
the destination; death: a dying flyer's lift, every Die clip within DIE_CLIP_MAX and a 7.97 s clip scheduled whole);
test/sim/displace-fx.test.js 1/1; render/interp 16/16; docs tests pass.
2026-10-08 19:08:27 +08:00