diff --git a/.gitignore b/.gitignore index a1706ce..c5fa310 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ Desktop.ini /.comet/* !/.comet/config.yaml # <<< Comet managed project state <<< +# Added by code-review-graph +.code-review-graph/ diff --git a/AGENTS.md b/AGENTS.md index 60cf879..19a6f6a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,3 +17,49 @@ In this repository, before starting work that may need code changes or investiga - If configuration or state is invalid and `nextCommand` is absent, stop and report the reason; do not guess another workflow. - Never attach unrelated work merely because an active change exists. The Native entry inspects uncommitted work; the probe does not attribute it automatically. + + +## MCP Tools: code-review-graph + +**This project has a knowledge graph. Start with the code-review-graph +MCP tools to narrow scope, then read the source.** The graph is cheaper than scanning files and +gives you structural context (callers, dependents, test coverage) that file search cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes_tool` or `query_graph_tool` instead of Grep +- **Understanding impact**: `get_impact_radius_tool` instead of manually tracing imports +- **Code review**: `detect_changes_tool` + `get_review_context_tool` instead of reading entire files +- **Finding relationships**: `query_graph_tool` with callers_of/callees_of/imports_of/tests_for +- **Architecture questions**: `get_architecture_overview_tool` + `list_communities_tool` + +### Verify in the source + +- Narrow scope with the graph, then read the source. Do not change code from graph output alone. +- For any non-trivial change, read the implementation and the relevant tests before concluding. +- Verify the exact source when touching behavior, database logic, migrations, retries, fallbacks, + recovery, or compatibility code. +- When the graph and the source disagree, the source wins. The graph may be stale or may not + model that relationship. +- An empty graph result can mean "not indexed" or "not statically visible", not "does not exist". + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes_tool` | Reviewing code changes — gives risk-scored analysis | +| `get_review_context_tool` | Need source snippets for review — token-efficient | +| `get_impact_radius_tool` | Understanding blast radius of a change | +| `get_affected_flows_tool` | Finding which execution paths are impacted | +| `query_graph_tool` | Tracing callers, callees, imports, tests, dependencies | +| `semantic_search_nodes_tool` | Finding functions/classes by name or keyword | +| `get_architecture_overview_tool` | Understanding high-level codebase structure | +| `refactor_tool` | Planning renames, finding dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes_tool` for code review. +3. Use `get_affected_flows_tool` to understand impact. +4. Use `query_graph_tool` pattern="tests_for" to check coverage. + diff --git a/mengsan/docs/liubei-gameplay-and-balance-proposal-20261030.md b/mengsan/docs/liubei-gameplay-and-balance-proposal-20261030.md new file mode 100644 index 0000000..0df6260 --- /dev/null +++ b/mengsan/docs/liubei-gameplay-and-balance-proposal-20261030.md @@ -0,0 +1,135 @@ +# 梦三与刘备玩法调整方案 V0.1 + +- 日期:2026-10-30 +- 状态:策划提案,尚未实施 +- 依据:当前项目源码与配置,尚未进行实战采样 +- 适用范围:梦三模式中的刘备、先天关张助战及相关构筑 + +建议把刘备定位为“能独立作战、通过仁德调度关张的协同型主角”,保留现有力量、自损、消耗牌组作为构筑分支。 + +本文中的建议数值需要通过对局验证;生成本文档不代表已经修改游戏机制,也不代表完成实机验收。 + +## 一、简单评估 + +梦三已经具备个人牌库、费用、怪物意图、地图选择、遗物和羁绊,足以支撑“战斗—构筑—路线选择”的基本循环。当前更值得优先处理的是角色特色和资源分配。 + +| 方面 | 当前情况 | 策划判断 | +| --- | --- | --- | +| 刘备特色 | 先天结识关张,但专属牌主要围绕力量、自损、消耗 | 角色技能与牌组之间缺少直接联系 | +| 玩家操作 | 3费用,默认每回合摸2张,手牌上限3 | 响应牌也占用手牌,可能出现有费用却缺少主动选择 | +| 关张差异 | 基础属性、默认牌库和意图相同 | 更换助战缺少战术意义 | +| 战斗波动 | 初始8级助战到场概率为77.78% | 重要战斗可能因助战缺席产生明显波动 | +| 回复收益 | 休息基础回复8;初始遗物每战结束回复6 | 休息的机会成本偏高,值得重新测试 | + +助战的群伤尤其需要关注:当前一次6点群体意图面对3名敌人,可以造成合计18点基础伤害,随后还可以继续出牌。这个收益会随敌人数增长,不能只按“6点伤害”估价。此处为不计力量、易伤、护甲等修正的数值举例,不是实测平均伤害。 + +## 二、刘备玩法方向 + +核心体验:**刘备决定资源交给谁、何时防守、集火哪个敌人,关张负责兑现不同的战术收益。** + +建议先保留两条主要路线: + +| 路线 | 核心打法 | 助战选择 | 代价 | +| --- | --- | --- | --- | +| 协同破阵 | 刘备施加易伤、提供手牌,集中消灭关键敌人 | 关羽 | 清理大量小怪较慢 | +| 坚守清场 | 刘备积累防御、处理杂牌,让助战持续压制群敌 | 张飞 | 单体爆发较弱 | + +现有自损、力量、消耗体系保留为进阶构筑。先让基础协同成立,再逐步加入“刘备承担代价、换取团队收益”的专属牌。 + +## 三、核心机制调整 + +新增先天技能「仁德」: + +> 每个自身出牌阶段限一次,消耗1费用,将一张可转移的非状态、非诅咒手牌交给另一名友方角色;然后自己摸1张牌,获得5点护甲。 +> 没有其他存活友方时,改为弃置一张符合条件的手牌,获得相同收益。 + +设计目的: + +- 有助战时,可以把攻击牌交给关张,自己承担防守。 +- 独自作战时,仍可整理手牌。 +- 与普通「防御」相比,同为1费用、5护甲;额外收益来自调度手牌,但每回合只能使用一次。 +- 转交不视为使用或响应,不触发该牌的使用效果;费用和手牌必须同时满足才能发动。 + +先维持刘备**50生命、3费用、每回合摸2张、手牌上限3**,观察仁德是否已经改善缺牌问题,避免同时提高所有资源。 + +## 四、第一轮数值平衡 + +以下数值作为一组测试配置,与当前版本对照。实际实施时仍按第六节分阶段验证。 + +| 项目 | 当前值 | 建议值 | 目的 | +| --- | --- | --- | --- | +| 刘备先天关张到场 | 初始8级,77.78% | 可参战且未濒死时100%;首战限制保留 | 让角色核心能力可靠 | +| 关张每回合费用 | 3 | 2,意图仍消耗1 | 降低助战替玩家完成战斗的程度 | +| 关张每回合摸牌 | 2 | 1 | 让仁德送牌具有实际价值 | +| 关张初始手牌 | 4 | 3 | 收紧开场爆发 | +| 关张手牌上限 | 5 | 4 | 仍允许保存玩家交来的牌 | +| 关羽最大生命 | 各等级40 | 30+等级,初始8级为38 | 等级提供小幅、确定的成长 | +| 张飞最大生命 | 各等级40 | 34+等级,初始8级为42 | 承担更持久的群战 | +| 休息基础回复 | 8 | 最大生命的30%,向上取整 | 50生命时回复15,让休息值得选择 | + +关张的确定到场规则仅作用于刘备先天羁绊。等级和现有成长进度保留,等级收益由到场概率转为上述生命成长。 + +关张意图改为各自循环: + +| 角色 | 第一次行动 | 第二次行动 | 第三次行动 | +| --- | --- | --- | --- | +| 关羽 | 单体7伤害 | 自身获得6护甲 | 单体10伤害 | +| 张飞 | 对全部敌人各造成3伤害 | 自身获得6护甲 | 对全部敌人各造成4伤害 | + +关羽优先攻击刘备上一回合最后攻击的存活敌人;没有有效目标时,攻击生命最低的敌人。张飞负责群体压制。 + +这些意图替换当前默认循环,并保留之后用剩余费用出牌的行为。面对3名敌人时,张飞第一次意图基础总伤害为9,低于当前的18;确定到场则减少了整体体验的波动。 + +## 五、初始牌组与高风险卡牌 + +初始牌组继续保持12张: + +**4杀+3防御+1闪+1桃+1无中生有+1八卦阵+1重杀。** + +具体是将当前的一张杀换成防御,将决斗换成重杀。这样新征程较早阶段即可体验“防御、施加易伤、关羽跟进”的基本配合。杀、防御、重杀的基础数值暂时保持。角色专属首战仍按现有限制不触发羁绊助战;关羽跟进的配合在后续允许助战的战斗中体验。 + +两张专属牌优先测试: + +| 卡牌 | 当前效果 | 建议调整 | +| --- | --- | --- | +| 炽焰 | 2费,给予另一友方5/7力量 | 改为3/4力量;费用保持 | +| 扯碎 | 2费,每次实际失血额外攻击一次,没有设计上限 | 最多额外攻击5次;每段伤害保持5/7 | + +表中的“5/7”等数值按未强化/强化顺序列出。扯碎上限仅针对额外段数,基础1段保留,即最多6段;其他伤害修正照常结算。 + +炽焰的力量会被多段、群体攻击放大,需要随助战体系一起评估。扯碎则保留成长爽点,但避免通过拖长战斗无限增加段数。 + +初始遗物每战回复6点、自损牌的生命代价先保持,避免这一轮同时改变过多续航来源。 + +## 六、验证与实施顺序 + +先收集当前版本基线,再测试调整版。使用相同地图种子和遭遇,分别覆盖单体、群怪、精英、Boss,以及助战濒死后的独立作战。 + +重点记录: + +- 刘备每回合剩余费用,以及“有费用却无有效牌”的次数。 +- 刘备与助战各自的伤害占比、战斗回合数。 +- 每场损失生命及战后回复后的净损失。 +- 关羽、张飞在不同遭遇中的选择价值。 +- 仁德使用率、送出的牌是否被有效使用。 + +首轮暂定目标:普通战斗约3—5个刘备回合;助战伤害占比中位数约25%—40%;关羽在单体战更有效,张飞在群怪战更有效。这些是调参目标,不是当前实测结果。 + +落地顺序建议为:**先测试助战与初始牌组数值,再加入仁德,最后调整专属牌和休息收益。** 每一步保留对照数据,确认收益来自哪里,再决定是否调整怪物强度。 + +## 七、当前配置依据 + +以下链接指向项目实际文件,便于后续实施时重新核对。本文记录的是编写时观察到的配置,源码后续可能变化。 + +- [刘备属性与先天技能](../content/scenario-characters.js) +- [费用、手牌上限与基础伤害](../battle/combat-rules.js) +- [刘备初始牌组](../cards/starting-deck.js) +- [关张基础属性与成长配置](../bonds/definitions.js) +- [助战概率、初始化与成长](../bonds/state.js) +- [默认助战意图及费用](../bonds/intents.js) +- [意图的敌对目标与效果结算](../battle/intent-effects.js) +- [炽焰、扯碎等专属牌数值](../cards/packs/liubei/data.js) +- [专属牌实际结算与失血次数统计](../cards/packs/liubei/runtime.js) +- [休息回复](../relics/rooms.js) +- [燃烧之血回复规则](../relics/rules.js) +- [新征程初始遗物授予](../progression/state.js) diff --git a/mengsan/docs/liubei-gameplay-and-balance-proposal-v0.2-20261030.md b/mengsan/docs/liubei-gameplay-and-balance-proposal-v0.2-20261030.md new file mode 100644 index 0000000..7bcb17b --- /dev/null +++ b/mengsan/docs/liubei-gameplay-and-balance-proposal-v0.2-20261030.md @@ -0,0 +1,389 @@ +# 梦三与刘备玩法调整方案 V0.2:敌人、意图循环与 Boss 联合平衡 + +- 日期:2026-10-30 +- 状态:策划提案;建议参数尚未实施,也未完成游戏内验证。 +- 范围:当前第一章、刘备、关张助战、4种弱池遭遇、12种强池遭遇、3种精英与3种 Boss 遭遇,以及它们的随从。 +- 前版:[V0.1](liubei-gameplay-and-balance-proposal-20261030.md)。本版与前版冲突时以本版建议为准,V0.1 保留作对照。 +- 证据:当前本地源码。下文的逐轮数据是规则推算,不是自动对局胜率;没有以外部游戏原版的数值证明梦三平衡。 + +## 1. 对 V0.1 的修正 + +V0.1 没有充分考虑怪物,不能直接作为平衡改动清单执行。它主要讨论玩家、助战和回复,遗漏了以下约束: + +1. 怪物的攻击意图目前通常作用于全部存活敌对角色,刘备和助战各承受完整伤害;助战到场并不分摊刘备受到的意图伤害。 +2. 意图通常只花1费用,之后仍能主动出牌。普通/精英/Boss 原有费用为2/3/4;图标上的意图伤害不等于整回合伤害。 +3. 力量按攻击段数放大;增益招式后的原生攻击牌会立即享受新力量,不能把增益轮直接当作安全轮。 +4. 血量之外,还有滑溜、护甲、回复、缩小、缓慢、伤口、感染、亡语和胜利条件。它们会改变击杀速度或实际生存空间。 +5. 多敌人的循环会在某一轮叠出峰值,不能把单只怪物平均伤害相加后就判定合理。 +6. V0.1 同时削减助战费用、摸牌、起手和攻击,缺少玩家能否承受后续怪物的依据;仁德换牌也不增加净手牌数量。 + +本版采用“先计算敌方整轮压力,再决定玩家可承担的防御成本和击杀时间”的方法。所有新规则均为策划建议,不能读成已经存在的机制。 + +## 2. 当前战斗规则及计算口径 + +### 2.1 已核对的事实 + +| 项目 | 当前实际规则 | 对平衡的影响 | +| --- | --- | --- | +| 刘备 | 50生命,3费用,默认摸2张,手牌上限3 | 不能默认每轮都有3张主动牌,更不能把3费用全部算作攻击 | +| 防御与回复 | 防御1费获得5护甲,强化为8;桃回复8;燃烧之血战后回复6 | 战后回复救不了战斗中的致死峰值 | +| 护甲 | 通常在持有者下次主循环回合开始时清除;保留类效果例外 | 护甲不能当作跨轮累计生命;给即将行动的助战护甲,可能先被清除 | +| 意图攻击 | 直接造成攻击伤害,没有【杀】的【闪】响应过程 | 不能把手中的闪自动算作抵消一次意图 | +| 普通敌人 | 摸1、上限3、费用2;大部分初始4张 | 意图后通常还留1费用 | +| 精英 | 摸2、上限5、费用3 | 意图后通常还留2费用 | +| Boss | 摸3、上限7、费用4 | 意图后通常还留3费用 | +| 关张 | 当前均40生命、起手4、摸2、上限5、费用3 | 两人尚无数值与意图差异 | +| 当前敌方牌组 | 包含杀、闪、桃、酒,较高阶还有决斗、无中、过河 | 原生出牌、响应及治疗都是额外变量 | +| 第一章 | 前3场普通胜利用弱池,之后用强池;专属首战不计数;当前章末结束内容 | 不能把第二、三章占位配置当成当前连续难度曲线 | + +来源:[战斗费用](../battle/combat-rules.js)、[卡牌效果](../cards/mode-cards.js)、[怪物属性与牌组](../monsters/monster.js)、[主循环与状态](../mode.js)、[普通胜场计数](../progression/encounter-progress.js)、[第一章地图](../content/acts/act1/map.js)。 + +### 2.2 应计算什么 + +以“刘备行动开始,到刘备下一次行动开始”为一轮,同时记录每个敌人实际执行的行动次数。下列简化表假设没有额外回合、击晕、提前死亡、反伤中断和异常状态;有这些效果时必须按实际行动重算。 + +- 每段攻击先计基础伤害与力量,再计虚弱、缩小,之后计目标易伤等修正。虚弱与缩小分别向下取整,易伤向上取整,不能先把所有段数合并再取整。 +- 基础攻击修正示例:`每段 = ceil(floor((基础伤害 + 力量) × 0.75) × 1.5)`,仅适用于同时有虚弱和易伤、没有其他修正的情况。 +- 一轮总压力 = 全部实际命中的意图伤害 + 实际命中的手牌攻击 + 感染/紧缠等额外伤害。 +- 生命损失按事件顺序抵扣当时护甲;不把同一份护甲重复用于多个敌人。没有中途增减护甲等效果时,才可简化为 `max(0, 本轮可抵扣伤害合计 - 本轮护甲)`。 +- 击杀所需时间同时取决于有效生命和实际输出。普通 `HP÷每轮输出` 只作估算;滑溜要数命中事件,雕像要数前置出牌,亡语要算下一批敌人。 +- 单独记录刘备和助战生命。当前全部意图打全队时,增加队友会增加队伍总承伤,不会降低刘备承伤。 + +**例如多尼斯异鸟3段啄击,+3力量后为6×3=18;若目标同时易伤,则9×3=27。绝不能算成9+3=12。** + +来源:[意图执行](../battle/intent-effects.js)、[意图伤害](../battle/intent-damage.js)。 + +## 3. 当前普通怪物:血量、循环与压力 + +以下数值均为当前值。`→循环`表示回到循环首项;“+力”在该次攻击结算后获得,除非注明开场增益。伤害均为单个目标承受的基础值,当前通常每名友方各受一份。HP范围采用入场随机函数,不用资料页中间值冒充固定血量。 + +| 敌人 | 当前HP | 当前意图与附加机制 | 主要问题 | +| --- | --- | --- | --- | +| 首关士兵 | 24 | 没有这批怪物的专属意图;依靠原生手牌、坐骑 | 单独作为教学战评价,不套专属意图伤害公式 | +| 毛绒伏地虫 | 55—57 | 酸液4→力量+7→酸液4→循环 | 实际前6次意图伤害4、0、11、11、0、18;第2次加力后仍可能出杀13 | +| 小啃兽 | 42—46 | 顶撞12→斩击6并护甲5→力量+2→循环 | 弱池首轮12,仍可能追加杀;双只从斩击、哈气错位开场 | +| 缩小甲虫 | 38—40 | 首次缩小,此后7与13交替;缩小令攻击伤害降低30%,源死亡解除 | 把玩家输出降低后,还按原DPS估计战斗时长会偏乐观 | +| 树叶史莱姆·小 | 11—15 | 每次等概率冲撞3或塞1黏液 | 随机重复塞牌拖慢循环 | +| 树叶史莱姆·中 | 32—35 | 塞2黏液→攻击8→循环 | 群怪战的卡手压力不能只计为0伤害 | +| 树枝史莱姆·小 | 7—11 | 每次攻击4 | 单只不高,和大怪同步时要合计 | +| 树枝史莱姆·中 | 26—28 | 首次塞1黏液,之后攻击11;黏液不连用,攻击最多连用两次 | 连续两轮11是实际允许分支 | +| 飞蝇菌子 | 48 | 猛砸11不连用;孢子8并2脆弱,间隔至少2次;2易伤第二次起可用,间隔至少3次 | 与同行怪物叠加易伤/脆弱,且座次决定当轮谁吃到增益 | +| 闪光贾克斯果 | 31—33 | 每次攻击3,之后力量+2 | 意图前4轮3、5、7、9;加力同时提高当轮后续杀 | +| 立柱构造体 | 65;初始13护甲、1人工制品 | 首次力量+2;以后攻击7并+2力、攻击7并+2力、5×2循环 | 实际前4次0、9、11、22;13初始护甲通常到其首回合开始被清除,并非永久加血 | +| 雾菇 | 74;眼6 | 首次召眼;重击8并+1力,最多连用两次,再头槌14;眼每次塞3晕眩 | 眼不必击杀才能获胜,但放任会降低摸到有效牌的概率 | +| 蛮兽 | 72 | 首次4×2;之后与14重击及一次性3易伤怒吼按约束抽选,同种攻击不连用 | 易伤后的14变21,仍未计额外出牌 | +| 藤蔓蹒跚者 | 61 | 6×2→8并1缠结→16→循环 | 缠结让下一次应对大伤害时攻击牌加费,抢杀能力下降 | +| 蛇行扼杀者 | 53—55 | 叠3紧缠→等概率7并护甲5或12→循环 | 紧缠在目标回合末造成可被护甲抵扣的非攻击伤害;来源存活时层数累计 | +| 墨宝 | 每只11—17,开场1滑溜;三只一组 | 奇数位刺击3,偶数位2×3起手;之后随机10或2×3与刺击交替 | 第一轮三只合计12,第二轮15—23;各自滑溜增加击杀所需命中次数 | + +循环源文件: [毛虫](../monsters/crawler-intent.js)、[小啃兽](../monsters/nibbit-intent.js)、[甲虫](../monsters/shrinker-intent.js)、[树叶小](../monsters/leafslime-intent.js)、[树叶中](../monsters/leafmedium-intent.js)、[树枝小](../monsters/twigslime-intent.js)、[树枝中](../monsters/twigmedium-intent.js)、[飞蝇](../monsters/flyconid-intent.js)、[贾克斯果](../monsters/jaxfruit-intent.js)、[立柱](../monsters/cubex-intent.js)、[雾菇](../monsters/fogmog-intent.js)、[蛮兽](../monsters/mawler-intent.js)、[藤蔓](../monsters/vine-intent.js)、[扼杀者](../monsters/strangler-intent.js)、[紧缠伤害](../monsters/strangler-constrict.js)、[墨宝](../monsters/inklet-intent.js)。 + +### 3.1 劫掠者必须作为组合评价 + +当前从5种成员随机取3名且不重复;表内HP为实际关卡抽取范围。 + +| 成员 | 当前HP | 当前循环 | +| --- | --- | --- | +| 暴徒 | 30—33 | 7伤害→力量+3→循环 | +| 刺客 | 18—23 | 每次10伤害 | +| 斧手 | 20—22 | 5伤害并护甲5→同招→12伤害→循环 | +| 弩手 | 18—21 | 护甲3→14伤害→循环 | +| 追踪手 | 21—25 | 首次2脆弱,此后每次1×8伤害;并非持续在两招间交替 | + +“刺客+弩手+追踪手”第二轮有10+14+8=32点意图伤害,对当前每名友方各结算一次;三名普通敌人还各可能出一张杀。该组合不能按三只低血量敌人处理。 + +来源:[三人编队](../content/acts/act1/raider-trio.js)、[实际循环](../monsters/raider-intent.js)。 + +## 4. 当前精英与 Boss 的完整威胁 + +### 4.1 精英 + +| 精英 | 血量与实际击杀要求 | 当前攻击循环 | 压力结论 | +| --- | --- | --- | --- | +| 多尼斯异鸟 | 81—84 | 17与3×3交替;每个自身回合结束+1力 | 前6次17、12、19、18、21、24;多段招增长更快 | +| 旧日雕像 | 127;己方每使用一张牌,后续攻击对它多10%伤害,同回合累计 | 沉睡→力量+10→每次13伤害 | 实际斩击23;只有沉睡明确取消出牌,苏醒轮仍可能出力量加成的手牌 | +| 异蛙寄生虫 | 61—64,死后生成4只17—21HP扭动虫,都要处理 | 塞3感染→4×4→循环;虫生成时跳过一次完整回合,此后错位执行6伤害与塞1感染/+2力 | 总需处理生命129—148;不能按62血精英定价。感染留在手中到弃牌前,每张造成3非攻击伤害 | + +来源:[异鸟](../monsters/byrdonis-intent.js)、[雕像](../monsters/effigy-intent.js)、[缓慢](../monsters/effigy-slow.js)、[异蛙与虫](../monsters/phrog-intent.js)、[亡语](../monsters/phrog-battle.js)、[感染](../cards/infection-card.js)。 + +### 4.2 Boss:当前逐轮意图伤害 + +以下只算意图,假定相关敌人持续存活、没有减伤和护甲。数值是对刘备的伤害;当前助战通常另承受同样一份。 + +| Boss/阶段 | 当前HP与机制 | 第1—8次行动的意图伤害 | +| --- | --- | --- | +| 墨影幻灵 | 173;初始9滑溜,每次实际失血至多1并耗1层;肢解塞3伤口 | 7、12、26、0、9、16、28、0,合计98 | +| 仪式兽一阶段 | 252;首招设置150血转换阈值,之后18伤害并+2力 | 若一直不转阶段:0、18、20、22、24、26、28、30 | +| 仪式兽二阶段 | 转换后力量归零,并跳过一次意图及出牌;之后咆哮→15→17并+3力 | 从二阶段首次咆哮起:0、15、17、0、18、20、0、21 | +| 同族小队 | 神官190+两信徒各58—59;只需杀神官即可获胜 | 三者均存活:18、16、9、14、26、10、33、24,合计150 | + +同族小队拆分:神官前8次为8、8、9、0、10、10、15、0;每名信徒为5、4、0、7、8、0、9、12。神官四步循环与信徒三步循环形成12轮组合;第11轮全部存活时,意图合计为53,不能只验第一圈。 + +仪式兽的150是生命阈值,不是150护甲。正常满血需先造成102实际生命损失才抵达该区间,并由符合条件的伤害事件触发转换;不能把血量写成252+150。 + +来源:[墨影](../monsters/vantom-intent.js)、[仪式兽](../monsters/beast-intent.js)、[同族](../monsters/kin-intent.js)、[Boss编队](../content/acts/act1/kin-group.js)、[意图实际执行](../monsters/actions.js)。 + +### 4.3 原生出牌造成的额外峰值 + +| 情景 | 意图 | 条件成立时的额外攻击 | 合计 | +| --- | --- | --- | --- | +| 墨影第3次行动 | 26 | 剩3费用,若有3杀且均合法使用、均未被闪抵消:18 | 44,另塞3伤口 | +| 同族第1轮 | 18 | 神官3杀+两信徒各1杀,均打刘备且命中:30 | 48,另施加脆弱 | +| 毛虫第2次行动 | 意图伤害0,力量+7 | 1杀,6+7=13 | 13,增益轮并不安全 | + +这些是有条件的压力情景,不是AI一定执行的行为,也不是全游戏理论上限。酒、其他增益、易伤、距离、手牌、选目标与响应都会改变结果。V0.1 用普通怪3—5回合、助战占比25%—40%作为直接平衡目标,依据不足。 + +## 5. V0.2 推荐采用的战斗规则 + +### 5.1 考虑过的两种路径 + +| 路径 | 做法 | 取舍 | +| --- | --- | --- | +| 保留自由出牌并降数值 | 保持当前全部意图打全队,敌人自由用剩余费用出牌,只降HP/伤害 | 改动较小,但意图仍不能解释整轮风险;需要大量对局才能约束峰值 | +| **意图明确目标,追加攻击也预告(本版推荐)** | 为招式区分单体/全体,收紧专属怪物的额外主动攻击,按完整预告调数值 | 需要调整执行与预告,换取可判断的防御窗口;保留有限的三国杀响应互动 | + +推荐路径由本提案提出,尚不代表用户已批准实现。下列参数以推荐路径为前提;如果保留当前无限制混合出牌,不可直接套用后面的承伤结论。 + +### 5.2 意图目标与原生响应 + +1. 普通怪和精英的意图默认单体,固定预告指向刘备;墨宝旋风、藤蔓挥击、异蛙甩动、异鸟啄击明确为全体。负面状态默认只施加给本次目标。 +2. Boss 招式按第8节逐招列出的目标执行。全体招式对每名友方结算完整伤害,不分摊;单体招式不暗中随机切到关张。 +3. 来源或目标提前死亡时取消对应效果,不在行动时临时换人;现有“刘备阵亡则结束征程”的流程优先。 +4. 脚本意图继续使用护甲、虚弱等机制应对,仍不能用闪直接抵消;预告中明确标注。实际追加的杀仍走闪、距离、装备等原生规则。 +5. 敌人的闪、对决斗打出的杀和濒死救援等响应继续保留;它们仍可能延长实际击杀时间,必须纳入游戏内采样。 + +### 5.3 限制意图后的额外主动出牌 + +对有专属意图的敌人,取消“发动完意图后任意主动出牌”。只允许下述事先预告的追加杀;不再自由主动使用桃、酒、无中、决斗或过河。没有专属意图的首关士兵仍按原流程行动。 + +- 普通遭遇:整支敌队每轮最多追加1张杀。该轮只有在意图原始合计伤害加该杀伤害不超过16时可选;含力量、段数,暂不计目标易伤、护甲及玩家减益。该值是基础预算,实际易伤后的伤害必须另行显示。 +- 精英遭遇:同口径上限20,整支敌队每轮最多追加1张杀。亡语生成的虫也共享额度。 +- Boss:仅墨影“墨迹”轮允许追加1杀;仪式兽、同族小队不额外主动出牌,使用其完整意图循环提供压力。 +- 只有本轮执行伤害意图的单位可以追加。整备、沉睡、苏醒、蓄力、召唤、单独施加负面状态和阶段击晕的单位不追加,形成真实准备窗口。 +- 在刘备行动前从符合条件的敌人已有手牌中选择并锁定1张实体杀,按固定座次选首个合格单位;不得把敌人随后新摸到的牌临时追加。预告显示来源、目标、伤害和“可用闪响应”。 +- 使用仍支付原费用并重新校验牌、距离、目标和战斗会话;牌被夺走、费用不足、单位被击晕时取消,不补抽、不替换、不补偿攻击。实际伤害按当时状态结算,预告随状态刷新。 +- 群怪原始意图本身已超过16/20时,不通过暗中削伤压回预算,而是禁止追加,并按第7节调整组合和出场时机。 + +这项规则会改变敌人手牌的主动用途,也减少主动回血造成的额外有效生命;因此它与后面的HP调整需要分批验证。 + +## 6. 刘备与助战:修订 V0.1 的内容 + +| 项目 | V0.2 建议 | 理由 | +| --- | --- | --- | +| 刘备基础 | 保持50生命、3费用、摸2、手牌上限3 | 先核对真实手牌吞吐;若缺牌再独立试摸3,不预先认定已有足够防御与输出 | +| 先天羁绊 | 仍提议关张可参战时100%到场,保留首战排除、濒死不能到场 | 核心玩法应可依赖 | +| 助战资源 | **撤回同时削费、削摸牌、削起手的建议**;首轮保留费用3、摸2、起手4、上限5、HP40 | 减少叠加削弱;先改敌方目标与意图,再观察输出占比 | +| 关羽意图 | 单体7→自身护甲8→单体10,循环;每次仍消耗1费用 | 集火,保留能应对群体攻击的防守轮 | +| 张飞意图 | 全敌各3→自身护甲8→全敌各4,循环;每次仍消耗1费用 | 清理低血随从,与关羽形成区别 | +| 仁德 | 沿用V0.1:1费用、每出牌阶段一次,给一张合规手牌/独行时弃一张,再摸1并自身护甲5 | 它是换牌与支援,不是净抽牌;不能当作每轮多摸1张 | +| 初始牌库 | 保留V0.1的12张提案:4杀、3防御、闪、桃、无中、八卦、重杀各1 | 提供防御、易伤和有限响应;首战不承诺关羽配合 | +| 炽焰/扯碎 | **撤回首轮立即削弱**;原数值作为候选基线,后续按力量多段与失血构筑实测处理 | 敌人和助战机制变化后,不能沿用旧假设直接砍关键输出 | +| 回复 | 休息基础30%最大生命向上取整仍列为后续独立实验;遗物额外休息回复另加;战后6保留 | 必须先保证战斗可生存,再评价跨关续航 | + +仁德的“不可转移/非状态/非诅咒”按卡牌实际资格判定;转交不等于打出。若实施为独立技能,需要明确仪式兽昏眩期间能否发动:本版建议**昏眩时仁德与主动牌共用一次主动行动额度**,避免技能绕过Boss限制;它不因此被视为卡牌,也不凭空触发出牌连锁。 + +新关羽优先攻击刘备最近一个自身回合最后攻击且仍存活的敌人,否则选最低生命敌人;张飞作用于全部存活敌人。护甲只给自己,避免“刘备先给关羽护甲、关羽回合开始立即清空”的时序问题。 + +## 7. 普通怪、编队与精英的建议参数 + +这是首轮试验值,不是已证明的最终值。未列出的机制保留;本节目标规则统一遵从5.2。所有修改按第10节分批加入,不一口气套用。 + +### 7.1 普通怪参数 + +| 敌人 | 当前HP → 建议HP | 意图建议 | 目标 | +| --- | --- | --- | --- | +| 首关士兵 | 24 → 24 | 保留原生出牌;不套专属意图限制 | 校准教学战 | +| 毛虫 | 55—57 → 45—48 | 4→加4力→4,循环 | 前6次变4、0、8、8、0、12;减缓滚雪球 | +| 小啃兽 | 42—46 → 36—40 | 顶撞12→10;斩击6→5、护甲5保留;加2力保留 | 压低弱池首轮冲击 | +| 缩小甲虫 | 38—40 → 34—36 | 缩小30%保留;7/13改7/11 | 用更低生命补偿其降低玩家输出的能力 | +| 树叶小/树枝小 | 11—15/7—11不变 | 3/4伤害保留,塞1黏液保留 | 让单体集火有明确击杀收益 | +| 树叶中 | 32—35 → 28—31 | 塞2黏液→1;伤害8→7 | 缓和多怪的卡手叠加 | +| 树枝中 | 26—28 → 24—26 | 扑击11→9,原连用限制保留 | 降低连续两轮尖峰 | +| 飞蝇菌子 | 48 → 42 | 猛砸11→9;伤害孢子8→6,脆弱2→1;易伤2保留 | 保留“先杀增伤源”的判断 | +| 贾克斯果 | 31—33 → 28—30 | 3伤害保留,每次+2力→+1力 | 增长3、4、5、6,便于给玩家集火时间 | +| 立柱 | 65 → 56;初始护甲13→10 | 开场+1力;重复轰击7并+1力,两次后4×2 | 前4次0、8、9、14,仍是成长型敌人 | +| 雾菇 | 74 → 64;眼6不变 | 重击8并+1力保留;头槌14→12;眼每次3晕眩→2 | 保留处理眼或抢杀本体的取舍 | +| 蛮兽 | 72 → 60 | 4×2保留;14→12;3易伤→2,怒吼一次限制保留 | 易伤重击由21降至18 | +| 藤蔓 | 61 → 54 | 全体5×2→单体6并缠结1→单体13 | 群体招更轻,缠结后仍有危险单体招 | +| 扼杀者 | 53—55 → 46—48 | 紧缠每次3→2;重击7/护甲5→6/4;甩动12→10 | 紧缠仍累计并由杀源解除 | +| 墨宝三只 | 各11—17保留 | 刺击3、全体2×3保留;凝视10→8;开场滑溜1保留 | 不同时削生命与破盾机制;控制随机爆发 | +| 劫掠者 | 五种原HP范围保留 | 暴徒5/加2力;刺客7;斧手4+护甲4、4+护甲4、9;弩手护甲3/10;追踪2脆弱后1×6 | 三人组合第二轮高压示例32→23,且无额外杀 | + +### 7.2 编队必须有出场时机和峰值验算 + +- 原有前3次普通胜利用弱池保持。前3胜保护已有普通化精英节点的逻辑,不重复设计一个冲突的保护。 +- 建议第4—5场普通战斗优先开放单体强敌与两单位组合;三墨宝、四史莱姆、劫掠者三人组从第6场普通战斗起加入。 +- 小啃兽双只继续错位起手。建议版前3轮意图为5、12、19:第一只“斩击、加力、顶撞”,第二只“加力、顶撞、斩击”。第3轮要在预告中表现为集火节点。 +- 甲虫+毛虫要同时计缩小对队伍输出的影响。优先杀甲虫释放输出,或抢杀毛虫阻止加力,都应有可行牌序;不要仅因总血量低于两只普通怪就判断简单。 +- 飞蝇与其他怪的组合应按实际座次计算:先施加易伤,后面的怪可能当轮受益;易伤层数在目标自己的回合结束衰减,不能按全局轮数随意扣。 +- 劫掠者3选5共有10种组合,全部检查前6轮。建议版“刺客+弩手+追踪手”第2轮仍有23原始伤害,作为晚段集火考验;若代表牌组在该轮前无法稳定杀掉一个低血目标,应继续降低该组合伤害或延后出现,不靠提高所有怪物血量修补。 +- 群怪阵亡后立即移除该单位余下行动、负面来源和后续轮贡献;“所有敌人永远存活”的表仅作为压力包络。 + +来源:[遭遇组成](../content/acts/act1/encounters.js)、[小啃兽双只](../content/acts/act1/nibbit-pair.js)。 + +#### 7.2.1 劫掠者10种组合的六轮压力表 + +以下按三人始终存活、原有循环起点不变计算,仅列对刘备的意图伤害;未加入手牌攻击、玩家护甲及状态修正。建议版采用7.1的参数。当前版同样的意图伤害通常还会对助战各结算一份,建议版这些招式均为单体刘备。 + +| 组合 | 当前第1—6轮 | 建议第1—6轮 | 六轮内最高意图伤害:当前→建议 | +| --- | --- | --- | --- | +| 暴徒+刺客+斧手 | 22、15、32、15、28、22 | 16、11、23、11、20、16 | 32→23 | +| 暴徒+刺客+弩手 | 17、24、20、24、23、24 | 12、17、14、17、16、17 | 24→17 | +| 暴徒+刺客+追踪手 | 17、18、28、18、31、18 | 12、13、20、13、22、13 | 31→22 | +| 暴徒+斧手+弩手 | 12、19、22、19、18、26 | 9、14、16、14、13、19 | 26→19 | +| 暴徒+斧手+追踪手 | 12、13、30、13、26、20 | 9、10、22、10、19、15 | 30→22 | +| 暴徒+弩手+追踪手 | 7、22、18、22、21、22 | 5、16、13、16、15、16 | 22→16 | +| 刺客+斧手+弩手 | 15、29、22、29、15、36 | 11、21、16、21、11、26 | 36→26 | +| 刺客+斧手+追踪手 | 15、23、30、23、23、30 | 11、17、22、17、17、22 | 30→22 | +| 刺客+弩手+追踪手 | 10、32、18、32、18、32 | 7、23、13、23、13、23 | 32→23 | +| 斧手+弩手+追踪手 | 5、27、20、27、13、34 | 4、20、15、20、10、25 | 34→25 | + +这张表说明建议值仍需要集火条件:例如“刺客+斧手+弩手”第6轮仍有26,“斧手+弩手+追踪手”仍有25。16点只是**追加杀的准入预算**,不是整轮伤害硬上限。对应超预算轮不追加杀;不能把这些组合标为已经平衡。 + +首轮实测优先检查第2次敌方行动前能否用正常手牌击杀刺客或弩手,并记录为此放弃的护甲和响应。若必须依赖极优起手或稀有卡,先降低相关成员伤害或延后组合开放,再复测;若常规集火已能稳定减员,则保留后续高压,让拖延具有明确代价。跟随追踪手的脆弱会使防御收益下降,仍须按实际逐张护甲向下取整,不能把上表直接减一个固定防御值就当成实战结果。 + +### 7.3 精英建议 + +| 精英 | 建议HP | 意图与机制调整 | 检验的能力 | +| --- | --- | --- | --- | +| 多尼斯异鸟 | 74—78 | 单体俯冲17→14;全体3×3保留;每回合+1力保留 | 前6次14、12、16、18、18、24,要求及时结束战斗或减力量/施虚弱 | +| 旧日雕像 | 108 | 沉睡、苏醒均无额外主动攻击;苏醒加10力→5;斩击基础13→11,即稳定单体16;缓慢机制保留 | 两轮准备后持续16,考验铺场和同回合多牌增伤 | +| 异蛙寄生虫 | 本体58—60;4虫各12—14 | 单体塞2感染与全体3×4交替;死亡仍生成4虫并各跳过一次完整回合;虫单体4与塞1感染/加1力错位循环 | 总生命106—116,考验在感染污染前杀本体并保留清场资源 | + +异蛙的4只虫是第二阶段战斗,不是奖励动画。不能在击杀本体时提前结算胜利;也不能按同族信徒的“杀首领即可赢”规则处理它。 + +## 8. 三类 Boss 的 V0.2 方案 + +### 8.1 墨影幻灵:多段破盾与伤口管理 + +| 参数 | 当前 → 建议 | +| --- | --- | +| HP | 173 → 150 | +| 初始滑溜 | 9 → 4;只初始化一次,按实际失血事件消耗 | +| 墨迹 | 7不变,单体刘备;允许预告追加1杀 | +| 墨水长枪 | 6×2 → 5×2,明确全体 | +| 肢解 | 26 → 18,单体刘备;伤口3→2,只加入被攻击且存活的目标个人弃牌堆 | +| 准备 | +2力→+1力,无主动出牌 | +| 循环 | 墨迹→长枪→肢解→准备→循环 | + +建议版前8次意图:**7、10、18、0、8、12、19、0**,合计74。假设两次墨迹轮都合法追加一张杀且命中,杀分别为6、7,则刘备总压力为**13、10、18、0、15、12、19、0**,合计87。关张只承受两次全体长枪,共22,不再完整复制刘备全部87点压力。 + +用“每轮恰有10护甲”的纯算术情景举例,刘备净损失为3、0、8、0、5、2、9、0,共27。没有把准备轮多余护甲挪到其他轮,也没有算战后回复。**此情景不证明2张摸牌、3费用能每轮同时打出10护甲与足够攻击,必须实战核对。** + +滑溜会使前4次真正掉血的事件每次最多掉1;不等于加4生命。若全是单段6伤害且全部命中、没有其他效果,150血+4滑溜需要4次各1伤害,再25次6伤害,共29次命中;同口径当前173血+9滑溜需37次。多段、非攻击伤害和响应会改变这个比较。 + +### 8.2 仪式兽:明确的转阶段窗口 + +| 参数 | 当前 → 建议 | +| --- | --- | +| HP | 252 → 180 | +| 转阶段阈值 | 150/252比例 → 明确108/180,即60%;覆写最大生命时按60%取整 | +| 一阶段 | 首次跺地设置阈值;之后单体14伤害并+1力,替代18并+2力 | +| 破阶段 | 保留符合条件伤害触发、力量归零、跳过一次意图与出牌 | +| 二阶段咆哮 | 对全体施加昏眩,下个自身回合只有一次主动行动;原生响应保留 | +| 二阶段踩踏 | 15 → 10,全体 | +| 二阶段碾碎 | 17/加3力 → 14/加1力,单体刘备 | +| 二阶段循环 | 咆哮→踩踏→碾碎→循环;无额外主动出牌 | + +**示例时间线,前提为玩家在第4个刘备行动中把Boss打到108或以下并成功触发转换:** + +| 敌方行动轮 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 行动 | 跺地 | 冲撞 | 冲撞 | 阶段击晕 | 咆哮 | 踩踏 | 碾碎 | 咆哮 | 踩踏 | 碾碎 | +| 对刘备意图伤害 | 0 | 14 | 15 | 0 | 0 | 10 | 14 | 0 | 11 | 15 | + +第4轮转阶段需要此前累计造成至少72实际伤害,平均约18/刘备行动;180生命希望在约8—10个玩家回合结束,需要整场实际输出约18—23/回合。它是检验牌组的目标,不是当前实测DPS。若第4轮没打到阈值,后续仍是16、17等一阶段冲撞,不能继续使用上表的安全窗口。 + +以每个危险轮8护甲示例,上表净损失合计31。昏眩后能否凑出8护甲尤其需要验证:一张未强化防御只有5,不能假设照常出两张牌。关张只承受表中两次全体踩踏,合计21;咆哮依然降低其有效输出。 + +### 8.3 同族小队:清随从与抢杀首领都应有价值 + +| 参数 | 当前 → 建议 | +| --- | --- | +| 神官HP | 190 → 140 | +| 两名信徒HP | 各58—59 → 各24—28 | +| 神官循环 | 单体6+1脆弱→单体6+1虚弱→全体3×2→自身+1力 | +| 信徒循环 | 单体4→单体2×2→自身+1力;两名仍同步起手 | +| 追加主动出牌 | 无;保留原生响应与濒死救援 | +| 胜利 | 杀神官获胜,仍不强制杀信徒;无新增召唤或复活 | + +全员存活时,前8轮对刘备意图为**14、14、6、10、19、7、20、16**,合计106;第11轮仍可达30。它仍是一个要求减员的Boss,不能宣称全部放着不管也已平衡。 + +若第3次敌方行动前已经杀掉一名信徒,且另一名始终存活,前8轮变为**14、14、6、5、13、7、14、10**,合计83。若每轮基础护甲8,受第1/5轮脆弱影响,第2/6轮只能获得6护甲,净损失为6、8、0、0、5、1、6、2,共28。神官第2轮施加虚弱还会降低随后玩家输出,此处没有把它忽略成免费的伤害窗口。 + +清一名随从约多花24—28点实际输出,却持续降低后续压力;抢杀神官只需处理140主体生命,但必须承担两名信徒全部攻击。建议以“第2轮能否杀掉一名信徒、杀后能否在第8轮附近结束”作为首轮验算,不把190+两只59全部当成强制击杀量。 + +## 9. 回合目标、牌组供给和跨关消耗 + +### 9.1 暂定的测试目标 + +“毛伤害”指实际扣血总量,尚未加回战中治疗及战后回复;它不同于意图原始伤害。 + +| 遭遇 | 暂定玩家回合数 | 对熟悉规则的代表牌组,刘备毛伤害目标 | 检查重点 | +| --- | --- | --- | --- | +| 首关 | 3—5 | 0—8 | 距离、坐骑、四回合剧情支援、提前胜利 | +| 弱池 | 3—5 | 4—10 | 不依赖稀有卡,单人也能通过 | +| 强池 | 4—6 | 8—16 | 组合优先击杀、应对状态牌 | +| 精英 | 5—8 | 14—24 | 有合理构筑后通过,失败能归因于战术或构筑缺口 | +| Boss | 7—10 | 20—32 | 约40以上生命进入时存在合理容错;各Boss按独立机制检验 | + +这些区间是设计目标,不是对全部种子、全部操作或未成型牌组的保证。第4次普通胜利后也不能机械把敌人整体再加血来满足回合数。 + +### 9.2 同时满足防御和输出 + +不能分别证明“能打20伤害”和“能有10护甲”就认定该回合可行;必须使用同一手牌、同一费用和同一响应消耗验证。 + +- 3费用中用2张基础防御取得10护甲后,只剩1费用,基础杀只能打6且可能被闪。 +- 每轮摸2、持续打出3张还要留闪,长期会缺牌。仁德给一摸一不增加刘备净手牌;助战也要花自己的费用用收到的牌。 +- 12张初始牌库的空转周期不等于固定6轮:起手、无中、保留手牌、响应、弃牌、消耗、状态牌都会改变它。 +- Boss前代表牌组至少分别验证:普通单体攻击构筑、易伤/力量构筑、消耗/多段构筑。不能只用一套极优稀有牌组来调全部Boss。 +- 若多数代表牌组付出一费防御后,仍常常无法形成有效进攻,单独比较“刘备每回合摸3”实验;先冻结其他数值,避免一起加摸牌、加费用、减敌血。 +- 昏眩、伤口、感染和缠结专门记录损失了多少有效出牌机会;不能都折成一个固定伤害系数。 + +### 9.3 续航与濒死 + +每场净变化按“入场生命+实际战中治疗-毛伤害+可生效的战后回复”计算,并受生命上限限制;阵亡时不能用战后6点逆转失败。 + +例如强池毛伤害12、没有战中治疗、战后实际回6,净耗6;连续4场约耗24,再考虑休息、商店和路线。休息由8提高至15的候选值应在这个背景下评估,而非仅与桃比较。 + +助战一旦濒死,当前救助取得途径尚不完整,必须测试缺席后能否继续推进。V0.2先用明确单体目标减少随机永久失去伙伴的风险;救助渠道作为后续独立设计项,不把未存在的免费复活计入生存预算。 + +## 10. 落地次序与验证要求 + +本次只交付方案。若后续实施,建议使用以下顺序,每阶段保留同种子对照,不把V0.2整包数值一次性落地。 + +1. **当前版本基线。** 记录实际入场HP、座次、起手、每次意图、力量、状态持续、主动牌、响应、护甲和净掉血;特别覆盖旧版墨影第3轮、同族第2/5/11轮、仪式兽转换和异蛙亡语。 +2. **先改威胁可读性与规则。** 实施单体/全体目标、受限且可预告的追加杀,冻结HP与其他伤害;确认没有隐藏的额外主动攻击,并观察仅此改动降低多少压力。 +3. **按遭遇逐个试建议HP与循环。** 先弱池,再强池组合,再精英,最后三个Boss。若第2阶段已经达到目标,相关降血/降伤可撤回,不机械执行全表。 +4. **再试刘备与助战。** 确定到场、关张差异、仁德和初始牌组分别记录效果;先保留助战原资源,确认是否确实需要削弱。 +5. **最后处理跨关续航及强构筑。** 单独试休息30%,再检查炽焰、扯碎及多段/消耗连锁,不用削核心牌补偿未处理的怪物问题。 + +建议首轮使用12组固定起始牌序/遭遇随机种子覆盖代表场景,不把同一随机种子的重复点击当独立样本。普通与精英各覆盖单独刘备、关羽、张飞;Boss另交叉3种代表牌组、至少2档入场生命(30/45)。无法一次完成时,先完成三个Boss及最高压群怪,不以少量样本发布精确胜率。 + +| 核对项 | 需要的记录/判据 | +| --- | --- | +| 循环正确 | 至少两圈;同族至少12轮包络;仪式兽分别覆盖早、正常、晚转换 | +| 伤害正确 | 按目标、按段、按当时力量及状态重算;示例中的53、44只是特定情景而非固定伤害 | +| 防御可行 | 同一手牌与费用同时满足防御和攻击;护甲不能跨自身回合误累计 | +| 群怪峰值 | 列出10种劫掠组合、三墨宝随机分支、双小啃兽错位、四史莱姆、飞蝇组合 | +| 实际减员 | 第一名敌人何时死、何时减少意图压力;不得只保留永远全员存活的模型 | +| 助战安全 | 被全体技能命中的轮次、是否在预告之外濒死、AI是否会用收到的牌 | +| 特殊机制 | 滑溜消耗、感染每张3伤害、亡语4虫、神官与雾菇胜利条件、击晕与昏眩区别 | +| 预告准确 | 显示目标与段数,额外杀单列;玩家改状态、夺牌或击杀后刷新;不给未锁定的新抽牌追加攻击 | +| 保存与兼容 | 旧存档现有牌组不强制重写;新数值作用范围明确;改过的规则说明同步 | + +参数数据、手算/脚本推演、隔离行为检查和真实游戏对局是不同证据。只有真实对局才能验证敌方AI、响应选择、抽牌波动、战斗耗时和体验;本版没有宣称这些已经完成。 + +## 11. 实施时必须同步的源码位置 + +| 事项 | 入口与约束 | +| --- | --- | +| 敌人HP | [monster.js](../monsters/monster.js)、各 `roll*Hp`、关卡单位覆盖及[角色资料](../content/scenario-characters.js);只改HEALTH可能被子类固定值或入场随机覆盖 | +| 意图目标、伤害与追加牌 | [actions.js](../monsters/actions.js)、[intent-effects.js](../battle/intent-effects.js)、[mode.js](../mode.js)及意图预告;不得只改文字 | +| 仪式兽阈值 | [beast-intent.js](../monsters/beast-intent.js)中当前比例150/252与阶段状态;新180HP下明确改60%,不能遗漏旧比例 | +| 状态牌数量 | [infection-card.js](../cards/infection-card.js)有本体必须3、虫必须1的校验,建议本体2必须连同校验调整;伤口、晕眩同样核对生成入口 | +| 助战与仁德 | [definitions.js](../bonds/definitions.js)、[state.js](../bonds/state.js)、[intents.js](../bonds/intents.js)、卡牌所有权与阶段限制;新单体关羽需要执行器支持 | +| 早期与后期组合 | [encounters.js](../content/acts/act1/encounters.js)、[state.js](../progression/state.js)、[encounter-progress.js](../progression/encounter-progress.js);按普通胜利次数,不按楼层替代 | +| 回复 | [rooms.js](../relics/rooms.js)、[rules.js](../relics/rules.js);先核对战中存活,后核对跨关净消耗 | + +本文是可审阅的联合平衡草案,关键建议是:**限制未预告的额外伤害,逐轮计算全队压力,保留Boss机制差异,并用相同资源约束同时验证输出与生存。** diff --git a/mengsan/tools/test-battle-hud.cjs b/mengsan/tools/test-battle-hud.cjs index cf176c0..e51b517 100644 --- a/mengsan/tools/test-battle-hud.cjs +++ b/mengsan/tools/test-battle-hud.cjs @@ -152,6 +152,36 @@ const server = http.createServer((req, res) => { assert.equal(initial.module,true,initial.error||'HUD mount module must exist');checks++; assert.equal(initial.parentKept,true);checks++; await page.waitForTimeout(70); + const releasedControls = await page.evaluate(() => { + const control = document.createElement('div'); + control.className = 'control'; + control.style.setProperty('left', '7px', 'important'); + ui.control.appendChild(control); + hud.refresh(); + const managed = control.style.left === 'auto'; + control.remove(); + hud.refresh(); + const released = control.style.left === '7px' && control.style.getPropertyPriority('left') === 'important'; + control.style.left = '13px'; + ui.control.appendChild(control); + hud.refresh(); + const reacquired = control.style.left === 'auto'; + control.remove(); + hud.refresh(); + const restoredAgain = control.style.left === '13px'; + const popup = document.createElement('div'); + popup.className = 'damage skill-popup'; + popup.style.left = game.me.offsetLeft + 'px'; + popup.style.top = game.me.offsetTop + 80 + 'px'; + ui.arena.appendChild(popup); + hud.refresh(); + const popupManaged = popup.classList.contains('mengsan-hud-notification-shuying'); + popup.remove(); + hud.refresh(); + return { managed, released, reacquired, restoredAgain, popupManaged, + popupReleased: !popup.classList.contains('mengsan-hud-notification-shuying') }; + }); + assert.ok(Object.values(releasedControls).every(Boolean), 'detached controls and notifications release HUD ownership and can be acquired again: ' + JSON.stringify(releasedControls));checks++; await page.evaluate(()=>testFan.sync(true)); const corners=await page.evaluate(()=>({portrait:parseFloat(getComputedStyle(game.me.node.avatar).borderTopLeftRadius)})); assert.ok(corners.portrait>=12,'portrait retains rounded edges: '+JSON.stringify(corners));checks++; diff --git a/mengsan/ui/hud/index.js b/mengsan/ui/hud/index.js index 6fe99d5..d8d4442 100644 --- a/mengsan/ui/hud/index.js +++ b/mengsan/ui/hud/index.js @@ -8,11 +8,24 @@ export function mountBattleHUD(player, battle, env) { if (!arena || !ui.me || !ui.control || !battle.session.active) throw new Error('梦三 HUD 缺少原生界面容器'); const handRoot = ui.me, controlRoot = ui.control; const overlays = createOverlayLayout(arena, handRoot, ui, player); - const restores = [], styled = new WeakMap(), hiddenMarks = new Set(); + const restores = [], nodeRestores = new Map(), styled = new WeakMap(), hiddenMarks = new Set(); let disposed = false, frozen = false, frame = null, dialog = null, previousFocus = null, resize, observer; + const retain = (node, restore) => { + let releases = nodeRestores.get(node); + if (!releases) nodeRestores.set(node, releases = []); + releases.push(restore); + }; + const releaseNodes = (detachedOnly = false) => { + for (const [node, releases] of nodeRestores) { + if (detachedOnly && node.isConnected) continue; + for (const restore of releases.reverse()) restore(); + nodeRestores.delete(node); + styled.delete(node); + } + }; const ownClass = (node, name) => { if (!node || node.classList.contains(name)) return; - node.classList.add(name); restores.push(() => node.classList.remove(name)); + node.classList.add(name); retain(node, () => node.classList.remove(name)); }; const style = (node, key, value) => { let values = styled.get(node); @@ -20,7 +33,7 @@ export function mountBattleHUD(player, battle, env) { if (!values.has(key)) { const old = node.style.getPropertyValue(key), priority = node.style.getPropertyPriority(key); const record = { last: null }; values.set(key, record); - restores.push(() => { + retain(node, () => { if (node.style.getPropertyValue(key) !== record.last) return; if (old) node.style.setProperty(key, old, priority); else node.style.removeProperty(key); }); @@ -348,6 +361,9 @@ export function mountBattleHUD(player, battle, env) { function refresh() { if (disposed || frozen) return; if (!battle.session.active || !arena.isConnected || !handRoot.isConnected || ui.me !== handRoot || ui.control !== controlRoot) { dispose(); return; } + // Closed native controls and expired popups must not stay retained for the whole battle. + // Restore them before forgetting their snapshots so reused nodes get a fresh baseline. + releaseNodes(true); text(name, nameOf(player)); text(hp, `生命 ${player.hp} / ${player.maxHp}`); text(block, `格挡 ${player.hujia || 0}`); healthFill.style.width = `${Math.max(0, Math.min(100, player.maxHp > 0 ? player.hp / player.maxHp * 100 : 0))}%`; text(energy, `费用 ${player.storage.mengsanEnergy_shuying ?? 0} / ${player.storage.mengsanMaxEnergy_shuying ?? 0}`); @@ -366,6 +382,7 @@ export function mountBattleHUD(player, battle, env) { frozen=true;window.clearInterval(timer); if(frame!==null){window.cancelAnimationFrame(frame);frame=null;} observer?.disconnect();resize?.disconnect();closeDialog();overlays.dispose(); + releaseNodes(true); ownClass(arena,'mengsan-hud-frozen-shuying'); } function dispose() { @@ -378,6 +395,7 @@ export function mountBattleHUD(player, battle, env) { closeDialog(); for (const mark of hiddenMarks) mark.classList.remove('mengsan-hud-represented-mark-shuying'); hiddenMarks.clear(); for (const restore of restores.reverse()) restore(); + releaseNodes(); root.remove(); link.remove(); } ownClass(document.body, 'mengsan-hud-active-shuying'); ownClass(arena, 'mengsan-hud-arena-shuying');