跳到主要内容

FreeMinecraftModels 模型创作注意事项

本页说明 FreeMinecraftModels 在导入和运行时读取的模型文件、配套文件及名称规则。

源格式​

FreeMinecraftModels 目前接受:

  • .bbmodel 文件,用于可编辑的源导入
  • .fmmodel 文件,用于精简的运行时就绪模型数据

对于没有配套文件的单个 .bbmodel:

  1. 将它直接放在 plugins/FreeMinecraftModels/imports 中,扩展名使用小写 .bbmodel
  2. 运行 /fmm reload
  3. 检查转换后的 .fmmodel 是否出现在活动模型文件夹中,以及重载是否成功

单文件导入器会把原文件留在 imports,因此后续导入会再次转换。它不收集散放的 .json 或 .yml 配套文件,也不接受散放的 .fmmodel。对于自制模型集,请将模型和配套文件一起放在活动 models 文件夹中,或使用结构正确的内容包。imports 中没有 pack.meta 的任意子文件夹会被跳过。被拒绝的重载可能保留旧目录,请检查控制台。

单文件转换只保留纹理的 source、id 和 name,会丢弃动画尺寸与时间元数据,并且要求存在 textures 数组。如果需要这些元数据,请使用活动模型文件夹或保留原文件的内容包;运行时模型读取器本身允许缺少纹理数组。

文件夹用途​

plugins/FreeMinecraftModels/imports
plugins/FreeMinecraftModels/models
plugins/FreeMinecraftModels/models_disabled
  • imports 是手动模型导入和官方包下载在处理前的接收文件夹
  • models 包含已激活安装的模型内容
  • models_disabled 包含当前已禁用的已下载或已安装的包内容

旧安装可能有首字母大写的 Models 文件夹。FreeMinecraftModels 运行时优先使用现有的小写 models,否则使用 Models。在不区分大小写的文件系统中,两者指向同一目录;在区分大小写的文件系统中,它们可以并存。此时共享内容包导入器优先使用现有的 Models 目标,而运行时读取小写 models。请在服务器停止时备份并统一到小写 models,避免导入文件落在活动模型树之外。

模型 ID​

  • 运行时模型 ID 来自文件名,不包含 .bbmodel 或 .fmmodel 扩展名
  • 使用稳定、唯一的文件名,因为 ID 是命令和 API 调用解析的目标
  • Blockbench 动画引用基于名称,因此模型内重复或不清晰的命名比干净、明确的命名方案更容易造成问题
  • 活动模型文件夹中的扩展名匹配不区分大小写,因此接受 .BBModel 和 .FMModel。从 imports 导入散放文件时,只识别小写 .bbmodel

ID 规范化与冲突​

文件名在成为运行时模型 ID 和资源包文件名之前会先被规范化:

  1. 转为小写
  2. 每一个不属于 a-z、0-9、.、_、- 的字符都会被替换为 _

因此 My Table.bbmodel、my table.bbmodel 和 my_table.bbmodel 全都规范化成同一个 ID:my_table。

在任何转换开始之前,FreeMinecraftModels 会扫描整个 models 目录树,检查是否有文件规范化后得到相同的 ID。如果拥有该 ID 的所有文件逐字节完全相同(两个内容包附带同一个模型时就会出现这种情况),FMM 会加载绝对路径排序最靠前的那个,并直接跳过其余副本,不产生警告。当这些文件内容不同时:

  • 每一个发生冲突的文件都会被拒绝 —— 它们都不会被加载,因此不存在悄悄的"最后一个胜出"
  • 该模型 ID 在本次加载过程的剩余阶段被封锁
  • 被拒绝的模型也会被排除在基岩版自定义实体资源包的导出之外
  • 控制台会输出:
[FMM Models] Rejected normalized model ID collision '<id>'. These files normalize to the same ID: <paths>. Rename the files so every normalized model ID is unique; no colliding model was loaded.

修复办法始终是重命名文件,使规范化后的 ID 各不相同。最稳妥的习惯是从一开始就用小写加下划线来命名模型文件(stone_table.bbmodel),这样文件名与运行时 ID 就完全一致,也彻底消除了意外冲突的可能。

