Commit Graph
21 Commits
Author SHA1 Message Date
sganggs 221e6b8dd2 0.2.5-dev: community round 30 and follow-ups
- Stock: fixed trait gifts (缪尔赛思 / 变形者集群 变形同构体, 耶拉 不融冰, 蜜蜡 / 卡涅利安 迅捷作战粮, 诗怀雅 盟约之币) still occupy stock but are granted past the cap; an operator card already shown in the shop or a reward can be taken after the pool runs out and overdraws (GitHub #498, the owner's decision); item buys and item rewards keep the stock check. 洛洛 / 焰尾 sub-pools use the measured weights (PR #497 by @2321Robin; the occupancy idea of PR #496 by @2321Robin re-implemented differently).
- Boss pairs are drawn at random once per match and fixed to battle start; the Hidden Core reuses them; a leaver does not split a full pair (the owner's decision).
- 阿戈尔 in 联防 no longer re-applies the opening devour HP loss or a false revive; Touch's team medic stays for the match after its holder leaves (owner-approved, official lifetime unverified).
- Auto-skill ranges: 司霆惊蛰 S2, 斩业星熊 S3 against air, 予愿安洁莉娜 S3; 自在's post-rebirth invulnerability is also untargetable (#510); Horn / Clementia / catapult / 忍冬 first hit (PR #502 by @Xinglan233); 不融冰 / tear gas trigger on real damage.
- Bond layer-up sound in round start / draft / prep / battle (#482): one channel, a new cue replaces the old, no extra cooldown; a prep update that adds layers and activates a bond plays one cue.
- Client: multi-swing fix (#506), refresh single-flight (PR #507 by @robll-v1), LP tower keeps the settled value with a −N tick (PR #504 by @robll-v1), export with only 潜能 / 练度 changes (PR #503 by @Xinglan233), spectator rosters list DIY members (PR #505 by @Xinglan233), banned members beside bond tooltips (PR #494 by @YuriRestia), recovery action above the away overlay (PR #511 by @RainoutOvO), the /dev/sim-check.html consistency page (PR #492 by @Cloudnyco), Korean (PR #490 by @D-Roote) and English Victoria wording (PR #499 by @YuriRestia).
- golden: 45 of 287 scenarios move against 0.2.4 (roster 17, bonds 3, fields 6, matches 17, standins 2), each attributed in docs/history/0.2.5.md §30.9 / §30.16.
2026-10-12 14:07:08 +08:00
sganggs 2fdc565c7c Reuse held Spine poses and redeploy countdown textures (#434) 2026-10-09 17:14:50 +08:00
sganggs 52f56319ac feedback7: merge fb7-gh-sim — PR #348 (take-the-highest chains), PR #293 (REA-Y in the engine), #329 ports (异客 13 tiles, 歌蕾蒂娅 net radius 1, 搅拌机 latest first, 大帝 uncapped), PR #365 (骨刺 forms + PRTS targeting), #298 (instant non-attack skills recast at most once per attack interval, attacks untouched), #364 (先兆者 shell 3×3), #220 (速射手 air first), 余 skips noStack bonds (owner)
- Conflict: docs/PLAYING.md 技能自动释放 bullet — both insertions kept (the 铁钳号 rule from fb7-owner-sim, the #298
  pacing sentence).
- Grok review: MERGE AFTER FIXES — the HIGH #298 finding (the cast replaced the due attack) fixed on the branch
  (db29acf9: per-skill nextCastAt; golden of #298 alone shrank from 84 scenarios to 2).
- Golden union: 4 matches differ from HEAD though the branch alone left them (coop2-NORMAL-3, coop4-ABYSS-7,
  coop2-NORMAL-8-serverrun, solo-HARD-9-boosted): HEAD's side had moved all four (#333's shop RNG …) and on those new
  bot paths the merged rules apply — the diffs are in-battle layer gains / damage (卡西米尔 50 → 45, 精准 80 → 76,
  叙拉古 176 → 168, kills ±2, solo-HARD-9 LP 397 → 399), no outcome change.
- Broad node --test 5571 (5570 pass, 0 fail, 1 skipped); lint 0 errors; typecheck.
2026-10-08 21:27:04 +08:00
Sukvii bfef34ffa3 feedback7 R22-GHSIM: 假想敌:骨刺 changes model with its 隐匿 at once — the three-headed snake (*_A) while hidden, its *_B set when blocked or revealed, back to *_A when hidden again (GitHub #296, PR #365 by @Sukvii, render part); golden: unchanged
The contributor's code (render/spine.js syncFormPose, the render/units.js wiring and FORMS entry, the headless
test/render/forms.test.js block), applied from PR #365, so they are the author of this commit. Maintainer side: the
hard-coded Spine id became a STEALTH_FORMS table (form while the stealth bit is off), comments and docs/ASSETS.md
reworded. Not ported: the PR's sim targeting rewrite (content/enemies/invisible.js), its enemies_bosses tests, its
roster.json and the Chrome suite (forms.browser.test.js, not run here).

Seen (#296, FrogThai): a blocked 骨刺 kept the snake. The sim already sends UF.STEALTH only while its 隐匿 is effective
(not blocked, not revealed — targeting.js enemyStealthed); the view now keys the FORMS 'revealed' clip set (Idle_B /
Move_B / Die_B / Attack_B, all in the skeleton) off that bit in UnitView.sync — before a DIE of the same snapshot — and
re-poses at once: a running attack continues in the other attack clip at the same point relative to its strike frame
(Attack_A hit 0.533 s, Attack_B 0.733 s; a pending wind-up still strikes on time), a stun / idle restarts on the new set
without a crossfade, and a frozen skeleton is posed with update(0); a model loaded later is posed the same way.
Golden: unchanged (render only).
2026-10-08 19:23:49 +08:00
sganggs 6326dd4d0b feedback7 R22-RENDER: an attack seen late plays its whole clip from the wind-up when the rhythm leaves room for it — 重犯's iron ball lifts before the slam (#246 by @TsangAsuna, accepted by the owner); golden: unchanged
SpineActor.attack() starts an attack that was not wound up (no look-ahead: a batch that arrived late) on its strike
frame — right for a quick rhythm, but for a slow clip-per-attack enemy the wind-up was cut out: 重犯 (Attack_grey
2.333 s, strike at 1.0 s, attacks every 3 s) showed the slam without the ball ever rising, and only 1.33 s of the clip.
The owner's decision of 2026-10-07 on #246: re-implement on the current spine.js so that, when the attack interval
leaves room for the whole clip, it plays once completely from the start. A clip-per-attack actor (enemies) with
interval ≥ the clip now plays it from 0 at its own speed for the whole clip, the strike landing a little late; a
quicker rhythm keeps the strike-frame start, and operators' looping attacks are unchanged (the PR's condition had it
the other way round: it changed the looping attacks and left out the clip-per-attack enemies it was written for).

Tests: test/render/feedback2-enemy-attack-clip.test.js (+1: 重犯 plays the whole clip from its wind-up, a quicker rhythm
and an operator start on the strike frame) 5/5; render eyemask, unitview, texas skill clip, skill idle 51/51.
2026-10-08 19:20:55 +08:00
sganggs 1e78648ad4 feedback7 R22-RENDER: closed eyes stay closed without the stencil masks — the eyelid clips' covered slots hide when their centre leaves the clip polygon (GitHub #177, re-implemented from PR #384 by @Convey123); golden: unchanged
The eyelids of 佩佩, 仇白, 隐德来希, 琳琅诗怀雅 and other models are Spine clipping attachments: the polygon is the eye's
opening and the eyeball / eye-white meshes drawn after it are clipped to it, so a blink or a knock-down closes the eye
through the mask. render/app.js pickClipping keeps the masks only for a lone clipped skeleton at high quality, so in a
battle the eyeballs showed through the closed lids. SpineActor._eyeMaskFallback now runs after each update while the
masks are off: it walks the draw order like pixi-spine (from a slot whose attachment in force is a clip, to its
endSlot — any skin) and hides the slot container of a covered slot whose drawn centre (a mesh's mean vertex, a region's
quad centre) lies outside the clip polygon [ASSUMED: all or nothing per slot]; turning the masks on shows them again.

PR #384's version hid `slot.currentSprite`, which pixi-spine leaves null on a mesh slot — every covered slot of the
417 local operator skeletons' 73 clipped ones is a mesh (313) or a region (54; regions have no worldVerticesLength, so
it never measured them) — and its test stubbed a currentSprite onto every slot, so nothing was hidden in the game. Kept
from it: the diagnosis, the ray-casting pointInPolygon and the key-frame expectations.

Tests: test/render/eyemask.test.js (new, 7, on real runtime objects — the official skeletons in @pixi-spine/runtime-3.8's
real Spine, @pixi/core display objects with a 16 px canvas stand-in, the real SpineActor: the eyeballs are meshes in
the clip's container; 佩佩 / 仇白 Die and 隐德来希 / 琳琅诗怀雅 Idle hide exactly the eye slots in the closed frames and
nothing open; a 30 Hz sweep of six clips; masks on hide nothing, turning them on shows all) 7/7 — the five skeleton tests
skip without public/assets (not committed; npm run assets), and fail on PR #384's code; render unitview, enemy attack
clips, texas skill clip 45/45.
2026-10-08 19:18:01 +08:00
sganggs 76a2db7dd0 feedback6 R21F: enemy animation states, the client part of PR #275 by @xcdoge re-implemented — the resolver gives an enemy every numbered skill clip (anims.skills; the caller's first index stays the primary, operators unchanged, 宴's PREFAB_SPINE_ROLES fix kept), the stun spellings Stun_1 and Dizzy_Begin/Loop/End, a separate run role (Run_Begin/Loop/End); the renderer walks an enemy faster than moveSpeed 1 on its Run cycle (猎狗pro, 深池侦察犬 ×2; [ASSUMED] threshold), swaps an enemy's skill clip on a cast event (UnitView.setSkillSlot; a form in force is kept), and plays the 重生 of 巨大的丑东西 (Revive, then the fleeing 大祭司 Idle_2 / Move_2 / Stun_2) and 自在 (Revive_01); data/assets.json regenerated offline: 18 enemies gain anims.skills, 6 anims.run, 3 a stun clip (巨大的丑东西, 斩胄之剑, 破胄之锤), nothing else; the sim's cast slot (a new event) is not part of it; golden: unchanged 2026-10-07 17:59:11 +08:00
xcdoge 64715116ba A skill clip with no Begin and no Idle plays once at its own length: 德克萨斯 S2 剑雨 and the other instant skills of that shape (#160)
Deploy-time passives without a duration send the same 0.5 s skill window, so 琳琅诗怀雅's passives play their clip too. Contributed by @xcdoge.
2026-10-05 22:36:43 +08:00
sganggs 819a5ad4ea feedback3 WI: 乌尔比安 S3 【移动】 and 【返回】 are free redeploys, and the return clears his SP 2026-10-04 20:33:29 +08:00
sganggs 5a8c271d19 feedback3 WD: a skill with its own idle clip stands in it between attacks, its loop only on attacks (community report #23, 折桠 S2) 2026-10-04 17:14:12 +08:00
sganggs 68da23e8ed feedback2 WK: enemies play their attack clip once per attack at its own speed, then their Move clip (no stretching over the attack interval; GitHub #58) 2026-10-04 02:49:33 +08:00
sganggs 0ac7dc7dd2 feedback2: merge WI — 归溟幽灵鲨's 替身 is drawn (form + status icon), makes no attack and casts nothing, S2's end switches her (GitHub #44) 2026-10-04 00:13:31 +08:00
sganggs d2d1c46364 feedback2: WA review wording — DESIGN §22.1 says only the model choice is unchanged for enemies and summons, the held idle frame is an [ASSUMED] look, the knocked-down pose keeps a Back skeleton's own Die clip 2026-10-03 23:31:03 +08:00
sganggs ff294b8e40 feedback2 WI: the client draws a dollkeeper's 替身 on its *_B clips (归溟幽灵鲨 Start_B / Idle_B / Die_B / Die_B_2, back on Start_2; 风丸 too) with a 替身 status icon; a form ends in the unit's own skill clips (issue #44) 2026-10-03 23:29:48 +08:00
sganggs 072e1231ae feedback2 WA: a knocked-out operator facing UP falls and lies with its Front model, the Back model holds still meanwhile (GitHub issue #25)
131 of the 135 Back skeletons have no Die clip, so SpineActor.die() changed nothing and the
attack / skill / idle loop went on under the redeploy ring. UnitView._wantsBack() now wants the
Back model only while the unit stands (or when its Back skeleton has a Die clip of its own);
die() / revive() mark the view and its update swaps the model in place after the frame's events
(a death and a redeploy in one frame load nothing). The Front model replays the fall (held end
for a unit already down), gets the knocked-down grey, and the redeploy brings the Back model back
with the deploy clip carried over. A skeleton without a Die clip holds its idle's first frame.
2026-10-03 22:58:19 +08:00
sganggs 4b15919185 feedback1 integrate: WN 灼热/炽焰源石虫 models (local overlay, tinted alias); 暴鸰 bomb drop
# Conflicts:
#	docs/SIM.md
#	public/js/render/app.js
#	public/js/render/spine.js
#	public/js/render/units.js
#	server/sim/content/enemies.js
#	server/sim/snapshot.js
2026-10-03 06:45:59 +08:00
sganggs 901d5b9613 feedback1d WN: 暴鸰 drops its bomb as a projectile and flies on without it (D4)
The drone triggered its one bomb, but the damage and the blast landed in the trigger tick
while the model kept the bomb hanging under it for good. Official (PRTS 暴鸰; the client's
battle prefab enemy_1040_bombd and projectile_bombd): the cast plays the Attack clip, the bomb
leaves on its OnAttack event (0.267 s), flies to the target at 5 tiles/s and explodes on it
and the 8 tiles around; the drone switches to its bomb-less clips and speeds up.

Sim (kitBombd): release after BOMBD_RELEASE with an 'atk' event of kind 'droneBomb' and fx
'phase' {kind: 'bombed'}, a homing projectile (PROJECTILE_SPEEDS.droneBomb 5) whose arrival
deals the damage, then the speed buff. Render: FORMS.enemy_1040_bombd.bombed (*_2 clips),
PROJ.droneBomb (a falling shell), a one-off cast plays the attack clip once at its own
speed instead of the drone's 5 s attack rhythm, no puff for the silent mode change.
2026-10-03 04:21:19 +08:00
sganggs 5c23eeb804 feedback1 WD: forms reach late views, stable enemy shapes, review fixes
- Every form change goes through content setForm(): the unit keeps it (e.form)
  and UnitInfo publishes it, so a view built mid-battle from fieldMeta (a
  watched teammate's field, 联防 observers, a reconnect) starts in the
  current form instead of the first-form model.
- Enemy profile (dmgType) and Unit moving / form are initialised at spawn:
  one object shape for the sim's hot loop (the boss-field bench is back at
  the base speed).
- 转译基底·α: an HP loss cannot knock out its original form (no death clip).
- 假想敌:再生: 1 s 重生 and walking 傀儡 cited from PRTS; shields within 1.8
  as the 再生状态 begins.
- Renderer: a 重生's closing clip (and the ember's stand-up clip) is timed
  from the fx dur to end with it, so the next form attacks on its own clips.
- Docs: ASSETS FORMS list, SIM form fx, PLAYING 隐匿 wording.
2026-10-03 03:02:46 +08:00
sganggs 06be81f67e feedback1 WD: a form change clip plays out; browser check of the forms
- render/spine.js: no attack (wind-up or 'atk') cuts a form's change clip short;
  a knocked-out 逐火 no longer reports its last attack in the snapshot.
- test/render/feedback1-forms.browser.test.js (opt-in RENDER_E2E=1): the real
  sim in headless Chrome on 战场#01 — 转译基底·α A_* → A_Die_B → B_* → B_Die,
  a 深池逐火战士 knocked out in front of its blocker: Die → the 隐匿 ember on
  Idle_2, beaten → Die_2.
- PLAYING.md: the 余烬 and 转译基底 rules for players.
2026-10-03 02:07:59 +08:00
sganggs 15291c2293 Playtest #5 fixes: hovering enemies, target order, blocking hand-over, 联防 knocked-out, elements, huge-boss hit area, maps, gear icon, phone HUD, 至简 price
- #1 近地悬浮 enemies count as air units (Unit.isFlying): ground-only attacks, splash, terrain and traps skip them;
  PRTS 不可对空 skill effects made ground-only; 掠海漂移体 / 吉兆飞鳞 drop modes; the bot plans them as air
- #2 an operator knocked out before 联防 is fielded and force-exited (PRTS 强制退场): it lies on its tile with the
  redeploy ring and redeploys (full timer [ASSUMED]); partners, observers and the server fallback included
- #3 element audit of every operator, item and enemy: 海嗣 numbers are official; bursts are 无来源, 元素脆弱 only
  raises 元素伤害, 元素抗性 applied, 盟约·辅助干员 fills all three gauges, 菲莱 / 哈洛德 / 纯烬 / enemy kits fixed
- #4 blocking by the official contact radius (0.7071): another operator in contact takes over at once when the
  blocker dies, withdraws or is stunned; melee blockers attack what they block
- #5 enemy target order per PRTS 索敌: blocker, special priority, taunt, last deployed; initial deploy 从上到下>从左到右,
  operators before summons; special priorities break ties by taunt then deploy order
- #6 act2 m01's normal-field blower machines (row 13) are drawn in the normal / 联防 views
- #7 Final Assault prep legality reads the player's half of the boss field (fence tiles deployable); all 11 stages
  audited against the official level files
- #8 regular settings gear; #9 the prep camera keeps the bench and temp rows clear of the shop bar on phones
- #10 huge bosses have the official 4.95 × 2.95 hit area (sim/body.js) and are 自缚 / unblockable
- #11 至简 costs 1: 购买价格为N's bb.price is a discount off the tier price, applied before other price effects
- DESIGN §19 and the normative §3 / §5 / §6 / §7 lines, SIM / META / DATA / PLAYING updated; 2595 unit tests and
  every browser suite green; dev recordings regenerated
2026-09-30 19:12:36 +08:00
sganggs 01a44cd288 卫戍协议:盟约 web remake — initial import
Online co-op browser remake of Arknights' Stronghold Protocol: Alliance
(client-simulated combat, official waves/bonds/items/strategies, 3D board,
facing wheel, operator loadout, official emotes, deployment scripts).
2026-09-29 16:21:31 +08:00