The proxy proved it; Meshy delivered it — Mixamo was never in the chain

The balance call returned 3,105 credits. That was confirmation the Meshy API key had actually landed in the Keychain, stored under meshy-api-key and retrieved via the standard Keychain workflow, verified with a live API hit before any mesh generation was attempted. Everything downstream was waiting on that number: the real Cj avatar, the rig, the Godot integration.

The proxy had been standing in since 2026-09-02. Capsule parts, human proportions, twenty-two mixamorig: bones placed correctly, five VRM-named face shape keys. Godot was already animating it through walk and idle cycles. The whole point of building the proxy first was to decouple mesh delivery from pipeline readiness: prove the animation system, the bone naming, and the Godot importer against something disposable, then swap in the real mesh when it arrived without touching anything downstream.

On 2026-09-03, the real avatar arrived. The proxy stepped offstage. Godot did not notice.

The plan that didn’t survive contact

The P0 bootstrap entry on 2026-09-01 named the intended chain: image-to-3D → Blender → Mixamo → Godot. In practice that’s more stops. The full sequence runs source images through an image-to-3D service, then Blender for cleanup and weight painting, then Mixamo’s auto-rigger, then an export step, then a format conversion step before Godot gets a file it can use. Five to seven steps depending on how you count, with Mixamo sitting in the middle as a black box that takes a mesh and returns a rigged one using its own format and conventions.

Mixamo’s auto-rigger produces usable results when the mesh cooperates. When it doesn’t, you end up correcting the rig in Blender anyway. The failure modes are familiar: topology too dense, proportions outside its assumptions, a mesh from an image-to-3D service that wasn’t built to Mixamo’s input preferences. The black box becomes a dependency with failure modes you can’t inspect.

The decision to try skipping Mixamo was made at P0. Not because there was evidence the auto-rigger would fail on this specific mesh, but because the mixamorig: bone naming convention Mixamo popularised is a convention, not a capability Mixamo owns. Godot’s humanoid importer understands those bone names. Any tool that produces a skeleton using them gets the same result in Godot. Mixamo is one such tool. Blender, given the right script, is another.

The proxy and what it established

Improving on the proxy rig that made Mixamo optional: that piece documented the proxy as proof-of-concept. This article is what the proof-of-concept produced.

blender/cj/proxy_rig.py generated a humanoid stand-in from Blender’s bmesh primitives: twenty-two bones named to the mixamorig: spec, skinned capsule geometry at human proportions, and five VRM-named shape keys for facial animation. The proxy had no artistic value; it had structural value. It existed so Godot could be set up and verified against a skeleton with the right interface before any Meshy credits were spent.

P4 was the gate before the real mesh was commissioned: the animation chain proven end-to-end on the proxy. Walk cycle running, idle cycle running, the Godot import confirmed, bone-name mismatches flushed. That all happened on the proxy. The Meshy call came after.

The proxy run wasn’t a separate phase to gatekeep an arbitrary milestone. It existed because P4-proven meant every downstream assumption had been validated before anything expensive was asked for. Cheap iteration first, costly generation second. That sequencing was deliberate from the start.

What Meshy does and where Blender comes back in

tools/meshy.py is stdlib-only. Seven tests, no external dependencies beyond the API itself. It wraps Meshy’s image-to-3D endpoint: reference images in, a mesh with skeleton data out.

“Rigged mesh out” from Meshy doesn’t mean “ready for Godot.” Meshy returns skeleton data in its own bone naming conventions. A raw Meshy export doesn’t map cleanly onto Godot’s humanoid import profile without adjustment. This is where Blender re-enters the chain, not to replicate what Mixamo would have done, but to perform a naming retarget: take the Meshy skeleton, map it to mixamorig: names, confirm the import against the same Godot project the proxy had already passed through.

That’s predictable work: one Blender session, one confirmed mapping. The proxy run had established exactly what the output needed to look like. There was no ambiguity about success criteria going in.

The old five-tool chain ran source images through image-to-3D, Blender cleanup, Mixamo rigging, format conversion, then Godot import. It becomes: Meshy, Blender, Godot. Two tools doing the work. Godot is the destination, not a pipeline step.

The sequencing argument

The proxy wasn’t a workaround. It was the cheapest way to validate every assumption before committing to the expensive step.

3,105 credits at the time the API key was verified. Mesh generation consumes credits. Discovering mid-pipeline that the bone naming is off, or that the Godot import fails for a reason the proxy could have surfaced, and then regenerating: that costs credits a second time plus the round-trip wait for the API. The proxy costs scripting time. The Meshy redo costs money and time together.

This is the general principle. Any pipeline with a billable or slow step in the middle benefits from proving the downstream with something cheap before committing to the expensive upstream. Sequence them correctly and the first Meshy call is the only one. Sequence them wrong and the second call teaches you what the first one should have been.

What Godot saw

A file replacement. The animation controller that had been driving the proxy’s walk and idle animations was pointing at bone names in the scene. The proxy’s export was replaced by the real avatar’s retargeted export. Godot re-imported. The bone names matched. The controller found what it was looking for and continued operating.

No modification to the animation controller, no adjustment to import settings, no change to the scene structure. The proxy-to-real swap was designed to be invisible to Godot, and it was. This is the value of agreeing on an interface before building either side of it. The mixamorig: bone naming spec was that interface. Both the proxy and the real avatar were built to honour it. Godot consumed both without revision.

If the retarget had produced a naming mismatch, Godot’s humanoid importer would have flagged missing or unrecognised bones at import time. That’s a loud failure, not a silent one. The proxy run had already flushed that failure mode. By the time the real avatar arrived, the only acceptable outcome was a clean import, and that’s what happened.

Out of scope

Mixamo was never run. The decision was conditional on the proxy proving the pipeline, and the proxy did. This isn’t a claim that Mixamo would have failed on this mesh. It’s a statement that the dependency was unnecessary.

Weight painting adjustments made during the Blender retarget are not documented here. The specifics depend on the mesh Meshy returned and sit inside the retarget session, not the pipeline design.

The wider EVA Music visualiser context exists as the live environment the avatar now inhabits: the studio set, the beat clock, the audio reactivity built in the same sprint. That’s not the subject of this article. The scope was the pipeline from reference images to rigged, imported, animating character.

The ledger

Real Cj avatar in the scene from 2026-09-03. Same animation controller. Same bone spec. tools/meshy.py: stdlib-only, seven tests, Keychain-sourced API key verified at 3,105 credits. blender/cj/proxy_rig.py established the interface. The retarget was one session.

Five tools planned. Two used. Godot unchanged.

All writing