I build a browser flight brawler in my own time. Characters fly, grab each other in the air, and throw. The numbers that describe a character's shape at a given moment, the poses, lived in two places: the game runtime and the pose editor I built to tune them.
This is a content pipeline bug with a very long history, and knowing about it did not save me from writing it.
How the drift showed up
On one pose, a three point landing, the hip height was 2.184 in the game and 0.18 in the editor. The game version had been hand tuned over weeks of play. The editor version was the original.
So exporting from the editor, which is the thing the editor is for, reverted weeks of tuning. Quietly, because a pose that is slightly wrong still looks like a pose.
Collapsing to one copy
Forty one poses went into a single file that both the game and the editor read. The important detail is how the numbers got there: not by retyping them.
Retyping forty one poses with a dozen joints each is several hundred transcription opportunities. I wrote a script that walked the game source, balanced brackets, and pulled each literal out verbatim. Then twenty four pose literals in the runtime were replaced with references to the shared table.
Pure data, with motion added on top
The consolidation forced a distinction I had been avoiding. Some of what was in a pose was not a pose. Grab jitter, slam drive and dive speed are dynamic, they vary per frame, and they had been baked into the stored numbers.
Those moved out, into values applied on top of a pose at runtime. What is left in the file is static and editable, which is what makes an editor meaningful. If your authored data has runtime behaviour mixed into it, your tool is editing something other than what the user sees.
Three bugs, one missing pose
Separately, playtesters reported three problems:
- Grab a character by the throat and the arms and legs dangle.
- The lift overhead does not happen.
- Grab animations look different in the game than in the editor.
These sound like an animation blending bug, a state machine bug and a tooling bug. They were one thing: a grabbed character was running full ragdoll, because no pose had ever been written for the held state. There was a slack table in the file, but it was only read inside the ragdoll solver.
The second report is the interesting one. The lift was happening, over roughly a second. But a limp body being raised does not read as a lift, so players saw nothing and reported nothing happening. The bug was in what the frame communicated, not in what the code did.
When three complaints arrive in the same area, look for the one missing piece of data before you look for three bugs.
What transferred to client work
All of this is the same lesson as a configuration record in an enterprise system, and I hit it in both places in the same year. Authored data wants exactly one home. Two copies will drift, the drift will be silent because both copies are plausible, and the tool that is supposed to help will become the thing that overwrites your work.