Skip to main content

FreeMinecraftModels Resource Pack Output

FreeMinecraftModels currently writes its generated pack into output, not outputs.

Default Output Paths

The plugin rebuilds this folder during startup and on /fmm reload:

plugins/FreeMinecraftModels/output/FreeMinecraftModels

It then zips that folder into:

plugins/FreeMinecraftModels/output/FreeMinecraftModels.zip

That zip path is the one ResourcePackManager expects when it integrates with FreeMinecraftModels.

What Gets Generated

The generated folder always includes:

  • pack.mcmeta
  • pack.png
  • assets/minecraft/atlases/blocks.json
  • assets/freeminecraftmodels/... model and texture output

FreeMinecraftModels generates item-model definition files under:

assets/freeminecraftmodels/items

A legacy leather-horse-armor override path still exists in the code for pre-1.21.4 servers, but the plugin declares api-version: 1.21.4, so no server that can load it takes that branch.

Display Model Output (1.21.4+)

When a model has a sibling .json display model file (see Model Authoring Notes), FMM copies that JSON (with texture references rewritten to match the extracted textures) into:

assets/freeminecraftmodels/models/display/{modelId}.json

It also generates a corresponding item definition at:

assets/freeminecraftmodels/items/display/{modelId}.json

The DisplayModelRegistry tracks which models have display JSONs at runtime so that ItemMeta.setItemModel() can be called on ItemStacks to give them the correct in-hand and inventory appearance.

Bedrock Custom-Entity Bundle

Alongside the Java pack assets, FreeMinecraftModels exports a Bedrock custom-entity bundle for every converted model into:

plugins/FreeMinecraftModels/output/FreeMinecraftModels/assets/freeminecraftmodels/rspm_bedrock_pack

Each model contributes its textures, geometry, render controller, animations, animation controllers, and entity definition, all under the freeminecraftmodels: namespace (freeminecraftmodels:<model_id>).

Notes that matter when authoring:

  • A model with no textures is skipped, with Skipping Bedrock custom entity export for <id>: model has no textures. in the console
  • The Java importer still accepts that texture-less definition; the explicit skip applies only to its Bedrock custom-entity bundle entry
  • Bedrock geometry excludes mount-point bones (m_), generated nametag bones (fmm_nametag_bone_*), and hitbox. Authored tag_ anchors remain in the geometry, often without cubes.
  • A model with no animations still exports a single idle animation slot
  • Runtime hitbox width/height for the Bedrock entity come from the model's hitbox bone; without one it falls back to 1.0 x 2.0

The Bedrock runtime backend requires an enabled plugin named floodgate, Geyser-Spigot, or Geyser. Name matching ignores case; a different plugin name does not match. On a Java-only server, FMM still exports the bundle files but does not construct or tick that backend.

Bow And Crossbow Conditional Item Output

When FMM detects a set of bow or crossbow state models (see Model Authoring Notes), it generates a single item definition JSON for the _idle model that conditionally switches between all states at the resource-pack level. No server-side packet work is needed -- the client handles state transitions natively.

Bow Output

For bows, the generated item definition uses minecraft:condition on using_item with a minecraft:range_dispatch on use_duration (scale 0.05):

ConditionModel used
Not using the item_idle
Using, fallback (just started)_draw_start
Using, threshold 0.65_draw_half
Using, threshold 0.9_draw_full

Crossbow Output

For crossbows, the generated item definition uses minecraft:select on charge_type. When charged (arrow or rocket), it shows the _charged model. The uncharged fallback uses minecraft:range_dispatch on crossbow/pull:

ConditionModel used
Not using, not charged_idle
Using, fallback (just started)_draw_start
Using, threshold 0.58_draw_half
Using, threshold 1.0_draw_full
Charged (arrow or rocket)_charged

Output Location

The generated conditional item definition is written alongside other item definitions at:

assets/freeminecraftmodels/items/display/{baseModelId}_idle.json

Only the _idle model gets an item definition file. The draw and charged models are referenced inside it as conditional entries.

Minecraft 26.1+ Compatibility Fixes

The pack generator applies two automatic compatibility fixes for Minecraft 26.1 and newer:

  • UV clamping: face UVs are clamped to the source texture's own pixel bounds (0textureWidth / 0textureHeight) before being rescaled into Minecraft's 16x16 UV space. Some .bbmodel authors leave negative or oversized UVs in faces — an atlas got resized, autouv overshot the edge, and so on — which 26.1's stricter validator rejects. Clamping lets the model bake; a face with out-of-bounds UV loses at most a few pixels of texture detail.
  • Empty and anchor-only bones are skipped: a bone with no cubes writes no geometry JSON, so writing an item-model definition for it would leave a dangling reference. 1.21.x tolerated that silently; 26.1+ logs every one as Missing block model: freeminecraftmodels:.... The generator now skips both the geometry file and the item definition for such bones. This also covers hitbox bones (collision-only), tag_name positional anchors, FMM's auto-generated fmm_nametag_bone_* variants, and pure wrapper/anchor bones.

These fixes apply automatically; no configuration is required.

note

Skipping those bones is why a tag_ nametag bone never needs cubes — it is a positional anchor, and the generator deliberately writes nothing for it. See Nametags Require A tag_ Bone.

Deterministic Output

The generated pack is byte-stable: regenerating it from unchanged models produces an identical zip, and therefore an identical SHA1.

This matters because ResourcePackManager skips re-uploading a pack whose SHA1 already matches what the remote host has. If the bytes churn, that check never matches, RSPM re-uploads on every restart, and every player re-downloads a pack whose contents did not change.

Two places in the generator write JSON straight to disk, so their map iteration order is the file's byte order:

  • the per-bone item-model definitions under assets/freeminecraftmodels/items
  • the per-bone model JSON display block under assets/freeminecraftmodels/models

Both now use insertion-ordered maps. Previously they used Map.of, which is backed by java.util.ImmutableCollections — that seeds a per-JVM random salt and probes from a salt-dependent index, so the same handful of keys came out in a different order on every server start. Keys such as translation / scale, and type / index / default, swapped places on each boot, rewriting every item definition and every model file for no reason.

If you previously saw players re-downloading the resource pack after every restart even though you changed nothing, this was why.

note

Determinism only holds if your model set is unchanged. Adding, removing, renaming, or editing a model legitimately changes the pack bytes and should trigger a re-upload.

Reload Behavior

When FreeMinecraftModels reloads, it:

  • tears down active models, props, disguises, script runtimes, listener state, and script cooldown stores before rebuilding them
  • re-runs the content import step
  • rebuilds the output/FreeMinecraftModels folder
  • regenerates output/FreeMinecraftModels.zip
  • dispatches resourcepackmanager reload if ResourcePackManager is installed
  • fires FmmReloadedEvent on the primary thread after the new initialization completes, so dependent plugins can recreate model attachments

This is why modern FMM + ResourcePackManager setups no longer need the old manual zip-copy workflow.