Commit Graph
11 Commits
Author SHA1 Message Date
sganggs 0b0ce4fbd7 Update expanded roster checks and register Clementia impact visuals 2026-10-09 17:46:07 +08:00
leiming2333 7c56335c06 feedback7 R22-LATE: 谢拉格's 盟约寒风 blows a blizzard up the field with a stronger cold flash; 灵知 / 麦哲伦's own cold wind keeps the light flurry; golden: unchanged
GitHub PR #386 by @leiming2333 (this commit is substantially the PR: its blizzard particles and flash). The official
blizzard blows bottom-up (the owner's confirmation of 2026-10-08; community report 「谢拉格的效果特性不明显,暴风雪应该
从下向上刮」): snowflakes rise off the bottom edge on a crosswind (48, low 22; were 26 drifting down), 10 gust streaks
(low 4) race up through the field, and the cold flash goes from 0.35 / 0.8 s to 0.45 / 1 s. Counts, speeds and lives
are marked [ASSUMED] (a visual choice).

Added on top of the PR: the same 'chill' fx is also the coldWind of 灵知 S3 (失温症, at its start) and of 麦哲伦 S1's
pulse (every 3 s — 248 in one golden battle); the PR turned every one of them into the full-screen blizzard. Only the
bond's field-wide wind (the device emits no anchor unit) gets it now; an operator's own coldWind (`id` = the unit)
keeps the light flurry and the softer flash it had.

Tests: test/render/fxchill.test.js (2; the gust case fails on the parent). Display only: golden unchanged.
2026-10-08 21:45:09 +08:00
sganggs cf98f4c3f8 feedback7: merge fb7-render — #382 赤刃明霄陈 S3 sword-qi drawn (sim chen3Wave fx), #381 enemy attack recovery held in interpolation, #380 push / pull slide (corpse stays where pushed; same-step kills finish the slide), #384 eye masks, 香槟炸弹 HP bar hidden, #246 an unwound attack plays its whole clip
- Conflicts with the merged fb7-hud (both added display-only snapshot lists): server/sim/battle/events.js, types/core.js,
  public/js/render/interp.js, docs/SIM.md, docs/design/network.md — union of ammo / wolves / neg and stand / standCut.
- Grok review: MERGE AFTER FIXES — the HIGH finding (same-step push kill) fixed on the branch (7a33bc7e).
- Golden: diy-073 / diy-074 (fx counts only; union OK); broad node --test 5442 (5441 pass, 0 fail, 1 skipped); lint 0
  errors; typecheck.
