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

feat(combat-insights): show realized periodic impact - #211

Merged
cauyxy merged 1 commit into
masterfrom
codex/periodic-effect-attribution
Aug 4, 2026
Merged

cauyxy merged 1 commit into
masterfrom
codex/periodic-effect-attribution

Conversation

@pengx17

@pengx17 pengx17 commented Aug 4, 2026

Copy link
Copy Markdown
Member

Context

Combat Impact 过去只能展示 Burn、Poison、Regen 的施加次数/总量,无法回答这些持续效果最终实际造成了多少生命伤害、消耗了多少护盾,或真正恢复了多少生命。

本 PR 引入一套可回放、可对账的周期效果归因模型:从有序战斗事件中重建生命、护盾与效果来源三本账,将实际影响附加到原有 Burn / Poison / Regen 行,并把生产战斗语料、诊断结果与模型版本一并落盘,方便后续规则变化时继续迭代,而不是从零分析。

改动重点

  • 新增 periodic-impact-v6 归因模型,统计:
    • Burn 实际生命伤害与实际护盾消耗
    • Poison 实际生命伤害
    • Regen 实际治疗量
  • 按事件顺序维护生命/护盾账本,并处理致死边界:
    • 致死 Burn / Poison 只计到剩余正生命值
    • 终局之后的周期效果不再计入
    • 连续的 Burn 生命/护盾调整作为原子组处理,保留致死 Burn 同组的护盾消耗
  • 来源归因只使用已观察到的 Regen apply 或 CardStats.RegenAdded;静态 RegenApplyAmount 只代表能力,不再被当作实际贡献。
  • 将实际影响作为原有指标行下面的 ruby-like 小字展示:复用游戏原生 Damage / Shield 图标,不新增 section,不显示近似符号或置信度标点。
  • tooltip 的标题和指标文本统一使用 Overflow,避免中文或密集布局被截成 ...;高度、底部留白和双行指标块按实际内容自适应。
  • 新增纯模型测试、固定生产语料 runner、语料清单、v5/v6 evidence snapshot 与可复现哈希。
  • 保留完整 goal ledger,记录规则修正、模型迭代、覆盖率口径和未闭环缺口。

协作过程

sequenceDiagram
    participant U as 用户
    participant C as Codex
    participant O as Claude Opus
    participant F as Claude Fable

    U->>C: Burn / Poison / Regen 同行展示实际影响
    C->>C: 建立生命、护盾、来源三本账
    U-->>C: 修正新版 Burn / Shield / Poison 规则
    C->>O: Red-team 归因与终局边界
    O-->>C: 指出来源缺失与致死事件对称性问题
    C->>C: 用生产回放迭代 v1-v5
    U->>C: 要求分析落盘并继续闭环 Regen
    C->>F: Review Regen 剩余缺口
    F-->>C: 指出出生基础值的观察不对称
    C->>C: v6 移除静态能力误归因并固定 evidence
    U->>C: 多轮真实游戏视觉验收
    C->>C: 收敛 Overflow、ruby 排版与自适应高度
Loading

方案讨论

ADR-001:以 typed adjustment 为权威事实

  • Context:状态数值只能说明“施加了多少”,不能说明最终损失了多少生命/护盾;逐帧差分又容易混入直接伤害、治疗和同帧多事件。
  • Options:状态量推算;帧差启发式;按顺序回放 typed health/shield adjustment。
  • Decision:以 typed adjustment 为实际影响的权威账目,状态事件只承担来源候选和归因约束。
  • Consequences:可以对生命/护盾守恒做会计式核对,但游戏未提供来源 ID 时仍需保留 Proportional/Unknown,而不能伪造 Exact。

