HOLLOWMAST

Build  •  Craft  •  Hold the night

A post-apocalyptic survival game that runs in one HTML file. An island the generator has never built before, a base you raise out of it, and a horde that comes for you every night until you find a way off.

Play in your browser How it's made No install  ·  no account  ·  1072 KB, then it's yours offline

HOLLOWMAST needs a keyboard. It loads fine on a phone, but there's no way to move yet — a touch control scheme is honest future work, not a shipped feature.

Copy the link and open it on a desktop.

Scroll
1072KB
One file
0
Dependencies
0
Asset files
224²
Tile island
23.6k
Lines of JS
~8ms
GPU / frame

The loop

A day is short. The night decides whether you kept it.

Nothing here is on rails. The island is seeded fresh, the tutorial gates on what you actually did rather than what you clicked, and the clock does not wait for you to be ready.

06:00 — Day

Take the island apart

Chop, mine, forage, and strip ruins for what people left. Every swing feeds a workbench, a forge, a chem station — and the tier of gear they unlock.

19:00 — Dusk

You get one minute

A warning, and then it is dark. Wall yourself in, lay spikes, light a fire — or find a ruin with one doorway and barricade it with your own build menu.

21:00 — Night

They path to the door

A flow field rebuilt around you every tick, with your walls costing extra — so they funnel to the gaps instead of clipping through. Every seventh night is a Blood Moon and all of them know exactly where you are.

And eventually

Out

Sixteen sectors, all of them holding nests — the only thing in the game that breeds infected. Clear them and the ground genuinely quiets. Repair three radio masts and something answers, names an evacuation site, and asks you to hold it for two minutes.

One run, in order

Seven days on one island.

Three moments from a single seed, in the order they happened. The clock in the top right is the game's, not ours.

8:19 AM Day 1 Clear
A four-storey ruined block seen from a high angle in morning light. The near wall
                      has dissolved into a dither pattern, showing the survivor standing inside on an
                      upper floor holding a torch, with the floor slabs and stairwell visible through
                      the cutaway. A tarmac road with a dashed centre line runs past on the left,
                      between trees and grass.
You go inside buildings, not up to them. The wall between you and the camera dissolves rather than swinging the view around, so a four-storey block is four floors of rooms to search — and whatever is already in them.
9:56 PM Day 1 Rain, fog
Night, heavy rain and fog. A walled compound of stone blocks encloses a lit
                      campfire, a bed, workbench, forge and storage crates. Rain streaks fall across a
                      fogged treeline. Floating damage numbers show turrets firing at attackers beyond
                      the north wall. The counter in the corner reads nineteen hostiles.
The first night you have walls for. Rain drops visibility and the fog comes in with it. The numbers over the wall are turrets doing 16 a shot to things you can't see yet.
7:15 PM Day 7 Blood moon
The same compound under a blood moon, everything washed deep red. A wall section
                      on the north side has been destroyed and infected are pouring through the gap
                      into the courtyard, where the campfire still burns. Damage numbers float over
                      the breach. The counter reads fifty-two hostiles with thirty-five more coming.
Night seven does not care about your wall. Fifty-two through the gap and thirty-five still walking in. The stone held for six nights; it is going to be gone by morning, and the workbench is on the wrong side of it.

What's actually in it

Not a prototype with one good idea in it.

Every number below is read out of the shipping build, not estimated.

Base building with a power grid

20 buildables — walls, doors, spikes, wire, stations, storage, beds, rain catchers, farm plots, torches, flood lamps, generators, and ammo-fed auto-turrets that need feeding and wiring.

107 items, 80 recipes

Across four crafting stations plus what you can make by hand, gated by level and by what you're standing next to. Tools wear, ammunition runs out, and the good tier is always one station away.

An island, seeded fresh

224×224 tiles, coast through plains and deep woods up to bare highland rock, 26 points of interest across nine kinds, and a UK-standard road network laid as splines that bend to follow the contours rather than cutting across them.

The island you can ask for

