简体中文
生物定义
mobs/*.yml 生物定义文件里每个字段的含义, 包括类型覆写, 属性, 威胁表, Boss 血条, 目标选择器与 model 节, 逐一说明如下
生物定义文件放在 plugins/EmakiMobs/mobs/*.yml, 一个文件对应一种自定义生物. 目录下所有 .yml 都会被加载; 某个文件解析失败只影响它自己 (会记录一条 issue), 其他文件照常加载. 首次启动释放的默认定义是 mobs/example_zombie.yml (由 release_default_data 控制); 下面的例子与插件内置的 mobs/elite_zombie.yml 结构一致
顶层字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
id | string | 是 | 无 | 非空白字符串 | 生物的唯一 ID. 为空或缺失时, 该文件会被记录 issue 并丢弃. 如果和原版 EntityType 名称完全一致 (大小写不敏感), 会自动开启类型覆写. 命令与 API 都按这个值区分大小写匹配 |
type | string | 否 | 与 id 相同 | 合法原版 EntityType 名 (如 zombie, skeleton, creeper, 大小写不敏感) | 底层用的原版实体类型; 解析不出来时该文件会被记录 issue 并丢弃 |
display_name | string | 否 | null | 任意字符串 | 只作为定义的元数据暴露给 API (MobDefinition.displayName()), 不会自动设成实体名牌, 也不会出现在命令输出里. 要在游戏里显示名称, 请用 components.custom_name |
experience | int | 否 | 0 | — | 击杀掉落的经验覆盖值; 大于 0 时就覆盖原版经验 |
components | section | 否 | 空 | 键名须在组件参考列表内 | 映射到实体的属性或数据组件. 不认识的键会被跳过 (不报错, 不打日志) |
ea_attributes | section | 否 | 空 | 值为数字; 键名对应 EA 属性 ID | EmakiAttribute 的属性映射. 只在安装了 EmakiAttribute 时生效, 没安装时整节被忽略, 也不影响其他功能. 旧键 attributes 会作为兼容回退读取并打 WARN, 建议迁移过来 |
actions | section | 否 | 空 | 值为动作行字符串列表; 键为触发器名 | 触发器到 CoreLib 动作行的对应关系. 由 CoreLib 动作管道执行, 不需要安装 EmakiSkills. 空列表会被忽略; 旧键 skills 会作为兼容回退读取并打 WARN, 建议迁移. 详见技能触发器 |
threat | section | 否 | 无 | 见下表 | 威胁仇恨表配置; 整节默认没写时就不启用威胁系统 (也不影响 target_selector) |
boss_bar | section | 否 | 无 | 见下表 | Boss 血条配置; 整节默认没写时就不注册血条 |
model | section | 否 | 无 | 子键: blueprint (必填), api, scale, animations.<动作>, keyframes.<动作>.{duration_ticks,loop,priority,conflict,frames[]}, lod.{near,mid,far} | 模型挂载与动画; 字段与默认值见实体模型与动画的"生物定义 model: 节". 缺 blueprint 时整节被忽略, 并打一条加载告警 |
target_selector | string | 否 | null | target_selectors.yml 中已定义的 selectors id | 目标选择器 id (读取时会转成小写). 设置后生物就按这个选择器挑目标, 优先于威胁表; 没设置时走威胁表逻辑. id 不存在时选择会失败, 目标不变 |
lock_target | section | 否 | 无 (按未启用处理) | enabled, interval_ticks | 目标锁定配置. 只在同时设置了 target_selector 且 enabled: true 时才生效: 按 interval_ticks 的周期重新选目标, 并写入实体目标 |
类型覆写
当 id 和一个有效的原版 EntityType 名称完全一致时 (大小写不敏感), EmakiMobs 会在 CreatureSpawnEvent 上给这只实体打上受管标记, 并对它套用本定义里的 components (包括把 max_health 补满). 标记完成后, ea_attributes 也经 EA 贡献提供方作用到这只实体上, 因为这个标记就是属性贡献的判据
yaml
# 对所有原版僵尸应用加强属性
id: zombie
type: zombie
components:
max_health: 22.0
attack_damage: 3.5类型覆写不会触发 EmakiMobSpawnEvent, 也不会执行 on_spawn 动作行 (这两个只属于经生物工厂创建的实体). 另外它不读 spawn_rules/, 所以不受刷新规则约束
CAUTION
⚠ 类型覆写会影响服务器上所有自然刷新的该类型生物, 包括其他插件产生的同类型生物. 如果只想要某个特定区域的自定义生物, 请用独立的 id, 并配合 spawn_rules/ 里的 type: natural 规则
ea_attributes 字段 (可选)
yaml
ea_attributes:
STR: 15 # 键名与 EmakiAttribute 中定义的属性 ID 一致
VIT: 10
AGI: 5这一节完全可选: 只有装了 EmakiAttribute 插件才会生效. 没装 EmakiAttribute 时, EmakiMobs 会忽略整个 ea_attributes 节, 不报错, 也不影响生物定义的其他部分
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
<属性 ID> | double | 否 | 无 | 数值; 绝对值 ≤ 1e-9 的条目被跳过 | 以属性 ID 作键, 数值作值. 只读数字类型, 非数字的值会被忽略 (不报错) |
资源类属性对怪物无效
health / mana 这类 RESOURCE 型属性, 当前值以玩家侧的资源系统为准, 对非玩家实体不产生效果. 想抬高怪物血量上限, 请用 components.max_health, 或者用 VANILLA 映射属性 (比如 max_health_vanilla). 如果同时在 components.max_health 和 ea_attributes.max_health_vanilla 里配置了同一个概念, 预检会打 WARN, 提示两者会叠加
threat 字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
enabled | boolean | 否 | true | true / false | 是否启用威胁系统. 填 false 时不累计威胁, 也不改写目标 |
max_range | double | 否 | 64.0 | — (格) | 把玩家移出威胁表的距离. 玩家可以在超出这个距离时继续累计威胁 (比如远程攻击), 但下一个衰减周期 (每 20 tick 一次) 会按这个距离把越界的玩家移出威胁表 |
weights.damage | double | 否 | 1.0 | — | 玩家对这只生物造成伤害时, 每点伤害累加的威胁值 |
weights.healing | double | 否 | 0.5 | — | 玩家每次回血 (包括自然回血) 时, 用治疗量乘以这个权重, 累加到它 32 格内受管生物的威胁表里 |
decay.rate | double | 否 | 0.05 | — | 每个衰减周期 (20 tick) 把威胁值乘以 1 - rate; 0.05 约等于每秒衰减 5% |
decay.out_of_range | boolean | 否 | true | true / false | 是否按 max_range 把越界的玩家移出去. 整节 decay 默认没写时按 true 处理 |
威胁值低于 0.001 的条目会被清理; 挑最高威胁目标时要求威胁值严格大于 0, 所以威胁衰减到接近 0 后, 这只生物不会再重新选目标 (表现出来就是不再主动追人)
boss_bar 字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
title | string | 否 | "" | 任意字符串 | 血条标题, 支持 MiniMessage 格式 |
color | string | 否 | PURPLE | PINK / BLUE / RED / GREEN / YELLOW / PURPLE / WHITE (大小写不敏感) | 血条颜色; 取值非法时会不报错地回退 PURPLE |
style | string | 否 | SOLID | SOLID / SEGMENTED_6 / SEGMENTED_10 / SEGMENTED_12 / SEGMENTED_20 (大小写不敏感) | 血条风格; 取值非法时会不报错地回退 SOLID |
range | double | 否 | 64.0 | — (格) | 可见范围. 每 20 tick 重算一次能看到它的玩家: 同世界且距离不超过这个值的在线玩家可见, 其余被移出去. 进度条在受伤与回血事件之后更新 |
非法取值会静默回退
color 与 style 用 valueOf 解析, 解析失败时不报错, 不打日志, 直接回退成默认值 (color → PURPLE, style → SOLID)
BarStyle 没有 NOTCHED_6 / NOTCHED_10 / NOTCHED_12 / NOTCHED_20 这类取值. 写成 NOTCHED_10 不会有任何提示, 血条会不报错地变成实心 (SOLID). 分段血条只能用 SEGMENTED_*
lock_target 字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
enabled | boolean | 否 | false | true / false | 是否启用周期锁定. 只在同时设置了 target_selector 时才参与锁定 |
interval_ticks | int | 否 | 20 | — (tick) | 重新选目标的周期. 锁定循环本身每 20 tick 跑一次, 配置值会向上取整到 20 tick 的整数倍 (< 20 按一轮处理) |
目标选择器 (target_selectors.yml)
target_selectors.yml 是插件的静态文件 (只在缺失时释放, 升级时不会合并覆盖), 所有生物共用. 你在生物定义里用 target_selector 引用 selectors 下面的 id
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
snapshot_interval_ticks | int | 否 | 20 | ≥ 0; 0 = 关闭快照 | 玩家打分快照的调度间隔 (tick). 关闭后 equipment, expression, health 恒为 0, 配了 filter 的选择器就选不出合格候选 |
snapshot_players_per_tick | int | 否 | 20 | ≥ 1 | 每轮最多把多少名在线玩家派到他们各自所属的线程上重算; 超出的玩家顺延到后面的轮次 |
equipment_tables.<表 id> | section | 否 | 空 | — | 装备权重表集合, 供 score.type: equipment 引用 |
equipment_tables.<表 id>.slots | string list | 否 | [] | 槽位名: head / chest / legs / feet / main_hand / off_hand (另接受 mainhand / offhand); 其他值按 EquipmentSlot 枚举名解析 | 参与打分的装备槽位; 认不出来的槽位会打 WARN 并跳过 |
equipment_tables.<表 id>.default_weight | double | 否 | 0 | — | 表内没列出的物品的默认权重 |
equipment_tables.<表 id>.weights.<物品源> | double | 否 | 无 | 物品源简写, 如 minecraft:iron_sword 或 emakiitem:<id> | 物品到权重的对应. 解析不出来或者物品源不可用的条目, 会打 WARN 并跳过 |
selectors.<选择器 id> | section | 否 | 空 | — | 选择器定义的集合. 整节缺失会被当成阻塞性配置错误 (预检 ERROR). 这个 id 读取时会转成小写, 供 target_selector 引用 |
selectors.<选择器 id>.mode | string | 否 | highest | highest / lowest / random / weighted_random / first_damager / last_damager (大小写不敏感) | 挑目标的方式; 取值非法会打 WARN, 并丢弃这个选择器. highest/lowest/weighted_random 在 score 为空时选不出目标 |
selectors.<选择器 id>.range | double | 否 | 未设置 | ≥ 0 (格) | 候选玩家的搜索半径. 默认没写时, 先回退到这只生物的 threat.max_range, 还不行再回退到 16 |
selectors.<选择器 id>.filter | section | 否 | 无 | CoreLib 条件块 | 候选的过滤条件; 以玩家为上下文, 按快照逐个玩家求值, 没通过的不进入候选 |
selectors.<选择器 id>.score | list | 否 | [] | 步项 type: threat / distance / health / equipment / expression | 打分项列表; 总分是各步项"取值 × factor"相加之和. 不认识的 type 或者不是有限值的 factor, 会打 WARN 并跳过该步项 |
selectors.<选择器 id>.score[].factor | double | 否 | 1.0 | 有限数值 | 该步项的权重系数 |
selectors.<选择器 id>.score[].table | string | type: equipment 时是 | 无 | 已定义的装备表 id | 引用的装备权重表; 不存在时会打 WARN, 并跳过该步项 |
selectors.<选择器 id>.score[].value | string | type: expression 时是 | 无 | 长度 ≤ 256, 括号嵌套 ≤ 10 层, 不含 `/$/\ | 表达式串 (如 %vault_eco_balance% / 1000); 校验失败会打 WARN, 并跳过该步项. |
NOTE
filter 与 score 的条件/表达式语法由 EmakiCoreLib 提供, 见 CoreLib 条件与表达式. 快照关闭 (snapshot_interval_ticks: 0) 时基于快照的步项恒为 0
完整示例
yaml
id: elite_zombie
type: zombie
display_name: "<gradient:#ff4444:#ffaa00>精英僵尸</gradient>"
components:
max_health: 80.0
movement_speed: 0.28
attack_damage: 7.0
follow_range: 40.0
knockback_resistance: 0.3
custom_name: "<gradient:#ff4444:#ffaa00>精英僵尸</gradient>"
custom_name_visible: true
persistent: true
experience: 80
ea_attributes:
STR: 15
VIT: 10
actions:
on_spawn:
- "nearby radius=20 include_players=true | send_message text='<red>精英僵尸降临!'"
on_death:
- "killer | give_exp amount=80"
threat:
enabled: true
max_range: 48.0
boss_bar:
title: "<gradient:#ff4444:#ffaa00>精英僵尸</gradient>"
color: RED
style: SEGMENTED_10
range: 60.0自定义掉落表与 loot_table 组件互相独立
loot_tables/<mob_id>.yml 只要同名文件存在就生效, 与 components 是否写 loot_table 无关; 生效后死亡时会先清空全部原版掉落 (经验仍保留). loot_table 组件只用于设置原版/数据包掉落表: 写 loot_table: "minecraft:entities/zombie" 会设置原版表, 但若同时存在同名 YAML 表, 原版掉落仍会被替换. 详见组件参考的"掉落类字段"