FreeMinecraftModels 资源包输出
FreeMinecraftModels 目前将其生成的资源包写入 output,而不是 outputs。
默认输出路径
插件在启动时和执行 /fmm reload 时重建此文件夹:
plugins/FreeMinecraftModels/output/FreeMinecraftModels
随后将该文件夹打包为:
plugins/FreeMinecraftModels/output/FreeMinecraftModels.zip
该 zip 路径正是 ResourcePackManager 与 FreeMinecraftModels 集成时所期望的路径。
生成的内容
生成的文件夹始终包括:
pack.mcmetapack.pngassets/minecraft/atlases/blocks.jsonassets/freeminecraftmodels/...模型与材质输出
对于 Minecraft 1.21.4+,FreeMinecraftModels 在以下路径生成 item-model 定义文件:
assets/freeminecraftmodels/items
对于较旧的服务器,它会回退到老式的皮革马铠覆盖模型路径。
Display 模型输出(1.21.4+)
当模型存在同名的 .json display 模型文件时(参见 模型制作说明),FMM 会将该 JSON(其中的材质引用已被改写为与提取的材质相匹配)复制到:
assets/freeminecraftmodels/models/display/{modelId}.json
它还会在以下位置生成对应的物品定义:
assets/freeminecraftmodels/items/display/{modelId}.json
DisplayModelRegistry 在运行时追踪哪些模型拥有 display JSON,以便可以对 ItemStack 调用 ItemMeta.setItemModel(),给予它们正确的手中与背包外观。
基岩版自定义实体资源包
除了 Java 资源包资源之外,FreeMinecraftModels 还会为每一个转换后的模型导出一份基岩版自定义实体资源包,位置在:
plugins/FreeMinecraftModels/output/FreeMinecraftModels/assets/freeminecraftmodels/rspm_bedrock_pack
每个模型都会贡献它的贴图、几何体、渲染控制器、动画、动画控制器以及实体定义,全部位于 freeminecraftmodels: 命名空间下(freeminecraftmodels:<model_id>)。
制作模型时值得注意的几点:
- 没有贴图的模型会被跳过,控制台会输出
Skipping Bedrock custom entity export for <id>: model has no textures. - Bedrock 几何排除骑乘点骨骼 (
m_)、自动生成的名称骨骼 (fmm_nametag_bone_*) 和hitbox。作者创建的tag_锚点仍保留在几何中,通常不含方块。 - 没有任何动画的模型仍会导出一个
idle动画槽
弓与弩条件式物品输出
当 FMM 检测到一组弓或弩状态模型时(参见 模型制作说明),它会为 _idle 模型生成单个物品定义 JSON,在资源包层面条件性地在所有状态之间切换。服务端无需任何数据包处理 —— 客户端原生处理状态转换。
弓的输出
对于弓,生成的物品定义使用 using_item 上的 minecraft:condition,并在 use_duration(缩放 0.05)上使用 minecraft:range_dispatch:
| 条件 | 使用的模型 |
|---|---|
| 未使用物品 | _idle |
| 正在使用,回退(刚开始) | _draw_start |
正在使用,阈值 0.65 | _draw_half |
正在使用,阈值 0.9 | _draw_full |
弩的输出
对于弩,生成的物品定义在 charge_type 上使用 minecraft:select。当装填完成(箭矢或烟花火箭)时显示 _charged 模型。未装填时的回退使用 crossbow/pull 上的 minecraft:range_dispatch:
| 条件 | 使用的模型 |
|---|---|
| 未使用、未装填 | _idle |
| 正在使用,回退(刚开始) | _draw_start |
正在使用,阈值 0.58 | _draw_half |
正在使用,阈值 1.0 | _draw_full |
| 已装填(箭矢或烟花火箭) | _charged |
输出位置
生成的条件式物品定义会与其他物品定义一同写入:
assets/freeminecraftmodels/items/display/{baseModelId}_idle.json
只有 _idle 模型会得到物品定义文件。拉弓与已装填的模型作为条件项被引用在其中。
Minecraft 26.1+ 兼容性修复
资源包生成器为 Minecraft 26.1 及更新版本自动应用两个兼容性修复:
- UV 裁剪: 面的 UV 在被重新缩放到 Minecraft 的 16x16 UV 空间之前,会先被裁剪到源纹理自身的像素边界(
0–textureWidth/0–textureHeight)。有些.bbmodel作者会在面上留下负值或超出范围的 UV —— 图集被调整了尺寸、autouv 越过了边缘等等 —— 而 26.1 更严格的验证器会拒绝它们。裁剪让模型得以烘焙;UV 越界的面最多损失几个像素的纹理细节。 - 跳过空骨骼与仅作锚点的骨骼: 没有立方体的骨骼不会写出几何 JSON,因此为它写物品模型定义会留下一个悬空引用。1.21.x 会默默容忍这种情况;26.1+ 则会把每一个都记录为
Missing block model: freeminecraftmodels:...。生成器现在会同时跳过这类骨骼的几何文件和物品定义。这也涵盖了hitbox骨骼(仅用于碰撞)、tag_name位置锚点、FMM 自动生成的fmm_nametag_bone_*变体,以及纯粹的包装/锚点骨骼。
这些修复会自动应用,无需任何配置。
正是因为这些骨骼会被跳过,tag_ 名牌骨骼才从来不需要立方体 —— 它是一个位置锚点,生成器有意不为它写出任何东西。参见 名牌需要一个 tag_ 骨骼。
确定性输出
生成的资源包是字节级稳定的:从未变更的模型重新生成它,会产出完全相同的 zip,因而 SHA1 也完全相同。
这一点很重要,因为当某个资源包的 SHA1 已经与远程主机上的一致时,ResourcePackManager 会跳过重新上传。如果字节不断变动,这项检查就永远匹配不上,RSPM 会在每次重启时重新上传,而每位玩家都要重新下载一个内容其实没变的资源包。
生成器中有两处会把 JSON 直接写到磁盘,因此它们的 map 迭代顺序就是文件的字节顺序:
assets/freeminecraftmodels/items下按骨骼生成的物品模型定义assets/freeminecraftmodels/models下按骨骼生成的模型 JSONdisplay块
两者现在都使用保持插入顺序的 map。此前它们使用的是 Map.of,其底层是 java.util.ImmutableCollections —— 它会生成一个每个 JVM 独立的随机盐值,并从依赖该盐值的下标开始探测,因此每次服务器启动时,同样那几个键的输出顺序都不一样。诸如 translation / scale,以及 type / index / default 之类的键在每次启动时互换位置,毫无理由地重写了每一个物品定义和每一个模型文件。
如果你以前遇到过什么都没改、玩家却在每次重启后都要重新下载资源包的情况,原因就在这里。
只有在你的模型集未发生变化时确定性才成立。新增、移除、重命名或编辑模型都会合理地改变资源包字节,并且应当触发一次重新上传。
重载行为
当 FreeMinecraftModels 重载时,它会:
- 重新执行内容导入步骤
- 重建
output/FreeMinecraftModels文件夹 - 重新生成
output/FreeMinecraftModels.zip - 若安装了 ResourcePackManager,则派发
resourcepackmanager reload
这就是为什么现代的 FMM + ResourcePackManager 配置不再需要老式的手动 zip 复制流程。
成功重建后会发出 FmmReloadedEvent。Bedrock 导出会先验证模型,并跳过没有纹理的实体,而不会发布不完整几何体。