Jump to Content
Gaming

Build a multiplayer game with Cloud Spanner

March 21, 2023
https://storage.googleapis.com/gweb-cloudblog-publish/images/gaming_2022_KeCqWW5.max-2500x2500.jpg
Sarun Singla

Technical Account Manager, Google Cloud

Sagar Vaidya

Senior Solution Architect, Niveus Solution

Fantasy sports games are live service games built on real-world data. The data is collected from various sources such as real-world sports leagues, statistics websites, and news outlets. A virtual world is built where players can draft teams and compete against each other at a global scale in real time.

These games are characterized by low latency requirements, huge fluctuations in workload, and the need for a zero downtime architecture.  A successful game requires a robust database that is highly reliable, globally available and quick to respond to varying workloads.

Niveus is a Google Cloud partner that specializes in helping enterprises digitally transform workloads to both enhance their customer experience and differentiate themselves in the marketplace. The Niveus team recently evaluated Cloud Spanner and we built a demo fantasy sports game; read on to see how Spanner was used for this workload.

Why consider Cloud Spanner for real time multiplayer games?

  • Globally distributed, and scalable database: Spanner is a globally distributed database that can span across multiple regions. The Spanner architecture decouples compute from storage, which allows it to scale processing resources separately from storage. This allows for increased flexibility, reduced cost, improved performance, and increased reliability. The distributed nature makes it an ideal solution for global unpredictable workloads, like online games. When a game goes viral, Spanner's infinite scalability ensures that the game doesn't become a victim of its own success.

  • Transactional and strong consistency: Spanner supports ACID transactions so that millions of player actions are secure and consistent, resulting in a single source of truth for the game state. By default, Spanner guarantees "strong" reads that observe the effects of all transactions before the start of the operation, regardless of distribution or node failures. This is critical for games for storing game state and in-game transactions. 

  • High availability: Spanner's 99.999% uptime with zero maintenance windows is a great match for gamers' high expectations around responsiveness and uptime. 

Multiple games customers, like Niantic, Bandai Namco and Embark Games use Spanner as their backend games database because of Spanner’s differentiated capabilities. More details can be found on the Databases for Games page.

Fantasy Sports League (FSL) Game Implementation

Each matchup in the sports league starts with creating a fantasy team. Each gamer selects players from two competing teams in an upcoming cricket match. Points are awarded for different game activities. A live leaderboard is maintained throughout the game and the fantasy team with the most points at the end of the match is the winner.

A multiplayer game requires read/write operations for each activity a gamer performs along with storage of that data (id, username, password, players on the gamer’s fantasy team, their stats, etc.). In addition to basic gamer details, the system must also store backend game state and derived data like leaderboard snapshots. A viral multi-player game whose user count shoots up would see an explosion of compute and storage requirements; satisfying these requirements with a database like MySQL would require a developer to create, deploy, and maintain a sharded environment. This is tricky, complex, and expensive. In contrast, a Spanner database automatically shards data and distributes based on compute load, while also managing replication to provide the "database is never down" experience that assures a great experience to gamers. 

The game uses Node JS for the application layer, Spanner as the backend game database, and Cloud Memorystore as a caching layer for storing leaderboard data.

While our code is focused on running the game on Spanner, one could extend this architecture to include the analytics piece that is critical to any game deployment. This will include Dataflow, BigQuery, and Looker for analytics on the game data collected. In this architecture, we use Spanner change streams to pull data into BigQuery. BigQuery is a scalable, highly reliable, and secure cloud-based data warehouse for storing and analyzing large datasets and Looker is a powerful business intelligence platform that helps you explore, share, and visualize your data.

https://storage.googleapis.com/gweb-cloudblog-publish/images/IMG_1_Architectural_Diagram.max-1900x1900.jpg
High Level Architecture

As you browse through the code you can see the microservices that we developed:

  • FSL-Backend-Common - Contains several methods and utilities used by other microservices.

  • FSL-MS-Resource-Management - Handles CRUD operation endpoints for tables like Team Details, Match Details, Player Details, Fantasy Team Details, etc.

  • FSL-MS-Simulator - Simulates the match.

  • FSL-MS-Update-Leaderboard - To calculate the score for each fantasy team and update the leaderboard in Memorystore.

  • FSL-MS-Display-Leaderboard - Displaying the leaderboard data for a contest.

Match Simulation

FSL-MS-Simulator microservices include APIs to simulate individual balls and matches. /simulateBall API is used to simulate a ball. Similarly, an entire match gets simulated using a simulate match API by calling /simulateMatch.

https://storage.googleapis.com/gweb-cloudblog-publish/images/IMG_2updatingScore_wth_Pub_Sub_1.max-1000x1000.jpg

SimulateBall pushes a message to Pub/Sub topic simulatorListener and updateScore. UpdateScoreListener receives the data packet from Pub/Sub and calls the /updateScore API, which makes batches of a fixed length and pushes to updateRedis Pub/Sub topic to execute a huge amount of data in parallel.

https://storage.googleapis.com/gweb-cloudblog-publish/images/IMG_3MatchSimulation_Update_score_flow_1.max-1200x1200.jpg

Updating Scores

Score calculations are based on incrementing score for each team in Memorystore as the game progresses. Once the score is updated in Memorystore, it is updated in Spanner. To scale the writes, the data is pushed to Pub/Sub where all the subscribers listen to publish events and start writing to Spanner.

https://storage.googleapis.com/gweb-cloudblog-publish/images/IMG_4Leaderboard_SpannerUpdateFlow.max-1400x1400.jpg

Storing Leaderboard data in Spanner

After the final ball, we update the leaderboard snapshots in Spanner, enabling anyone who visits the site after the match completion to see the final leaderboard for the match. Machine Learning models can be built on the stored data in the future for predicting user scores and potentially winners.

https://storage.googleapis.com/gweb-cloudblog-publish/images/IMG_5MatchSimulation_ScoreIUpdates.max-1000x1000.jpg

Leaderboard

Fantasy teams are listed on the leaderboards and are ranked based on the scores. The score gets calculated in Memorystore for each team. During a live match, all the writes happen to the cache and a live leaderboard is retrieved from  Memorystore.

https://storage.googleapis.com/gweb-cloudblog-publish/images/IMG_6Get_LeaderboardScore_ToMemoryStore.max-700x700.jpg

Post Simulation Results

Post-simulation, we store the top ten fantasy teams in the contestDetails and MatchResults tables in Spanner.

https://storage.googleapis.com/gweb-cloudblog-publish/images/IMG_7Get_LeaderboardScore-Spanner.max-700x700.jpg

Conclusion 

Spanner with its high availability, strong consistency, and distributed nature became a goto database for our multiplayer game development. Many gaming studios and game developers trust Cloud Spanner to provide a rock-solid backend that lets them focus on what they do best: building great games. 

Learn more about the Spanner free trial instances available at no cost to both existing and new Google Cloud customers. 

If you want to learn more about uses of Spanner, and specifically how it helps in games:


We would like to thank Aalok Muley, Group Product Manager, Databases (Google Cloud) for his help on this blog.

Posted in