2026-10-08 20:51:11 +08:00
IceCodeNewandConvey123 8ae891f1f3 feedback7 R22-HUD: the HP bar shows the ammo skill's rounds as yellow cells (隐现 S2: 14), 伺夜's 狼影 left as diamonds and 斩业星熊's 我执 pool as a red bar — one snapshot change for PR #303 and #378 by @IceCodeNew and PR #383 by @Convey123; golden: unchanged
The three PRs patched the same snapshot and HUD lines (Grok's review: do not merge three diffs), so this is one design
built from their code and tests; IceCodeNew is the commit author (#303, #378), Convey123 co-author (#383).

- b.snap gains three optional, display-only lists beside the unchanged 9-field tuples (snapshot.js ammoView / wolfView /
  negView, called from battle/events.js snapshot(); a living, deployed, visible ally, only when it has one):
  ammo [[id, rounds left, magazine]] (whole rounds; the magazine is the activation's real total that unitTuple's SP
  fraction runs on, extras and refills included), wolves [[id, 狼影 left, talent maximum]] (mem.shadows of the new
  mem.wolfCapacity, set by tokens.js wolfPack and the managed vigil kit), neg [[id, fill]] (unit.negFill(), a function
  op-hsgma2.js sets: the pool is read when the snapshot is taken, no per-tick sync). UnitInfo.ammoSkill (an ally whose
  skill is an ammo magazine) is known from the first appearance: fx events run before the frame's sample, so the aura
  cannot wait for the first ammo row.
- render/interp.js keeps the lists per snapshot (malformed rows / unknown ids dropped) and sample() hands them out from the
  older snapshot like flags (they step with the skill flag); render/units.js draws them: the ammo magazine replaces the
  SP bar (a cell per round, thin cuts, exact fill, no cuts under 2 px a cell), a row of diamonds under the bars for the
  wolves (the element gauge row moves below), the red bar over the drained HP bar for the pool. An ammo skill draws no
  standing aura (rings.js _aura; the activation burst stays).
- PR #378's wolf-head avatars are NOT taken: the count is data (the talent text 至多3只, mem.shadows), the HUD art of the
  official counter is in no game data we have, so the pips are plain diamonds [ASSUMED look]. The PRs' own tests are
  folded in and extended (test/sim/hud-readouts.test.js, test/render/hud-readouts.test.js, op_hsgma2.test.js).
- Docs: network.md, SIM.md §9, client.md, PLAYING.md, types/core.js.
- Golden: unchanged (283 scenarios; the canon hashes units / down / elem only, no sim state moved).
- Tests: 4 + 14 new + 1 in op_hsgma2 (12), all fail on the parent; 344 related tests pass; lint 0 errors, typecheck,
  check:imports, docs tests.

Co-authored-by: Convey123 <Convey123@users.noreply.github.com>
2026-10-08 19:22:08 +08:00
Convey123 ffa538c39d feedback7 R22-RENDER: 赤刃明霄陈 S3's sword wave is drawn along its path — the sim sends its position as a chen3Wave fx every 0.12 s, the client draws a 'qi' blade (PR #382 by @Convey123, owner item 12); golden: diy-073 / diy-074 events.fx and fx.chen3Wave only
The 赤霄·天喟 wave is a kit-managed probe (it turns corners and lives as long as the skill), not a snapshot
projectile, and the sim emitted one `dash` at the cast and a `slash` per hit — nothing along the way, so the client
drew no wave. op-chen3.js now emits fx('chen3Wave', { x, y, fromX, fromY, dr, dc, id }) every WAVE_FX_EVERY (0.12 s;
4 ticks), the trail restarting at a corner; render/fx registers chen3Wave → 'qi' (pt: drawn at the event, never on
her) and draws a streak plus a crescent head turned the way it travels. The look is a procedural stand-in, not the
official particle prefab.

Substantially @Convey123's code (PR #382), authored as theirs. Changed on review: the head is projected after
streak() — streak() reuses the effect system's projection scratch, so the PR drew the crescent on the trail's start,
one event behind the wave — and the trail, head and heading share one height; an unused test variable dropped.

Golden: diy-073 (5_diy*=chen3 S3 in two slots) events.fx 508 → 1558, fx.chen3Wave → 1050; diy-074 (6_diy*=chen3 S3)
events.fx 272 → 872, fx.chen3Wave → 600. HP, kills, damage, hooks and snapshot hashes unchanged: battle.fx only
records an event.

Tests: test/content/op_chen3.test.js (+1: the events, their cadence, id, direction, trail start, silence after the
skill) 12/12; test/render/fxchen3wave.test.js (new, 6: the archetype, drawn at the wave not at her, the head on the
wave and turned with it, a sweep joining into one trail, junk input, nothing left after) 6/6; boardart 15/15.
2026-10-08 18:48:53 +08:00
sganggs b87848a443 feedback5 R19G: 蕾缪安's S3 no longer ends by itself when nothing is in her range — it keeps its bullets and locks and locks the next enemy that comes; the bombardment follows only when the bullets are spent (community report); golden: 3 scenarios move
Seen (community report 「蕾缪安3技能范围里没人好像会自动结束」, relayed by the owner): with S3 locking, the locked enemy
killed or walking out of her range and nobody else in it, the skill ended at the next lock tick — the shells fell at
once and the bullets left were thrown away (repro on 0255afd: 3 of 5 bullets lost; a walker leaving her range, 1 lost).
Cause: chess_char_6_01-lemuen.js:169 `if (!e) { if (m.lemLocks.length) skill.end('ammo'); return; }`, there since the
initial import with no decision behind it.
Official: 「攻击装有5发弹药,打完后结束(可随时停止技能)」 — an ammo skill ends when its bullets are spent or the player
stops it; PRTS 卫戍协议/帮助 技能操作 「通常不会自动关闭技能」 (only 玛露希尔's 召唤使魔 is closed automatically); the client
(charpack char_4193_lemuen, buff_template_data lemuen_s_3): the S3 lock is an attack that needs a target and the skill
buff switches to the bombardment mode on ON_BUFF_FINISH only.
Now: with nothing to lock the skill waits (bullets and locks kept, the marks following their enemies or staying where
they left), its lock ready, so the next enemy in range (or 通缉) is locked on the next tick; it ends when the bullets are
spent and the shells fall on every mark in lock order as before. The S3 'lock' fx carry `hold`: render/fx/locks.js keeps
those reticles while the shooter's skill bit (UF.SKILL) is on and starts their LOCK_T at the skill's end (they faded 5 s
into a wait otherwise); S2's aim lock keeps its timeout.

Golden — traced on both trees (SkillRuntime start / end, the round's fields, the carried SP); in each the first
divergence is an S3 the parent ended with bullets left and nothing in her range:
- roster-018: the elite 蕾缪安's S3 of 7.63 s ended at 9.63 s with 2 of 6 bullets left; now the 6th goes at 12.00 s
  (first differing snapshot window 0–10 s).
- boss-boss_3-pair: her S3 of 27.8 s ended at 30.3 s with 4 of 9 left; now all 9 by 34.43 s (window 30–40 s); the boss
  now falls at 199.53 s instead of the 200 s cap.
- coop2-NORMAL-14-standins: ai_0's 蕾缪安 in round 11 ended S3 at 17.2 s (6 of 8 left) and 77.97 s (7 of 9); now she
  spends them, enters the 联防 with 25.96 SP instead of 10.27, casts S3 there and kills one more of h_0's leaked enemies:
  h_0 loses 1 LP less (rounds 11–12 LP 18 → 19, 8 → 9; lpLost 30 → 29; ai_0 kills +1).
bonds, standins, diy unchanged.

Tests: test/sim/feedback5-lemuen-s3-wait.test.js (3; the killed target and the walker who leaves fail on the parent),
test/render/fxproj.test.js +1 (a held lock waits while the skill bit is on; fails on the parent renderer).
Docs: CHANGELOG 0.2.0 规则(按官方), docs/history/0.2.0.md §25.22.8 (also notes, unchanged: S2 spends a bullet on every
normal attack where PRTS says only the 通缉 snipe does — left to the owner).
2026-10-07 12:19:55 +08:00
sganggs f1e462ef62 feedback5 CB2: persistent ground areas stay readable when they stack — a zone re-sent under one key updates in place, persistent areas are dimmer and share their light where they overlap (community report of 2026-10-06 「炼金单元等范围持续性技能特效太亮(尤其是多层叠加以后)」)
Cause: 引星棘刺 S2's drifting alchemy unit is re-sent every second (position and radius change) and the client drew each
event as a new additive zone lasting the rest of the unit's life — up to twelve layers on one spot; overlapping units
(锡人's charges, several alchemists) added up the same way (render/fx/zones.js: disc alpha 0.28, edge 0.75, ADD blend).
Now: the sim fx carries `key` (kits/ops/chess_char_5_15-thorn2.js) and zones.js updates the zone under that key in place;
zoneAlpha draws a persistent area (> 3 real s) at 0.16 / 0.5 and ÷ √n among the n persistent areas overlapping it (centres
closer than ¾ of their radii summed); short bursts and telegraphs unchanged.

Golden: unchanged (fx events are counted by kind; the snapshots do not carry fx).
Tests: test/render/feedback5-zone-stack.test.js (3, fail on the parent).
2026-10-07 02:32:28 +08:00
sganggs 6372f2892b feedback5 WAA: the 孤岛风云 prisoners leave the gate confined and change model as their official prefabs do — grey while 【禁锢】, the blinking orange warning before the last confined attack, red once freed; the 4th attack already hits freed (community report of 2026-10-06 「囚徒类敌人出门就是已解放的模型」)
- Cause, client: the prisoner skeletons carry three clip sets whose collar light is grey, blinking orange
  and red. The official battle prefabs (local client battle/enm_pfb_6.ab: the Graphic component's anim key
  -> clip table, the modes' replace pairs, the clip the Spine starts on) draw mode Default (【禁锢】) on the
  grey set, mode R (the warning) on the orange set and mode L (【解放】) on the red one. The name-based role
  resolver gave 普通囚犯 / 老练囚犯 their unnumbered set — the red one — so they came out of the gate freed;
  no FORMS entry existed, so no prisoner ever changed (强壮囚犯 / 拳师囚犯 / 重犯 / 传奇重犯 stayed grey).
- Cause, sim: buff_template_data enemy_confinement[atk_cnt] spends a charge ON_BEFORE_ATTACK (not while
  麻痹) and switches to mode R when one is left; enemy_liberty_listener[warning] switches to mode L before
  the next attack (PRTS "进行第4次攻击前,切换至解放状态"). archetypes.js prisoner() counted on the 'attack'
  hook, after the damage, so the 4th attack still hit confined, and it sent no form.
- Now: prisoner() counts in `before` (an attack 麻痹 interrupts never gets there, PRTS 拳师囚犯), setForm
  'warning' (fx 'phase', drawn silently: kinds.js SILENT_PHASES) before attack times-1 and 'liberty' (fx
  'liberate') before attack times; 重犯's free-all and 杰斯顿's KO switch the freed ones too.
  render/units.js FORMS maps 'warning' / 'liberty' for the six skeletons (普通 / 老练囚犯 *2 / unnumbered,
  强壮囚犯 *2 / *3, 拳师囚犯 / 重犯 / 传奇重犯 *_orange / *_red). tools/assets/spine.mjs PREFAB_SPINE_ROLES gives
  普通囚犯 / 老练囚犯 their grey *3 set; data/assets.json regenerated (fetch-assets --offline --add-only, JSON
  compare: only those two anims and the hash), data/enemies.json too (build-data --offline: only their
  attackAnim.clip Attack -> Attack3, same length and strike frame). The 3D board draws the same Pixi views.
- Docs: ASSETS.md (PREFAB_SPINE_ROLES, the prisoner forms), SIM.md (the form fx), design/client.md (FORMS).
- Tests: test/content/feedback5-prisoners.test.js (the six: warning before attack 3, attack 4 hits with
  ATK +50 %, the forms reach the client and UnitInfo; free-all; 麻痹), test/render/feedback5-prisoners.test.js
  (manifest = the prefab's grey set, FORMS sets, view clips, PREFAB_SPINE_ROLES = the committed manifest) —
  both fail on the parent but the 麻痹 pin; test/render/feedback5-prisoners.browser.test.js (RENDER_E2E=1:
  three prisoners on the 2D and the 3D board, each model's set follows its sim form).
- Golden: 28 scenarios. Only the warning's new 'phase' fx (the prisoner fell before its 4th attack):
  roster-001, roster-003, roster-007, roster-024, roster-033, bond-miraShip-low. The 4th attack now hits
  freed, one attack earlier than before, so the fight after it moves: roster-004, roster-022, roster-026,
  bond-kazimierzShip-low, bond-raidShip-low, bond-soloShip-low, bond-victoriaShip-low, bond-visiShip-low,
  standin-01, diy-024, diy-061, diy-065, diy-066, diy-094, diy-097, diy-104, diy-105, diy-127; only the
  per-second snapshots besides the fx: roster-021, diy-017; and the bot matches whose battles field
  prisoners: solo-ABYSS-2, solo-HARD-9-boosted.
2026-10-06 21:57:51 +08:00
sganggs 4b059c9d8d feedback5: integration fixes after wave 1 + W5K + W5M — visuals for the 13 fx kinds the new 自选 kits emit (render/fx/kinds.js), 老鲤's Back skeleton (a 自选 pick's art) has a fall clip, the ISW-A kit tests follow W5K's roster rule (refused; another module passes); full unit pass 4265 with these five fixed, browser: render 21/21, mock e2e 32/32, standin / diy / i18n e2e 1/1 each 2026-10-06 00:56:52 +08:00
sganggs 4b57f8120c feedback5 WG: 补位 in the browser — the 干员持有 tab next to 干员调配 (the 53 NORMAL chess by tier, operator → stand-in, a switch each, 全部持有, export / import, localStorage + room.ownership through the shared sync engine), 「替补:X」 on shop / reward cards and own prep pieces, the stand-in's model on the board, its body on the detail card (own pieces, cards, any unit with standInFor), placement and ranges by the stand-in 2026-10-05 19:34:52 +08:00
sganggs c1b8292f92 feedback5 R5: split the battle effect system into modules
public/js/render/fx.js becomes a re-export barrel. Speeds, camera heights, fonts, the kind table and the shared tunables move verbatim into public/js/render/fx/*.js. FxSystem keeps its constructor, clear, update, counts and destroy; the other methods move verbatim into container classes installed on FxSystem.prototype in source order. simSpeeds and fontsReady each stay one instance. The dynamic import of /sim/constants.js stays next to setSimProjectileSpeeds.
2026-10-05 17:13:07 +08:00