#vmdl
18 items (18 fixes)
Two-stage flow: Blender headless emits Y-up OBJ, then pure Python writes vmats/vmdls and a C# model catalog.
An AnimFile whose name contains a hyphen never reaches the compiled model. The fbx bakes, the animation list writes, the vmdl compiles green with no errors and no warnings, and the sequence is simply absent at runtime. The SkinnedModelRenderer.Sequence.Name setter accepts the missing name and echoes it back, so the obvious guard cannot fire. Sanitise the typed name to one hyphen-free word, and check Sequence.SequenceNames before you assign.
A PhysicsHullFile node compiled with import_mode HullPerElement treats a material break as an element boundary. Paint two adjoining primitives with a second material and the compiler folds them into one element and builds one convex hull across both. The convex hull of a wall with a hole in it is a solid wall, so every doorway and window built the same way seals shut at once, with no geometry change in the diff. Every offline check stays green, because none of them compile the model. The defect is only visible in the compiled collision, which the editor or an in-engine walk probe can see. Fix by giving physics its own single-material copy of the source mesh, so the render mesh's material list never reaches the physics node, and pin the physics mesh to the render mesh with a lint.
ERROR models or white materials persist after fixing the source: delete the compiled artifact AND touch the source file to force recompilation, or poke asset_compile per source file.
Forge delivery job errors out but the build stage's previewGlbUrl stays downloadable: recover the GLB through Blender into your standard delivery shape instead of re-spending.
The render node in a vmdl honours import_rotation. PhysicsHullFile and PhysicsMeshFile ignore it. So correcting an off-axis import with import_rotation fixes the picture and leaves the collision exactly where it was. The model builds clean with no error and no warning, photographs correctly, and a player walks straight through it. Bake a corrected engine-frame copy of the mesh that both the render node and the physics node read, rather than rotating one consumer with a property the other ignores.
CC0 kits import like any OBJ+vmdl; city kits share colormap.png, nature kits need per-color vmats, and facing is a per-model yaw guess.
Model.Load of a missing vmdl can return the orange ERROR mesh with the requested path as its Name: check IsError, not just null. And a failed load is cached for the life of the editor PROCESS: play_stop/play_start won't clear it, only a fresh editor will.
RenderMeshFile alone compiles clean with zero physics: ModelCollider needs PhysicsMeshFile/PhysicsHullFile in the vmdl.
Blender +X becomes world −Y after OBJ import; yaw +90° faces +X, and Blender +Y rotation tips the +X edge down.
CapsuleCollider and ModelCollider ignore WorldScale; BoxCollider follows it. Bake scale into import_scale instead.
A PhysicsShapeList node compiles with several tagged PhysicsHullFile children, so one vmdl can carry a compound collision volume. The per-shape tags stay inert through a scene ModelCollider.
A multi-hull vmdl authored with per-shape collision_tags does not get those tags at runtime -- a scene ModelCollider overwrites every shape with the GameObject's own tags, so Scene.Trace.WithoutTags can't filter one hull from another. Split the hulls across separate collider GameObjects instead.
PhysicsShapeList + PhysicsJointList in the vmdl + ModelPhysics toggle. No collapse clips, no SetBoneTransform. On current builds ModelPhysics.PhysicsGroup reads NULL: enumerate ModelPhysics.Bodies directly and resolve bones by name→index.
Scenes never load raw OBJ/GLB: always wrap with a .vmdl and remap materials under both bare and .vmat names.
Model compiler rewrites upper_arm.L → upper_arm_L; physics KV3 that still says .L makes limb bodies unknown while the torso works.
Default −Z/Y axes, bake_space_transform, no leaf bones, X/Z bone axes, mesh FBX + per-clip armature FBX; scale via ScaleAndMirror 0.3937.
AI mesh generators (Tripo, Meshy, Rodin) deliver textured OBJ+vmdl, but modeldoc32 headers, ~1m normalize, corrupt textures, bare texture paths, and missing colliders will ERROR the asset until patched.