A console-style game select screen that boots classic id Tech games. Each engine is compiled to WebAssembly and driven from a single Kotlin Multiplatform host — the same launcher, renderer, input layer and save system serve every game behind it.

Slipgate is a launcher first and an engine host second. You pick a gate, the screen warps, and the game takes over the surface.

Android Web · WasmJS iOS Open source
The rack

Gates

A gate is one game plus the engine that runs it. Each gate is named for a figure from the game behind it rather than for the game itself, so the rack reads as a row of places to go rather than a list of products.

Mars gate cover — an armored marine facing a wall of fire

Mars

Doom · 1993

Doom opens on the Union Aerospace Corporation's facility on Phobos, where a teleport experiment has torn something open. The marine who fights back through it was posted to Mars for assaulting a superior officer who ordered him to fire on civilians.

Playable Chocolate Doom Freedoom included
Corvus gate cover — an elven archer under a storm of green lightning

Corvus

Heretic · 1994

Heretic's hero is the last of the Sidhe elves, one of seven who refused to serve D'Sparil and were named heretics for it. The other six were broken; Corvus went into the dungeons after the Serpent Rider alone.

Playable Chocolate Doom · Raven Blasphemer included
Korax gate cover — three silhouetted heroes before a serpent throne

Korax

Hexen · 1995

Korax is the second Serpent Rider, who took the world after his brother fell. Three heroes survived the call to arms that emptied their orders — and the player is whichever one they choose.

Playable Chocolate Doom · Raven Own IWAD required
Chthon gate cover — a horned lava demon wading through molten rock

Chthon

Quake · 1996

Quake's first boss — the lava thing under Shub-Niggurath's dimension shard, waiting at the bottom of the first slipgate run. The gate that gave this project its name.

In development Mark V WinQuake Own PAKs required
Macil gate cover — a cloaked rebel before the Order's iron gates

Macil

Strife · 1996

Strife's rebel leader, who runs the Front against the Order from under a town the Order already owns. The same engine tree that builds the first three gates builds this one too — and it did: dialogue, shops and all.

Playable Chocolate Doom Own IWAD required
First run

Game data

No game data ships with Slipgate. Not in the repository, not in releases, not in CI caches. Acquisition is a first-run flow inside the app: Doom offers a Freedoom download, Heretic offers Blasphemer, and Hexen and Strife take your own IWAD — their gate cards say so instead of showing a download button that cannot work.

Both free options are named as what they are: a replacement rather than the original. Freedoom is not Doom and Blasphemer is not Heretic — different levels and art, the same game to play — and the data screen says so before you download half a gigabyte expecting otherwise.

Supplied files are validated by contents, never by filename — signature, lump directory, palette, and the translucency table that separates the engine families. A file that is game data for the wrong game is refused by name: "that is Doom data and this gate needs Hexen."

Whether a file carries a palette decides what it can be: one that does can boot a gate, one that does not is an add-on loaded over a game already installed. That is how the engines themselves decide it — and it gets the two famous exceptions right: Chex Quest is a whole game under a PWAD header, and Hexen's Deathkings expansion is an add-on under an IWAD one. Thirty years of custom map packs install per gate and load in a stable order with -file.

Serve your own library

The LAN shelf

Game data you own can live on a machine you own. The shelf is a folder tree on your NAS or desktop — one folder per gate — served on the local network by a small script from the repository:

./tooling/data-shelf/serve-shelf.py

It prints the address to point a device at, answers with the CORS and Range headers a browser and a resumed download need, and your phone pulls files straight from it — through the same downloader that fetches Freedoom. No cloud, no account, no upload of purchased data to anyone else's server. Away from home, a companion script puts the same shelf behind a tunnel your own devices can find.

A manifest.json catalogues every file the way the app itself reads it — kind, role, flavour, episode and map counts, size and sha256 — produced by the same content-based rules, never by filename.

ShelfHolds
mars/Ultimate Doom, Doom II, Final Doom, Chex Quest
corvus/Heretic: Shadow of the Serpent Riders
korax/Hexen: Beyond Heretic
macil/Strife: Quest for the Sigil, and its voices
chthon/Quake — the registered paks, laid out as the engine expects
eidolon/Hexen II at 1.11, and Portal of Praevus beside it
addons/Deathkings, and thirty years of map packs sorted per gate
Under the surface

Engines & architecture

The four playable gates are built from the Chocolate Doom tree, which carries Doom, Heretic, Hexen and Strife behind one platform abstraction — the reason a single port effort yields four gates. The Quake gate is built from Mark V WinQuake, the lineage behind QuakeDroid; behind it wait Hexen II through uHexen2 and Wolfenstein 3D through Wolf4SDL, each planned in the open before a line of its port is written.

Each engine is compiled to WebAssembly from a pinned upstream revision and executed by Chasm, a Kotlin Multiplatform wasm runtime. The host feeds a palette-indexed framebuffer to the GPU as an R8 texture with the palette as a 256-entry lookup, and resolves colour in the fragment shader — so palette effects like the damage flash and the Tome of Power come for free.

Nothing in the host assumes 320×200, 8-bit colour, 35 Hz tics or a single save blob — those are properties of a session, which is what keeps engines beyond id Tech 1 viable. One shader dialect (SkSL/AGSL) draws inside Compose's own canvas on every platform, with an edge-adaptive upscaler in the spirit of FSR1's EASU for smooth-edge scaling, and an optional tube effect — curvature, scanlines and grille, as a television of the period had.

The host never depends on the games; gates are discovered through a registry the platform entry point populates. The host is dual-licensed MIT / Apache 2.0; the engines are GPLv2, and so are the wasm modules built from them, with complete corresponding source and pinned revisions published for every module.

Standing on shoulders

Inspiration & credits

Slipgate exists because mood demonstrated that a full id Tech 1 game can be driven from Kotlin Multiplatform through a wasm runtime. The host architecture here — a palette-indexed framebuffer pipeline fed by a wasm game instance — follows the approach mood established, studied and reimplemented rather than copied. Slipgate extends it to multiple engines behind a single launcher.

Prior art

mood

Charlie Tapping's proof that Doom runs from Kotlin Multiplatform via a wasm runtime. The spark for this whole project.

Runtime

Chasm

The Kotlin Multiplatform WebAssembly runtime that executes every engine module on every platform.

Engines

Chocolate Doom

The conservative, historically-accurate port carrying Doom, Heretic, Hexen and Strife — and decades of contributors' care.

Engines

Mark V WinQuake

Baker's Quake port, the QuakeDroid lineage — the engine behind the Chthon gate.

Free data

Freedoom & Blasphemer

Freely licensed IWADs that let the Mars and Corvus gates run with nothing purchased.

The originals

id Software & Raven Software

Doom, Quake, Heretic, Hexen — the games that made source ports a culture, released under the GPL so all of this could exist.

Slipgate is built by Jackson F. de A. Mafra. Doom, Heretic, Hexen, Strife and Quake are trademarks of their respective owners; Slipgate is an unaffiliated open-source launcher and ships none of their data.