A typed seed — a word is hashed, a number the game printed is taken as itself — then six presets and nine multipliers the generator reads instead of nine constants. Every one defaults to exactly 1, and that default has to regenerate the old island tile for tile: saves written before the config existed carry none, so a default that is not an exact identity quietly loads a different world under a player standing on the same coordinates.

A spine that added no systems

Eleven beats across the 28-day year, one open at a time and never two. It opens no panel, places no marker and invents no subsystem — every beat drives something that already shipped, and arrives through the objective line, the existing banner and the tutorial's own card slot. Nothing blocks, nothing is failable in a way that ends a run, and a run that ignores it never sees a nag.

Routes, not headings

A* across all 50,176 tiles on a binary heap, with an octile heuristic scaled by the fastest tile on the board so it stays admissible, and a door priced at three tiles because you stop to open it. Resolution is one tile rather than two: a compound doorway is exactly one tile wide, and at two every building on the island reads as sealed. The search cap was 40,000 pops and all 1,916 failures in three nine-day runs ended on it — 93% of that budget spent re-expanding cells already settled, so it took a closed set rather than a bigger number.

Ten kinds of infected

Screamers summon, spitters kite and throw acid, stalkers cloak, bloaters burst into gas, brutes charge, juggernauts are a boss. Any of them can roll one of five elite affixes that change the silhouette, the stats and the death.

Survival that actually interlocks

Hunger, thirst, temperature, wetness, bleeding, infection, sickness, stamina and encumbrance all feed each other. Caught out on a wet night with no fire, the cold alone kills you in about seventy seconds.

Nine vehicles, and they break

Gated behind progression, and each one has to be found, repaired, fuelled and kept running before it will take you down the 6.4 km of trunk road.

The Record — 24 things left behind

Tapes from the staff who were meant to be in charge, torn pages from the people who were not. Seeded to the world, so a given island always hides the same object in the same place — and nothing on the HUD points at any of them.

Other people, briefly

A wandering trader with rolling stock who does not wait long, and downed survivors you can revive and recruit — up to four, each taking one of three standing orders. They shoot, they take hits, and they bleed out if you leave them.

Weather you have to answer

Rain that fills your catchers and muffles sound, fog that hides what's in it, ashfall that takes your sight away, lightning, and a live wind value that leans every canopy and lays the whole grass field over at once.

How it's made — the interesting part

No engine. No assets. Nothing downloaded but the page.

Every mesh, every sound, every note of the score, every UI icon and every tile of the island is generated in your browser at runtime. There is no three.js, no shader pack, no texture atlas, no audio file, and no third-party line of code anywhere in the build.

src/ — 36 files, one shared scope
  • 00_core.jsmath, RNG, noise, colour, containers
  • 05_audio.jsWebAudio synthesis — every SFX and the adaptive score
  • 15_fx.jsparticles, decals, damage numbers, camera rig, hitstop
  • 20_items.jsitems, recipes, structures, perks
  • 25_world.jsworldgen, biomes, points of interest
  • 30_art.jsitem icons and the paperdoll, drawn with canvas paths
  • 35_entities.jsplayer, infected, flow field, projectiles, fire, gas
  • 43_meta.jssectors, the radio chain, the evac finale
  • 46_gl.jsmat4 maths, a thin WebGL 1/2 wrapper with instancing
  • 47_geom.jsunit primitives, mesh builder, instance batches
  • 48_scene.jsterrain heightfield, chunk meshes, every world model
  • 50_render.jsshaders, shadow + main passes, sky, water, weather
  • 60_ui.jsHUD, inventory, crafting, build, skills, map, menus
  • 70_game.jsstate machine, day cycle, input routing, main loop
…and 22 more. build.sh concatenates them in numeric order into one self-contained HTML file. That is the entire toolchain.

The renderer is the point

It is roughly 4,600 lines of hand-written WebGL: instanced low-poly meshes at one draw call per primitive, a chunked terrain heightfield with baked grass, a 2048² PCF shadow map that follows the player, hemispheric ambient plus a wrapped sun, the eight nearest point lights per pixel, a raymarched sky with a drifting cloud deck, depth-shaded water with shoreline foam, and exponential-squared fog.

