Terrarium

September 17, 2026 · View on GitHub

A sandbox where a TypeSafe System One model (Jev) presses the controls of a small creature. Code runs the world, Jev only ever picks a button, and every decision is logged in full: the state it was sent, every question, every probability, and the rule that fired.

What Jev is

Jev is TypeSafe's "System One" model. It does not generate text. You send it a state (any JSON) and a map of typed questions, and it returns typed answers with calibrated probabilities: a Choice picks one option from a list you define, a Score places the state on a rubric you define, and a Noul returns the probability that a yes/no statement is true. Every question in a request is answered in parallel in one round trip of roughly 100 to 400 ms, so asking fifty questions costs about the same time as asking one.

Why this exists

I built this to measure two things: how fast Jev answers when a whole world state and a few dozen questions ride in each request, and how accurate its snap judgments are when the objects are anything a person can type. Both matter for where I want to take it next: a live real-world application where a decision has to land in the time a user notices, a game where an NPC needs a judgment every frame rather than every paragraph, or a robot that has to decide what to do about the thing in front of it without waiting for a language model to finish a sentence. The decision log is the instrument: every step shows latency, token count, the full probability table, and whether code had to overrule the model.

Run

Requires Node 20 or newer. No dependencies.

git clone https://github.com/TheGali/terrarium.git
cd terrarium
node serve.mjs 5180

Open http://localhost:5180. Without a key the page runs a mock brain so the game still plays.

To go live, get a key from the TypeSafe console and either export it as TYPESAFE_API_KEY or put TYPESAFE_API_KEY=… in a .env file in the repo root (gitignored). The key stays on the server; the browser only ever talks to /api/think.

How it works

  • One request per STEP. state is the world as JSON (species profile, position, eight drives, every object with distance and direction, the last five events). questions is one Choice over the eleven controls plus a speculative fan-out: for every object, a threat Score, an edible Noul, a drinkable Noul, an interest Score and a shelter Noul; plus the most pressing drive, an in-danger Noul, and a mood Score. All answered in parallel in one round trip.
  • Code decides. It walks the control distribution from the top and takes the first control the world can honour. eat with nothing edible adjacent is rejected and the log says so. Targets for investigate, hide, flee, eat and drink are resolved from Jev's per-object judgments, not hard-coded.
  • One request per free-text drop. Jev is asked what the thing is (food type, poison, heat, contact harm, shelter, novelty, alive, behavior, company, icon). Code turns those answers into the same property sheet the palette objects have. Consequences are real: eat something Jev judged edible that the world says is poison, and health drops.
  • Drives are deterministic. Hunger, thirst, fatigue, fear, curiosity, loneliness, warmth and health tick by the constants in src/world.js. Nothing in the model changes a number directly.

Files

FileWhat lives there
src/questions.jsEvery question and every threshold. The file to review.
src/world.jsThe deterministic sim: grid, drives, object effects, resolving controls.
src/brain.jsTransport, parsing, the decide loop, the mock brain, physics derivation.
src/objects.jsThe palette and the property sheet free-text objects are mapped onto.
src/species.jsThe five profiles Jev reads to know who it is.
src/render.jsCanvas grid with pixel-emoji sprites.
src/log.jsThe decision log panel.
serve.mjsStatic server plus the /api/think proxy that holds the key.

Demo script

  1. Drop an apple three cells away. STEP a few times: watch control favour the move that closes the distance, then eat once adjacent.
  2. Drop a snake. Watch danger flip, the threat Score for the snake, and flee or hide win.
  3. Switch species to snake with the same objects. The mouse is now food and the fire is a comfort.
  4. Type “glowing mushroom”. Read the physics answers before placing it. Then see whether the creature trusts it.