Zack Lovisa Software developer Start an estimate

Case study

2026

Denoms

A browser autobattler with no controls: the serial number off a dollar bill deterministically generates a creature, and the fight resolves itself.

  • Client Personal project
  • Discipline Game
  • Duration Ongoing
  • Budget band Personal project
  • TypeScript
  • three.js
  • React
  • Deterministic Sim
Denoms shown on screen

The problem

An autobattler lives or dies on whether players trust the result. If the same fight can play out differently on two machines, or if nobody can reproduce a match after the fact, then every loss looks like a bug and a leaderboard means nothing.

The first version was built quickly on a hosted platform. That got it playable, but it left the game logic and the rendering tangled together, which is fine right up until you want replays, tournaments, or a server that can check a result rather than take a player at their word.

What I did

The game is split in two, and the split is the whole design. The simulation is pure TypeScript with no DOM, no network and no clock. Every random stream comes from a seeded generator, and the build fails if Math.random appears anywhere in the package at all.

The renderer is not allowed to reach into the simulation. It receives a typed stream of events and draws them. Because the engine has no idea a screen exists, the identical code runs in a browser and on a server, so a match can be verified instead of trusted and a replay is a seed rather than a recording.

Creatures come from money. You enter the serial number printed on a dollar bill, and that serial is the seed, so the same bill produces the same denom for everyone, permanently. It is a small idea that does a lot of work: identity, scarcity and shareability fall out of a number people already carry.

Outcome

Playable at denoms.gg, with an arena you watch rather than play, plus tournaments and a ratings lobby built on top of it.

The transferable part is the discipline, not the game. Deciding on day one that the engine may not touch the renderer, the network or the clock is the same judgement that keeps a client’s pricing rules out of their checkout page. It costs almost nothing to decide early and it is expensive to retrofit, which is why I keep choosing it.

View it live