Blockbench 兼容性​

  • FreeMinecraftModels 会从 .bbmodel 中读取 meta.format_version,并根据其主版本号分支
  • 缺少 meta 块、缺少 format_version,或者值无法解析,都会回退到版本 4,并输出一条指明该模型的信息/警告
  • 缺少 textures 数组是被接受的,会被当作空纹理列表处理,而不会让导入器崩溃。此后基岩版自定义实体导出器会跳过该模型,因为基岩版导出至少需要一张纹理
  • 提取出的纹理文件名会被统一规范为单一的 .png 扩展名。诸如 body.jpg、body.PNG 或 body 这样的源名称,都会以 body.png 的形式写出并被引用
  • format_version 4.x 及更早:骨骼直接从 outliner 树中读取,该树内联携带骨骼名称
  • format_version 5.x 及更新:outliner 的结构发生了变化。outliner 现在是由纯 UUID 字符串和 {uuid, isOpen, children} 字典构成的嵌套树,其中没有 name 键,而真正的骨骼数据(包括 name)保存在一个独立的扁平 groups 数组中。FMM 通过 UUID 把两者连接起来 —— 每个 outliner 节点会被替换为它在 groups 中匹配的条目,然后递归合并子节点 —— 因此骨骼名称、原点和旋转都能正常解析
  • 手工编辑或程序生成 .bbmodel 文件时值得了解的影响:
    • 缺少 groups 数组的 v5 文件会不经合并直接传递。已经合并的 outliner 仍可能正常工作;未经处理的无名 v5 组节点则可能在骨架读取器需要名称时导致模型加载失败
    • outliner 和 groups 之间的 UUID 必须完全一致;没有匹配 group 的 outliner 节点会被原样保留,而不是被丢弃
    • 不要把 v5 的 format_version 与 v4 形态的 outliner 混在一起,反之亦然 —— 分支是根据声明的版本选择的,而不是根据实际结构
  • 如果导入日志显示模型格式与 FreeMinecraftModels 不兼容,请首先将其视为模型格式问题,而不是 wiki 或命令问题

影响运行时的骨骼约定​

当前转换器和骨架管线识别以下命名约定:

  • hitbox
    • 保留用于碰撞箱生成
    • 应该清晰地定义模型碰撞箱,而不是用作视觉骨骼
    • 必须是 outliner 中的顶级骨骼才能定义运行时碰撞。嵌套的 hitbox 会经过普通骨骼解析,但保持隐藏,且不会定义模型的碰撞箱
    • 应恰好包含一个立方体,定义宽(x)、深(z)和高(y)。额外立方体会记录 has more than one value defining a hitbox! Only the first cube will be used。空组会记录 has a hitbox bone but no hitbox cube!,并留下零尺寸,与没有 hitbox 不同。立方体的偏移和旋转不会成为碰撞箱偏移:解析器使用各边长度的绝对值和零模型偏移
    • 永远不会被动画化(指向 hitbox 的动画轨道会被跳过)、永远不会被渲染,并被排除在基岩版几何体导出之外。在基岩版上,没有 hitbox 骨骼的模型会回退到 1.0 x 2.0
  • tag_...
    • 作者可选添加的名牌锚点,参见下方名牌位置
  • h_...
    • 被视为头部骨骼
  • b_...
    • Java 运行时的非显示骨骼。结构用途请使用不含立方体的骨骼:基岩版几何导出不会过滤 b_ 前缀,因此这些骨骼上的立方体仍可能显示
  • m_...
    • 骑乘点骨骼。每个带此前缀的骨骼创建一个玩家座位,由 MountPointManager 管理。多个 m_ 骨骼创建多个座位。管理器选择第一个空座位,并在占用期间使用临时 Interaction 实体;其公开骑乘方法接受玩家,不接受任意实体。

前缀区分大小写,hitbox 名称的比较则不区分。这些名称影响转换和运行时行为。

名牌位置​

tag_ 骨骼现在是可选的。FMM 按名称字母顺序选择第一个 tag_ 骨骼作为名牌锚点。没有这类骨骼时,会将名牌放在缩放后的碰撞箱上方,因此无标签骨骼的模型也能显示名称。

如果备用位置不合适,可添加不含立方体的 tag_name 骨骼。多个标签骨骼不再产生同一名牌的多个副本。

API 支持多行名称、缩放、行距和可见性。各行从上到下排列,最后一行位于锚点处。参见API 指南。

