VIDEO · 2026
Giving an AI limbs: how Jev plays Doom in real time at 120 ms
A 7-minute breakdown (Chinese narration). No pixels, no screenshots — just a plain-text state report, queried about ten times a second. Jev picks the goal like a commander; ordinary code does the key presses.
Chinese narration · 720p · captions track (zh) · MP4
Article: An AI that plays Doom without looking at the screen
The TypeSafe team published a demo video of an AI playing the classic shooter Doom in real time: dodging monsters, picking things up, finding its way around. It looks like yet another "AI watches the screen and plays a game" clip, but this AI never sees the screen and never reads a single pixel. What it gets each time is a status report written out as text by a program.
The model making the calls is Jev, which TypeSafe released in September 2026. TypeSafe calls it a "System 1 model", borrowing the term for the fast, unreflective intuition people rely on. It is used very differently from a chat model like ChatGPT that writes prose. A program first hands Jev a description of the current situation, then asks it a few multiple-choice questions whose options were written in advance. Jev doesn't generate text; it assigns each option a probability, meaning how likely it thinks that option is the right answer. Think of an answer sheet on an exam: Jev can only mark the boxes it is given and never outputs anything outside them. Because it doesn't produce an answer word by word, it is fast and cheap.
For anyone building AI features, backends or automation, the interesting part isn't that an AI can play a game. It's that the demo shows one way to structure a system that has to make many small decisions every second. This article follows the video: what the status report contains, what Jev is asked, which decisions go to the model and which to ordinary code, and what the demo does not prove.
The numbers in the demo
Start with speed and cost. Two kinds of source are involved here, and they should be kept apart: figures from the official announcement, and readings taken from the demo's on-screen interface.
According to the official announcement, the system queries Jev about 10 times per second during play, and TypeSafe estimates it costs about $7 an hour to keep running. The demo's top bar, meanwhile, shows an average of about 118 ms per decision, so roughly 120 ms. In the same session Jev was called a little over 2,700 times, and the bottom bar shows a running cost of $0.64.
A big reason it can be this fast and this cheap is that there's no heavy vision model in the loop. Recognising a screen means processing a lot of pixels; reading a text report is far lighter. That design choice is the starting point, so the report is where to look first.
The status report: a 3D battlefield written as text
Between roughly 0:30 and 0:44 of the demo recording, a long block of JSON scrolls across the screen. (JSON is a common structured format programs use to exchange data.) This is the status report the program writes for Jev.
It opens with a set of rules written for the model. Distances are measured in Doom map units, and the player's body is about 32 units wide. Distance comes in four bands: contact is within 64, close is 64 to 256, medium is 256 to 768, and far is beyond 768. Angles are relative to where the player is facing: positive is left, negative is right, and plus or minus 180 degrees is directly behind. The game's basic unit of time is the tick, one thirty-fifth of a second, and the rules say a decision is made every 4 ticks, about every 0.1 seconds, with keys held down between decisions. Even the weapons come with a plain-language note; the shotgun, for example, is described as devastating up close, with the pellets spreading out at range.
After the rules comes the player's own state at that moment. Health is 55 out of a maximum of 100, so the player has already taken damage. Armour is 39, with a cap of 200. The weapon in hand is a shotgun, but it is out of shells; the player also carries a pistol with 60 rounds left.
Next is the enemy list, one entry per monster. An imp labelled imp F is 57 units away, in the contact band, at minus 92 degrees, which puts it directly to the player's right. Another, imp G, is at 293, in the medium band, at plus 49 degrees, ahead and to the left. Its status reads out of view: it's nearby, but can't be seen right now. Items on the floor get distances and directions too; one ammo clip, for instance, sits at 814, which counts as far.
In other words, the program first translates the 3D battlefield into a text briefing the model can read, and Jev decides based on that briefing alone.
Questions in layers: pick a goal, then ask how
At that same moment, with health at 55, the right side of the demo interface lists the four questions Jev is answering, each phrased as an English question. Next to each answer is a confidence value, meaning how sure Jev is about the option it picked.
The first is the firing question: should the trigger be pulled right now? There are only two options, fire and hold fire. Jev chose hold fire with a confidence of 0.99. A low probability of firing doesn't mean the model is hesitating; it means the model is very sure it shouldn't shoot.
The second is the goal question: given the player, the enemies and the items, what should be the top priority now? At this moment it has six options: upgrade weapon, scout, kill an enemy, get ammo, get armour, and restore health. Jev chose restore health with a confidence of 0.95.
The third is the dodge question, and its wording already includes the previous answer, roughly: the player's top priority right now is to restore health with a medkit, so what should happen this instant? The options are carry on, dodge left, dodge right or back off. Jev chose carry on, but with a confidence of only 0.54, so it wasn't at all sure this time. The fourth is the movement question, which also carries the restore-health goal and asks how to move now.
So the questions are layered. A broad goal is chosen first, and the later questions take that goal as given when asking about concrete actions.
The options themselves aren't fixed either. At 1:21 in the recording the player is at full health, and the goal question offers only five options; restore health doesn't appear at all. Which options are on the table is decided by the program based on the situation. At that same moment a human has typed "don't fire, just dodge" into the command box, and the firing question's answer is hold fire, with a confidence of 0.97. The interface also shows a "director" program that keeps spawning monsters onto the map.
Commander and hands: which layer the model decides
Below the questions, the interface has a flowchart of the same 1:21 moment. On the left are the known enemies, medkits, ammo, weapons and armour. In the middle a goal is chosen first; here Jev picked scout. Then a specific target is chosen, such as which monster to face. Finally everything resolves into four outputs: FACE at 76 degrees, MOVE as a destination coordinate, TRIGGER set to hold fire, and WEAPON set to no change.
My reading is that the angles and coordinates are computed by code from the status report, and Jev only picks among options. One way to picture the split is a commander and a pair of hands. Jev is the commander and decides "go heal now". The controller code is the hands: it handles walking step by step to the medkit, which means planning the route, turning the view and pressing the keys. Keys are held for about 0.1 seconds, and then the next round of decisions begins.
Why split it this way? Because what the model can decide depends on the options the program gives it. If the only options are forward, back, left and right, that's all Jev can choose. Putting goals like restore health or scout into the options is what actually hands the real decision to the model. That doesn't mean more abstract goals are always better. Once a goal is handed to the model, the controller has to be able to carry it out reliably. The clever part of the demo is exactly this: the model makes the decisions, and conventional code does the execution.
Put together, the loop has four steps. Low-level code reads the game's internal data and writes the text status report. The program asks Jev its questions layer by layer and gets a probability for each option. The controller turns the winning options into real key presses such as turning, moving forward, firing or opening a door. The keys stay held until the next round, and the loop starts again.
The community replica: one answer sheet with four questions
The code for the official demo hasn't been released, but there is a community replica on GitHub, jev-doom-agent, created on 17 September 2026. It compiles the real Doom engine to WebAssembly, a format that lets programs run in the browser, and exports health, armour, ammo, coordinates, kill count, and the visible monsters and items. Its description likewise says Jev receives structured game state, not pixels.
Each time the replica sends Jev a request, it's like handing over one answer sheet with four questions. The first is movement, with six options such as stay put, explore, approach an enemy and retreat. The second is view, with three options. The third is the trigger and the fourth is using doors and switches, with two options each. All four answers are executed at the same time, and the overall confidence is the lowest of the four. If a request fails or confidence is too low, the interface clearly shows FALLBACK, meaning Jev's answer wasn't used for that step and a conservative fallback action was taken instead.
The official demo and the replica differ in detail, but the real work sits in the same places: how the state is written, how the options are designed, and whether the controller can be trusted. The model is just one piece.
What the demo doesn't prove
First, the demo feeds Jev a text description, not the game screen. That shows the text route can be fast and cheap; it doesn't show that vision-based approaches can't work.
Second, being able to choose restore health or scout isn't the same as long-term planning. The options come from the program based on the situation, the route is computed by the controller, and the explored parts of the map are also tracked by surrounding code and fed back in as input.
Third, since the official code isn't public, we don't know how many questions it asks per request. The community replica asks four per request, but the official version may not.
Fourth, 10 queries a second, $7 an hour and an average of 118 ms are numbers from this one demo. A different game, or a different way of writing the state, could give different results.
Takeaways
The demo boils down to a pattern: write the state as text, turn decisions into multiple-choice questions, and pair the model with a controller you can rely on as its hands. The model's speed matters, but the more important design choice is which layer the model gets to decide. The options you offer set what the model can decide, and the controller's abilities set whether those decisions turn into action.
The pattern isn't limited to games; UI automation and robot control, anywhere that needs many small decisions per second, are candidates. That said, this analysis is based on the official demo footage and the community replica's code, and the internals of the official implementation remain unknown. Moving the idea to another domain means measuring speed, cost and decision accuracy all over again. The original demo post is on X.