Repository navigation
Game Server Requirements
The game server is the brains of the game operation. It manages running the simulations for the players.
- Being able to run multiple games at once
- Load balancing and queuing players' games
- Build code and test player code in a safe and controlled environment
- Running headless simulations of games
- Matchmaking system for any amount of players
- Any game must accept one or more players
- Storing and replaying game sessions from events gathered between each client and server interaction.
- Players must be able to run their code in 3 modes: debugging, testing and playing
- Players' agents may or may not respond within the time frame and the decision must be left to the maker of the game.
There are 3 modes that a participants can "run" their code
- Debugging: Locally on their laptop sending messages to the server and playing against an admin test agent (as soon as the game is done it resets to play again). If the game is PVE, no admin test agent is required.
- Testing: Participants queue in to make their latest uploaded code run inside the server (docker) and play against the admin test agent (can only requeue when their game was played).
- Playing: When the administrators decide, the last uploaded version of a participants code will be put against the other participant's agents
Testing can occur one of two ways, either the player queues in for their latest version of their code to be tested or if their latest agent version is still untested.
The purpose of testing is to:
- Allow participants to see how their code will behave in the same environment as real games.
- See if participants have the minimum requirements to play the game (i.e. they would loose every single game)
To pass the test and compete, an agent must be able to complete a game against the admin agent and send minimum 1 action.
To test games that have more than 2 players, the admin agent will be utilized until the room is full. E.G: You have a 4 vs 4 game that you want a participant's agent to be tested, you need the participant player to be in the same room with 3 copies of the admin agent. If you are playing a 1v1, the admin agent is only needed once.
Some games will decide that an agent must always do an action and that if it doesn't that player looses. In these types of games, the test will not pass because the game will end immediately and the agent will not have made any actions.
Players will have 3 SDKs (Software Development Kits) available to them to code in different languages: Python, C#, and Typescript. These SDKs will enable the participant to construct their best solution for the game offered by the hosts. The users will have access to a test solution with which they can go up against locally and manage the game session as they wish.
A replay view of the test game will be saved, enable participants to replay the simulations at will locally.
When a participant submits code as their solution, it will be built and transformed into a named docker image ready to be used. This docker image can then be instancetiated multiple times if it needs to play multiple games in parallel.
The goal is to have the simulations run separatly from the graphics. This enables to us to simply store the server and client interactions as a sequence of linear events or actions from either side. This makes the game "run" headless as we can simply refer to these saved events in order to reconstruct the session and offload the rendering to the user.
The container management would be done with Kubernetes Pods where we can start, stop and monitor how participant agents are doing (i.e. did they crash?). This architecture would help us to keep track of containers while writing less code.
The game controller is a code abstraction that separates how a game is run (game logic) and which game needs to be run at at what time.
The game controller needs to:
- Decide who is in what game
- Start a game
- See when a game was finished
- See when an agent in a game has crashed (TODO: figure out how to give this information to player/host)
- Tally the scores of games
- Keep track who won which game
- Decide when to save recordings of games
A queue system will be needed in order for participants to be able to test their code on the host's infrastructure and keep the infrastructure running on a consistent amount of resources usage.
We must be able to accept any number of players that are playing the same "game" together.
Since one of the requirements is to be able to handle a great amount of player, we want to reduce minimize the amount of simulation to run once it is time to score players. Therefore, with huge amounts of players, we will run and ELO rating system similar to how chess rating works. The point is to have everyone go through a maximum amount of games against other players in order to get a ELO rating.
Once an ELO rating is achieved, the players are ranked according to their rating from best to worst. Then, a group of 2^X top players are chose to compete in tournament elimination style games with an odd amount of rounds in order to produce a winner from each matchup. Thus, players progress through the brackets, and a winner is is declared in log(X) matches. The hosts will also be able to make the entire tournament or only certain brackets viewable by all the players at once. Following the design of Simlations, we will have the rounds simulated and then replayed live so that other players can view them.
We will assume that any agents that are run are hostile and unreliable. That is, they may try to cheat the game and that they may not always respond in time for the next game tick (also called step).
Notice that an agent missing a tick (or step) in the game could be a valid strategy for certain games. For example, they could be doing an initial computation of strategy before their first move. The game server should leave it up to the game designer to decide what should be done when an agent doesn't answer in time.
To achieve these goals, the server must wait for the players in a room (or game) to answer within a time frame (say 0.5s) and collect all of the actions. If a player doesn't answer in this time frame, the player action is not collected and the simulation tick goes ahead without that player.
sequenceDiagram
autonumber
participant S as Game Server
participant A1 as Agent 1
participant A2 as Agent 2
participant A3 as Agent 3
Note over S: Start simulation tick (step)
S->>+A1: Send initial game state
S->>+A2: Send initial game state
S->>+A3: Send initial game state
A1->>-S: Action1
A2->>-S: Action1
Note over S,A3: Wait Ended 0.5s
Note over S: Advance simulation tick<br/>using only collected actions
par
S->>+A1: State1
S->>+A2: State1
end
A3->>-S: Action1
A1->>-S: Action2
A2->>-S: Action2
Note over S,A3: Wait Ended 0.5s
Note over S: Advance simulation tick<br/>using only collected actions
par
S->>A1: State2
S->>A2: State2
S->>A3: State2
end
Note over S,A3: Repeat until game is over
The SDK generation will be handled for each language the same way. We describe the types in CSharp and annotate which fields need to be sent to the client. We generate the .proto file for the specific types. And then we generate file types and connection code for each language.
flowchart TD
Types["Define types in C#"] --> Fields["Annotate fields to send to the client"]
Fields --> Schema["Generate shared .proto schema"]
Schema --> Generation["Generate SDK for each supported language"]
Generation --> TS["TypeScript"]
Generation --> CS["C#"]
Generation --> PY["Python"]
TS --> TSFiles["Type definitions and connection code"]
CS --> CSFiles["Type definitions and connection code"]
PY --> PYFiles["Type definitions and connection code"]
TSFiles --> TSSDK["TypeScript SDK"]
CSFiles --> CSSDK["C# SDK"]
PYFiles --> PYSDK["Python SDK"]
Interaction Website Requirements
Team Website Meeting Minutes
Team Server Meeting Minutes
Team Viewer Meeting Minutes
User Consent and End-User License Agreement
Overall Architecture and Class Diagrams
Testing Plan and Continuous Integration
Deployment Plan and Infrastructure