******** Concepts ******** Definitions =========== In the |ss| we make the distinction between the *Client* and the *Player*. Client The client is the program that runs on the machine and that connects to the server. The client also contains the necessary Finite State Machine to play on the server. Player This is the human that controls the program. Robot A robot (*bot* for short) is part of the Client, it implements an AI. Device On mobile platforms (Android, iOS), the *Device* is the mobile device the Player is using on which the *Client* runs. Feature List ============ The |ss| is geared toward bringing the best experience to cross-platform online players with some unique features to implement turn by turn games. Player Features --------------- The |ss| implements various features pertaining to the player: * authentication and authorization * player ranks * karma * presence * devices Community Features ------------------ The |ss| also implements community features enhancing the player experience: * buddy list (list of friends to ease playing with them) * ignore list (list of other players for which no chat or no invitation will be received) * activity (what a player is doing at a given moment) * interactive lobby with: - persistent chat - list of players currently in the lobby - open-game list - real-time game creation Game Features ------------- The turn-by-turn game model of the |ss| allows the following features: * player clocks * turn by turn * asynchronous games * real-time synchronous games * robot hotswap * cross-platform push notifications of game events * persistent chat * in-game presence * game state persistence * game observation Player Concepts =============== .. _concept-player: Player ------ The :ref:`reference-message-com.daysofwonder.Player` is a set of data pertaining to a given player of a given game. This information is kept by the |ss| (and available on demand or when authenticating). It's also an entity that stays in the |ss| for as long as a connection is up or a player has games in progress. This entity is also the host of some information, like the linked :ref:`concept-device`. Authentication -------------- Before a player is authenticated, it isn't possible to do anything with the server. A given player is authenticated (for the moment) with her ``name`` and ``password`` combination. Upon authentication the |client| receives a :ref:`concept-session` identifier, which it should keep locally. This :ref:`concept-session` identifier has to be sent back for the next authentication to speed up the process. .. _concept-avatar: Avatar ------ Each player can have an avatar. This avatar can be either a 100x100 pixels image uploaded to |dow| website (custom avatar), or a link to either: * a standard |dow| avatar * an avatar from a partner .. _concept-session: Session ------- A session is a persistent entity in the |ss| representing the player, it is designed by a session identifier. .. _concept-ranks: Rankings -------- Each :term:`Game` can have several associated ELO-like rankings. Those rankings are the decreasing ordered list of player scores (that are called :term:`Rankscore`). The player that has the greatest (*i.e.* best) rank score has rank *#1*. There can be more than one ranking per :term:`Game` (like for instance to capture rankings in different game configurations, or for game variants). .. _concept-variants: Game Variants ------------- All games have at least one overall ranking. A game can have more rankings if it has variants. When creating a game, specifying ``main_variant`` and ``extra_ranking_variants`` in the configuration will make the |ss| update ranking for each of these variants. The ``main_variant`` will be stored in the player history. For instance, Ticket To Ride will provide the map as main variant (because in this game maps have different game rules). There are also orthogonal rankings, for instance to separate game modes or DLC. This is were ``extra_ranking_variants`` are useful: they only affect rankings. All incoming variants are expected to be simple short strings (not containing underscore) and will be returned in the format ``"_"``. For instance, when a Ticket To Ride ("TT") game is created with the main variant ``uk`` and extra variants ``[2p, ia]``: - ranking will be computed for ``TT_uk``, ``TT_2p``, ``TT_ia`` and ``TT`` (overall variant, always computed), - ``TT_uk`` will be stored in the player games history - karma will be updated for the overall game (``TT``) .. _concept-karma: Karma ----- The karma is an integer ranging from 0 to 100, that aims to represent the capacity of a given |player| to finish games. Each time a |player| doesn't finish a game, she loses karma, each time she finishes a game, she earns more karma. Usually it is possible to prevent people with low karma to join a game. .. _concept-presence: Presence -------- The |ss| maintains a presence status for every player. The status is ``present`` for connected and active players. It is possible for a |player| to subscribe for presence status change stream for some other players. .. _concept-device: Devices ------- To be able to send push notifications on the supported platforms (iOS, Android Google Play and Steam), it is required for the client to send push information to the |ss|. This usually happens during authentication. This push information, elsewhere called :ref:`reference-message-com.daysofwonder.game.push.DeviceType` usually takes the form of an opaque binary string given by the OS push notification service and a type. It is possible for a client to unlink a device. Community ========= .. _concept-buddylist: Buddy and Ignored List ---------------------- Each |player| has a Buddy list, which contains the friends of this player. The server allows the |Player| to manage this buddy list (add, remove or list buddies). Buddies are used when creating games by invitation. Friends are not reciprocal, you can add anyone to your Buddy List without her consent, and that doesn't make you one of her buddy. Like for buddies, each |player| has an Ignore list. This list contains players that are ignored by a given |player|. In this case, this |player| won’t be able to see chat from her ignored players, or play against those ignored players. .. _concept-activity: Activity -------- Each |player| using our systems will have an internal activity, telling if she is playing, in the lobby, waiting for friends... To have the full list of activities handled by the |ss|, please see :ref:`reference-field-com.daysofwonder.Activity.Code`. The |ss| tracks activities of all players, but reports it only for a given |player|'s buddies. In the Buddy List, each buddy will have its activity filled in. Please read :ref:`reference-message-com.daysofwonder.PlayerActivity` to learn more. .. _concept-lobby: Lobby ----- The lobby is a special place in a client where the players can see each others. This is where the community takes place in the client. The |ss| has a notion of lobby. A |player| can be in the lobby or not. When a |player| enters the lobby, her client will receive an endless stream of lobby events, among them: * content of the player-in-lobby list * content of the joinable open game list * chat events The *Lobby* also allows to create a new open game that other players in the lobby can join. This is the interactive real-time game creation. Once an open game is ‘full’ (with respect to the number of players set during game creation), the game really starts (it is removed from the open game list, the participating players are removed from the lobby). .. _concept-invitation: Invitation ---------- It is also possible for a |player| to invite some of her buddies to a game. It is not required for the |player| to be in the Lobby to do that. The system will send a Push Notification to the buddies that are not connected. The game will start only if all invited players accept the invitation (players can decline the invitation, in which case the game is aborted). .. _concept-private-games: Private Game ------------ A game created in the lobby can be *private*. This type of games requires giving a password to create them, this password is also needed to join. Private games can't be observed. Game ==== Once a game is started, it exists as an entity in the |ss|. Each and every game has an identifier (currently a 64 bits unsigned integer). All communication from a client to a specific game will require this identifier to be given. A Player can be part of numerous games at the same time (there is a limit of 100 games per player, though). At any time a player can get the list of the game they are part of (see :ref:`workflow-whatsnew`). What makes a game is the following information: * static :ref:`reference-message-com.daysofwonder.async.GameConfiguration` * list of :ref:`reference-message-com.daysofwonder.Player` * :ref:`Player Clocks ` * full :ref:`concept-game-state` * summary game state Local ids --------- Each player in a game has a 1-based id called the *local id*. Most of the interactions within a game are using those local ids. Not to be confused with |dow| ids or so-called global ids. Configuration ------------- The game configuration is used to set the number of players, and some other various aspects of a game prior to create it. Amongst Game Configuration properties, we have the ``rules_engine_version`` field which is at the discretion of the client to ensure a client can play with other on the same wavelength (avoid rules incompatibility, serialization model issues, ...). .. _concept-player-clock: Player Clock ------------ Each Player in a game has a Player Clock associated. This is the total time this |player| will be able to play in a given game. This duration is setup during the game creation (see :ref:`reference-message-com.daysofwonder.async.GameConfiguration`), it can range from several minutes to several weeks. When it is a player turn, her Player Clock ticks until it runs out. Once a given Player clock has run out of time, the player can’t play anymore in this game, and is replaced by a robot. When a Player Clock runs out of time, we say that the Player *timed out*. This feature prevents a non-playing player to abuse a game. Once her player clock has timed out, the game can progress. .. _concept-idle-timer: Idle timer ---------- Specifying an ``idle_time`` in :ref:`req-GameConfiguration` at game creation will start a timer (separate from :ref:`concept-player-clock`) at the end of which the active players will be considered idle. The idle timer is started immediately at the beginning of a new turn. At exhaustion, a robot will then be asked to play for the idle players. This timer aims to mitigate abuse of the player clock by malicious players, as they cannot lock the game by not playing during their whole player clock. See more in the appropriate section :ref:`workflow-idle-timer`. .. _concept-game-mode: Game Modes ---------- The Scalable Server supports two types of games that present a distinct game experience for the players: * *Synchronous Game*: those games are usually played in realtime and quickly. Players should have only one of them running at a time. The players are supposed to stay connected during those games. When a player is disconnected or leaves this game, she is automatically replaced by a Bot. Disconnected players can resume the game. Player that are still away at the end of the game will have ranking and karma penalties. * *Asynchronous Game*: those games are usually longer, and Players can have multiple of them at the same time. When players leave a game (or are disconnected), they are not replaced by a robot, but their Player Clock is running. Only when the player times out are they replaced by a robot (and get a ranking penalty). +-------+------------+-----------+ | |Asynchronous|Synchronous| +=======+============+===========+ |Forfeit| hotswap | hotswap | +-------+------------+-----------+ |Timeout| hotswap | hotswap | +-------+------------+-----------+ |Leave | | hotswap | +-------+------------+-----------+ .. _concept-forfeit: Forfeit ------- |player| can decide to definitely leave a game, in which case they :ref:`workflow-forfeit`. Once forfeited, the player is replaced by a robot, and her karma and ranking is affected (she is considered as losing the game). .. _concept-player-status: Player Status ------------- A |player| is considered live if her Client is connected to the server. If the |player| forfeited, timed out or left, they are not considered live. .. _concept-game-state: Game State ---------- Each game has an accompanying game state and possibly a summary game state. This game state is an opaque binary string for the server, where the Client implementer can put anything. Though, it is recommended to adopt an Event Sourcing scheme (allowing better counter-cheating controls). This game state can be quite large, and sometimes it is not fully needed when interacting with the clients, that's the reason it is possible to also set and retrieve a summary game state. For instance, it could be useful to keep in the summary game state only information that could be displayed in the out-of-game user interface, like player scores or number of cards. .. warning:: The game state data model will evolve during the lifetime of the client, for instance when fixing bugs or releasing new functionalities. You need to think about the incompatibilities of different versions of the client playing in the same game. We recommend reading `Manage online versioning `_ and using the ``GameConfiguration.rules_engine_version`` setting. .. _concept-game-status: Game Status ----------- Each game has one of the following status (see :ref:`reference-enum-com.daysofwonder.async.GameStatus`): * NOT_STARTED: before the first player played * IN_PROGRESS: during the game * OUTCOME: when one of the Clients declared the game is over * OVER: after all Players have seen the outcome * ABORTING: all Players forfeited (or left), this phase duration is short and the game proceeds to ABORTED * ABORTED: all Players forfeited (or left) .. _concept-user-data: User data --------- Sometimes a specific game requires each joining/invited player to provide specific private data. This is possible with the *user data* (see :ref:`reference-message-com.daysofwonder.async.LobbyJoinGameRequest` for instance). All the players' user data will be sent to the first player of the game, or will be accessible in the game :ref:`reference-message-com.daysofwonder.async.StatusReport`. .. _concept-observation: Observation ----------- The server supports the possibility for any players to observe a game in progress, depending on its configuration. If the observation is possible all the game events are broadcast to all the observers. Of course it is up to the game client implementer to do the necessary to prevent cheating (for instance by masking the game private information in the game UI).