Skip to content

Architecture

Server-authoritative networking model

CCG Kit is built around a server-authoritative networking model. This means the server is responsible for managing the state of the game in an authoritative way that prevents modified ("hacked") clients from maliciously altering said state. In that regard, clients are little more than "dumb" terminals that:

  • Send their input to the server.
  • Receive the state from the server and update the client's visual representation accordingly.

"Dumb" is a bit of an unfair term for clients though, considering that they also run the exact same logic the server does but locally in order to present lag-free visuals to the player. What does this mean, exactly? Let's consider how the use case of playing a card, a pretty common action in most CCGs, would flow in different server scenarios.

Non-authoritative server model

  • The client sends the information of the card it wants to play to the server.
  • The server accepts the information sent by the client and updates the state of the game accordingly.

The main problem of this approach is that the server does not perform any kind of validation on the information the client sends to it. This opens up the possibility of manipulating a client to implement the ability to play cards without having the appropriate amount of mana to spend, or even modifying the stats of the card to play to be a more powerful one (e.g., a 10/10 with abilities instead of a vanilla 2/3).

Server-authoritative model

  • The client sends the information of the card it wants to play to the server.
  • The server validates the information sent by the client and, if (and only if) it is deemed valid, updates the state of the game accordingly.

This approach prevents malicious clients from altering the state of the game by validating the client's information (in our example, making sure the client has enough mana to spend on the card he wants to play and also that the card is actually one of his hand cards). But it has an entirely different kind of problem: the client will only update its visual representation of the game after it receives a response back from the server. As online games always have a certain degree of lag, that lag will also translate into the visual representation of the game, resulting in a less-than-optimal user experience (in our example, the card will not move instantly from the hand to the board, but only after a response has been received from the server).

Server-authoritative model with client-side logic

  • The client sends the information of the card it wants to play to the server.
  • The client updates its local state of the game (in prevision that the server will find it valid).
  • The server validates the information sent by the client and, if (and only if) it is deemed valid, updates the state of the game accordingly.

This approach is an enhancement over the previous one. It still is server-authoritative (and therefore prevents hacking), but it also presents smooth, lag-free visuals because the client locally executes the same game logic that the server does. This is the networking model used in CCG Kit.

Of course, with this approach you could still have a malicious client performing invalid actions (or, more accurately, trying to). The difference is that now that would only be reflected on his local copy of the game state and would not affect the state of the server or any other players at all. At the next server-to-client synchronization step (usually the beginning of a turn), things would get back to normal on the malicious client side.

Core classes

All the core classes in CCG Kit are located in the Core/Scripts folder and live under the CCGKit namespace.

Server

The Server class is the brain of CCG Kit. On the editor side, it is a server-only object named Server and located in the Game scene. It manages the entire state of a game and the players connected to it. Communication between the server and the clients (the connected players) happens exclusively via network messages. Higher-level constructs like commands, client RPCs or SyncVars are not used for simplicity, efficiency and a higher degree of control.

NetworkProtocol

The NetworkProtocol class contains all the unique network message identifiers that are used in the kit. Sometimes, network messages are sent from the server to the players (e.g., the StartTurn message). At other times, they are sent from a player to the server (e.g., the PlayCard message). The entire architecture of the kit is built around network messages.

GameState

The GameState class contains the complete state of a game, including the state of the players and each and every one of the cards they own. The players store local copies of the game state that are periodically synchronized with the server (usually at the beginning of a turn).

EffectSolver

The EffectSolver class is responsible for applying the card effects of the game. Both the server and the clients have objects of this type in order to be able to update their copies of the game state accordingly.

Card

The Card class is the archetype of a card in your game. For example, a 2/2 Goblin.

RuntimeCard

The RuntimeCard class represents a particular runtime instance/copy of a card that can (and usually will) change during the course of a game. Following our previous example, we could have a copy of the Goblin card that has been damaged and currently has the values 2/1.