Playtest #6 follow-up (v2.5.1): leader HP review — 直接乘算, one debuff instance, 999 layer cap, 限伤; elite to the board; 假想敌:胄 kit
- co-op leaders died within seconds: leader HP is the official data (40 values pinned); bond / strategy / item / 机变 / 特质 "+X%" bonuses now add up (PRTS 直接乘算) instead of compounding; a same-named enemy debuff keeps one (strongest) instance per target (奥术 across a pair field); leader parts pass damage 1:1; fixed co-op pool (the user's call) - official limits read from the client: each bond stops at 999 layers (MAX_GARRISON_STACK); a leader hit of 300000+ in boss / hidden battles is cancelled (MAX_BATTLE_DAMAGE, 限伤) — shared/constants.js switches, research 11 - a merge that consumes a deployed copy puts the elite on that tile and facing (user-confirmed); gold target highlight, promotion effect - 假想敌:胄 per PRTS: one shell, shells within range, any drone death costs 2 % max HP, 剑/锤 sorties and 瘫痪 - DESIGN §20.10–§20.14; 2842 unit tests, all 28 browser suites green; Chrome = Node on boss fields
This commit is contained in:
1 parent
6464e4b46a
commit
620f88c0d8
81 files changed
+4194
-447
No files matched your search
@@ -17,6 +17,7 @@ Tags: **[DATA]** client game data · **[VERIFIED]** official or wiki rule text,
|
||||
| `05-enemies-levels.md` / `05-enemies.json` / `05-maps.json` | Stage terrains (8 active), 38 wave templates with routes, 326 enemies, special-enemy pools, generation algorithm, bosses, bounties, LP rules. Addendum: DP, hidden-core thresholds, multi FUNNY rounds, stat scaling. | `05-maps.json: stages, roundLevels`; `05-enemies.json: enemies, specialEntries, bosses, bountyEffects, generation, _criticAddendum` |
|
||||
| `06-multiplayer-ux.md` | Co-op flow and state machine, 联防, shared vs individual, shared pool, cross-player effects, emotes and broadcasts, settlement, per-screen UI layout, style guide, server notes. Addendum: TL;DR fixes, banned-operator UI. | – |
|
||||
| `07-assets.md` / `07-assets.json` | Verified URL patterns and resolved URLs for avatars, portraits, skills, bond/item/band icons, UI, Spine (ops + enemies), BGM/SFX, fonts; build plan. Addendum: spot check 40/40 OK. | `operators[*]`, `enemies[*]`, `bonds`, `items`, `bands`, `autochessUi`, `audio` |
|
||||
| `11-limits-official.md` | Official limits read from the client (2.7.71 il2cpp) and the community: bond layers cap at **999** per bond (`MAX_GARRISON_STACK`, `AddBondCount` = min(L + n, 999)); in boss battles outside training a single hit of **≥ 300000** on a leader (`IsBossEnemy` = an `autoChessData.bossInfoDict` enemyId) is **cancelled** ("限伤", `MAX_BATTLE_DAMAGE`); implemented in DESIGN §20.12. | `shared/constants.js BOND_LAYER_CAP / BOSS_HIT_LIMIT` |
|
||||
|
||||
## 2. Match structure
|
||||
|
||||
@@ -72,7 +73,7 @@ Boss rounds: the battle continues past the timer. Merged team LP drains **1/s af
|
||||
|
||||
The visible chess per tier are 16/17/19/22/19/19. The item slot uses the same tier shares, then picks uniformly within the tier [ASSUMED].
|
||||
|
||||
**Merge:** 3 copies of the same chess (board or hand) merge into 1 elite (`_b`), sent to the **hand**. 风丸 needs 2. Elites never merge. The equipment of the merged copies returns to the hand. Reward: the shop temporarily shows 3 operators of tier min(shopLv+1, 6) at price **0**; take 1; no refresh or freeze; gone at round end. A purchase that completes a merge is allowed with a full hand. [VERIFIED]
|
||||
**Merge:** 3 copies of the same chess (board or hand) merge into 1 elite (`_b`), sent to the **hand** — or, when a consumed copy was deployed, to **that copy's board position** (PRTS 卫戍协议/帮助 "若消耗已部署至作战区的干员,则发送至作战区对应位置"; 01 A1 row 7). 风丸 needs 2. Elites never merge. The equipment of the merged copies returns to the hand. Reward: the shop temporarily shows 3 operators of tier min(shopLv+1, 6) at price **0**; take 1; no refresh or freeze; gone at round end. A purchase that completes a merge is allowed with a full hand. [VERIFIED]
|
||||
|
||||
## 4. Board, hand, combat
|
||||
|
||||
@@ -86,7 +87,7 @@ The visible chess per tier are 16/17/19/22/19/19. The item slot uses the same ti
|
||||
| Skill auto-cast | Default: SP ready + about to attack/heal + an enemy in the **initial** range. ~~`skillTriggerDataList` rows with `skillIndex` 0 = skill 1 only (TANK S1 → on damage: only 古米 and 灰毫 this season)~~ — Superseded by user playtest #6 (DESIGN §20): the class rows apply to **every MANUAL skill** of the class and never to an AUTO skill (PRTS 卫戍协议/帮助 names whole classes; the 阵法术师 row must cover 薄绿's default S2, a phalanx that never attacks with its skill off); a MANUAL skill with its own 技能范围 (not an attack-range change) uses SKILL_RANGE; automatic operations have a 3 s cooldown. charId rows per 03. | VERIFIED (class-row reading superseded) |
|
||||
| Speed | 2× forced, no manual control | VERIFIED |
|
||||
| Board geometry | 19×21 stage. Player board rows 9–12, cols 2–10. Gates (9,10) and (12,10); R1–3 use only the lower one. Goal (9,2). Col 9 is a non-deployable lane. Hand row 7 cols 0–9. Temp hand row 8 cols 4–8. Boss field rows 1–5. | DATA |
|
||||
| Bond counting | Distinct operators on board. 远见/奇迹/投资人 also count the hand. 绝技 counts elites. Layers persist all match; **no IN_BATTLE layer gains in 联防 or boss rounds**. | DATA/VERIFIED |
|
||||
| Bond counting | Distinct operators on board. 远见/奇迹/投资人 also count the hand. 绝技 counts elites. Layers persist all match; **no IN_BATTLE layer gains in 联防 or boss rounds**; each bond's layers stop at **999** (research 11). | DATA/VERIFIED |
|
||||
|
||||
## 5. LP, 联防, Final Assault, Hidden Core
|
||||
|
||||
@@ -98,6 +99,7 @@ The visible chess per tier are 16/17/19/22/19/19. The item slot uses the same ti
|
||||
| Elimination | LP ≤ 0: out; copies return to the pool | VERIFIED/COMM |
|
||||
| Final Assault (R14) | LP of all alive players **merged**, no cap. Players in pairs, and an **odd player alone**. Movable bosses spawn one per alive player's side and share one HP pool. Overtime −1 LP/s after 150 s. Wave leaks cost `lifePointReduce`. | VERIFIED |
|
||||
| Boss HP pool (`bloodPoint`, F/N/H/A) | boss_1 247.5k/675k/1.8M/3.6M · boss_2 225k/400k/800k/3M · boss_3 285k/708.75k/2M/4M · boss_4 307.5k/708.75k/2.1M/4.2M · boss_5 200k/390k/780k/3M · boss_6 285k/705k/1.99M/3.98M · boss_7 277.5k/787.5k/2M/4M. Pick weights 6/6/6/5/10/5/5. | DATA |
|
||||
| Boss-hit limit (限伤) | Final Assault / Hidden Core: one hit of ≥ 300000 on a leader deals **0** (cancelled, not clamped); minions, normal rounds and 联防 unaffected (research 11). | DATA/COMM |
|
||||
| Hidden Core (R15, 险境+) | Solo: activated layers **> 350** and LP > 1. Co-op: team sum **> 1200** and merged LP > 1. Bosses boss_8/9/10 (weights 50/40/40; HP N 937.5k/900k/1.0125M, H 3.6M/2.8M/3.8M, A 7.2M/3.95M/7.6M). Failure doesn't affect the clear. | VERIFIED/DATA |
|
||||
|
||||
**Enemy scaling (non-boss)**, per mode and round [VERIFIED via PRTS, user-sourced]:
|
||||
|
||||
@@ -9560,7 +9560,11 @@
|
||||
"source": "official intro '多余的装备无法进行出售,可以销毁'"
|
||||
},
|
||||
"promotion": {
|
||||
"eliteGoesTo": "hand",
|
||||
"eliteGoesTo": "hand; when a consumed copy was deployed, that copy's board position (PRTS 卫戍协议/帮助 '发送1名【精锐】状态的该干员至手牌区(若消耗已部署至作战区的干员,则发送至作战区对应位置)'; user-confirmed after playtest #6)",
|
||||
"eliteTileAmongSeveralDeployed": {
|
||||
"rule": "the consumed deployed copy that deploys first (board row desc, then col asc; mirrored on the right boss half), with its facing",
|
||||
"assumed": true
|
||||
},
|
||||
"equipmentReturnsTo": "hand",
|
||||
"reward": "shop temporarily shows 3 ops of tier min(shopLevel+1,6) at price 0; take 1; no refresh/freeze; expires at round end",
|
||||
"verified": true
|
||||
|
||||
@@ -338,6 +338,10 @@ The 20-fund 绮良 / 55-fund 帕格尼尼 band thresholds count **funds spent**
|
||||
- WIKI: "三位同名干员(无论是否部署)会自动合并且晋级为精锐干员".
|
||||
- `upgradeNum`=3 for 132 chess; **风丸 `chess_char_2_11_a` needs 2**.
|
||||
- Elites have `upgradeNum`=0: **no further merging**.
|
||||
- **Where the elite goes:** to the hand, **unless a consumed copy was deployed — then to that copy's board position**.
|
||||
PRTS 卫戍协议/帮助 §干员的获得与精锐化: "发送1名【精锐】状态的该干员至手牌区(若消耗已部署至作战区的干员,则发送至作战区对应位置)";
|
||||
confirmed first-hand by the user after playtest #6 ("合成精锐时,如果消耗了场上的干员,精锐会出现在场上那个位置"). See A1 row 7
|
||||
for the remake's choices where the text is silent.
|
||||
- **Equipment:** anything the merged units carried returns to the bench. Tip: "干员晋级后已配发装备会回收至整备区".
|
||||
- **Bond traits** of "<获得时>" type: a triple stacks 1+1+2 (the elite value is double) [COMM].
|
||||
- **Stats (`shopCharChessInfoData`):**
|
||||
@@ -838,7 +842,7 @@ Local copies are in `scratchpad/gd/extra/critic/` (`bw_盟约.txt`, `bw_sweep.tx
|
||||
| new | – | At **combat start, all unfrozen shop contents are cleared** ("进入作战期后,栏上若未处于冻结状态则清空全部物资"). | VERIFIED |
|
||||
| 4.2 / 8 | bench 10 + temp area | **Hand (手牌区/整备区) = 10 regular + 5 temporary slots**, shared by operators, **items** and hand-deployable **summons**. Several summons of one owner stack into 1 slot; summons of different owners don't stack.<br>When the regular hand is full, every action that would add a card is refused: buy, and withdraw from the board. Exception: a purchase that completes a 3-merge nets −1 card, so allow it.<br>Passive gains (merge result, band/trait/item grants, items returned by promotion) overflow into the temp slots. **While temp is non-empty the player cannot start combat.** Temp is wiped when the next phase starts.<br>A board↔hand swap is allowed even with a full hand. Cards fill hand slots **right→left**. | VERIFIED |
|
||||
| 5.2 | – | **Items cannot be sold** ("多余的装备无法进行出售,可以销毁"). They can only be destroyed for 0 funds. Operators sell for 1 from board or hand. | VERIFIED |
|
||||
| 7 | promotion reward [COMM] | Confirmed (PRTS 帮助, BWIKI, official intro). On acquiring the 3rd copy:<br>1. The 3rd copy is not created, and the 2 owned copies are destroyed wherever they are.<br>2. **1 elite goes to the hand, not to a board tile.** Their equipment returns to the hand.<br>3. The shop then temporarily shows **3 operators of tier min(shopLevel+1, 6) at price 0**. The official intro shows "II 0 ×3" after a tier-I merge at L1 and "III 0 ×3" at L2.<br>4. The player takes **1**. The offer cannot be refreshed or frozen and expires at round end. | VERIFIED |
|
||||
| 7 | promotion reward [COMM] | Confirmed (PRTS 帮助, BWIKI, official intro). On acquiring the 3rd copy:<br>1. The 3rd copy is not created, and the 2 owned copies are destroyed wherever they are.<br>2. **1 elite goes to the hand — or, when a consumed copy was deployed, to that copy's board position** (PRTS 帮助 "发送1名【精锐】状态的该干员至手牌区(若消耗已部署至作战区的干员,则发送至作战区对应位置)"; the user confirmed it first-hand after playtest #6 — this row used to read "not to a board tile", a misreading of the same sentence). Their equipment returns to the hand ("干员晋级后已配发装备会回收至整备区,需要重新配置"). [ASSUMED] where the text is silent: with two or three deployed copies the elite takes the tile of the one that deploys first (top→bottom, then left→right — the official deploy order) with its facing; a deployed operator transformed into the completing copy (突变细胞) counts as deployed; the copies' summons leave and the elite's own summon card joins the hand (§战斗部署 "如果部署的干员拥有可手动部署的附属召唤物,则该召唤物会立刻加入手牌区"); the deploy count never grows.<br>3. The shop then temporarily shows **3 operators of tier min(shopLevel+1, 6) at price 0**. The official intro shows "II 0 ×3" after a tier-I merge at L1 and "III 0 ×3" at L2.<br>4. The player takes **1**. The offer cannot be refreshed or frozen and expires at round end. | VERIFIED (elite to the copy's board position: PRTS + the user); the tile among several deployed copies ASSUMED |
|
||||
| 2 | BAND_CHECK "3 random + reroll" [ASSUMED] | **All unlocked bands are shown.** In co-op, players pick **one at a time in a random order** shown on the left ("以随机顺序进行策略轮选"). Each co-op player may **skip once**. The step lasts 50 s; on timeout the band is 华法琳. **Duplicates are allowed:** the official illustration shows 2 teammates' picks still un-greyed in the grid. [ASSUMED] 12 s per turn inside the 50 s step. | VERIFIED except the per-turn timer |
|
||||
| 2 | banned bonds "1 core + 1 add-on" [ASSUMED] | Replaced by the verified rule in **A2**. | VERIFIED |
|
||||
| 1, 12 | one ×0.7/×0.8 multiplier per mode; `aceffect_enemy_*` mapping [ASSUMED] | Replaced by the **per-round table in A3**. | VERIFIED (PRTS, user-sourced) |
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"Each player has one integer layer counter L per bond (23 counters). All start at 0 when the simulation starts, are never reset between rounds and are never reduced (no layer-loss effect exists in the data) [ASSUMED: never reduced].",
|
||||
"L is kept while the bond is inactive, but bond effects only apply while the bond is active (PRTS 盟约记录).",
|
||||
"Wording contract used by every source: \"使已激活的【X】层数+N\" -> add only if bond X is active at the moment of the trigger; \"(无需激活盟约)\" -> add even if X is inactive. \"自身所属盟约\" = every bond of that operator; \"自身已激活的盟约\" = only its bonds that are active.",
|
||||
"No global layer cap. Caps are per source: max_add_count_per_battle (layers a single garrison instance may add in one battle), max_layer (per round, e.g. 安洁莉娜 12/round).",
|
||||
"No layer cap in the data. Caps are per source: max_add_count_per_battle (layers a single garrison instance may add in one battle), max_layer (per round, e.g. 安洁莉娜 12/round). The official cap is in the client, not the data: AutoChessBattleConst.MAX_GARRISON_STACK = 999, AddBondCount stores min(L + n, 999) per bond (research 11 §1). Since 2026-10-01 (DESIGN §20.12) the remake stops each bond at 999 (shared/constants.js BOND_LAYER_CAP, layerGainRoom); the community agrees (巴哈姆特 12534 \"每把都能999层\", \"沒999層的盟約情況下\"; 12316 \"999謝\").",
|
||||
"Layers gained in battle persist after the battle and immediately affect formulas that read L [ASSUMED live update: recompute bond buffs whenever L changes; the reference game uses env_gbuff that reads current stacks].",
|
||||
"IN_BATTLE layer gains are disabled while fighting for a teammate in the 联防 (Unite) phase and in the leader/boss round (巴哈姆特 snA=12294; arknights.wiki.gg: \"Players cannot gain stacks via Combat-related Operator Attributes when assisting other players in the Unite Phase\").",
|
||||
"魔王 (garrison_59, emptyShip): whenever the operator on the tile in front of 魔王 raises layers through its own trait during battle, that raise gets +1 extra layer (per trigger).",
|
||||
@@ -36,7 +36,7 @@
|
||||
"DIY (自选) chess slots chess_char_5_diy1/2 and chess_char_6_diy1/2 have bondIds [] and are filled with a 6-star operator the player owns (diyChessDict = TIER_6). Their bond is derived from the chosen operator's nationId/groupId/teamId matched against autoChessData.bondInfoDict[*].powerIdList (e.g. yan: yan,sui,lungmen,lee,lgd; victoria: victoria,glasgow; kjerag: kjerag,karlan; egir: egir,abyssal; siracusa: siracusa,chiave; kazimierz: kazimierz,pinus; sargon; laterano). No match -> constData.fallbackBondId = emptyShip (协防干员). (bwiki: operators from those nations get the nation alliance, \"others receive the 协防 designation\".)",
|
||||
"Prototype substitution: a NORMAL chess whose operator the player does not own is fielded as its backupCharId (预备干员 / 原型干员) but keeps the chess's bonds and traits (PRTS: \"烛煌(或对应的原型干员)\").",
|
||||
"Mode filter: 标准模拟 (mode_single_funny / mode_multi_funny) enables only 13 bonds (炎 萨尔贡 维多利亚 谢拉格 叙拉古 精准 迅捷 坚守 助力 远见 不屈 调和 协防干员); 拉特兰 阿戈尔 卡西米尔 灵巧 奥术 奇迹 投资人 突袭 独行 绝技 are inactive there. Training/险境/绝境/终极 enable all 23.",
|
||||
"Stat math: attribute bonuses from 盟约, strategies and equipment are \"直接乘算\" - each is a separate multiplier on the operator's already-final stat, independent of the operator's own talents/skills (PRTS 盟约记录). E.g. 炎 +50% ATK and an item +30% ATK -> final = own_final_atk x 1.5 x 1.3.",
|
||||
"Stat math: attribute bonuses from 盟约, strategies and equipment are \"直接乘算\" (PRTS 盟约记录 \"盟约效果,策略效果,装备效果提供的属性加成均为直接乘算,与自持有干员的属性加成独立\"). Corrected 2026-10-01 (DESIGN §20.10): 直接乘算 is PRTS's modifier class whose values are SUMMED with each other and with the skills' \"+X%\" (游戏数据基础: D_t = t1 + ... + tn, A = (A0 + D_p)(1 + D_t)); \"与自持有干员的属性加成独立\" = separate from the 自持有加成 table (an owned operator +5-10% ATK / DEF / max HP by its real promotion; not modelled). E.g. 炎 +50% ATK and an item +30% ATK -> final = base_atk x (1 + 0.5 + 0.3), not x 1.5 x 1.3 (the reading used until v2.5).",
|
||||
"Core bonds (bondType SEASON, isPower) = 炎 萨尔贡 维多利亚 谢拉格 拉特兰 阿戈尔 叙拉古 卡西米尔 (8). The other 15 are add-on (REGULAR). bondOrder: 调和 = 1 (listed first in UI), others 2.",
|
||||
"weight (10 for most, 0 for 投资人/调和/协防干员/绝技): weight used when an effect picks a random bond (e.g. SERVER_ADD_BOND_ACTIVATED_RANDOM, random bond chess) [ASSUMED meaning]."
|
||||
],
|
||||
@@ -5721,7 +5721,7 @@
|
||||
"tiers": [
|
||||
{
|
||||
"need": "2 distinct",
|
||||
"effect": "When an 奥术 member deals magic damage, the target takes magic damage x(1.20 + 0.01*L) (i.e. +(20+L)%) for 3 s. One instance per (source unit, target); reapplying refreshes."
|
||||
"effect": "When an 奥术 member deals magic damage, the target takes magic damage x(1.20 + 0.01*L) (i.e. +(20+L)%) for 3 s. ONE instance per target whatever applies it: the strongest value wins, a weaker one resumes if it outlasts it; reapplying refreshes (corrected 2026-10-01: PRTS 作战机制 同名buff默认只表现出一个; 巴哈姆特 12316 the two players of a pair field compete for it)."
|
||||
},
|
||||
{
|
||||
"need": "3 distinct",
|
||||
@@ -5736,7 +5736,7 @@
|
||||
},
|
||||
"layerGain": "夕 +2 per operator gained; 阿罗玛 +2 per refresh (<=6); 溯光星源 +2 per 3 gold spent; 海霓 first kill +3; 获得时: 深靛 +2, 协律 +4 (hidden). 机变 \"莫斯提马的盟誓\" +10.",
|
||||
"assumed": [
|
||||
"instances from different 奥术 sources stack multiplicatively"
|
||||
"one instance per target, the strongest (the engine's default same-name rule; the two players of a pair field compete for it) — until v2.5 the remake kept one per player and they multiplied"
|
||||
]
|
||||
},
|
||||
"members": [
|
||||
|
||||
@@ -51,7 +51,7 @@ Core (isPower, bondType SEASON): 炎 萨尔贡 维多利亚 谢拉格 拉特兰
|
||||
- DIY (自选) chess slots chess_char_5_diy1/2 and chess_char_6_diy1/2 have bondIds [] and are filled with a 6-star operator the player owns (diyChessDict = TIER_6). Their bond is derived from the chosen operator's nationId/groupId/teamId matched against autoChessData.bondInfoDict[*].powerIdList (e.g. yan: yan,sui,lungmen,lee,lgd; victoria: victoria,glasgow; kjerag: kjerag,karlan; egir: egir,abyssal; siracusa: siracusa,chiave; kazimierz: kazimierz,pinus; sargon; laterano). No match -> constData.fallbackBondId = emptyShip (协防干员). (bwiki: operators from those nations get the nation alliance, "others receive the 协防 designation".)
|
||||
- Prototype substitution: a NORMAL chess whose operator the player does not own is fielded as its backupCharId (预备干员 / 原型干员) but keeps the chess's bonds and traits (PRTS: "烛煌(或对应的原型干员)").
|
||||
- Mode filter: 标准模拟 (mode_single_funny / mode_multi_funny) enables only 13 bonds (炎 萨尔贡 维多利亚 谢拉格 叙拉古 精准 迅捷 坚守 助力 远见 不屈 调和 协防干员); 拉特兰 阿戈尔 卡西米尔 灵巧 奥术 奇迹 投资人 突袭 独行 绝技 are inactive there. Training/险境/绝境/终极 enable all 23.
|
||||
- Stat math: attribute bonuses from 盟约, strategies and equipment are "直接乘算" - each is a separate multiplier on the operator's already-final stat, independent of the operator's own talents/skills (PRTS 盟约记录). E.g. 炎 +50% ATK and an item +30% ATK -> final = own_final_atk x 1.5 x 1.3.
|
||||
- Stat math: attribute bonuses from 盟约, strategies and equipment are "直接乘算" (PRTS 盟约记录 "盟约效果,策略效果,装备效果提供的属性加成均为直接乘算,与自持有干员的属性加成独立"). **Corrected 2026-10-01 (DESIGN §20.10):** 直接乘算 is PRTS's technical modifier class (游戏数据基础 属性基本公式: "直接乘算结果 D_t = t₁ + t₂ + … + tₙ", A = (A₀ + D_p)(1 + D_t); 作战机制: X₂ = X₁(1 + b₁% + b₂%), a skill's "攻击力+180%" being the example) — the values are SUMMED with each other and with the skills' "+X%"; "与自持有干员的属性加成独立" means they are separate from the **自持有加成** (PRTS 卫戍协议:盟约 下半, its own table: an operator the player really owns gets +5–10 % ATK / DEF / max HP by its real promotion — 精英1 Lv.1 +5/+5/–, 精英2 Lv.1 +10/+5/+5, 精英2 Lv.60 +10/+10/+10, the highest met applies), which the remake does not model. E.g. 炎 +50% ATK and an item +30% ATK -> final = base_atk x (1 + 0.5 + 0.3) (+ any skill %), not x 1.5 x 1.3 (the reading used until v2.5).
|
||||
- Core bonds (bondType SEASON, isPower) = 炎 萨尔贡 维多利亚 谢拉格 拉特兰 阿戈尔 叙拉古 卡西米尔 (8). The other 15 are add-on (REGULAR). bondOrder: 调和 = 1 (listed first in UI), others 2.
|
||||
- weight (10 for most, 0 for 投资人/调和/协防干员/绝技): weight used when an effect picks a random bond (e.g. SERVER_ADD_BOND_ACTIVATED_RANDOM, random bond chess) [ASSUMED meaning].
|
||||
|
||||
@@ -60,7 +60,7 @@ Core (isPower, bondType SEASON): 炎 萨尔贡 维多利亚 谢拉格 拉特兰
|
||||
- Each player has one integer layer counter L per bond (23 counters). All start at 0 when the simulation starts, are never reset between rounds and are never reduced (no layer-loss effect exists in the data) [ASSUMED: never reduced].
|
||||
- L is kept while the bond is inactive, but bond effects only apply while the bond is active (PRTS 盟约记录).
|
||||
- Wording contract used by every source: "使已激活的【X】层数+N" -> add only if bond X is active at the moment of the trigger; "(无需激活盟约)" -> add even if X is inactive. "自身所属盟约" = every bond of that operator; "自身已激活的盟约" = only its bonds that are active.
|
||||
- No global layer cap. Caps are per source: max_add_count_per_battle (layers a single garrison instance may add in one battle), max_layer (per round, e.g. 安洁莉娜 12/round).
|
||||
- No layer cap in the data. Caps are per source: max_add_count_per_battle (layers a single garrison instance may add in one battle), max_layer (per round, e.g. 安洁莉娜 12/round). The official cap is in the client, not the data: `AutoChessBattleConst.MAX_GARRISON_STACK = 999`, `AddBondCount` stores `min(L + n, 999)` per bond (research 11 §1). Since 2026-10-01 (DESIGN §20.12) the remake stops each bond at 999 (`shared/constants.js BOND_LAYER_CAP`, `layerGainRoom`); the community agrees (巴哈姆特 12534 "每把都能999层", "沒999層的盟約情況下"; 12316 "999謝").
|
||||
- Layers gained in battle persist after the battle and immediately affect formulas that read L [ASSUMED live update: recompute bond buffs whenever L changes; the reference game uses env_gbuff that reads current stacks].
|
||||
- IN_BATTLE layer gains are disabled while fighting for a teammate in the 联防 (Unite) phase and in the leader/boss round (巴哈姆特 snA=12294; arknights.wiki.gg: "Players cannot gain stacks via Combat-related Operator Attributes when assisting other players in the Unite Phase").
|
||||
- 魔王 (garrison_59, emptyShip): whenever the operator on the tile in front of 魔王 raises layers through its own trait during battle, that raise gets +1 extra layer (per trigger).
|
||||
@@ -655,11 +655,11 @@ Members (12 chess, 11 in current shop pool; by tier in shop: {'1': 1, '2': 2, '3
|
||||
|
||||
**Implementable spec**
|
||||
|
||||
- **[2 distinct]** When an 奥术 member deals magic damage, the target takes magic damage x(1.20 + 0.01*L) (i.e. +(20+L)%) for 3 s. One instance per (source unit, target); reapplying refreshes.
|
||||
- **[2 distinct]** When an 奥术 member deals magic damage, the target takes magic damage x(1.20 + 0.01*L) (i.e. +(20+L)%) for 3 s. ONE instance per target whatever applies it — the strongest value wins, a weaker one resumes if it outlasts it; reapplying refreshes (corrected 2026-10-01, DESIGN §20.10: PRTS 作战机制 "同名buff的默认叠加策略buff只能表现出一个"; 巴哈姆特 12316 first-hand "共享型buff會跟對面搶 如果對面層數比你高就不需要再特別激活直接吃他的奧術buff就行" — the two players of a pair field compete for it).
|
||||
- **[3 distinct]** Against enemies below 50% HP the multiplier is 1.4 x (1.20 + 0.01*L) = 1.68 + 0.014*L (i.e. +(68+1.4L)%).
|
||||
- Formulas: `magicTakenMul = 1.20 + 0.01*L`; `magicTakenMulLowHp(3) = 1.4*(1.20 + 0.01*L)`; `hpThreshold = 0.5`; `durationSec = 3`
|
||||
- How layers are gained: 夕 +2 per operator gained; 阿罗玛 +2 per refresh (<=6); 溯光星源 +2 per 3 gold spent; 海霓 first kill +3; 获得时: 深靛 +2, 协律 +4 (hidden). 机变 "莫斯提马的盟誓" +10.
|
||||
- [ASSUMED] instances from different 奥术 sources stack multiplicatively
|
||||
- [ASSUMED] one instance per target, the strongest (the engine's default same-name rule; the two players of a pair field compete for it). Until v2.5 this read "instances from different 奥术 sources stack multiplicatively" and the remake kept one instance per player, so two players' instances multiplied.
|
||||
- Bond item (with 变形同构体 grants this bond): 奥术法阵 `chess_item_3_08_e` (1 gold: 法术抗性+20,攻击使目标失去特殊能力5秒)
|
||||
- Garrisons that explicitly add layers to this bond: `garrison_119`, `garrison_121`, `garrison_122`, `garrison_131` (see section 4; plus the generic ones)
|
||||
- Garrisons that scale with this bond's layers: `garrison_05`
|
||||
|
||||
@@ -487,7 +487,7 @@ The gate is the start of the action's route. R1–R3 use only the lower gate. No
|
||||
| 4 | `pickEntries` `inactiveIn`, `pickReplacement` filters attached keys | inactive list also filters N/E replacements | only `specialEnemyKey` is filtered | [DATA], [WIKI] 上半 note | change |
|
||||
| 5 | `data/tuning.json → modes[*].enemyHpMul / enemyAtkMul` (all 8 modes, e.g. multi 险境 R13 HP ×0.55) | custom per-round multipliers from `tools/balance.mjs` | none; only the PRTS table (`config.enemyScale`) | [WIKI] | **delete** (keep `titles.comment_3`, which is unrelated) |
|
||||
| 6 | `data/tuning.json → mode_single_funny.bossHpMul 0.6` | leader pool ×0.6 in solo 标准 | none | — | **delete** |
|
||||
| 7 | `config.bossHpScale` `bloodPoint × alive/4`, solo ×0.25 [ASSUMED] | pool scales with alive players | co-op: split leaders share HP, "敌方领袖的总生命值不变" → pool = `bloodPoint` (no alive scaling found); **solo: unknown** | [WIKI] notice 5114 / PRTS 下半 | co-op: use `bloodPoint` as is; solo: keep a config value, flagged unknown |
|
||||
| 7 | `config.bossHpScale` `bloodPoint × alive/4`, solo ×0.25 [ASSUMED] | pool scales with alive players | co-op: split leaders share HP, "敌方领袖的总生命值不变" → pool = `bloodPoint` (no alive scaling found); **solo: unknown**. **Re-read 2026-10-01 (DESIGN §20.10):** notice 5114's full sentence is "在联合模拟的最终攻势阶段,部分敌方领袖会同时出现在战场的左右两侧,两侧的敌方领袖共享生命值(敌方领袖的总生命值不变)" — the left / right copies of one pair field share the HP; it says nothing about the number of players. The one note on that is community (巴哈姆特 12294 "聯機隊友(撤退/死掉)變少,最後boss血條也會變少", no proportion); it is kept as the config switch `bossHpScale.aliveScaling` (× alive / 4), **off** until the user confirms it from official play — it would shorten fights after eliminations, the opposite of the playtest report | [WIKI] notice 5114 / PRTS 下半 | co-op: `bloodPoint` whatever the alive count (× alive / 4 behind the switch, [ASSUMED proportion]); solo: keep a config value, flagged unknown |
|
||||
| 8 | `waves.js bountySpawns` `soloMul 0.7` for "perfect" bounties | bounty HP/ATK/DEF ×0.7 **on top of** the solo 0.7 base | no bounty-specific rule; the "70 %" note is the global solo base, already in `enemyScale` | [WIKI] 上半 11/18 log | remove `soloMul` |
|
||||
| 9 | `bountySpawns` timing | t = 4 s, +5 s per bounty, interval 3, `routeByMotion` | attached to the template's first N / NF action window (§5) | [DATA] | change |
|
||||
| 10 | `buildUniteWave` | grouped by slot class N/E/S/…, compressed into 40 % of the time limit | walkers → `lrsldr` action, flyers → `yokai`, tokens → T/TF; per-owner 0.5 s spacing | [DATA] (partial) | change |
|
||||
@@ -536,7 +536,7 @@ Everything in `docs/BALANCE.md` §4 (the tuned tables) and the `tools/balance.mj
|
||||
2. **Stat scaling and balance.**
|
||||
- Delete every `enemyHpMul`, `enemyAtkMul` and `bossHpMul` in `data/tuning.json`. Keep the `titles` block.
|
||||
- Remove the `soloMul` in `bountySpawns`.
|
||||
- `config.bossHpScale`: co-op pool = `bloodPoint[difficulty]` with no alive-player factor; solo stays a flagged config value.
|
||||
- `config.bossHpScale`: co-op pool = `bloodPoint[difficulty]` with no alive-player factor; solo stays a flagged config value. (2026-10-01: × alive / 4 available behind `aliveScaling`, off, see §6 #7.)
|
||||
- Keep `enemyScale` (PRTS table) and the 终极 speed ×1.15 from R3.
|
||||
- Re-run `tools/balance.mjs --tuning off` only to report, not to tune.
|
||||
3. **Pathing** (`server/sim/grid.js`, `server/sim/ai.js`, `server/sim/Battle.js`):
|
||||
@@ -566,7 +566,7 @@ Everything in `docs/BALANCE.md` §4 (the tuned tables) and the `tools/balance.mj
|
||||
| # | Question | Default |
|
||||
|---|---|---|
|
||||
| 1 | Do 射击台 (act1 m03 (10,3)/(10,4)) and 土石结构 block ground movement? | Block [ASSUMED] |
|
||||
| 2 | Leader HP pool in solo, and in co-op with fewer than 4 alive players | co-op `bloodPoint`; solo config value (flagged) |
|
||||
| 2 | Leader HP pool in solo, and in co-op with fewer than 4 alive players | co-op `bloodPoint` (× alive / 4 behind `aliveScaling`, off — ask the user, 2026-10-01); solo config value (flagged) |
|
||||
| 3 | Unit of `maxPlayTime` | Real seconds (×2 game) [ASSUMED] |
|
||||
| 4 | Exact 联防 predelay formula (`_CalculateActionPredelayConsiderUid`) | 0.5 s per owner [ASSUMED] |
|
||||
| 5 | DEF reduction in the 70 % / 80 % bases | HP/ATK only (下半 text) |
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
# 11 · Official limits: the 999 bond-layer cap and the 300000 boss-hit limit ("限伤")
|
||||
|
||||
Written 2026-10-01 as research (no code changed then). It follows the boss-HP review (DESIGN §20.10), where
|
||||
community first-hand reports pointed at two official mechanics the remake lacked: bond layers that stop at 999, and a
|
||||
"限伤" that makes very large hits deal nothing. **Implemented** the same day after the user asked for the co-op leaders to
|
||||
be as hard to kill as officially — §6 below and DESIGN §20.12; §2.3 (who counts as a leader) was read from the client
|
||||
while implementing.
|
||||
|
||||
**Tags** (as in research 09)
|
||||
- **[DATA]**: read from the official client. Here that is the local Windows client 2.7.71 (Unity 2021.3.39f1, files dated
|
||||
2026-08-20): `global-metadata.dat` (il2cpp v29: class, field and method names, constant values) and `GameAssembly.dll`
|
||||
(x86-64 machine code, disassembled with `llvm-objdump`; method addresses mapped to names through the
|
||||
`Assembly-CSharp.dll` code-gen module's method-pointer table and the metadata method tokens).
|
||||
- **[COMM]**: community posts (Bahamut, NGA, bilibili).
|
||||
- **[ASSUMED]**: our inference or proposal.
|
||||
|
||||
---
|
||||
|
||||
## 0. TL;DR
|
||||
|
||||
| # | Question | Official answer | Tag |
|
||||
|---|---|---|---|
|
||||
| 1 | Do bond layers cap? | **Yes, at 999.** `Torappu.Battle.AutoChessBattleConst.MAX_GARRISON_STACK = 999`. The client's bond-layer counter (`AutoChessPlayerDataModel/ScenePlayerData.AddBondCount`) adds the gain and then clamps: `count = min(count + n, 999)`. | DATA + COMM |
|
||||
| 2 | Is there a damage limit? | **Yes, on boss leaders in boss battles: a single hit of 300000 or more is cancelled (0 damage).** It is not a clamp and not an integer overflow. `AutoChessBattleConst.MAX_BATTLE_DAMAGE = 300000`; `AutoChessStepModeManager._OnBossEnemyTakeDamage` computes `d = ceil(hit)` and calls `modifier.Cancel()` when `d ≥ 300000`. | DATA + COMM |
|
||||
| 2a | Where does it apply? | Only in **boss battles outside training** (the Final Assault and the Hidden Core: `AutoChessGameStatus.inBossBattleState && !isTrainingMode` starts "step mode"), and only to enemies that `AutoChessBattleUtil.IsBossEnemy(enemyId)` accepts (the leaders). Normal rounds, 联防, minions in boss battles and training are not affected. | DATA |
|
||||
| 2b | What does a player see? | The hit does nothing: no HP loss, nothing counted toward the shared pool. Bigger multipliers therefore *lower* the damage of hits pushed past the line, which is why the community advice is to *not* light extra damage bonds on a 999-layer board. | DATA + COMM |
|
||||
|
||||
---
|
||||
|
||||
## 1. The 999 layer cap
|
||||
|
||||
### 1.1 Constant
|
||||
|
||||
`Torappu.Battle.AutoChessBattleConst` (metadata field default values; ints are compressed in v29):
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| `MAX_GARRISON_STACK` | **999** |
|
||||
| `MAX_BATTLE_DAMAGE` | **300000** |
|
||||
| `MAX_BATTLE_DEPLOY_CNT` | 12 |
|
||||
| `MAX_WEAR_EQUIP_CNT` | 2 |
|
||||
| `SPEED_LEVEL_IN_BATTLE` | 2 |
|
||||
| `BATTLE_WAIT_UI_TIME` / `HELP_BATTLE_WAIT_UI_TIME` | 1.5 / 2.5 (float) |
|
||||
|
||||
(`Torappu.UI.AutoChess.AutoChessCountDownView.COUNT_DOWN_MAX_NUM = 999` is an unrelated UI countdown.)
|
||||
|
||||
### 1.2 Where it is used
|
||||
|
||||
C# constants are inlined, so the use sites were found by scanning the il2cpp code section for the immediate. In every
|
||||
`AutoChess` method, 999 appears as a clamp only in
|
||||
`Torappu.Battle.AutoChess.AutoChessPlayerDataModel/ScenePlayerData::AddBondCount(bondId, n)`:
|
||||
|
||||
```
|
||||
TryGetValue(bondId, out bond); if (!bond.valid) return false; // [rcx+0x20]
|
||||
bond.stack += n; // add edx, edi ; [rcx+0x18]
|
||||
bond.stack = bond.stack < 999 ? bond.stack : 999; // mov eax,0x3e7 ; cmp ; cmovl
|
||||
return true;
|
||||
```
|
||||
|
||||
Its only caller is `AutoChessGarrisonManager._TriggerGarrisonStatusRefresh`, the in-battle 特质 / bond layer gain on the
|
||||
viewed player's data (`AutoChessDataCenter.viewPlayerData`). The prep-side gains are computed by the scene server, whose
|
||||
code is not in the client; the client clamp, the constant's home (`AutoChessBattleConst`) and the community reports
|
||||
(§3) say the cap is the same there. [ASSUMED: the server clamps every gain the same way, `min(L + n, 999)`.]
|
||||
|
||||
### 1.3 Reading
|
||||
|
||||
- A hard gameplay cap, not a display cap: the clamped value is the one stored (and the layer readers — `GetBondStackCount`,
|
||||
`AutoChessAssignBondStackCntToBB` — read the stored value).
|
||||
- Per bond: each bond's layer counter stops at 999 on its own.
|
||||
- The per-battle gain limits of individual 特质 (e.g. 锏 ≤ 24, 凛御银灰 ≤ 200; blackboard `max_add…`,
|
||||
`AutoChessGarrisonManager.BOND_ADD_MAX_PER_BATTLE`) are separate and unchanged.
|
||||
|
||||
## 2. The 300000 boss-hit limit
|
||||
|
||||
### 2.1 The code
|
||||
|
||||
`Torappu.Battle.AutoChess.AutoChessGameManager.StartBattle`:
|
||||
|
||||
```
|
||||
if (gameStatus.inBossBattleState && !isTrainingMode) { // [this+0x18] = get_isTrainingMode
|
||||
inStepMode = true;
|
||||
BattleController.ReqChangeDeltaTimeFPInStepMode();
|
||||
stepModeManager.Start();
|
||||
}
|
||||
```
|
||||
|
||||
`AutoChessStepModeManager.OnEnemyRegistered(enemy)`: `if (AutoChessBattleUtil.IsBossEnemy(enemy.id)) bosses[enemy.instId] = enemy`.
|
||||
|
||||
`AutoChessGameManager.OnEntityApplyModifier(entity, modifier)`: `if (inStepMode) stepModeManager.OnEntityApplyModifier(...)`,
|
||||
which forwards to `_OnBossEnemyTakeDamage` when the entity is a registered boss.
|
||||
|
||||
`AutoChessStepModeManager._OnBossEnemyTakeDamage(enemy, modifier)`:
|
||||
|
||||
```
|
||||
int d = (int)Math.Ceiling(modifier.value.AsFloat()); // roundsd …, 0xA (toward +∞)
|
||||
if (enemy == null || modifier.isCancelled || !modifier.isDamage) return;
|
||||
if (d <= 0) return;
|
||||
if (d >= 300000) { modifier.Cancel(); return; } // cmp ebp, 0x493e0 ; jge → Modifier::Cancel(0)
|
||||
bossDamage[localPlayer] += d; // TryGetValue / set
|
||||
actions.Add(new StepAction { type = 3, d, killedInfo… }); // the step relayed to the server / partner
|
||||
```
|
||||
|
||||
There is no other use of 300000 (or 299999, or the float 300000.0) in the autochess code; the other three hits of the
|
||||
immediate in the binary are `HttpWebRequest` / `FtpWebRequest` timeouts.
|
||||
|
||||
### 2.2 Reading
|
||||
|
||||
- **Cancel, not clamp.** `Modifier.Cancel` is the engine's ordinary damage cancel (the same call as for invulnerability):
|
||||
unless the modifier carries an ignore-cancel mask for reason 0, the hit is dropped. So a hit worth 299999 lands, a hit
|
||||
worth 300000 deals **0**.
|
||||
- **The value checked is the hit about to be applied** (`modifier.value` at apply time: after DEF / RES and every
|
||||
multiplier). [ASSUMED: before HP shields, after hit-negating blocks.] Only two leader defences in our data are
|
||||
affected by this order:
|
||||
- 阿利斯泰尔 (boss_6) gets an HP shield, the 5000-HP barrier of 莫非王土's shield equipment (`boss:vest`, skill
|
||||
`store` / `storeA` `dynamic` 5000 in data/enemies.json). The order decides only its hits within 5000 of the line:
|
||||
with the limit first, a hit of 300000–304999 is cancelled and the barrier stays; with shields first, 5000 would be
|
||||
absorbed and 295000–299999 would land. The vest's ×0.2 on hits from its side is a multiplier, so it counts before
|
||||
the check.
|
||||
- 假想敌:管 (boss_10, hidden template h08_03) can stand in 假想敌:再生's aura (`Aura.max_damage_block_cnt` 5), which
|
||||
negates a whole phys / arts hit in the `hit` step, before the limit. So a hit past the line spends one block
|
||||
instead of being cancelled by the limit; either way it deals 0.
|
||||
- **Who:** the leaders only (`IsBossEnemy`, §2.3). Minions in the boss battle, every enemy in normal rounds and 联防, and
|
||||
everything in training are uncapped.
|
||||
- **Why it exists [ASSUMED]:** in step mode every boss hit is relayed as an action so both players of a pair and the
|
||||
server keep one shared pool; the limit looks like a sanity guard on those reports. It still decides real fights:
|
||||
the co-op leader pools (`bloodPoint`, data/bosses.json) run from 200000 (FUNNY) to 7600000 (ABYSS), so in the easy
|
||||
modes one hit over the line would be a whole pool.
|
||||
- **Not an overflow.** Nothing wraps at 2³¹; the line is a deliberate constant.
|
||||
|
||||
### 2.3 Who is a leader: `AutoChessBattleUtil.IsBossEnemy(enemyId)` [DATA]
|
||||
|
||||
Read while implementing (metadata token 0x6013192, method pointer 0x180b058e0 in the same build; `Il2CppCodeGenModule`
|
||||
method-pointer table of research 08 Appendix B):
|
||||
|
||||
```
|
||||
foreach (var kv in <activity data>.autoChessData.bossInfoDict) // Dictionary<string, AutoChessBossInfoData>
|
||||
if (string.Equals(kv.Value.enemyId, enemyId)) return true; // [value+0x18]; the class's fields: bossId 0x10,
|
||||
return false; // enemyId 0x18, handbookEnemyId 0x20
|
||||
```
|
||||
|
||||
So a leader is an enemy whose id is a `bossInfoDict[*].enemyId` — the 10 keys of data/bosses.json `enemyKey`
|
||||
(enemy_9013_acstmk, enemy_9017_achunt, enemy_9021_acduml, enemy_1521_dslily, enemy_2016_csphtm, enemy_9032_aclionk,
|
||||
enemy_9033_acdeer and the hidden enemy_9013_acstmk_2 / enemy_9017_achunt_2 / enemy_9021_acduml_2). It matches by id, so
|
||||
every instance counts — the second copy a pair field spawns (boss_battle_multi_player) included. The hidden leaders'
|
||||
parts (“斩胄之剑” / “破胄之锤” enemy_9014/9015, “碎铳之簧” enemy_9018–9020, 假想敌:弦 enemy_9022 and “裂管之音” /
|
||||
“断弦之音” enemy_9023), 假想敌:胄's 刺胄之弹 (enemy_9016_acstmr) and drones (enemy_1005_yokai), escorts and bounty enemies
|
||||
are not in the list: hits on them are never cancelled — the share a part passes on to its leader ("被击落时受到伤害以一定
|
||||
比例传递") is a hit on the leader and is checked [ASSUMED: the transfer is an ordinary damage modifier on the leader].
|
||||
In the remake's wave data the tag-'boss' spawns of the boss / hidden templates are exactly those keys and nothing else
|
||||
(test/sim/playtest6_limits.test.js checks it).
|
||||
|
||||
## 3. Community reports
|
||||
|
||||
Paraphrased; only key terms are quoted.
|
||||
|
||||
### 3.1 Layers stop at 999 [COMM]
|
||||
|
||||
- **Bahamut** [C.php?bsn=33651&snA=12522](https://forum.gamer.com.tw/C.php?bsn=33651&snA=12522) (2026-06-28): the text says
|
||||
999 layers are usually reached within 2 rounds, and that 精准 and 萨尔贡 were stacked full at 999. Its screenshots:
|
||||
R12 谢拉格 696 → R13 谢拉格 **999**, 灵巧 301, 炎 122 → R14 谢拉格 still **999** while the author kept feeding it,
|
||||
灵巧 671, 炎 537 → R15 炎 / 谢拉格 / 灵巧 all **999**, 迅捷 222. Each bond stops on its own.
|
||||
- **bilibili** [BV16bU7BTEX1](https://www.bilibili.com/video/BV16bU7BTEX1) (2025-11-22): 萨尔贡 filled from 0 in one round, the
|
||||
surplus wasted; a commenter lists the 「层数上限」 among what holds 瑰盐 back.
|
||||
- **TapTap** [moment 747932824320870144](https://www.taptap.cn/moment/747932824320870144) (2025-12-10): 谢拉格 from 100 to 999
|
||||
in one round.
|
||||
- More videos treating 999 as full: bilibili BV1xVdBBWEuu, BV1vUyJB4Ero ("all bonds 999"), BV1eoCSBzEde (拉特兰 999 by
|
||||
R11); YouTube thG4eVPnSnM. No source shows a bond above 999.
|
||||
- Not stated anywhere official: the excel tables (`activity_table` act2autochess / `autoChessData`: no cap field,
|
||||
`maxInactiveBondCount = -1`), PRTS (卫戍协议:盟约, 下半, 帮助, PRTS盟约记录), BWIKI and the in-game help.
|
||||
|
||||
### 3.2 "限伤" [COMM]
|
||||
|
||||
- **Bahamut** [C.php?bsn=33651&snA=12316](https://forum.gamer.com.tw/C.php?bsn=33651&snA=12316) (【心得】衛戍協議:盟約上下差異整理,
|
||||
2026-05-04): some big bond combinations make the output too high, and the 「限傷」 then keeps it from coming out; with
|
||||
999 谢拉格 do not light 奥术, or 大初雪 (圣聆初雪, tier 6, S3) is limited away; 瑪 (玛恩纳) should not switch to 谢拉格
|
||||
for the same reason; the same warning for 阿戈尔. No number given.
|
||||
- **bilibili** 【卫戍攻略#1】维多利亚&谢拉格篇 [BV19UXZBJExQ](https://www.bilibili.com/video/BV19UXZBJExQ) (comments, 2026-04):
|
||||
a high-layer 圣雪 easily hits the limit and her damage goes to zero; at 999 谢 do not light 奥术, maybe drop 灵知; a
|
||||
teammate's 奥术 in the boss fight zeroes her too. Asked what 限伤 means, a reply gives the number:
|
||||
「一次超过30w会被卡掉」 (a single hit over 300k is cut) — the client's `MAX_BATTLE_DAMAGE`.
|
||||
- **bilibili** 每把都能999层 谢拉格 [BV1xVdBBWEuu](https://www.bilibili.com/video/BV1xVdBBWEuu): bullet comments call an on-screen
|
||||
hit of 272451 "nearly at the limit" and warn that the damage "overflows to zero"; in the comments 160k hits are said
|
||||
to be safe, and a player's 0 damage *on the boss* is discussed.
|
||||
- **bilibili** 【卫戍攻略#4】什么叫叠到999层反而亏输出 [BV1nrdqBLERz](https://www.bilibili.com/video/BV1nrdqBLERz): comments mention
|
||||
"炎999限伤" and ask whether 仇白 S3 reaches it.
|
||||
- JP wikiru (堅守協定:盟約 2nd) says the damage limit wastes layers beyond a point.
|
||||
- Not the main game's overflow: PRTS 定点数与浮点数 / 数值范围 — battle values are a 64-bit fixed point (the client's
|
||||
`Torappu.FP`), max ≈ 2³¹; a main-game hit past 2.1 billion shows 0 (bilibili BV1bhgz6DEKS, Integrated Strategies).
|
||||
That is ~7000× the 卫戍 line; PRTS 作战机制 records ordinary hits in the millions, so the 300000 rule is mode-specific.
|
||||
|
||||
Why the hits get that big (data blackboards): 谢拉格 ×(1.35 + 0.01·L) vs cold / frozen = ×11.34 at 999; 奥术 arts taken
|
||||
×(1.2 + 0.01·L) = ×11.19 at 999, a debuff on the target (so the partner's 奥术 boosts your hits); 灵知 +27–29 % taken on
|
||||
cold targets, doubled on frozen; 圣聆初雪's 特质 +1 % ATK (elite +2 %) per 3 layers of her bonds; 炎 ATK
|
||||
+(0.23 + 0.009·L).
|
||||
- NGA [tid=46592301](https://bbs.nga.cn/read.php?tid=46592301) "卫戍协议BUG汇总&神秘机制": every endpoint answers 403
|
||||
「访客不能直接访问」 (login required); not read.
|
||||
|
||||
These reports fit §2 exactly: the advice is to *avoid* extra multipliers, which only makes sense if a hit past the
|
||||
line is lost rather than clamped.
|
||||
|
||||
## 4. What the remake did before the implementation, and what it does now
|
||||
|
||||
| | Remake before (master 7094892) | Remake now (§6) | Official |
|
||||
|---|---|---|---|
|
||||
| Layers | uncapped: `PlayerState.addLayers` (prep), `Match.js` settle (`ps.layers[b] += layerGains`), `Battle.addLayers` (live in-battle copy) | per bond `min(L + n, 999)` at every writer (`layerGainRoom`) | per bond `min(L + n, 999)` |
|
||||
| Boss hits | no limit (`sim/damage.js dealDamage` → `applyHpLoss` → `bossPool.damage`) | leader hit in a 'boss' / 'hidden' battle with `ceil(d) ≥ 300000` → cancelled, 0 (`leaderHitCancelled`) | leader hit with `ceil(d) ≥ 300000` → 0 |
|
||||
|
||||
## 5. Proposal (as written before the implementation; §6 is what was built)
|
||||
|
||||
- `shared/constants.js`: `BOND_LAYER_CAP = 999` and `BOSS_HIT_LIMIT = 300000` (each `0`/`Infinity` = off), the switches.
|
||||
- Layers: clamp in `PlayerState.addLayers`, the settle in `Match.js`, and `Battle.addLayers` (the live copy, as the
|
||||
client's `AddBondCount`); `onLayers` reports the clamped `to`; a gain at the cap adds 0.
|
||||
- Boss hits: in `dealDamage`, after the multipliers and before shields, `if (target.isBoss && (battle.kind === 'boss' ||
|
||||
battle.kind === 'hidden') && Math.ceil(final) >= BOSS_HIT_LIMIT) final = 0` (with a `capped` event so the client can show it) [ASSUMED: shown as
|
||||
no number, like the official].
|
||||
- Tests, docs (META / SIM / BALANCE / PLAYING) and a DESIGN draft.
|
||||
|
||||
## 6. Implementation (2026-10-01, DESIGN §20.12)
|
||||
|
||||
- `shared/constants.js`: `BOND_LAYER_CAP = 999` and `BOSS_HIT_LIMIT = 300000` (0 / Infinity = off), plus
|
||||
`layerGainRoom(before, n)` = min(n, cap − before), never negative.
|
||||
- Layers: every writer clamps with it — `PlayerState.addLayers` (every prep-side gain: 特质, items, bands, 机变 cards,
|
||||
bonds), the settle of the in-battle gains (`Match.js`), `Battle.addLayers` (the live in-battle copy, after the
|
||||
`layerGain` hook, as the client's `AddBondCount`); a gain at the cap adds 0 (no onLayers, no 'layer' event, no hook),
|
||||
so the per-N milestones (远见, 奇迹, 维多利亚 …) stop with the count; the client-result check (`fields.js`) bounds a
|
||||
reported gain by the room left from the bond's starting layers; `invariants.js` flags a bond above the cap. The dev
|
||||
tools write through the same helper: `tools/matchrun.mjs --layers N` (a raw boost, no milestones) and
|
||||
`tools/balance.mjs applyBoard` (any `--profile`) stop at 999 too.
|
||||
- 限伤: `sim/damage.js leaderHitCancelled` in `dealDamage` (after DEF / RES and every multiplier, before shields) and in
|
||||
`Battle.loseHp` (losses passed on to a leader): a leader (`isBoss`, the tag-'boss' units = §2.3) in a 'boss' / 'hidden'
|
||||
battle with `ceil(amount) ≥ 300000` → the hit returns 0 before shields (阿利斯泰尔's 5000 `boss:vest` barrier stays
|
||||
untouched; 再生's hit blocks act earlier, in the `hit` step, §2.2), HP / pool loss, stats, the damage number, the
|
||||
`damaged` / `fatal` hooks and the kill; what ran before it (the attack, its SP, the `hit` hook, separate element 损伤
|
||||
hits) stays. Element bursts (元素伤害) and DoT ticks are checked like any hit; element 损伤 (gauge fill) removes no HP
|
||||
and is not. The sim emits `['fx', 'hitCap', x, y, { id, n }]`; the client draws nothing for it (no number, like the
|
||||
official [ASSUMED]).
|
||||
- Fixed-ratio losses on a leader scale with the pool, so the pool size decides whether they meet the line. The one that
|
||||
can: 【死亡集群】 (boss_1 / boss_8 skill 2, bb `hp_ratio 0.02`): a drone killed by an operator costs the leader
|
||||
0.02 × its max HP, and a leader's max HP is the shared pool's max (`Battle` syncs it). Today's largest such pool,
|
||||
boss_8 ABYSS 7.2M, gives 144000, which lands. A pool above 14999950 (≈ 2.08 × that; ceil(0.02 × max) = 300000)
|
||||
would turn every drone kill into a cancelled hit [ASSUMED: the official routes this loss through the same
|
||||
`_OnBossEnemyTakeDamage` check]. Any change to the pool size (an alive-scaled pool, a new difficulty) should keep this
|
||||
in view; a real-kit test pins the line (`test/sim/playtest6_limits.test.js`, 【死亡集群】).
|
||||
Reference in new issue
Block a user