Built with jev-state (npm), an open-source library that turns raw app and game state into state Jev reads well.
Two game bots share one brain: Jev, TypeSafe AI's decision model. Every 1.5 seconds each bot asks Jev what to do, with the same rules and the same question. The only difference is what each bot sends:
- Raw bot: its raw game state:
hp: 38, maxHp: 250, exact distances, epoch timestamps, positions, and debug data. - jev-state bot: the same state after jev-state:
hp: "critical",distance: "near",lastNoiseAt: "just now".
You fight both at once in two mirrored arenas. Every decision is checked against the rules, so you can see which bot reads the situation correctly.
You need Node.js 22+.
git clone https://github.com/suranjaychandra/two-bots-one-brain.git
cd two-bots-one-brain
npm installWith Jev (needs a TypeSafe API key):
cp .env.example .env # paste your TYPESAFE_API_KEY and save
npm start # http://localhost:3001Without a key:
npm run offline # both bots use the local rules instead of JevOpen http://localhost:3001, choose YOU PLAY (WASD to move, click to shoot) or WATCH (a scripted player), then press START ROUND. Every decision is also printed in the terminal.
The MISTAKES.live bar above the arenas counts each bot's wrong decisions by the rules, for this round and for every round since the page loaded. Survival doesn't affect it.
These screenshots are from real rounds against the live Jev API, with the same rules for both bots.
In this session, the raw bot made 5 wrong decisions out of 107. The jev-state bot made 0 out of 109. Each answer is checked against the rules for that bot's own situation.
After a round you can download a result card to share:
This is a handful of rounds, not a benchmark. For a reproducible benchmark (420 calls, seeded scenarios), see jev-state.
| File | What it does |
|---|---|
brain.ts |
The rules Jev is given, the raw state, the jev-state schema, and the correct answer by the rules |
server.ts |
Receives each bot's numbers, builds its state, and asks Jev. The API key stays here. |
public/game.js |
The arenas, the bots, and the round. You move the same way in both arenas. |
The bots choose between five actions: retreat, heal, attack, investigate, and patrol. A minute of play makes about 80 Jev calls, roughly $0.003.
- Same everything except the state. Both bots get the same rules, the same question, the same model, and the same starting position. You move the same way in both arenas.
- Same aim. The bots end up in different places, so a click aims at each arena's own bot when it's close to where you clicked. One click is equally accurate in both arenas.
- Each arena has its own fight. You have 150 hp in each arena, and bullets travel 16–18 m, so retreating out of range actually saves a bot.
- Correct decisions is the fair score. Each answer is checked against the rules for that bot's own situation. Who wins a round also depends on aim and positioning, so compare outcomes over several rounds rather than one.
npm testThe tests check the rules' priorities and boundaries, the raw state, the jev-state projection, and the browser snapshot. They use a fixed clock and make no Jev calls. CI runs them on Node.js 22, 24, and 26.
The browser rounds each bot's numbers once (whole hp, 0.1 m, 0.1 s) before a decision. The correct answer and both bots' states are built from that same snapshot, so every bot is judged on exactly what it was shown.
The game's rules differ slightly from the jev-state benchmark: here, critical health plus any visible enemy means retreat; the benchmark has seven actions and needs a near enemy.
MIT © 2026 Suranjay Kumar
Unofficial community project. Not affiliated with or endorsed by TypeSafe AI.
- jev-state: the library behind the jev-state bot, with a reproducible benchmark and a playground.