ADR-002:覆盖率不等于精确率

  • Context:原生周期 tick 没有携带具体来源,多来源场景无法总是精确拆分。
  • Options:全部记给最新来源;按候选权重分摊;无法证明时隐藏;显式保留证明等级。
  • Decision:内部保留 Exact / Constrained / Proportional / Unknown;UI 只展示已归因金额,不展示会增加噪音的置信度符号。
  • Consequences:99% 指金额已有可解释来源,不代表 99% 都能逐来源精确证明。

ADR-003:出生 Regen 基础值不参与来源归因

  • Context:生产语料中存在开场 Regen 正值,但没有对应 apply transition;静态 item/skill 能力会制造看似合理、实则无法证明的来源。
  • Options:用静态 RegenApplyAmount 补齐;按场上候选平分;作为稳定出生 baseline 单独排除。
  • Decision:仅把观察到的 apply / RegenAdded 作为贡献;稳定出生 baseline 独立核对并从来源覆盖率分母中排除。
  • Consequences:v6 的 Regen 数值更诚实;剩余 4,956 继续保持 Unknown,不用错误归因换取表面 100%。

ADR-004:实际影响附着在已有行

  • Context:新增 section 会放大 tooltip 高度和视觉噪音。
  • Options:新增“实际影响”区块;串在总计同一行;作为总计下方的小字。
  • Decision:作为现有 Burn / Poison / Regen 总计下方的自适应 secondary line,并复用原生图标。
  • Consequences:信息层级更紧凑;布局需要同时适配单行/双行总计、CJK 文本和密集 tooltip。

最终方案

flowchart LR
    A[CombatSim 有序事件] --> B[Typed health / shield ledger]
    A --> C[Status apply 与 CardStats 来源候选]
    B --> D[致死截断与 Burn 原子组]
    C --> E[来源约束与权重]
    D --> F[周期效果实际金额]
    E --> G[Exact / Constrained / Proportional / Unknown]
    F --> H[PeriodicImpact]
    G --> H
    H --> I[附着到原 Burn / Poison / Regen group]
    I --> J[自适应 ruby-like secondary line]

    K[固定生产 bundle 清单] --> L[Corpus runner]
    L --> M[守恒诊断与覆盖率]
    M --> N[v5 / v6 evidence snapshots]
Loading

验证情况

  • ./run.sh format-check:通过,检查 1,162 个文件。

  • dotnet test tests/PostCombatImpact.Tests/PostCombatImpact.Tests.csproj --no-restore --verbosity minimal:149/149 通过。

  • ./run.sh test:完整测试套件通过。

  • ./run.sh build --fast:通过,0 warnings / 0 errors,并替换本地 Debug mod DLL。

  • 固定生产语料:100 个 bundles、1,110 场战斗、339,649 帧、53,068 个 adjustments;7 个 unresolved actions,0 missing stat identities,0 invalid payloads。

  • v6 可归因金额覆盖率:

    指标 已归因 / 可归因总量 覆盖率
    Burn Health 1,219,514 / 1,227,284 99.37%
    Burn Shield 425,085 / 428,748 99.15%
    Poison Health 1,001,417 / 1,010,235 99.13%
    Regen 686,099 / 691,055 99.28%
  • v6 evidence 与完整 report 连续两次运行字节一致:

    • evidence SHA-256: 9ca232d60e5a30ae218400619092af71aeb1e8ab915473e5b5a71fa6e3ee0997
    • report SHA-256: eb129d33bdb2a566c9bc87a8f8ce5c77d0bbda7ae5ace585f94808a3bcc3c012
  • 用户已在真实游戏中多轮验收中英文、长短 tooltip、同行实际影响和自适应 padding;Codex 未自动启动游戏。

已知局限 / 后续工作

  • 原生周期 tick 不携带来源 ID;多来源拆分中仍存在 Proportional 归因,金额覆盖率不能解读为逐来源精确率。
  • Regen 仍有 4,956 的来源缺口(主要是开场状态且缺 apply source),当前保持 Unknown。
  • 54,230 的稳定出生 Regen baseline 已能独立对账,但没有可靠来源证据,因此不展示为某个物品/技能的贡献。
  • evidence snapshot 固定当前生产语料与模型口径;游戏规则或采集 schema 变化时需要显式升级模型版本并重跑快照。

