intro

Coup is a turn-based game where players try to eliminate other players while trying to survive. Everybody in Coup is out for themselves. To learn more about the game, check out the boardgamegeek.com’s page on it.

Today, I will cover about the internal data structures that implement the Game logic coup-server.

types

hand

A hand is a fixed-array of 2 uint8 values. All cards in the game are prescribed as uint8 values since there are only five cards.

cards

There is no card type in coup-server, instead uint8 is used all around since it is easier to do operations with it compared to a specific type.

claim

A claim is a data structure that essentialy has 4 values:

  • The player’s pointer
  • The value of character
  • A nullable succeed value
  • A nullable challenge value

Whenever the controller makes the claim pass, the succeed value is set to true.

However when the controller challenges the claim, the challenge value is set to true.

Now, after a claim has been challenged, one can either prove that the original claim has succeed or not via Prove.

Claims can be converted to Actions through the Action method.

This allows the Claims to be able to be stored in databases. More on that later.

notifier

Notifier has nothing to do with the game logic but has everything to do with coordinating value changes.

What Notifier does is provide a subscribe, announce, unsubscribe, set and get functions so that parts of the game package could easily be informed about different mutations to values.

actions

Actions are essentially what makes the game work. Similarily to how moves in chess further the game, actions are a representation of what things have happened.

It is worthy to note that claims can be converted to actions so that they’re stored in history.

game

A Game is essentially a collection of the Notifier, Action and Claim datatypes.

The reason why other packages will use Game rather than Action and an internal array of players is because Game does more than that. It glues everything together.

functional actions

One thing you’ll notice about coup-server is that actions are implemented about three of four times. The reason is simple: Each implementation deals with a specific data type or condition.

For example, the base IncomeAction function deals with uint8 values. However, the action data type glues those the player’s data structure with the IncomeAction function. Lastly, there is game that depends on the Action data type’s implementation but also stores actions in a history field.

Diagram representing the internal data structures and their purposes

I think this is what made much of coup-server enjoyable to me; the fact that debuggability is extremely easy. There is no need to create a game object, a player object to debug basic game functionality.

controller package

The Controller package deals with abstracting away the protocols. There aren’t any protocols planned besides HTTP, so using Controller is more of a design choice than anything else.

Controller would interact with the game internal package and the connected clients while also providing features that game doesn’t have.

For example, timer-sensitive turns and actions or protection of certain routes and functionality.

The following diagram illustrates the Controller package’s responsibility. A diagram showcasing the relationship between the client, the controller package and the game package

Timer-sensitive turns and actions would like this.

A diagram showcasing how timers could be implemented in the Controller


Stay tuned for more updates on this project.