Skip to content

Latest commit

 

History

History

backend

Requirements

Player identification

  1. A User needs to have tokens which she/he will then provide to her/his bot.

  2. Bots and Users can play a game as a given player. The game needs to know if the User/Bot is allowed to play as this player.

  3. Some games can allow multiple players to play simultaneously.

  4. Users might play multiple players in debug mode.

  5. Points 3 and 4 imply that the User needs to say which player she/he wants to play.

  6. The token used by bots is used to create the connection which will last until every game is finished. Thus it needs to contain an identifier which can be used by the backend to identify which player the bot can play during each game.

  7. When Users and Bots are rescheduled from one game to the next their player number might change. Thus we can’t use playerNumber as identifier. We need a unique identifier.

Training

  1. Users should be able to know how well their bot performs against bots from other teams. We want to encourage teams to provide their bots all the time so that they play against each other. Thus every match scheduled automatically will count toward the final score. This will also create a sense of urgency.

  2. We want to avoid teams winning because they provided a basic bot very early and other teams forgot to do it. Thus early matches make you win less points than the last matches.

Design

Game State

  • A Game State is just a JSON object.

  • A Game State has a flag indicating if the game is ongoing or finished.

  • A Game State has one or more Player Spots.

  • A Game State is not dependent on who are the Players.

Game

  • A Game has a Game State.

  • A Game can be reset to a past or future state by just replacing its state.

  • A Game has one or more Players.

  • A Game links Players to Player Spots in the Game State.

  • A single Player can control multiple Player Spots. This is useful when a user debugs a bot, as she/he can control multiple oponent players at the same time.

Player Spots

  • Each Player spot has a unique number.

  • Each Player spot has a flag indicating if the corresponding player is currently playing.

  • Multiple Player spots can play at the same time if the game allows it.

Players

  • A Player is either a bot or a user.

  • A Player has a unique identifier.

User

  • A User belongs to a Team.

  • A User is authenticated via a browser.

  • A User has a User Token. It enables the server to recognize her/him at every request.

Bot

  • A Bot is owned by a Team.

  • A Bot connects to a Game Schedule using a token.

  • A Bot has a name which can be changed whenever its owner want. This enables the creation of win/loss statistics during the training phase.

Team

  • A Team regroups multiple Users and their Bots.

  • A Team can be composed of a single User or multiple Users.

Tournament

  • Users join a Tournament and form Teams.

  • Teams fight in the Tournament Arena to win.

  • Teams can train in the Training Arena

  • Teams can test and debug their Bots in their own Debug Arenas.

Game Schedule

  • A Game Schedule is a sequence of Game to which subscribers play.

  • Multiple Players can subscribe to a single Game Schedule. They move together from Game to Game.

  • There are two kinds of Game Schedule: Debug Game Schedule and Versus Game Schedule.

Debug Arena

  • A Team has one Debug Arena per User in the Team.

  • Every User in a Team has access to every Debug Arena of this Team.

  • A Debug Arena runs successive Games. Users control when a new Game is started.

  • Users can configure the Game which will be started.

  • A Debug Arena has a single Game Schedule to which every Player connects.

  • A Debug Arena provides tokens for each Player Spot so that Bots can play them.

  • It is possible to select to play against a bot connected to the training arena.

Training Arena

  • Multiple Teams can connect to the Training Arena whenever they want.

  • A scheduler starts automatically matches between every connected bot.

  • The results of each match is aggregated

  • A match is stopped and deleted if either:

    • If a match is not finished after 5 minutes it is automatically dropped.

    • If the name of a bot changed during a match, this match is dropped.

  • Each Team has a single Game Schedule in the Training Arena. Teams Bots and Users connect to this Game Schedule.

Tournament Arena

  • The Tournament Arena opens only once.

  • Games in the Tournament Arena are scheduled automatically.

  • The Team winning the most Games in the Tournament Arena wins the Tournament.

  • Once a winning Team is chosen the Tournament is closed.

  • Each Team has a single Game Schedule in the Tournament Arena. Team’s Bots and Users connect to this Game Schedule. Every time a new Game is accepted the Game Schedule sends this Game to every player.

User Token

  • A user token contains the user ID. This user ID plays also the role of Player ID.

Bot Token

  • A Bot token contains a unique Player ID.

  • The PlayerID is unique to a Game Schedule. ⇒ The Token is different for the Debug Arena, Training Arena and Contest Arena.

Architecture

High level model

classDiagram
class Game
class TournamentGame
class DebugGame

class Player {
  +UUID PlayerId
}
class Observer

class Tournament
class TeamMember
class Team
class DebugArena
class TournamentArena
class TournamentRound
class GameRules {
  +number numberOfPlayers
}

Game <|-- TournamentGame
Game <|-- DebugGame

Player "2..*" --> "*" Game: plays
Observer "*" --> "1" DebugGame: observes
Observer "1" --* "1" DebugArena

Tournament "1" *-- "1" TournamentArena
TournamentArena "1" *-- "1..*" TournamentRound
TournamentRound "1" *-- "*" TournamentGame
TournamentGame "*" --> "2..*" Team

Tournament "1" *-- "*" Team
Team "1" o-- "1..*" TeamMember

Tournament "1" *-- "1" GameRules


Team "1" *-- "1..*" DebugArena
TeamMember "1" --> "1" DebugArena: manages
DebugArena "1" *-- "1" DebugGame

