REGION Nordholm ValleyPOS 64°11′N 14°22′ETEMP −8°CWIND NNE 24km/hDAY 01
Everything out here is trying to cool you to the temperature of the snow. Warmth is the only thing you really own — and the valley keeps asking for it back.
01 — SURVIVAL
Warmth is a resource you spend
Cold, wet, hunger and exhaustion each pull on the others. Let your core temperature fall and hypothermia sets in; frostbite takes fingers; damp gear stops insulating. Fire, food and shelter aren't features — they're the loop.
HypothermiaFrostbiteWet gearAfflictions
02 — WORLD
A valley built by hand, not spawned
Nordholm Drift Mine. Site 7. A radio mast that shouldn't still have power. Landmarks are authored, not scattered — each one is somewhere to reach, read, and figure out what happened here before you did.
Authored landmarksEnvironmental storyFast travel
03 — THREAT
You are not the only thing awake
Wolves hunt in packs, bears and moose hold their ground, and something colder keeps watch near the mine. Read tracks, pick fights you can win, and know when the smart move is simply to be somewhere else.
Pack AIHuntingPredatorsThe Warden
04 — PROGRESS
Shelter, craft, and dig in
Turn a wreck and a treeline into a foothold: light fires, cook what you hunt, craft tools and warmer clothing, and set snares while you sleep. Every night survived is ground you don't have to take twice.
CraftingCookingTrapsPerks
Captured in engine
The valley, in stills
Every frame is the live game — a stylized low-poly winter rendered in real time.
Wreck site · first lightNordholm Drift Mine · Site 7Trapper's cabin · nightStalking the herdField camp · nightfall
Behind the build
A from-scratch game engine, hiding under the snow
No off-the-shelf engine. Frostwake is a custom TypeScript ECS driving a deterministic simulation through a hand-rolled Three.js renderer — 80+ independent systems held together by a typed event bus.
A survival game is a lot of small systems arguing about one player. This is how Frostwake keeps that argument fast, deterministic, and buildable by many hands at once — a from-scratch TypeScript engine, no off-the-shelf framework doing the heavy lifting.
01 — The game
A frozen valley, a dog, and a signal
Frostwake is a top-down survival game set in Nordholm Valley, a Nordic wilderness after a bush-plane crash. The core loop is the honest survival one — manage warmth, water, food and rest against weather and injury — but it's wrapped around a place with a history: an abandoned drift mine, a radio mast still transmitting, and a companion husky you keep alive alongside yourself.
Progression is spatial. You push out from the wreck to authored landmarks, each a small story beat and a survival problem: how far can you get before dark, how much warmth does the trip cost, and what's waiting when you arrive. Perks, crafting and better gear widen your range; the valley's threats — and something colder near the mine — keep pushing back.
02 — Architecture
An ECS built to be worked on in parallel
Everything in the world is an entity — a bag of optional components, which are pure data. Behaviour lives in systems: plain functions of the shape (world, dt, ctx) => void that query for the components they care about and mutate them. That's the whole model.
The rule that makes it scale: systems never import each other. They coordinate only through shared components and a typed event bus — a system reacts to damaged or fireLit without knowing who emitted it. Decoupling like this isn't just tidy; it's what lets many separate coding sessions build different systems at once without colliding. Each new system is one line in the registry.
03 — Rendering
Top-down look, real 3D underneath
The game reads as a clean 2D top-down world, but it's rendered in genuine 3D through Three.js with an orthographic camera — that's what gives the crisp, flat, readable silhouette while still allowing real geometry, height and dynamic light. Gameplay stays honest 2D in pixel space; the render layer maps those coordinates onto the ground plane via a single WORLD_SCALE constant and a height function.
The hard part is volume. A valley holds tens of thousands of static props — trees, rocks, scatter. Walking that whole set every frame would stall, so the renderer keeps an active set and freezes static chunks: props that never change are baked into per-cell groups and stop updating, while anything that can move or change stays live. A winter shader, tree-reshaping and instancing sit on top for the snow-blown look.
1/48
World scale
~50k
Entities in a valley
480
Worldgen grid
O(n)
Placement, area-scaled
04 — Simulation
Deterministic on purpose
The simulation runs on a fixed 1/60-second timestep with an accumulator, decoupled from render framerate. Given the same seed and the same inputs, it produces exactly the same run — every time. That's enforced, not hoped for: gameplay randomness only ever comes from a seeded ctx.rng, and sim code is forbidden from reading the wall clock. A unit test fails the build if either rule is broken.
Determinism buys three things at once: tests can assert on outcomes, bugs reproduce from a seed instead of a shrug, and the door stays open to lock-step co-op later — the codebase already avoids assuming a single player and gives every networked entity a stable id.
Why it matters
“It only crashes sometimes” is the most expensive sentence in games. A deterministic sim turns intermittent into reproducible — you replay the seed and watch it happen.
05 — Tooling
The game can be driven — and can play itself
Frostwake ships with an unusually deep verify loop. The dev build runs in an Electron window with a live debug port, so a script can reach into the running game: teleport the player, set the weather, spawn a wolf pack, then screenshot or record a clip — every marketing still on the home page was captured this way.
Agent-play harness — a scripted “player” that can navigate, gather, craft, fight and survive, used to smoke-test the game end to end without a human at the keys.
Playlog + QA monitor — every run logs survival snapshots and flags physics anomalies (stuck-in-solid, wedged, out-of-bounds) automatically.
In-app map editor — author and place landmarks live inside the running world.
Vite · Vitest · CI — instant reloads, unit tests mirroring each system, and a pipeline that gates every change on type-check, tests and dead-code.
06 — Scope
Eighty systems and counting
Survival, afflictions, fire, weather, crafting, cooking, hunting, AI and combat, save/load, fast-travel, a journal, a perk tree, a full render pipeline, an editor — 80+ systems, each in its own file, each individually testable. Content is data, not code: items, recipes, enemies and biomes are JSON, so the world grows by adding files rather than editing engine internals.
It is, deliberately, a game first and a systems-engineering showcase second — but the two are the same artifact.