Motherload came out in 2004 and I still think about it. You pilot a little drill rig into the earth, fill your cargo hold with ore, fly back to the surface, sell it, buy better equipment, and go deeper. That is the whole game. It is perfect.
This is a version of that idea that runs right here, in your browser, on your phone or on your desktop. No install, no app store. Just a canvas element and about 500 lines of JavaScript.
The game
Drill downward through layers of earth. Collect ore, return to the surface station to sell it and refuel. Spend your earnings on upgrades: a stronger drill, bigger fuel tank, tougher hull, and more cargo space. See how deep you can go before your hull gives out.
On mobile, two transparent d-pads appear in the bottom corners. Swipe the direction you want to go. Drive up to the station to enter the shop, or roll over the pump pad to refuel and sell your cargo on the move.
The layers
The world is 40 tiles wide and 200 tiles deep, divided into eight depth bands. Each layer has its own palette, its own ore distribution, and a couple have nasty surprises waiting for you.
| Layer | Depth | Notes |
|---|---|---|
| Topsoil | 0–15m | Loose dirt and roots. Coal and copper. |
| Bedrock | 15–35m | Bauxite, iron, the first silver. |
| Permafrost | 35–55m | Frozen solid. Requires the Heated Drill upgrade or you cannot break a single tile. Methane ice deposits hide here. |
| Fossil layer | 55–80m | Ancient sediment. Amber with insects, trilobite fossils. |
| Deep crust | 80–110m | Cinnabar, gold, and the first uranium veins. |
| Magma veins | 110–145m | Glowing red rock. Without a Heat Shield, your hull drains continuously while you are inside. |
| Crystal caves | 145–180m | Tanzanite, more diamonds. The walls glitter. |
| Mantle edge | 180–200m | Painite and unobtanium. Even worse heat than the magma layer. Endgame only. |
What is down there
Eighteen things to mine, give or take. Some are real, some are deliberately not. Where the real ones are concerned I have played a little fast and loose with relative values, but the general ordering — copper before silver before gold before tanzanite before painite — is roughly how the world works.
| Ore | Value | Found in | Notes |
|---|---|---|---|
| Coal | $5 | Topsoil → bedrock | Cheap and common. |
| Copper | $12 | Topsoil → bedrock | Starter cash. |
| Bauxite | $25 | Bedrock | Aluminum ore. |
| Iron | $35 | Bedrock → deep crust | Ubiquitous. |
| Pyrite | $60 | Bedrock | Fool's gold — looks valuable, isn't. |
| Silver | $90 | Bedrock → deep crust | |
| Methane ice | $180 | Permafrost | Heated drill required. |
| Cinnabar | $140 | Deep crust | Mercury ore. Crystal clusters. |
| Gold | $200 | Deep crust | The real thing. |
| Amber | $350 | Fossil layer | Insect trapped inside. |
| Trilobite | $600 | Fossil layer | Half-billion-year-old arthropod. |
| Uranium | $800 | Deep crust | Glows. Requires drill Lv 3. |
| Obsidian | $280 | Magma veins | Volcanic glass. |
| Emerald | $900 | Fossil → crystal | |
| Ruby | $1,400 | Deep crust → crystal | |
| Tanzanite | $2,000 | Crystal caves | Real, found only in Tanzania. |
| Diamond | $3,000 | Crystal caves | Requires drill Lv 4. |
| Painite | $6,000 | Mantle edge | Real, briefly the world's rarest gem. |
| Unobtanium | $12,000 | Mantle edge | Not real. Sue me. |
Dirt and stone are not in this table because you do not collect them — they are rubble. You drill them, they disappear, you move on. The shop has six upgrades: drill, fuel, hull, cargo, plus a one-time Heated Drill purchase (gates the permafrost) and a two-tier Heat Shield (lets you survive the magma and mantle layers).
The stack
There is no stack, really. That is the point. One HTML file, one
CSS file, one JavaScript file, and an <canvas>
element. No build step, no bundler, no framework, no
node_modules. The whole game is about 900 lines in
an IIFE, served as a static file. If you can open it in a
browser, you can run it.
Everything renders with the 2D canvas API — fillRect,
createLinearGradient, arc, the usual
suspects. State is plain objects. The game loop is
requestAnimationFrame with a delta-time
update(dt) followed by render(). Input
is keyboard listeners on desktop and a virtual d-pad I draw onto
the canvas itself for touch. That is the whole architecture.
Three pieces of code I like
Depth-biased ore generation
The world is generated once at startup. Every tile rolls against a list of candidate ores filtered by depth, with rarer ores getting slightly better odds the deeper you go. The trick is walking the candidate list from rarest to most common — that way diamond gets first dibs on the random number, and common dirt only gets picked when nothing rarer has claimed the roll.
function pickOre(depth) {
var candidates = [];
for (var i = 0; i < ORE_KEYS.length; i++) {
var o = ORES[ORE_KEYS[i]];
if (depth >= o.minDepth) candidates.push(ORE_KEYS[i]);
}
var r = Math.random();
// Deeper = rarer ores more likely. Walk from rarest to common.
var cumul = 0;
for (var j = candidates.length - 1; j >= 0; j--) {
var ore = ORES[candidates[j]];
var adjustedChance = ore.chance * (1 + depth * 0.003);
cumul += adjustedChance;
if (r < cumul / (cumul + 1)) {
return { type: candidates[j], hp: ore.hp };
}
}
if (Math.random() < 0.12) return null; // air pocket
return { type: 'dirt', hp: ORES.dirt.hp };
}
The cumul / (cumul + 1) bit is a soft normalization
trick: it keeps the running probability bounded between 0 and 1
without having to know the total ahead of time, while still
preserving the rare-first ordering. The depth multiplier
(1 + depth * 0.003) is small but compounds — by 150
metres down, rare ores are getting a 45% bonus.
Collision against a tile grid
There is no physics engine. The whole world is a 2D array of tiles, and the player is an axis-aligned rectangle. To check if the player overlaps anything solid, I floor-divide its four corners by the tile size and look up every cell in the range:
function solidAt(px, py, w, h) {
var c1 = Math.floor(px / TILE);
var c2 = Math.floor((px + w - 1) / TILE);
var r1 = Math.floor(py / TILE);
var r2 = Math.floor((py + h - 1) / TILE);
for (var r = r1; r <= r2; r++) {
for (var c = c1; c <= c2; c++) {
var t = tileAt(r, c);
if (t === 'wall' || t !== null) return true;
}
}
return false;
}
Movement then becomes: tentatively move on X, check; if blocked, don't move and zero the X velocity; do the same for Y. Separating the axes is what stops the player from slipping into corners diagonally, and it is what lets you slide along walls smoothly. The whole movement function is maybe 25 lines.
Touch d-pad as an angle sweep
On mobile, the d-pad is just two transparent circles drawn at
the bottom corners of the canvas. There are no actual buttons.
When a touch lands, I take the vector from the d-pad center to
the touch and use atan2 to slice it into four
directions:
function updateDpad(x, y) {
dpad.left = dpad.right = dpad.up = dpad.down = false;
var dx = x - DPAD_CX;
var dy = y - DPAD_CY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < DPAD_SIZE * 0.85) {
var a = Math.atan2(dy, dx);
if (a > -0.7 && a < 0.7) dpad.right = true;
if (a > 2.4 || a < -2.4) dpad.left = true;
if (a < -0.7 && a > -2.4) dpad.up = true;
if (a > 0.7 && a < 2.4) dpad.down = true;
}
}
atan2 returns an angle from -π to
π. The 0.7 cutoffs (about 40°) carve the circle
into four wedges with no dead zones between them. Drag your
finger around inside the d-pad and the direction follows
smoothly — there is no concept of "lifting off one button and
pressing another." It feels much better than literal buttons,
and it is six lines of math.
How it all fits together
The camera follows the player with a smooth lerp
(cam.x += (target - cam.x) * 0.12). Drilling sets a
timer on the target tile and subtracts hit points based on
drill level — when HP hits zero, the tile is replaced with
null and the ore goes into your cargo array. Every
valuable ore gets a small white square drawn in the corner so
you can spot it underground.
Strategy
Early game: drill straight down through topsoil, sell coal and copper constantly, and rush the fuel upgrade. Your starting tank barely gets you to 30 metres and back. Once you have fuel level three or four, you can start going after silver and gold. The pump pad outside the shop refuels and sells your cargo automatically when you drive across it — you never actually need to enter the shop just to refuel.
Mid game: hit the permafrost wall around 35 metres, head back up, and save for the Heated Drill. Without it you cannot break a single tile in that layer — not even dirt. Once you punch through, the fossil layer pays well: amber and trilobite fossils sell for hundreds. Uranium starts showing up around 80 metres but needs drill level 3 to chip at.
Late game: the magma layer at 110 metres is genuinely hostile. Without a Heat Shield, your hull drains every second you spend inside, regardless of whether you are drilling. Buy at least the Mk 1 shield before you commit. Below that, the crystal caves are mostly safe and full of tanzanite and diamond. The mantle edge at 180 metres is worse than the magma layer and holds painite and unobtanium — do not go down there without Mk 2 shield, max drill, and a full tank.
And cargo, always cargo. A single painite is worth $6,000 but if your hold only fits five items, you are making a lot of round trips. Max it out and each run to the deep zone pays for itself many times over.