Use case
Jev for games and realtime control
Games are the cleanest test of a decision model: the legal actions are enumerable, the clock is unforgiving, and a hallucinated move is visible immediately.
Why games are the honest test of a decision model
A game hands you both halves of the problem already solved. The legal actions are enumerable, so the answer space is closed. The state has a fixed shape, so the input is bounded. And the result of a wrong answer is visible in the next frame, which means you find out immediately rather than three paragraphs later.
That is why so many of the builds we collected are games, and why they make good examples even if you are not building one. A loop that can pick a landing square 30 times a second is the same loop that picks a retry strategy, a queue, or an escalation path.
state = { board, piece, legal_moves[0..n] }
questions = {
placement: { type: choice, criteria: { "0": {landing}, "1": {landing}, ... } },
}
answer = { choice, confidence, probabilities } // one call per frameThe schema is the safety property, not the prompt
Every one of these builds leans on the same property: the model cannot return a move that is not in the list, because the response type only admits members of that list. You do not need to instruct it to play legally; an illegal move is unrepresentable.
That is a different guarantee from the one you get from a chat model with a careful system prompt. With a prompt, legality is a behaviour you hope holds and test for. With a closed choice set, it is a property of the interface. For anything that acts on the world, including many loops that are not games, that difference is the whole reason to care.
What the reported per-move numbers leave out
Per-move latency in the 200–500 ms range recurs across independent builds, which is a consistent enough signal to plan around. What the posts do not state is the part that decides whether the loop is usable: the size of the state you serialise, and whether the calls were warm.
Our own measurement puts Jev at a 313 ms warm median and 443 ms cold, with a minimal-payload round trip of roughly 280 ms from the same machine. In other words, on this kind of workload the model accounts for a small fraction of the wall clock and the round trip accounts for most of it — and a cold call costs you more than a frame at 60 fps. The board representation you choose, and whether you keep the connection warm, will move your frame budget more than the choice of model will.
What the low per-decision costs do buy is a design change. When a decision costs a fraction of a cent rather than a fraction of a cent per hundred tokens, you can afford to ask on every frame instead of every tenth frame, and you can afford to ask about things you would otherwise have hard-coded — whether to chase, whether to retreat, whether the current target is still worth pursuing. Most of the builds in the list below are interesting for that reason rather than for their frame rate: they replaced a rule with a question, and the budget allowed it.
Keeping a loop inside its budget
The builds that hold their frame rate share three habits. They enumerate moves locally and send the list rather than the whole game. They treat the decision as fire-and-forget with a deadline: if the answer does not arrive in time, the loop uses the previous decision or a fallback rule rather than blocking the frame. And they keep a deterministic fallback in code, so a slow or failed call degrades the play rather than stopping it.
const deadline = 250 // ms, one frame budget at 4 fps-equivalent headroom
const pending = jev({ state, questions })
const answer = await Promise.race([
pending,
new Promise((r) => setTimeout(() => r(null), deadline)),
])
const move = answer?.placement.choice ?? fallbackRule(state) // never block the loopFailure modes you will meet in the first week
Obvious moves get a low score less often than ambiguous ones, but scoring is not calibrated to your game: a 0.7 on a forced move and a 0.7 on a genuinely close call look identical. Measure the distribution on your own positions before you set a threshold, because the useful cutoff is a property of your state encoding, not of the model.
State size grows faster than you expect. A board of 200 cells described in prose is a long input, and long inputs cost both latency and money; the reported spread in per-decision cost across builds tracks how verbose their state was far more than which model they used.
Parallelism has a ceiling. One build ran hundreds of agents in the same simulation and published 35 calls per second, which is a throughput number, not a latency number — under load your per-frame budget is set by queueing, and the retry logic that looked harmless at one agent becomes the thing that saturates the service.
Ties are real and must be defined. When two moves score the same, the model may pick either on different runs. If your evaluation depends on reproducibility, break ties in code after the call rather than expecting the model to prefer the lower index.
Where this sits in the wider pattern
If your loop already has a clean observation step, the browser agent page shows the same pattern with the DOM supplying the option list. If your loop is not about actions at all but about which tool or route to take, that is the agent-loop case.
Reported on X
Quoted metrics are as posted by the author and are not verified or normalised by us.
Rubik's cube solved by putting a beginner method in code and letting Jev choose each step.
Reported: 94 moves, ~250ms per decision
@redp314 on XChrome dino runner driven by a snapshot of the page state.
Reported: ~280ms average response, $4.65 total run
@mittalparth_ on XA 3D environment with hundreds of agents running in parallel.
Reported: 500ms average, 35 API calls/s, naive implementation
@crislenta on XSeven independent Jev instances playing a realtime multiplayer game against each other.
Reported: 100–200ms reactions
@yelkhayami on XBoard game loop with a fixed state format, cost measured per game.
Reported: $0.00022113 per run
@Entelic_Aria on X