[P2][T16] 实现符文之语:Runes.txt 169 行(complete=1 仅 78 条可用) #105

Closed
opened 2026-09-18 10:50:52 +00:00 by troytt · 1 comment
Owner

问题

符文之语是 D2 的核心玩法之一,母 issue 的验收项里明确列了「符文之语可合成且属性正确」。

金标准数据

Runes.txt —— 169 行 × 49 列

Name | Rune Name | complete | server | itype1..itype6 | etype1..etype3 | *runes |
Rune1..Rune6 | (T1Code1..7, T1Param1..7, T1Min1..7, T1Max1..7) | eol

真实样例:

Runeword1  Rune Name="Ancient's Pledge" complete=1 itype1=shld
           Rune1=r08 Rune2=r09 Rune3=r07
           T1Code1=res-cold 30/30 T1Code2=res-all 13/13 T1Code3=ac% 50/50
           T1Code4=dmg-to-mana 10/10
Runeword6  Rune Name=Black complete=1 itype1=club itype2=hamm itype3=mace
           Rune1=r10 Rune2=r16 Rune3=r04
           T1Code1=crush 40/40 T1Code2=dmg% 120/120 T1Code3=swing2 15/15
           T1Code4=red-mag 2/2 T1Code5=att 200/200 T1Code6=charged param=74 12/4
Runeword26 Rune Name=Doomsayer complete=1 itype1=axe itype2=pole itype3=hamm
           *runes=HelOhmUmLoCham
           Rune1=r15 Rune2=r27 Rune3=r22 Rune4=r28 Rune5=r32
           T1Code1=dmg% 280/320  T1Code2=aura param="Holy Freeze" 12/12
           T1Code3=swing2 45/45  T1Code4=noheal 1/1  T1Code5=pierce-cold 40/60
           T1Code6=allskills 2/2 T1Code7=hit-skill param=Volcano 5/18
列 语义
Name 内部行名(Runeword1…),同时是 string.tbl 的 key
Rune Name 设计者备注,不是显示名
complete 1 = 本版本启用,1.13c 里 169 行只有 78 行为 1
server 1 = 仅 ladder / realm(1.13c 有 23 行)—— 列名叫 server 不叫 ladder
itype1..6 允许基底类型白名单(任一命中,沿 Equiv 链)
etype1..3 排除类型
*runes 纯注释列(星号前缀,游戏忽略)
Rune1..Rune6 符文 item code,顺序即插入顺序,非空个数 = 需要的插槽数
T1CodeN/ParamN/MinN/MaxN(N=1..7) 符文之语自身附加的最多 7 条属性

实现要求

新建 src/game/runeword.ts(母 issue 指定的文件名)。

合成判定(高可信推断,与 1.13c 表结构完全自洽):

触发时机:往带空槽的物品插入最后一颗符文时检查

1. 基底品质必须 normal(非 magic / rare / set / unique / crafted)
2. socket 总数 == 该行 Rune1..Rune6 的非空个数(不能多也不能少)
3. 基底 ItemType ∈ itype1..6 且 ∉ etype1..3(沿 Equiv 链)
4. 已插入符文【按顺序】逐位等于 Rune1..RuneN
5. complete == 1
6. server == 1 时仅 ladder 生效(1.13c 单机 / 非 ladder 不成立)
7. 成立 → 置 runeword 标志;物品同时获得:
     · 各符文在该类基底上的属性(来自 Gems.txt,见 T-18)
     · T1Code1..7 的属性(min/max 各自随机)

陷阱

[!CAUTION]
显示名走 Name 而不是 Rune Name。 Runeword26 的 Rune Name 写的是废弃旧名 Doomsayer,而 Name(Runeword26)查 string.tbl 得到的是真名 Doom。照 Rune Name 显示会给玩家看到错误名字。

[!CAUTION]
插槽数必须恰好等于符文数,多一个少一个都不成立。这条约束不在 Runes.txt 里,是引擎硬编码的。同理「基底必须是白 / 灰色」也不在表里。

[!WARNING]
complete=1 只有 78 条。另外 91 条是历史遗留 / 未启用,必须过滤,否则会出现原版里不存在的符文之���。

[!WARNING]
server 列容易被误读成「服务器端」。它实际是 ladder 限定标志,23 行为 1。

