CAUSEWAY
A Space Racer Built to Look Like 1993

Causeway is a Skyroads-shaped racer: floating roads through empty space, a fuel gauge, an oxygen gauge, and a jump button. The constraint that shaped everything is that it had to look like it actually shipped in 1993 — not a modern game wearing a retro filter, but one built the way the originals were built.
Origin Story開発の背景
It started as a tribute to Skyroads, the 1993 Bluemoon game I lost weeks to as a kid. The temptation with a homage is to modernise the parts that were hard back then. I went the other way and adopted the limits deliberately: a 320x200 framebuffer, sixteen levels per colour channel, and a hand-authored 5x7 bitmap font. Every design problem after that had to be solved inside those limits rather than around them.
How It's Builtつくり方
There is no build step and no dependencies — plain ES5 in classic script tags, which means it runs off the filesystem in any browser. The whole game is drawn into a 320x200 buffer that is then blown up with nearest-neighbour filtering into a 4:3 window, so the pixels come out tall and chunky the way a CRT stretched them. Music is generated at runtime by a two-operator FM synth rather than sampled. The macOS build wraps that same unmodified game in a small native Swift shell.
Engineering Notesエンジニアリングノート
The limits are the design
Everything is drawn into a 320x200 framebuffer and blown up with nearest-neighbour filtering into a 4:3 window, so the pixels come out tall and chunky exactly as a CRT stretched them. Colours snap to sixteen levels per channel — a ramp the EGA palette sits on exactly, so interface colours pass through untouched while every blended shade in the 3D view picks up the banding a 256-colour display would have had. None of this is a post-process filter over a modern renderer; it is how the frame is actually built.
Level variety is an architecture problem
The first version drew all thirty roads from one weighted bag of features, so only the seed and the palette differed — structurally they were interchangeable. The fix was compositional: each world biases the feature weights toward its own signature, each of its three roads has a different job, pressure rises and falls in waves along the length, and every road closes on a set piece built from that world's signature. A generator also has to be held to its own promises — if the dice fail to produce a jump or a climb by halfway, it insists on one, because a road that never leaves the ground is forgettable however hard it is.
Why the desktop build is under a megabyte
The obvious way to ship a browser game on the desktop is Electron, which means shipping a whole browser — around ninety megabytes to run a game that is a few hundred kilobytes of JavaScript. Causeway instead uses a small native Swift shell around WKWebView, the engine already on every Mac. The entire signed, universal download comes to roughly half a megabyte.
A loopback socket instead of file://
The obvious way to load bundled HTML into WKWebView is a file:// URL, and it does not work here: WebKit refuses localStorage on file origins, and localStorage is where campaign progress, ghost replays, options and the chosen language live. So the app serves its own bundled game over an ephemeral loopback socket, which gives WebKit a real origin and keeps the game's storage working exactly as it does in a browser. About a hundred lines, bound to loopback only, with a path-traversal guard.
Galleryギャラリー



The interesting work in Causeway was not making it look old. It was that adopting a real constraint forces real decisions: you cannot solve legibility with a bigger font when the cell is five pixels wide, and you cannot solve level variety by adding more content when every road is generated from the same handful of rules. The limits did the design work, which is the whole argument for taking them seriously.
What It Does主な機能
Composed, Not Sprinkled
Thirty roads across ten worlds, seeded-procedural so they rebuild identically every time. Each world biases the generator toward its own signature — Zarah is ice, Vela is altitude, Erebus is minefields, Tenebra is single-lane causeways over nothing. Each world's three roads have different jobs: teach it, test it, wring you out. Pressure rises and falls in waves along a road rather than uniformly, and every road ends on a set piece built from its world's signature.
Symbols, Not Colour Codes
Every tile that does something to you wears a 5x5 symbol stamped on its face — a drop for fuel, a bubble for oxygen, an arrow for boost — and names itself in the cockpit the moment you touch it. Symbols rather than letters, deliberately, so the vocabulary reads identically in all three languages.
A Cockpit, Not a HUD
You drive from inside a braced window: a squared frame with two structural beams raking down to the shoulders, phosphor screens either side, and a coaming that sweeps the opposite way to the glass so the road sits in the deepest part of the opening. The road scope is let into the housing where the beams meet.
Three Languages at 5x7
English, Japanese and Roman Urdu. The Japanese is katakana only, which is exactly the constraint a 1993 release faced, with voiced kana decomposed into base plus dakuten the way 8-bit hardware did it.
Road Editor
Paint roads tile by tile, set the world and gravity, test-drive them, save them to local storage or copy them out as JSON.
Ghost Replays
Your personal best on a campaign road comes back as a second ship to race against.
Where It Stands現在地
Causeway is finished and shipped as a signed macOS app — thirty roads, ten worlds, three languages and an editor. The natural next steps are more worlds and sharing player-made roads, though the honest answer is that it is complete: it does the thing it set out to do, at the size it set out to be.
The renderer is a hand-rolled pinhole camera writing quads to a 2D canvas — no WebGL. The road is drawn back-to-front by row with only genuinely exposed block faces filled in. Colours are snapped to sixteen levels per channel, a ramp the EGA palette sits on exactly, and the sky is ordered-dithered with a Bayer matrix rather than smoothly blended. Chromatic aberration runs per-pixel inside the framebuffer so the fringes are themselves chunky VGA pixels. The macOS app is a small native Swift shell around WKWebView — not Electron, which is why the download is under a megabyte instead of ninety — signed with a Developer ID certificate and built with the hardened runtime.