立方体着色与发光​

  • 来自 Blockbench 的立方体 light_emission 值为 0 到 15 之间的整数时会被保留。其他任何值都会被丢弃,并输出一条以 with invalid light_emission. Expected an integer from 0 to 15; ignoring this value. 结尾的控制台警告。
  • 关闭了着色(shade: false)的立方体还会在生成的几何体中获得 shade_direction_override: "up",这样 Minecraft 26.3 客户端也会像旧版客户端一样以无着色方式渲染它。FMM 对同名显示模型 .json 中的立方体也应用相同规则。你自己设置的值会被保留

未分组的立方体​

在 outliner 顶部声明、不属于任何组的立方体,会以纯 UUID 字符串而不是骨骼条目的形式到达。FreeMinecraftModels 会把它们挂到自动生成的根骨骼(freeminecraftmodels_autogenerated_root)上,因此它们仍会被渲染。它们无法被动画寻址,所以任何你打算做动画的东西都要放进一个真正的组里。

IK、空对象和定位器​

当前代码确认支持:

  • Blockbench 空对象作为 IK 控制器
  • IK 链蓝图和运行时 IK 求解(FABRIK)
  • 定位器解析。定位器也可以作为 Blockbench 粒子效果的锚点;参见粒子

只有当空对象的 .bbmodel 条目同时包含 ik_source(源骨骼)和 ik_target(目标骨骼或定位器)时,才会成为 IK 控制器。导入器搜索层级,也包含同级和向下的搜索路径。根层级的同级节点会产生仅含源的链。lock_ik_target_rotation 会被读取并保存,但当前求解器并不应用它。

重要的实际限制:

  • 源/目标之间的关联是通过 UUID 建立的,因此重命名不会破坏它 —— 但如果任一 UUID 在模型中缺失,控制台会记录 IK chain in model <model>: Could not find source bone with UUID ... / Could not find target with UUID ...,并跳过该骨链
  • 如果搜索找不到从源到目标的路径,会记录 Could not find path from source to target 并跳过该链
  • 控制器的动画查找是基于名称的,因此控制器命名需要在模型结构和动画数据之间保持稳定
  • 只有位置关键帧驱动 IK,其偏移会加到目标骨骼或定位器的静止位置上,而不是保存的控制器静止位置。旋转和缩放轨道不会驱动 IK

关于 IK 是如何逐帧被驱动的,参见动画。

1.21.4+ 输出拆分​

FreeMinecraftModels 声明了 api-version: 1.21.4,因此 1.21.4 是最低服务器版本,你拿到的永远是现代的物品模型定义布局:

plugins/FreeMinecraftModels/output/FreeMinecraftModels/assets/freeminecraftmodels/items

旧版(1.21.4 之前)基于皮革马铠 override 的分支在代码中依然存在,但任何能加载当前插件的服务器都不会走到那里。如果你在看旧的笔记或旧的输出文件夹,你看到的差别就是这个。

展示模型 JSON(1.21.4+)​

管理员可以在 .bbmodel 或 .fmmodel 文件旁边放置一个同名的 .json 文件(例如 table.bbmodel + table.json)。此 JSON 应从 Blockbench 导出为"Java Block/Item"模型,定义物品在手持或在物品栏中显示时的外观。

FMM 读取活动模型旁的 JSON,将其复制到资源包,并重写 textures 映射中不带命名空间的值。数字纹理键对应模型已提取纹理的索引;未匹配的键会使用一个可用纹理(如果存在)。带命名空间的值保持不变。没有配套 JSON 时,物品使用基础材质的外观:装饰物放置物品通常为纸,手持物品则使用配置的材质。格式错误的配套文件会记录 Failed to process display model JSON for ...,且不会注册该显示模型。

YML 中的自定义物品配置​

在模型配套 YAML 中设置 material,即可注册手持物品:

isEnabled: true
material: DIAMOND_SWORD
name: "&6Flame Blade"
lore:
- "&7A blade with a fire enchantment"
enchantments:
- "minecraft:fire_aspect,2"

附魔 ID 应为小写且带命名空间。皮革材质接受 RGB 染色后缀,例如 LEATHER_CHESTPLATE:ff8800;参见配置。使用不支持的材质、无命名空间附魔或非空 scripts: 列表的物品不可用;控制台会说明原因,原文件则会保留。scripts: 仍仅用于装饰物。

