How Turnbase keeps track of the game¶
Game State¶
During play, the Turnbase backend keeps an internal representation of the game state. The game state is a hierarchical structure.
- Game state consists of a set of PROPs and a set of CONTAINERs
- A CONTAINER‘s state consists of a set of PROPs and a set of TOKENs
- A TOKEN‘s state consists of a set of PROPs
So the game state looks like this:
game state
- props
- prop1
- prop2
- ...
- containers
- container1
- props
- prop1
- prop2
- ...
- contents
- token1
- props
- token2
- props
...
- container2
- props
- contents
...
PROP¶
Props are indexed by strings and can be any basic data type (numbers, strings, lists, etc. – anything but containers or tokens). Basically, it’s a special DICT
that we use special functions to access.
The game state must contain a PROP called play_order
. This should be a list of strings that contain the roles of the players. For example, for chess this would be ['white', 'black']
. During play, this PROP is used to determine CURRENT_PLAYER
as well as whose turns are coming up next.
Note
Prop values must be JSON serializable (e.g., basic data types (string, numbers), lists, dicts). Examples of things that are not JSON serializable are containers and tokens (see below).
CONTAINER¶
Containers are indexed by strings and have a set of props (similar to game state) as well as a list of children. The children are all TOKENs.
One of the props containers have is visible_to
, which is expected to be a list of strings denoting player names. This is used to manage visibility (for example, you may be able to see your own hand but not opponents’).
TOKEN¶
Tokens have a set of props and nothing else.
Initial State JSON¶
The initial game state JSON is not part of the LudL specs, but it is expected by the Game Prototype Editor, and provides a way to directly manipulate the game state at the beginning of the game.
Note
Do not directly specify token JSONs in the initial state JSON. Token should be instantiated with the INSTANTIATE_TOKEN
or INSTANTIATE_ALL_TOKENS
primitive, which take care of bookkeeping logic such as keeping track of the number of duplicates of a given token. Directly specifying token JSONs doesn’t take advantage of this built-in machinery and may cause conflicts.
Sample JSON:
{
"props": {
"tick": 0,
"suit_led": null,
"current_trick_num": 0,
"current_trick_count": 0,
"play_order": [
"player_0",
"player_1",
"player_2",
"player_3"
],
"player_scores": {
"player_0": 0,
"player_1": 0,
"player_2": 0,
"player_3": 0
}
},
"containers": {
"draw_deck": {
"props": {
"name": "draw_deck",
"type": "container"
},
"contents": []
},
"player_0_hand": {
"props": {
"player_id": 0,
"visible_to": [
"player_0"
],
"back_visible_to_all": true,
"name": "player_0_hand",
"type": "container"
},
"contents": []
},
...,
"player_0_play": {
"props": {
"player_id": 0,
"visible_to": [
"player_0",
"player_1",
"player_2",
"player_3",
"observer"
],
"back_visible_to_all": true,
"name": "player_0_play",
"type": "container"
},
"contents": []
},
...,
}
}
- As discussed,
play_order
must be a key forprops
and its value must be a list of strings indicating player names - Containers have
props
andcontents
as keys specifying their props and contents, respectively. - Containers have a
visible_to
key specifying a list of players who have visibility access to the contents of that container. - If the container contains only cards, they can have a
back_visible_to_all
prop indicating whether all players can see the backs of the cards.