AGENTSOLVER · UNREAL ENGINE 5.6 · PART 1 OF 4

Muscles instead
of keyframes.

A monster with simulated muscles, a physics solver I wrote from scratch, and a neural network trying to work out how to stand up. So far it has learned to crouch for money, to fly 330 metres straight up thanks to one of my bugs, and — finally — to stand up at full height without shaking itself apart.

ENGINE Unreal Engine 5.6
LANGUAGE C++ · Python
FOCUS Physics · RL · Tech Animation
STATUS Still going
41 BODIES · 68 DOF · FALLING WITH GREAT PRECISION
// 01 · why bother

What if it could learn?

After trying many different techniques to adapt animation to its environment — failing sometimes, succeeding other times — I wanted to explore new horizons.

So what would happen if, instead of me programming a solution to every problem and every possible situation I could think of, I could just... make it learn?

That turned out to need three things I didn't have: a physics solver fast enough to train against, a way to author muscles onto a skeletal mesh, and an RL setup that doesn't fall apart. So I just... built all three?

The first goal might not be the most incredible thing that has ever happened, but making it stand would already be a great success.

// 02 · the shape of it

Physics, authoring and learning.

01 Skeletal Mesh 52-bone rig
→
02 Muscle + Mass Authored physical profile
→
03 Physics Solver 41 bodies / 68 DOF
→
04 RL Policy Custom PyTorch PPO
→
05 Animation Learned physical behaviour
41Simulated bodies
68Degrees of freedom
64Creatures per batch
330 mHighest it has flown


Wait... what do you mean, "highest it has flown"? You'll understand later — but if you're too curious, click here.
And if you want to break your head on all the technical stuff, you'll find it here. This page stays mostly maths-free.

// 03 · meet the patient

Muto

The creature used for the experiments is a reproduction of the Female MUTO from Godzilla (2014).

I picked a big multi-limbed monster for the least technical reason possible: I'd rather work on something fantastical than on yet another human biped. Creatures are more fun. That it also makes the solver work harder is a happy accident.

ASSET CREDIT

Female MUTO
Original creator: AllThingsSaurus
Originally obtained from Sketchfab
Third-party asset used exclusively for technical animation demonstration.

To be clear about what's mine: I did not model this. I did rig and skin it myself, and everything around it — the physics, the muscles, the tools, the learning — is mine too.

// 04 · where it stands

It stands up.

Under normal gravity, on the ground, with nothing cheating: the creature reaches its full standing height of 414 units and holds it. That was the milestone this whole thing was pointed at, and it took about eighteen months of the creature falling over to get there.

It arrived shaking, though. The first policies that made it all the way up stood there vibrating, because slamming 68 muscles between slack and full every tick is a perfectly good way to balance if nothing stops you. Two changes fixed it: muscle activation is now smoothed on its way into the solver instead of taking the raw policy output, and the reward charges for rapid changes in muscle intensity. Before and after, in the bug journal.

Getting here took a detour. An earlier version survived entire episodes in a deep crouch, because a safety clamp on the reward was paying it exactly the same for crouching as for standing tall. It optimised what I built rather than what I meant, and did it superbly. The autopsy is in the bug journal.

BEFORE / AFTER THE SMOOTHING FIX · FULL HEIGHT, 414 UNITS
✓ Custom Featherstone solver 41 bodies, 68 DOF, limb collisions on
✓ Muscle / mass authoring Working
✓ Batched AVX2 simulation 64 creatures per batch
✓ Hand-written PyTorch PPO MLP and Mamba, training end to end
✓ In-engine policy playback MLP and Mamba, any run, one click from the panel
✓ Joint welding momentum leak Fixed: welding is gone from the solver
✓ Standing at full height 414 units, on the ground, nothing cheating
✓ Smoothed muscle activation Fixed the jitter, together with a rate penalty
→ Shifting its weight Next milestone. Then, maybe, a step.
· Locomotion Not started. Not even a little.
// 05 · and then it flew

I asked it to stand. It learned to fly.

Every other bug in this project presents identically: the creature falls over. This one is the exact opposite.

I wanted the creature to stand as high as it could, so it learned to go as high as it could.

NOT A FEATURE · IT WORKED IT OUT BEFORE I DID

From the data on TensorBoard, nothing alarming, but when I opened the custom visualizer I saw it exploiting this bug that I didn't even know existed.
The full story — including how I bisected it — is in the bug journal.

// 06 · what this taught me

The solver was the easy part.

Featherstone is written down in books. You can look it up. What nobody writes down is that the same system has to be correct mathematically, plausible physically, fast enough to train against, and configurable by someone who has no intention of reading your C++. Getting all four at once is the actual job.

And "plausible" is doing a lot of work in that sentence. The flying bug looked like a jump at start then become worst. Measuring it make it instantly clear. The other thing I got out of this project is a debugging habit: I stopped trusting what looks right and started testing what has to be true. The bug journal has the receipts.

// 07 · next

It's standing. Now make it move.

One creature, standing, on purpose, at full height, with both the reward and the physics telling the truth — that box is ticked. Next it gets to shift its weight, then take a step, and if it ever walks I will be insufferable about it.

Further out: getting this out of the training rig and into something production-shaped, via Chaos and Control Rig. Learning in a sandbox is fun. Learning something an animator can actually use is the point.

Next: the tools →