RaidGuild Cohort
Public

Jev Doesn’t Drive the Tank

Author

Shatner and Queen Raida

Date Published

Doctrine tank duel arena showing Jev selecting a maneuver with confidence information while local game mechanics remain visible.

Created by Ai by real conversations and demos by RaidGuild members

Dave Nellis’s Doctrine experiment puts Jev in a live tank duel without asking it to run the game. Local TypeScript code still owns movement, collision, line-of-sight checks, aiming, firing, and the rest of the arithmetic. Jev receives a compact symbolic view of the fight and returns a typed judgment about what the tank should do next.

That split is the point. In Doctrine, Jev is a decision layer, not a player.

The public Doctrine repository is a browser-first Phaser, Vite, and TypeScript tank duel. Each side can be human-controlled, use a local preset, or use Jev with its own doctrine prompt. The presets—Cautious, Berserker, and Ambusher—make the contrast easy to see: the game already has rules. The experiment is about replacing a narrow piece of the if-ladder, not replacing the game engine.

Doctrine setup screen showing the tank control mode and doctrine configuration used before a Jev-driven match.

In his project handoff, Dave describes Jev as selecting which local state should be active. That is a practical framing: use the model for a bounded decision, rather than asking it to run the game.

What is Jev doing in the loop?

TypeSafe describes Jev as a system for returning typed decisions with probabilities rather than generated prose. In Doctrine, the application turns the live arena into a symbolic state: health bands, reload status, cover, approximate distance and direction, line of sight, recent actions, and the player’s doctrine prompt. It does not send raw coordinates as an invitation for the model to do geometry.

Jev can choose a maneuver such as advance, retreat, take cover, flank, or hold, and provide an aggression judgment. The game then executes that choice locally. The repository’s guide is explicit: the code aims and fires; Jev never chooses either.

The wall was the useful failure

The first version exposed the obvious trap. A Berserker could make an aggressive choice and drive into a wall. Sending more state—the full map, bullets, tank coordinates—didn’t solve the underlying problem. More tokens did not turn a decision API into a collision system.

The revision went the other direction: let local code do the geometry and pass Jev a smaller description of what the game already knows. An array like [open, open, blocked, open] is more actionable for a maneuver decision than a raw coordinate soup. Local steering around obstacles keeps the tank from treating a wall as a philosophical problem.

The source code now reflects that design. It converts world state into symbolic words, calculates line of sight locally, and uses local movement and obstacle-steering functions to carry out the maneuver. When Jev is unavailable or responses are stale, the game falls back to a cautious local brain.

The game loop is deliberately bounded

An early field note discussed trying Jev at higher rates. The current public repository sets the decision cadence to 350 milliseconds—roughly 2.9 calls per second—with one request in flight at a time. It drops responses older than 1.2 seconds, holds a chosen maneuver for at least 600 milliseconds, gates low-confidence maneuver changes, and switches to local fallback after repeated failures.

Those are not incidental guardrails. They are part of what makes the loop playable. A model response is one input into a system that still has to feel coherent frame to frame.

What builders can take from Doctrine

Doctrine is not evidence that models should run game physics, nor that every application needs a decision model. It is a clean example of where one might fit.

If your application has unstructured or messy state and needs to choose among a small, defined set of actions, a typed decision can be useful. Keep the action set bounded. Keep the state relevant. Keep deterministic rules, permissions, arithmetic, side effects, and safety checks in code.

The tank is just a loud way to see the boundary. When the boundary is wrong, it hits a wall. When it is right, the application keeps its mechanical responsibilities and lets the model contribute a narrow judgment.

See the Doctrine source at https://github.com/dnellis74/doctrine and TypeSafe’s Jev introduction at https://docs.typesafe.ai/introduction.

Have a project in mind?

Start a conversation with RaidGuild

Tell us what you are building and where the guild could help.

Make a general inquiry

Comments

No comments yet.

Log in to leave a comment. Log in
Jev in a Live Game Loop: A Bounded Decision Layer | RaidGuild Portal