Engine¶
The game loop, legal move routing, state rendering and replays.
GameRunner ¶
Plays a game by asking agents for actions until it ends.
Each iteration, every agent with legal actions is asked at the same time, with the state scrubbed for that agent. A failed attempt is retried, and after max_retries failed retries the runner plays a random legal action for the agent.
Attributes:
| Name | Type | Description |
|---|---|---|
state |
The current, unscrubbed game state. |
|
replay |
Every action applied so far. |
|
agents |
Each agent, keyed by UID. |
|
max_retries |
Retries allowed after an agent's first failed attempt. |
|
timeout |
Seconds allowed for each attempt, or |
|
rng |
Random generator that picks fallback actions. |
|
faults |
tuple[AgentFault, ...]
|
Every failed attempt, in order. |
__init__ ¶
__init__(
agents: Sequence[Agent],
initial_state: GameState | None = None,
seed: int | None = None,
roles: Mapping[int, Role] | None = None,
shuffle_players: bool = True,
discussion_enabled: bool = False,
discussion_rounds: int = 2,
max_retries: int = 2,
timeout: float | None = 120.0,
)
Sets up the runner and, unless initial_state is given, a new game.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agents
|
Sequence[Agent]
|
The players. Each agent's |
required |
initial_state
|
GameState | None
|
A state to start from instead of a new game. |
None
|
seed
|
int | None
|
Seed for the new game and for fallback actions, or |
None
|
roles
|
Mapping[int, Role] | None
|
Fixed role for each UID, or |
None
|
shuffle_players
|
bool
|
Whether to shuffle the seating order. |
True
|
discussion_enabled
|
bool
|
Whether to hold discussions. |
False
|
discussion_rounds
|
int
|
How many times the table goes around in each discussion. |
2
|
max_retries
|
int
|
Retries allowed after an agent's first failed attempt. |
2
|
timeout
|
float | None
|
Seconds allowed for each attempt, or |
120.0
|
Raises:
| Type | Description |
|---|---|
TyrantError
|
If the settings are not valid for a new game. |
run
async
¶
run() -> GameState
Plays the game until it ends.
Returns:
| Type | Description |
|---|---|
GameState
|
The final, unscrubbed game state. |
Raises:
| Type | Description |
|---|---|
TyrantError
|
If no player has a legal action. |
render_dict ¶
render_dict(state: GameState, viewer_uid: int) -> dict
Returns a JSON-serializable view of the state, scrubbed for the given viewer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
GameState
|
The game state to render; it is scrubbed for the viewer first. |
required |
viewer_uid
|
int
|
UID of the player who will see the view. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
A dict with |
Raises:
| Type | Description |
|---|---|
TyrantError
|
If the viewer is not in the game. |
render_text ¶
render_text(state: GameState, viewer_uid: int) -> str
Returns a prompt-ready Markdown view of the state, scrubbed for the given viewer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
GameState
|
The game state to render; it is scrubbed for the viewer first. |
required |
viewer_uid
|
int
|
UID of the player who will see the view. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Markdown with sections for the viewer, the players, private knowledge, the timeline, the board, the government and the current turn. |
Raises:
| Type | Description |
|---|---|
TyrantError
|
If the viewer is not in the game. |
read_replay ¶
read_replay(path: str | Path) -> dict
Reads a gzipped JSON replay file into plain dicts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
The file to read. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
The replay in the format returned by |
replay_dict ¶
replay_dict(replay: Replay) -> dict
Returns a JSON-serializable replay with a full board snapshot after every step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
replay
|
Replay
|
The replay to convert. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Plain JSON values holding the settings, every player's hidden role, the initial snapshot, one entry per step and the result. |
write_replay ¶
write_replay(replay: Replay, path: str | Path) -> None
Writes the replay to a gzipped JSON file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
replay
|
Replay
|
The replay to write. |
required |
path
|
str | Path
|
The file to write. |
required |
apply_action ¶
apply_action(
state: GameState, action: Action, player_uid: int
) -> GameState
Applies a player's action to the game.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
GameState
|
The full game state. |
required |
action
|
Action
|
The action to apply, usually one returned by |
required |
player_uid
|
int
|
UID of the acting player. |
required |
Returns:
| Type | Description |
|---|---|
GameState
|
The new game state. |
Raises:
| Type | Description |
|---|---|
InvalidMoveError
|
If the action is not legal in this state. |
TyrantError
|
If the action type is not recognized. |
get_legal_actions ¶
get_legal_actions(
state: GameState, player_uid: int
) -> tuple[Action, ...]
Lists the actions a player may take now.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
GameState
|
The current game state. |
required |
player_uid
|
int
|
UID of the player. |
required |
Returns:
| Type | Description |
|---|---|
tuple[Action, ...]
|
The legal actions, or an empty tuple if the player is dead or not due to act. |
Raises:
| Type | Description |
|---|---|
TyrantError
|
If the player is not in the game. |