Skip to content

How the pack is built

Ember Forge builds one pack from every source, in a fixed order.

1. Merge base packs

Each zip in include-packs is merged underneath your items. Their dispatch tables are read structurally and folded into one table per base material.

This matters more than it sounds. The client's range_dispatch picks the nearest lower threshold, so an item whose exact id is missing from the pack a player has renders as some unrelated model — not as nothing. Everything has to live in one table or items quietly turn into each other.

pack.mcmeta from a base pack is not copied, but its overlay declarations are carried across. Overlays are how a pack ships different assets per client version; dropping the declaration leaves the overlay directories present but unreachable, which blanks every vanilla item the source pack touched.

2. Write dispatch tables

For every base material, one assets/minecraft/items/<material>.json:

{"model":{"type":"minecraft:range_dispatch",
  "property":"minecraft:custom_model_data",
  "entries":[{"threshold":20001,"model":{"type":"minecraft:model","model":"mypack:item/ruby"}}],
  "fallback":{"type":"minecraft:model","model":"minecraft:item/paper"}}}

The fallback is mandatory. Without it a plain paper — one with no custom model data — renders as nothing at all.

3. Copy namespaced assets

Only namespaces other than minecraft are copied, so a content pack can never overwrite a vanilla model for every player wearing the pack. Both layouts are read:

resourcepack/assets/<namespace>/...
resourcepack/<namespace>/...

Attempts to merge models/item, models/block, textures/item or textures/block into the vanilla namespace are refused and logged.

4. Merge fonts

assets/minecraft/font/default.json providers are merged rather than overwritten. Two packs shipping this file would otherwise fight, and one glyph set would vanish silently.

5. Validate, then publish

Every dispatch entry is resolved: model file, parent chain, every texture. An entry that cannot render is removed so the item falls back to its plain base material. A vanilla model override that cannot render is deleted so the client uses its own built-in model.

[EmberForge] Pruned 41 unrenderable item entr(ies) and 0 vanilla model override(s);
             1302 entries verified renderable.

References into the minecraft namespace that the pack does not ship are assumed fine — those are vanilla assets the client already has.

Determinism

Entries are written sorted, with a fixed timestamp of 1980-01-01. Identical input produces a byte-identical zip and therefore a stable SHA-1. If the hash changed on every rebuild, every client that already downloaded the pack would reject it.