[!NOTE]
*runes 是注释列(如 HelOhmUmLoCham),不要拿它去解析符文序列 —— 用 Rune1..Rune6。

验收标准

  • 169 行全部解析,complete=1 恰好 78 条、server=1 恰好 23 条
  • 只有 complete=1 的进入可合成池
  • 显示名走 Name → string.tbl:Runeword26 → Doom(专门写一条断言)
  • 插槽数不匹配时不合成(多一个 / 少一个各一条测试)
  • 符文顺序错误时不合成
  • 基底品质非 normal 时不合成
  • itype/etype 沿 Equiv 链匹配
  • Ancient's Pledge(Runeword1) 合成后 4 条属性全对
  • 所有 T1CodeN 都能在 Properties 里解析到
  • npm run typecheck 0 error
  • npx vitest run 全绿
  • npx tsx scripts/verify-items.ts 新增断言通过

溯源

金标准(数据) 1.13c MPQ data\global\excel\ 下的 Runes.txt / Gems.txt / Properties.txt(本机 /usr/local/google/home/taodao/d2-data,挂载序 d2data → d2exp → Patch_D2,Patch_D2 优先)
本 issue 结论强度 表数据与列语义为本机 1.13c 实测确证;合成判定流程为高可信推断(未定位判定函数,但与表结构自洽)

[!WARNING]
D2MOO 是 1.10f,不是本项目的金标准。 它只能作线索使用。任何涉及常量、列序、整数截断位置或 RNG 消耗次数的结论,都必须回到 1.13c 的表格或 DLL 复核后再落地。

