Last week I posted about AniMate Waifu — a desktop companion that puts a VRM character on your desktop — and the three things that fought back while building it. This is the follow-up I promised: what actually breaks when users import their own models.
Short version: it's usually not the model.
Once your app accepts user-supplied files, you inherit every way a file can be wrong. Ours imports VRM 0.x and VRM 1.0 — files arrive from VRoid Studio, from Blender, and from conversion pipelines out of PMX and FBX. After enough "my model is broken" reports, a pattern shows up fast, and the pattern is not broken geometry.
Four checks before blaming the model
None of these involve the file, which is exactly why they're worth running first:
- Is the app current? Format support widens with releases. An import that fails on an old build may be a bug that's already fixed.
- Is the feature unlocked? In our app, custom import is the paid feature. Better to surface that before a user spends an evening debugging their model against a paywall.
-
Did the download complete? A truncated
.vrmis the single most common "corrupt file" report — and it's a download problem, not a model problem. Compare the file size against the source. -
Is it actually a
.vrmfile? Not.pmx, not.fbx, not a Live2D.model3.json, not a folder of textures. One file, ending in.vrm.
The rename trap
VRM is a profile on top of glTF 2.0, and renaming doesn't convert anything. A .pmx or .fbx renamed to .vrm still has the wrong bones and shaders inside. Plain glTF out of Blender renamed to .vrm is the same story — the extension alone doesn't make a file VRM, which is why the Blender path goes through the VRM add-on: it maps the humanoid bones and writes the VRM extension block.
Thirty-second check: rename a real .vrm to .glb and a glTF viewer will parse it (materials will look wrong — that's MToon, and that's fine). Rename a .pmx to .vrm and nothing will parse it at all.
What the symptoms are actually telling you
When the file genuinely is a VRM and it still misbehaves, the symptom usually names the cause:
| Symptom | Usual cause |
|---|---|
| Imports, then stands frozen | Humanoid bone mapping missing or non-standard — the mesh loads, the rig doesn't |
| Black, glowing, flat or invisible materials | Version mismatch: 0.x uses MToon, 1.0 uses MToon10 — a file exported as one version with materials authored for the other |
| No facial expressions | Blendshapes missing, or a 0.x/1.0 naming difference |
| Hair and skirt rigid | SpringBone physics stripped on export |
| Very slow | Polygon, material and physics weight — an overlay that renders all day punishes what a game engine forgives |
| Wrong size or facing the wrong way | Not a defect: models arrive at wildly different scales, so scale is the first knob, not a bug report |
The second row is the sneaky one: the file is internally consistent — it was just exported as one version with materials authored for the other.
Export settings beat modelling
If there's one takeaway, it's this: export configuration causes more import failures than the modelling does.
Exporting from VRoid Studio: confirm the humanoid rig, include expressions, keep SpringBone physics — and let VRoid reduce polygon and material counts on export, because at desk scale nobody sees the difference and the GPU notices. One more version note: current VRoid Studio dress-up exports are VRM 1.0 only, so this trap is getting more common, not less.
What we changed app-side
Two things, after enough of these reports. Parse at preview, before anything is committed — a bad file surfaces there with its reason, not after it's already in the library. And never open with "your file is broken": a meaningful share of those reports turn out to be something on our side. We keep the current version of the checklist in our VRM import guide, and issues and releases live in the GitHub repo.
Next
From last post's list, two candidates remain: the licensing side — which VRM models you can actually show and ship — and keeping a 3D overlay light enough to leave running all day.
If you've shipped an import pipeline, 3D or otherwise: what's the failure mode your users keep finding?
Top comments (0)