跳到主要内容

定义秘境

秘境是"一次性或可认领的小世界":定义只是一份模板,每一份实例都是一个真正的、独立的运行时维度。玩家进去、出来、再进去看到的是同一份地形——只要它还被认领。

先分清两个命令

/realm 只管线性境界链(/realm set <境界>、/realm chain <境界>);秘境实例的运维全在 /mxt secret_realm …。本篇讲的是后者。

你要搭建什么​

文件用途
data/example/mxt/secret_realm/trial_realm.json一份秘境模板:生成方式、边界、落点、寿命。

第 1 步 —— 世界模板​

// data/example/mxt/secret_realm/trial_realm.json
{
"generation": {
"type": "mxt:flat",
"preset": "1*minecraft:bedrock,2*minecraft:dirt,minecraft:grass_block;minecraft:plains"
}
}

generation 是唯一必填的字段,type 决定其余参数:五种生成方式与各自的字段见秘境生成方式。教程用 mxt:flat——预设串里 ; 之后是群系,最省事;mxt:void 没有地层,落点会掉进虚空,要用就得自己放结构托住。

秘境的维度 id 由定义与序号生成:<定义的命名空间>:secret_realm/<定义的路径>/<序号>,序号从 0 开始——所以同一份模板可以开出很多份互不干扰的世界。

第 2 步 —— 划定边界​

"border": {
"center": [0, 0],
"size": 256,
"warning_blocks": 5,
"warning_time": 15,
"damage_per_block": 0.4,
"safe_zone": 3.0
}
字段默认说明
center[0.0, 0.0]边框中心,写法是 [x, z](只有两个数)。
size29999984.0直径,必须正有限。
warning_blocks / warning_time5 / 15距离边界多少格开始警告、警告持续多少秒。
damage_per_block / safe_zone0.2 / 5.0越过安全区后每格掉多少血。

写入的就是原版世界边界,所以越界的观感、提示与伤害都是原版那一套,模组不额外加逻辑。没写 border 也会被显式设成原版默认值——这是刻意的,免得新维度继承主世界被缩小过的边框。

第 3 步 —— 落点​

不写 entry 时落点是随机的(半径默认取边框直径的 40%,圆心取边框中心,y 取地表)。想控制落点就写一个列表:

"entry": [
{
"pos": [0, 80, 0],
"yaw": 0, "pitch": 0,
"enter_condition": {"type": "mxt:always"},
"enter_denied_message": {"text": "你还没有资格踏入此地"}
},
{
"random_center": [64, 64], "random_radius": 12, "spread": 4.0, "weight": 3,
"enter_action": {"type": "mxt:play_sound", "sound": "minecraft:block.beacon.activate"}
}
]
字段默认说明
pos无精确落点;写了就用它,y 不会被改写。
yaw / pitch进入者自身角度进入时的朝向。
random_center / random_radius边框中心 / 边框 size × 0.4没有 pos 时在这个圆里随机,y 在结构放完之后取地表。
spread3.0同批多人进入时的散开半径(取所有落点里最大的那个)。
weight1多个落点之间的相对权重。
enter_condition / exit_condition恒真进/出这一次的门槛;exit_condition 只约束主动离开。
enter_denied_message / exit_denied_message无(显示失败码)被门槛拦下时给玩家看的话。
enter_action / exit_actionmxt:no_op落位之后 / 传回之前执行。

第一个进去的人落在锚点上(被选中的那个落点会持久化);之后的人按六边形散开,免得一队人叠在一起。

第 4 步 —— 进入权限、认领与时限​

字段默认说明
ownedfalse为真时第一个进入者成为主人,实例从此保留地形、只卸载不删除;为假时最后一人离开就删掉整份实例与地形。
max_instances1(1..256)这份定义所有实例合计的上限(休眠的认领实例也算),满了报 NO_FREE_INSTANCE。
max_members不限每一份实例能同时容纳多少人。
duration_ticks0(不过期)实例存活时长;到期把在线成员送出去并收尾。

认领式与一次性的区别值得写清楚:

  • owned: true:主人离线、所有人都离开,世界也只是休眠——地形、方块、里面的建筑与库存都在,下次有人进来用同一个种子重新打开。它跨服务器重启保留,但重启后成员表会清空(/mxt secret_realm list 里那条 loaded=false 就是它)。
  • owned: false:最后一人离开即删除整份实例目录(含该维度的灵气区域与阵法数据)。适合"打一趟就散"的试炼场。

