Building Ethoas - Multiplayer Software Architecture

Tech — Software Architecture— Overview

Bálint Biró
4 min readMay 4, 2020
Photo by Cederic X on Unsplash

“DAWN WAS COMING. The Waystone Inn lay in silence, and it was a silence of three parts.”

Excerpt From: Rothfuss, Patrick. “The Wise Man’s Fear.”

Much like the silence of the Waystone Inn, the architectural backend of Tales of Ethoas — Eternal Struggle consists three major parts.

Eternal Struggle is a fast-paced, real-time multiplayer action RPG for mobile platforms. I know, I know, that’s quite the mouthful.

Let’s break it down:

  • Fast-paced, real-time: based on some preliminary user testing of a random group of people (N=20), the average player will issue 8 actions per second. Some will go up to 20–30+ actions per second. All of this is happening in real-time, so there are no turns in the game like there would be in chess, for example.
  • Multiplayer: each game session can host up to 4 players. This means that in a full game room I’m expecting on average 32 actions/second up to 80–120+ actions per second. Players can see and interact with each other in the game in real-time.
  • Action RPG (Role Playing Game): the typical core game loop in action RPGs is based on the player getting stronger with each game session by killing monsters, gaining items and new skills. Typical examples would be Diablo or Path of Exile. As Eternal Struggle is a mobile-first game, I’m designing each game session to last 10–15 minutes on average.
  • Mobile platforms: fairly self-explanatory, but it just means that the (main) target platforms are iOS and Android.

It’s important to establish and understand these concepts as they heavily influence the overall system’s design. Every game is different and what exactly your architecture should look like will depend on what your end goal is.

Three parts

While in this post I’m not going to go into details on how each tier works, I’m going to give you an overview of what’s involved in each and how they interact with each other.

We’ll dive into the specifics in upcoming posts.

Client (Frontend)

The game client is the thing that runs on the end-users physical device. It contains all the assets for the game but none of the actual game logic. Its role is to display the game in action to the user, send input from the user to the authoritative game server and process its output.

It is built in Unity3D with C#.

Web (Backend)

The web backend where metadata for the game is accessed. Metadata in this context is anything from user data to configuration that the game servers use to calculate how certain actions are executed.

It hosts both external and internal APIs, both with different authentication methods. Internal APIs are only accessible for trusted sources — e.g. the game server — , while external APIs are only accessible with authenticated user credentials.

It is written in Python 3.7 with the Chalice serverless framework and runs on AWS Lambda.

Game Server (Backend)

The game server hosts the actual game logic for Eternal Struggle. It takes input from the users, validates and acts on them accordingly. It is the meat and sauce of the game.

It is built in Unity3D as a game server linux build and is hosted on top of AWS GameLift.

Through the GameLift API, players can request new game sessions. If there’s a free game server process in the fleet, it gets notified, loads in a bunch of data from the web backend, generates a game session and notifies GameLift that it’s ready. The game client periodically checks in with the GameLift API and when it sees that the game session is ready, it establishes a direct TCP connection with game server. The player then joins the game and starts playing.

I’m a very visual person, so for me visualizing the architecture through diagrams helps a lot in understanding how certain pieces connect. The following chart is a rough depiction of the whole architecture.

This might look intimidating at first but in upcoming posts we’ll dissect the different components and take a deeper look at how they actually work together.

There’s a lot of thought that needs to go into systems design and it’s even tougher when it comes to stateful services. What tools you choose to run your game will heavily depend on the resources available to you. I’m relatively well-versed in AWS technologies, Unity3D, C# and Python (among other languages and tools), so for me it made sense to build my system around these technologies. As a solo developer I feel I need to utilize my own skill set to the best of my abilities and so this is what I ended up with.

I find that in the indie game development scene we rarely talk about the complexities of multiplayer games. Perhaps it’s down to the fact that building a multiplayer game is objectively hard and so it’s out of scope for most developers. Perhaps I just haven’t found the right resources yet. In any case, I’m really interested to hear about your solutions, tool choices and struggles along your own journey!

--

--