Navigator
[!INFO] Git Commit:
8c9087c| Updated: 2026-10-01
地图 API 库,modid navigator。为 JourneyMap / Xaero World Map / Xaero Minimap
(VoxelMap 部分支持)提供统一的图层(layer)抽象层,
让第三方模组只写一份代码就能在多个地图模组上显示数据。
身份
| 属性 | 实测值 |
|---|---|
| modid | navigator(全小写,Navigator.java:20) |
| modName | Navigator(:21) |
| 资源域 | navigator(与 modid 一致,无分裂) |
| Java 文件 | 73(5 251 行) |
| 注册内容 | 0 方块 / 物品 / 实体(纯 API + Mixin) |
| 配置项 | 5(2 个 general + 3 个 module 开关) |
| 硬依赖 | 仅 gtnhlib(dependencies = "required-after:gtnhlib;",:17) |
[!IMPORTANT] 定位:地图 API 库,不是导航 / 指南针 mod 仓库名「Navigator」有歧义,但源码
mcmod.info的 description 明写A map API providing integration for Journeymap & Xaeros maps,README.md首句也是Navigator is an api mod that allows for other mods to add integration for JourneyMap / Xaero World / Xaero Minimap / VoxelMap。全文无任何「指南针 / 罗盘 / 朝向指示」相关实现。 本 mod 自己不显示任何 UI —— 它提供的是 「数据源 → 图层管理器 → 渲染步骤」的框架, 由消费方模组(本仓的
impl/4 个类)实例化后才产生可见效果。
依赖关系
dependencies.gradle 里只有 3 条真实依赖 + 4 条 compileOnly:
| 依赖 | 作用域 | 说明 |
|---|---|---|
| GTNHLib | api |
唯一硬依赖;提供 @Config / ConfigurationManager / 事件总线 |
org.jetbrains:annotations |
compileOnlyApi |
@NotNull / @Nullable |
| NotEnoughItems | devOnlyNonPublishable |
仅开发期,不进产物 |
| journeymap-api-forge | compileOnly |
JourneyMap 官方 API 1.7.10-2.0.0 |
| journeymap 5.2.20 | compileOnlyApi(rfg.deobf) |
JourneyMap 5 本体进公开 API |
| xaeros-minimap / xaeros-world-map | compileOnly |
经 deobfCurse(...) |
| voxelmap | compileOnly |
经 deobfCurse(...) |
⚠️ 4 个地图模组全部 compileOnly ——
运行期都不需要安装,README.md 明写
Map mods remain optional at runtime。
SupportedMods 用 Loader.isModLoaded 探测。
⚠️ VoxelMap 有 API 类但没有 mixin:
api/voxelmap/VoxelMapWaypointManager.java(75 行)存在,
但 Mixins 的 6 个常量里没有 VoxelMap,
SupportedMods 也没有 VoxelMap 枚举值。
这与 README.md 的 VoxelMap (Limited support) 一致 ——
只保留路点管理,不接入图层/渲染框架。
⚠️ JourneyMap 5 的本体是 compileOnlyApi(rfg.deobf),
即 JM5 的类型泄漏进了本 mod 的公开 API。
而 README.md 明确说 JM5 专用 API 已废弃:
The JourneyMap-specific renderer and render-step APIs are deprecated because they support only JourneyMap 5。
gtnhlib 已登记未成文(前向引用)。 JourneyMap / Xaero World Map / Xaero Minimap / VoxelMap / NEI 均不在收录范围,故只以纯文本提及,不建分类、不加链接。
三个加载阶段
本 mod 同时扮演 coremod(early) 与 late mixin loader 两个角色:
| 角色 | 类 | mixin 配置 | 阶段 |
|---|---|---|---|
| coremod + early mixin | NavigatorCore | mixins.navigator.early.json |
EARLY |
| 常规 early mixin | 无独立加载器 | mixins.navigator.json |
EARLY |
| late mixin | NavigatorLateMixins | mixins.navigator.late.json |
LATE |
⚠️ 三个 mixin 配置的 package 各不相同:
| 配置 | package | minVersion |
|---|---|---|
mixins.navigator.early.json |
com.gtnewhorizons.navigator.mixins.early |
0.8.3-GTNH |
mixins.navigator.json |
com.gtnewhorizons.navigator.mixins |
0.8.3-GTNH |
mixins.navigator.late.json |
com.gtnewhorizons.navigator.mixins.late |
0.8.3-GTNH |
三份配置共用同一个 refmap mixins.navigator.refmap.json,
且 compatibilityLevel 都是 JAVA_8。
late 配置独有 injectors.maxShiftBy = 3。
⚠️ mixins.navigator.json 的 package 是 ...mixins,
而 TargetedMod 与
Mixins 也在这个包下 ——
枚举类本身不是 mixin(无 @Mixin 注解),
但配置会扫描该包。靠 MixinBuilder 的 addClientMixins 精确点名实际类,
所以不会误注册枚举。
16 个 mixin 的归属
见 Mixins:
| 阶段 | 常量 | 目标模组 | mixin 类数 |
|---|---|---|---|
| EARLY | TEXTURE_ATLAS_SPRITE_ACCESSOR |
无(无限制) | 1 |
| EARLY | ENABLE_STENCIL |
XaeroMiniMap 且 XaeroWorldMap | 1 |
| LATE | JOURNEYMAP_V5 |
JourneyMap | 7 |
| LATE | JOURNEYMAP_V6 |
JourneyMap | 2 |
| LATE | XAEROS_GUI |
XaeroWorldMap | 1 |
| LATE | XAEROS_MINIMAP_WAYPOINT |
XaeroMiniMap | 1 |
| LATE | XAEROS_MINIMAP_RENDERER |
XaeroMiniMap 且 XaeroWorldMap | 1 |
合计 14 个 @Mixin 类 + 2 个 @Accessor 接口
(TextureAtlasSpriteAccessor、DisplayVarsAccessor、
FullscreenAccessor —— 实际 3 个 accessor)= 16 个类。
⚠️ ENABLE_STENCIL 用 addRequiredMod 同时要求 XaeroMiniMap 与 XaeroWorldMap
(两个 addRequiredMod 调用,:17-18),
所以只装其中一个时模板缓冲不会被强制开启。
这是有意的(stencil 主要给 world map 用),但对只装 minimap 的用户无效。
配置项(5 项)
两个 GTNHLib @Config 类:
GeneralConfig(无 category,2 项)
| 字段 | 类型 | 默认值 |
|---|---|---|
enableDebugLayers |
boolean | false |
rememberSearchText |
boolean | true |
ModuleConfig(category = modules,3 项)
| 字段 | 类型 | 默认值 |
|---|---|---|
enableJourneyMapModule |
boolean | true |
enableXaeroWorldMapModule |
boolean | true |
enableXaeroMinimapModule |
boolean | true |
⚠️ enableDebugLayers 默认 false,而
ClientProxy(:22-24)只在它为真时注册
DirtyChunkLayerManager ——
即本仓自带的唯一可见图层默认关闭。
⚠️ 3 个 module 开关全默认 true,
但 SupportedMods 会再与
「是否真的装了该模组」取逻辑与 ——
所以装了就自动生效,没装则枚举值为 false。
键位(1 个)
public static final KeyBinding ACTION_KEY = new KeyBinding(
"navigator.key.action", Keyboard.KEY_DELETE, Navigator.MODNAME); // NavigatorApi.java:34-37
| 属性 | 值 |
|---|---|
| 本地化 key | navigator.key.action |
| 默认键 | DELETE(Keyboard.KEY_DELETE) |
| 分类 | Navigator(MODNAME,不是 modid) |
⚠️ 键位分类用 Navigator.MODNAME("Navigator",首字母大写),
而 modid 是 navigator(全小写)——键位列表里显示为
Navigator > navigator.key.action。
⚠️ 默认占用 DELETE 键(与 TiC Tooltips 的「出厂未绑定」相反),
会与 BiomeMerger 之类的删除类键位冲突。
分层架构
ILocationProvider ← 数据源(消费方实现)
↓
LayerManager ← 图层管理器(缓存 + 生命周期 + 视口)
↓
LayerRenderer ← 按地图模组分发的渲染器
↓
RenderStep / InteractableStep ← 实际绘制/交互
| 层 | 抽象 | 地图中立实现 |
|---|---|---|
| 按钮 | ButtonManager | — |
| 图层 | LayerManager(623 行,全 mod 最大) | — |
| 渲染器 | LayerRenderer | UniversalLayerRenderer |
| 渲染步骤 | RenderStep | UniversalRenderStep(280 行) |
| 交互步骤 | InteractableStep | UniversalInteractableStep / UniversalLocationInteractableStep |
| 标记 | MapMarker(320 行) | — |
| 路点 | Waypoint / WaypointManager | — |
地图中立(map-neutral)是官方推荐路径;
JourneyMap 专用与 Xaero 专用渲染器作为备选:
api/journeymap/render/(2 个)、api/xaero/renderers/(2 个)。
源码缺陷
-
ModConfig三个开关的求值时机在类初始化 —— SupportedMods 的构造参数Util.isJourneyMapInstalled() && ModuleConfig.enableJourneyMapModule在枚举常量初始化时求值,即SupportedMods类首次被加载的那一刻。 若该时刻早于 GTNHLibConfigurationManager读盘(见缺陷 2), 三个开关全是 Java 默认值false→ 枚举全部false, 且final字段无法在配置加载后刷新(需重启游戏才生效)。 -
配置注册在 coremod 的 static 块里,早于 mod 加载 —— NavigatorCore(
:20-27)的static {}调ConfigurationManager.registerConfig(GeneralConfig.class)。 这是 GTNHLib 配置的推荐做法(早期读盘), 但与缺陷 1 叠加时,若SupportedMods被更早的类初始化, 就会读到未加载的配置。 -
ClientProxy.onClientConnect是static但注册在实例代理上 —— ClientProxy(:27-30)的方法是public static void+@SubscribeEvent, 而类本身带@EventBusSubscriber(side = Side.CLIENT)。@EventBusSubscriber扫描 static 方法,不需要实例, 所以new ClientProxy()(由@SidedProxy创建)实际上没有任何用途 —— 它的preInit覆写(:19-25)才是唯一有效逻辑。 这不是 bug,但是冗余的实例化。 -
@Mod注解缺acceptableRemoteVersions之外的服务端声明 ——acceptableRemoteVersions = "*"(:16)允许不带本 mod 的客户端连服务端。 但本 mod 纯客户端(ClientProxy才注册内容), 服务端装它没有任何作用(CommonProxy 三个方法全空)。不加限制是安全的。 -
NavigatorApi.registerLayerManager不去重 —— 源码注释明写This method does not deduplicate registrations(:45-46)。 同一LayerManager注册两次会在layerManagers里出现两次, 导致该图层被渲染两次(getActiveRenderersFor不去重, 见 NavigatorApi 的:61-67)。 API 契约靠调用方自觉。 -
VoxelMap 支持是死代码 ——
api/voxelmap/VoxelMapWaypointManager.java(75 行)无任何调用点 (VoxelMap 既不在 SupportedMods, 也不在 Mixins)。 见本分类页「依赖关系」的说明。 -
ENABLE_STENCIL的双模组要求 —— 只装 Xaero Minimap(不装 World Map)时, ForgeHooksClientMixin 不会应用, 模板缓冲不被强制开启。见本分类页「16 个 mixin 的归属」。
分类索引
核心与入口
- Navigator -
@Mod主类:3 个生命周期转发 + 唯一硬依赖声明 - NavigatorCore - coremod + early mixin loader;配置注册的 static 块
- NavigatorLateMixins - late mixin loader
- ClientProxy - 注册
ACTION_KEY+ 条件注册调试图层 - CommonProxy - 三个空钩子(纯客户端 mod)
- NavigatorApi - 公开 API 入口:图层注册、渲染器查询、排序
配置
- GeneralConfig - 2 项(调试图层 / 记住搜索文本)
- ModuleConfig - 3 项模块开关
模型层
- SupportedMods - 4 个枚举值,安装探测 + 配置开关的逻辑与
- LayerManager - 图层管理器基类(623 行,缓存 + 视口 + 生命周期)
- LayerRenderer - 渲染器接口(按地图模组分发)
- InteractableLayerManager - 可交互图层管理器
- InteractableLayer - 可交互图层绑定
- UniversalLayerRenderer - 地图中立渲染器
- UniversalInteractableRenderer - 地图中立可交互渲染器
- ButtonManager - 图层按钮:激活/停用切换
- ILocationProvider - 数据源接口(坐标 + 显示名)
- IWaypointAndLocationProvider - 兼具路点能力的数据源
- MapMarker - 地图标记模型(320 行)
- RenderStep - 渲染步骤接口(最简)
- InteractableStep - 交互步骤接口
- LocationInteractableStep - 坐标交互步骤
- UniversalRenderStep - 地图中立渲染步骤(280 行)
- UniversalInteractableStep - 双击切换路点
- UniversalLocationInteractableStep - 非路点交互
- Waypoint - 路点模型
- WaypointManager - 路点管理接口
工具
- Util - 模组安装探测(JourneyMap 5/6、Xaero ×2)
- DrawUtils - 绘制辅助(291 行)
- ClickPos - 点击位置记录
- LayerRefreshEvent - 图层刷新事件
内部实现
- FormattedTextField - 带格式的文本输入框(276 行)
- SearchBar - 搜索栏
- NEISearchFormatter - NEI 搜索串格式化
- JourneyMapIntegration - JM 集成门面
- JourneyMapV5Renderer - JM5 渲染器实现
- JourneyMapV5Fullscreen - JM5 全屏地图标记
- JourneyMapV6Plugin - JM6 插件(847 行,全 mod 最大)
- JourneyMapV6WaypointManager - JM6 路点管理
参考实现
- DirtyChunkLayerManager - 脏区块调试图层
- DirtyChunkButtonManager - 调试图层按钮
- DirtyChunkLocation - 脏区块数据源
- DirtyChunkRenderStep - 脏区块渲染步骤
JourneyMap 专用 API(已废弃)
- JourneyMapVersion - JM5/JM6 版本判定
- JMLayerRenderer - JM5 渲染器接口
- JMInteractableLayerRenderer - JM5 可交互渲染器
- JMRenderStep - JM5 渲染步骤
- JMInteractableStep - JM5 交互步骤
- JMWaypointManager - JM5 路点管理
Xaero 专用 API
- XaeroLayerRenderer - Xaero 渲染器接口
- XaeroInteractableLayerRenderer - Xaero 可交互渲染器
- XaeroRenderStep - Xaero 渲染步骤
- XaeroInteractableStep - Xaero 交互步骤
- SizedGuiTexturedButton - 可指定尺寸的按钮
- WaypointWithDimension - 带维度的 Xaero 路点
- XaeroWaypointManager - Xaero 路点管理
VoxelMap(部分支持)
- VoxelMapWaypointManager - VoxelMap 路点管理(无调用点)
Mixin
- Mixins - 6 个构建器常量,管辖 16 个 mixin 类
- TargetedMod - 3 个目标模组(GTNHLib Mixins 框架)
- TextureAtlasSpriteAccessor - EARLY:纹理图集 padding 状态
- ForgeHooksClientMixin - EARLY:强制开启模板缓冲
- DisplayVarsAccessor - LATE JM5:显示变量访问器
- FullscreenAccessor - LATE JM5:全屏地图访问器
- FullscreenMixin - LATE JM5:全屏地图注入(343 行)
- MiniMapMixin - LATE JM5:小地图注入
- RenderWaypointBeaconMixin - LATE JM5:路点光柱
- TextureCacheMixin - LATE JM5:纹理缓存
- WaypointManagerMixin - LATE JM5:路点管理器
- JourneyMapV6FullscreenMixin - LATE JM6:全屏地图
- MapChatMixin - LATE JM6:地图聊天
- MinimapRendererMixin - LATE:Xaero 小地图渲染器(130 行)
- WaypointsIngameRendererMixin - LATE:Xaero 游戏内路点
- GuiMapMixin - LATE:Xaero World Map GUI(332 行)
源码:/Users/evlos/a/mirror/Navigator/
API 文档:/Users/evlos/a/mirror/Navigator/docs/API.md
关系登记:见 data/relation.md(全局 Wiki 分类映射表)