AWS for Games Blog
Host persistent world games on Amazon GameLift Servers
Multiplayer games have evolved from pure session-based and traditional massively multiplayer online games (MMOs) to newer online experiences that combine persistent and session-based elements. Games such as Destiny 2 and Rust are great examples of this. The persistent gameplay can be “hubs” or “home worlds” that players wander in and interact with, then launch into session-based experiences. These games can allow players to create new persistent worlds and log in and out as they please. Supporting this new wave of multiplayer experiences necessitates flexible technology, both for game session management and game world data persistence.
Amazon GameLift Servers is a purpose-built solution for hosting multiplayer games across multiple genres at global scale. The service supports multiple use cases from classic session-based games to different types of persistent gameplay. The introduction of containers support for Amazon GameLift Servers streamlines the challenges of hosting persistent world and session-based games. Persistent world games can run sidecar container processes with each game server to access databases for persistence data. You can also split world state management into multiple container processes that can communicate over localhost. When you need access to other Amazon Web Services (AWS) services for the game, the AWS Identity and Access Management (IAM) role of the container-based fleet is assigned automatically to each container, allowing you to use the AWS SDK and AWS Command Line Interface (AWS CLI).
In this post we cover how to combine persistent and session-based gameplay. This includes how to do the following:
- Manage the lifecycle of persistent worlds
- Manage player sessions for persistent worlds
- Persist the state of the game world
- Start session-based gameplay from within the persistent experience
Manage the lifecycle of persistent worlds
Persistent worlds encourage you to create new worlds as needed and allow players to join and leave them. The world creation can be player triggered, or centrally managed by your backend. You also need to route players to these worlds and manage player sessions.
The first step is to upload your game server build either as zip file or a container image, and create a global fleet for hosting on Amazon GameLift Servers. The multi-location capabilities allow you to host game worlds close to your players around the globe. The Containers Starter Kit is a quick and easy way to get any game server build running on the service.
To create the game world instances on the fleet, use the CreateGameSession
API with the AWS SDK. When calling the API, you pass the location and any game world specific metadata you need to create the world and receive information of the world in response. For a more event-based flow, you can also use an Amazon GameLift Servers Queue, and place game sessions on fleets through the queue.
An example request for the CreateGameSession call (using the AWS CLI for demonstration purposes) could look like the following:
A successful response would look like the following:
Then, the game session information you receive in response should be stored in a database for future reference. An option for storing the data is Amazon DynamoDB, which allows you to store key-value data at massive scale. The following figure shows a sample architecture for storing game world information. The game world creation can either be triggered by player requests (creating a persistent world to play in with friends for example), or by a backend process (provisioning persistent worlds based on a developer-provided configuration for example).
When game worlds become idle or meet their fixed lifetime, the underlying game session is typically terminated by the game server process itself. Amazon GameLift Servers allows you to host a game server process for as long as you need. After the game server has stored its state and is ready to terminate, it calls the ProcessEnding()
method of the Amazon GameLift Server SDK to automatically remove the game session. The fleet immediately creates a new process that is ready to host another world. It’s also possible to trigger the game session termination externally with the TerminateGameSession
API from the game backend. When using the graceful termination option of this API, the game server gets a callback and can manage a graceful termination.
Manage player sessions for persistent worlds
Players can typically leave and join persistent worlds over time. You can choose to either manage player sessions within your backend or use the player session capabilities of Amazon GameLift Servers. Player sessions are created with the CreatePlayerSession
API.
The following is a sample of requesting a player session with the AWS CLI:
Upon successful response, you receive connection information that can be passed back to the game client:
Then, the game client can connect to the session directly with IP/DnsName
and Port
. The attribute PlayerSessionId
can be used to validate the player identity on the game server side and to activate the player session. The figure below shows how a player requests to join a specific world, with the world information queried from DynamoDB and player session created for the world to provide the connection information.
To track the current player session count in a world, such as updated information on players who have left, we recommend centrally updating the game session data in your database. You can run a backend process that constantly updates the data. The DescribeGameSessions
API can be used to iterate through all game sessions. it retrieves up to 100 game sessions per request, and you can iterate through all sessions using the NextToken
received in the responses. The following figure shows an example of this implementation.
Persist the state of the game world
Typically when the session is running, the state of the game world is stored in-memory. However, we recommend periodically storing the world state to an external data store for multiple reasons. One reason is to clean up idle worlds after persisting their state, which allows you to restore the state when players rejoin. If you host game worlds that have a lifetime of multiple weeks or even months, then you want to be able to restore the world state in case the game server process crashes, or when doing a periodic rotation of the worlds to avoid memory leak issues.
The following are some options for storing the world state from your game server fleet:
- Storing a world save file directly to Amazon S3
- Running a local database on-disk and synchronizing the database dump/backup to Amazon S3
- Storing world data as key-value data in DynamoDB
- Implementing a secure API layer that receives the world data and stores it in a database of your choosing
In the following sections we go into detail for each of these options.
Storing a world save file directly to Amazon S3
Amazon GameLift Servers supports attaching an IAM role to Amazon Elastic Compute Cloud (Amazon EC2) instances or containers in your fleet. You can attach permissions to this role to access resources such as Amazon S3. Access to these resources can be done with the AWS SDK directly on the game server process or running a sidecar process or container that manages the access.
When storing world save files directly to Amazon S3, you generate the save file on your game server and upload it to Amazon S3. If you need to restore the world state on another game server process at a later stage, then you load the world data at launch.
Running a local database on disk and synchronizing a database dump to Amazon S3
Another approach is to host a local database, typically a SQL-based database solution to which the game server continuously writes world updates. Then, you have a sidecar process or a container that generates database dumps and uploads to Amazon S3 on an interval of your choosing.
Storing world data as key-value data in DynamoDB
A recommended option is to store the world state directly to a database, again either using the AWS SDK on your game server or using a sidecar process or container with which the game server communicates. Amazon DynamoDB is a great highly scalable option for this.
The benefit of this approach is that you have a fully managed highly scalable key-value database, and all world state changes are recorded in near real-time. This approach also offers seamless restoration of the world state. If your game design necessitates every player action to be persisted immediately, then this approach works well. The Amazon Games New World is an example of a game that uses this approach, handling about 800,000 writes every 30 seconds to store the game state. DynamoDB has an item size limit of 400 kB, so you often need to split the world data into multiple items.
Using a sidecar process for storage and databases
Game servers are commonly headless versions of your Unreal, Unity, or other game engine builds. Accessing a database or a storage service directly from the game server is doable, but separating this responsibility to a sidecar process or container provides several benefits:
- Use an AWS SDK in a language that is commonly used for backend features such as Python or Go
- No need to bring more dependencies to your game server project
- Develop and maintain database and storage integrations independently from your game server
- Offload the I/O intensive database operations from your game server process
Amazon GameLift Servers container fleets allow you to define a sidecar container, which the game server can access, for example with a localhost HTTPS endpoint, as shown in the following figure.
Start session-based gameplay from within the persistent experience
When we have our persistent experience in place, we can review the session-based elements of our game. This could be players grouping up in your hubs and heading out for a session-based PvE adventure, or a matchmaking-based PvP experience, as dictated by the game design.
Whatever the case, session-based game hosting is native to Amazon GameLift Servers. First, you upload your game server build, and set up which of the locations around the world you want to host games in. Then, you have two options depending on the experience: directly create sessions for a party of players, or use matchmaking.
Create a session for a party of players
When you already know the party of players who you are starting a session for (maybe they grouped up in your hub world), you can use an Amazon GameLift Servers Queue to request a session placement for them. You can either pass the latencies of each player against all locations you support or provide a priority list of locations in which to host the session. You can also define the properties of the session in the placement request. The game server process receives this information and can use it to load the correct map for example.
The following is an example of a request for session placement for multiple players using AWS CLI:
The Queue emits placement events that your game backend can process to pass on session information to the players.
Use matchmaking to group players
The other option is that players choose the session-based experience they want to join, and the game backend creates matchmaking tickets for each player to find the optimal group of players. This built-in matchmaking that uses Amazon GameLift Servers FlexMatch can have rules to match based on latencies, teams, as well as skill level and other player attributes. If your players have already created parties in the persistent experience, then they can be matched together to make sure they join the same team in a shared session.
The following is a sample API call to start a matchmaking ticket:
For a pre-formed party of players, you would pass all the players in a single call to make sure that they join the same team in a shared session:
Conclusion
In this post we covered how Amazon GameLift Servers can be used to host persistent world gameplay globally. We covered how you can manage player sessions for persistent worlds. Furthermore, we discussed the different approaches for persisting the world state and went deeper into how you can combine session-based gameplay with persistent experiences.
Modern multiplayer games use numerous strategies to manage how players are grouped, and how they are mapped to different instances of the game worlds and session-based gameplay. Amazon GameLift Servers provides the capabilities and APIs that allow you to build the unique experience that aligns well with your game design. Moreover, the power of the breadth of services on AWS allows you to efficiently expand to different methods of managing backend functionality and persisting world state.
Get started today with Amazon GameLift Servers for multiplayer game server hosting. Contact an AWS Representative to learn how we can help accelerate your business.