About 8 ms of GPU per frame at full zoom-out with ~560k triangles on screen — half the 60 fps budget, on a WebGL 1 fallback path that works when WebGL 2 isn't there.

  • EngineNone. Custom renderer, custom everything
  • DependenciesZero. No npm, no bundler, no CDN
  • Asset filesZero. Meshes, icons, audio all generated
  • RequestsOne for the page, plus anonymous reports unless you turn them off
  • Your dataSaves stay in localStorage; run reports go to hollowmast.com
  • Build stepOne bash script that runs cat

Proof, rather than a claim

This is the generator. Press it.

The island isn't picked from a set of maps. It's computed, and the code doing it below is the game's own — the same noise, the same island falloff, the same biome thresholds, running at map scale in this page.

seed 224 × 224

What you're watching

Three noise fields are laid down first — height, moisture, and ash. The height field is domain-warped before it's sampled, so inland ground breaks into ridges and hollows instead of smooth blobs, and a radial falloff pulls the edges under the sea so the map is an island rather than a slab. A ridged fractal goes on top of that for the highlands.

Then every one of the 50,176 tiles is classified from those three numbers alone. There is no map data anywhere in the game — the whole island is these few lines of arithmetic, which is why it costs nothing to carry and why no two are the same.

  • Height < .20Deep water — the only impassable terrain
  • < .31Shallows, then the beach
  • > .655Gravel, then bare rock — the Highlands
  • Moisture > .60Deep Woods, where the canopy closes over
  • OtherwisePlains — grass and tall grass, most of the island

Roads, the sixteen sectors, 26 points of interest and every nest are placed on top of this and aren't drawn here. Shading is by height, so the relief reads at map scale.

Build log

How it got here.

In the order it was built, which is the only order there is a record of — this was a folder on one machine, not a repository, and nothing kept a changelog until there was a version number to put in one. So the rows below are a sequence, not a calendar, and only the row with a date on it has one because that date was written down at the time.

Order · 01The engine

A renderer first, because everything after it depends on one

  • 00_core
  • 46_gl
  • 47_geom
  • 48_scene
  • 50_render

Buffers, shaders, camera, culling and the geometry layer every model in the game is assembled from. No three.js underneath it and no meshes to load, so the first problem to solve was making solid shapes out of arithmetic — which is also why there are no assets to download later.

Order · 02The world

224² tiles of island, generated the moment you press New Game

  • 25_world
  • 30_art
  • 42_interior
  • 49_ambience

Height, moisture and ash noise fields into biomes; a trunk road network laid over them; points of interest with buildings you can walk inside. Then the art layer that turns all of that into meshes, and the sky, weather and sound that sit on top.

Order · 03The game

Everything that turns a world into a run

  • 20_items
  • 35_entities
  • 37_npc
  • 39_relic
  • 40_build
  • 43_meta
  • 44_events
  • 45_systems

107 items and the crafting ladder that gates them, ten kinds of infected with their own behaviour, survivors and a trader, relics and set bonuses, base building, and the sector campaign that ends with an evacuation you have to hold a position for.

Order · 04The shell

The parts you actually touch

  • 60_ui
  • 15_fx
  • 10_input
  • 11_pad
  • 65_save
  • 67_intro
  • 68_tutorial

The HUD and every panel behind it, saves, the opening cutscene, a tutorial that unlocks in steps rather than front-loading, and full gamepad support — which was cheap only because every hit test in the game already ran against a cursor position, so the pad drives a virtual one and no panel needed rewriting.

16 Aug 20260.1.0

The build stopped being only mine

  • version stamp
  • save format check
  • crash-loop guard
  • crash reporting
  • cheated-run flag
  • desktop-only gate

Not one feature in that row. It is the work that has to exist before anyone else can play the thing: a build string in every report so a bug can be pinned to bytes; a save that refuses to open rather than deleting a run when the format changes; a render loop that halts on the first exception instead of repainting the error sixty times a second; a flag on any run that touched the dev console, so the balance data stays worth reading; and an honest screen for anyone who arrives on a phone. The game was named HOLLOWMAST the same day.

Everything above 0.1.0 is ordered by src/, which is numbered in the order it was written and loaded in that same order. From 0.1.0 onward each build carries a stamp instead — this page is describing build 0.1.0, and so is the game one click away. What is coming next is on the other page.

Controls

Keyboard and mouse. Or a pad.

Movement is camera-relative — W always walks away from you, whichever way the camera is facing. There are three cameras and X cycles them: tactical, over the shoulder, and a genuine first person you can fight from. An Xbox pad is fully supported and drives a virtual cursor, so every panel works without a mouse.

WASDMove
ShiftSprint — costs stamina
SpaceDodge roll, with i-frames
ClickAttack, gather, place
EInteract — doors, crates, stations, beds, farms, masts, people
18Hotbar
TabInventory and gear
CCrafting
B VBuild menu · toggle build mode
PSkills — twelve of them
MWorld map
JThe Record — what you've recovered, and what it says
R F QReload · quick-heal · drop
XCamera — tactical, over the shoulder, first person
WheelZoom · middle-drag to orbit · H resets

Fact sheet

For anyone writing about it.

Title
HOLLOWMAST
Tagline
Build. Craft. Hold the night.
Genre
Top-down survival · base building · roguelite run structure
Platform
Any desktop browser with WebGL. No install.
Requires
A keyboard. There is no touch scheme yet.
Price
Free, in public playtest
Developer
Solo
Engine
None — hand-written WebGL renderer
Size
1072 KB, one HTML file, one request
Source
Around 23,600 lines of JavaScript across 36 files
Languages
English
Status
Playtest — build 0.1.0

Questions

The honest answers.

Is it really free?

Yes, and there is nothing to buy in it. It's in a public playtest — the point right now is to find out where people stop playing and why. Whether it ever becomes a paid thing is a decision for after that, not before it.

Does it work on my phone?

It loads, and then you can't move. Every control is keyboard or pad, and a proper touch scheme is real work that hasn't been done. Rather than let you find that out the hard way, the game tells you up front and asks you to come back on a desktop.

Where do my saves go?

Into your browser's localStorage, on your own machine. Nothing is uploaded and there is no account to make.

That does mean saves are per-browser, and clearing site data clears them. Saves are version-stamped: when the format changes, an old save is refused rather than eaten — you'll be told which build it came from instead of losing the run to a crash.

What gets sent back to you?

No analytics, no tracker, and no third-party line of code — that is a property of the build rather than a promise about a future one, and it is the claim worth checking. The whole bundle contains exactly one URL, and it is ours: reports.hollowmast.com. Nothing is fetched from anywhere, by anyone else, ever. This website carries no third-party code today either, though it is expected to be funded by advertising eventually; the privacy policy says what that will and will not mean.

That one URL is the reporting layer, and since 18 August 2026 it is live — anonymous crash reports, a bug-report key, and a session ping carrying the build number and how far you got. It is on unless you turn it off. The switch is in Settings on the pause menu, and it stops the sends outright rather than merely hiding them. Being honest about the awkward part: a run has to be under way before you can reach it, because there is no route to Settings from the title screen yet. No accounts and no personal data — though the report does carry your browser, your graphics card and the country the request came from, and every field is listed.

Every field it would send is listed on the support page, along with the ones it never will.

Why one HTML file? Isn't that a gimmick?

It started as a constraint and turned into the design. No asset pipeline means no asset budget, so the island, the meshes, the icons and the music all had to be generated — which is why every run looks different and why the whole game fits in less space than a single texture would take.

It also means you click a link and you are playing, on any machine, forever, with nothing installed and nothing to uninstall.

How long is a run?

The first Blood Moon lands on night seven. A run ends when you die, or when you repair all three radio masts, hold the evacuation site for two minutes, and leave — which is a long way past night seven.

It's running badly. Anything I can do?

Zoom in — the cost is almost all in how much island is on screen at once. F3 shows frame time, triangle and draw counts if you want to see where it's going. The renderer falls back to WebGL 1 on machines without WebGL 2, and that path is tested rather than theoretical.

It's one click away. That was the whole idea.

No launcher, no account, no download, no patch. The island is generated the moment you press it, and it has never existed before.