Skip to content
← All work
2026In progressRuns locally

Spielburg

Sierra’s Quest for Glory I, rebuilt for the browser from its own files: Claude Code read the 1992 engine’s data and bytecode, wrote the rules up as cited specs, and ported the game as data instead of emulating it. Owning the engine then made a second thing possible: AI models playing the game on the same dice, side by side.

Solo — direction, review and play-testing, with Claude Code doing the reverse engineering and the port

A personal rebuild, not distributed. Quest for Glory, its art and its world are Sierra’s.
Resources decompressed exactly
1,405 of 1,405
Original lines recovered
5,006
Valley screens and exits
40 and 125
Models screened to play
53
Ready to play
31
Agent turns played (Oct 13)
20,000+

01 / problem

The problem

I played Quest for Glory I over and over as a kid, compared notes with friends and kept journals trying to decode its world. I’ve replayed it for years since, most recently in DOSBox. This started as a half-memory that I had DOSBox on this machine. I didn’t, so the question became whether the game could be rebuilt on a modern platform instead.

Rebuilding a 1992 Sierra game honestly means reading it, not imitating it. The rules live in compiled bytecode for an engine retired three decades ago. The text, the conversations and the walkable floors are scattered across compressed resource volumes.

So the real question was whether Claude Code could act as a decompiler: read the game’s own files, recover its rules exactly, and keep a record precise enough that every behaviour could be traced back to a script and an address.

02 / build

What I built

A browser version of the 1992 VGA remake, built from the GOG release’s own data. Claude Code did the reading and the porting. I set the direction, reviewed, play-tested and made the calls.

  • A toolchain for the SCI engine. A resource reader, a decompressor, picture and sprite decoders, an object reader, a disassembler and a pseudo-code printer, all written for this. 1,405 of 1,405 resources decompressed byte-exact on the first run.
  • Port to data, not emulate. Each room is a declarative file written from its decompiled scripts, citing the script objects it came from. ScummVM runs the bytecode. This rebuild turns it into data that a variant can override line by line.
  • Specs that cite the source. Combat, magic and thief rules were written up by agents reading the scripts, every rule with its script, object and address, and anything inferred marked GUESS. The port was built from the specs, and the specs corrected earlier work.
  • Parallel agents with a validator as the contract. Town rooms, NPCs, shops and 83 outdoor rooms went to agents running side by side, each held to a content validator. Their reports of what the format couldn’t express became general engine features.
  • Variants on top. An AI-repainted skin (“AIGA”) and a painted valley map sit on the faithful base, which stays playable as it was.
  • Agent mode and the matrix. Any Ollama model can play the game: it creates its own hero, explores, talks, fights and keeps a notebook. Up to six models play side by side on seeded dice, and every decision is recorded.

The deep dive below goes through each part.

03 / signal

What it shows

Claude Code works as a reverse engineer when the work is set up to be checked. Every claim cites the bytes it came from, and contradictions get chased. Three early bugs were caught only because the output disagreed with something already known. One was a coordinate of 226 that was really −30, because Sierra sign-extends one-byte immediates.

It also shows a way of running agents I keep coming back to. Give them a contract (a schema, reference ports, a validator) and have them report what they couldn’t express. Then fix the engine so the workaround has no reason to exist.

And it shows why porting to data paid off twice. Because the engine is mine, every roll can be seeded, every decision logged and every model briefed in the same words. That made the game a benchmark: 53 models screened, 31 able to play, and races between them on identical dice.

Gallery 1 / 5

The faithful port, in the 1992 art: the Sheriff’s pipe and Otto’s yo-yo run as their original idle loops.

06 / deep dive

How it was rebuilt

Spielburg was built in sessions logged as they happened, so the numbers here come from that log and the commits, not from memory. The chapters follow the order of the work: read the files, choose how to port, scale out with agents, write the rules up, then build on top.

01

Reading the game’s own files

GOG’s installer held both versions: the 1989 EGA original and the 1992 VGA remake on Sierra’s SCI1.1 engine, with fan fixes applied as loose patch files. We built from the VGA remake and kept the EGA parser’s vocabulary as a reference.

The first parse of the resource map assumed 5-byte entries, from memory of the spec, and the type counts didn’t divide evenly. A divisibility check showed this build uses 6-byte entries. A census found only one compression family (PKWARE’s “implode”), so one decompressor ported from Mark Adler’s blast.c handled all 1,405 resources, every size exact.

The text gave the project its architecture. Every line is addressed by Sierra’s own key, (module, noun, verb, condition, sequence), which became the stable ID that variants target. The VGA “Ask About” system turned out to be a ready-made topic-to-answer table for every character. From there: 300 of 300 sprites, all 84 picture streams, and walkable floors recovered from compiled scripts as polygons. Within one session the hero walked the original street behind the right posts and tables.

02

Port to data, not emulate

Room exits turned out to live in code, so reading scripts became unavoidable. Claude wrote an object reader, a disassembler for about 128 opcodes, and a printer that renders sends as readable calls (ego.posn(305, 113).setMotion(MoveTo, 305, 125)).

Three bugs were caught because the output contradicted something already known, not because a test failed. Two bits in the variable opcodes were swapped. A room said you arrive at x = 226 and walk west, while the neighbouring room put it to the east: one-byte immediates are sign-extended, so 226 is −30, off-screen. And a switch lost its subject at each case label.

Then the decision that shaped everything. Running the bytecode in a browser VM is how ScummVM does it, and it’s the most faithful. But every variant would mean patching bytecode. So each room became a declarative file, written from its decompiled scripts, in a step vocabulary that mirrors Sierra’s own primitives and records its sources. A variant can now override a single line by its ID.

