Codex in the dungeon
/ Oriole field notes
A coding agent, a dungeon, and five minutes to figure things out. Four models started in the same place. One made it seven floors down.
Watch the recorded runs ↓01 / The idea
What happens when the next task is a dungeon?
Codex can read a terminal, choose a command, and see what happened. NetHack gives that loop a different kind of task: explore a map, deal with monsters, watch your health, and find the stairs before you get stuck.
Oriole already contained NetHack research code and a knowledge graph built from the game’s wiki. The experiment was to give Codex a small, persistent game interface and let it choose the next key itself.
The game runs locally. The model uses the usual Codex CLI and a ChatGPT subscription login. There is no separate API key, local language-model server, or hand-written policy deciding its moves.
02 / The loop
Read the screen. Pick a key. Read again.
- 01Observe
./play observeDungeon, health, turn, and message.
- 02Choose
Codex reasonsThe model chooses its next move.
- 03Act
./play act northA real key goes to the live game.
- ↺Inspect
./play observeSee the consequences. Continue.
The process keeps the game alive between commands. Codex can open inventory, answer menus, fight, and descend stairs. It can also look up extracted wiki facts through ./play knowledge. Every key and resulting screen goes into a replayable trace.
03 / The experiment
The same starting room. Four different routes.
Each model got seed 43, a lawful human Valkyrie, medium reasoning effort, and a five-minute limit. The four games ran concurrently in separate sessions. The starting screens were identical, verified by matching hashes.
| Model | Deepest floor | Score | Keys | Final health |
|---|---|---|---|---|
| GPT-6 Luna | 2 | 67 | 159 | 14/16 |
| GPT-6 Sol | 2 | 79 | 198 | 16/16 |
| GPT-6.1 Sol | 7 | 607 | 470 | 29/39 |
| GPT-6 Astra | 6 | 438 | 592 | 27/27 |
All four were alive when the supervisor stopped them. None ascended. The limit was 300 seconds; shutdown adds about a second to elapsed time.
04 / The recordings
Follow the character down.
Choose a model, drag the timeline, or jump to the moment it reached a new floor. The initial view is GPT-6.1 Sol’s final screen. Hit play to watch its route from the beginning.
---------------
|..............####### #####
|.............| ################# %
|............<. # #
|.............| #
- ------------- ##### ###
# @#
# #
# ##
# #
-----# #
+...|( #
|...-# ##
|...| #
|..*| ##
|....####
-----
Agent the Skirmisher St:18/03 Dx:11 Co:18 In:9 Wi:8 Ch:12 Lawful S:60
Dlvl:7 $:43 HP:29(39) Pw:9(9) AC:0 Xp:3/49 T:39405 / A useful failure
The first run mostly searched the same room.
Before the comparison, Luna played for ten minutes. It stayed on floor 1. Of its 305 keys, 157 were searches. It survived, but kept revisiting the same area.
That prompted adding visit counts to the observations and explicit instructions to keep track of the route and avoid cycling. The paired trials above use that updated setup. The earlier run is kept separate because its instructions and recorded settings differ.
This is the part I want to explore next: how much progress comes from the model, and how much from giving it a useful way to remember where it has already been?
06 / What this tells me
A good start, with a long game ahead.
GPT-6.1 Sol reached the deepest floor in this run. Astra sent more keys. These are useful observations from one seed, not a general model ranking. Equal wall-clock time also gives faster models more chances to act.
Five minutes measures early exploration. It does not show whether an agent can manage a full inventory, survive deeper threats, or win NetHack. The next experiment should use more seeds, repeat the runs, and give the characters much longer to play.
07 / Run it locally
A subscription login and a few commands.
In an Oriole checkout with the gameplay tools installed, a bounded trial looks like this:
codex login
./play trial --model gpt-6-luna --seconds 600 --seed 43
./play results
# During a run, in another terminal:
./play results --liveThe runner requires ChatGPT authentication and does not fall back to API-key billing. Model availability and usage limits depend on the account. OpenAI documents the subscription sign-in flow.