The replay system aims to provide a means to reproduce issues in the bot that are otherwise hard to track down by performing a repeat of a particular game. This replay will allow standard python debuggers to step through the game state at the developer's leisure and investigate exactly what is happening.
Recording replay data
Replay data is a complete snapshot of the bot's state at the start of the file, followed by IRC messages sent and received by the bot which modify said state. This allows for full reproduction of what happened even without a live IRC connection or if configurations are different. As the data only needs to be consumed by the bot, it need not be in a human-readable format.
The snapshot should include the following details:
- All configuration/state variables (all of the ALL_CAPS things in var.*)
- Bot configuration (botconfig.*), with exception of the following variables:
In addition to the snapshot, IRC messages are stored. This should include a precise (at least millisecond precision) timestamp, direction (incoming/outgoing), and the raw message. Messages should start being logged at the initial !join (the initial !join is what prompts snapshot generation as well), and should stop being logged after the game has ended. At that time, the stored replay data is exported into a JSON string and compressed via gzip, with the raw data being discarded, see below for the JSON schema. The compressed JSON data is kept in memory for 5 games, after which it is discarded. Should any errors be logged during this time, full details on the error (message, traceback) is also recorded.
Saving replay data
When an error is logged, the replay data for that game is automatically saved to disk. An opt-in switch in botconfig can be set to automatically stream the data to an API on werewolf.chat where it is stored for later examination by lykos developers. Beyond this, the replay data for an individual game can also be saved to disk by a bot admin via the command
!fsave <gameid>. Issuing
!fsave without a parameter enumerates the game ids currently stored in memory, along with the time the game started and which team won the game.
!fsave <gameid> is issued, the compressed JSON is saved to disk as
replay-<gameid>.gz in the
replays directory of the bot (this directory should be added to
.gitignore). Should the file already exist, the command overwrites it.
Running a replay
The bot has an additional switch
--replay file to alert it to replay the file rather than connecting to an IRC server. Should this switch be issued, no IRC connection is attempted and the bot merely attempts to replay that one game, exiting after completion. It first decompresses the file and loads the JSON into memory, setting its internal state to mirror the state in the snapshot. It then enumerates all of the incoming messages and parses them just as if the bot was connected and it was receiving the messages from an IRC server. When it detects an outgoing message, it logs it for later comparison to what the replay output is. Upon completion, the bot's output and the replay output are run through diff to detect any discrepancies.
When running a replay, two modes can be selected: fast-forward or realtime. The default mode is fast-forward, realtime can be specified by passing the switch
--realtime to the bot. TODO: Finish