实体模型
实体模型把服务端配置与客户端生物渲染关联起来。服务端同步定义、管理强制模型和特殊动画;客户端按实体当前数据匹配模型,并根据状态自动选择动画。
完整配置
文件位置:plugins/ChaEngine/entity/*.yml
crystal_guardian: # 实体模型 ID
model: "guardian/guardian.geo.json" # 相对于客户端 model/ 的模型
animation: "guardian/guardian.animation.json" # 动画文件
texture: "guardian/guardian.png" # 模型贴图
scale: 1.0 # 模型缩放
position: [0, 0, 0] # X、Y、Z 位置偏移
collision: [1, 1, 1] # X、Y、Z 碰撞尺寸;会参与真实碰撞和命中
match: # 可选;只通过模型 ID 显式绑定时可以省略
- "name#start#水晶,type#equal#minecraft:zombie"
- "name#equal#水晶守卫"字段说明
model、texture 和 animation 均支持本地相对路径或 HTTP/HTTPS 直链,可以混用。完整网络配置、下载缓存与失败重试见网络资源。
| 字段 | 必填 | 默认值 | 说明 |
|---|---|---|---|
model | 是 | 无 | 模型相对路径或 HTTP/HTTPS 地址 |
animation | 建议 | 空 | 自动状态动画和特殊动画使用的文件,相对路径或 HTTP/HTTPS 地址 |
texture | 条件必填 | 无 | PNG 相对路径或 HTTP/HTTPS 地址;BBModel 使用工程自身纹理时可留空 |
scale | 否 | 1.0 | 模型整体缩放 |
position | 否 | [0, 0, 0] | 模型相对实体的位置偏移 |
collision | 否 | [1, 1, 1] | X、Y、Z 碰撞尺寸;会同步改变服务端和客户端的真实碰撞与命中范围 |
match | 否 | 空 | 客户端自动匹配实体的规则列表;省略时不会自动命中 |
匹配字段
| 字段 | 写法 | 说明 |
|---|---|---|
name | name#操作符#值 | 优先读取自定义名,否则读取实体名称;比较双方都忽略颜色和格式代码 |
type | type#操作符#值 | 同时接受完整 ID(如 minecraft:zombie)和路径部分(如 zombie) |
uuid | uuid#操作符#值 | 实体 UUID 字符串 |
nbt | nbt#顶层键#值 | 保存实体后读取顶层 NBT 键,并做精确字符串比较 |
perm | perm#权限节点 | 仅匹配拥有该权限的玩家;检查被匹配玩家本人,普通生物不匹配 |
name 会同时清理实际名称和规则值中的颜色与格式代码,支持 §a、&a、§l 等传统写法,展开式 RGB(如 §x§F§F§A§A§0§0、&x&F&F&A&A&0&0),以及 &#RRGGBB / §#RRGGBB。例如实体名 §6双手骑士 可以匹配 name#equal#双手骑士,也可以匹配 name#equal#&a双手骑士。等级、普通文字前后缀、空格和大小写仍参与比较;只有颜色代码的规则值无效。type、uuid、nbt 和 perm 不做颜色清理。
name、type、uuid 支持以下操作符:
| 含义 | 推荐写法 | 同样接受 |
|---|---|---|
| 开头是 | start | startsWith、starts |
| 结尾是 | end | endsWith、ends |
| 完全相等 | equal | equals、eq |
| 不相等 | notEqual | not_equals、neq、ne |
| 包含 | contains | — |
| 不包含 | notContains | not_contains |
规则列表的多行之间是 或;同一行用英文逗号分开的条件之间是 且。空规则、未知字段、未知操作符和格式不完整的条件都不会匹配。
按玩家权限匹配
perm#权限节点 只有两段,不填写比较操作符。服务端使用被匹配玩家的有效权限进行判断,继承、否定权限及默认授权按服务端权限系统的结果处理;观看该玩家的人是否拥有权限不影响结果。普通生物即使名称相同,也不会满足 perm。
下面是完整实体模型配置,放入 plugins/ChaEngine/entity/knight.yml:
knight_twohand:
model: "knight/knight-twohand.geo.json" # 客户端模型文件
animation: "knight/knight-twohand.animation.json" # 客户端动画文件
texture: "knight/knight-combat-all-opaque.png" # 客户端贴图文件
scale: 1.0 # 整体缩放
position: [0, 0, 0] # 模型偏移
collision: [1, 1, 1] # 实体碰撞尺寸
match:
- "perm#chaengine.model.knight" # 拥有该权限的玩家如果还要限定名称,将这条规则替换为 name#equal#双手骑士,perm#chaengine.model.knight,两项必须同时成立。这里只使用实体名称或自定义名;聊天昵称、Tab 昵称未必是同一个值。
服务端每 20 tick 检查一次配置中使用的权限节点,授权或撤销后通常在下一次检查生效,正常 20 TPS 下约为 1 秒;进服和配置重载时会补发当前结果。收到服务端结果前按不匹配处理,离线后清理。临时或永久强制模型仍优先于 match,所以撤销权限不会清除命令指定的模型。
该规则需要同时更新服务端插件与客户端 Mod;旧客户端不支持 perm,不会命中包含它的规则。六个受支持客户端都使用相同权限语义;Forge 1.16.5 保持现有能力范围,实体规则用于碰撞匹配,目前不提供世界实体替换显示。perm 不适用于物品模型或物品背景。省略整个 match 或填写 match: [] 仍然有效,此时仅通过模型 ID 显式选择。
运行规则
自动匹配与 MythicMobs
客户端按照同步配置的顺序检查 match。对 MythicMobs 生物,最容易复现的做法是先按最终显示名匹配:
match:
- "name#equal#水晶守卫"颜色代码会自动忽略。如果名称带等级或文字前后缀,可以在确认实际纯文本名称后改用 start 或 contains。需要用 NBT 时先确认目标值确实是顶层键;当前写法不遍历任意嵌套路径。
直接绑定 MythicMobs 生物
如果模型只服务于某一种 MythicMobs 生物,可以在 MythicMobs 生物配置中直接填写 ChaEngine.model,不必为它编写名称或 NBT 的 match 规则:
CrystalGuardian:
Type: ZOMBIE
Display: "水晶守卫"
ChaEngine:
model: crystal_guardian # 来自 plugins/ChaEngine/entity/*.yml 的模型 ID,不是文件路径ChaEngine 会在每次新生成该 MythicMobs 生物时使用这个实体模型 ID,写入永久模型并应用对应的 collision。该配置只影响之后新生成的生物;已经存在的实体不会被批量迁移。模型 ID 必须能在实体模型目录中找到,大小写也要一致。ChaEngine 段缺失、值为空白或 ID 未知时,生物仍会按 MythicMobs 原配置生成,不会取消事件;服务端会针对同一 MythicMobs 类型和 ID 限制警告次数。生成后仍可使用本页的命令或 Java API 覆盖模型。
强制模型优先级
实体还可以由命令或 Java API 强制指定模型。客户端选择顺序固定为:
- 临时强制模型;
- 已同步的永久强制模型;
- 实体自身保存的永久模型 NBT;
match规则。
临时指定只影响当前运行状态。永久指定会把模型 ID 保存到实体的 ChaEngine 自定义数据,并在实体重新加载后恢复。清除强制模型后才重新使用 match。
若较高优先级保存了一个不存在的模型 ID,客户端会失败关闭该强制结果,不继续回退到 match,以免无意显示错误模型。
真实碰撞与命中
实体模型生效时,collision 不只是渲染参考,而会参与服务端真实碰撞、攻击命中和客户端选取。Y 表示高度;X、Z 中较大的值作为水平宽度。三个值都必须是大于或等于 0 的有限数。
玩家切换模型时,collision 不改变第一人称视点高度。站立、蹲下、游泳等姿态继续使用玩家原有眼高;无需为了修正视点而调大模型碰撞箱。六个受支持客户端版本均遵循此规则。
临时或永久强制模型、自动 match 模型都会使用对应配置的碰撞尺寸。清除模型、实体卸载、配置失效或插件停用时会恢复原实体尺寸。
Citizens NPC 与普通生物采用各自兼容入口。若当前服务端核心或实体实现不允许修改真实尺寸,ChaEngine 会保留原碰撞并在服务端日志记录警告;此时不要把客户端看到的模型大小当作服务端命中范围。
发光描边
实体获得原版发光效果时,替换后的实体主体也会显示描边。除此之外,管理员或业务插件可以为实体设置严格的 #RRGGBB 自定义颜色,例如 #33CCFF。这项能力仅接受 Bukkit LivingEntity,不会作用于掉落物、弹射物等非生物实体。
自定义颜色优先于原版队伍颜色;清除自定义颜色后,实体重新遵循原版规则,包括发光状态与队伍颜色。Forge 1.20.1 与 NeoForge 1.21.1、1.21.4、1.21.8、1.21.11 中,原版实体和 ChaEngine 替换模型的实体主体都适用,额外挂载的时装、装备、方块模型和模型预览不适用。
Forge 1.16.5 当前不提供世界实体替换显示,因此该版本只对原版 LivingEntity 绘制自定义描边。
这是客户端轮廓描边,不是 Buff,也不是表面自发光或材质发光。它不会让模型在黑暗中自行发亮,也不会绕过客户端的原版实体轮廓开关、可见性判断、剔除或渲染距离。
同一实体的自定义颜色对所有玩家一致,重复设置会覆盖旧颜色。状态只保存在当前运行期;实体卸载、切换维度、插件重载或服务器重启时都会清理,不写入实体自身数据。
辅助命令
/chaengine entity model set <entity> <id>
/chaengine entity model set <entity> <id> <temporary|permanent>
/chaengine entity model clear <entity>
/chaengine entity glow set <entity> <#RRGGBB>
/chaengine entity glow clear <entity>
/chaengine entity animation play <entity> <animation>
/chaengine entity animation stop <entity>管理员玩家可以把 <entity> 写成 @aim 或 @nearest;控制台应使用实体 UUID 或当前运行期数字 ID。省略模式时按 temporary 处理。排查自动匹配时可以先执行 /chaengine entity model set @aim crystal_guardian temporary,验证结束后执行 /chaengine entity model clear @aim 恢复 match。
动画与同步时序
客户端根据实体状态寻找空闲、移动、奔跑、攻击、受伤、死亡、跳跃、游泳、潜行和使用等动画名称;找不到时回退到可用的 idle。服务端触发特殊动画后,它会临时覆盖自动状态动画,停止后恢复自动选择。业务插件还可播放一层覆盖动画,让受击、技能等动作叠加在基础移动动画上。
玩家加入时服务端立即同步模型配置,并在 20 tick、60 tick 后补发。客户端注册相关能力后,永久强制状态还会在 1 tick、20 tick 后补发,用于处理登录阶段先后顺序。资源文件始终由客户端本地读取。
常见问题
名称规则不匹配:颜色代码会自动忽略;先核对实际实体名称的等级、文字前后缀和大小写,再用一条 name#equal#实际名称 验证。
权限规则不匹配:确认写的是 perm#权限节点,目标是在线玩家,并且权限授予了被匹配玩家本人。等待至少 20 tick,检查服务端与客户端是否都已更新;若已用命令强制指定模型,应先清除强制模型再验证 match。
NBT 规则不匹配:确认键在实体保存数据顶层,且字符串表示与规则值完全一致;nbt 不使用通用比较操作符。
被强制模型后无法回到自动匹配:执行 /chaengine entity model clear <entity>;仅停止动画不会清除模型覆盖。
模型出现但状态动画不切换:核对动画文件中实际 ID,并查看模型动画的名称候选规则。
模型大小正确但攻击范围不对:确认服务端日志没有真实碰撞适配警告,并检查 collision;水平宽度取 X、Z 较大值,高度取 Y。
切换玩家模型后第一人称突然变矮:旧版客户端可能把模型碰撞高度当成玩家眼高。更新客户端 Mod 并完整重启游戏,再在同一位置切换模型、蹲下和起身检查;不需要修改模型文件或碰撞尺寸来补偿视点。
客户端日志显示 forced model id missing:服务端保存的强制 ID 不在本次同步配置中。恢复对应配置,或清除该实体的强制模型。
MythicMobs 生物没有替换模型:确认 ChaEngine 与 model 的缩进、ID 是否来自 entity/*.yml,并执行 /chaengine reload 后重新生成生物。若仍无效,查看服务端是否记录了未知 ID 的一次性警告,并确认客户端已收到同名模型配置。
猹件开发组