Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
BetterMapFix
[AI-generated] Patch for BetterMap: pins mistlands vegvisir stones, adds missing dungeon entrances (infested mines, morgen holes, hildir crypts), renames pin labels to Chinese. Client-only. Read the applicability notice first.
By s6652289
| Date uploaded | 2 days ago |
| Version | 1.1.10 |
| Download link | s6652289-BetterMapFix-1.1.10.zip |
| Downloads | 48 |
| Dependency string | s6652289-BetterMapFix-1.1.10 |
This mod requires the following mods to function
denikson-BepInExPack_Valheim
BepInEx pack for Valheim. Preconfigured with the correct entry point for mods and preferred defaults for the community.
Preferred version: 5.4.2350xtavim-BetterMap
Puts creatures, boats, carts and resources on your map. Pins what you find as you find it, keeps and clears your death markers, and names the traders. Everything can be turned on and off, biome by biome, and syncs with ServerSync.
Preferred version: 1.0.5README
BetterMapFix
⚠️ APPLICABILITY NOTICE — please read this before installing.
This patch was written for my own, heavily modded setup (30+ mods enabled in an r2modman profile — BepInEx 5.4.2350 / Valheim 1.0.15). The symptom described below may be caused by my particular mod combination rather than by a bug in the original mod.
This is not a bug.
xtavim-BetterMapis not defective — it behaves exactly as it was designed to. What this patch adds are cases the original mod does not implement at all (see the table below), plus a rename of pin labels that the original has no setting for. The original mod's author bears no blame — this patch has no relationship with them and was written without their consent or review.
- If you are not seeing exactly this symptom, please don't install this — it may do nothing for you.
- This patch may not apply to your setup at all — with a different mod list the symptom may never appear.
- Even with the same symptom, the root cause may be different — this is only a workaround derived from what I found on my machine.
- If you don't want these extra pins, just don't install it — this is a preference, not a right/wrong question.
- If you think the original mod misbehaves, please report it to its author first.
⚠️ 适用性声明 —— 请先读这一段,再决定装不装。
本补丁是在我自己那套环境里做出来的:r2modman 的 profile 里同时装着 30+ 个模组 (BepInEx 5.4.2350 / 游戏 1.0.15)。下面描述的“症状”有可能是我这套模组组合互相冲突造成的。
这不是 bug。
xtavim-BetterMap本身没有问题,它完全按自身设计正常工作 —— 本补丁补的是它根本没有实现的那些情况(见下面的对照表),以及一个它本来就没有开关可调的 「图钉名中文化」。原模组作者不应被追责:本补丁与他没有任何关系, 未经其同意、也未经其审查。
- 如果你没有遇到完全相同的症状,请不要安装本补丁 —— 它可能什么都不做;
- 本补丁可能不适用于你的环境:换一套模组组合,症状也许根本不会出现;
- 就算症状一样,成因也可能不同 —— 本补丁只是我按本机情况查出来的绕行方案;
- 如果你不需要这些额外的图钉,那根本不用装 —— 这是一个取舍,不是「谁对谁错」;
- 如果你觉得原模组有问题,请先向原模组作者反馈。这只是我个人“能跑就行”的绕行方案, 不保证适用于任何人。
给 BetterMap 打的客户端补丁 —— 修三件事(另见 CHANGELOG 的 1.1.3):
- 迷雾之地的女王指引石(Vegvisir)不会被标记。
- 洞穴/地牢条目不全:希尔迪的地牢、半埋墓穴等在原版地图上不会出现。 (腐疫矿区与腐朽之穴上游 1.0.5 已自己补上; 女王洞穴入口这类上游不该自动标记的,直接在上游 cfg 里关掉即可 —— 见下方「上游已有的开关」。)
- 图钉名中文化(洞穴、要塞、祭坛那类地点图钉)。
- 补一条上游没有的规则「软组织」(
giant_brain= Soft Tissue = 软组织)—— 上游的Giant Remains只盯骨与盔甲武器,不认软组织。不要上游那几条(上古之剑/上古盔甲/骨)的话,在上游自己的 cfg 里关
[Auto Pins - Mistlands] Giant Remains = false即可 —— 本补丁不碰上游规则。
⚠️ 本模组由 AI 生成(AI-generated)。
依赖:denikson-BepInExPack_Valheim-5.4.2350 + xtavim-BetterMap-1.0.5。
(1.1.3 起要求 1.0.5 —— 上游那一版自己补上了腐疫矿区与腐朽之穴,本补丁随之去掉这两条注入。)
上游已有的开关 —— 本补丁配套关掉了两个
这两条属于上游自己的行为,本补丁不去改它、也不去删图钉,
而是在上游自己的 cfg(BepInEx/config/xtav1m.BetterMap.cfg)里关掉:
| cfg 键 | 设为 | 原因 |
|---|---|---|
[Auto Pins - Mistlands] Giant Remains |
false |
它盯的是骨与盔甲武器(giant_ribs / giant_helmet1-2 / giant_sword1-2),会把上古之剑、上古护甲、肋骨全钉出来。不要这些就关掉它 |
[Auto Pins - Mistlands] Entrance to the Queen |
false |
女王洞穴入口 —— 按游戏流程它该由女王指引石标记,不该再额外出一枚入口图钉 |
关掉之后:
- 上游不再为它们落新图钉;
- 地图上已存在的那几枚要你自己右键删(本补丁不再代为删除)。
装不装本补丁都能这么关 —— 这跟补丁无关,是上游自己的配置。
上游 1.0.4 / 1.0.5 已经修了一部分(2026-09-21 核对)
上游 BetterMap 在 1.0.4 里自己修好了「Boss 指引石不落钉」并补上「冰霜洞穴」;
1.0.5 又补上了「腐疫矿区」与「腐朽之穴」(后者改名 Putrid Holes)。
本补丁重新逐项核对后,收缩到上游仍然缺的那部分。想弄清两边的边界,看这张表:
| 功能 | 上游 1.0.4 | 本补丁 |
|---|---|---|
| Boss 指引石落钉机制 | ✅ 已修(Rule.Component + 挂在 Location 生成事件上扫内部组件) |
迷雾之地那一段交给上游;自己的扫描器留作兜底 |
| 迷雾之地的女王指引石 | ❌ 仍然没有 —— 上游 Vegvisirs 规则只有 7 个群系(无 Mistlands) |
✅ 补上 [Mistlands] Vegvisirs |
女王洞穴入口(Entrance to the Queen) |
✅ 有(IsLocation=1 / 默认开)⇒ 会自动出一枚入口图钉 |
默认跳过(Skip Rules)—— 按游戏流程它该由女王指引石标记,不该双重标记 |
冰霜洞穴 Frost Caves |
✅ 已补 | 兼容旧版仍注入(上游已有则自动跳过,不重复) |
腐疫矿区 Mistlands_DvergrTownEntrance1/2 |
✅ 1.0.5 起已有 Infested Mines(同名同 prefab、默认开) |
不再注入;但映射 Infested Mines=腐疫矿区 仍保留(上游那条无 NameToken,图钉名是英文) |
腐朽之穴 MorgenHole1/2/3 |
✅ 1.0.5 起已有 Putrid Holes(NameToken $location_morgenhole ⇒ 游戏自己翻) |
不再注入;映射改为 Putrid Holes=腐朽之穴(保险) |
希尔迪三个地牢 Hildir_cave/crypt/plainsfortress |
❌ 没有 | ✅ 补上(默认关) |
| 图钉名中文化 | ❌ 没有 | ✅ 本补丁的主要价值 |
所以:只装 BetterMap 1.0.5 而不装本补丁,迷雾之地女王指引石依旧不会出现在地图上 (腐疫矿区与腐朽之穴 1.0.5 已经有了,但希尔迪地牢、半埋墓穴、以及图钉中文名仍然缺)。
⚠️ 一个容易看错的陷阱:Dvergr Town 不是腐疫矿区
上游规则表里有一条叫 Dvergr Town、描述写着 "The dvergr settlements out on the ash sea." 的规则,
光看名字很像"矮人要塞/矿区"。它实际是:
Prefabs = ['CharredTowerRuins1_dvergr'] ← 灰烬之海的矮人据点
Biome = AshLands ← 灰烬之地,不是迷雾之地
DefaultOn = false ← 默认还是关的
BetterMap 落钉要过群系过滤(Heightmap.FindBiome(位置) == 规则.Biome),
所以它永远命中不了迷雾之地的 Mistlands_DvergrTownEntrance1/2。
这就是「规则名看着像、群系一票否决」的静默失效形态 —— 核对覆盖率时必须逐条比 prefab 名 + 群系,
不能看规则名。
为什么指引石标记不了(根因)
BetterMap 的自动标记(AutoPins.Sweep)只遍历 ZNetScene.instance.m_instances
—— 那是一张 Dictionary<ZDO, ZNetView>,只包含有网络对象的东西。
而指引石是烘焙进 Location 预制体里的子物体,没有自己的 ZDO;
它们也不在 ZNetScene 的名字表里(GetPrefab 实测返回 null),于是
ZNetScene.IsPrefabZDOValid 永远过不了、ZDO 永远不存在。
BetterMap 自己在日志里就把结论写出来了:
[Warning: BetterMap] AutoPins: "Vegvisirs" watches a prefab named Vegvisir_DragonQueen,
which this game has none of. Nothing will ever be pinned for it.
7 种 Boss 指引石全都是这个下场(不是龙母特有),cfg 里也没有自定义名字的选项。
上游 1.0.4 的修法(与本补丁当初的诊断完全一致):规则改填新字段 Component = typeof(Vegvisir),
新增 AutoPins.Spawned(LocationProxy) / Inside(...),挂在 Location 生成事件上扫内部组件 ——
比本补丁「按 Exploration Radius 扫玩家附近」更彻底(Location 一生成就能标记,不受半径限制)。
但上游只给 7 个群系加了 Vegvisirs 规则,没有迷雾之地,所以女王指引石仍然要靠本补丁。
这个补丁怎么做(尽量走 BetterMap 自己的路)
| 功能 | 做法 |
|---|---|
| 洞穴/地牢补全 | 在 Plugin.BindPinRules 跑之前,往 PinRules.All 里补几条规则。剩下的 BetterMap 自己全包 —— 在它自己的 cfg 里生成开关(分区 Auto Pins - <群系>、中文注释)、并进 _byLocation 地点表、进图例、按 Merge Distance 去重、"删掉的钉不会再出现"。名字与群系跟上游已有的重了会自动跳过,不会出双份。 |
| 指引石 | 1.0.4+:把迷雾之地那条规则也填成 Component=typeof(Vegvisir),交给上游自己的新机制;本补丁的扫描器保留作兜底(上游落过钉的位置会被去重记录挡住,不会双钉)。1.0.2/1.0.3:上游没有这条通道,靠本补丁挂在它自己的 AutoPins.Sweep 之后,沿用它的扫描节奏与探索半径找玩家附近的 Vegvisir 组件,再调它自己的 AutoPins.Place(rule, null, pos) 落钉。 |
补的规则(开关出现在 BetterMap 自己的 cfg 里):
| 规则名 | 分区 | 位置名(ZoneLocation.m_prefabName) |
默认 | 中文图钉名 |
|---|---|---|---|---|
Infested Mines |
Auto Pins - Mistlands |
Mistlands_DvergrTownEntrance1、…2 |
开 | 腐疫矿区 |
Morgen Holes |
Auto Pins - AshLands |
MorgenHole1、2、3 |
开 | 腐朽之穴 |
Frost Caves |
Auto Pins - Mountain |
MountainCave02(1.0.4 上游已有,会自动跳过) |
开 | 冰霜洞穴 |
Hildir Cave |
Auto Pins - Mountain |
Hildir_cave |
关 | 希尔迪洞穴 |
Hildir Crypt |
Auto Pins - BlackForest |
Hildir_crypt |
关 | 希尔迪墓穴 |
Hildir Fortress |
Auto Pins - Plains |
Hildir_plainsfortress |
关 | 希尔迪平原要塞 |
Half Burried Crypt |
Auto Pins - BlackForest |
HalfBurried_ForestCrypt(实测 m_enable=**False**,原版不放置) |
关 | 半埋墓穴 |
Vegvisirs |
Auto Pins - Mistlands |
组件通道 Vegvisir(1.0.4+)/ Vegvisir_SeekerQueen(旧版) |
开 | 沿用游戏本地化 |
位置名不是猜的:本地化表 resources.assets 里
location_dvergrtown = Infested Mine = 简中「腐疫矿区」;
资产表 SoftRef/manifest 里 Assets/world/Locations/Mistlands/Mistlands_DvergrTownEntrance1.prefab 等。
名字如果写错,BetterMap 自己的自检会打
"watches a place named X, which this game has none of" —— 日志里没有这条就说明名字对。
本补丁自己的配置(BepInEx/config/bettermapfix.client.only.cfg)
| 键 | 默认 | 说明 |
|---|---|---|
1 - General / Enabled |
开 | 总开关 |
2 - Vegvisirs / Scan Vegvisirs |
开 | 指引石补标记(1.0.4 上相当于兜底) |
3 - Caves / Inject Cave Rules |
开 | 注入上面那几条洞穴规则 |
4 - Labels / Log Unknown Pin Names |
开 | 诊断:把映射表没命中、且像英文的图钉名打进日志(去重,最多 60 个)。看到不认识的英文名就加进 Name Map |
4 - Labels / Chinese Labels |
开 | 图钉名中文化 |
4 - Labels / Name Map |
69 条 | 内置表已覆盖 BetterMap 全部规则名,正常不用动。写 英文名=你的译名 可覆盖;写 英文名=(值留空)= 删掉这一条 |
4 - Labels / Merge Default Map |
开 | 把内置默认译名表合并进上面那张表(你的条目优先)。见下节 |
4 - Labels / Rename Existing Pins |
开 | 连已放在地图上的旧图钉一起改名 |
9 - Debug / Dump Location Names |
关 | 世界加载后把游戏的地点表整表打进日志,用来核对位置名 |
9 - Debug / Verbose Pin Log |
开 | 每落一个指引石图钉打一行日志 |
为什么需要 Merge Default Map
BepInEx 的配置有个特性:cfg 文件里已经存在某个键时,它不会用新的默认值覆盖文件里的旧值。
于是本补丁每次升级新增的内置译名,对"cfg 里早就写过旧表"的老用户永远不会生效 ——
症状是「新补的图钉标出来了,但名字还是英文」。补丁 1.1.0 实际踩到了这个坑:
新增 Infested Mines=腐疫矿区 之后,腐疫矿区图钉能标出来,名字却仍是 Infested Mines。
所以现在会把内置表与你的表做并集(内置先铺、你的覆盖):
| 你想做的事 | 怎么做 |
|---|---|
| 什么都不管,希望自动获得新译名 | 保持 Merge Default Map = 开(默认) |
| 改某条的译名 | 在 Name Map 里写 英文名=你的译名(你的优先) |
| 删掉某条内置译名 | 在 Name Map 里写 英文名=(值留空) |
| 完全自己掌控,不要任何内置译名 | 关掉 Merge Default Map |
图钉中文化怎么实现的(只动标签这一层)
原模组落钉时用 PinNames.For(Rule, GameObject) 算图钉名;地点类规则的 NameToken 是空的、
go 传 null ⇒ 图钉名就等于英文规则名(这就是 Troll Caves / Bear Caves 的由来)。
本补丁只给这个函数的返回值做精确整串替换:
- 不改
rule.Name—— 那是原模组 cfg 的键名,改了会把你的配置项也改名; - 不动规则表、图标、图例、去重记录;
- 表里没有的名字原样放行,所以只影响你想翻的那几个。
内置表覆盖 BetterMap 全部 69 条规则名(不是只覆盖地点类)。
为什么必须全覆盖:图钉名由
PinNames.For(Rule, GameObject)决定, 只有NameToken与For(go)两条路都取不到名字时,才会兜底用英文规则名; 而AutoPins.Place里没有任何本地化调用 ⇒ 落到兜底支的图钉就是英文。 会落到兜底支的包括:① 全部地点类规则(落钉时go传null); ② 预制体类里那些没有 Piece / Pickable / MineRock 组件的预制体(如Leviathans)。 与其逐个判断哪些预制体缺组件,不如一次全覆盖 —— 整串精确匹配,多余条目无副作用。
译名优先取游戏自己的本地化表,与你在游戏里看到的名词一致;游戏里没有的才自拟(
Sulfur Arches / Frozen Trolls / Ash Pots / Unstable Lava Rock)。
Leviathans 现为「甲壳素」(按需求定的译名)。
⚠️ 替换挂在两个地方:
PinNames.For(规则路径)+Minimap.AddPin(兜底)。 全量反汇编 BetterMap 1.0.4 发现Minimap.AddPin有 6 个调用方 (AutoPins.Place/CreatureTracker.Add/NamedPins.Retag/DeathMarkers.Rebuild/VehicleTracker.Reconcile/AutoPins.Portal), 而只有AutoPins.Place走PinNames.For—— 生物、传送门、死亡标记这些路径各自算名字, 只补前者会漏(1.1.1 就漏了Leviathans)。在AddPin上兜一层后与走哪条路无关。
Name Map 里键名写错只会静默不生效,所以交付前有一条机器校验(拿 BetterMap.dll 的字符串堆逐个核)。
旧图钉:名字是落钉那一刻写进地图数据的,光改上面那个函数对它们无效, 因此另有一趟 2 秒一次的低频重命名,只动名字精确命中映射表的图钉,直接改显示文本(不重建 UI)。
指引石仍然听 BetterMap 各群系里的 Vegvisirs 开关 —— 本补丁不改它。
怎么确认它在干活
日志里出现这些就说明工作正常:
[Info : BetterMapFix] BetterMapFix 1.1.2 已加载:洞穴规则注入=True,指引石扫描=True,中文图钉名=True(接口自检通过)。
[Info : BetterMapFix] 检测到 BetterMap 支持 Rule.Component(1.0.4+):是 —— 迷雾之地 Vegvisirs 交给它自己的「Location 内部组件」通道,本补丁扫描仅兜底。
[Info : BetterMapFix] 中文名映射 = 内置 69 条 ∪ 用户表(覆盖 33 / 用户新增 0 / 显式删除 0)→ 生效 69 条
[Info : BetterMapFix] +规则 [Mistlands] Infested Mines → Mistlands_DvergrTownEntrance1, Mistlands_DvergrTownEntrance2(默认 开,地点类)
[Info : BetterMapFix] +规则 [AshLands] Morgen Holes → MorgenHole1, MorgenHole2, MorgenHole3(默认 开,地点类)
[Info : BetterMapFix] +规则 [Mistlands] Vegvisirs → 组件 Vegvisir(默认 开,组件类)
[Info : BetterMapFix] 规则 [Mountain] Frost Caves 已存在(原模组自己提供,或本补丁已注入过),跳过。
[Info : BetterMapFix] 已有图钉改中文名 1 个(累计 1 个)。
[Info : BetterMapFix] 指引石已标记 [Mountain] 位置 1234.5,-678.9(距玩家 42.3 m)
[Info : BetterMapFix] 本轮扫到附近指引石 2 块 → 新落钉 1,跳过 1(已记过账 / 该段开关关着)。
「中文名映射」那行的三个数字要盯一下:生效条数应当 ≥ 内置条数(36)。
若生效条数明显少于内置条数,说明 Merge Default Map 被关了。
装的是 BetterMap 1.0.4 时两条都是正常的:
+规则 [Mountain] Frost Caves … 已存在,跳过—— 上游自己有了,本补丁不重复注入(预期行为);- BetterMap 仍可能对
Vegvisir_SeekerQueen打 "which this game has none of" 警告 (1.0.2/1.0.3 上是因为我们把它放进了规则表,而它的 ZDO 扫描永远够不着); 在 1.0.4 上我们改走组件通道,这条警告应该消失。
兼容性
- 面向 BetterMap 1.0.2 / 1.0.3 / 1.0.4(
xtav1m.BetterMap)编写,按版本自动选择通道: 有Rule.Component(1.0.4+)就走上游的组件机制,没有就退回本补丁自己扫描。 - 所有内部调用都走反射并做存在性自检;
Rule.Component是可选字段, 缺了不会让自检失败(否则 1.0.2 上会把整个补丁停用)。 BetterMap 换版本时本补丁只会打印一条"接口自检不通过"并停用,不会拖垮游戏加载。 - 纯客户端、不声明 NetworkCompatibility(NotEnforced)⇒ 主机不装也能用、不挡联机。
- 只读场景对象与本地地图数据,不改任何网络权威数据。
卸载
删掉 BepInEx/plugins/<这个包>/BetterMapFix.dll 即可。
留在 BetterMap cfg 里的那几个键(Infested Mines / Morgen Holes 等)删不删都行,
删掉下次启动会按默认值重建。
CHANGELOG
Changelog
首次公开发布 = 1.0.2。下面的 1.0.0 / 1.0.1 是开发期迭代,没在 Thunderstore 上发布过 (列在这里是为了说明代码里那几处防护是怎么来的)。
[1.1.12] — 修 Ash Pot / Greydwarf Nest 两枚图钉显示英文(NameToken 与规则名单复数不匹配)
问题
灰烬之地的红陶罐图钉在地图上显示英文 Ash Pot(用户报告:"map 里标记的 ash pot 是什么")。
根因(不是漏翻,是键名单复数不匹配)
PinNames.For(Rule, GameObject) 的取名优先级(IL 实证):
① rule.NameToken 非空 ⇒ 返回它 ← Ash Pots 走的就是这条,返回 "Ash Pot"
② 否则 For(go):Piece / Pickable / MineRock 的名字
③ 兜底返回 rule.Name(英文)
上游有两条规则的 NameToken 是裸英文(不是 $ 本地化键,游戏不翻),
且与规则名差一个字母(规则名复数、钉名单数):
| 规则名(= cfg 键名) | NameToken(= 图钉名) | 旧内置表键 | 结果 |
|---|---|---|---|
Ash Pots |
Ash Pot |
Ash Pots=灰烬陶罐 |
❌ 命不中 |
Greydwarf Nests |
Greydwarf Nest |
Greydwarf Nests=灰矮人巢穴 |
❌ 命不中 |
而替换是整串精确匹配 ⇒ 只写复数规则名,单数钉名永远命中不了。
(Giant Remains / Leviathan 两组两种写法都齐,所以没事。)
改动
- 内置表补两条:
Ash Pot=灰烬陶罐、Greydwarf Nest=灰矮人巢穴(69 → 71 条) - README 的条数说明与「NameToken 变体」⚠️ 注记同步更新
- 源码里补了注释,说明这两条为什么必须收(避免后来人当"重复条目"删掉)
备注
- 本机 cfg 的
Name Map不需要动 —— 内置表与用户表做并集,重启即生效。 - 已落地的旧图钉由
Rename Existing Pins那趟 2 秒低频重命名兜底改名。
[1.1.11] — 改回 Giant Remains=巨人遗骸(跨工程交叉评审发现的错)
问题
由 EasyMap 工程(BetterMap + 本补丁成果的内联版)评审时发现:
Giant Remains=软组织 ← 错
上游 Giant Remains 规则管的是骨与盔甲武器,它自己的 Description 就写着
(IL 实证,原文照抄):
The bones and armour of the fallen giants. Black marble, and iron and copper scrap.
Prefabs = giant_ribs, giant_helmet1, giant_helmet2, giant_sword1, giant_sword2。
而软组织是另一个东西(giant_brain,piece_giant_brain = Soft Tissue),
1.1.9 起已由本补丁单列一条 Soft Tissue 规则 + Soft Tissue=软组织 映射。
⇒ 同一个「软组织」挂在两条语义不同的规则上,是矛盾的。
为什么会出现(不是"笔误",是遗留物)
- 1.1.8:用户要求把当时的显示名改成「软组织」。那时上游这条规则被本补丁劫持成
只认
giant_brain⇒ 标「软组织」在当时是对的。 - 1.1.9:改成「关上游 + 新增
Soft Tissue规则」,但把这条映射留在了内置表里。 当时的理由是"地图上已有的软组织钉存的m_name就是Giant Remains,删了会变回英文"。 - ⚠️ 这个理由只对发布者那一台机器的存量图钉成立,不该写进发布默认值。
任何没关掉上游
Giant Remains的用户(或将来重新打开的), 骨/剑图钉都会被错标成「软组织」。
改动
- 内置表:
Giant Remains=软组织→Giant Remains=巨人遗骸 - 同步修正本机 cfg 里那条 1.1.8 时期写下的陈旧值(
Name Map值 +# Default value:注释两处)
对已有图钉无影响
改名趟是就地覆写 pin.m_name(RenamePin: pin.m_name = zh),
所以之前被改名成中文「软组织」的那批钉,存的已经是中文;
改回默认值后查表查不到,不会再变。软组织仍由 Soft Tissue=软组织 负责。
与 EasyMap 的一致性
两个工程的 ChinesePins 表各有 71 条,本次修正后完全一致。
(EasyMap 那边本来就是对的,无需改动。)
[1.1.10] — 同样的思路也用在「女王洞穴入口」上:删掉 Skip Rules
[1.1.10] — 同样的思路也用在「女王洞穴入口」上:删掉 Skip Rules
背景
1.1.9 把「巨人遗骸」改成「上游 cfg 关掉 + 补丁新增规则」之后,Skip Rules 就成了最后一块
"补丁去拦截/删除" 的遗留物。它做三件事:
- 在
AutoPins.Place前拦掉落钉(RuleInjection.PlacePrefix); - 每 2 秒扫一遍地图,把该规则已有的图钉删掉(
ChineseLabels.SkipExisting); - 一个配置项
[3 - Caves] Skip Rules指定要跳过的规则名。
而上游 cfg 里本来就有这个开关:
[Auto Pins - Mistlands] Entrance to the Queen。⇒ 照 1.1.9 的模式简化掉。
改动
- 上游开关关掉(在上游自己的 cfg 里):
[Auto Pins - Mistlands] Entrance to the Queen = false - 删掉
Skip Rules整套:SkipRules配置项、RuleInjection.PlacePrefix、BetterMapFixPlugin.SkipRules(含启动日志那行)、ChineseLabels.SkipExisting()、_skippedTotal、以及AutoPins.Place上那条 prefix 挂载。
DLL 43,008 → 40,960 字节。
保留
映射 Entrance to the Queen=女王巢穴入口 —— 万一将来重新打开上游那个开关,
图钉名仍是中文。
现在的整体形态
补丁只做加法:
| 补丁做的事 | 说明 |
|---|---|
| 注入 6 条上游没有的规则 | 半埋墓穴 / 希尔迪 ×3 / [Mistlands] Vegvisirs / 软组织 |
| 图钉名中文化 | 上游的规则名是普通英文串(不是 $ 键),游戏不会翻 |
| 指引石兜底扫描 | 挂在它自己的 Sweep 之后 |
不再修改上游规则、不再删除任何图钉。
[1.1.9] — 换思路重做「巨人遗骸」:关上游 + 新增一条规则(删掉全部拦截机器)
[1.1.9] — 换思路重做「巨人遗骸」:关上游 + 新增一条规则(删掉全部拦截机器)
用户重新梳理后的诉求(本版的依据)
- 不想要上游标记的巨人遗骸(上古之剑、上古盔甲、骨…)—— 如果上游配置文件里能直接关,就不需要补丁来拦截、删除;
- 软组织上游没有标记 ⇒ 补丁该做的是新增一条规则帮它钉住软组织。
之前的做法(1.1.4~1.1.8):5 个活动部件,全是绕路
| 部件 | 干什么 |
|---|---|
Rule Prefab Overrides |
劫持上游 Giant Remains 的 Prefabs,5 个骨剑换成 giant_brain |
Drop Existing Pins For Overridden Rules |
按名字删旧图钉(85+ 枚) |
| 一次性清理守卫 | 防止每 2 秒重删把新钉的也删掉 |
PinRecord.Wipe() |
清掉「已钉过」记录(否则同位置的新规则钉不出来) |
ForceResweep() |
清节流让上游立刻重扫 |
这 5 个部件在 1.1.4→1.1.8 期间一共引出 4 个 bug(钉不出来 / 钉了又删 / 来不及重扫 / 译名不生效)。
本版做法:2 个部件,不碰上游规则
-
上游开关关掉(在上游自己的 cfg 里):
[Auto Pins - Mistlands] Giant Remains = false上游就不再钉骨/剑了。零补丁代码,而且用户随时能改回来。
-
本补丁新增一条规则(用已有的注入机制,和 5 条洞穴规则同一套):
Name = Soft Tissue Prefabs = [giant_brain] Biome = Mistlands Category = Ore DefaultOn = 1 IsLocation = 0- 映射表
Soft Tissue=软组织。
- 映射表
🔑 为什么这样能"零清理"
反汇编 PinRecord.Has(category, position, within)(IL 实证):
ldfld entry.Category
ldarg.0 ; 查询用的 category
bne.un → 跳过 ; 分类不同就跳过
去重记录是带分类比较的。 所以新规则只要沿用同一分类 Ore:
- 老位置(原来骨/剑图钉占过的)→ 记录还在 → 新规则不重复钉; 但那儿本来就有图钉(且显示「软组织」)⇒ 无需删、也不会重复
- 新位置 → 没记录 → 新规则正常落钉 ✅
⇒ 不用删图钉、不用清记录、不用强制重扫。
删掉的代码
Rule Prefab Overrides、Drop Existing Pins For Overridden Rules、
ApplyPrefabOverrides()、_overriddenRuleNames、_overrideCleanupDone、
PinRecordWipe()、ForceResweep()、MPinRecordWipe、FNextSweep —— 约 150 行。
DLL 46,080 → 43,008 字节。
保留的
- 映射
Giant Remains=软组织—— 地图上已有的那批软组织图钉存的m_name就是Giant Remains(当时的规则名),删了它们会变回英文。 Skip Rules(女王洞穴入口)—— 那是另一件事,本次不动。 (不过同样的思路也适用于它:上游 cfg 里本来就有[Auto Pins - Mistlands] Entrance to the Queen,将来想简化也可以照这个模式来。)
[1.1.8] — 「巨人遗骸」改名「软组织」
[1.1.8] — 「巨人遗骸」改名「软组织」
背景
1.1.7 之后软组织正常钉出来了,但图钉名显示「巨人遗骸」—— 那是规则名
(Giant Remains → 映射表译名),而这条规则现在只认软组织,标签该跟着变。
改动
- 内置映射表:
Giant Remains=巨人遗骸→Giant Remains=软组织。 Rule Prefab Overrides的说明文字改用英文规则名(Giant Remains)指代, 不再用中文译名 —— 译名会变,拿它解释配置容易再次对不上。
⚠️ 重要:老用户必须手动改 cfg,否则不生效
Name Map 是可配置项,而 BepInEx 的 cfg 里已存在的键不会用新默认值覆盖。
实测你这台机器的 cfg 里存着 1.1.0 时期写下的旧值:
Name Map = …Giant Remains=巨人遗骸…
它会盖过内置表,所以光升级 DLL 名字不会变。两处要一起改:
- 第 85 行
Name Map = …里的那条(真正生效的那处); - 第 84 行
# Default value: …的注释(只是展示用,顺手保持一致)。
(1.1.8 的交付已替你改好,并留了 bettermapfix.client.only.cfg.bak-<时间戳> 备份。)
已有图钉会一起改名
改名趟是按 PinData.m_name 查表的,而旧图钉存的 m_name 就是 Giant Remains
⇒ 下一轮扫描会自动改成「软组织」,不用删了重钉。
[1.1.7] — 清完去重记录后立刻重扫;加 ZNetScene 名字核查诊断
[1.1.7] — 清完去重记录后立刻重扫;加 ZNetScene 名字核查诊断
背景:1.1.6 的测试时间上不够,不能算软组织失败
1.1.6 那次跑的日志时间线:
12:53:50 世界加载(覆写生效)
12:54:48 玩家在移动
12:55:05 删除旧图钉 + PinRecord.wiped ← 清理实际发生在这一刻
12:55:08 Stopping build thread
12:55:11 Net scene destroyed(游戏关闭)
清理后只过了 6 秒就关游戏了 —— BetterMap 的 AutoPins.Tick 有节流
(if (Time.time < _nextSweep) return;),来不及重新落钉。
所以"软组织没钉出来"这次没有得到有效验证。
本版改动
- 清完
PinRecord后主动触发一次重扫:把AutoPins._nextSweep清 0, 让 BetterMap 下一次Tick立刻扫一遍,不用干等节流间隔。 (⚠️ 不直接Invoke它的Sweep()——Tick里在它之前还有Build()和三个索引的非空检查, 走它自己的路径最稳。) - 新增诊断
[9 - Debug] Dump ZNet Names(默认giant):把ZNetScene里名字含关键词的 已注册预制体与世界里活着的实例打进日志,并单独核查配置里点名的名字是否注册。 回答两个问题:- 规则里写的预制体名到底注册没有(没注册 ⇒ 规则永远匹配不到,属于"静默失效");
- 世界里那个东西的实际名字是什么。
[1.1.6] — 修「新钉出来的软组织立刻又被删」;Leviathan 真名查到了
[1.1.6] — 修「新钉出来的软组织立刻又被删」;Leviathan 真名查到了
用户实测反馈(1.1.5)
① 软组织被标记之后立刻又被删掉;② Leviathan 那边仍不中文。
① 死循环根因:清理是每 2 秒重复的,而目标规则还在继续落钉
真机日志(同一位置出现两次删除):
已删除图钉 «巨人遗骸»(位置 (-5949.3, 28.4, -2799.9),剩 355 枚)。
[BetterMap] PinRecord: wiped
BetterMapFix: 已清空 BetterMap 的「已钉过」记录(PinRecord.wiped)
已删除图钉 «巨人遗骸»(位置 (-5949.3, 28.4, -2799.9),剩 354 枚)。 ← 新钉出来的又被删
链条是:删旧钉 → PinRecord.Wipe() → BetterMap 按新规则重新钉出 giant_brain
→ 但它的图钉名仍是规则名 Giant Remains(⇒ 翻成「巨人遗骸」)
→ 名字跟旧的一模一样,又被那趟清理删掉,循环往复。
修法:覆写规则的清理改成每会话只做一次(_overrideCleanupDone 标记)。
清掉"改规则之前留下的"那些就够,之后新落的一律放过。
(Skip Rules 的删除不受影响 —— 那些规则永远不会落钉,重复删也无害。)
② Leviathan 的真名:诊断开关一次就查到了
日志实证:
[诊断] 未翻译的图钉名 #21: "Leviathan"
是单数 Leviathan,不是规则名 Leviathans(之前只映射了复数版,所以永远命不中)。
它来自生物通道:CreatureTracker 走 Localization.Localize(Character.m_name),
而 m_name 是普通字符串 "Leviathan"(不是 $ 键)⇒ Localize 原样返回 ⇒ 地图上显示英文。
修法:映射表补上 Leviathan=甲壳素(保留 Leviathans=甲壳素,两条都留)。
顺带收紧了诊断过滤器:原来把 $item_copperore / $enemy_dragon 这类本地化键
也记了,实测 60 个名额大半被它们占掉 —— 而那些键 Minimap.PinNameData.SetTextAndGameObject
里游戏自己会 Localization.Localize,根本不用我们管。现在只记纯 ASCII 的英文名。
[1.1.5] — 修「软组织钉不出来」;加未翻译图钉名诊断
[1.1.5] — 修「软组织钉不出来」;加未翻译图钉名诊断
用户实测反馈(1.1.4)
① 覆写生效了、旧图钉也删掉了(日志实证:覆写 1 行、删除 85 枚),但软组织没被钉出来; ② Leviathan(甲壳素)那枚还是没翻成中文。
① 软组织钉不出来的根因:PinRecord 去重记录没清
反汇编 PinRecord(IL 实证):
| 方法 | 行为 |
|---|---|
Load() |
_loaded == false 时从 Player.m_customData["BetterMap.pinned"] 读回记录 |
Forget() |
只清内存缓存、不落盘 ⇒ 下次 Load() 又把数据读回来 |
Wipe() |
清空并 Flush() 落盘,打 PinRecord: wiped |
1.1.4 只删了 Minimap 上的图钉,没清去重记录 ⇒ 那些位置仍算"已钉过",
于是盯着同一位置的 giant_brain 被 dedup 挡掉,永远钉不出来。
(日志里没有 PinRecord: wiped,证实从没被清过。)
修法:删掉"被覆写规则"的旧图钉后,调一次 PinRecord.Wipe()(每会话只做一次)。
副作用:BetterMap 会按当前规则重新评估一遍该钉什么 —— 这正是想要的效果。
② Leviathan 名字对不上:静态分析查不到,改用真机诊断
已排除的可能(都查过):
CreatureTracker.Describe的名字是Named ? (given 为空 ? Localize(Character.m_name) : given) : nullCreatureTracker.Add用Named ? Label : ""作为图钉名- 本地化表里没有
enemy_leviathan(只有成就项ach_grindleviathan) - UnityPy 读
Leviathan预制体:7 个组件里一个字符串都没有 ⇒ 看不到Character.m_name
⇒ 加诊断开关 [4 - Labels] Log Unknown Pin Names(默认开):
把映射表没命中、且看起来需要翻译(纯 ASCII 或以 $ 开头)的图钉名打进日志,
去重、最多 60 个、满就停。看到那个英文名是什么,加进 Name Map 就能翻。
[1.1.4] — 「巨人遗骸」改为只认软组织
[1.1.4] — 「巨人遗骸」改为只认软组织
需求
用户:BetterMap 自带的巨人遗骸会识别很多种要素(上古之剑、上古护甲、肋骨…),只想让它认软组织。
根因(IL + 资产表 + 本地化表三重核对)
上游 Giant Remains 规则盯着 5 个 prefab:
| prefab | 游戏内名称 |
|---|---|
giant_ribs |
肋骨(本地化表无 piece_giant_ribs) |
giant_helmet1 / giant_helmet2 |
上古护甲 |
giant_sword1 / giant_sword2 |
上古之剑 |
而 giant_brain(= 软组织)在整个 BetterMap 1.0.5 的 DLL 里一次都没出现 ——
上游根本没识别它。⇒ 所以这不是"过滤掉别的",而是把整份列表换成 giant_brain。
(附带确认:这 4 个预制体的组件结构完全一样,都没有 Piece、没有任何 $ 串
⇒ PinNames.For(go) 返回 null ⇒ 图钉名就是规则名 Giant Remains,
映射表里已有 Giant Remains=巨人遗骸,不用改映射。)
本版改动
- 新增
[5 - Rules] Rule Prefab Overrides(默认Giant Remains=giant_brain): 覆写某条规则盯哪些预制体。格式规则名=prefab1,prefab2,多条用;隔开。 只改Prefabs,不动规则名 ⇒ BetterMap 的 cfg 键名不变,开关还在原地。 - 新增
[5 - Rules] Drop Existing Pins For Overridden Rules(默认开): 被覆写过的规则,地图上已有的旧图钉按规则名(含中文译名)删掉;重访后按新规则重新落钉。 (改规则只影响新落钉,旧的那些得单独清。) SkipExisting的限流门拆开:清理不再被Rename Existing Pins开关挡住 ("改名"和"清理"是两件事),且清理排在改名之后(删除集合同时认英文与中文译名)。- 通用性:这套覆写机制不限于巨人遗骸,以后想改任何规则的盯捕范围都直接改配置。
[1.1.3] — 适配 BetterMap 1.0.5;去掉已被上游覆盖的两条注入
[1.1.3] — 适配 BetterMap 1.0.5;去掉已被上游覆盖的两条注入
上游 1.0.5 做了什么(IL 实证,不是看 CHANGELOG 猜的)
拆 PinRules..cctor 重建规则表,并用已知良好的 1.0.4 表做归一化逐条校验后才下结论:
规则数 73 → 75,只多两条。
| 新规则 | prefabs | Biome | Category | DefOn | IsLoc | NameToken |
|---|---|---|---|---|---|---|
Infested Mines |
Mistlands_DvergrTownEntrance1/2 |
Mistlands | Dungeon | 1 | 1 | 无 |
Putrid Holes |
MorgenHole1/2/3 |
AshLands | Dungeon | 1 | 1 | $location_morgenhole |
另修了三项:没有指引石的遗迹不再出指引石图钉(AutoPins.Inside 组件扫描改了)、
图钉图标不再与 TargetPortal 等自带图标模组冲突、同会话二次读世界不再反复报错。
本版改动
- 删除两条注入:
Infested Mines、Morgen Holes—— 上游 1.0.5 已提供 (后者改叫Putrid Holes)。依赖同步升到xtavim-BetterMap-1.0.5, 装不上 1.0.5 就不会缺这两条。 - 🔴 新增第二道判重:比 prefab 集合。 原来只比「规则名 + 群系」,
上游把规则改名(
Morgen Holes→Putrid Holes)就认不出来,会注入出 第二条同 prefab 的规则 ⇒ cfg 里两个开关管同一批位置。现在只要上游已有规则 盯着同一批 prefab,不管叫什么名字都算已覆盖、跳过。 - 映射表调整:
Infested Mines=腐疫矿区保留 —— 上游那条没有 NameToken,图钉名还是英文规则名;Morgen Holes=腐朽之穴删除 —— 上游没有这个名字的规则了,留着永远命不中;Putrid Holes=腐朽之穴新增(保险)—— 上游那条有 NameToken,游戏自己会翻。
- 兼容性:本补丁挂载的 6 个类型 / 38 个方法签名与 1.0.5 零差异,不存在挂失败风险。
仍然需要本补丁的(上游 1.0.5 依旧没有)
Half Burried Crypt、Hildir Cave / Hildir Crypt / Hildir Fortress、
迷雾之地的 Vegvisirs(上游 7 条 Vegvisirs 仍无 Mistlands)、
Entrance to the Queen 的跳过、以及整套图钉名中文化。
[1.1.2] — 修「非规则路径的图钉名不中文」;女王洞穴入口不再自动标记
[1.1.2] — 修「非规则路径的图钉名不中文」;女王洞穴入口不再自动标记
修复
-
🔴
Leviathans(以及所有非规则路径落的钉)名字没被翻成中文。 用户实测 1.1.1 后反馈"leviathan 没有被正确显示中文"。根因(全量反汇编 BetterMap 1.0.4 才发现):
Minimap.AddPin一共有 6 个调用方 ——AutoPins.Place/CreatureTracker.Add/NamedPins.Retag/DeathMarkers.Rebuild/VehicleTracker.Reconcile/AutoPins.Portal。 而其中只有AutoPins.Place走PinNames.For取名,其余五条各自算名字 (生物走Character.m_name、传送门/死亡标记走自己的逻辑)。 1.1.1 只把替换挂在PinNames.For上 ⇒ 这五条路径一个都没覆盖到。修法:在游戏侧
Minimap.AddPin上再兜一层 postfix,对刚落的那枚图钉做同一张表的替换。 与走哪条落钉路径无关,六条全盖住。原有的PinNames.Forpostfix 保留作双保险。 -
旧图钉改名趟的挂载点不可靠。 原来挂在
Minimap.UpdatePins上,但 IL 实证Minimap.Update()里是if (m_pinUpdateRequired) { m_pinUpdateRequired = false; UpdatePins(); }⇒ 只在校验位置位时才跑,不是每帧。改挂每帧都跑的Minimap.Update(内部仍 2 秒限频)。 (这就是"地图上已有的英文图钉没被改掉"的原因。)
变更
Leviathans的译名按你的要求改为「甲壳素」(原为「利维坦」)。- 新增配置
[3 - Caves] Skip Rules(默认Entrance to the Queen): 不自动落钉的规则名,逗号分隔,填 BetterMap cfg 里的规则名(键名)。 默认填女王洞穴入口 —— 按游戏流程,迷雾之地的女王巢穴是由女王指引石标记的, 不该再额外出一枚入口图钉(会变成双重标记)。 · 只挡新落钉(挂在AutoPins.Place前面,那是它所有规则落钉的唯一入口); · 地图上已有的那枚会被自动删掉,每删一枚打一条日志(同时认英文原名和中文译名, 避免"先被翻成中文就删不掉"); · 想恢复自动落钉就把这里清空。 · 🔴 我们的 prefix 整段 try/catch,出错时return true放行 —— 绝不因为补丁自己的异常把 BetterMap 的落钉搞停摆。
兼容性
- 与 1.1.1 相比只改了挂载点与内置译名表;依赖仍为
xtavim-BetterMap-1.0.4。
[1.1.1] — 图钉中文名全覆盖(69 条规则名)
[1.1.1] — 图钉中文名全覆盖(69 条规则名)
修复
-
有些图钉名仍是英文。 用户实测发现
Leviathans(海洋利维坦)没被翻成中文。根因(全部 IL 实证):图钉名由
PinNames.For(Rule, GameObject)决定,三个分支 —— ①rule.NameToken非空 ⇒ 返回本地化键(如$piece_vegvisir),游戏自己翻; ② 否则For(go):Piece.m_name/Pickable掉落物名 /MineRock掉落物名… 也都是本地化键; ③ 都拿不到 ⇒ 兜底返回rule.Name(英文)。 而AutoPins.Place里没有任何Localization调用 ⇒ 落到第 ③ 支的图钉就是英文。会落到第 ③ 支的有两类:
- 地点类规则(
IsLocation=true,落钉时go传null)⇒ 必然走兜底; - 预制体类规则里、那些没有 Piece / Pickable / MineRock 组件的预制体 ——
Leviathans正是这种。
修法:不再逐个判断哪些预制体缺组件,直接把 BetterMap 全部 69 条规则名一次覆盖。 匹配是整串精确匹配,多余条目永不被命中、无副作用;代价只是 cfg 里那串稍长(1353 字符)。
- 地点类规则(
-
内置映射表 36 → 69 条。新增的 33 条(按上一条的性质,其中地点类 5 条是"必然英文"):
规则名 中文 规则名 中文 Leviathans利维坦 Beehives蜂房 Sulfur Arches硫磺拱 Thistle蓟草 Frozen Trolls冰冻巨魔遗骸 Mushrooms蘑菇 Boar Runestones鬓猪符文石 Dandelions蒲公英 Draugr Runestones尸鬼符文石 Flint燧石 Greydwarf Runestones灰矮人符文石 Copper / Tin / Silver Deposits铜 / 锡 / 银矿源 Ash Pots灰烬陶罐 Obsidian Deposits黑曜石矿源 Unstable Lava Rock不稳定熔岩 Flametal焰金属 Vegvisirs导向符文石 Magecap法师帽菇 Greydwarf Nests灰矮人巢穴 Jotun Puffs巨人泡泡 Fuling Totems丑地精图腾 Smoke Puffs余烬泡泡 Raspberry / Blueberry / Cloudberry / Lingonberry Bushes覆盆子 / 蓝莓 / 云莓 / 越橘丛 Vineberries酒莓 Carrot / Turnip / Kale Seeds胡萝卜 / 芜菁 / 羽衣甘蓝种子 Snowballs雪球 译名优先取游戏自己的本地化表(
resources.assets的简中列),所以与你在游戏里看到的名词一致; 游戏里没有对应名词的才自拟(Sulfur Arches/Frozen Trolls/Ash Pots/Unstable Lava Rock/Leviathans)。注:
鬓猪是游戏官方简中的写法(enemy_boar),照抄是为了与游戏内一致 —— 不习惯可以自己改。 -
顺带修正了三处与游戏官方译名不一致的旧译法(之前是按字面直译的):
Copper/Silver/Obsidian Deposits由 矿脉/矿 → 矿源(游戏里叫Copper Deposit=铜矿源),Thistle蓟 → 蓟草,Fuling Totems地精图腾 → 丑地精图腾(item_goblintotem)。 其余 30 条原有译名一字未改(已用脚本逐条比对确认),你地图上已有的中文图钉不会变样。 -
配置项
Name Map的注释同步改写:原先给的"示例串"如今都成了内置项, 改成说明「内置表已覆盖全部 69 条规则名,正常不用动这里」+ 如何覆盖某条内置译名。
兼容性
- 与 1.1.0 相比只改了内置译名表与文案,注入规则、指引石链路、依赖声明均未动。
- 依赖仍为
xtavim-BetterMap-1.0.4。
[1.1.0] — 适配 BetterMap 1.0.4;补上腐疫矿区 / 腐朽之穴
背景:上游 BetterMap 在 1.0.4(2026-09-19 发布)里自己修好了「Boss 指引石不落钉」, 并补上了「冰霜洞穴」。本版据此重新核对了两边,把补丁收缩到上游仍然缺的那部分。
变更
-
依赖版本升到
xtavim-BetterMap-1.0.4。补丁同时兼容 1.0.2 / 1.0.3 / 1.0.4, 但依赖里写 1.0.2 会让 r2modman 把你已经升上去的 BetterMap 要求降回 1.0.2。 -
上游 1.0.4 的改动(逐条核对结果),规则表 diff 只有三处:
变化 细节 指引石机制 7 条 Vegvisirs规则由Prefabs=[Vegvisir_*](这条路天生走不通,指引石是 Location 预制体的子物体、没有自己的 ZDO)改为新字段Component=typeof(Vegvisir);新增AutoPins.Spawned(LocationProxy)/Inside(...),挂在 Location 生成事件上扫内部组件 —— 比本补丁「按 Exploration Radius 扫玩家附近」更彻底。冰霜洞穴 新增 Frost Caves(MountainCave02/ Mountain / Dungeon / 默认开),与本补丁 1.0.0 起注入的那条逐项同构。其他 Obsidian Deposits默认值 开 → 关。 -
上游仍然缺的(本次补上):
Infested Mines(迷雾之地 /Mistlands_DvergrTownEntrance1、Entrance2)—— 默认开。 官方简中译名「腐疫矿区」(location_dvergrtown= Infested Mine)。 ⚠️ 上游有一条Dvergr Town看着像它,实际是CharredTowerRuins1_dvergr+Biome=AshLands, 落钉要过群系过滤 ⇒ 永远命中不了迷雾之地的入口。Morgen Holes(灰烬之地 /MorgenHole1、2、3)—— 默认开,简中「腐朽之穴」。Hildir Fortress(平原 /Hildir_plainsfortress)—— 默认关,与另两个希尔迪地牢一致。
-
迷雾之地 Vegvisirs 改为「上游优先」:检测到
Rule.Component字段存在(1.0.4+)时, 本补丁也照上游的写法把这条规则填成Component=typeof(Vegvisir),交给它自己的新机制。 本补丁自己的扫描器保留作兜底:上游先落钉并写进PinRecord,本补丁随后被去重挡住, 不会产生重复图钉;万一上游没有接管这条规则,女王指引石仍然标得出来。 -
中文映射表新增
Infested Mines=腐疫矿区、Morgen Holes=腐朽之穴、Hildir Fortress=希尔迪平原要塞(共 36 条)。 -
修复:升级后新增的内置译名对老用户不生效(补上三条译名之后立刻验收发现)。 症状:腐疫矿区图钉能标出来了、但名字还是英文
Infested Mines。 根因:BepInEx 的ConfigEntry在 cfg 文件里已存在某个键时,不会用新的默认值覆盖文件里的旧值 —— cfg 里早就写着 1.0.3 那张 33 条的Name Map,所以 1.1.0 新增的三条根本没进内存 (日志里中文名映射已载入 33 条就是证据)。 修法:新增[4 - Labels] Merge Default Map(默认开)—— 内置默认表先铺一层,再用你的Name Map覆盖(你的条目优先),以后再加内置译名就不会重犯。- 想完全自己掌控映射表(只认你写的那张):关掉本项。
- 想删掉某条内置译名:在你的表里写
英文名=(值留空 = 显式删除)。 - 日志改为打出「内置 N 条 ∪ 用户表(覆盖 X / 用户新增 Y / 显式删除 Z)→ 生效 K 条」, 这类"静默不生效"的问题看数字比读代码快得多。
- 离线核验:
verify_merge_default_map.py7 组用例全通过(含"拿你当前 cfg 预演 → 36 条、旧 33 条全保留")。
-
新增交付前核验脚本(开发者侧)
verify_bettermapfix.py:机器核对 ① 映射表英文键能否命中上游字符串堆或本补丁注入的规则名(键名打错只会静默不生效); ② 注入的地点 prefab 是否真在游戏地点表里、群系是否一致、是否enable=True; ③ 规则名(会成为上游 cfg 的键)是否含 BepInEx 禁用字符; ④ 脚本内清单与实际 DLL 是否一致(防清单漂移)。 本版跑分:映射表 36/36 命中;9 个地点 prefab 全部存在且群系一致; 唯一 WARN 是已知的HalfBurried_ForestCrypt(m_enable=False,默认关)。
兼容性
- 逐项核对过上游两次改动:
Plugin.BindPinRules/AutoPins.Sweep|Build|Place(Rule, ZNetView, Vector3)/PinRecord.Has/PinNames.For(Rule, GameObject)/Rule原有 9 个字段 + 无参构造 —— 1.0.2 → 1.0.4 全部保留、签名未变,只多了一个Component。 所以接口自检在两种版本上都会通过,功能按版本自动选择通道。
[1.0.3]
仅文档 —— DLL 一字未改
- README 顶部新增中英双语「适用性声明 / Applicability Notice」:本补丁是在本机 (BepInEx 5.4.2350 / 游戏 1.0.15 / 30 个启用模组)那套环境下做出来的,下面描述的症状 有可能是我这套模组组合互相冲突造成的,并不一定是原模组本身的 bug,可能不适用于他人的环境; 如遇问题请先向原模组作者反馈。
manifest.json:description末尾加一句Read the applicability notice first., 并压缩原有措辞以适配 Thunderstore 的 256 字符上限(实测值)。- 补丁本体未重新编译:
BetterMapFix.dll29184 字节, sha256c51accfbd6b9dbec0b904cd1459283ba508c6b707c15efe9ca520025614595e1—— 与 1.0.2 完全一致,已装 1.0.2 的不需要换文件。
[1.0.2]
新增:图钉名字中文化
- 打开
[4 - Labels] Chinese Labels(默认开)后,地图上图钉的名字会显示中文 (洞穴、要塞、祭坛那类地点图钉)。做法是给原模组算图钉名的PinNames.For(Rule, GameObject)做一个精确整串替换 —— 不动rule.Name(那是它 cfg 的键名)、不动规则表、图标与去重记录。 Name Map(默认 33 条,英文=中文逗号分隔)可自行增删;键名照抄 BetterMap cfg 里的键即可, 想连资源图钉也中文就往后面加(配置注释里给了现成一串)。Rename Existing Pins(默认开):已经放在地图上的旧图钉也一并改名。 名字是落钉那一刻写进地图数据的,所以单独跑一趟低频重命名(2 秒一次), 只动名字精确命中映射表的图钉,直接改显示文本、不重建 UI 元素。- 交付前校验脚本新增「映射表英文键必须存在于 BetterMap.dll」检查(33/33 通过)—— 键名打错一个字母只会静默不生效,必须机器核。
修正
Half Burried Crypt默认值改为关:实测游戏地点表里HalfBurried_ForestCrypt的m_enable = False,原版永远不会放置它,这条规则放着也不会落钉。
[1.0.1]
修复(重要 —— 1.0.0 会让 BetterMap 的自动标记整体停摆)
- 规则名里的撇号踩了 BepInEx 的 cfg 键字符限制。
Hildir's Cave/Hildir's Crypt里的'属于 BepInEx 禁用字符 (ConfigDefinition.CheckInvalidConfigChars:= \n \t \ " ' [ ]), 原模组把rule.Name直接当 cfg 键用 ⇒Config.Bind抛ArgumentException。 又因为 Harmony 的 prefix 抛异常会让原方法整体不执行,AutoPins.Build每轮都在开头炸掉, 连带 BetterMap 自己的资源标记全部失效(日志里每 10 秒一条ArgumentException)。- 规则改名为
Hildir Cave/Hildir Crypt(去掉撇号)。 - 新增注入前名字校验:含禁用字符的规则直接跳过并报错,绝不让它进原模组的规则表。
- 规则改名为
- 补上异常熔断:两条 prefix 全程
try/catch,逐条BindRule也各自try/catch—— 以后任何意外都只记一条日志,绝不会再波及原模组的Build。
说明
- 因为 BepInEx 的补丁是内存里的,1.0.0 造成的停摆需要重启游戏才会随 1.0.1 一起恢复。
[1.0.0]
首个版本,针对 BetterMap 1.0.2。
修复
-
Boss 指引石从不被标记。根因:BetterMap 的自动标记只遍历
ZNetScene.m_instances(只有网络对象 ZDO),而指引石是 Location 预制体的子物体、没有 ZDO,也不在 ZNetScene 的名字表里(GetPrefab返回 null ⇒IsPrefabZDOValid永远不过)。7 种 Boss 指引石全是这个下场。 做法:挂在 BetterMap 自己的AutoPins.Sweep之后补扫玩家附近的Vegvisir组件, 再调用它自己的AutoPins.Place(rule, null, pos)落钉 —— 类别 / 图标 / 标签 / 去重记账 全部沿用原模组,连"删掉就不再出现"都一致。 -
洞穴条目不全。原模组只在黑森林补了墓穴 / 巨魔洞 / 熊洞,山脉段没有洞穴条目。 做法:在
Plugin.BindPinRules之前往PinRules.All注入规则,剩下的交给原模组 (建 cfg 开关、进图例、进_byLocation地点表、去重)。
新增
- 规则
Frost Caves(MountainCave02,山脉)—— 冰霜洞穴入口。 - 规则
Half Burried Crypt(HalfBurried_ForestCrypt,黑森林)。 - 规则
Hildir's Cave(Hildir_cave,山脉)、Hildir's Crypt(Hildir_crypt,黑森林)—— 默认关。 - 规则
Vegvisirs(Vegvisir_SeekerQueen,迷雾之地)—— 原模组每段都有 Vegvisirs,唯独这段没有。 - 调试项:
Dump Location Names(整表打印游戏地点名,用于核对)、Verbose Pin Log(逐钉日志)。