跳到主要内容

生成型副本

生成型副本没有模板世界。你一次性构建若干小房间,描述它们如何连接,生成器就会为每次运行组装一个新的布局:从起始房间出发,经过普通房间、宝藏房间和隐藏房间,直到 Boss 房间。

固定型和生成型副本共用相同的运行、菜单、箱子、NPC、怪物、事件和事实(fact)。不同的只是房间的来源。

组成部分​

部分条目说明
门类型Dungeon Connector Type门洞的尺寸、封住未使用门的方块,以及哪些类型之间可以连接。
房间Dungeon Room Template保存下来的结构(以 artifact 形式保存的 Paper 结构 .nbt),带有分类、门和标记点。
房间池Dungeon Room Pool房间模板的加权列表。
生成器Dungeon Generator规则:使用哪些房间池、房间数量、Boss 的深度、路径分叉的频率。
词缀Dungeon Affix随机抽取的运行修饰,例如“快速怪物”。
副本Dungeon Instance它的 generator 字段使其成为生成型副本。

一步步构建​

  1. 门类型。 至少添加一个 Dungeon Connector Type。设置它的 width 和 height(默认 3 × 3)、封住未使用门的 sealBlock(默认 minecraft:stone_bricks),如果有多种类型,还要设置 compatibleWith。一种类型总是可以与自身连接。
  2. 房间。 为每个房间添加一个 Dungeon Room Template,并使用游戏内编辑器捕获它的方块,放置它的门和标记点。选择它的 category。
  3. 房间池。 为起始房间添加一个 Dungeon Room Pool,为 Boss 房间添加一个,为其他房间添加一个(或多个),还可以为走廊添加一个(可选)。起始、Boss 或走廊房间池只能包含该分类的模板。普通房间池可以混合 NORMAL、TREASURE 和 SECRET 模板。
  4. 生成器。 添加一个 Dungeon Generator,并设置 startPool、bossPool、可选的 corridorPool,以及各带一个权重的 normalPools。
  5. 副本。 在你的 Dungeon Instance 上设置 generator。templateWorld 留空:生成型副本没有模板世界。隔离模式必须是 AUTO 或 WORLD_PER_RUN。
  6. 游戏逻辑。 使用房间模板的 onEnter 和 onClear 触发器、TRIGGER 标记点、房间事件、位于 MOB 标记点上的 Dungeon Mob Spawn 条目,并用 Dungeon Complete 结束运行。

如果房间池和模板无法生成副本,启动会被拒绝,服务器日志会说明原因(例如房间池中没有任何起始房间,或模板没有可读取的捕获)。生成器的 messages 字段保存报告给你(作者)的原因。玩家只会看到取自 snippet content.dungeon_generated.refusal.setup(房间池和模板无法生成副本)和 content.dungeon_generated.refusal.paste(房间无法粘贴)的一小段文本,你可以在 Web 面板中编辑它们。不会因此收取任何东西。宣布某次运行词缀的那一行是 snippet content.dungeon_generated.affix.announcement。

房间分类​

房间模板的 category 表明它可以扮演的角色。

分类角色
START运行从这里开始。每个副本一个。必须包含一个 SPAWN 标记点。
NORMAL普通房间。
TREASURE总是在分支上,绝不在通往 Boss 的路径上。
CORRIDOR插入在两个无法直接相接的房间之间。
SECRET总是死胡同。
BOSS最后一个房间。每个副本一个。

房间门对门连接,所以没有门的房间只能是死胡同式的 START。开启了 required 的门必须与另一个房间连接:无法填满所有必需门的模板永远不会被使用。没有人通过的门,会用其类型的 sealBlock 封上。

标记点​

标记点是房间内的一个兴趣点。每个标记点都有一个 kind:

种类作用需要填写的字段
SPAWN运行开始时玩家出现的位置。只使用起始房间的第一个 SPAWN。无
CHEST这里会放置一个战利品箱。它的位置和偏航角(yaw)会替换条目的 location。由标记点指定的箱子总是会被放置,即使其条目处于 manualMode。chest:一个 Dungeon Loot Chest
TRIGGER为到达该房间的玩家触发这些触发器。triggers
NPC一个 Dungeon NPC Instance 站在这里,向该次运行的成员显示。npc
MOB当该次运行的某位成员第一次进入房间时,Dungeon Mob Spawn 的怪物会在这里出现。mob

标记点的 yaw 决定箱子(它朝向背对 yaw 的方向)和 NPC(它朝向 yaw 的方向)的朝向。标记点通过它在 markers 列表中的位置与其条目关联。

游戏中的房间​

当玩家进入生成型副本的某个房间时,先触发其模板的 onEnter 触发器,然后触发它的 TRIGGER 标记点的触发器和 MOB 标记点的怪物。开启 enterOnce(模板的默认值)时,它们只会在每位玩家于一次运行中第一次进入该房间时触发。

