← All work

Frostwake: survival in a frozen valley, on an engine we built

A top-down survival game about a plane crash, a frozen valley and the cold. We built it without an off-the-shelf game engine, in TypeScript and Three.js, as R&D in real-time 3D rendering and in how many parallel AI coding sessions one codebase can take.

Status
In development
Engine
Custom: TypeScript, Three.js, Miniplex ECS
Simulation
Deterministic, fixed 1/60 s step
Source
Private — walkthrough on request
Frostwake artwork
The survival setting: a frozen valley.

What's in it

Cold as the main enemy

Cold, wet, hunger and exhaustion pull on each other. Fire, food, shelter and layered clothing make up the loop, with afflictions such as hypothermia and frostbite.

A large world with many regions

A world grid of 480 with lakes, forests, mountains, a town, caves and camps, plus building interiors, fast travel and a map with fog of war.

Hunting and set-piece fights

Wolves that hunt in packs, bow hunting, snares and bait, and telegraphed attacks you can kite, up to a boss fight with the Warden.

The Drift

A slow contamination clock that rises with time in the valley. As it climbs, your aim starts to shake and your compass starts to lie, and in the end it decides how the story ends.

Deterministic, and enforced

Same seed, same world, same run. All randomness goes through a seeded generator, simulation code may not read the clock, and a test fails the build if either rule breaks.

A game that can play itself

The dev build runs in an Electron window with a debug port, so scripts and an AI playtest brain can drive the game, set up scenarios and capture screenshots.

Relevant if you're looking for…

Frostwake is R&D and still in development, so it is mainly of interest to survival fans and to anyone building 3D games in TypeScript.

  • Survival where the cold is the main enemy: cold, wet, hunger and exhaustion pull on each other, and fire, food, shelter and layered clothing make up the loop.
  • A Three.js game engine that copes with a big world: the valley holds tens of thousands of props, and static scenery is frozen into per-cell chunks that the renderer can skip.
  • Three.js game development at scale: more than 80 gameplay systems that never import each other, a deterministic 1/60 s simulation step, and 663 automated tests at v0.1.0.

We build this for clients: Custom software and internal tools

How the engine works

  1. 01

    Components

    Every entity is a bag of plain data.

  2. 02

    Systems

    One function each; systems never import each other.

  3. 03

    Events

    Systems coordinate through a typed event bus.

  4. 04

    Render

    A fixed 1/60 s simulation step, then Three.js draws the frame.

How it's built

Frostwake is an entity-component-system on Miniplex. Systems are plain functions that never import each other and talk only through shared components and a typed event bus, so separate AI coding sessions can own separate systems and build them in parallel without stepping on each other. Adding a system is one line in the main loop.

The hard part was performance at scale: the valley holds tens of thousands of static props. The renderer keeps a small active set and freezes static scenery into per-cell chunks that Three.js can skip, which removed a per-frame walk that cost about 9 ms. World generation places props in O(n) with a spatial hash, so generation time grows in step with the map.

Engineering highlights

  • 80+ gameplay systems
  • 663 automated tests at the v0.1.0 baseline, including a determinism test
  • CI on every pull request: type-check, tests and a dead-code scan
  • Content as JSON: a new item is a new file, with no code change
  • Prepared for multiplayer: stable entity ids and no single-player shortcuts

Questions

Can I play Frostwake?

Frostwake is still in development, and frostwake.agentas.net is its home page.

What engine is Frostwake made in?

An engine we built ourselves, with no off-the-shelf game engine: TypeScript, Three.js for rendering and Miniplex for the entity-component-system.

What does deterministic mean in Frostwake?

Same seed, same world, same run. All randomness goes through a seeded generator, simulation code may not read the clock, and a test fails the build if either rule breaks.

Want something like this?

Frostwake shows how we keep a codebase fast and safe to change with many hands on it: strict module boundaries, deterministic logic that tests can pin down, and performance rules written down as contracts.

Get in touch

← All work · Software & AI for businesses