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 Blood Moon horde that comes for you every seventh night until you find a way off.
Touch controls are live. Turn your phone sideways for the movement stick, aiming, action buttons, pack and building controls.
The loop
A day is short. The Blood Moon 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.
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.
You get one minute
A warning, and then it is dark. Ordinary nights reward quiet routes and broken sightlines. When the moon is wrong, wall yourself in, lay spikes, light a fire — or find a ruin with one doorway and barricade it with your own build menu.
Only the Blood Moon knows
Ordinary infected follow sight, sound and local alerts; darkness alone does not summon them. Every seventh night the Blood Moon starts a deliberate swarm. Its flow field is rebuilt around you every 0.28 seconds, with your walls costing extra, so the horde funnels to gaps instead of clipping through.
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.
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
23 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.
117 items, 89 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. It keeps a closed set rather than a bigger search budget, because the failures were not searches that ran out of room — they were the same cells being settled over and over.
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 — once autumn is in, at least. A summer night never gets cold enough to hurt you, which is the week the game gives you to learn.
10 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 two kilometres of 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 asset files. The game downloads nothing.
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.
- 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
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 about 5,500 lines of hand-written WebGL across four modules — the context and matrix layer, the primitives, the scene builder and the renderer — covering 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.
It falls back to WebGL 1 when WebGL 2 is not there, and that path is tested rather than theoretical. Frame time, triangle and draw counts are on F3 — read them on your own machine rather than taking a number from mine, because that is the only reading that describes the hardware you are actually playing on.
- EngineNone. Custom renderer, custom everything
- DependenciesZero. No npm, no bundler, no CDN
- Asset filesZero. Meshes, icons, audio all generated
- RequestsOne for the page, plus first-party reports — on by default
- 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 and the same height cuts, running at map scale in this page. One honest simplification: the game picks its woodland cut as a per-seed quantile so the share stays steady across islands, and the demo uses a fixed threshold instead.
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 authored map data in the file — the whole island starts with 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
117 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
- touch-device notice
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 a device-aware start 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, pad or touch.
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. On a phone, a movement stick, aim area and contextual buttons cover the same run in landscape.
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
- Desktop and mobile browsers with WebGL. No install.
- Controls
- Keyboard and mouse, gamepad, or touch. Phones play in landscape.
- Price
- Free, in public playtest
- Developer
- Solo
- Engine
- None — hand-written WebGL renderer
- Size
- 1791 KB, one HTML file, one request
- Source
- Around 36,600 lines of JavaScript across 48 files
- Languages
- English
- Status
- Playtest — build 0.1.0
Built with
The tools behind the build.
Links marked affiliate pay this project a commission if you subscribe through them. That is the whole arrangement — nobody paid for placement, and nothing appears here that did not build the game.
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?
Yes. Touch controls cover movement, aiming, combat, the pack and building controls. Play in landscape so the wider interface fits. This is still a public playtest, so the phone layout may have rough edges worth reporting.
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 the live copy is per-browser, and clearing site data deletes it. The title screen can export a pasteable save blob and import it elsewhere. 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 third-party analytics, advertising tracker or third-party line of code
is in the game — that is a property of the build rather than a promise about
a future one. The bundle does contain first-party reporting. It has exactly
one URL, and it is ours: reports.hollowmast.com. The game
fetches nothing from anyone else.
One honest caveat if you check with devtools rather than by reading the file:
the claim is about the file, and a host can wrap the file. When
Cloudflare's bot protection is on it may inject its own script tag into the page it
serves here, and itch.io appends its player wrapper to the copy it serves — neither
is in the build, and the game calls neither. Save the page and diff it against the
file, or count its <script> tags: the build has one.
One honest asterisk, because you are going to open devtools anyway: our host
adds a script we did not write. Cloudflare injects its bot check
(/cdn-cgi/challenge-platform/…) into pages it serves, so the page you
get from hollowmast.com is about 900 bytes larger than the file in the
repository. That is the CDN, not the game — the build is byte-identical either way,
and the copy you download from itch.io does not have it. We would rather say so here
than have you find it and wonder what else was rounded off.
This website is a different thing: it can run Google Analytics, and only after you accept it on the banner; it is expected to be funded by advertising eventually, behind the same banner. The privacy policy says exactly what that means.
That one URL is the first-party reporting layer, live since 18 August 2026. It records crashes, bug notes, funnel milestones and session summaries. Reporting defaults on. In the current build, opening the game queues a loaded milestone and a GPU-class report before the saved setting is read. The Settings → Send anonymous reports switch is on the title screen and stops every later report before a run starts. Reports carry no name, email or account, but they do carry a stable install identifier, browser details, graphics card and the request country. Every recorded 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.