Engineering log
Notes from the workbench.
A running record of what gets built here — what each thing does, what it currently scores, and the stories worth telling from building it. Most of it is Game Boy work: an emulator, a neural player, an evidenced cartridge atlas and three more. Three pieces aren't — Glyphsmith is the hand-drawn alphabet that drew all of their logos, ShowReel is the renderer that turns their footage into a film, and AsciiWorldEngine is a walkable ASCII city with nothing to do with any of it. Most of the source repositories are private; this is where the interesting parts are visible.
Flagship · AI plays Pokémon
Six hundred copies of a hundred-thousand-parameter network genuinely play Pokémon Blue.
Real buttons, a real emulator, a cold boot every time. The 21-link chain — bedroom to Poké Balls in hand — now runs 600 for 600. A confidence gate that used to lock onto one button forever, fixed by letting the belief in it decay instead of banning it; and chambered goals that let 306 of those runs walk themselves to a Pokémon Center and heal, mid-chain, for free: all on the project page.
The projects
What each one is, what it does, and where it stands today.
Standing pages
Three pages that grow rather than get published once.
Gen 1 cartridge
Cartridge finds
Things the cartridge actually does. The player and rival are already called NINTEN and SONY before either naming screen runs; the learnset table is not indexed the way anyone expects; a trainer sees straight through walls. Each entry with its addresses and its mechanism.
AgentGB
Agent progress
From a random walk where nobody leaves the first town, to a screen-only student completing a sixteen-link chain 145 times in 150 cold boots. The arc in order, with the number that was true at each point, and the ledger of what is still not true.
TerminalGB
Performance
414× real time on one core, 3,735× on twenty, and a same-session comparison against two other emulators. Every figure carries the core, the engine and the load average, because on this box the same binary reads 56% apart between a quiet machine and a busy one.
Writing
One story each.
-
The infrared had to go
A 74LVC2G17 where the infrared transceiver was, and a ⌀70 steel ball to put it in. The shell weighs 86.1 g, the Poké Ball look turns out to be paint, and the USB-C plug cannot reach its socket.
-
The leaderboard that does not exist
Three of our own published speed numbers did not survive being measured properly. What replaced them puts the fastest emulator on this machine at zero on the hardest accuracy suite in the field.
-
The trainer who saw him black out
He fainted next to a Bug Catcher, blacked out, and woke up in Viridian City. Forty-five tiles and 385 decisions later he stepped back into the forest and the Bug Catcher fought him where he stood — on the doorway tile, nine decisions after crossing the boundary.
-
The trap was always on the map
A compiled copy of the student finished 0 of 10 cold boots where the original finished 8. Nothing was retrained and the two paths pick the identical button a thousand times running. The obvious conclusion — the new thing is broken — was wrong.
-
A perfect score and 361,567 false alarms
A recogniser scored a held-out balanced accuracy of 1.000 and then said yes to 361,567 of 1,383,924 frames of real play. Five rounds, one of them poisoned by the tool's own refusal message — and the bug that was actually ending runs turned out to have no weights in it at all.
-
Teaching a network to notice
Five triggers that read the cartridge were replaced with networks that look at the screen. Held-out accuracy said 1.0000 and the probe said zero false alarms — and the labels themselves were poisoned, in a way only a person looking at the pile could see.
-
Exponential decay of belief
A confidence gate locked onto one button, fourteen times out of fourteen the same way. Letting the belief in it decay instead of banning it took the chain from 594 to 600 of 600 — and taught it to heal itself mid-run for free.
-
One character becomes three thousand
A single character stands in a bedroom, then three thousand of it walk themselves into a Pokéball, in one unbroken shot. Getting there took a stage with no map and six real bugs, most of them nowhere near the camera.
-
Three bytes a cell, doing nothing
A reference clip filled the cell behind every glyph instead of drawing bright characters on black. The plumbing to do the same here turned out to already be wired in, end to end, and doing nothing.
-
The chiptune that outgrew its blog post
A demo video needed music with no licence to worry about, so a 114-line Python script wrote its own chiptune. The captain asked why a generator that times itself to a video lived beside a blog asset instead of inside the renderer — and eighteen minutes later, it didn't.
-
The number that could have sunk it
Could Remotion open on Pokémon Blue's title screen, pull back to the whole world map, and burst out real battle footage from where it happened? Two of the three ingredients already existed. The one real unknown came back at 4.3 milliseconds a frame.
-
The one clean miss
The captain wanted the display style of a specific YouTube editor. Six of the seven techniques it needed already existed. The seventh was small, and it still isn't built.
-
Every failure was the same starter
A twenty-six agent swarm scored 88.5% and looked healthy. Watching the film instead of reading the table showed all three failures were the same starter Pokémon — one chance in 2,600.
-
The wall you hit walking home
An agent learned the walk to the shop perfectly and could not learn the walk back. Two measured rates that sum to a hundred are the signature of an impossible task, not a hard one.
-
The day that added nothing
Five identical training runs scored 100, 92, 92, 85 and 77 per cent. Every ablation published before that lacked the control.
-
293 runs stopped on the same text box
A nine-link chain collapsed from 300 of 300 to 7. The student was doing exactly what its supervisor had told it to do.
-
The one failure in twelve thousand
Four certification cells of 3,000 attempts produced exactly one failure. Somebody was standing on the corner tile, and stayed there for 4.7 minutes of game time.
-
Reading the screen without reading the letters
At 40×36 no letterform survives. Six in-game messages are still 97.2% separable — and the first two experiments that said otherwise were both too small to say anything.
-
271 colours in a four-shade picture
Half-block terminal output was blurry on GNOME terminals and crisp on WezTerm. The cause was a hard-coded smoothing filter four lines down in a dependency — and doing the sampling ourselves is cheaper.
-
The transfer controller owns the bus
Object DMA is usually modelled as a copy. It is also an address-bus conflict, and the sprite scan is on the other end of those lines.
-
The red we refused to fix
One sweep would have turned a failing test green. Taking it would have moved every Color cartridge's divider on the evidence of a single row.
-
The double-speed bug that cost 2,304 pixels
A register-commit trick worth exactly one dot of time vanished when the CPU clock doubled — and a Color game drew a wrong stripe across the screen.
-
TACKLE is 95 per cent and we said 94
Nothing failed. A number had been computed from a belief rather than read from the cartridge, and it sat in four files for as long as they existed.
-
The ledge in Viridian City
Seventeen runs of six hundred died on the same row of the same town. A flood fill said the tile was reachable, and the flood fill was right.
-
Let go of the D-pad
One line took a cartridge map capture from 113 maps to 216. A door is a warp on both sides, and a player still holding the direction walks straight back out.
-
The door rule
The cartridge says where outdoor maps go and says nothing at all about interiors. Placing 190 rooms is a decision, and it was settled by measurement.
-
A hundred checks in one session
A new check found a real bug on the day it was written — one that thousands of rows across five public suites could not see, because of the shape they have.
-
Three ways this cartridge was wrong about itself
A verdict decided by which checks failed above it, a subroutine that ate a measurement, and two checks that skipped on every console, forever.
-
Four bugs, one line each
A dropped field, a RETURNING clause that returns the wrong thing, a bigint that arrived as a string, and a grid that could not get narrower than 16rem.
Start your own
This site is a small, complete blog, and it is a GitHub template. Take a copy and the writing is the only part left.
One click
Use this template
GitHub makes you your own copy of this repository, and Pages builds it. Change
seven values in _config.yml, drop a markdown file into
_posts/, and it is live. There is no build step, no framework and
no dependency to keep alive — the only thing this site loads from anywhere else
is a font.
Five minutes
How it fits together
What each front-matter field does, how a post becomes a page, and where the four colour palettes live. Every page here is either a markdown post or a hand-written HTML file that Jekyll copies through untouched, so there is very little to learn before you can change something.