简体中文
刷新规则
刷新规则写在 spawn_rules/*.yml, 也就是设定一只自定义生物在什么条件下会出现
刷新规则文件位于 plugins/EmakiMobs/spawn_rules/*.yml, 每个文件里可以写多条规则, 都放在 rules: 列表下. 文件缺失, 或者 rules 缺失, 或者 rules 不是列表时, 这个文件就不会产生任何规则. 首次启动释放的默认规则是 spawn_rules/overworld_elites.yml (只有一条 natural 规则)
文件结构
yaml
rules:
- mob_id: <生物 id>
type: <刷新类型>
# 各类型专属字段...只接受两种 type
当前加载器只认 type: natural 和 type: autonomous. 写 structure, biome, player_relative, day_interval, custom 这些值不会报错, 但会被记成 Unknown spawn type, 并且不报错地跳过整条规则; 缺 mob_id 或 type 时同样会跳过, 并打 WARN
内置参考文件 spawn_rules/overworld.yml 里有两条规则不会被加载
这个文件在插件 jar 里面, 不会自动释放到 plugins/EmakiMobs/spawn_rules/ (首次启动释放的是 overworld_elites.yml). 它一共有三条规则: natural (elite_zombie) 是有效的, 而 type: structure (bone_lord) 和 type: biome (jungle_stalker) 会走到上面那个未知类型分支, 被不报错地跳过. 照抄这个文件时, 请按下面 natural / autonomous 的写法改写这两条
natural — 原版事件拦截
满足条件时, 按概率把原版刷出来的生物替换成自定义生物. 自然刷新走 PreCreatureSpawnEvent (在实体创建之前就拦住); 其余不是 NATURAL 也不是 SPAWNER 的刷新来源, 走 CreatureSpawnEvent 并取消原来的刷出
yaml
- mob_id: elite_zombie
type: natural
biomes: # 限定生物群系列表; 留空则不限
- plains
- forest
y_range: [-64, 50] # 仅在此 Y 范围内替换
light_level_max: 7 # 光照等级上限 (含)
replacement_chance: 0.08 # 替换概率, 0.0–1.0
max_nearby: 3 # 64 格内同 id 生物上限; 0 = 不限
count:
min: 1
max: 1| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
mob_id | string | 是 | 无 | 已加载的生物定义 id | 要刷出的生物; 不是字符串或缺失时, 整条规则被跳过. id 没注册时不刷出 |
type | string | 是 | 无 | natural | 固定值 |
worlds | string list | 否 | [] (不限) | 世界名 (World#getName) | 限定在哪几个世界生效 |
biomes | string list | 否 | [] (不限) | 群系键, 可带命名空间 (取 : 之后一段并转小写) | 限定在哪些群系; 认不出来的名字会打 WARN 并忽略这一条, 规则剩下的部分仍然生效 |
y_range | int list [min, max] | 否 | [-64, 320] | 按下标读取列表: 第 1 项为 min, 第 2 项为 max, 缺项用默认值 | 刷出位置的 Y 范围 (包含两端) |
light_level_max | int | 否 | 15 | 0–15 | 刷出位置的综合光照等级不超过这个值才会触发; 默认 15 就相当于不限制 |
replacement_chance | double | 否 | 1.0 | — | 命中条件之后替换的概率: 0.0 永远不替换, ≥ 1.0 必定替换 (没有做过钳制) |
max_nearby | int | 否 | 0 | ≥ 0; 0 = 不限 | 64 格内同 id 的受管生物到了这个数量就不再触发 |
count | {min, max} | 否 | {1, 1} | min ≤ max | 每次触发刷出的数量 (在区间里随机, 包含两端). min > max 会在触发时抛异常, 让这次替换失败 |
condition | section | 否 | 无 | CoreLib 条件块 | 额外的条件.没有玩家上下文, 所以不能写玩家占位符 (这一点和 autonomous 不同) |
autonomous — 自主定时刷新
它完全不碰原版刷新事件, 由插件自己的调度器驱动, trigger 决定用哪种调度方式. 候选位置按"以玩家为圆心, 在 distance 距离上取一个随机角度"来生成, 最多尝试 6 次, 还要求这个位置上方能通行, 下方是固体方块, 所以不是每次尝试都能刷出来
yaml
- mob_id: elite_zombie
type: autonomous
trigger: interval
interval_ticks: 1200
worlds:
- world
biomes:
- plains
distance:
min: 16
max: 64
max_nearby: 4
max_global: 10
count:
min: 1
max: 2四种 trigger
trigger | 调度方式 | 相关字段 |
|---|---|---|
interval | 按全局固定周期跑 (启动后 1 tick 开始起算), 每轮把所有在线玩家逐个扫一遍, 对每名玩家各尝试一次 | interval_ticks, worlds, max_global |
player_follow | 按全局固定周期跑, 每轮随机挑一名在线玩家尝试一次 | interval_ticks, worlds, max_global |
day_interval | 每 20 tick 检查一次各个世界的游戏日计数 (每个世界分别记上次触发是哪一天), 到点时为该世界里所有玩家各尝试一次 | interval_days, on_day_start, worlds, max_global |
cron | 按真实系统时间的 Cron 触发, 每次为每个在线玩家各尝试一次 | cron, worlds, max_global |
trigger 值不区分大小写. cron 使用 6 段 Quartz 格式, 写法见 CoreLib 表达式 - Cron 表达式; 表达式为空或无法解析时只打一条警告, 该规则永远不会触发
autonomous 字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
mob_id | string | 是 | 无 | 已加载的生物定义 id | 要刷出的生物; 不是字符串或缺失时, 整条规则被跳过 |
type | string | 是 | 无 | autonomous | 固定值 |
trigger | string | 是 | 无 | interval / player_follow / day_interval / cron (大小写不敏感) | 用哪种调度方式. 缺失或者不认识时, 整条规则被跳过并打 WARN |
interval_ticks | long | 否 | 600 | ≥ 1 (tick) | interval / player_follow 两种调度的周期 |
interval_days | int | 否 | 1 | ≥ 1 (游戏日) | day_interval 每隔多少个游戏日跑一次 |
on_day_start | boolean | 否 | false | true / false | 填 true 时只在该世界时间 < 1000 (刚天亮) 那会儿触发; 填 false 时时间到就触发 |
cron | string | 否 | "" | 6 段 Quartz 表达式 | trigger: cron 用的表达式; 为空时打一条警告, 并且该规则永远不会触发 |
worlds | string list | 否 | [] (不限) | 世界名 | 限定在哪几个世界生效 |
biomes | string list | 否 | [] (不限) | 群系键 (同 natural) | 限定刷出点所在的群系 |
structures | string list | 否 | [] (不限) | NamespacedKey, 如 minecraft:stronghold | 限定刷出点要落在该区块里某结构的包围盒 (框住整个结构的那个范围) 内; 不认识的结构会打 WARN 并忽略这一条 |
y_range | int list [min, max] | 否 | [-64, 320] | 同 natural | 刷出位置的 Y 范围 (包含两端), 和 natural 一样 |
light_level_max | int | 否 | 15 | 0–15 | 综合光照的上限; 只有这个值小于 15 时才会检查, 默认 15 时完全不检查光照 |
time_of_day | string | 否 | any | any / day (1000–12999) / night (≥ 13000 或 < 1000) (大小写不敏感) | 限定在哪个时段; 取值认不出来时等同于 any |
require_surface | boolean | 否 | false | true / false | 填 true 时要求刷出点的天光是 15 |
distance | {min, max} | 否 | {16, 64} | ≥ 0 (格) | 离玩家的刷出距离范围 (包含两端); min ≥ max 时固定用 min |
max_nearby | int | 否 | 0 | ≥ 0; 0 = 不限 | 64 格内同 id 受管生物的数量上限 |
max_global | int | 否 | 0 | ≥ 0; 0 = 不限 | 全服 (所有世界加起来) 同 id 的数量上限; 到了上限就整轮跳过 |
count | {min, max} | 否 | {1, 1} | ≥ 1 | 每次刷出的数量 (在区间里随机, 包含两端); min ≥ max 时固定用 min |
condition | section | 否 | 无 | CoreLib 条件块 | 额外的条件; 以触发这次尝试的那名玩家为上下文, 可以渲染 PlaceholderAPI 占位符 |
与 natural 的差别
natural 的 condition 没有玩家上下文; autonomous 的 condition 会用当前尝试的那名玩家来渲染占位符. 两者的 count, distance 也都在 min 和 max 相等时退化成固定值