fix: correct community-reported combat and strategy draft behavior

Guard lethal stuns against a replacement deployment; keep bard auras running
through stun; require an active Aegir bond for Clementia's strategy; allow
Compass SP to bypass recovery locks; and refresh Hidden Core gun mitigation
against current gun/spring companions. Set multiplayer strategy picks to 50s
and describe renderer fallback without diagnosing unsupported hardware.

Golden moves (full 285-scenario regeneration):
- roster-008: inactive Aegir no longer gains 18 strategy layers.
- boss-boss_4-solo: bard regeneration continues through stun.
- hidden-boss_9-pair: mitigation covers first hits/current companions.
- standin-07: hammer stun cannot follow an immediate revival deployment.
No ending-reason changes. Sources and report-by-report findings: DESIGN 28.25.
This commit is contained in:
sganggs committed 2026-10-10 00:45:41 +08:00
1 parent 77cd29f07a
commit 708caf7d06
37 files changed
+277 -103

No files matched your search

+2 -2
View File
@@ -80,7 +80,7 @@ legal from R14 into R15. The client mirrors it
| Timer (real s, × `opts.timerScale`) | Value |
|---|---|
| INFO_CHECK | `config.timers.infoCheck` 25 |
| band draft turn | `Match.BAND_TURN_SECONDS` 30 [ASSUMED] (= `timers.bandTurn`), the step's only countdown: `m.public.deadline` = the current turn's end, no step cap (`timers.bandDraft` 50 = the official whole step, informational) (co-op; solo / single human untimed) |
| band draft turn | `Match.BAND_TURN_SECONDS` 50 (owner official-play report, 2026-10-10) (= `timers.bandTurn`), the step's only countdown: `m.public.deadline` = the current turn's end, no step cap (`timers.bandDraft` 50 = the official whole step, informational) (co-op; solo / single human untimed) |
| BATTLE_CHECK | `battleCheck` 3 |
| 机变 first / other pickers | `spFirst` 30 / `spTurn` 16 (co-op; solo / single human untimed) |
| PREP | `modes[m].rounds[r].prepTime` (co-op; solo / single human untimed) |
@@ -98,7 +98,7 @@ band draft / 机变 / PREP deadline, and BATTLE_CHECK / ROUND_START / SETTLE run
`m.public.overtimeAt` = when the overtime drain starts, 150 real s; both on the field clock).
### 1.1 Band draft
Co-op: random order (all seats, bots included), one pick per turn, ONE countdown: `BAND_TURN_SECONDS` 30 s per turn,
Co-op: random order (all seats, bots included), one pick per turn, ONE countdown: `BAND_TURN_SECONDS` 50 s per turn,
published as `m.public.deadline` (= `draft.turnDeadline`; `draft.turnSeconds` its length) — no step cap; AI seats pick
at once. A turn that runs out takes the strategy the player highlights in the draft screen (`g.bandFocus {bandId?}`,
`Match.timeoutBand`) while it is allowed and no teammate holds it, else `bandDraft.timeoutBandId` 华法琳, else the first
+1 -1
View File
@@ -19,7 +19,7 @@
| 阶段 | 说明 |
|---|---|
| 确认本局信息 | 本局地图(标准模拟固定为「战场#01」;险境从 8 张地图中随机,绝境 / 终极从不含战场#01 的 7 张中随机)、敌方派系(三种特训敌人类型,如折射、飞行:和官方一样,每种占全局 15 个回合位中的 3 个,第 14 回合领袖战和第 15 回合隐秘核心也各占一个位,所以险境 / 绝境 / 终极第 1–13 回合中有 7–9 波是这三种类型、每种最多 3 波,其余各波是「特异」类型;每波只有一种类型)、**被禁用的盟约及其干员**、领袖预告。所有人确认后继续;同盟模拟最多 25 秒;只有你一名玩家时(独立模拟,或同盟模拟只带 AI 队友)不限时。 |
| 选择策略 | 40 名策略(分队长)决定**初始目标生命值(20–45)**和一条永久规则。同盟:随机顺序轮流选,**每人 30 秒**,右上角和「决策中」显示同一个倒计时;AI 队友立即选完;队友已选的不能重复,每人可**跳过一次**(排到最后);创建者可以在同盟等待室打开「**AI 队友最后选择**」(默认关闭):选择策略和机变轮选时所有博士都排在 AI 队友前面(博士之间、AI 之间仍是随机顺序,AI 托管或掉线的博士也算博士),跳过时排到其他还没选的博士之后、AI 之前(没有其他博士时排到最后);超时自动选你**当前选中**的策略(已被队友选走则选华法琳)。独立:自由选择、不限时;同盟模拟只有你一名玩家时也不限时。选的时候可以点左侧决策顺序下方的「查看禁用盟约与干员」,再看一遍「确认本局信息」里的盟约(置灰、禁用人数)和本局禁用干员:只能查看,倒计时照常走,底部也显示轮到谁和剩余秒数;点「关闭」、点窗口外面或按 Esc 关闭,轮到下一位时会自动关闭。 |
| 选择策略 | 40 名策略(分队长)决定**初始目标生命值(20–45)**和一条永久规则。同盟:随机顺序轮流选,**每人 50 秒**,右上角和「决策中」显示同一个倒计时;AI 队友立即选完;队友已选的不能重复,每人可**跳过一次**(排到最后);创建者可以在同盟等待室打开「**AI 队友最后选择**」(默认关闭):选择策略和机变轮选时所有博士都排在 AI 队友前面(博士之间、AI 之间仍是随机顺序,AI 托管或掉线的博士也算博士),跳过时排到其他还没选的博士之后、AI 之前(没有其他博士时排到最后);超时自动选你**当前选中**的策略(已被队友选走则选华法琳)。独立:自由选择、不限时;同盟模拟只有你一名玩家时也不限时。选的时候可以点左侧决策顺序下方的「查看禁用盟约与干员」,再看一遍「确认本局信息」里的盟约(置灰、禁用人数)和本局禁用干员:只能查看,倒计时照常走,底部也显示轮到谁和剩余秒数;点「关闭」、点窗口外面或按 Esc 关闭,轮到下一位时会自动关闭。 |
| 机变 | 部分回合开始前出现:同盟共 6 张卡轮流各取 1 张(随机顺序,开启「AI 队友最后选择」时博士先选;首位 30 秒,其余 16 秒;只有你一名玩家时不限时),独立 3 选 1。卡片包括装备、资金、干员、盟约层数、悬赏等;**悬赏决策**为你的作战添加悬赏敌人,卡上用蓝字标出持续多久:「下场作战」/「接下来两场作战」的只出现一场或两场,之后不再出现;官方的「多轮悬赏」(原文写「之后的每场作战」)在这里也按「接下来两场作战」处理,只出现两场(如教鞭的法术大师A2·多轮战术特训)。各回合的悬赏决策按官方对局截图来出:第 3 回合是 6 张「接下来两场作战」的悬赏(3 张 1 资金、2 张 2 资金、1 张 3 资金);第 9 回合是各首领的「下场作战」悬赏和「源石虫·特训」;绝境 / 终极的第 11 回合多半是悬赏决策(也可能是机密商店或战术决策),其中的悬赏通常有 1 只特异巨兽,其余是各阵营的「下场战斗」悬赏。击倒悬赏敌人的人(联防中的队友也算)获得资金;右侧效果栏会写「还剩 N 场作战」。**机密商店**的 6 件装备都免费,和官方一样可能出现两件相同的装备(各算一张卡,可以分别被选走);第 11 回合(绝境 / 终极)的机密商店按官方:2 件 VI 阶、至少 1 件 V 阶和 1 枚盟约之币,标准 / 险境较早回合的机密商店各阶装备都可能出现。**战术决策**也和官方一样可能出现两张相同的卡(官方截图里出现过两张「补给」;各算一张卡,可以分别被选走,每张只生效一次,两人各选一张全队卡则效果叠加);第 11 回合(绝境 / 终极)的战术决策按官方截图只出盟誓、驰援、列装 / 财富 / 补给 / 整备 / 升华等增益卡,不出削弱敌人的卡和战场演变卡。每张卡左上是图标和名称,下面写着完整效果(与详情卡相同的官方描述,手机上也显示);已被选走的卡变暗,右上角显示选走它的玩家头像(悬停可看名字)。选卡要**点两次**:第一次只选中(金框 +「确认选择 · 再次点击」),再点同一张或点右上的「确认选择」才生效;点别的卡换选,按 Esc 或点空白处取消。 |
| 休整期 | 购买、摆阵、配装备、冻结 / 刷新、升级调度中心;同盟有倒计时(65–215 秒,随回合增加);独立模拟、以及只有你一名玩家(只带 AI 队友)的同盟模拟不限时。所有人「准备就绪」即提前开战,全员就绪前可取消;点「准备就绪」时商店自动收起、棋盘放大到全场,取消准备时商店再展开(资金旁的「收起」和商店标签「展开商店」随时可以手动切换)。 |
- **特殊地形点一下就有说明**:战场上的**活性源石**、**沼泽**、**排气格栅**、**深水区**,以及**红门 / 蓝门 / 传送点**,点一下就会弹出它自己的说明卡——名称、机制,以及**这一关自己的数值**(比如战场#04 的活性源石:每秒 70 点真实伤害、攻击力 +20%、攻击速度 +20、持续 300 秒)。休整期和作战期都能点。普通地板 / 道路 / 高台点了不会弹东西,所以点一下仍然只是「取消选中、关掉卡片」。
+5 -3
View File
@@ -840,7 +840,7 @@ registration order. `battle.off(handle)` / `battle.off(name, fn)` / `battle.offO
| `tick` | `{ dt }` | end of every tick |
| `beforeAttack` | `{ attacker, targets, isSkill, profile }` | allies **and** enemies; replace/filter `ctx.targets` |
| `enemyAttackStart` | `{ enemy, targets }` | an enemy starts a normal attack (it has targets), **before** 麻痹 may interrupt it (ai.js enemyAttack; the client's ON_BEFORE_ABILITY_SPELL_ON): a burst a handler causes interrupts that very attack (酒神 堕梦, PRTS 备注 "触发的元素爆发可打断当次普攻"); a handler that kills or stuns the enemy ends it |
| `attack` | `{ attacker, targets, isSkill }` | an attack/heal was performed (projectiles may still be in flight) |
| `attack` | `{ attacker, targets, isSkill, targetDeployments? }` | an attack/heal was performed (projectiles may still be in flight). Normal enemy attacks provide a `Map<Unit, deploySeq>` captured before their damage; post-attack control effects must not cross a target redeployment. |
| `hit` | `{ source, target, dmg, credit }` | before mitigation; mutate `dmg` (not fired for gauge fills — see `elementHit`). `source` may be null (terrain; 无来源 `dmg.sourceless` bursts, whose `credit` names the unit credited) |
| `elementHit` | `{ source, target, dmg }` | before a gauge fill (`dmg.type === 'element'`); mutate `dmg.amount`/`dmg.mul`, set `dmg.cancel` |
| `damaged` | `{ source, target, amount, type, dmg, credit }` | after application (`amount` may be 0 when shielded); element fills too (with their source); 无来源: `source` null, `credit` set |
@@ -996,8 +996,10 @@ flag alters movement or 失衡.
attack speed paces it, and an SP refund that refills the bar at once (迅捷) no longer recasts it every tick (GitHub #298,
引星棘刺 S1; [ASSUMED] one attack interval: PRTS prints no 前后摇 for such casts). The cast is no attack: the unit's
attacks and heals keep their own rhythm, and its first cast comes as soon as it is ready (#124). `gainSp` is ignored while a duration/ammo/toggle skill
runs (its bar shows the skill), whatever the reason, and — any reason but `'init'` — while the unit has the `noSp`
flag (阻回: "停止并阻止任意形式的技力回复"; the operators' 凋亡 burst, §3).
runs (its bar shows the skill), and while the unit has `noSp` (阻回; the operators' 凋亡 burst, §3), except for
deployment initialization (`reason: 'init'`) and explicitly documented bypasses.
`gainSp(n, reason, silent, { ignoreLock: true })` bypasses both locks while retaining the source reason, charge cap
and `spGain` hook; used by 黄沙罗盘 (PRTS says all its SP ignores 阻回), including its caster's +3 SP.
- Kinds: `duration` (mods for `duration` s), `ammo` (mods until `ammo` attacks were made, optional duration cap),
`instant` (onStart + optional one-shot attack override applied to the next attack), `charges` (instant with charges),
`passive` (always on from deployment, no SP), `toggle` (stays on until death once activated).
+4
View File
@@ -121,3 +121,7 @@ sound. A selected mode with no mix uses its own default volume/probability, not
A model that arrives after an actual deployment continues Start at the elapsed game time; after the clip's duration it
shows the current base pose. A subsequent attack/death supersedes that pending entrance. No extra deployment sound
or per-phase animation schedule is added by this change.
The simplified-view notice describes a renderer load failure, rather than declaring the device incapable of 3D.
The same fallback covers import failure, timeout and WebGL initialization errors; a reload can retry.
It does not diagnose a particular user's GPU or persist a disabled renderer preference (§28.25).
+14
View File
@@ -202,3 +202,17 @@ the existing per-tick behavior. The optional flag defaults to false for compatib
0.2.3 echo/counter interaction (DESIGN §28.24): recursively earned “余音” pulses are drained FIFO by that echo in the
same call, retaining the earned attack value and the lethal-hit pulse. [ASSUMED] This local order avoids exhausting
the hook-depth guard on scaled hit-count HP; the guard remains unchanged for other recursive handlers.
### Community corrections (2026-10-10, §28.25)
- A normal enemy attack's post-hit status belongs to the target's deployment at the strike. If lethal damage
immediately redeploys the target (不屈), that old attack cannot stun the new deployment.
- Bard continuous regeneration, including 浊心斯卡蒂's replacement trait, continues through stun; leaving the field
stops refreshing its aura. Stun still prevents attacks and skill use.
- 黄沙罗盘 SP ignores both an active skill's recovery lock and `noSp`, including the caster and other 萨尔贡 recipients
of the 浓茶 combination. Other SP gifts retain their existing restrictions.
- 克莱门莎's 崇高牺牲 strategy requires 阿戈尔 to be active before a knock-out grants layers.
- 隐秘核心 铳 takes 20% physical/arts damage while another gun or spring remains. The condition is checked on each hit
as well as by its aura tick, including the first hit and immediately after the last companion leaves.
Sources and the feedback items requiring no simulation change are recorded in [§28.25](../history/0.2.3.md#2825-community-feedback-of-2026-10-10).
+1 -1
View File
@@ -7,7 +7,7 @@ Part of [DESIGN.md](../DESIGN.md) (the index; section numbers are global).
### 6.1 State machine (Match.js)
```
LOBBY(room) → INFO_CHECK (co-op 25 s; solo and any single-human match untimed (§18.2); all ready ⇒ skip; the operator loadout (§16) locks when it ends) → BAND_DRAFT (co-op: random order — the room option 「AI 队友最后选择」 (host, off by default; `room.setAiPicksLast`) puts every human seat before every AI seat, each group keeping the drawn order, and draws no extra random number; a skipping human goes behind the other humans still to pick and ahead of the AI seats, or to the very end when no other human remains [ASSUMED] —, ONE countdown — `BAND_TURN_SECONDS` 30 s per turn = m.public.deadline, AI seats pick at once, 1 skip each, a strategy a teammate already took is refused (队友已选), timeout ⇒ the strategy the player highlights (`g.bandFocus`) while free, else band_bldsk, else the first free one; solo: free pick, no timer, no skip; a single human: untimed) → BATTLE_CHECK (3 s)
LOBBY(room) → INFO_CHECK (co-op 25 s; solo and any single-human match untimed (§18.2); all ready ⇒ skip; the operator loadout (§16) locks when it ends) → BAND_DRAFT (co-op: random order — the room option 「AI 队友最后选择」 (host, off by default; `room.setAiPicksLast`) puts every human seat before every AI seat, each group keeping the drawn order, and draws no extra random number; a skipping human goes behind the other humans still to pick and ahead of the AI seats, or to the very end when no other human remains [ASSUMED] —, ONE countdown — `BAND_TURN_SECONDS` 50 s per turn = m.public.deadline, AI seats pick at once, 1 skip each, a strategy a teammate already took is refused (队友已选), timeout ⇒ the strategy the player highlights (`g.bandFocus`) while free, else band_bldsk, else the first free one; solo: free pick, no timer, no skip; a single human: untimed) → BATTLE_CHECK (3 s)
→ loop r = 1..lastRound:
ROUND_START (income, upgrade price −1 (floor 0), temp NOT wiped — what overflowed after the last prep's deadline is shown in this
prep (§6.2 temp overflow), unfrozen shop slots rerolled, frozen kept, <进入休整期时> effects)
+47
View File
@@ -348,3 +348,50 @@ and the queue clears. Both tests fail against the previous implementation. Toget
刺玫 healing suites, 273 tests pass. The benchmark now writes actual diagnostic messages beside nonzero error counts,
so failures cannot be mistaken for ordinary performance results. Recomputed golden and final benchmark results are
recorded with the candidate; do not reuse the earlier, erroneous benchmark as a clean result.
### 28.25 Community feedback of 2026-10-10
The current development candidate was checked against thirteen reports, including feedback explicitly describing
0.2.1. Sources: [PRTS mode strategies](https://prts.wiki/w/卫戍协议:盟约),
[alliance/item notes](https://prts.wiki/w/卫戍协议:盟约_下半/PRTS盟约记录),
[吟游者 branch notes](https://prts.wiki/w/分支特性信息/data),
[假想敌:铳](https://prts.wiki/w/假想敌:铳), the cached official enemy and activity tables, and the owner's supplied
克莱门莎 official showcase. The multiplayer 50-second setting is the owner's explicit official-play requirement.
| Report | Verified result / change |
|---|---|
| 1. Lethal hammer/sailor stun after 不屈 | Fixed. Enemy normal attacks snapshot target deployments before damage. The subsequent periodic stun cannot affect a replacement deployment created during that strike. A surviving target is still stunned normally. Covers both hammer variants (third strike) and both dock sailors (fourth strike). |
| 2. Opening strategy time | Multiplayer picks now have 50 seconds each, including skips; the header and per-turn deadline remain one clock. Solo and single-human matches remain untimed. Regenerated `config.json` from the builder. |
| 3. Fartooth + dollkeepers | Already fixed in §28.1. Existing actual Kazemaru and Specter alter swap/return tests pass, including active-bond gating, caps and repeated swaps. |
| 4. Gavial S2 pulls final boss | Not reproduced. Both tier-4 and tier-5 S2 implementations use the shared pull API, which rejects boss-pool leaders. New actual-S2 tests hit a final boss without moving it and additionally reject exaggerated pull force. |
| 5. Clementia strategy gains inactive Aegir | Fixed. PRTS explicitly requires activation; the former `requireActive: false` and its old test contradicted that note. An inactive bond now gains nothing; an active one gains the knocked-out member's tier, still disabled in unite/boss battles. This is the strategy, separate from the new playable operator. |
| 6. Pith/Aegir ATK in 0.2.1 | No confirmed current defect. Devoured ATK is `atkFinal`, added after an operator's own ATK percentages, then scaled by independent multipliers; existing numeric tests check this order. The report lacks the full lineup, skill/equipment state and exact unrounded stats, so 5340 versus “about 6040” alone cannot establish a discrepancy. |
| 7. Stunned bards stop regeneration | Fixed for the default trait and Skadi alter's custom continuous trait. Aura refresh requires being on-field, not being able to act. Stun still blocks attacks/skill use, and leaving stops the aura. |
| 8. Stationary redeployment loses Raid | Current code grants the ATK/HP bonus to the deployment made by Raid's relocation. Ordinary redeployment clears it; the existing passive-skill revive tests do jump promptly when their conditions hold. PRTS's “期间” does not settle whether an ordinary stationary redeploy should retain it. Preserve this rule pending an official comparison of that exact case. |
| 9. Gun boss “90% reduction absent” | The official value is damage ×0.2 (80% reduction), already implemented. Fixed an actual coverage gap: PRTS includes another gun as well as springs in the condition. Also refresh on hit so the first hit and immediate companion removal cannot see an outdated aura. |
| 10. Compass/tea +3 bypasses SP lock | Fixed. PRTS says all 黄沙罗盘 SP bypasses 阻回. A documented `ignoreLock` option permits the first-end refund and combo gift during `noSp` or a running skill, including the caster. Ordinary SP gifts still obey both locks. |
| 11. Dobermann whip random bounty | Already implemented as a private three-choice selection (§27). Existing choice and reconnect tests pass. A timer/bot can still resolve an unanswered choice automatically. |
| 12. Lemuen ammo does not gain layers | Not reproduced with real S3 consumption, normal and elite. Each ten bullets grants +2/+4 to each active named bond when at least three own operators share the row. Two actual casts cross that threshold and gain the expected layers. The existing garrison tests also cover fewer than three in the row. |
| 13. Sudden simplified view | The message is emitted for any renderer startup failure, including import timeout, not exclusively unsupported hardware. Reworded it to describe the failure and offer reload. The prior mount-cancellation/late-disposal fix remains; the report alone does not identify this user's browser failure. No forced persistent 2D preference is written. |
The new same-strike revival, bard and SP-lock regressions fail seven checks against the pre-change simulation and
pass after these fixes. The additional band and boss tests exercise inactive activation and same-tick reduction.
The validation record accompanying the candidate lists full CI, browser recovery and golden results.
The official showcase was reviewed in talent/S1, S2 and S3 segments. S2 shows a moving cabin then a stationary vortex,
including the second battlefield demonstration. S3's repeated bombardments agree with the documented three-hit,
one-second pulse interval. Crownslayer's supporting skill and smoke are visible in the later S3 segment and are not
attributed to Clementia. Edited footage does not settle the absolute first-bomb offset, S2 splash radius, or all exile
status rules; the existing marked assumptions remain. No visual resemblance is used as proof of extra immunity.
Full golden regeneration covers all 285 scenarios. Four digests intentionally move relative to the preceding candidate:
- `roster-008`: 崇高牺牲 no longer grants 18 阿戈尔 layers while inactive; combat damage and kills are unchanged.
- `boss-boss_4-solo`: the bard's regeneration continues during stun, changing healing, subsequent attacks and snapshots.
- `hidden-boss_9-pair`: 铳's reduction is checked for the first hit/current companions; boss HP left changes
2,992,115 → 2,992,511.
- `standin-07`: hammer stuns no longer cross the immediate revival deployment provided by M3茧甲; kills 9 → 10,
counted leaks 71 → 70, with corresponding combat/RNG/snapshot differences.
No scenario's ending reason changes. The bonds, matches and DIY families are byte-identical to the preceding golden
files. The 50-second setting and fallback-message change do not alter battle rules in those digests.