Skip to content
After hours

Web and mobile game · social policy

Private build

The Veil · El Velo

Set six social policies without knowing who you’ll be, then live fifteen random lives under those rules. Designed in Spanish first.

The Veil rules screen, with Piso and Producción meters above sliders for the first four laws.
Role
Solo: design and code
Timeline
Jun 2026 to now
Stack
TypeScript, React, Zustand, Capacitor, Vitest

Private build. The code is private, but I’m happy to walk you through it on a call. Status checked Oct 22, 2026.

By the numbers

55

tests in 6 files, including checks of the game’s premise

15

lives per run under the rules you set

48

paired-seed batches for each live policy preview

The idea

In The Veil, you set society’s rules before knowing your place in it. Choose six social policies, then live fifteen randomly assigned lives under them. Your score reflects how those lives turn out, including the worst one.

What I built

The simulation uses pure TypeScript, independent of the interface and state layer. I run it headless in Node to tune the six policies with Monte Carlo batches. These checks confirm that balanced rules outscore pure equality and pure laissez-faire, and that the highest-scoring rules sit between the extremes. The results apply to the game’s model and make no general claim about real societies.

Velo scores the average outcome minus a penalty for the gap to the worst life. Velo de Hierro scores only the worst life. I built the interface first in Spanish using React and Zustand. The shareable Constitution card is drawn as SVG with embedded fonts, then converted to PNG.

The hard parts

  1. 01 Testing the game’s premise

    Unit tests check the game’s premise in both scoring modes: balanced rules outperform both extremes, and the worst life reaches its best outcome at an intermediate level of redistribution.

    Where in the code: src/engine/model.test.ts

  2. 02 Consistent policy previews

    Moving a slider previews each policy’s effect on the worst life. The preview runs 48 batches using the same seeds for both sides of the comparison, holding births constant while laws change. Both meters and all six policy chips use the same sample.

    Where in the code: src/engine/preview.ts

  3. 03 Daily events with consistent births

    The daily challenge uses your local date as its seed and adds a recession or pandemic modifier. The modifier has its own random stream, keeping births unchanged.

    Where in the code: src/engine/daily.ts

Before and after

BeforeAfterSource
Policy preview time per tick13.5 ms8 msReported in commit 7425eda after caching citizen cohorts; I have not re-measured it.

What’s next

Choose a domain and deploy the web version.

El Velo title banner, with a Spanish invitation to write the rules of a society without knowing who you will be in it.

Shared approaches