A game leaves a trail.

A card is played. A room changes. A deck gains or loses a card. The logger catches these events and records the surrounding state, including player resources, cards, and enemy intentions.

run.jsonlEXCERPT
01
run_started

run started

02
room_entered

room entered

03
deck_card_removed

deck card removed: CARD.STRIKE_DEFECT

04
combat_setup

combat setup: ENCOUNTER.CORPSE_SLUGS_WEAK

05
room_entered

room entered

06
turn_started

turn started: round 1 Player

One event. One line. A record of the run.

Selected event fields from the repository's example Defect run. This is a recorded excerpt, not a live game feed.

Inspect the event excerpt
[
  {
    "event_index": 1,
    "type": "run_started",
    "summary": "run started"
  },
  {
    "event_index": 2,
    "type": "room_entered",
    "summary": "room entered"
  },
  {
    "event_index": 3,
    "type": "deck_card_removed",
    "summary": "deck card removed: CARD.STRIKE_DEFECT"
  },
  {
    "event_index": 4,
    "type": "combat_setup",
    "summary": "combat setup: ENCOUNTER.CORPSE_SLUGS_WEAK"
  },
  {
    "event_index": 5,
    "type": "room_entered",
    "summary": "room entered"
  },
  {
    "event_index": 6,
    "type": "turn_started",
    "summary": "turn started: round 1 Player"
  }
]

From action to record

One event at a time.

  1. 01

    Listen

    Patches and runtime hooks capture actions and changes in the game.

  2. 02

    Snapshot

    Record the relevant player, card, room, and combat state.

  3. 03

    Write

    Append structured JSONL events with identifiers and an event index.

Each line is a standalone JSON record. Session and run identifiers keep the records tied to their context, while the event index makes their order explicit.

Explore the game snapshotsopens in a new tab

A resumed run is not a new run.

Continuing a save introduces a less obvious problem: the game can revisit state the logger has already seen. EventLogger includes handling for continuing existing run logs and detecting state rewinds. It also tracks deck mutations to avoid recording the same change more than once.

These checks matter before any analysis or training. A repeated event or an unexplained jump backward can change what a sequence of actions appears to mean.

Read EventLoggeropens in a new tab

Check the record before using it.

A validation script checks the log structure, event ordering, timestamp progression, and the pairing of card-play start and end events. The example log gives those checks something concrete to run against.

  • Event indices make gaps or ordering problems visible.
  • Paired action events help identify incomplete sequences.
  • State snapshots preserve the context needed to interpret an action.
View the validation scriptopens in a new tab

The experiment so far.

The project collects structured game data for later analysis and possible AI training. The work shown here is the logging mod and its validation tools. It does not include a trained game-playing agent.

The next question is what can be learned from a run. First, the run needs a record worth learning from.