PRTS 术语释义 寒冷 「友方寒冷始终需要两两一对产生友方冻结,持续时间取双方之中最高」, 异常效果 COLD 「在特定条件下转变为冻结」:
applyStatus kept the older cold on for as long as the freeze, so every later cold froze again; the wind (every 25 s,
20 + 0.1 x layers s of cold) froze an enemy anywhere for the rest of the battle once its cold outlasted 25 s, never
below. Now the pair turns into the freeze (max of the two, as before) and leaves no cold on an enemy; a cold on an
operator (敌方寒冷) keeps the old rule. The wind alone now freezes 20 + 0.1 x L s of every 50 s from 51 layers (all of
it from 300). Tests: test/sim/feedback5-kjerag-cold.test.js (fails on the parent); feedback3-cold-freeze and 灵知 S2
(kits_t4) updated to the pairing. Docs: SIM.md cold row, design/engine.md.
Golden: every scenario where a second cold met an enemy still cold (灵知, 初雪, 雪猎, 耶拉, 圣聆初雪, 凛御银灰, items,
the 谢拉格 wind) — the pair no longer leaves a cold: roster-005 / 009 / 010 / 012 / 014 / 015 / 016 / 018 / 026 / 029 /
031 / 036 / 040 / 042 / 046 / 047 / 049; bond-egirShip-high, bond-indomShip-low, bond-kjeragShip-high,
bond-maniShip-high, bond-raidShip-low, bond-steadShip-high, bond-suntShip-low; boss-boss_2-pair / boss_3-pair /
boss_4-pair / boss_6-pair, hidden-boss_8-pair / boss_10-pair; matches solo-HARD-1, solo-ABYSS-1, coop3-ABYSS-5,
coop4-FUNNY-6, coop4-ABYSS-7.
- Reproduced (scratchpad scripts): on its own field a bounty enemy the 活性源石 alone burns to death pays its
owner — on this tree and on v0.1.4 (all 96 walking kill-bounty enemies, 战场#04, no operator: 0 unpaid). The
loss is in 联防: a leaked bounty enemy re-enters with `bounty.ownerPlayerId` = the leaker (unite.js
planUnite), who has no per-player entry in that battle. A death without an operator killer fell back to that
owner, and Battle.addCoins dropped the coins. Until 0.1.3 the 联防 field was the round's map, so 战场#04's
活性源石 burned leaked bounty enemies for nothing — the report; since then the 联防 maps have no terrain, but a
无来源 tick, the enemy's own drain or another enemy's hit still paid nobody.
- Official: PRTS 卫戍协议:盟约 决策 "该敌人于对应玩家所属区域倒下时,使相应玩家获得额外资金"; the bounty pays whenever the
body dies (the owner's decision, relayed 2026-10-06; 0.1.1 "paid once, at the final death"). No PRTS exception
for 环境伤害.
- Now: Battle._bountyPayee (battle/economy.js): an operator or summon of a player in the battle that dealt the
blow pays its player (as before, 联防 helpers included); any other death pays the card's owner when that player
fights there (own field, Final Assault / Hidden Core — unchanged), else the player whose half of the field the
enemy fell on (Battle._ownerForTile) [ASSUMED for 联防: no source names the payee of a death nobody caused there].
- Docs: SIM.md §1.2, META.md SETTLE, PLAYING.md (联防 rules), unite.js header.
- Tests: test/sim/feedback5-bounty-payee.test.js — the 联防 case (one helper; two helpers by half; killed by
nobody, 无来源 terrain damage, another enemy, its own HP loss) fails on the parent; pinned: the own-field
活性源石 death, a helper's operator on the other half, a pair boss field. Golden unchanged.
Ported by hand from PR #209 by @qingjingshenghuo (its one-line data/config.json was not taken):
- server/match/gamedata.js bossPoolShareOf (used by GameData.bossPoolShare and by finalAssault.bossPoolHp for a plain
game-data object): solo × `solo` (1); co-op with `perPlayer` true × `coop` (1) × the players alive at the boss
round's start (bots and AI 托管 seats count, eliminated / departed seats do not; at most aliveFull 4; a count left
out = a full team). The fixed pool stays restorable through config: bossHpScale perPlayer false + solo 0.25 (and its
optional aliveScaling).
- tools/build-data.mjs: the global bossHpScale carries the rule (perPlayer true, solo 1); the modes' entries keep only
bloodPointKey / unaffectedByEnemyScale. data/config.json regenerated offline — JSON compare: only bossHpScale (global
and the 9 mode entries) changed.
- The problem #209 documented: a 胄 drone death is 2 % of the pool and 限伤 cancels a hit of ceil ≥ 300000, so the
hidden 胄 终极 pool at 3 / 4 players (21.6M / 28.8M) would cancel every drone (432000 / 576000). The drone link is
a share of the pool, no hit: Battle.loseHp takes noHitLimit and the link passes the limit [ASSUMED: the official
client checks every damage modifier and PRTS calls it 真实伤害, but which max HP it reads is undocumented]; a part's
传递 and every hit stay under the limit.
Golden (regenerated; why: the pool size):
- fields: boss-boss_1..7-pair/-solo and hidden-boss_8..10-pair/-solo (all 20 boss / hidden scenarios) — a pair
field's pool × 2 (two players), a solo template's × 4 (solo × 1, was × 0.25); boss-boss_1-pair, boss-boss_1-solo,
boss-boss_3-pair, boss-boss_3-solo, boss-boss_5-solo, boss-boss_7-pair and hidden-boss_9-solo now end at the
200 s cap instead of clearing; the two 联防 scenarios are unchanged.
- matches: solo-FUNNY-2, solo-NORMAL-1, solo-HARD-1, solo-HARD-2 now lose the Final Assault (solo leaders have 4× the
HP: team LP 0 with 93088–176395 of the pool left); solo-FUNNY-1, solo-NORMAL-2, solo-HARD-9-boosted (its Hidden Core
too), coop2-NORMAL-3, coop4-FUNNY-6, coop2-ABYSS-10-boosted, coop2-NORMAL-70-diy still win with more leader damage
(pool × players alive; solo-FUNNY-1 / solo-HARD-9-boosted end with 6 / 1 team LP less). Unchanged:
coop2-NORMAL-8-serverrun and coop2-NORMAL-14-standins (one player left at R14: × 1 as before) and the matches that
end before R14; roster / bonds / standins / diy unchanged.
Tests: test/match/boss-hp-scaling.test.js (from PR #209, adapted — every leader and difficulty × 1–4 players and solo;
R14 / R15 leave out two departed players; AI 托管 and bots count, an eliminated player does not; config restores the
fixed pool, the opposite of the PR's test; the plain-object fallback agrees; only the leader's HP scales);
test/content/enemies_bosses.test.js (hidden 胄 终极 at 3 / 4 players: the drone share lands, a hit of the same size is
cancelled — fails without the change). Updated on purpose: finalAssault, balance, bosshp, connection, docs-consistency
(the §20.9 record points to §25.13.4; the data carries perPlayer true), sim/playtest6_limits (the drone share lands
past the line), match/playtest6-bosspool (the 5 % knob halved to keep the 2-player pool's size: that test is about the
pool's arithmetic). Docs: PLAYING §7, DATA, META, BALANCE, SIM, design engine.md / network.md, the §20.9 / §20.10
records, research 00 / 01 / 08, the code comments, DESIGN §25.13.4 and the §25.10 table.
New on feedback4 since the last merge: W4D (bbe59b9, merged as 7ee815e) and the 0.1.4 version commit (30e7ace).
feedback5 keeps its own package.json / package-lock.json / APP_VERSION / README / DEPLOY version lines (0.2.0 sets
its own version later) and takes feedback4's CHANGELOG 0.1.4 entry, with W4D's line in it.
- Port (PRTS 异常效果 SLEEPING 沉睡 = 无法行动+无敌+不可阻挡; GitHub #140; the owner's decision of 2026-10-06):
`_checkBlock` refuses `flags.sleep` (battle/blocking.js) and `applyStatus` releases an enemy that falls asleep
(battle/status.js). Battle.js stays feedback5's façade, and tier3.js stays deleted (the 瑕光 comment is in her kits/ops
file). ai.js: WE1 (89f730d) cuts a swing before enemyAttack on a stun / freeze / sleep. The cannot-act branch is still
there, and a plain-buff `flags.sleep` still makes the enemy `stun` (units.js), so the plain-buff release stays in that
branch, after the cut, with its comment rewritten for the new order.
- New on feedback5: 酒神's 迷狂牢笼 (kits/ops/op-phatm2.js cageBlock, O22) duplicated the old three-flag 不可阻挡 check.
It now skips a sleeper too. No golden scenario spawns a 牢笼 over a sleeper: the corpus is identical with that line
reverted. 予愿安洁莉娜's S3 helper is unchanged, since canTargetEnemy already drops sleepers.
- Readers that follow without code: blockedTargets (blocked-first targeting, the DEFAULT trigger, hitAllBlocked), the 要塞
branch of acquireTargets (u.blocking), “庞贝”'s clock (blockedBy), the snapshot's UF.BLOCKED and the client's block
marker (render/units.js). 死芒 S2 折朽 (自选) lets go a linked enemy that her 悲叹的仆役 held.
- Docs: DESIGN §24.9, its §24 intro entry, the §5.5 Blocking sentence (on feedback5's 阻挡半径倍率 text) and §22.8's
"(since §24.9)", all as on feedback4; SIM.md as on feedback4 (the plain-buff sentence merged with feedback5's
noNewBlock / undying text).
- Golden: a probe (counting successful sleeps on a blocked enemy, plain-buff sleeps and 牢笼 spawns over sleepers) ran
over all 283 scenarios. Every scenario that moved sleeps blocked enemies; the counts are in brackets:
roster-003 (小满 S2 [5]: same fight, blocked 27 → 29, snapshot hashes); roster-005 (elite 小满 S2 [3]: the 140 s
timeout with 83 kills and 1 leak, where it used to clear at 135.43 s with 84); roster-013 (缇缇 S3 [11]: same kills,
blocked 22 → 33); roster-032 (缇缇 S1 [10]: 71 kills instead of 68, 8 leaks instead of 11, 4 knock-outs instead of 8,
萨尔贡 layers 41 → 35); roster-038 (elite 缇缇 S2 [1]: ends at 197.40 s instead of 197.27 s); roster-039 (瑕光 S2
normal + elite [31 + 12]: same kills and counted leaks, the 窃贼 gets away, blocked 53 → 87); roster-042 (缇缇 S2 [3]:
ends at 168.77 s instead of 166.93 s); bond-maniShip-high (小满 [1]: blocked 29 → 30, snapshot hashes); solo-FUNNY-1
(ai_0's 缇缇 [3]: only ai_0's damage dealt); coop4-FUNNY-6 (ai_0's 缇缇 [15 + 56]: from round 9 ai_0's 精准 / 萨尔贡
layers and boss damage move, ai_1 loses no LP from round 11, team LP 124 → 130); coop4-ABYSS-7 (ai_2's 小满 [18]: ai_2
one kill fewer, ai_0 one more LP lost in round 9); coop2-NORMAL-8-serverrun (ai_1's 缇缇 [83]: only ai_1's damage dealt;
WE1 had already turned this match into a loss); coop2-NORMAL-70-diy (the 自选 seat h_0's 缇缇 [171], ai_0's 缇缇 [74]
and 小满 [19 + 21]: h_0's layers move from round 4, then its AI 托管 buys differently (boards from round 7); ai_0 246
kills instead of 233, same end); diy-131 (死芒 S2 at tiers 5 and 6 [1 + 1]: snapshot hashes only); diy-132 (elite
死芒 S2 [2]: ends at 199.50 s instead of 198.13 s, same kills). One scenario sleeps a blocked enemy and did not move:
coop2-HARD-4 [1]. ai_1's 小满 lets go the enemy it holds; another enemy takes the slot; the sleeper wakes with no room
and is blocked further on by 2_16_a. The match digest has no snapshot hashes, and its kills, leaks, damage and funds
are identical. fields and standins did not move. Most outcomes differ from feedback4's list because feedback5's
baselines differ (WE1's damage frame, etc.).
- Tests: test/sim/feedback4-sleep-unblock.test.js (from feedback4) passes 5/5 on the split layout. Every case fails with
the three sim hunks reverted, and case 3 (plain buff) fails with only the ai.js release reverted. Targeted sim tests
pass 184/184 (blocking, block targets, enemy swing, feedback2-enemy-attack-stand, combat / statuses, robustness,
stun SP, professions, healers, fidelity …). Content tests plus kits_layout and docs-consistency pass 658/658 (kits
t1t2 / t3 / t5 and alt t2 / t3 / t5 for 小满 / 瑕光 / 缇缇, 酒神, 死芒, garrisons, bosses, items). Stealth / liftoff /
enemies pass 36/36. npm run golden: all 283 match. GOLDEN_FULL=1 test/golden.test.js passes 9/9 (no stored engine
error). lint 0 errors, check:imports and typecheck clean.
PRTS 状态机: ATTACK / COMBAT "每帧检查异常状态,若有则切换到异常状态的状态"; PRTS 异常效果 STUNNED (the state machine
leaves the attack), DISARMED "正在进行的普通攻击将被中断". The strike frame is data/enemies.json attackAnim.hit.
- ai.js: attackWindup = the clip's strike frame (half the clip when none is named), shortened with the clip like the
stand; the cooldown counts down to the strike and the swing (enemy.swing) starts when it reaches the wind-up with a
target in reach (attackTargets, shared with the frame) — steady-state strikes stay one interval apart. An enemy whose
cooldown ran out before it had a target (walking, just blocked, a cut swing) swings from the start: the whole wind-up.
- A stun / freeze / sleep / 浮空 / hiding, 缴械, 恐惧, 战栗 while blocked or losing every target cuts a swing short of its
frame: no strike, the next swing starts from its wind-up. A stun in the cooldown only pauses it; a strike already
made stays made. No clip known (36 of 249 kinds): no wind-up, the old rule. [ASSUMED] targets re-taken at the frame,
a cut swing does not spend the cooldown, enemy heals keep no wind-up.
Golden: 275 of 283 scenarios moved — roster all 49; bonds 41 of 46 (unchanged: bond-arcaneShip-high,
bond-kjeragShip-low, bond-maniShip-low, bond-skillfulShip-high, bond-swiftShip-low); fields all 22; matches all 18;
standins all 10; diy 135 of 138 (unchanged: diy-027, diy-029, diy-087) — every battle where a clip-carrying enemy meets an
operator: the first strike of a contact waits its wind-up, stuns cut swings (the cut alone moves 55). With every
attackAnim stripped from the data the corpus is byte-identical to the previous commit (nothing else moved). Bot
matches: solo-HARD-2 now wins, coop2-NORMAL-8-serverrun now loses; the other 16 keep their result.
Tests: test/sim/feedback5-enemy-swing.test.js (new, 6). Updated on purpose: feedback2-enemy-attack-stand.test.js (it
locked the instant first strike), enemies_bosses.test.js (沉沙 / 新硎's cleared interval, 帝国的甲胄, 斩胄之剑 / 破胄之锤 wait
for the frame). test/sim, test/content, test/match pass. Docs: SIM.md, DATA.md (attackAnim), ASSETS.md.
- kits/ops/op-ironmn.js — 白铁 (char_4072_ironmn): S1 / S2 / S3, 战地工程师 (device stock 3, CRA-X +1, refilled at each
deployment; a device that left comes back on its tile after its redeploy time, paying its cost, one stock, while he stands;
his devices leave with him), 节约经费 (prob 0.7 / CRA-X stage 3 0.9), CRA-X (stock, costs, stage 3 SP +0.2/s), CRA-Y
(redeploy times, stage 3 ASPD +6 on device-buffed operators); the device kits 白铁™多功能平台 (S1 ATK +12 % ×2.5 / 3 in S1;
S2 1 SP / 3.5 s, 2.5 / 2 s in S2, 0.4 % / s 流失 ×2) and 铁钳号·原型机 (an ally target: damage cancelled, 1 SP per hit,
a 工匠's hit heals 1 %; its skill −2.5 % then 230 / 260 % + 110 / 120 % within 1.1 of 白铁's ATK; 团结的力量 ×0.8
physical behind it). Exports the shared 工匠 device helpers.
- kits/ops/op-nasti.js — 娜斯提 (char_4212_nasti): S1 / S2 / S3, 前方施工 (stock; CRA-X stage 3 first device −3, combined
ranges), 注意安全 (10 % 庇护, 15 % + 1 SP / 6 s for her and our ranged operators once a ranged enemy appeared), CRA-X; the
device kits “质检专员”, “监工专员” (3 / 8 HP, its S2 pulses of SP and her barrier) and “应急承重小组” (小工程师 + the 高台 it
builds and levels).
- kits/ops/op-necras.js — 死芒 (char_450_necras): S1 / S2 / S3, 复燃 (summon on the kill tile or a random tile of her range,
upgrade at 3), 回光黯淡, the trait (the enemies her summons block are her targets; SOC-X ×1.15), SOC-X stage 3; the
悲叹的仆役 kit and its special form (S3).
- Engine (additive): Battle.setAllyTarget / allyTargetsInKeys / isAllyTarget (battle/queries.js); ai.js acquireTargets puts a
registered ally target of the range after every enemy, performAttack flies ranged attacks to it. Nothing changes while
none is registered: every golden family but diy unchanged. docs/SIM.md §6 documents it.
- kits/index.js: the three files appended to OPERATOR_KIT_FILES.
- Tests: test/content/op_ironmn.test.js, op_nasti.test.js, op_necras.test.js, test/sim/feedback5-o23-engine.test.js.
- Golden: only diy moved — diy-106 … diy-109 re-chunked (the new operators' configurations come before the prototypes),
diy-110 … diy-114 new.
ba.groundbind "目标变为地面单位,无法移动;使部分近地悬浮敌人掉落;对重量大于3的单位持续时间减半" (予愿安洁莉娜 S2 needs it):
- buffs.js: STATUS groundbind (flag groundbind + noMove, move x0), FLAG_KEYS, RESIST_STATUSES (as 束缚, [ASSUMED]);
- units.js isFlying: an enemy under 缚地 is a ground unit unless a 浮空 lifts it (same result as before without the flag);
- battle/status.js: 浮空 lands on a 缚地 data flyer (PRTS 异常效果 "…且不持有缚地异常…则Buff取消"), 缚地 halved on weight > 3;
- content/enemies: 掠海漂移体 / 吉兆飞鳞 drop on 缚地 as their PRTS text says (吉兆飞鳞 stays down while it holds);
- render/style.js: the 束缚 icon for it; docs/SIM.md (§2 isFlying, §3 flags / status table / 抵抗).
Nothing applies it yet: every golden family is unchanged. Test: test/sim/feedback5-groundbind.test.js.
Three owned-6★ picks get their operator kits (kits/ops/op-slent2.js, op-haruka.js, op-phatm2.js; OPERATOR_KIT_FILES):
every skill at rank 4 / 7, both talents, the trait and every module at stages 1 and 3, from data/backups.json, PRTS and the
client's battle data (charpacks + buff_template_data of the three operators).
- 淬羽赫默: 护佑者 (arts attacks, heals while a skill runs; BLS-X 100 %, BLS-Y 2 targets); 无声砥柱 庇护 10 % → 24 % by the
lost HP (shared `protect`); 丰润羽翼 as 生命回复速度 (the atk_to_hp_recovery template PRTS documents so for 絮雨 / 琴柳), ×2
for 莱茵生命; BLS-X Lv3 max HP +10 %, BLS-Y Lv3 the once-per-deployment barrier; S2's placed 夜灯 (T1 ×2.1 / ×2.4 around it,
withdrawn at the skill's end or when she leaves); S3's 不死 for the first lethal hit in her range, 2 uses a battle.
- 遥: bubbles with each attack (or instead of one), 30 % 庇护 ([bonus], ×1.4 / ×1.7 in S3), breaking 0.5 s after an enemy's
damage, the break heal (BLS-Y Lv3 +1 SP to the holder); S1 re-bubbles around, S2 heal → arts splash and endless from the
2nd use, S3 y-8 and the levitation with its damage.
- 酒神: T1 神经损伤 on each hit + 1.3 splash; 堕梦 ASPD cut in 神经 bursts and 70 / 90 on enemy attacks (a burst interrupts
the attack); RIT-X ×1.18 vs elite / leader; S1 two hits + 束缚 ×1.3 / ×1.5; S2 (SP_FULL toggle) the placed 本能的召唤
(lure 4, exit 停顿 + DoT, 25 s redeploys while it runs); S3 y-8, per-second 神经损伤 until a burst, 1.5× burst recovery
and the 迷狂牢笼 (blocks its tile's enemies at spawn / refresh, 1 per hit, 30 s after the skill).
Engine (additive, no handler before): ai.js hook `enemyAttackStart` (an enemy's normal attack, before 麻痹), blocking.js
flag `noNewBlock`, items/battle.js `holdsUndying` also sees a buff flagged `undying`; docs/SIM.md §3 / §5, kits/README.md
(docked skill-summon pieces: their kit without offOwner).
Golden: only diy moved — diy-106 … diy-109 (the prototype configurations shifted behind the new operators) and the new
diy-110 … diy-114 (the three operators' configurations); roster, bonds, fields, matches, standins unchanged.
Tests: test/content/op_slent2.test.js (11), op_haruka.test.js (9), op_phatm2.test.js (13).
Two owned 6★ picks get their operator kits (kits/ops/op-kalts2.js, op-monstr.js; OPERATOR_KIT_FILES):
- 凯尔希·思衡托 (char_1052_kalts2, 守望者, no module): heals that pass 凯尔希's Mon3tr; 遗尘守望 (HP / DEF +25 %,
block +1, 阻挡半径倍率 +0.23, 起飞); 医者丰碑 (operators entering her range: a 1-hit 护盾 and 生命回复速度 +50 / 罗德岛
+100 for 30 s); S1 (ATK / ASPD, other 起飞 operators' 阻挡半径倍率); S2 (y-11, 10 shots: true damage + 停顿 and a
heal within 1.5, at an enemy or an injured ally); S3 (ATK, interval −1.55, 2 targets; with her placed anchor: two
operators withdrawn into 【待投放】 and back, her flight and 【移动】 onto the anchor). The anchor's kit (无敌, never
attacked); content/tokens.js docks it as a skill's summon.
- Mon3tr (char_4179_monstr, 链愈师, XAH-X): her own chain (x-4 jumps, ×0.75 / ×0.85, free links), the 重构体's kit
(禁疗 but hers, 流失, ATK aura, its return), 战术协同 ASPD, S1 next heal, S2 (the 重构体 first, a second chain
0.6 s on), S3 (needs the 重构体: the move onto its tile, true melee, 不死, the 【返回】).
Engine (additive): mod `blockRadiusScale` = 阻挡半径倍率 − 1 (buffs.js, units.js s.blockRadiusScale): the air-block
radius of Battle._checkBlock is 0.8944 × (1 + it) — 0 for every other unit. docs/SIM.md §1.2 / §2 / §3, DESIGN §5.5.
Tests: test/content/op_kalts2.test.js (10), test/content/op_monstr.test.js (10).
Golden: only diy moved — diy-110 … diy-112 are new and diy-106 … diy-109 re-packed (the two kits' configurations
join the family's 12-per-battle packing); roster, bonds, fields, matches and standins are byte-identical.
- buffs.js makeBuff / damage.js absorbShields: `shieldType` may be a list of damage types — the shield absorbs those only
(机械师's 屏障 absorb physical and arts damage, not true: buff_template_data mcnist_t_2 / mcnist_s_2_shield BlockDamage
PHYSICAL_AND_MAGICAL); a single type and an untyped shield work as before.
- damage.js heal / Battle.injuredAlliesInKeys: a healer profile's `healThrough(healer, ally)` names allies its heals reach
through their 禁疗 (the `noHeal` flag of a summon's 禁疗, the `healFree` flag; a profile `noHeal` — 无法被友方治疗 — still
stops it), and its heal selection takes them (凯尔希 on her Mon3tr: PRTS Mon3tr(凯尔希的召唤物) "持有禁疗(可被凯尔希…
无视)"; her charpack attack `_ignoreHealFree`); every other healer still skips them.
- docs/SIM.md §3 / §4 / §8, professions.js profile field list.
No content uses either yet: golden unchanged.
Test: test/sim/feedback5-o16-engine.test.js (2).
Conflicts: tools/golden.mjs / test/golden/README.md take both new families (standins from W5G, diy from W5H); DATA.md / SIM.md keep both texts. data/ equals an offline build of the merged tools/build-data.mjs. Golden regenerated on the merged code: against feedback5 nothing moved, diy.json is new; against fb5-diy the W5G / W5J / W5L scenarios moved, and diy-004 / diy-006 (the prototype battles with Touch, changed by W5L) — diy-001/002/003/005 identical.
The shared code of the 外勤医疗 strategy's Touch and the Touch 补位 stand-in (content/tokens.js touchGospel /
mapCharTalents), against PRTS Touch(卫戍协议) and its 备注 / 修正:
- S3 恳切福音's extra heal: 30 % of the main heal's base (before the ×1.35 / ×1.40), a heal of its own — its recipient
below half HP gets the boost (and the elite's PHY-X), 备注 「额外治疗可触发技能后半段的治疗量提高效果」; it goes to the
lowest HP ratio of the main target and its 4 orthogonal neighbours, a full-HP unit included (x-5,
「可治疗生命值已满单位」). The touchExtra / touchMainHeal block is gone.
- The boost needs HP strictly below half (修正 「低于」, was 「不高于」).
- 攫升: every heal she outputs gives SP — a heal on herself and one that restores nothing too (备注 「无需实际产生治疗量」);
still no device, no unit without a skill, and not her own HP-regeneration tick.
- 超脱: a forced exit that plays the death animation counts like a knock-out (备注 「如史尔特尔的天赋效果」). Battle.retreat
takes `dying` and the death hook carries it: 史尔特尔's 余烬 and 骑士戒律 + 竞技旗 set it; planned exits (耀骑士临光 S2,
伊内丝 S3), the 商人's automatic 撤退 and the 突袭 jump do not. A battle has no player 撤退 command.
Golden moved: roster-041 (the strategy's Touch heals differently: S3 extra heal / boost), standin-03, standin-04,
standin-08, standin-09, standin-10 (Touch standing in for 塞雷娅 / 塑心 / 纯烬艾雅法拉), coop2-NORMAL-14-standins (the
human seat plays 外勤医疗, so its Touch takes part). Docs: SIM.md (death hook `dying`, retreat option, the forced-exit
paragraph).
- simdata: DataSource keeps `backups` (rawBackups follows the fallback chain); getStandIn = shared/standIn.js
standInRecord normalised (the chess's ids / bonds / 特质 / tier, the stand-in's body, def.standInFor); a PRESET / DIY
chess or a source without backups fields itself; the per-battle view maps id-only lookups.
- spec.js keeps `standIn` only when exactly true (never on a token); Battle passes it to getChess; syncUnitLoadout
carries it; UnitInfo `standInFor`.
- content/index.js kitOf: a stand-in's kit is KITS[def.charId] only; no default skill (a stand-in kit writes `skills`);
without a kit the generic kit plus genericTalents. kits/index.js STANDIN_KIT_FILES / STANDIN_KITS, merged after the
tier groups (old keys keep their order; golden unchanged).
- server/data.js and tools/setup.mjs expect backups.json.
- test/content/standin.test.js: the plumbing and the eight 预备干员 on all 28 chess records they replace.