Copilot AI lite review requested due to automatic review settings August 4, 2026 14:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the PostCombatImpact / Combat Insights pipeline to compute and display realized periodic-effect impact (Burn/Poison actual HP damage, Burn shield consumption, Regen realized healing) by replaying ordered CombatSim events with a versioned attribution model (periodic-impact-v6), then rendering the realized totals as a compact secondary line under the existing Burn/Poison/Regen rows.

Changes:

  • Add a runtime periodic-effect attribution pass (PeriodicEffectAttribution) and attach its results onto existing CombatImpact groups (CombatImpactProjector), including new model types in CombatImpactModels.
  • Update tooltip rendering to support a stacked “authoritative total + secondary realized impact” metric block and switch cloned TMP text overflow to Overflow to avoid ellipsis truncation.
  • Add extensive unit tests plus a deterministic corpus runner + evidence snapshot infrastructure under tests/PeriodicEffectAttribution.Corpus/.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/PostCombatImpact.Tests/PostCombatImpact.Tests.csproj Links the new attribution model into the PostCombatImpact test project.
tests/PostCombatImpact.Tests/PeriodicEffectAttributionTests.cs Adds focused goldens covering Burn/Poison/Regen pool booking, death-frame rules, ownership epochs, and formatter output.
tests/PeriodicEffectAttribution.Corpus/Program.cs Adds an executable corpus runner that inventories/validates attribution and emits deterministic report + evidence snapshots.
tests/PeriodicEffectAttribution.Corpus/PeriodicEffectAttribution.Corpus.csproj New exe project for the corpus runner.
tests/PeriodicEffectAttribution.Corpus/evidence/README.md Documents how to regenerate deterministic evidence snapshots.
tests/PeriodicEffectAttribution.Corpus/CorpusInventory.cs Implements the corpus inventory, reconciliation gates, and attribution/terminal diagnostics collection.
tests/PeriodicEffectAttribution.Corpus/ContractlessRunArtifact.cs Adds a contractless bundle model for reading older/newer run bundle shapes.
src/BazaarPlusPlus/Patches/PostCombatImpact/NativePostCombatImpactTooltipView.cs Renders periodic realized impact as a ruby-like secondary line and adjusts TMP overflow behavior.
src/BazaarPlusPlus/Game/PostCombatImpact/Data/PeriodicEffectAttribution.cs Implements the periodic-impact-v6 attribution model (pool reconstruction + ownership allocation).
src/BazaarPlusPlus/Game/PostCombatImpact/Data/CombatImpactProjector.cs Attaches periodic impacts into the aggregated combat impact report.
src/BazaarPlusPlus/Game/PostCombatImpact/Data/CombatImpactModels.cs Adds periodic-impact model types (kind/proof/key/impact) and a nullable field on groups.
src/BazaarPlusPlus/Game/PostCombatImpact/Data/CombatImpactMetricFormatter.cs Formats the secondary realized-impact string for tooltip rendering.
docs/drafts/2026-08-04-periodic-effect-attribution-goal.md Adds/updates the goal ledger documenting the model contract, evidence, and iteration history.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +28 to +36
var corpusPath =
args.Length >= 1 ? args[0] : Environment.GetEnvironmentVariable(corpusEnvironmentVariable);
if (string.IsNullOrWhiteSpace(corpusPath))
{
Console.WriteLine(
$"Periodic-effect corpus acceptance skipped; pass a path or set {corpusEnvironmentVariable}."
);
return;
}
@cauyxy
cauyxy merged commit 287ca41 into master Aug 4, 2026
1 check passed
@cauyxy
cauyxy deleted the codex/periodic-effect-attribution branch August 6, 2026 11:16
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants