In the previous two articles, we covered the "straightforward port" stage of the adaptation process and then went onto describing all the different types and approaches we identified for it over the years. You can refresh your memory on straightforward ports right here and on this page. Now, let's move on to the next stage in the process, which we call the "tailored build."
The goal of the tailored build stage is to conceptually and technically match the game to the target platform in such a way that it plays and feels as if it were designed for this particular platform from the start. We tailor games because we want to leverage any platform specific features to the maximum extent, and we aim for these versions to be the best versions to date.
This process starts with an intimate understanding of each platform, including strengths, limitations, quirks and gimmicks, etc. Abstraction has been doing this for quite some time, so this knowledge already exists and is not just academic, but also practical knowledge.
The next step is to look at platform-specific features that make sense for any given title and cater the game to utilize these as much as possible. These could include peripheral features (like HD rumble and adaptive triggers), platform service features (like achievements, leaderboards, cloud saving, (multi-)user engagement and player presence), and other more generic features that players of the platform have come to expect (like tutorials, localization to more languages, voice chat, etc).
Below is another story from the Abstraction Vault, from when we adapted a game to two different platforms that each provided completely different tailoring challenges.
Tailoring SNK Heroines
By Micael Dias (programmer)
Tailoring SNK Heroines for PC and Switch was very challenging for many different reasons. The Nintendo Switch is a platform that needs special attention to performance and useability for both handheld mode and docked mode; while PC can usually expect fairly capable hardware but with more problems due to many kinds of different input peripherals. We want all of these to be properly adapted and not just implemented as in a "straightforward port."
Since the game was originally developed with PS4 in mind, optimizing for performance on Switch was no easy task. There were issues with both raw power and memory availability when trying to do the same thing as the original platform, so we had to optimize textures, meshes, and other rendering technicalities.
This proved to be quite a challenge, and some assets proved to be challenging to execute as the automated ways to reduce polygon count just couldn't do the task without leaving behind major artifacts or other quality issues. We ended up developing our own tools to do this in ways that allowed us to hand tweak everything that needed extra attention. We also had to reduce vertices' precision to 16-bit only, which generated a whole lot of other quality issues that had to be dealt with.
In some instances, the UI itself also proved to be a performance problem, and parts of it had to be either tweaked or redone to accommodate the Switch hardware.
Another area that needed a lot of attention on the Switch was the handheld mode, where the game's UI had to remain readable on a much smaller screen. We had to create a solution that automatically changed the font scale when switching from docked to handheld mode and vice versa. This created more issues, as text strings wouldn't fit inside their UI element anymore, and so on, so heavy tweaking was done to the UI to remain as close as possible to the original while still delivering good usability.
On the PC, the problems that need tackling were very different. Performance was no longer the biggest issue, but instead, we had a whole lot of different peripherals that we wanted to support, including a keyboard option for multiple players. Usually, on consoles, it's expected that each player holds their own device, so the internals of the game weren't ready to support multiplayer on a single device. We did not want to just hack it by using fixed keys, so we heavily modified the input system and the button binding UI in order to fully support the keyboard as well as any other type of input peripheral.
The keyboard and other peripherals support didn't end with wiring the correct keys to the right actions though. All the UI pieces that reference a key now had to know which type of peripheral was connected and what key that action corresponds to. This gets especially difficult with a keyboard if the engine is not ready for it, which was the case. So, we again had to shape it into supporting this.
When a game features a multiplayer mode, it usually means that many other aspects need to be considered during tailoring. Features like controller pairing -- especially with online features -- are handled in a unique fashion per platform and have very little overlap between them. Below are two different cases related to multiplayer taken from our Vault. The first describes the challenges when tailoring a local multiplayer game mode, while the latter goes in-depth into online features.
Adapting a game that supports local multiplayer
By Coen Campman (lead programmer), Mike van Mourik (programmer), Tomas Lori (programmer)
Local multiplayer has been around since the early days of consoles, and for many people it has been at the core of the console experience. The fun of sitting around the TV with friends for some co-op or battling each other to see who the is the best is a very different experience from today's online multiplayer paradigm.
Usually, games that support couch co-op make it a core part of the experience and as such, when it comes to adapting a game with it, it can make or break the adaptation.
When it comes to adapting a game with [couch co-op], it can make or break the adaptation
Totally Reliable Delivery Service (TRDS) had both local and online multiplayer, but they were kept as separate game modes by the original developer. You could either play with up to three friends locally (each with one controller sharing the same console) or up to three friends online (allowing only a single player on each separate console).
Here we will dissect some of the complexities to deal with when adapting the local multiplayer feature, such as engagement, controller pairing, performance issues, and more.
- Engagement and controller pairing
In the old days, you would simply have controller 1 and controller 2 and that was it, but with the current-gen consoles, there is a lot more to it.
Controller pairing is quite simply the mapping of users to controllers. This is necessary, for example, to identify which specific player unlocked an achievement, and other things like saving game progress and player preferences. To be able to do this properly, we need to know who is using which controller.
Xbox gives a lot more control (or responsibility) to the game on how controllers and players are linked together
When you boot up a game, you often find yourself looking at a "press (X or A) to start" screen. This is the engagement screen, and it's the moment where the game ties the primary player's user account to the controller he or she is using. In most games, the engagement with this primary player has a bit of extra weight to it. Their account is used to set up core game systems such as saving, and most games return to the main menu if this account is signed out from the console unless some kind of handover is performed.
A thing to note when it comes to controller pairing on Xbox is that the platform gives a lot more control (or responsibility) to the game on how controllers and players are linked together. This pairing must be done by the game and reported to the system, unlike platforms such as PlayStation, where this is handled by the console itself. Not doing this correctly is often a reason for a game to fail certification.
Depending on the type of game, there are multiple approaches to configuring additional players. One of the most common is having a lobby where people can easily configure the player-controller bindings for all the non-primary players.
A traditional approach to local multiplayer is splitting the screen, which has significant performance implications. If a game requires each player to render their own camera view, you might find that the game suddenly doesn't run at 60 fps anymore and can sometimes even struggle to reach a stable 30.
Certain optimizations like turning sections of a level off when your player isn't in that area might suddenly not work anymore because the other players in the game can spread out to these other sections, increasing the load.
For TRDS, we relied on disabling sections of the level that players were not using quite frequently for online multiplayer. However, when it came to optimizing the local multiplayer, it quickly became apparent that we needed to make these sections smaller to have a higher chance of being able to disable them. In the end we also ended up using H-LOD, which allowed us to draw simplified versions of meshes in the distance.
Adapting a game that supports online multiplayer
By Coen Campman (lead programmer), Tom Jansen (programmer), Tomas Lori (programmer)
Online multiplayer is often underestimated and can be quite complex to implement, especially when not taken into account from the start of development. It is an altogether different beast than local multiplayer and there are a lot more factors to consider. However, most of it boils down to synchronizing the state of the game across the network correctly, timing/latency, and potentially error correction. There is often one authoritative instance of the game, such as a dedicated server or a host player with one or more other players that are purely clients and only control a player character, for example.
Some available game engines do make this process a lot easier because they often provide the user with a higher level of abstraction. For example, Unreal Engine 4 provides a complete Replication system out of the box. You can build a multiplayer game by purely using Blueprints and marking properties you want to be replicated for multiplayer. Additionally, important core functionality such as creating and destroying objects, the Player Controller, Pawn, and Movement, all support multiplayer out of the box. Epic also integrated many changes based on their own experience with Fortnite, such as the Replication Graph, which allows multiplayer to scale a lot better with larger player counts.
Adding new features will always require extra thought about how to replicate their state to other clients and the host
Even with all these tools, multiplayer can still be a challenge to implement correctly. Adding new features will always require extra thought about how to replicate their state to other clients and the host, and often about how to interpolate their state over time.
When we worked on ARK: Aberration, we initially ran into some issues with multiplayer synchronization. ARK is based on a modified version of Unreal Engine 4.5, which did not have any of the network optimizations that were introduced later, such as the much more efficient Replication Graph. As a result, it contained a fair number of custom changes to optimize network traffic because of the large number of players in ARK multiplayer. One of them was to not replicate state by default, which in some cases required the developer to manually request this. This goes to show that you should never make assumptions about any codebase you are not intimately familiar with! Things are not always as they appear.
If that wasn't enough, for adaptations, there are even more things to consider when it comes to multiplayer games. Here are a few of the more common ones.
- Sessions and invites
Having an actual multiplayer session registered on the platform service backend is often a requirement for consoles. These sessions contain data such as which players are playing, what they are doing, and the state of the game. This information is primarily used for integration with the console OS interface.
If a player sees someone else playing in a multiplayer game with a (joinable) session, they can join them from the OS interface. Another player can also invite a friend to join the multiplayer game he is currently playing. Both cases initiate the invitation flow. Having this flow up and running is almost always a requirement for console certification in games that support multiplayer.
The thing that will often cause problems here is that the player can essentially accept an invite from outside the game but also from anywhere within the game (even during a loading screen!). This means the invitation flow handling can be quite interwoven with the game and menu flow, and if not considered carefully, this can easily lead to very hard to reproduce issues.
An interesting example is the game Totally Reliable Delivery Service (TRDS) mentioned above, which featured a main menu that acted as a lobby for local multiplayer where active players could walk around. Here, we encountered a bug where due to the complex invitation flow, we ended up in an undefined state where remote players were walking in the main menu's local player lobby background. Hilarious, but in a rather unintentional kind of way.
Finding other players to play with online is an essential part of multiplayer, and most consoles offer their own service backend that allows you to do this. If a multiplayer game doesn't have this functionality at all (e.g., it only has a server browser), an adaptation should have at least a 'quick join' feature, which can be easily achieved through matchmaking.
For Awesomenauts Assemble, the original developers built their own skill-based matchmaking system based on monthly leaderboard scores. When we worked on the PS4 and Xbox One adaptations, we had to find a creative workaround, so we ended up using the console specific leaderboard and matchmaking services to achieve the same result.
- Servers and security
Having dedicated servers available for PC games is very common, so much so even, that players can even host their own servers. This is not so straightforward for consoles, and it usually requires some extra effort. First parties often require that these servers properly authenticate console players for security reasons.
- Third-party plugin (Photon)
Totally Reliable Delivery Service made use of the Photon plugin to handle network communication between players. While the game was already playable online on PC, it required setting up the needed backend authentication to handle secure communication between the console user and the Photon services.
Except for online invites (which were not fully supported), the vast majority of the setup was made significantly easier by using a well-supported third party plugin such as Photon, since it allowed for easier monitoring, cleaner authentication routes, and more streamlined server upscaling.
That's it for tailoring. Getting a game to run on a new platform is usually half the battle. Making the game shine on its new home on the other hand requires a lot more effort and some creative problem solving. Thankfully, that's exactly where Abstraction thrives, and this level of creativity and attention to detail is what our clients have come to expect from us.
We hope you have enjoyed this part of the series. Be sure to keep an eye out for the next article where we go over the next stage in the process: the release candidate.
Authors: Ralph Egas (CEO of Abstraction), Erik Bastianen (CTO of Abstraction), Coen Campman (lead programmer), Tom Jansen (programmer), Tomas Lori (programmer), Savvas Lampoudis (senior game designer), Micael Dias (programmer), Mike van Mourik (programmer)