A 336,000-parameter transformer, written from scratch, that learned to behave
like a fish. It emits one behavior token every 0.4 seconds — motion, sounds,
moods — and the canvas just renders them. The whole model runs in this tab:
no server, no inference runtime, a hand-written forward pass in 189 lines of
JavaScript.
What the fish is thinking
loading weights…
—
last token —
How it feels
hunger0%
fear0%
drowsy0%
The model stores no hunger, fear or sleep variable. These are read
out of its own next-token distribution, and correlate r = 0.84 / 0.88 / 0.91
with the simulator's real hidden values. Hunger greys out while it sleeps — a
sleeping fish shows no hunger behaviour, so there is nothing to read.
Mood changes time since load
nothing yet
Model
memory used0 / 511
How full its 511-token memory is. Once that fills, the oldest
moment drops off — it can remember about 3½ minutes.
age0
parameters—
torch ↔ js—
Model trace
youthe tankmoodfeedingmotion
Tap it repeatedly
It startles the first time and stops caring by the tenth. That habituation
needs ~300 ticks of memory — a 5-gram structurally cannot do it, and that gap is
the reason this is a transformer and not a state machine.
Then starve it
Wait without feeding and it turns hungry, scanning the surface. Feed it when
it's full and it only glances over. Nothing stores a hunger variable — the model
infers it from its own recent behavior.
How good is it
2.6087 bits/token against a 2.5616 irreducible floor, measured from the
simulator that generated the training data. It closed 84.5% of the gap between a
5-gram baseline and the entropy of the process itself.
Source
Simulator, model, training, and this page:
github.com/arsallls/tiny-tank.
The dot above is live — it re-runs the PyTorch parity fixture on load.