Skip to content
This repository was archived by the owner on Sep 20, 2026. It is now read-only.
This repository was archived by the owner on Sep 20, 2026. It is now read-only.

RFC(live-build): 为十胜阵容关联代表战局回放 #306

Description

@pengx17

Context

Live Build 当前展示“十胜阵容”:根据玩家选中的卡牌,从 analyzer-v4 的聚合 corpus 中召回候选阵容,并展示最终棋盘、十胜样本数、十胜率、结束日和评分。

希望讨论能否在每个十胜阵容上增加“观看代表战局”入口,让玩家不只看到静态终局阵容,还能观察该阵容在真实 PvP 中的启动顺序、技能互动和对局节奏。

这里建议使用“代表战局”而不是“回放此阵容”:一个 corpus 条目汇总了多场 Run 的统计,不天然对应唯一战斗,不能暗示展示棋盘与某一场回放必然一一对应。

已验证的当前状态

  • 十胜 corpus 的 build 行当前只有 card_refs、layout、stats、selection;没有 run_id、battle_id、Bundle ID 或 replay 引用:src/BazaarPlusPlus/Game/LiveBuildPanel/Recommendations/TenWinBuildCorpus.cs:29-57,388-423。
  • 当前 BuildId 是 hero 的 builds 数组内隐式零基索引,不是可跨 corpus 版本长期引用的稳定身份:src/BazaarPlusPlus/Game/LiveBuildPanel/Recommendations/TenWinBuildCorpus.cs:14-18,401-423。
  • Mod 投影推荐结果时只保留聚合统计和棋盘,生成的 tenwin-build:{buildId} 只是本地 UI board identity:src/BazaarPlusPlus/Game/LiveBuildPanel/Recommendations/BuildRecommendationRepository.cs:52-80,83-98。
  • 战斗回放需要一个具体 battleId,以及完整的 Spawn / Combat / Despawn 原始消息:src/BazaarPlusPlus/Game/PvpBattles/PvpReplayPayload.cs:4-14。
  • 单个已上传 Run Bundle 可以携带可回放战斗,但回放输入允许缺失,也可能因 Bundle 体积预算被裁剪;并非每个十胜 Run 都保证存在回放:src/BazaarPlusPlus/Game/BundlePipeline/RunPayloadComposer.cs:69-77,159-177,338-358。
  • HistoryPanel 已有远端 Ghost Bundle 下载、完整性校验、原子缓存和 imported replay 播放链路,可以作为 Mod 端复用基础:src/BazaarPlusPlus/Game/HistoryPanel/Ghost/GhostBattleSyncService.cs:220-291、src/BazaarPlusPlus/Game/HistoryPanel/HistoryPanelReplayService.cs:164-272。

因此,当前十胜阵容没有绑定回放;即使上游某些来源 Run 保留了 replay,analyzer 输出也已经丢弃了将聚合阵容追溯到具体战斗所需的引用。

候选方向

flowchart LR
    A["Analyzer 聚合十胜阵容"] --> B["为 build 选择 1..N 场完整代表战局"]
    B --> C["Corpus 只发布轻量 replay_ref"]
    C --> D["Live Build 显示『观看代表战局』"]
    D --> E["Mod 按需请求 Replay Bundle"]
    E --> F["复用 Ghost Bundle 校验与本地缓存"]
    F --> G["ReplayImportedBattle 播放"]
Loading

建议的职责边界:

  1. Analyzer:在组成某个 build 统计的来源 Run 中,只选择具有完整 replay inputs、与展示 layout 匹配且仍可下载的代表战局。
  2. Ten-win corpus:只增加轻量引用和必要的展示/兼容性元数据;不要把回放二进制嵌入当前静态 corpus。
  3. Backend:通过 opaque replay_ref 提供受控的 Bundle 下载,并定义过期、缺失和权限策略。
  4. Mod:按需下载,复用现有 Bundle contract、payload store 和 imported replay runtime;无可用回放时隐藏或禁用入口。

需要讨论的决策

  • 产品语义:统一叫“观看代表战局”,还是允许在严格一一对应时显示“回放此阵容”?
  • 稳定身份:是否给 analyzer build 增加稳定 build_key;不能把当前数组索引 BuildId 当远端长期主键。
  • 代表局选择:优先最终第十胜、最高分段、最新游戏版本、棋盘完全匹配,还是从多场中随机/轮换?
  • 一条还是多条:每个 build 只保留一场,还是提供 2~3 场并允许切换?
  • 兼容性:游戏数据或协议更新后,旧 replay 如何标记 incompatible、降级和淘汰?
  • 留存与失效:Bundle 过期、被清理或回放字段被 size budget 裁剪时,corpus 如何避免长期发布死引用?
  • 隐私与滥用:代表战局是否隐藏账号 ID、对手昵称等字段;下载接口是否需要限流或签名引用?
  • 透视约定:是否沿用 Ghost Battle 的 recorder perspective / PerspectiveVersion,避免 UI 与回放双方身份颠倒?
  • 跨仓库落地顺序:analyzer、backend、mod 的 contract 由谁先定义,如何做向后兼容发布?

建议的最小版本

  • 每个 build 最多一个可选 replay_ref。
  • 只选择最终第十胜且四组 snapshots、三段 replay bytes 均完整的战斗。
  • 引用包含可判断兼容性的版本信息和可选失效时间,不暴露真实存储路径。
  • UI 仅在引用可用时显示“观看代表战局”;下载或校验失败保持静态阵容可用。
  • 下载与播放复用现有 Ghost Bundle 路径,不建立第二套 replay transport/runtime。
  • corpus 和旧版 Mod 保持向后兼容;未知字段由旧版忽略。

非目标

  • 不根据静态棋盘合成一场虚假的模拟战斗。
  • 不把 replay payload 直接塞进 tenwin_builds.json。
  • 不保证每个十胜阵容都有代表战局。
  • 不让回放下载失败阻塞 Live Build 推荐、刷新或静态预览。

讨论完成条件

  • 确认“代表战局”的用户语义和 UI 入口。
  • 确认稳定 build identity 与 replay reference contract。
  • 确认代表战局选择、兼容性、留存和隐私策略。
  • 划分 analyzer / backend / mod 三端 owner 和发布顺序。
  • 决定是否拆分三个实现 issue,并记录依赖关系。

验证情况

本 issue 创建时只进行了只读核对:

  • 核对当前 ten-win corpus 解析与推荐投影字段。
  • 核对本地/导入回放所需 payload contract。
  • 核对 Bundle 中 replay 的可选与体积降级行为。
  • 核对现有 Ghost Bundle 下载和 imported replay 播放链路。
  • 尚未验证后端是否长期保留所有 analyzer 来源 Run 的原始 Bundle。
  • 尚未统计现有十胜来源中完整、兼容 replay 的实际覆盖率。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestneeds-triageMaintainer needs to evaluate this issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions