Last modified: May 03, 2026
This article is written in: 🇺🇸
BPAT is the game's motion book for a creature species.
A horse, elephant, humanoid, or sword-ready humanoid does not figure out every joint from scratch in the middle of battle. Instead, the hard animation work is prepared ahead of time and packed into a BPAT file. During play, the game only needs to answer two easy questions:
That is why large battles can stay lively without turning animation into a performance disaster.
Imagine the animators as drill masters before the campaign begins. They teach each creature its full set of moves: idle, walk, trot, attack, recoil, death, and so on.
Then the game's build tools write those lessons into a single travel book for that species: a BPAT file.
When the battle starts, the game does not re-teach the horse how to bend a knee or swing a neck. It simply opens the book, jumps to the right move, picks the right moment, and says:
"Show me frame 18 of the gallop."
The GPU then turns that stored pose into the moving creature you see on screen.
So BPAT is a promise:
In code, that "intent" is basically: play this clip at this phase.
Think of the file as a chest with a few labeled compartments.
| Part | Plain-English meaning |
| Header | Who this file is for and where the other parts begin |
| Clip list | The named moves, such as walk or attack |
| Socket list | Attachment points for gear, riders, or props |
| String table | The actual text names used by the clip and socket lists |
| Palette data | The real pose data for every frame of every move |
| Socket data | Optional pre-baked attachment transforms |
The header gives the game the basics:
Each clip entry describes one named move:
In simple terms, the clip list is the table of contents for the motion book.
Some creatures need stable attachment points: a saddle, a rider anchor, a banner pole, a carried prop.
Each socket entry says:
This is just the name drawer. Instead of storing repeated text inside every entry, the file keeps the names together in one block and points to them from the clip and socket lists.
This is the heart of the file.
For every stored frame, BPAT contains the full pose of the creature: where each bone should be and how it should be oriented. The data is laid out in one long run of frames, clip after clip.
If you like analogies, this is a flipbook where each page contains the full bone pose for that instant.
This part is optional. If present, it stores ready-to-use attachment transforms so the game does not have to combine the bone pose with that extra socket offset every time. That saves extra work during rendering.
tools/bpat_baker bakes creature motion into BPAT files.No live "solve the whole skeleton from scratch" step runs in the shipping build.
That is the idea behind the format.
If you want the game to regenerate the current creature BPAT assets, use the prebaker.
make bake-bpat
That runs the built baker and writes the generated creature assets into assets/creatures/.
./build/bin/bpat_baker
The tool takes one optional argument: the output directory.
./build/bin/bpat_baker assets/creatures
./build/bin/bpat_baker /tmp/creature_bakes
At the moment, the prebaker writes all built-in species in one pass:
| Output | Notes |
humanoid.bpat |
default humanoid animation set |
humanoid_sword.bpat |
sword-ready humanoid animation set |
horse.bpat |
horse creature BPAT |
horse_minimal.bpsm |
horse minimal snapshot mesh |
elephant.bpat |
elephant creature BPAT |
elephant_minimal.bpsm |
elephant minimal snapshot mesh |
So this is not a pick-one-species command yet. The current CLI bakes the whole built-in set.
For whole-creature species such as horse and elephant, the current prebaker path is driven by SpeciesManifest.
To hook a new species in, provide a manifest with:
species_idbpat_file_nameminimal_snapshot_file_namebind_palettecreature_specbake_clip_paletteThen expose that manifest and call bake_species_manifest(...) from the baker entrypoint.
The engine uploads the baked pose data as a texture on the GPU.
Why a texture? Because GPUs are extremely good at reading texture data quickly and in parallel. Instead of treating the texture like a picture, the engine treats it like a shelf full of pose rows.
So when the creature is drawn, the graphics card reads the right bone rows from the texture and bends the mesh into the correct pose.
In player terms: the creature animation is packed like an image so the graphics card can replay it fast.
| Term | Easy meaning |
| Bone palette | The full creature pose for one frame |
| Clip | One named move, like idle or attack |
| Frame | One step inside that move |
| Socket | A named attach point for equipment or props |
| Phase | How far through the move the creature currently is |
| Species | Which body plan this file belongs to |
For readers who want the important hard facts without drowning in byte offset tables:
BPAT.The frame data is flat and simple:
So a clip entry does not own a separate chunked mini-file. It simply points to its starting place inside the full shared stream.
The current reader accepts a BPAT file when:
BPAT magic10..3 today)NULThe writer still emits zeroed padding and reserved fields, but the current reader does not actively reject non-zero reserved bytes.
This page now tells the story first.
For the exact C++ layout used by the engine, see:
render/creature/bpat/bpat_format.hFor the broader rendering flow, see:
docs/RENDERING_ARCHITECTURE.md