fixed # 归档梦三战斗生命周期修复

This commit is contained in:
2026-10-13 10:44:41 +08:00
parent 9f485a1401
commit 5063ba0042
5 changed files with 447 additions and 0 deletions
@@ -0,0 +1,32 @@
# Outcome
修复梦三独立审查确认的两项战斗生命周期缺陷:整角色退出遗漏装备技能登记,以及引擎忽略异常时战斗准备失败导致外部控制器永久等待。目标是减少连续对局残留,并让准备失败能自动记录诊断、停止开战、进入已有异常退出提示。
# Scope
仅修改梦三的战斗准备、整角色技能释放及相关回归测试。调查依据为主工作区 docs/reviews/mengsan-20261013.md 的两项已确认问题,以及本地无名 1.11.5.2 的原生 GameEvent、装备触发登记和释放实现;审查报告用于定位,不作为全包功能改造需求。
修复基线为主工作区 main 的 28f7096 加用户已有的未提交受保护技能修复。进入 Build 后将以下已有文件的当前内容同步到隔离工作目录,再实施本次最小修复:.gitignore、mengsan/README.md、mengsan/battle/battle-flow.js、mengsan/battle/skill-teardown.js、mengsan/mode.js、tools/test_skill_teardown.mjs。保留这些文件中已有的结算提交状态、失败不重放及诊断行为,不修改主工作区。
关键行为:装备和已初始化的触发登记必须按角色释放;需要执行的原生装备卸载子事件在删除角色节点前完成。准备异常在梦三内容边界传递给外部控制器,不能依赖引擎 root.start() 是否拒绝。
# Non-goals
不改无名引擎或其他扩展;不清空公共技能/触发表;不删除 fixed、superCharlotte 标签或技能定义;不调整卡牌、羁绊、遗物、奖励规则。不全面修复审查中发现的旧测试夹具失配;只新增或调整本次相关有效回归。PC/安卓整局实机验证没有运行环境,不宣称已完成。此阶段不提交、合并、推送或发布,回到主工作区交付需在验证结果确认后决定。
# Acceptance examples
- 装备八卦等只登记于装备/已初始化技能来源的角色整局退出后,该旧角色的 initedSkills 和对应触发登记清除;连续退出多局不累积这些登记。
- 需要执行的装备卸载回调及其子事件在整角色销毁之前完成;回调失败可向外部传播并记录,已执行的释放回调不会因重试再次运行。
- 既有受保护技能策略保持:纯元数据标记可以保留在退场对象上,活动技能正确释放,局内单技能保护继续有效;其他角色持有的共享全局技能登记保持有效。
- 战斗准备抛出异常时,无论引擎 ignore_error 为 true 或 false,外部控制器都能收到原始异常并结束等待,进入已有战斗异常退出路径,不继续战斗或进入奖励结算。
- 准备失败生成梦三诊断记录并保留原始错误上下文;该失败路径不提交胜负结果、不改变上次成功存档、不发放奖励;正常准备和正常结算路径继续有效。
- 提供可重复执行的装备登记与原生事件异常回归,相关受保护技能/结算/诊断回归通过;独立只读验证报告明确列出未实测的 PC 和安卓整局限制。
# Constraints and invariants
只操作梦三拥有的战斗和角色资源。维持现有事件排空顺序、存档事务和奖励去重语义,不修改通用 Player.prototype。使用原生登记/卸载和 GameEvent 代码核对兼容性,不用与实现同形的空桩代替关键因果验证。
# Decisions
此前用户已选择在当前目录审查最新代码和未提交修复。此次 CLI 明确拒绝第二活动任务复用当前目录;因此为梦三单独创建 codex/mengsan-lifecycle-fixes 工作目录,原天书任务保留。两项缺陷涉及同一生命周期,采用一个 Native change 顺序处理,不拆分并行实现任务。正式验证使用新启动的 GPT-6.1 Sol 高推理只读验证者。
@@ -0,0 +1,255 @@
schema: comet.native.v4
name: mengsan-lifecycle-fixes
language: en
phase: archive
status: done
state_version: 11
brief: brief.md
document_constraints_version: 2
shape_confirmation_hash: e9c151b43d8a9b61035c6dbcf96cdc2d8e4c276b78f160cbc8bc26a67647abbf
spec_changes:
- capability: mengsan-battle-lifecycle
operation: create
source: specs/mengsan-battle-lifecycle/spec.md
workspace:
isolation: worktree
change_branch: codex/mengsan-lifecycle-fixes
target_branch: main
finish: merge
loop:
stage: done
goal_cycle: 1
iteration: 1
attempt: 1
retry_epoch: 0
failed_iteration_count: 0
no_progress_count: 0
execution_failure_count: 0
previous_unresolved_ids: []
next_action: null
acceptance:
- id: A1
source: brief.md
text: 装备八卦等只登记于装备/已初始化技能来源的角色整局退出后,该旧角色的 initedSkills 和对应触发登记清除;连续退出多局不累积这些登记。
result: passed
reason:
text: skill-teardown.js:125-130、142-150、184-216 清点 initedSkills 与装备技能,按角色使用原生
removeEquipTrigger/removeSkillTrigger。test_battle_lifecycle.mjs:108-140
使用本地1.11.5.2原生方法验证连续三局八卦旧角色登记归零、仅初始化来源和另一角色登记保留;Runtime regressions
第1-2行通过。
truncated: false
- id: A2
source: brief.md
text: 需要执行的装备卸载回调及其子事件在整角色销毁之前完成;回调失败可向外部传播并记录,已执行的释放回调不会因重试再次运行。
result: passed
reason:
text: skill-teardown.js:148-182 包装本次装备卸载产生的已编译事件及后代内容,排空后记录并抛出原始失败;93-117
正常退出释放根事件,131-133、223 缓存操作避免重放。battle-flow.js:52-60
在session.dispose前等待释放;test_battle_lifecycle.mjs:143-171、241-254
验证回调/子事件顺序、两种ignore_error失败传播、一次执行及栈排空,Runtime第3-5、9-10行通过。
truncated: false
- id: A3
source: brief.md
text: 既有受保护技能策略保持:纯元数据标记可以保留在退场对象上,活动技能正确释放,局内单技能保护继续有效;其他角色持有的共享全局技能登记保持有效。
result: passed
reason:
text: skill-teardown.js:5-15、184-197 保留纯元数据受保护标记,10-90
区分活动技能整角色卸载与局内保护。test_skill_teardown.mjs:40-119及121-158的9项回归通过;test_battle_lifecycle.mjs:127-140
以原生globalmap确认另一角色共享全局登记保留;未清空公共hook/skill或修改Player原型。
truncated: false
- id: A4
source: brief.md
text: 战斗准备抛出异常时,无论引擎 ignore_error 为 true 或
false,外部控制器都能收到原始异常并结束等待,进入已有战斗异常退出路径,不继续战斗或进入奖励结算。
result: passed
reason:
text: mode.js:900-919
在prepareBattle内容内保存原始错误、requestStop,root.start排空后唤醒外层;920-930
异常提示及模式选择分支绕过结算。与原生gameEvent.js:196-257吞错/栈弹出逻辑一致;test_battle_lifecycle.mjs:208-227
两种ignore_error在2秒内退出、Error身份一致、栈为空,Runtime第6-7行通过。
truncated: false
- id: A5
source: brief.md
text: 准备失败生成梦三诊断记录并保留原始错误上下文;该失败路径不提交胜负结果、不改变上次成功存档、不发放奖励;正常准备和正常结算路径继续有效。
result: passed
reason:
text: mode.js:900-906记录原始Error与sessionId/runId/nodeId;失败分支928返回,不进入930结算。mode-storage.js:11-16、125-126读取存档副本,准备期间不提交新结果;test_battle_lifecycle.mjs:208-239、256-280
验证失败存档基线不变、提交0次、实际临时诊断JSON含原栈/节点和正常提交1次。结算后清理失败不重发奖励及相关诊断/事务回归通过。
truncated: false
- id: A6
source: brief.md
text: 提供可重复执行的装备登记与原生事件异常回归,相关受保护技能/结算/诊断回归通过;独立只读验证报告明确列出未实测的 PC 和安卓整局限制。
result: passed
reason:
text: 完整brief和Spec的A1-A6均独立核查。Runtime state.json:5-8、25-70
当前候选绑定和工作区正确,regressions 46 tests/46 pass/0 fail/skip;syntax
exitCode=0。关键回归抽取本地1.11.5.2原生GameEvent、ArrayCompiler、Player与全局登记卸载源码;README.md:60-62提供重复入口及PC/安卓限制。复用有效检查,无重复整套运行。
truncated: false
builder_handoff:
candidate_id: 013d3893-4bba-4fb3-81e1-46b49e47e09b
identity_provider: skill-coordinated
builder_execution_ref: skill-coordinated:builder:7a547236-6f9c-4f1e-92e9-ae185431d904
iteration: 1
summary:
text: 补齐退场角色装备及 initedSkills
登记释放,等待并捕获装备卸载子事件异常;准备内容内捕获原始错误,停止会话,根事件正常排空后唤醒外部协调者。保留已同步的受保护技能兼容修复、提交状态和奖励去重。
truncated: false
addressed_acceptance_ids:
- A1
- A2
- A3
- A4
- A5
- A6
acceptance_review:
- id: A1
status: implemented-with-evidence
evidence:
- mengsan/battle/skill-teardown.js:createPlayerTeardown;tools/test_battle_lifecycle.mjs
连续三局原生八卦注册释放及仅 initedSkills 来源回归通过
note: 按角色调用原生 removeEquipTrigger/removeSkillTrigger,补齐登记来源,不清空公共表。
- id: A2
status: implemented-with-evidence
evidence:
- skill-teardown.js 装备事件局部边界和 waitNext;原生 onLose/嵌套子事件错误在 ignore_error
true/false 均传播、队列排空和一次执行回归通过
note: 事件内容已编译,仅包装当前装备卸载产生的事件及后代;复用缓存操作避免重放。
- id: A3
status: implemented-with-evidence
evidence:
- tools/test_skill_teardown.mjs 9/9 通过;test_battle_lifecycle 原生
addGlobalSkill/removeGlobalSkill 保留另一角色所有权回归通过
note: 同步并保留现有保护策略、纯元数据标记和局内单技能边界。
- id: A4
status: implemented-with-evidence
evidence:
- mengsan/mode.js:playBattle 内容内 failBattle 边界;原生
GameEvent.loop/ArrayCompiler 两种 ignore_error 准备抛错回归通过
note: 原始错误在引擎可能吞错前保存;正常根事件排空后结束外层等待,不进入结算。
- id: A5
status: implemented-with-evidence
evidence:
- test_battle_lifecycle 准备失败写出实际临时报告
JSON,检查原始错误栈/节点;存档基线不变、提交计数0;正常结算计数1;protected teardown 提交后失败不重发奖励回归通过
note: 调用现有诊断接口,不改存档事务,失败走保留存档退出路径。
- id: A6
status: implemented-with-evidence
evidence:
- 新增 tools/test_battle_lifecycle.mjs 11/11 通过,相关 skill teardown 9/9
通过;mengsan/README.md 记录回归入口及实机限制
note: 已提供可重复回归和正式检查计划,提交后按 Native 协议启动新的只读验证者;正式验收结果尚未宣称通过。
checks:
- name:
text: targeted lifecycle and protected teardown
truncated: false
result: passed
note:
text: 20/20;后续仅格式调整后生命周期11/11再次通过。
truncated: false
- name:
text: diff whitespace
truncated: false
result: passed
note:
text: git diff --check 通过;正式候选需复核最终修改。
truncated: false
checks_truncated: false
known_limits:
- text: 未执行PC或安卓客户端整局;本地引擎证据为无名1.11.5.2的原生事件/编译器和登记卸载函数,外围服务为最小依赖桩。
truncated: false
- text: 未修改其他扩展或无名引擎;不承诺所有外部扩展及所有客户端版本兼容。
truncated: false
- text: 旧审查的16个旧夹具失败未全面改造,本次仅相关有效回归。
truncated: false
- text: 实现位于独立工作目录;尚未提交合并推送发布。
truncated: false
- text: codebase-memory技能已读取,但本会话未暴露图谱工具,结构证据以源码核对为准。
truncated: false
known_limits_truncated: false
review: null
submitted_at: 2026-10-13T02:25:19.819Z
blockers: []
verification:
candidate_id: 013d3893-4bba-4fb3-81e1-46b49e47e09b
identity_provider: skill-coordinated
verifier_execution_ref: skill-coordinated:verifier:59515ca5-0d91-4ded-9343-b64a59ac88d9
iteration: 1
attempt: 1
assurance: skill-coordinated
verdict: pass
checks:
- id: regressions
name:
text: relevant-regressions
truncated: false
argv_display:
- text: -NoProfile
truncated: false
- text: -Command
truncated: false
- text: $env:NONAME_ROOT = 'D:\Work\noname\resources\app'; & 'C:\Program
Files\nodejs\node.exe' --experimental-vm-modules --test
tools/test_battle_lifecycle.mjs tools/test_skill_teardown.mjs
tools/test_diagnostics.mjs tools/test_mobile_memory.mjs
tools/test_intent.mjs tools/test_event_compilation.mjs; exit
$LASTEXITCODE
truncated: false
argv_truncated: false
cwd_ref: .
status: passed
exit_code: 0
duration_ms: 763
- id: syntax
name:
text: syntax-and-whitespace
truncated: false
argv_display:
- text: -NoProfile
truncated: false
- text: -Command
truncated: false
- text: "& 'C:\\Program Files\\nodejs\\node.exe' --check
mengsan/battle/skill-teardown.js; if ($LASTEXITCODE -ne 0) { exit
$LASTEXITCODE }; & 'C:\\Program Files\\nodejs\\node.exe' --check
mengsan/mode.js; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE };
git diff --check; exit $LASTEXITCODE"
truncated: false
argv_truncated: false
cwd_ref: .
status: passed
exit_code: 0
duration_ms: 461
summary:
text: 独立只读验收A1-A6全部通过;当前候选正式回归46/46与语法检查通过,未发现本次范围内实质失败。PC/安卓整局未实测。
truncated: false
risks:
- text: 未执行PC或安卓客户端完整对局;验收依据为源码核查和自动化回归,不能视为实机证明。
truncated: false
- text: 原生事件/编译器/登记卸载方法由本地无名1.11.5.2源码抽取,事件管理器、界面、外围服务和结算入口有最小依赖桩;不承诺其他客户端版本或所有外部扩展改写兼容。
truncated: false
risks_truncated: false
completed_at: 2026-10-13T02:32:58.872Z
history:
- goal_cycle: 1
iteration: 1
attempt: 1
outcome: pass
unresolved_ids: []
summary:
text: 独立只读验收A1-A6全部通过;当前候选正式回归46/46与语法检查通过,未发现本次范围内实质失败。PC/安卓整局未实测。
truncated: false
completed_at: 2026-10-13T02:32:58.872Z
history_overflow:
dropped_entries: 0
first_dropped_at: null
last_dropped_at: null
outcome_counts:
pass: 0
fail: 0
blocked: 0
execution-error: 0
recovery: 0
verification_result: pass
verification_report: verification.md
archived: true
created_at: 2026-10-13T02:05:19.971Z
@@ -0,0 +1,47 @@
# 梦三战斗生命周期
## 资源所有权与退出顺序
梦三每场战斗拥有自己的会话、角色及相关资源。正常结算先停止玩法根事件并排空子事件,再提交结果,完成整角色技能和装备登记的释放,最后销毁角色及界面资源并返回地图或结局。释放失败保留已提交结果,不重复奖励,不盲目重放部分执行过的回调。
整角色退出的登记清点包括角色技能、隐藏技能、不可见技能、临时技能、附加技能、装备技能及已初始化的触发登记。释放仅针对当前退场角色,使用引擎的角色级卸载能力,保留其他角色的共享登记;不能以清空公共 lib.hook、删除 lib.skill 定义或修改全局 Player 原型实现。装备卸载要求的回调及子事件必须在角色节点销毁前完成。
### Scenario: 装备登记完整释放
Acceptance: A1
装备八卦等技能只通过装备触发接口登记、没有出现在 player.skills 时,整角色退出仍移除该角色的相应 initedSkills 和触发条目。重复多场独立战斗退出后,不累积旧角色登记。
### Scenario: 卸载回调完成与失败传播
Acceptance: A2
存在原生装备卸载回调时,退出流程执行并等待其子事件后才能销毁角色。回调失败时记录失败并向外层传播,不能报为成功;同一退出操作重试不会重新调用已执行的释放回调。
## 受保护技能和共享登记
fixed 和 superCharlotte 是需要识别的兼容标记,不删除定义上的标记。纯元数据标记可保留在退场对象上;具有触发器、mod、onremove 或标记资源回调等活动行为的技能在整角色退出时需要释放。局内移除单技能继续遵守保护边界。一个角色退出不应撤销仍由其他角色持有的共享全局技能。
### Scenario: 保留既有兼容边界
Acceptance: A3
纯元数据 chaofeng_common 类标记不会阻止退出;活动受保护技能被释放且标记定义不变。局内单技能保护有效,其他角色持有的共享全局登记在退场角色卸载后仍有效。
## 战斗准备的异常边界
战斗准备使用梦三自己的内容边界捕获异常,保存原始错误并通知外部战斗协调者;不能仅依赖引擎对 root.start() 的拒绝。协调者结束等待后进入现有战斗异常提示及保留存档退出路径,停止继续开战。错误消息与原始栈、会话和准备阶段上下文通过现有梦三诊断系统记录。
### Scenario: 引擎忽略异常仍结束等待
Acceptance: A4
准备抛错,在 ignore_error 开启或关闭时均将原始错误送达外部协调者、结束等待、走战斗异常退出路径;不开始后续战斗或奖励结算。正常内容边界不将成功准备误判为异常。
### Scenario: 诊断与存档不变性
Acceptance: A5
准备失败留下可定位的梦三诊断错误记录;失败前已保存的征程仍有效,不写入新胜负结果或奖励。正常准备和正常结算仍按原先事务提交和奖励去重行为运行。
## 验证边界
### Scenario: 可重复回归与独立验证
Acceptance: A6
关键装备登记和事件吞错回归使用本地原生引擎实现或可验证的原生接口接入,在项目中可重复执行。相关受保护技能、结算和诊断检查通过,由独立只读验证者核查六项验收。验证记录明确指出仅有源码和自动化回归证据,没有 PC/安卓整局实机证明。
@@ -0,0 +1,66 @@
---
generated_from_state_version: 11
---
# Verification
## Current result
- Result: **Archived**
- Verification status: **Checks completed; result confirmed**
- Goal cycle: 1
- Iteration: 1
- Verifier attempt: 1
- Completed: 2026-10-13T02:32:58.872Z
- Summary: 独立只读验收A1-A6全部通过;当前候选正式回归46/46与语法检查通过,未发现本次范围内实质失败。PC/安卓整局未实测。
## Acceptance
| ID | Result | Source | Criterion | Reason |
| --- | --- | --- | --- | --- |
| A1 | passed | brief.md | 装备八卦等只登记于装备/已初始化技能来源的角色整局退出后,该旧角色的 initedSkills 和对应触发登记清除;连续退出多局不累积这些登记。 | skill-teardown.js:125-130、142-150、184-216 清点 initedSkills 与装备技能,按角色使用原生 removeEquipTrigger/removeSkillTrigger。test_battle_lifecycle.mjs:108-140 使用本地1.11.5.2原生方法验证连续三局八卦旧角色登记归零、仅初始化来源和另一角色登记保留;Runtime regressions 第1-2行通过。 |
| A2 | passed | brief.md | 需要执行的装备卸载回调及其子事件在整角色销毁之前完成;回调失败可向外部传播并记录,已执行的释放回调不会因重试再次运行。 | skill-teardown.js:148-182 包装本次装备卸载产生的已编译事件及后代内容,排空后记录并抛出原始失败;93-117 正常退出释放根事件,131-133、223 缓存操作避免重放。battle-flow.js:52-60 在session.dispose前等待释放;test_battle_lifecycle.mjs:143-171、241-254 验证回调/子事件顺序、两种ignore_error失败传播、一次执行及栈排空,Runtime第3-5、9-10行通过。 |
| A3 | passed | brief.md | 既有受保护技能策略保持:纯元数据标记可以保留在退场对象上,活动技能正确释放,局内单技能保护继续有效;其他角色持有的共享全局技能登记保持有效。 | skill-teardown.js:5-15、184-197 保留纯元数据受保护标记,10-90 区分活动技能整角色卸载与局内保护。test_skill_teardown.mjs:40-119及121-158的9项回归通过;test_battle_lifecycle.mjs:127-140 以原生globalmap确认另一角色共享全局登记保留;未清空公共hook/skill或修改Player原型。 |
| A4 | passed | brief.md | 战斗准备抛出异常时,无论引擎 ignore_error 为 true 或 false,外部控制器都能收到原始异常并结束等待,进入已有战斗异常退出路径,不继续战斗或进入奖励结算。 | mode.js:900-919 在prepareBattle内容内保存原始错误、requestStop,root.start排空后唤醒外层;920-930 异常提示及模式选择分支绕过结算。与原生gameEvent.js:196-257吞错/栈弹出逻辑一致;test_battle_lifecycle.mjs:208-227 两种ignore_error在2秒内退出、Error身份一致、栈为空,Runtime第6-7行通过。 |
| A5 | passed | brief.md | 准备失败生成梦三诊断记录并保留原始错误上下文;该失败路径不提交胜负结果、不改变上次成功存档、不发放奖励;正常准备和正常结算路径继续有效。 | mode.js:900-906记录原始Error与sessionId/runId/nodeId;失败分支928返回,不进入930结算。mode-storage.js:11-16、125-126读取存档副本,准备期间不提交新结果;test_battle_lifecycle.mjs:208-239、256-280 验证失败存档基线不变、提交0次、实际临时诊断JSON含原栈/节点和正常提交1次。结算后清理失败不重发奖励及相关诊断/事务回归通过。 |
| A6 | passed | brief.md | 提供可重复执行的装备登记与原生事件异常回归,相关受保护技能/结算/诊断回归通过;独立只读验证报告明确列出未实测的 PC 和安卓整局限制。 | 完整brief和Spec的A1-A6均独立核查。Runtime state.json:5-8、25-70 当前候选绑定和工作区正确,regressions 46 tests/46 pass/0 fail/skip;syntax exitCode=0。关键回归抽取本地1.11.5.2原生GameEvent、ArrayCompiler、Player与全局登记卸载源码;README.md:60-62提供重复入口及PC/安卓限制。复用有效检查,无重复整套运行。 |
## Checks
| Check | Command | Working directory | Status | Exit | Duration |
| --- | --- | --- | --- | ---: | ---: |
| relevant-regressions | -NoProfile -Command $env:NONAME_ROOT = 'D:\Work\noname\resources\app'; & 'C:\Program Files\nodejs\node.exe' --experimental-vm-modules --test tools/test_battle_lifecycle.mjs tools/test_skill_teardown.mjs tools/test_diagnostics.mjs tools/test_mobile_memory.mjs tools/test_intent.mjs tools/test_event_compilation.mjs; exit $LASTEXITCODE | . | passed | 0 | 763 ms |
| syntax-and-whitespace | -NoProfile -Command & 'C:\Program Files\nodejs\node.exe' --check mengsan/battle/skill-teardown.js; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; & 'C:\Program Files\nodejs\node.exe' --check mengsan/mode.js; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; git diff --check; exit $LASTEXITCODE | . | passed | 0 | 461 ms |
### Builder-reported evidence
These are Builder reports, not Runtime check receipts or independent verification results.
- targeted lifecycle and protected teardown: passed — 20/20;后续仅格式调整后生命周期11/11再次通过。
- diff whitespace: passed — git diff --check 通过;正式候选需复核最终修改。
- Known limitation: 未执行PC或安卓客户端整局;本地引擎证据为无名1.11.5.2的原生事件/编译器和登记卸载函数,外围服务为最小依赖桩。
- Known limitation: 未修改其他扩展或无名引擎;不承诺所有外部扩展及所有客户端版本兼容。
- Known limitation: 旧审查的16个旧夹具失败未全面改造,本次仅相关有效回归。
- Known limitation: 实现位于独立工作目录;尚未提交合并推送发布。
- Known limitation: codebase-memory技能已读取,但本会话未暴露图谱工具,结构证据以源码核对为准。
## Blockers
_None._
## Risks and skipped work
- 未执行PC或安卓客户端完整对局;验收依据为源码核查和自动化回归,不能视为实机证明。
- 原生事件/编译器/登记卸载方法由本地无名1.11.5.2源码抽取,事件管理器、界面、外围服务和结算入口有最小依赖桩;不承诺其他客户端版本或所有外部扩展改写兼容。
## Previous iterations
| Goal cycle | Iteration | Attempt | Outcome | Unresolved | Summary | Completed |
| ---: | ---: | ---: | --- | --- | --- | --- |
| 1 | 1 | 1 | pass | — | 独立只读验收A1-A6全部通过;当前候选正式回归46/46与语法检查通过,未发现本次范围内实质失败。PC/安卓整局未实测。 | 2026-10-13T02:32:58.872Z |
## Conclusion
独立只读验收A1-A6全部通过;当前候选正式回归46/46与语法检查通过,未发现本次范围内实质失败。PC/安卓整局未实测。
@@ -0,0 +1,47 @@
# 梦三战斗生命周期
## 资源所有权与退出顺序
梦三每场战斗拥有自己的会话、角色及相关资源。正常结算先停止玩法根事件并排空子事件,再提交结果,完成整角色技能和装备登记的释放,最后销毁角色及界面资源并返回地图或结局。释放失败保留已提交结果,不重复奖励,不盲目重放部分执行过的回调。
整角色退出的登记清点包括角色技能、隐藏技能、不可见技能、临时技能、附加技能、装备技能及已初始化的触发登记。释放仅针对当前退场角色,使用引擎的角色级卸载能力,保留其他角色的共享登记;不能以清空公共 lib.hook、删除 lib.skill 定义或修改全局 Player 原型实现。装备卸载要求的回调及子事件必须在角色节点销毁前完成。
### Scenario: 装备登记完整释放
Acceptance: A1
装备八卦等技能只通过装备触发接口登记、没有出现在 player.skills 时,整角色退出仍移除该角色的相应 initedSkills 和触发条目。重复多场独立战斗退出后,不累积旧角色登记。
### Scenario: 卸载回调完成与失败传播
Acceptance: A2
存在原生装备卸载回调时,退出流程执行并等待其子事件后才能销毁角色。回调失败时记录失败并向外层传播,不能报为成功;同一退出操作重试不会重新调用已执行的释放回调。
## 受保护技能和共享登记
fixed 和 superCharlotte 是需要识别的兼容标记,不删除定义上的标记。纯元数据标记可保留在退场对象上;具有触发器、mod、onremove 或标记资源回调等活动行为的技能在整角色退出时需要释放。局内移除单技能继续遵守保护边界。一个角色退出不应撤销仍由其他角色持有的共享全局技能。
### Scenario: 保留既有兼容边界
Acceptance: A3
纯元数据 chaofeng_common 类标记不会阻止退出;活动受保护技能被释放且标记定义不变。局内单技能保护有效,其他角色持有的共享全局登记在退场角色卸载后仍有效。
## 战斗准备的异常边界
战斗准备使用梦三自己的内容边界捕获异常,保存原始错误并通知外部战斗协调者;不能仅依赖引擎对 root.start() 的拒绝。协调者结束等待后进入现有战斗异常提示及保留存档退出路径,停止继续开战。错误消息与原始栈、会话和准备阶段上下文通过现有梦三诊断系统记录。
### Scenario: 引擎忽略异常仍结束等待
Acceptance: A4
准备抛错,在 ignore_error 开启或关闭时均将原始错误送达外部协调者、结束等待、走战斗异常退出路径;不开始后续战斗或奖励结算。正常内容边界不将成功准备误判为异常。
### Scenario: 诊断与存档不变性
Acceptance: A5
准备失败留下可定位的梦三诊断错误记录;失败前已保存的征程仍有效,不写入新胜负结果或奖励。正常准备和正常结算仍按原先事务提交和奖励去重行为运行。
## 验证边界
### Scenario: 可重复回归与独立验证
Acceptance: A6
关键装备登记和事件吞错回归使用本地原生引擎实现或可验证的原生接口接入,在项目中可重复执行。相关受保护技能、结算和诊断检查通过,由独立只读验证者核查六项验收。验证记录明确指出仅有源码和自动化回归证据,没有 PC/安卓整局实机证明。