QUEST LOG · September 7, 2026· UPDATED October 29, 2026
How Is Your Work Worse Than GPT's? Burning 1.4 Billion Tokens to Rig a Live2D Girl (v1)
The most infuriating complaint I made in the session: "Sure, all the features are there, but what I wanted was a range of motions, not her eyes shooting off her face."
The session that burned the most tokens this month wasn't for work, and it wasn't for a hackathon. It was for the little Live2D girl in the bottom-right corner of this blog.
Three-plus days, four context blowouts and restarts, and one session that ate roughly 1.47 billion tokens (though the vast majority were cache reads; output was about 2.8 million). In the end she can blink, turn her head, and wave. The process was basically me cursing the whole way, the AI apologizing the whole way, and then redoing everything the whole way.
(If this part reads very AI, that's because I fucking had the AI tally up the numbers.)
First, who she is. Her name is 希夜 Kiya, and she's my adorable daughter.
How she came to be is actually kind of funny: I got an NFT, and then the team rug-pulled. The more I thought about it, the angrier I got. If the project won't give this image any utility, I'll give it utility myself. So I first used NovelAI to test Image2Image and made the first version of her avatar. The very first Live2D version was a way to test what Gemini could do, and to let her stand in the bottom-right corner of the blog while I was at it. It was the first batch I produced back when gemini-cli usage was still basically unlimited and, paired with agy, you could generate images endlessly.
This post documents the first version built on the new architecture. She's still being tuned, and there will probably be another post later. This is no longer the Gemini era, where "it moves" was good enough.
# Round 1: The model isn't broken. It just never moved.
The initial request was simple: I had an older 12-15-daughter1.cmo3 on my desktop and Cubism Editor installed, and I wanted a version that the free edition could open. That older version had been made the easy way: borrow another open-source Live2D rig and do a simulated fine-tune on top of it. Usable, but it fell apart if you looked closely. A toy, in the end.
When the AI opened it in the Editor, the only thing over the FREE limit was the parameter count: 53, with a cap of 30. After deleting 28 "empty parameters" it was down to 26. Everything else, the deformers, ArtMeshes, and parts, was already within limits. Makes sense, since that version had been built by swapping the textures on someone else's model.
But!!!!! Then, almost in passing, it discovered something hilarious:
The model isn't broken, but the one on the blog has never actually moved.
My inner monologue reading that was: holy crap, holy crap, so what the hell was all that stuff I painstakingly exported back then? I read your conclusion and understood none of it.
The culprit turned out to be this: the blog's live2dAnimator.ts drives standard IDs like ParamAngleX, ParamEyeLOpen, and ParamMouthOpenY, and in the old model those IDs happened to be exactly the 28 empty parameters. The ones actually bound to anything were old Cubism 2.1-style IDs like PARAM_ANGLE_X.
In other words, from the day this mascot went live, she had always been a still image. I never noticed. I could cry. I even needed the AI to check the versions for me.
So much for Live2D. She spent quite a while on the blog as a static character portrait.
# Round 2: The result is absolutely terrible
I swapped in the new model (gpt) and deployed it. The head turned, the eyes followed, the hair tips swayed. Feature-wise, it was all there.
Then I took one look, and her eyes had drifted up onto her hair. So I grilled the AI:
The result is absolutely terrible, you didn't do any fine-tuning at all
It took that seriously and went off to research: is there an MCP for Live2D? No. Nothing on the MCP registry, and the two on GitHub either control a desktop player or use GUI automation to click around the Windows version of the Editor. From Cubism 5.1 onward there's an official WebSocket external API (port 22033), but it can only read the model structure and temporarily set parameter values; it can't change deformers, keyforms, or meshes.
So rigging can only be done in the Editor's GUI. That left exactly one path: computer use, letting the AI click around that Java window by itself.
For the next few hours, the transcript looked roughly like this:
- "The sub-dialog is stuck (clicks / Escape / accessibility all unresponsive)"
- "The sub-dialog froze again (both times right after scrolling inside the dialog)"
- "The parameter row is off by one again (it changed 'Mouth Deform' instead)"
- "The Editor is stuck on an invisible modal dialog (every menu is grayed out), so I restarted it"
An AI wrestling a Java Swing window, and losing, over and over.
Still, it really did produce v4: pupils that move inside the whites of the eyes via a clipping mask, highlights on their own layer, the mouth split into upper lip, lower lip, and mouth interior, 2048 textures, and a set of Tap motions. It also fixed the "two hands show up" problem along the way. The cause was that the jacket in the original illustration had actually been drawn three times.
Sounds pretty complete, right?
# Round 3: Her whole body is like jelly
You know you accidentally cranked the whole parameter effect so she's now jelly from head to toe, and the joints at her hands are broken too, right
The AI used Cubism Core to sweep every parameter to its extremes. The result: at Body Rotation Y = −10, the torso stretched 3.8× and shifted down by 1700px.
1700px. The entire image isn't much taller than that.
It fixed that, I had it open the simulator so I could look for myself, and then I listed ten points:
- The tap motion is wrong, her head flips backward
- Turning her head makes her face go flat
- When she blinks the eyes just vanish, and the eyebrows disappear
- The bangs effect jumps around, wtf?
……- You cut the image up any which way, her upper and lower body literally peel apart
Did you even look up anyone else's tutorial? How is your work worse than gpt's
I meant that line when I sent it.
Opus 5.5 wasn't out yet, and this session was running mainly on Fable 5.1. And GPT 6 astra was genuinely strong during that period. Its computer use was flat-out unbeatable. For work that's all about clicking a GUI over and over, the comparison was completely fair.
# Cause of death: using one hammer on every nail
This time it finally stopped and laid out the root causes first, and it was honest about it:
Cause of death 1: treating "Apply 3D Rotation Expression" as a universal keyform generator. Head turns, blinks, mouth, eyebrows, body: all done with the same dialog. All it does is rotate each part in 3D as if it were a flat card. So turning the head flattened the face, nodding flipped the whole head back like a card, and blinking squashed the eye into a line instead of bringing the eyelid down.
Cause of death 2: rigid rotation for the hair. The bangs rotated as one piece around a single point, which is exactly what "jumping around" looks like.
Cause of death 3: never looking at the render parameter by parameter. It used Core to check vertex numbers, but never rendered each parameter at its extremes to actually look at it.
The third one hurts most. It kept verifying "are the numbers right," not "does it look right." A month later, when I was making AI animation, every automated check came back PASS and I still didn't want to watch the result. Same exact trap, all over again.
Only after that did it go read the official manual and community tutorials, writing up its findings in three documents that flatly pronounced v4 dead:
- The official docs state outright that "Apply 3D Rotation Expression" overwrites keyforms, and is only recommended for objects with no keyforms yet
- "Auto-generate Sway Motion" only supports warp deformers; rotation deformers are explicitly unsupported
- For hair physics, there are numbers you can copy straight from the official sample: a two-segment pendulum, lengths 10/7, ease 0.95/0.86……
And one thing I hadn't thought of myself: the infinite jelly in web tracking happens because pixi-live2d-display 0.4's focus() converts the cursor position into a unit vector with atan2. Whether you're 5px or 500px from the center, it's a full ±30° deflection. And there's no handling for the mouse leaving, so the model never returns to center.
The research that should have come first only happened in Round 3. Everything burned before that was tuition.
# Round 4: v5 is ruined, go back to v4
After the research, it re-cut the PSD according to plan and built v5. The first pass at the bangs hard-cut them into straight wedges; the session log has me asking "what the hell is a long bundle." The second pass traced along the hair strands instead, and that one I thought was right.
Then it blew up again after importing into the Editor:
I think you should just tune v4, this version is almost completely ruined
And what the hell did you cut, none of your edge cleanup is clean, the eyes had the fewest problems to begin with and you made them way worse
It owned it: the v5 cuts only used an alpha threshold plus dilation. No defringing, no cleaning up stray islands, no edge tightening. The eyes were cut well in v4 to begin with and should never have been re-cut.
So v6 was "v4's eyes + v5's research." This time, after every step it exported the moc3 and rendered it with an offline renderer it wrote itself, and I checked before it went further. Along the way we hit a classic pitfall:
The Editor writes slider values as parameter defaults
At export time the right eye's open/close slider happened to be sitting at 0, so in her idle state she had one eye shut.
# Handing off to GPT, then taking it back
Halfway through, I told it to write a handover "in the simplest words possible" so I could pass it to gpt 6 astra, for the reason above: its computer use was stronger. Claude wrote a docs/handover.md.
Then I came back and told it "fix this for me," and the moment it opened things up it noticed:
The Editor was relaunched by someone and a new
v7/folder exists next to v6
It didn't just overwrite anything. It first checked what had actually changed on disk before touching it. Two AIs taking turns on the same Editor, and neither broke the other's work. Honestly I think that's rarer than the rigging itself.
The last few rounds were the arms: drag the elbow's rotation pivot onto the joint, let the forearm fold to 150°, keep the hand from flinging off the canvas while waving. Along the way it stepped on yet another one, "the select-all shortcut applied opacity to every single mesh," and had to roll back to a saved file.
# TLDR
- With a tool that has no API, the AI is just suffering alongside you with a mouse. Cubism Editor can't edit rigging programmatically, so every keyform was clicked out via computer use, and every invisible dialog meant another restart
- Research first, then build. The most expensive mistake this time was only reading the official manual in Round 3. The first two rounds used automation features to cobble together something where "all the features are there"
- Verify "how it looks," not "the numbers." Every vertex coordinate was reasonable, and she was still jelly. Writing your own offline renderer to output images beats any numeric check
- Don't redo the parts that are good. v5 died because it re-cut the eyes, which had been the least problematic part
Bottom line: this session burned 1.4 billion tokens not because Live2D is that hard, but because I let it skip the "understand it first, then do it" step, and then spent three days of back-and-forth making up for it.
AI is great at apologizing, but apologies don't make her bangs float.
At least now, if you tap her, she waves. An NFT from a rug-pulled project finally came to life on my blog, and this utility, at long last, is one I gave her myself.
That's it for the first version; Kiya is still being tuned. I'll write again once the next version is done.
Apps I ship
Free on iOS and Android.


