什么是模块化地牢?
模块化地牢是 BetterStructures 2.0.0 及后续版本的地牢系统。它将手工建造的小型模块动态组装起来,而不是直接生成一个固定的原理图。模块可以组成多层地牢,每次生成都有不同的布局。
模块化地牢的生成方式
-
模块 模块尺寸可以配置,常见尺寸为 16×16×16 方块,有些内容包使用 32×16×32 或其他尺寸。通过边界标签和统一的连接位置,让模块拼接时没有间隙或重叠。生成器用
moduleSizeXZ和moduleSizeY定义尺寸。模块可以包含走廊、房间、楼梯和特殊战斗区域。 -
生成过程 在新区块生成时,BetterStructures 使用波函数坍缩(WFC)算法,根据边界标签随机选择兼容模块并组装地牢。耗时取决于半径、垂直范围、模块池、约束和服务器性能。布局计算异步运行;排队的粘贴操作共享每个服务器 tick 配置的时间预算。大型或不兼容的布局仍可能消耗大量资源或无法完成组装。
-
地牢大小 增大半径可以生成跨越数百方块的地牢。多数地牢有多个楼层,通过楼梯或竖井连接。上下连接使用
borders中的up和down,相对两面的标签必须匹配。
内容包与组合
内容目录包含 Dungeoneering Modules Free 和 Dungeoneering Modules Premium。随附的 dungeoneering 生成器列出了两个包的起始原理图。目录中还包含 Tommyknockers Modules Free 和 Tommyknockers Modules Premium,这是一座由 EliteMobs Boss 把守的模块化矿井;Premium 需要 Free 包。请安装内容包指定的模块和依赖,包括所需的 FreeMinecraftModels 内容。添加兼容模块会增加布局选择;单独安装原理图不会安装配套模型或怪物内容。
实体和容器标记
模块生成读取告示牌正面文字,并丢弃空行。在第一行写小写标记,参数紧接在下方。标记匹配区分大小写,[elitemobs] 除外。模块粘贴会移除所有告示牌方块,包括装饰告示牌和不支持的标记。
| 告示牌标签 | 附加行 | 行为 |
|---|---|---|
[spawn] | 第 2 行填写 Bukkit 实体类型 | 以告示牌所在方块为中心生成持久的原版实体。专用模块世界还会将此位置记录为供集成使用的出生标记。 |
[chest] | 无 | 放置箱子,并用模块生成器的 treasureFile 填充。 |
[trapped_chest] | 无 | 放置陷阱箱,并用模块生成器的 treasureFile 填充。 |
[pool: poolname] | 无 | 从 EliteMobs 生成池中选出一个 Boss,并以告示牌所在方块为中心生成它。在现有地形中,该 Boss 是一次性的 EliteMobs 区域 Boss。在专用模块世界中,普通 Boss 和实例 Boss 的处理方式见生成池一节。 |
[elitemobs] | 后续各行填写 EliteMobs Boss 文件名,各行直接拼接,不加分隔符 | 仅适用于粘贴到现有地形的模块(isWorldGeneration: false):以告示牌所在方块为中心生成一个一次性的 EliteMobs 区域 Boss。专用模块世界会忽略它。 |
[barrel] | 无 | 在专用世界记录木桶位置,由集成调用 spawnBarrels() 放置。标记本身不会放置或填充木桶。 |
[exit] | 第 2、3 行填写上、下组件名,不含 .schem | 在专用世界记录出口。集成必须放置 components/ 中的组件。任一参数行缺失时,两个名称均回退为 genericelevator_up 和 genericelevator_down。 |
[barrel] 和 [exit] 标记只在 isWorldGeneration: true 时处理。向现有地形粘贴地牢时使用 isWorldGeneration: false;[spawn]、[chest]、[trapped_chest]、[pool: poolname] 和 [elitemobs] 在此模式下可用。现有地形中的 Boss 告示牌需要启用 EliteMobs;否则 BetterStructures 会为每个地牢记录一条警告,且不生成任何 Boss。模块不会创建 WorldGuard 竞技场保护。普通战利品木桶应使用实际的木桶方块,并按下文配置战利品。
生成池
[pool: poolname] 告示牌读取 spawn_pools/ 下的配置文件。每个 YAML 文件支持以下字段:
| 字段 | 默认值 | 说明 |
|---|---|---|
isEnabled | — | 不会被读取。生成池没有启用开关。 |
poolStrings | [] | 可选的 EliteMobs Boss 文件名列表。 |
minLevel | -1 | 会保存,但不会被读取。 |
maxLevel | -1 | 赋予此生成池中实例 Boss 的等级。请明确填写有效等级。 |
处理器需要 EliteMobs,并从 poolStrings 随机选择一个 Boss 文件名。它将生成器的 spawnPoolSuffix 插入 .yml 前,例如 _hard 会选择 poolname_hard.yml。没有 spawnPoolSuffix 的生成器会查找 poolname.yml。池名末尾不要留空格。如果生成池文件缺失、poolStrings 列表为空,或 Boss 文件名不被 EliteMobs 识别,会记录一条警告,该告示牌处不会生成任何东西。
在专用模块世界中,非实例 Boss 会在粘贴期间生成。实例 Boss 会排队等待集成调用 spawnInstancedEntities()。每个实例 Boss 都以生成池的 maxLevel 生成,并根据其与地牢起点的距离选择一个 EliteMobs 实例难度 ID。距离取 X 与 Z 偏移中较大的一个,并与地牢宽度 (2 × radius − 1) × moduleSizeXZ 比较:小于宽度的六分之一为 2,小于三分之一为 1,再远则为 0。useGradientLevels 不影响此计算。
模型和怪物集成
模块粘贴与普通结构粘贴使用不同的告示牌处理器。如上表所示,模块粘贴仅在现有地形中处理 [elitemobs] 告示牌。创建结构中的 [mythicmobs] 和 [custom] 结构告示牌不会被模块粘贴处理。请使用上方支持的标记,并遵循内容包的依赖说明。
原理图本身不能重建由其他插件管理的任意模型实体。请安装内容包所需的模型和配套插件,不要依赖缺失的 Boss 自动变为装饰模型。
模块尺寸
模块尺寸可以配置,并非固定值。
生成器使用以下选项:
moduleSizeXZ:宽度和深度,单位为方块;请按原理图明确填写。moduleSizeY:高度,单位为方块;请按原理图明确填写。
常见尺寸: 16×16×16 方块,仍需明确配置。 其他常见尺寸: 部分内容包使用 32×16×32 方块。
模块创作者应:
- 查看生成器的
moduleSizeXZ和moduleSizeY。 - 将该生成器的所有模块建成完全相同的尺寸。
- 核对原理图的实际尺寸和连接点;生成器不会替你验证几何形状。
自定义尺寸示例:
在生成器配置中填写:
moduleSizeXZ: 32 # Width and depth
moduleSizeY: 16 # Height
同一生成器中的模块必须保持尺寸一致。不要在同一个地牢系统中混用 16×16×16 和 32×16×32 模块。
模块生成器配置字段
除 moduleSizeXZ 和 moduleSizeY 外,生成器还提供下列设置:
| 字段 | 默认值 | 说明 |
|---|---|---|
isEnabled | true | 允许自然选择。手动命令不检查此开关。 |
radius | 明确填写 | 以模块网格单元为单位的半径,水平单元尺寸为 moduleSizeXZ。最外层单元保留为边界。 |
edges | false | 已保存,但当前生成器不读取。边缘放置由 world_border 标签控制。 |
startModule | — | 起始 .schem 文件名列表。随机选一个,以旋转 0 放在网格 (0, 0, 0)。 |
minChunkY | 0 | 模块网格的最小垂直索引,包含此值,不是世界方块 Y 坐标。 |
maxChunkY | 0 | 模块网格的最大垂直索引,包含此值。范围必须包含第 0 层。 |
moduleSizeXZ | 明确填写 | 模块的宽度和深度,单位为方块。 |
moduleSizeY | 明确填写 | 模块高度,单位为方块。 |
debug | false | 在目标世界绘制诊断方块和文字。仅在可丢弃的生成区域使用。 |
useGradientLevels | false | 已保存,但当前生成池等级计算不读取。 |
spawnPoolSuffix | — | 附加到生成池名称的后缀。无后缀时省略此项或填写 ""。 |
isWorldGeneration | false | true 创建专用虚空世界;false 粘贴到现有世界。 |
treasureFile | — | 地牢箱子的战利品配置文件。 |
generateLootInBarrels | true | 是否填充模块中的木桶。 |
barrelTreasureFilename | treasure_barrel_food.yml | 地牢木桶的战利品配置文件。 |
validWorlds | 空,所有世界 | 允许自然生成的世界名称列表。 |
validWorldEnvironments | 空,所有环境 | 允许的环境列表:NORMAL、NETHER、THE_END、CUSTOM。随附的 dungeoneering 生成器明确使用 [NORMAL, CUSTOM],所以初始只在主世界类型的世界生成。省略此键时的行为见下文。 |
centerModuleAltitude | 0 | 在现有地形自然生成时的起始 Y 坐标。第 0 层向上偏移 moduleSizeY 的一半。在现有世界手动放置时从玩家位置开始;专用世界从 (0, 0, 0) 开始。 |
缺失的键使用生成器定义的当前字段值。预设生成器会按自己的内容初始化。手写生成器的 radius、moduleSizeXZ 和 moduleSizeY 从 0 开始,这些零也可能写入文件。不要假设缺少尺寸就会使用 16。省略 validWorlds 或 validWorldEnvironments 不施加限制,因此不会限定为 NORMAL/CUSTOM。请以完整可用的生成器为基础,明确设置半径、尺寸、起始模块和世界限制。
单个模块配置字段
各模块可以设置以下字段:
| 字段 | 默认值 | 说明 |
|---|---|---|
isEnabled | true | 是否启用模块。 |
weight | 100 | 生成时的选择权重。负值或非有限值会记录一条警告并变为 0,从而将该模块排除在选择之外。 |
repetitionPenalty | 0 | 每有一个已选的相邻模块使用相同原理图文件名,就将此值加到权重上。正值鼓励重复,负值减少重复。请保持最终权重为正。 |
noRepeat | false | 排除与相同配置标识的已选模块相邻的候选,包括克隆。不保证整个地牢中只出现一次。 |
enforceVerticalRotation | false | 上下相邻的任一模块启用时,要求两者的 Y 轴旋转相同。 |
enforceHorizontalRotation | false | 水平相邻的任一模块启用时,要求两者的 Y 轴旋转相同。 |
minY | -4 | 候选选择允许的最低模块网格层,包含边界值。 |
maxY | 20 | 候选选择允许的最高模块网格层,包含边界值。 |
biome | default | 已保存,但不限制模块选择。 |
minecraftBiome | null | 已保存,但不限制模块选择。 |
treasureFile | — | 会加载到配置中,但当前模块粘贴的标记箱子使用生成器的 treasureFile。 |
generateLootInBarrels | true | 是否填充此模块的木桶。 |
barrelTreasureFilename | treasure_barrel_food.yml | 此模块木桶的战利品配置文件。 |
borders | — | 定义连接兼容性的边界标签映射。 |
cloneConfig | — | 从另一个模块配置文件读取克隆设置。 |
compoundModule | — | 已保存,但当前生成器不使用它组装复合模块。 |
isAutomaticallyPlaced | true | 允许普通候选选择。配置中的起始模块会绕过此过滤。 |
必须定义 borders 的六个条目:north、south、east、west、up 和 down,每项包含标签列表。普通标签区分大小写,必须完全一致。例如 corridor 匹配 corridor;no-mirror_corridor 匹配 corridor,但不能连接另一个 no-mirror_corridor。每个模块提供 0、90、180、270 度四种 Y 轴旋转。
nothing 允许空邻居。world_border 将模块标为水平可放置区域的最外圈;所有朝外的面都只能包含 world_border 标签。封闭的上、下边界使用 nothing。半径 5 最多允许 9 × 9 个水平模块单元,周围边界留空。这些规则过滤普通候选;起始模块直接放置,所以其配置和形状必须适合原点。
cloneConfig 指向另一个模块的 .yml 文件名,克隆设置会从该文件读取。目标存在时,BetterStructures 会从本模块的磁盘文件中删除冗余键:treasureFile、barrelTreasureFilename、generateLootInBarrels、borders、minY、maxY、weight、repetitionPenalty、两个旋转开关、noRepeat、六个 *IsPassable 键和 isAutomaticallyPlaced。isEnabled、biome、minecraftBiome、cloneConfig 和 compoundModule 留在文件中。运行时的复合模块查询也遵循克隆目标。目标文件不存在时,会警告并忽略克隆,保留本模块的值。
生成的配置中还会有 northIsPassable、southIsPassable、eastIsPassable、westIsPassable、upIsPassable 和 downIsPassable。它们默认为 true,但生成器不读取,修改没有效果。请使用 borders。
不要让 cloneConfig 形成循环。像 a.yml -> b.yml -> a.yml 这样的循环会使模块加载停止,并报出一条注明该链条的 "Cyclic module clone configuration" 错误。
使用 /bs generateModules 手动生成地牢
/bs generateModules <ModuleGeneratorsConfigFile.yml> 按需运行,不必等待自然生成。Tab 补全列出所有已加载的模块生成器文件。
结果取决于 isWorldGeneration:
isWorldGeneration: true:创建新世界。世界名为生成器文件名加上_0、_1、_2…,选择文件夹尚不存在的第一个名称。它是NORMAL环境的虚空世界,出生区块不常驻内存,自动保存关闭。命令将玩家切换为旁观者,但不会传送到新世界。isWorldGeneration: false:在玩家当前所在的世界生成。
Boss 血条显示布局组装进度,粘贴排队后就会消失。组装完成消息不代表方块或实体已经粘贴完毕。如果没有安装任何已配置的起始原理图,生成会停止;禁用的起始模块也可能因容器不可用而导致取消。
命令需要拥有 betterstructures.generatemodules 的玩家,内容重载期间会拒绝执行。手动生成绕过自然放置检查,包括生成器启用状态、世界限制和占地保护。请谨慎选择目标位置。
模块文件存放位置
模块放在 plugins/BetterStructures/modules。该目录递归扫描,因此内容包可将 .schem 放在子目录,对应 .yml 会在旁边生成。
原理图文件名必须在整个 modules 目录树中唯一。重名或不可读文件会中止模块加载。读取原理图先于 isEnabled 检查,因此禁用模块无法绕过损坏文件。isEnabled: false 的内容包文件夹会被整体跳过,其中的模块既不会被读取,也不会被加载。
自然放置与保护
自然生成检查完整的配置占地。如果与围绕世界坐标 (0, 0) 的配置保护半径、具名 WorldGuard 区域或近期未被观察为新区块的已生成区块重叠,就跳过放置。粘贴排队前会再次检查 WorldGuard;最初未生成的区块若已在此期间生成,也会拒绝运行。这检查的是区块状态,不是扫描玩家建造的方块或其他领地保护插件。在旧基地旁生成一个新区块,不会让整个占地都符合条件。
自然选择的生成器应保持 isWorldGeneration: false。自然选择器不排除 true;此设置仍会创建独立世界,而非粘贴到已检查的地形。
方块、方块实体、战利品、实体和标记共享粘贴时间预算。WorldGenerationFinishEvent 在专用世界粘贴及其即时后处理成功后触发,不表示集成已放置出口或生成队列中的实例 Boss。大型建筑在布局计算后仍可能需要多个 tick。
模块战利品优先级
标记箱子和陷阱箱使用生成器的 treasureFile。实际木桶方块要求生成器与模块都允许 generateLootInBarrels。模块的非空 barrelTreasureFilename 优先于生成器;生成的模块文件默认使用 treasure_barrel_food.yml。箱子和木桶在应用物品栏快照前都会触发可取消的 ChestFillEvent。
生成箱子战利品请使用标记。当前模块粘贴不保留原理图内普通箱子、陷阱箱和木桶的物品栏。屏障方块会跳过;基岩标记只在目标方块非固体时变为石头。空气会在现有世界挖出内部空间,在专用虚空世界则会跳过。
保存在模块中的实体(如盔甲架、画和物品展示框)会随模块一起粘贴。画和物品展示框会随模块的旋转而转动,从而保持贴在墙上。