抽奖池 Tier 复盘与调整

SkillFiles & storage

Reviews lottery pool tier distribution based on an active/passive ability stats CSV (columns: ability, tier dimension, win rate, event count). Reads the current pool shape from src/vscripts/modules/lottery/lottery-abilities.ts, compares it against target shares (T5 4–5% / T4 13–15% / T3 21–23% / T2

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the 抽奖池 Tier 复盘与调整 skill

What this skill tells your AI

The instructions your AI receives, as published by windy10v10ai/game in .claude/skills/adjust-lottery-tier/SKILL.md and read by ahel’s review.

基于 CSV 统计数据调整 src/vscripts/modules/lottery/lottery-abilities.ts 的 Tier 分布。

参考文件路径见 CLAUDE.md「Dota 2 参考文件速查」。


设计原则(背景知识)

理论权重 vs 实际行为

BASE_TIER_RATES = [1, 5, 20, 60, 100](T5→T1)对应单次抽取权重 1:4:15:40:40。但玩家"抽 6 选 1"会挑优,实际选取分布严重偏向高档:

Tier理论权重%实际选取%(历史加权)目标池占比
T51~64–5%
T44~1813–15%
T315~2621–23%
T240~3333–36%
T140~1724–27%

目标池占比 = 0.35 × 理论 + 0.65 × 实际。主动/被动两池使用同一套目标占比

样本量与胜率置信度(p≈0.8,95% CI)

n±pp可用性
50±11.1不可用
100±7.8仅看极端
150±6.4需辅助证据
200±5.5判档阈值线
300±4.5较稳
500±3.5稳健

第一步:收集 CSV 输入

用 AskUserQuestion 询问用户提供:

  • 主动技能 CSV 路径
  • 被动技能 CSV 路径

若只提供一份,只处理该池;两份都有则两池独立分析。

CSV 格式:技能,等级维度,胜率,事件数(表头行跳过)。


第二步:解析与聚合

对每份 CSV:

  1. 解析每行 → (name, tier, winrate, events)
  2. 按 tier 聚合:
    • tier_events[t] = 该档总事件数
    • tier_count[t] = 该档技能数
    • tier_winrate_avg[t] = 加权均值 Σ(wr·ev) / Σev
    • tier_winrate_sd[t] = 事件数加权标准差(用于判"偏离 > Nσ")
  3. 计算池总事件数、各档实际占比 tier_events[t] / total

第三步:整体样本充分性检查(关键:数据不足必须停止)

按以下规则判断数据是否足够支持本次分析,任一条触发即停止工作,提示用户补充数据后再运行 skill

  • 池总事件数 < 5000
  • 任一档的中位技能事件数 < 100(整档普遍样本不足)
  • 条数 ≥ 10 的档中,n ≥ 200 的技能占比 < 30%

停止时告知用户当前数据量与缺口,不生成 plan。


第四步:读取当前池状态

Read src/vscripts/modules/lottery/lottery-abilities.ts

解析两个数组 abilityTiersActive / abilityTiersPassive,统计每档条数与技能列表。注意 lottery 文件中技能带中文注释,保留注释用于 plan 展示。


第五步:计算池形状差距

对每池:

  • 目标条数(按中点占比 T5 4.5% / T4 14% / T3 22% / T2 34% / T1 25.5% × 当前总条数,取整)
  • 差值 = 目标 − 当前

输出每档"需增减多少条"。

5.1 关键原则:按全池胜率分位数划分理想档位,限速收敛

档位的本质是"在整个池子里的胜率排名位置",不是"配额"也不是"相对当前档均值"。

5.1.1 错误做法警示
  • 按档均值 argmin 判档:档均值被档内容污染,导致"T5 均值被 T5 尾部差技能拉低" → T4 头部 |wr−μ_5| 反而小 → 错判升档。此方法会放大池形状偏差,不收敛。
  • 按"配额决定方向":T5 需 −1 就不许升档,T1 需 +3 就不许降档。与胜率实际匹配度脱节,导致明显该升的技能(如 life_stealer_rage 91.13%)被压在 T4、明显该降的坐在 T5。
5.1.2 正确做法:分位数锚定 ideal_tier

仅用池内 n ≥ 200 的技能计算理想档:

  1. 按胜率降序排所有 n ≥ 200 的技能,得到 rank。
  2. 按目标占比切分位数:
    • 前 4.5%:理想 T5
    • 接下来 14%:理想 T4
    • 接下来 22%:理想 T3
    • 接下来 34%:理想 T2
    • 剩余 25.5%:理想 T1
  3. 每条技能的 ideal_tier = 其 rank 所落分位区间对应的档。
  4. shift = ideal_tier − current_tier

分位数法的优点:

  • 自我稳定:不依赖当前档均值,不会被档内容污染。
  • 自动收敛池形状:按定义,完全按 ideal_tier 迁移后,池形状就是目标分位。
5.1.3 保守限速(避免一次大改)

一次完全按 ideal_tier 迁移可能产生 30+ 条变动,单版本太激进,容易误伤边界技能,也让玩家一版体验剧变。因此引入限速规则

  • 单档单次变动上限 = max(3, 当前档条数 × 15%)。即每档升出 + 降出总数不超过该档 15%(或至少 3 条)。
  • 优先级排序:按 |shift| 降序、胜率偏离原档中位数幅度降序。每档取排序靠前的候选执行,超限部分保留到下版。
  • 跨档 shift ≥ 2:优先保留这些技能的迁移,因为它们偏离最远、最拖累池结构。
  • shift = ±1 且边界接近:若与相邻档分位线距离 ≤ 1pp,优先保留为 shift=0(避免因样本抖动反复升降)。
5.1.4 终态模拟与池形状验证

所有迁移候选确定后,用以下公式模拟终态:

终态[t] = 初始[t] + Σ(进入该档) − Σ(离开该档) − Σ(该档被移除)

收敛验证:每档 |终态 − 目标| 必须 ≤ |初始 − 目标|(即不能反向偏离)。若反向偏离:

  • 检查是否误把 shift=0 的技能移动了(回滚)。
  • 检查该档升出/降出是否失衡——若升出过多但实际需要增加条数,减少升出候选。
5.1.5 多版本逐步收敛

差距大(|初始 − 目标| > 5)时,一次调整通常无法到位。在 plan 末尾明确"本轮收敛 X/Y"与"下版待处理 Z 条",作为下次运行 skill 的输入锚点。


第六步:逐技能打标签

核心方法:为每条 n ≥ 200 的技能计算"最匹配档位"(见 5.1.1),根据 shift = best_tier − current_tier 决定调整方向。 同档均值与 σ 用于 T1 特判与极端判定。

条件标签
n < 50,且同档其他技能普遍 n ≥ 200询问用户(选择率过低)
50 ≤ n < 200观察(样本小),仅当 shift ≥ +2 或 shift ≤ −2 时才带"可能需调整"备注
n ≥ 200 且 shift = +1升 1 档
n ≥ 200 且 shift = −1,非 T1降 1 档
n ≥ 300 且 shift ≥ +2 且 偏离原档均值 > 15pp升 2 档(罕见)
n ≥ 300 且 shift ≤ −2 且 偏离原档均值 < −15pp,非 T1降 2 档
n ≥ 300 且 shift = +1 且 事件数同档 TOP 3 且 原档位 ≥ T4建议削弱(OP 信号,数值处理,档位可保留)
n ≥ 200 且 事件数同档 TOP 2 且 shift = 0观察(过曝光)
T1 档 且 n ≥ 200 且 胜率 < T1 均值 − 8pp询问用户(T1 胜率异常)
其他(shift = 0 或无效信号)无调整

best_tierargmin(|wr − μ_t|)。若两档距离接近(差 < 1pp),优先保留在较低档(保守)。

T1 末档询问规则:仅当某 T1 技能胜率低于 T1 加权均值 > 8pp 才询问。不是"末尾 10% 必淘汰"——正常偏低的 T1 技能保留。


第七步:补齐中文名

对每条将要调整或标记的技能,按顺序查中文名用于 plan 展示:

  1. Grep game/resource/addon_schinese.txt,模式 DOTA_Tooltip_ability_{系统名}\s+,提取下一行的值
  2. 若未命中,Grep docs/reference/<latest-version>/abilities_schinese.txt 同模式
  3. 两处都找不到 → 跳过中文名,plan 中只显示系统名(不触发 AskUserQuestion)

<latest-version>docs/reference/ 下最新数字版本目录。


第八步:生成 Plan

写 plan 前必须完成第五·5.1 节的"终态模拟",plan 中必须包含"初始→终态→目标"对比表(见下方模板),验证每档都在向目标收敛。

写入 C:\Users\windy\.claude\plans\adjust-lottery-tier-<yyyymmdd-hhmm>.md,结构:

# 抽奖池 Tier 复盘 - <日期>

## 数据概览
### 主动池(总事件 N)
| Tier | 条数 | 事件数 | 占比% | 加权胜率 | 胜率 σ |

### 被动池(总事件 N)
(同上)

## 池形状差距
| Tier | 目标% | 主动当前/目标条数/差 | 被动当前/目标条数/差 |

## 主动技能调整清单

### T5(需增/减 N 条)
- `system_name` (中文名) | n=XXX | wr=XX% | **升 1 档** → 偏离 +Xpp, 样本充足

### T4 / T3 / T2 / T1
(同上结构)

### 需人工确认(T1 胜率异常)
- `system_name` | ... | 执行阶段将用 AskUserQuestion 询问

### 需人工确认(选择率过低)
- `system_name` | n=XX(同档中位 N) | 几乎无人选,询问降档/加强/移除/保留

## 被动技能调整清单
(同上结构)

## 数值调整清单(移交 update-abilities-override)
- `system_name` | 建议加强 | 理由:胜率 XX% 低于同档均值 Xpp,n=XXX
- `system_name` | 建议削弱 | 理由:OP 信号

## 汇总
- 升档:N 条 / 降档:N 条
- 加强建议:N 条 / 削弱建议:N 条
- 待询问用户:N 条
- 无调整:N 条

第九步:用户确认

输出 plan 文件路径,告知用户查看并确认。等待用户批准后进入执行阶段。


第十步:执行池结构调整(用户批准后)

10.1 逐条处理「询问用户」标签

对每条 询问用户(T1 胜率异常)询问用户(选择率过低) 的技能,单独调用一次 AskUserQuestion:

  • T1 胜率异常选项:加强数值 / 移除 / 保留观察
  • 选择率过低选项:降一档(提升曝光) / 加强数值 / 移除 / 保留观察

10.2 修改 lottery-abilities.ts

用 Edit 工具处理每条带"升/降档"标签的技能:

  1. 从旧档 names 数组中删除(包括其中文注释行)
  2. 插入新档 names 数组,尽量放入相似分区(// 大招 / // 小技能 / // 自定义技能 / // 法球/开关技能 / // 单位技能
  3. 保留原中文注释

对移除类:从数组中删除该行(含注释)。

不修改 BASE_TIER_RATES / PREMIUM_TIER_RATES

10.3 数值调整类建议移交

对每条 建议加强 / 建议削弱 / 被用户选为"加强数值"的技能:

  • 调用 update-abilities-override skill 处理对应 KV 数值
  • 每次处理一条技能,单独与用户确认数值改动

10.4 验证提示

执行完成后提示:

  • 运行 npm test
  • 进游戏实际抽奖验证高档出现频率变化

Skill 交互规范

  • 数据不足 → 停止工作(第三步),不生成 plan。
  • T1 胜率异常 / 选择率过低 → AskUserQuestion,单独一问一答。
  • 中文名查不到 → 跳过,不询问。
  • 数值加强/削弱 → 移交 update-abilities-override,不在本 skill 内改 KV。
  • 调整幅度:常规 ±1 档;极端(n≥300 且偏离>15pp)才 ±2 档。
  • 不修改 BASE_TIER_RATES / PREMIUM_TIER_RATES

Signals

GitHub stars
73
Forks
40
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
adjust-lottery-tier
Source
github.com/windy10v10ai/game