当玩家站在房间内,执行 Dungeon Clear Room 动作时,onClear 触发器每次运行触发一次。平台绝不会自行判定房间已被清空:这由你决定,例如在最后一只怪物死亡时通过怪物死亡事件。

房间的触发器可以从上下文中读取这些值(通过 interaction_context_variable):

键值
RUN_ID运行的 id。
SEED副本的种子,十进制。
ROOM房间编号:0 是起始房间,之后按生成器放置的顺序排列。
ROOM_TEMPLATE房间模板条目的 id。
DIFFICULTY生成器的 difficulty。
POSITION对于 TRIGGER 标记点,是该标记点的方块;否则是玩家的位置。

词缀的触发器只能读取 RUN_ID、SEED 和 DIFFICULTY。固定型副本不提供其中任何一个键。

种子、词缀与难度​

相同的种子总是生成相同的副本,因此布局可以重放。每次运行都会抽取一个新的种子。种子会随运行一起保存,因此重载会在内存中重建相同的副本。如果无法重建,该运行会在启动时被关闭,而不是带着没人认得的房间被接管。

词缀在布局之后抽取:从生成器的 affixes 中按 weight 抽取 affixCount 个,不重复。抽取遵循种子,但绝不会改变布局。它们的修饰器和触发器会在运行开始时应用于每位成员。

difficulty 只是一个通过上下文交给你的触发器的数字:它本身不会改变布局。

重要的生成器设置​

字段默认值说明
minRooms, maxRooms6, 10房间总数,包括起始和 Boss,不含走廊。允许范围:2 到 256。
minBossDepth3Boss 距离起点至少这么多步。
branchRatePercent40主路径之外的房间开出支路的概率,以百分比计。
quotas无对 NORMAL、TREASURE 和 SECRET 房间数量的上下限。没有设置界限的分类不受限制。
trialBudget, replans20000, 5搜索在失败前会尝试多久。试验预算乘以 (replans + 1) 必须保持在 5 000 000 以内。
baseY64起始房间地板在运行世界中的高度。
roomsPerTick4每个服务器 tick 粘贴的房间数。调低可使 tick 保持较短;调高则更快。
pasteTimeoutSeconds120超过这个时间后,启动会被取消,费用被退还,世界被丢弃。
naturalSpawningoff怪物和动物会在运行世界中自行生成。默认关闭。
verticalMargin1.0判断玩家是否在内部时,在每个房间的天花板之上和地板之下增加的方块数。
pasterSTRUCTURE使用 Paper 结构 API:不需要其他插件。

一个房间模板每边最多 256 格,最多 64 扇门和 1024 个标记点。

游戏内编辑器​

在 Web 面板中打开一个 Dungeon Room Template,点击 artifactId 字段的内容编辑器。你的快捷栏中会得到一组工具:

工具用途
角点魔杖左键点击一个方块设为角点 A,右键点击一个方块设为角点 B。
捕获把盒子内的方块保存为模板的结构。
门工具右键点击墙上的一个方块以添加一扇门(该方块是门洞底部的中心)。左键点击则移除那里的门。
门类型右键切换到下一个连接器类型,左键切换到上一个。
必需开关切换接下来放置的门是否为必需。
标记点工具右键点击一个方块,在其前方添加一个标记点。左键点击则移除那里的标记点。
标记点种类右键切换到下一个种类,左键切换到上一个。
保存把门和标记点写入条目。

Boss 血条会显示盒子的大小、门和标记点的数量,以及你是否有未保存的工作。房间的大小是从保存的结构中读取的,而不是手动输入的。添加门之前,你必须至少创建并发布一个连接器类型。

捕获默认会跳过实体,因为活体实体会在每次捕获时改变房间,并且会在每个副本中作为游离的怪物回来。这些行为以及编辑器的所有文本,都是 content.dungeon_room_template. 之下的 Typewriter snippet,因此你可以在 Web 面板中修改或翻译它们:

Snippet默认值含义
capture.include_entitiesfalse捕获时是否保存盒子内的实体。
capture.max_volume262144一次捕获最多读取的方块数。它在一个服务器 tick 内读取:非常大的盒子会占住那个 tick。
capture.timeout_seconds30放弃前等待捕获的秒数。
sound.confirmentity.experience_orb.pickup捕获或保存之后播放的声音。留空:不播放。

限制与良好实践​

  • 生成型副本只使用 WORLD_PER_RUN:每次运行创建一个世界,之后将其删除。
  • 固定房间(节点)的编辑器在 content.dungeon_room. 之下有自己的 snippet(消息 node.*、save.*、editor.*,工具 tool.add、tool.remove、tool.save)。
  • 构建房间时,要让两扇相连的同类型门对齐。偶数的门洞宽度,其多出的一格方块位于模板的 x 或 z 较大的一侧。当偶数门洞需要时,生成器会把房间平移一格。
  • 整个副本必须从 baseY 起算,容纳在世界的最低方块与最高方块之间。
  • 不要依赖固定的房间数量:请使用标记点和事件,而不是房间编号。