Most of the creatures my project has made so far are sine waves with legs. This is a real one. The model gave it seven legs and wrote this for its brain:
def act(obs, mem):
t = obs["t"]
freq = 1.5
cmds = []
for i in range(7):
phase = i * 2 * pi / 7
# Drive legs in a wave.
# Negative sine pushes legs back (relative to rest) to propel body forward.
cmd = -sin(freq * t + phase)
cmds.append(cmd)
return cmdsIt barely moves, and neither do most of the others.
Cambrian is a project where a language model running locally designs creatures like this one, a physics engine tests them, and the ones that do best get bred into new ones. This post covers how it works and what happened the first night I left it running.
Free Tokens
I have access to a DGX Spark (Flint) and an older Linux box that's always on (Cygnus). Flint has 128 GB of memory, which is enough to run a 122B-parameter model locally. So basically I got infinite tokens.
That made me want to try something that only makes sense when a model can run nonstop for weeks without costing anything. I thought about training a small model with RL to beat me at a game, and about a TV channel generated entirely by local models. I went with evolving creatures. Karl Sims was evolving virtual creatures back in 1994, and a 2022 OpenAI paper had language models write little walking robots, so the idea isn't new. What I can do is leave it running for as long as I want.
What a Creature Is
A creature has a body and a brain, and the model writes both.
The body is a list of capsule-shaped segments joined by motorised hinges. There are hard limits so the model can't make something absurd. It gets 2 to 16 segments, it has to weigh between 0.5 and 60 kg, and the total strength of its motors has to scale with its weight.
{"id": "leg", "parent": "torso", "attach": 1.0, "angle": -90,
"length": 0.3, "radius": 0.04, "joint": {"range": [-45, 45], "gear": 40}}The brain is a Python function, like the seven-legged one at the top. It gets called 50 times a second and returns how hard to push each joint. The model can also read which body parts are touching the ground and react to that, though it rarely even tries.
Scoring
Each creature gets dropped into MuJoCoA physics engine made for robotics research (now open source from Google DeepMind). Here it simulates gravity, friction, joints and motors, so the creatures move the way real objects would. and runs four 15-second tests: flat ground, a 12° hill, ice, and flat ground where it gets shoved sideways every couple of seconds. Each test runs three times from slightly different starting poses, and the creature gets its worst result of the three, so a gait that only works when it gets lucky doesn't count.
From that it gets six stats from 1 to 255: Speed, Stamina, Climb, Grip, Leap and Poise. They add up to a base stat total (BST). If this sounds like Pokémon, that's because I stole it from Pokémon. Every species that survives gets a numbered page in what I'm calling the Flintdex, with a name, a short entry, and its evolution chain.
The part I spent the most time on is keeping the world varied. If you always breed from the best creature, you end up with a thousand versions of one design. So the world is split into 100 niches (how it moves × how many limbs × how heavy), each niche keeps its own champion, and parents get picked evenly across niches rather than by score. About one breeding in eight is the model inventing something from scratch for a niche nobody has filled yet.
Loopholes
Evolution doesn't care what I meant a score to measure. It only cares about the number, so if there's a cheaper way to get a high number, something eventually finds it. Some of the cheap ways were my own scoring mistakes. Others were bugs in the physics.
I found the first scoring mistake before anything had even evolved. Poise is supposed to measure how well a creature holds its course when it gets shoved. My hand-written inchworm barely moves, and it had the second-best Poise of anything, because a creature that isn't going anywhere can't be knocked off course. Poise now only counts in proportion to how much a creature actually moves.
The second was Leap, which measured how high a creature's centre of mass got. A creature that started lying down and then stood up got credit for jumping. Leap now only counts height gained while nothing is touching the floor.
The fourth creature my setup ever bred was the other kind. This is its log line:
02:44:44 mutate suspect BST 533 "a single, long, stiff spring-like tail
angled downward to store energy and
launch the body upward"It scored 533 which was higher than anything else at the time. And technically the scores weren't wrong like it really did travel that far. Though it did it by sinking its tail about 11 cm into the floor, and the physics engine shoved it back out hard enough to launch it forward every time. I already had a check for creatures sinking into the floor, but it only flagged them as suspicious, and suspicious creatures still counted. So two minutes after breeding started, we had our first cheater!
Cheaters don't get deleted though, They go into a separate gallery of caught cheaters, a hall of shame if you will.

Which Model
There are three Qwen 3.5 models on Flint: 27B, 35B and 122B. The 35B is a lot faster, so I ran a small bake-off, with the same 8 breeding tasks for each model, "thinking" on and off, and every result judged by the physics.
35B, thinking on: used all 16,384 tokens thinking and never answered, 6 times out of 8
no thinking: 92 kg, 207 kg and 338 kg creatures, against a 60 kg limit
122B, thinking on: 8 valid creatures out of 8Without thinking, the models don't add up the weight of what they designed. The 122B with thinking checks its numbers. So the 122B with thinking on invents new creatures, and the 122B with it off handles small edits to existing ones, which are about ten times faster.
Eight tasks isn't much data, though. I later ran a much bigger test on the edits, and it changed my answer. Stay tuned!
The First Night
Breeding started at 2:42 am on Saturday. By 9:30 it had made 281 creatures. My hand-written starting creatures scored 223 at best. The best creature by morning scored 574: a fusion that tumbles forward on five jointed legs, descended from a starwheel I wrote by hand. Three families had already evolved into third forms, and the floor trick had been caught a few more times.

Most of them still barely move, though. These are the speeds for the first 316 creatures that passed every check:
slower than 1 cm/s 87 (28%)
slower than 5 cm/s 202 (64%)
slower than 10 cm/s 256 (81%)
faster than 50 cm/s 14 (4%)
fastest 1.23 m/sThe seven-legged creature from the top of this post is in the second row. The 14 at the bottom do some kind of hopping or tumbling and those are the ones I'm hoping to see more of.
Why Bother
A lot of AI work right now is about getting one good answer out of a model as cheaply as possible. I wanted to see what happens when you flip that and let a model generate ideas constantly, almost all of them bad, with something strict deciding which ones survive.
There are two questions I actually care about. The first is how long this keeps finding new things. Systems like this usually run out of steam once the easy designs are taken, and I want to see where that happens and what it takes to get it going again. The second is whether the model can get better at breeding. Because the model is local, I can eventually fine-tune it on its own successful creatures and see if its next ones improve, which isn't really possible with a model behind an API.
Also, waking up to a new batch of creatures and how well they performed is just a lot of fun!
To answer the first question, I'm running this in generations. Generation 1 is what's running now: flat ground, four tests, capped stats. I'm leaving it alone until it stops producing new things. Then I'll change the world enough that the old champions stop winning, and start Generation 2. Each one gets a post.
Next post will be what Gen 1 actually evolved, how a third-form evolution turned out to be cheating all along, and whether the AI judge I built to rate how interesting a creature is has any taste.
'Til next time!