This commit is contained in:
2026-04-28 19:36:39 +08:00
parent a9febe7678
commit f0471a4f8d
206 changed files with 18456 additions and 10133 deletions

View File

@@ -0,0 +1,63 @@
# RPG 运行时战斗后处理后端迁移落地方案2026-04-28
## 目标
本方案承接 `docs/audits/engineering/RPG_FRONTEND_SCRIPT_BACKEND_MIGRATION_AUDIT_2026-04-28.md` 的 4.5 项,专门收口三类仍由前端补真相的逻辑:
1. 战斗胜利 / 切磋完成后的正式 `GameState` 清理。
2. 玩家死亡后的复活场景、血蓝恢复与首场景 act 状态。
3. 战斗结束后章节 act 推进与 `currentStory.deferredOptions` 编排。
## 边界
后端负责:
1. 根据 battle resolver 的 `outcome` 决定 `victory``spar_complete``defeat``escaped` 的最终状态。
2. 写回 `inBattle``currentEncounter``sceneHostileNpcs``currentNpcBattleOutcome``playerHp``playerMana``storyEngineMemory.currentSceneActState`
3. 为死亡复活构造回到首场景的快照,并恢复 `playerHp = playerMaxHp``playerMana = playerMaxMana`
4. 为胜利 / 切磋完成构造只含 `story_continue_adventure` 的当前 story并把真实后续 options 放入 `deferredOptions`
5. 在最后一幕或无需等待继续按钮时直接返回场景旅行 / 常规 fallback options。
前端只负责:
1. 播放 `presentation.battle` 对应动画。
2. 使用 `response.snapshot.gameState``response.snapshot.currentStory` 渲染。
3. 不再调用 `buildPostBattleVictoryState``buildPostBattleVictoryStory``buildRevivedFirstSceneState``buildDeathStory` 作为服务端动作后的正式状态。
## 后端落点
1. `server-rs/crates/module-runtime-story-compat/src/post_battle.rs`
- 增加纯 JSON helper迁移战斗后状态、复活和 scene act 推进。
2. `server-rs/crates/api-server/src/runtime_story/compat.rs`
-`resolve_battle_action` 之后、生成 AI fallback 之前统一调用 post-battle finalizer。
3. `server-rs/crates/api-server/src/runtime_story/compat/presentation.rs`
- 复用现有 option / current story 构造函数。
4. `packages/shared/src/contracts/rpgRuntimeStoryState.ts`
- battle outcome 增加 `defeat`,避免前端类型层把失败误判成非战斗终局。
## 落地补充
1. 后端 post-battle finalizer 在 `resolve_battle_action` 之后、LLM fallback 之前执行,终局战斗不再生成额外 AI 文本。
2. 胜利 / 切磋完成会清理战斗态并推进当前场景 act非最后一幕只展示 `story_continue_adventure`,真实后续动作写入 `deferredOptions`
3. 败北复活会先写回首场景、回满血蓝、重置首场景 act再基于复活后的场景重新生成 `deferredOptions`,避免沿用战斗前旧场景选项。
4. story engine 投影额外接收 battle outcome只有 `victory / spar_complete` 会记录胜利信号,`defeat` 不会被“战斗态从 true 变 false”误判成胜利。
5. 前端 `runServerRuntimeChoiceAction` 的服务端路径不再调用 `postBattleFlow` 构造正式状态;死亡动画仍可短暂播放,但最终 `GameState/currentStory` 只采用后端 hydrated snapshot。
## 本轮收口记录
1. `choiceActions.ts` 删除 `shouldResolveCombatChoiceLocally(...)``battle_* / inventory_use` 不再因战斗可见态回落到本地 continuation。
2. `storyChoiceContinuation.ts``battle_* / inventory_use` 以及被分类为 `battle / escape` 的动作加硬保护,误入时不会裁决掉落、复活、任务推进或战后 story。
3. `storyChoiceRuntime.ts` 删除本地敌对 NPC 战斗奖励 helper前端不再调用 `rollHostileNpcLoot(...)``addInventoryItems(...)` 生成正式战利品。
4. 删除 `postBattleFlow.ts` 与其测试,前端不再保留死亡复活、胜利后 story、deferred options、章节推进的正式构造函数。
5. `choiceActions.test.ts` 覆盖 `battle_use_skill`、stale `battle_attack_basic``inventory_use` 全部进入后端 resolver`storyChoiceRuntime.test.ts` 继续覆盖服务端胜利 / 失败 snapshot 被直接采用。
## 验收
1. Rust 单测覆盖:
- 服务端 battle victory 返回后,`currentEncounter = null``inBattle = false``currentStory.options = [story_continue_adventure]``deferredOptions` 存在。
- 服务端 battle defeat 返回后,玩家复活到首场景,`playerHp/playerMana` 回满,`currentStory` 为死亡复活故事。
2. 前端单测覆盖:
- `runServerRuntimeChoiceAction``victory``defeat` 都直接采用服务端 snapshot/story不再本地构造 post battle / revive 状态。
3. 搜索确认 `src/hooks/rpg-runtime-story` 不再出现 `shouldResolveCombatChoiceLocally``buildPostBattleVictory*``buildRevivedFirstSceneState``buildDeathStory``buildHostileNpcBattleReward`
4. Rust 单测覆盖:
- story engine 对 `defeat` outcome 不写入 `win_battle` 信号和敌压 mutation。