数据包开发总览
文件路径
data/<namespace>/mxt/<registry>/<path>.json例如 data/example/mxt/ability/fireball.json 的定义 ID 是 example:fireball。
内容一多,请按类别把 JSON 分进子文件夹。 一个注册表目录下平铺几十上百个文件时,「哪几个是同一套流派的被动」只能靠文件名猜;分好类之后路径本身就是索引:
data/example/mxt/ability/sword/slash.json → example:sword/slash
data/example/mxt/ability/sword/parry.json
data/example/mxt/ability/passive/body_tempering.json
data/example/mxt/artifact/sword/azure_flight_sword.json
data/example/mxt/artifact/charm/ward_jade_talisman.json分类方式没有硬性规定,按用途(passive/、active/)、按流派(sword/、alchemy/)或按一次更新的批次都行。几条要注意:
- 目录就是 ID 的一部分:
data/example/mxt/ability/sword/slash.json的 ID 是example:sword/slash,换目录等于换 ID。别的定义、标签、存档(技能授予账本、冷却、轮盘格子的 id)存的全是这个 ID,所以分类要在写内容之前定好。 - 按 id 生成的
name/description键也带这段路径(<类别>.mxt.<命名空间>.<路径>,路径里的/原样保留),分文件夹不会多出第二套翻译键规则。 - 标签有自己的一棵树(
tags/mxt/<注册表名>/...),不必与定义目录逐层对应;按同一个分类习惯摆只是为了好找。标签里的值要写带目录的完整 ID。 - 层级只影响可读性,不参与加载与校验:
data/<命名空间>/mxt/下面第一层永远是注册表名(ability/、artifact/……),分类只能加在它下面;把所有文件塞进同一个注册表目录也照样能跑。
数据包加载使用 NeoForge 原生可写注册表,服务器加载后同步到客户端。定义读出来就是只读的,不要在运行时改动从定义里取到的集合。
共同的规则在数据包约定:怎么写引用、标签怎么用、名字与描述从哪来、写错的字段会怎样、数值怎么写。
注册表索引
| 分类 | 注册表 |
|---|---|
| 资源与修炼 | resource、aura、element、element_reaction、realm_stage、spirit_root、physique、technique、progression、cultivation |
| 技能与规则 | ability、curse、formation、tribulation、trigger、talisman |
| 灵气与世界 | aura_zone、secret_realm、block_aura |
| 物品与品质 | pill、pill_binding、technique_binding、artifact、quality、item_aura、currency、default_quality、item_binding、weapon_binding、tool_binding、blueprint_binding |
| 炼丹与灵植 | medicinal_property、spirit_herb、alchemy_furnace、alchemy_wall_material、heat_source |
| 经济与内容 | forging_method、forging_blueprint、creature_profile、contract_type |
七张物品键的注册表(item_aura、currency、default_quality、item_binding、weapon_binding、tool_binding、blueprint_binding)里,currency 用 item 认领物品、其余六张用 items,两张方块键的(block_aura、heat_source)按 blocks 认领方块;文件、字段形状与加载规则与其余注册表完全一致,见 JSON 数据格式。
丹方不是注册表:它是原版配方类型 mxt:alchemy,文件放在 data/<命名空间>/recipe/ 下,字段见炼丹配方。
模块页面
加载与覆盖
40 个数据包注册表使用 NeoForge 原版数据包注册表加载;世界加载时读取并校验,并在客户端加入时通过原版同步机制提供只读快照。从磁盘上的文件到玩家看到的结果就是下面这条路径。
- 文件冲突遵循 Minecraft 数据包优先级:高优先级数据包覆盖低优先级数据包的同一路径。
- 原版标签使用
replace: false时,值按数据包合并顺序追加;除品质排序标签外,玩法不依赖标签值顺序。
名字与描述的翻译键、neoforge:conditions、写错字段会怎样,都在数据包约定。
把这个规则展开成一句可操作的判断:同一个 id 的新旧两份定义不会同时存在,高优先级包的那一份整份取代低优先级包的那一份,不会合并字段。
加载、同步与调试
- 这些注册表属于原版数据包注册表,在世界加载时读取:JSON 解析、条目解析和字段校验都在世界加载过程中完成,
neoforge:conditions也在这一步判掉,条件不成立的条目连解码都不会进。/reload不会重新读取它们——/reload只刷新配方、战利品表、进度、函数这些原版监听器,以及 KubeJS 的服务端脚本。改完要重新加载世界(单机退回标题界面再进入,或重启服务器)。 - 动态注册表由原版同步机制在客户端加入时发送;客户端 HUD、雾效和贴图只负责展示,不决定扣除、突破、锻造或兑换结果。
/mxt aura query查询当前位置最终灵气;/mxt aura vein查询灵石矿脉信息。/mxt registries list列出这些动态注册表与各自的条目数量;/mxt registries validate报出上一次构建发现的所有问题,并逐条指出问题来自哪个文件(修炼、技能与功法的引用链条,以及忘了写行为的触发器规则)——没有问题时报出注册表数量、条目总数与「校验通过」。世界加载完之后跑一次这条命令,可以确认数据包产出的注册表状态是能用的。/mxt technique repair清理玩家数据里已失效的功法引用(引用的定义已被数据包删除、或被neoforge:conditions挡掉时使用);dry-run只报告不改动;/mxt technique drop <id>精确移除某一门功法。见下节。/picker [<分类 id>]打开物品选择器,直接查看这些定义认领的物品或方块:分类就是注册表 id(如/picker mxt:aura、/picker mxt:artifact、/picker mxt:currency、/picker mxt:item_binding、/picker mxt:block_aura),不写则列出全部已注册分类。物品键的注册表列它认领的物品,mxt:block_aura与mxt:heat_source列它们认领的方块。命令由内置的 Picker 模组提供,需要 gamemaster 权限,且只在创造模式下可用。- 测试模组数据位于
src/test-mod/resources/data/mxt_test/mxt,启动测试服务端可验证数据包闭环。
修复失效的功法引用
玩家已学会的功法以引用形式存在玩家数据里。当数据包删掉某个 technique、或用 neoforge:conditions 把它挡在注册表之外后,存档里的引用就指向了一个不存在的定义。
这种情况不会摧毁数据。 玩家数据里的功法列表逐元素解码,跳过解码失败的条目并保留其余条目,同时打出一条 WARN 日志:
[WARN]: Ignoring invalid list element: Failed to get element <namespace>:<path>也就是说,失效引用只损失它自己:其他功法、其他字段都正常加载。看到这条 WARN 就说明确实存在失效引用;看不到就说明不存在,此时问题在别处,不要用修复命令去「治」它。
| 命令 | 作用 |
|---|---|
/mxt technique repair dry-run | 报告有多少条失效引用,不改动任何数据 |
/mxt technique repair | 清理失效引用与重复项,并重建其带来的属性、能力与等级 |
/mxt technique drop <id> | 按 id 精确移除一门功法(包括仍然有效的) |
清理后会把失效功法曾提供的属性、能力和资源上限一并收回——否则玩家会保留一门已经不在身上的功法给的加成。
WARNING
修复命令只处理引用失效(指向已经不存在的定义)和重复条目。功法面板空白、功法书无反应若没有伴随 Ignoring invalid list element 警告,则不是本节的问题,需要另找原因。
WARNING
定义解码是唯一的加载契约。本文中的默认值、字段范围和示例以当前源码为准;数据包写入未列出的字段不会自动生效,写入未知 type 会导致加载失败。