Game Developer Deep Dives are an ongoing series with the goal of shedding light on specific design, art, or technical features within a video game in order to show how seemingly simple, fundamental design decisions aren’t really that simple at all.
Earlier installments cover topics such as how solo developed Devon Wiersma optimized the spraypainted world of Bombing!! 2: A Graffiti Paradise, the updated visuals and production pipeline of Ravenlok, and how the team behind the genre-bending God of Rock blended fighting and rhythm games into one cohesive style.
In this edition, Total Mayhem Games’ co-founder and tech manager Sam Meyer explains how planning for crossplay in We Were Here Forever started long before the game’s development and how thinking ahead can help you build an infrastructure that will benefit all your games in the long term.
In today’s gaming industry, enabling crossplay functionality has become crucial in connecting players and allowing them to enjoy games with friends on different platforms. For Total Mayhem Games, the indie game developer behind the popular co-op puzzle adventures of the We Were Here series, communication and cooperation are fundamental game mechanics.
The studio’s latest installment, We Were Here Forever, is a cooperative puzzle game where players take on the roles of two Explorers trapped in the fallen kingdom of Castle Rock. The game is played in a first-person perspective, with each player starting in a different location and unable to see the other player’s surroundings. To progress through the game, players communicate with each other using walkie-talkies and solve a series of mind-blowing puzzles together. This unique adventure features various asymmetric puzzle designs where each player can access different information and must share it with their partner to progress. The game requires players to work closely together and communicate clearly, which, when it goes wrong, can end up in hilarious, puzzling and sometimes slightly confusing or panicky situations. Luckily, most Explorers make it out of there happy and healthy, with their friendship still intact… we think.
”Explorers? Are you there?”
Hi, I’m Sam Meyer, one of Total Mayhem Games’ founders and tech manager. As of March 2023, We Were Here Forever has broken all the studio’s records since its release, making it clear that the game’s popularity is rapidly growing. The game’s success has made crossplay functionality even more important, allowing players on different platforms to join forces and solve challenging puzzles together.
Achieving crossplay functionality requires significant coordination and cooperation between platform providers and game developers. In this article, we will explore the steps Total Mayhem Games took to enable crossplay within We Were Here Forever and the processes involved in making it all happen.
The process of creating support for crossplay in We Were Here Forever started long before the actual production of the game began. As a studio, we learned a lot from repeatedly rewriting the same functionalities during previous games’ development. This experience prompted the team to take the time to refactor and draw out all the systems that were common functionalities for any game and created what we call a ‘core’ package. That package can be reused in any game we develop, saving a lot of time. It is a single point of entry for game code to utilize features such as input handling, accessing account info, unlocking achievements, connecting to voice-chat servers, retrieving friend lists, storage management, and creating and managing online sessions. And because it is isolated from implementation, it becomes easier to reuse.
All of the core systems in We Were Here Forever are built as a ‘provider-based layer.’ This means that all third-party plugins can be swapped out if needed. This approach is not only a great way to support crossplay but also helps centralize any external dependencies. If, for example, a plugin’s backend solution is discontinued, we can delete the providers based on that system and rewrite them using another service.
But how does this help with crossplay?
Consider the following simplified overview of how player data is retrieved in Forever:
When launching the game, we initialize core functionalities with a native provider corresponding to the platform it’s currently running on and a backend provider. Because each implementation is forced to give its results in the same way back to the core package via an interface, the game code doesn’t have to deal with how every platform handles each feature. It can rely on a homogenized, platform-agnostic data container displayed in the image as ‘User Data.’ Therefore, the game can display and interact with other players regardless of what platform they are playing on.
Accessing player data from someone playing on another platform can be challenging. In that case, the local native provider cannot find that player, and the returned data will only contain the backend ID, display name, and avatar URL. Because each player is registered on their backend when they first launch the game, this info will always be available cross-platform. The game code cannot depend on these values to be available in every instance.
The lobby and matching system in We Were Here Forever is another system that is built in the same manner. To team up with each other cross-platform, the client needs a platform-independent data representation of native handles and player IDs, displayed in the image below as ‘Lobby Data.’ When the game code asks for a new lobby to be created, the lobby system will do so in three steps: 1) first, it creates a group entry on the backend, 2) then it attempts to create a native session using the platform-specific provider, which is required to be able to see and join others through, for example, the steam friends list, and 3) finally, the native session ID is stored inside the backend session object, and the game code is notified of the result of the operation.
When inviting a friend through the game UI in the main menu, the backend lobby ID is sent to the other client to join as an invite. If that client is running on the same platform, a native invite is also sent. Because the game code doesn’t know about any platform-specific implementations, it doesn’t require changes when adding new providers for other platforms. It just communicates with the lobby system if a player wants to invite someone regardless of the target player’s current platform.
The same goes for join requests that players make when they see their PlayStation friend awaiting other players in the main menu. Our native PlayStation provider catches it and invokes an event through the Lobby system.
Before I go, let me leave you with a final recap of our journey that might help you save time in your development process. Developing games can be a race against deadlines, so designing your code with cross-platform in mind can really save you some sleepless nights.
In short, think about crossplay functionalities early on in development. Explore how the same functionalities work on every platform you plan to release your game on. That way, you know how to build a single data structure that game code can utilize without any platform dependencies. Adding on more platforms becomes plug-and-play by creating a layer between platform-specific code and game functionalities.