时限只在主世界时钟上扫描(每 20 tick 一次),到期对所有在线成员执行离开——不看 exit_condition;离线成员直接从成员表剔除。认领实例到期只是暂停计时并卸载,下次有人进来重新开始算。

第 5 步 —— 放入结构(可选)​

"structures": [
{
"nbt": "example:trial_platform",
"pos": [0, 64, 0],
"rotation": "clockwise_90",
"integrity": 1.0,
"chance": 1.0,
"relative_to_entry": false,
"ignore_entities": false,
"keep_liquids": true
}
]

结构文件是原版结构:data/<命名空间>/structure/<路径>.nbt。pos 是结构原点;rotation / mirror 决定朝向;integrity 是完整度(0..1);chance 每份实例掷一次;relative_to_entry 让坐标以落点为基准。写了 border 时,绝对坐标的结构必须落在框内(只检查 x/z),否则整份定义加载失败。

结构缺失不会在加载期报错,而是在进入时返回 MISSING_STRUCTURE——所以改完结构记得真的进去一次。

第 6 步 —— 秘境里的灵气、阵法与裂隙​

  • 灵气:实例维度是运行时维度,没有自己的 LevelStem 条目,所以 aura_zone.dimensions 除了直接写实例维度 id,还可以写定义 id 或所用的 stem id,一次命中这份模板开出的所有实例。
  • 群系绑定的灵气区域不会自动命中:mxt:void 的群系是 minecraft:the_void,所以按 #minecraft:is_overworld 绑定的区域进不来。任何区域都没命中时落到空域——秘境默认是没有灵气的,想要灵气就得显式绑一份。
  • 阵法与灵气库存存在该维度自己的 data/ 里,所以 owned: false 的实例被删时它们一起消失。
  • 裂隙可指定秘境定义或实例内坐标,遵守同一套进出条件、成员与人数上限。秘境令牌召入口门,进入秘境后可召返回门;布局出口写在定义的 portals 数组中。

在游戏里验证​

/mxt registries validate
/mxt secret_realm enter example:trial_realm
/mxt secret_realm list
/mxt secret_realm info example:secret_realm/trial_realm/0
/mxt secret_realm exit
/mxt secret_realm destroy example:secret_realm/trial_realm/0
  1. 重新打开世界(注册表只在世界加载时读取,/reload 不会重读),/mxt registries validate 应无 Codec 错误。
  2. enter 成功时提示"已进入秘境",失败时是"无法进入秘境:"后面跟着失败码。
  3. list 每行包含维度键、序号、定义、成员数、上限、主人、是否备好、是否加载——loaded=false 就是休眠的认领实例。
  4. 走一圈再 exit,然后用 /mxt secret_realm info <维度> 看它的状态;对 owned: true 的实例再进一次,应该回到同一份地形。
  5. destroy 会真的删掉地形(认领过的也删),所以删定义之前先 destroy,否则实例记录读不出来、地形会被当作遗留数据清掉。

常见错误​

现象原因
进不去,报 NO_FREE_INSTANCEmax_instances 满了(含休眠的认领实例);先 destroy 掉不用的,或把它调大。
进不去,报 MISSING_STRUCTUREstructures[].nbt 指向的结构文件不存在或路径不对。
进不去,报 CONDITION_NOT_MET选中的落点 enter_condition 不成立;写了 enter_denied_message 就会显示那句话。
进不去,报 DISABLED那个 id 不在当前注册表里(含被 neoforge:conditions 挡掉的定义)。
进不去,报 ALREADY_TRAVELLING这个玩家已经处在一次进出流程里。
一进去就往下掉用了 mxt:void 又没放结构:空列的地表高度就是世界底部。
地形没了实例是 owned: false,最后一人离开即删除;要保留就写 true。
重启后认领的秘境 loaded=false,人也回不去了这是休眠,不是丢失:下一个人进入会按同一个种子重新打开;重启后成员表会清空,被"遗留"的玩家会在登录时送回进入前的位置。
离线的人还占着名额成员表是权威的,离线成员仍算在场(也让实例不进入休眠)。
改完定义进不去 / 世界加载不了秘境定义是注册表条目,解码失败会让世界加载不了;读日志最后一条 Codec 错误。
结构没放出来chance 小于 1 时每份实例掷一次骰子;integrity 小于 1 会随机缺块。

接下来​