其他无效定义,例如非布尔值 isEnabled、格式错误的附魔条目、重复附魔或无效物品文件名,可能导致候选目录和重载被拒绝。物品文件名应为小写,只含 a-z、0-9、.、_ 和 -,最长 128 个字符。自定义物品扫描读取 .yml,不读取 .yaml。通过 /fmm giveitem <item> 或管理员浏览器获取已注册物品;装饰物配方和商店购买产生的是纸质放置物品。

物品效果现在由附魔定义管理。魔杖和法杖使用魔法武器配置。两者都不使用旧的装备物品 Lua 运行时。

基岩版和渲染路径注意事项​

  • 基岩版支持取决于 sendCustomModelsToBedrockClientsV2(默认值为 true;替代了较旧的 sendCustomModelsToBedrockClients 键)以及周围的 Floodgate/Geyser/资源包路径
  • 受支持版本上的 Java 客户端可以在启用 useDisplayEntitiesWhenPossible 时使用展示实体渲染
  • 不要假设在 Java 客户端上显示正确的模型对您的基岩版路径自动安全

实用创作建议​

  • 保持文件名稳定,因为它们会成为运行时 ID
  • 保持控制器和动画命名明确,因为 Blockbench 动画查找是基于名称的
  • 按用途使用保留的虚拟骨骼名称(hitbox、tag_、h_、b_、m_)。只有碰撞箱上方的备用名牌位置不合适时,才添加 tag_ 锚点
  • 共享运行时状态使用小写 spawn、idle、walk、attack 和 death;攻击和死亡仍需要运行时触发,其他名称则需明确调用播放(参见动画)
  • 打算用于 /fmm disguise 的模型至少也应当附带 idle,还可以加上 sneak 和 jump,这两者只有伪装控制器才会识别(参见玩家伪装)
  • 在 /fmm reload 后验证导入的输出,而不仅仅是在 Blockbench 内部
  • 验证为目标 Minecraft 版本生成的包内容,尤其是 1.21.4+

弓和弩状态模型​

FMM 在生成资源包时自动检测弓和弩的显示状态。每个必需状态都要有已加载的模型文件,以及处理成功的配套显示 .json;仅有文件名并不足够。请用基础名称配置手持物品,并使用对应的 BOW 或 CROSSBOW 材质。

命名约定​

后缀用途弓弩
_idle手持物品,未拉弓或未装填必需必需
_draw_start刚开始拉弓必需必需
_draw_half拉到一半必需必需
_draw_full完全拉满必需必需
_charged已装填的弩(箭或火箭)--必需

弓需要四个模型(除 _charged 外全部)。弩需要全部五个。

示例文件布局​

plugins/FreeMinecraftModels/models/my_weapons/
cool_bow_idle.bbmodel
cool_bow_idle.json
cool_bow_draw_start.bbmodel
cool_bow_draw_start.json
cool_bow_draw_half.bbmodel
cool_bow_draw_half.json
cool_bow_draw_full.bbmodel
cool_bow_draw_full.json
cool_bow.yml

对于弩,还需添加 cool_bow_charged.bbmodel 和 cool_bow_charged.json。物品配置为 cool_bow.yml,使用不带 _idle 的基础名称。

检测机制​

  • 检测在资源包生成时(启动时或 /fmm reload)自动进行。
  • 完整的显示状态集会得到一个以基础名称命名的公开物品定义,例如 cool_bow.json。各个 _idle、拉弓和装填状态的物品定义会移除,但其几何仍由基础定义引用
  • 显示注册表公开基础 ID 并移除状态 ID。包含 _charged 的完整集合视为弩,不含则视为弓。缺少显示状态会阻止分组
  • YML 配置使用基础名称,例如 cool_bow.yml。物品目录会跳过带状态后缀的 YML 文件,装饰物配置查找也会去掉后缀

展示模型 JSON​

每个必需状态都必须有自己的配套显示 .json,例如 cool_bow_idle.json 和 cool_bow_draw_full.json。FMM 通过生成的基础物品定义连接它们。条件和输出路径请参阅资源包输出。

超出范围​

本页不尝试保证:

  • 确切的 Blockbench UI 步骤
  • 艺术工作流偏好
  • 旧版本地 README 材料中描述的每个遗留 .bbmodel 特性

这些细节的变化速度比上述已验证的运行时契约更快。