## 问题 符文之语是 D2 的核心玩法之一,母 issue 的验收项里明确列了「符文之语可合成且属性正确」。 ## 金标准数据 ### Runes.txt —— 169 行 × 49 列 ``` Name | Rune Name | complete | server | itype1..itype6 | etype1..etype3 | *runes | Rune1..Rune6 | (T1Code1..7, T1Param1..7, T1Min1..7, T1Max1..7) | eol ``` 真实样例: ``` Runeword1 Rune Name="Ancient's Pledge" complete=1 itype1=shld Rune1=r08 Rune2=r09 Rune3=r07 T1Code1=res-cold 30/30 T1Code2=res-all 13/13 T1Code3=ac% 50/50 T1Code4=dmg-to-mana 10/10 Runeword6 Rune Name=Black complete=1 itype1=club itype2=hamm itype3=mace Rune1=r10 Rune2=r16 Rune3=r04 T1Code1=crush 40/40 T1Code2=dmg% 120/120 T1Code3=swing2 15/15 T1Code4=red-mag 2/2 T1Code5=att 200/200 T1Code6=charged param=74 12/4 Runeword26 Rune Name=Doomsayer complete=1 itype1=axe itype2=pole itype3=hamm *runes=HelOhmUmLoCham Rune1=r15 Rune2=r27 Rune3=r22 Rune4=r28 Rune5=r32 T1Code1=dmg% 280/320 T1Code2=aura param="Holy Freeze" 12/12 T1Code3=swing2 45/45 T1Code4=noheal 1/1 T1Code5=pierce-cold 40/60 T1Code6=allskills 2/2 T1Code7=hit-skill param=Volcano 5/18 ``` | 列 | 语义 | |---|---| | `Name` | 内部行名(`Runeword1`…),**同时是 string.tbl 的 key** | | `Rune Name` | 设计者备注,**不是显示名** | | `complete` | **1 = 本版本启用**,1.13c 里 169 行只有 **78** 行为 1 | | `server` | **1 = 仅 ladder / realm**(1.13c 有 **23** 行)—— 列名叫 server 不叫 ladder | | `itype1..6` | 允许基底类型白名单(任一命中,沿 Equiv 链) | | `etype1..3` | 排除类型 | | `*runes` | **纯注释列**(星号前缀,游戏忽略) | | `Rune1..Rune6` | 符文 item code,**顺序即插入顺序**,非空个数 = 需要的插槽数 | | `T1CodeN/ParamN/MinN/MaxN`(N=1..7) | 符文之语自身附加的最多 7 条属性 | ## 实现要求 新建 `src/game/runeword.ts`(母 issue 指定的文件名)。 合成判定(**高可信推断**,与 1.13c 表结构完全自洽): ``` 触发时机:往带空槽的物品插入最后一颗符文时检查 1. 基底品质必须 normal(非 magic / rare / set / unique / crafted) 2. socket 总数 == 该行 Rune1..Rune6 的非空个数(不能多也不能少) 3. 基底 ItemType ∈ itype1..6 且 ∉ etype1..3(沿 Equiv 链) 4. 已插入符文【按顺序】逐位等于 Rune1..RuneN 5. complete == 1 6. server == 1 时仅 ladder 生效(1.13c 单机 / 非 ladder 不成立) 7. 成立 → 置 runeword 标志;物品同时获得: · 各符文在该类基底上的属性(来自 Gems.txt,见 T-18) · T1Code1..7 的属性(min/max 各自随机) ``` ## 陷阱 > [!CAUTION] > **显示名走 `Name` 而不是 `Rune Name`。** `Runeword26` 的 `Rune Name` 写的是废弃旧名 `Doomsayer`,而 `Name`(`Runeword26`)查 string.tbl 得到的是真名 **`Doom`**。照 `Rune Name` 显示会给玩家看到错误名字。 > [!CAUTION] > **插槽数必须恰好等于符文数**,多一个少一个都不成立。这条约束**不在 Runes.txt 里**,是引擎硬编码的。同理「基底必须是白 / 灰色」也不在表里。 > [!WARNING] > `complete=1` 只有 **78** 条。另外 91 条是历史遗留 / 未启用,**必须过滤**,否则会出现原版里不存在的符文之���。 > [!WARNING] > `server` 列容易被误读成「服务器端」。它实际是 **ladder 限定**标志,23 行为 1。 > [!NOTE] > `*runes` 是注释列(如 `HelOhmUmLoCham`),**不要拿它去解析符文序列** —— 用 `Rune1..Rune6`。 ## 验收标准 - [ ] 169 行全部解析,`complete=1` 恰好 **78** 条、`server=1` 恰好 **23** 条 - [ ] 只有 `complete=1` 的进入可合成池 - [ ] 显示名走 `Name` → string.tbl:`Runeword26` → **`Doom`**(专门写一条断言) - [ ] 插槽数不匹配时不合成(多一个 / 少一个各一条测试) - [ ] 符文顺序错误时不合成 - [ ] 基底品质非 normal 时不合成 - [ ] `itype`/`etype` 沿 Equiv 链匹配 - [ ] `Ancient's Pledge`(Runeword1) 合成后 4 条属性全对 - [ ] 所有 `T1CodeN` 都能在 Properties 里解析到 - [ ] `npm run typecheck` 0 error - [ ] `npx vitest run` 全绿 - [ ] `npx tsx scripts/verify-items.ts` 新增断言通过 --- ### 溯源 | | | |---|---| | 金标准(数据) | 1.13c MPQ `data\global\excel\` 下的 `Runes.txt` / `Gems.txt` / `Properties.txt`(本机 `/usr/local/google/home/taodao/d2-data`,挂载序 d2data → d2exp → Patch_D2,**Patch_D2 优先**) | | 本 issue 结论强度 | 表数据与列语义为**本机 1.13c 实测确证**;**合成判定流程为高可信推断**(未定位判定函数,但与表结构自洽) | > [!WARNING] > **D2MOO 是 1.10f,不是本项目的金标准。** 它只能作线索使用。任何涉及常量、列序、整数截断位置或 RNG 消耗次数的结论,都必须回到 1.13c 的表格或 DLL 复核后再落地。
troytt added this to the [M10] 真实物品系统:500 基础物品、1000 词缀、TreasureClassEx 掉落树 milestone 2026-09-18 10:50:52 +00:00
Author
Owner

已完成 Runes.txt 169行解析、78组完整符文之语与23组天梯符文之语支持、严格基底品质/插槽数/符文顺序匹配算法与属性聚合,合并入 main (commit 3cdf9dc)。

已完成 Runes.txt 169行解析、78组完整符文之语与23组天梯符文之语支持、严格基底品质/插槽数/符文顺序匹配算法与属性聚合,合并入 main (commit 3cdf9dc)。
Sign in to join this conversation.
No Label
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: troytt/diablo2-web#105
No description provided.