跳到主要内容

FreeMinecraftModels 资源包输出

FreeMinecraftModels 目前将其生成的资源包写入 output,而不是 outputs

默认输出路径

插件在启动时和执行 /fmm reload 时重建此文件夹:

plugins/FreeMinecraftModels/output/FreeMinecraftModels

随后将该文件夹打包为:

plugins/FreeMinecraftModels/output/FreeMinecraftModels.zip

该 zip 路径正是 ResourcePackManager 与 FreeMinecraftModels 集成时所期望的路径。

生成的内容

生成的文件夹始终包括:

  • pack.mcmeta
  • pack.png
  • assets/minecraft/atlases/blocks.json
  • assets/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 空间之前,会先被裁剪到源纹理自身的像素边界(0textureWidth / 0textureHeight)。有些 .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 下按骨骼生成的模型 JSON display

两者现在都使用保持插入顺序的 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 导出会先验证模型,并跳过没有纹理的实体,而不会发布不完整几何体。