Skip to content

Validation & the GLB validator

The mod ships a structural GLB validator that inspects every item’s .glb model on each resource reload and reports problems before you find them as a broken render in-game. It’s a quick sanity pass, not a full glTF conformance checker — it reads the file’s header and JSON chunk only, and flags the handful of mistakes that actually break TiedUp! skinning.

The validator opens each GLB, reads the 12-byte header and the first (JSON) chunk, then inspects that JSON. It never decodes the binary mesh (BIN) chunk — no vertex positions, no weight values, no triangles. That keeps it fast and lets it run on every model every reload, but it also bounds what it can know:

ChecksDoes NOT check
Header magic / version / declared lengthPer-vertex weight sums (needs the BIN chunk)
A skins array exists and is non-emptyBone names / typos against the biped (see below)
inverseBindMatrices presence, type, countTriangle count / poly budget
WEIGHTS_0 / JOINTS_0 on the selected meshEmbedded textures / materials
Multiple non-Player meshes (ambiguity)UVs, normals, vertex colours
An Idle animation existsThe actual mesh geometry
Animation channels target real skin joints
  1. On client startup and on every resource reload (F3+T, or after /reload).
  2. It runs after the item parser, so the item registry is already populated — it validates the model GLB of every loaded data-driven item definition, not loose files on disk.
  3. Results replace the previous run’s results (the diagnostic registry is cleared first).

So the loop is: edit your GLB → F3+T → check the result. You don’t need to relaunch the game.

Three places, in increasing detail:

Log summary

Every reload logs one line under the GltfValidation logger: Validated N GLBs: X passed, Y with warnings, Z with errors.

Toast (errors only)

If any model has an error, a system toast pops: “N model(s) have errors. Run /tiedup validate”. Warnings do not toast.

/tiedup validate

The full per-file report, colour-coded, printed in chat. This is where you read the actual findings.

/tiedup validate # report every validated GLB
/tiedup validate <item_id> # report one model or item (e.g. mymod:models/gltf/binds/wrist_cuffs.glb)

Each finding prints as [SEVERITY] CODE: message, coloured red (error), yellow (warning). A file with no errors is headed green; a file with an error is headed red.

  • ERROR — the model is structurally broken; it sets the file’s status to failed and fires the toast. The runtime parser will likely choke or render nothing useful.
  • WARNING — the file loads, but something looks wrong and the result on the body probably isn’t what you intended (bind-pose render, dropped animation, etc.).

There is no INFO output in practice — every finding the validator emits today is an error or a warning.

CodeWhat it meansFix
MISSING_GLBThe item’s model resource location resolves to no file in any pack.Check the model path in the item JSON and that the .glb is actually shipped at assets/<ns>/models/gltf/<category>/.
INVALID_GLB_HEADERNot a valid GLB: bad magic, wrong version, truncated, or the first chunk isn’t JSON.Re-export as glTF Binary (.glb) — not .gltf (text), not a renamed .zip. A .gltf+.bin pair won’t pass; export the single binary .glb.
GLB_TOO_LARGEThe file declares a size over the 50 MB safety cap.Reduce mesh/texture size. A worn item should be a few hundred KB, not tens of MB.
GLB_READ_ERRORThe file existed but couldn’t be read/parsed.Re-export; the file is likely corrupt or partially written.
NO_SKINSNo skins array, or it’s empty. The mesh isn’t rigged to a skeleton.Select the mesh AND the armature before exporting, and enable skinning in the glTF exporter so a skin is written.
IBM_MISSING_TYPE / IBM_WRONG_TYPEThe inverseBindMatrices accessor has no type, or it isn’t MAT4.Re-export with the skin’s armature selected — these come from a malformed skinning export.
IBM_COUNT_MISMATCHThe number of inverse-bind matrices ≠ the number of joints in the skin.Re-export with the skin’s armature selected; don’t hand-edit the joints/IBM arrays out of sync.
CodeWhat it meansFix
IBM_MISSINGThe skin has joints but no inverseBindMatrices. The runtime substitutes identity → mesh renders in bind pose at the origin.Re-export with skinning enabled so the IBM accessor is written.
NO_WEIGHTSThe selected mesh’s first primitive has no WEIGHTS_0 attribute → skinning won’t deform correctly.Weight-paint the mesh to the armature and ensure the exporter includes vertex weights.
NO_JOINTSThe first primitive has no JOINTS_0 → every vertex binds to joint 0, so the item sticks to the root bone regardless of how you painted it.Same fix: paint weights and export with joint indices.
MULTI_MESH_AMBIGUITYMore than one non-Player mesh in the file — the parser can’t be sure which one is your item.Name your item mesh Item so it’s selected explicitly, or export a single mesh.
NO_IDLE_ANIMATIONNo animations array, or none named Idle.Usually harmless for a static item (the pose comes from EF-JSON, not the GLB). Only matters if you intended a baked rest pose — most items can ignore this.
ANIM_CHANNEL_NOT_IN_SKINAnimation channels target nodes that aren’t in the skin’s joints — the runtime silently drops them. The classic cause: keyframing the Armature object instead of its bones.In Blender, animate the bones, not the Armature object’s transform.

How “mesh selection” works (for the ambiguity / weight warnings)

Section titled “How “mesh selection” works (for the ambiguity / weight warnings)”

When the validator (and the runtime parser) pick which mesh in the file is your item, they use the same rule:

  1. A mesh literally named Item wins immediately.
  2. Otherwise, the last non-Player_* mesh in the file is used.

The WEIGHTS_0 / JOINTS_0 checks run against that selected mesh’s first primitive — so if you ship multiple meshes, name the real one Item to be sure the validator (and the renderer) look at the right one.

A typical static worn item — one skinned Item mesh, an armature, weights painted, exported as binary glTF — passes with no errors and at most a NO_IDLE_ANIMATION warning you can ignore. If you see that and nothing else, you’re good to equip and look. For anything that survived validation but still renders wrong (bone misplacement, flat-white surface, dropped joints at equip), continue to Common errors.