How Exile works
00 · How Exile works

Why I rebuilt Exile, and how

The motivation and the method: investigate each system, understand it, recreate it in TypeScript, and prove it right at the level of individual bits and screen bytes.

Why

Exile has been with me for a long time. It was published for the BBC Micro in 1988, written by Peter Irvin and Jeremy Smith, coming towards the end of the BBCs commercial life and when many were, or had, moved on. However it was clear to everyone who played it that it was doing things an 8-bit machine had no business doing: a vast procedurally generated cave system, creatures that seemed to have intentions and certainly showed different behaviours, real physics including gravity, momentum, wind, water and all of it in 32K. It was an open world and a metroidvania before those terms were even coined. And it routinely tops lists of the greatest technical achievements on the platform: it literally seemed like wizardry. It still does.

That question of how it worked never really left me and decades on we have the tools to answer it properly: an excellent disassembly of the enhanced version exists, browsers are absurdly capable, and TypeScript is a perfectly good language for expressing what twenty thousand lines of hand-scheduled 6502 are actually for.

So this project set out to do two things at once: understand Exile completely and authentically recreate the game itself running natively in a web page, not through emulation, which is what you’ll find on the front of this site.

What it is not: an emulator with a nice wrapper. Emulating Exile tells you nothing about it. Every system here has been re-implemented as readable TypeScript: the landscape generator, the physics kernel, the creature behaviours, the renderer, the particle and sound engines, the main loop. The emulator this project does contain has a different job entirely, which is the interesting part of the method.

The inspiration for this is the work I did on understanding Thrust, which, ironically, is another game by Jeremy Smith. With that game I set off wanting to understand it by recreating it but quickly realised that the game contained so many tricks that you couldn’t just implement a newtonian physics system. It would, and did, feel completely wrong. Instead you had to really break down the 6502 assembly and recreate it - carry flags and all.

I learned a lot doing that and felt that using what I’d learned I could do a credible job with Exile. And finally scratch my nearly 40 year itch.

And I should add that in creating all this I’ve taken massive inspiration not only from the authors of the original game but also from Mark Moxon and his amazing work doing source code and systems analysis of games like Elite, Lander and Revs.

The approach

Looking at Exile, just as a player, there are clearly a lot of interlocking systems. There are obvious things like the graphics and the physics and so I began by creating a list of the discrete systems and set myself a roadmap with the intention of understanding each system in turn, creating a demo and enough notes that I could both write a document describing how it works and create a pathway to understanding the full game. Finally recreating it in the last step.

The work settled quickly into a loop, applied to one system at a time — the landscape first, then graphics, physics, the player, creatures, and onward through nineteen layers:

Investigate. Start from the disassembly and work out what a routine is actually doing, not line by line as trivia, but as intent. Why does the landscape hash shift by three here? What is this byte at &4b for? Exile’s code is dense with tricks: self-modifying opcodes, the carry flag used as a courier between subsystems, one zero-page byte doing two unrelated jobs because the authors knew both uses precisely. It’s some of the densest code I’ve ever looked at.

Recreate. Write the system in TypeScript, structured the way a modern reader would want it — named functions, explicit state, comments that record the why — while preserving the original’s exact arithmetic. This is important, as I noted earlier the “feel” of the game often lives in the peculiarities of 8-bit arithmetic and bit operations. Particularly in the Exile codebase where things like carry flags are used to carry a signal across multiple subroutines.

Test at the bit level. This is the step that makes the other two work, and I’ve got an article devoted entirely to this in the series. The project includes a tiny 6502 emulator that executes the actual game code, loaded straight from the disassembly listing. Every reconstructed system is then run side by side with the real thing: identical starting state, one unit of work each, and a comparison of everything either side could possibly have touched. For pure functions that means every possible input, for example the landscape generator is checked across all 65,536 map cells. For physics it means fuzzing: around a hundred thousand randomised object ticks, comparing the complete object tables after each one. For the renderer the comparison is the frame buffer itself, which for Exile is 16K of screen memory, byte for byte. And for the finished game it means whole frames: thousands of consecutive main-loop iterations with randomised input, where a single wrong bit anywhere - a flag, a table entry, a pixel — fails the run on the exact frame it first appears giving you a chance of fixing it.

“Bit-identical” sounds obsessive, and it is, but it earned its keep within days. Exile is a game where the random number generator’s next value depends on which carry flag a particle routine happened to leave behind. Test it by eye — the player walks about right, the doors open — and you ship a hundred subtle wrongs that surface as one inexplicable divergence twenty minutes into play. Test every byte and there is nowhere for a bug to hide; when something is wrong, the validators tell you which byte, on which frame. Several of the most fascinating discoveries in this series — systems that work only because of a leftover value, code that rewrites itself mid-loop, a listing that turned out to be subtly wrong about its own boot state — were found not by cleverness but by a comparison loop refusing to say yes.

How well did this work? Pretty well. When I composed the final game it largely “just worked”. That said, I’m not done, and the odd bug is still coming up. And by bug I mean something that the TypeScript version does that is different to the original release.

My intention is to work through a couple of walk throughs of the game end to end. One of the beauties of Exile is that there are multiple ways to solve problems that emerge from the systems. And the complexity of the game means there are quirks that can be exploited. Those quirks, in particular, are a good proof of accuracy.

What you get at the end

The result is a game provably identical to the 1988 original with the same bytes, same behaviour, and the same chaos. And a game that also happens to be a modern, embeddable web component. Because the reconstruction is known to be right, it could be extended without fear and I could use repeatable tests to be sure that any enhancements I made did not interfere with the accuracy of the recreation.

Why enhance the game? Some things just make it more playable for the modern player. For example Exile, famously, had a convoluted approach to saving games, because the game used the disc filing system’s workspace for its own use and so once running you couldn’t use the disc for anything else. Thats not a constraint for the TypeScript version so I’ve added in named saves, and quick save and quick load. I hope that this change alone makes the game more accessible to more players.

But (and mostly just for fun) I’ve added a widescreen enhanced mode and a status bar showing energy levels, inventory etc. These changes are completely optional. As an interesting aside its worth noting that the widescreen mode does change the feasbility of some solutions to problems due to nuances of the original game and how it activated / deactivated objects within the game world.

The rest of this series walks through the systems in the order they were rebuilt, from the landscape hash to the final assembled game. Each article digs into how the original works, how the reconstruction expresses it, and what the bit-level testing turned up along the way — which is usually where the best stories are.

Exile © 1988 Peter Irvin and Jeremy Smith · published by Superior Software
Reconstructed by James Randall from the enhanced version disassembly created by level7
Presented as a tribute to its authors.