03

Agents with a contract

Once two rooms were ported by hand and the format had settled, the rest of town went to three agents running side by side. Each got a brief with the schema, the two reference rooms and a translation table from pseudo-code idioms to steps, plus a validator it had to pass. They finished in two and a half to three minutes each.

The useful part was what they reported. Several agents independently hit walks that keep the hero’s current coordinate. They dropped those steps and said so, rather than inventing numbers, and the format gained "ego" as a coordinate. One noticed its edits didn’t show in git status. A .gitignore pattern had been silently excluding every room file while commit messages claimed otherwise. Commit messages are claims, not evidence.

That loop repeated through NPCs, shops, seating, 83 outdoor rooms and the magic and thief paths. Agents work around a gap and name it precisely, then the engine gains a general feature that removes the workaround’s reason to exist.

04

Specs that cite the bytecode

For the big systems, an agent read the scripts first and wrote a spec. Every rule carries its script, object, method and address, and anything inferred is marked GUESS. The combat spec runs to about 1,300 lines. Its first finding was that the brief itself was wrong: the scripts it named are the Weapon Master’s sparring lesson, and real combat lives elsewhere.

The specs keep the original’s oddities as data rather than smoothing them over. The goblin’s armour encumbrance is 1,400, so it’s hit 95% of the time unless it guards. Fleeing in three particular rooms turns any monster into a brigand. A shopkeeper takes your money and then tells you it’s too early to rent a room.

The later magic and thief specs corrected earlier work, including the magic user’s starting spell, two swapped spell verbs and three wrong thief gates. A spec that cites its sources can be checked, which is what makes it worth more than a port written from memory.

05

Agent mode: a model plays the game

The original design rule was that the engine owns the state and a language model only ever speaks within it. Agent mode turns that around and lets a model play. It sees what a player sees (the room, the listed features and exits, the time of day as Sierra phrases it), picks an action, and keeps a notebook of quests and lessons.

Most of the work was making the game legible to a model without giving anything away. Objects that draw nothing yet, like the acorn before it falls, are hidden, because a player can’t click them either. It’s told what the original manual teaches a player: bodies are searched for money, and you sit down to be served. Two deaths to the Night Gaunt, sleeping outside the shut town gate, are why it now knows where sleeping is safe.

The models taught the harness too. Some copied placeholders from the instructions literally ("<stat id>", fighter|magic-user|thief), so the instructions now show real examples. One model recorded six lessons that Antwerp was Crusher’s password. Now a lesson is kept only when the game shows a clear result, and lessons are reviewed and dropped when something goes against the agent.

Then the harness was rebuilt from counting what the models got wrong. In one day’s 12,549 turns, 1,946 actions failed, 590 of them because a model called something by a different name than the game does, so people and things now answer to the names a player would use. Agents had fled 140 of 164 recorded fights, so each fight now shows the record of every move against that monster, and each hero sees its rough odds against the valley’s seven monsters, played out a few hundred times on the game’s own attack, defence and damage formulas. A fighter with about a 90% chance against brigands had fled every one, and the counsel that once sent a hero into the ogre’s cave at 3% now won’t send anyone past a monster under 70%. Of 31 fights lost the next day, 18 were unarmed deaths after heroes threw their only dagger, so a hero with no weapon is now told so every turn. Heroes thought themselves lost 70 to 90 times a run, and five of eleven prayers asked the way, so each turn now carries a route from a map generated from the rooms’ own exits. No agent had ever cast a spell outside a fight; now one can. And the four minigames that still needed a human (the kobold, the Weapon Master’s lesson, Dag-Nab-It and the Mage’s Maze) are now played by the models, move by move.

The Agent Models page, listing models with their verdict, the six scenarios passed, and median and slowest reply times.

06

The matrix: the same dice for every model

Because the engine is mine, every gameplay roll can go through one seeded generator: combat, encounters, skill checks, which line is said, each minigame. Each kind of roll gets its own stream, so one extra roll of one kind doesn’t shift another, and saves carry the dice’s position. A match gives every model a new run on the same seed. Differences in where they get to come from their decisions, not their luck.

The matrix plays up to six games side by side, in rounds to a target turn. Each tile shows the model’s hero, score, vitals and latest thought. A match can be paused, resumed and joined late, and a watcher can whisper to a hero from the side panel: it hears a voice in its head, keeps it in mind for 40 turns and replans around it. Every decision is a row in SQLite, so the analysis compares models on pace (points per 100 turns), their longest dry spell and how much of the valley they explored, not just their score.

Getting in is gated. A Models page runs each model through six scenarios built from the agent’s own instructions, with every reply validated and timed. Of the 53 models checked, 31 came out ready to play. The rest were slow, unreliable or no longer served.

The matrix only needs moves, so a simulated fruit-fly brain plays too: Shiu et al.’s model of the whole FlyWire connectome, about 139,000 neurons. The game reaches it only through its sensory neurons, and the spikes of its descending neurons are read as moves. With the brain frozen and a small learner trained to read it, the fly averaged 6.51 points per 50-move episode against 4.32 for the same learner fed noise (83 and 63 episodes, p < 0.0001). Its own mushroom body learned a two-choice maze but made no difference in the game. The fly work has since moved to a game of its own; it has its own Lab card.

The Agent Analysis page comparing nine models on runs, turns, scores, pace, dry spells, places and deaths, above a chart of score over turns.