Game State Model

Each Game stores its state as a javascript object. This object contains some mandatory fields.

classDiagram
class Game {
  +Map[PlayerId,PlayerNumber] playerAssignments
}

class GameState {
  +boolean end
  +Array[PlayerNumber]? winners
  +Array[PlayerNumber] playing
}

Game "1" *-- "1" GameState

Tokens

Both user and Bots use tokens to authenticate to the server.

classDiagram
class UserJWTokenData {
  +UserId userId
  +string JWTFingerprint
}

class BotJWTokenData {
  +PlayerId playerId
}

Observing a game

Team member observing a debug arena

sequenceDiagram
autonumber
participant Teammate Browser
participant User Browser

User Browser -) Server: Observe Debug Arena (UserJWTokenData, TeamMemberId)
activate Server
Server ->> Database: subscribeDebugArena (TeamMemberId)
Database -->> Server: Response (GameId)
Server --) User Browser: Subscription Event (GameId)
loop For each new game
  Teammate Browser ->> Server: Create new game (UserJWTokenData, TeamMemberId, Config)
  activate Server
  Server ->> Database: Create new game (TeamMemberId, Config)
  Server -->> Teammate Browser: Success
  deactivate Server

  Database --) Server: Subscription Event (GameId)
  Server --) User Browser: Subscription Event (GameId)
end
User Browser ->> Server: End Observation
deactivate Server

Team member observing a debug game

sequenceDiagram
autonumber
participant Bot
participant User Browser

User Browser -) Server: Observe Debug Game (UserJWTokenData, GameId)
activate Server
Server --) User Browser: Subscription Event (Game History)
loop For each new game state update
  Bot ->> Server: Play Game (BotJWTokenData, Action)
  activate Server
  Server -->> Bot: Success
  deactivate Server

  Server --) User Browser: Subscription Event (GameState patch)
end
Server --) User Browser: Game end (End Observation)
deactivate Server

Playing a game

Bot connecting to a player schedule

Note that bots don’t know if they connect to tournament or debug games. All they know is that they have a set of games scheduled which they have to play.

sequenceDiagram
autonumber
Bot -) Server: Subscribe as player (BotJWTokenData)
activate Server
Server --) Bot: Subscription Event (PlayerSchedule & list of GameIds)
loop For each new scheduled game
  Server --) Bot: Subscription Event (GameId)
end
Bot ->> Server: End Subscription
deactivate Server

Bot playing a game

sequenceDiagram
autonumber

participant Other Bot
participant Bot

Bot -) Server: Subscribe to game as player (BotJWTokenData)
activate Server
Server --) Bot: Subscription Event (Game & GameSate)
loop For each new scheduled game
  alt Bot turn to play
    Bot ->>+ Server: play (BotJWTokenData, action)
    Server -->>- Bot: Success
  else Other Bot turn to play
    Other Bot ->>+ Server: play (BotJWTokenData, action)
    Server -->>- Other Bot: Success
  end
  Server --) Bot: Subscription Event (GameState patch)
end
Server --) Bot: Game end (End Subscription)
deactivate Server

Tournament Round Scheduling

Tournament Round Draw

A set of games is automatically scheduled during each Tournament Round. When a tournament is created two formats are available:

  • exhaustive matches: players play agaist every other player. This creates a lot of matches. For example it schedules 190 matches at each round for only 20 players. This format is not recommended for more than 20 players.

  • random draw: multiple small group of players are randomly created. Every player plays other players in its group. New groups are randomly created with the winners of each group. The group size can be configured. For example it schedules only 240 games for 100 players with a group size of 5 players.

This is what a random draw looks like with 10 players and a group size of 3.

flowchart BT
    p1["player1"]
    p2["player2"]
    p3["player3"]
    p4["player4"]
    p5["player5"]
    p6["player6"]
    p7["player7"]
    p8["player8"]
    p9["player9"]
    p10["player10"]
    p3l2["player3"]
    p4l2["player4"]
    p9l2["player9"]
    p4win["player4 (winner)"]

    subgraph level 1
      subgraph group 1
        p1
        p2
        p3
      end
      subgraph group 2
        p4
        p5
        p6
      end
      subgraph group 3
        p7
        p8
        p9
        p10
      end
    end

    subgraph level 2
      subgraph group 1
        p3l2
        p4l2
        p9l2
      end
    end
    p3 --> |wins| p3l2
    p4 --> |wins| p4l2
    p9 --> |wins| p9l2

    p4l2 --> |wins| p4win

Tournament round execution

stateDiagram-v2

  state "Waiting next Round" as wait
  state "Retrieving connected players" as connectedPlayers
  state "DrawingGroups" as drawingGroups
  state "Scheduling games" as scheduleGames
  state "Waiting for games to end" as waitGames
  state "Saving level results" as SaveLevelResults
  state "Saving round results" as SaveRoundResults

  [*] --> wait: start Tournament
  wait --> connectedPlayers: new Round triggered
  connectedPlayers --> RunLevel

  state RunLevel {
    [*] --> drawingGroups
    drawingGroups --> scheduleGames
    scheduleGames --> waitGames
    waitGames --> SaveLevelResults
    SaveLevelResults --> [*]
  }
  RunLevel --> RunLevel: run next level
  RunLevel --> SaveRoundResults: last level finished
  SaveRoundResults --> wait