Racing games involve multiple vehicles racing a number of laps. They can be realistic or arcade-y, but the end goal is always the same: crossing the finish line first.
In multiplayer racing games it is vital to have as precise information about the position of other clients as possible. The server and the players both need to know details like if its possible to overtake in a curve, if players bumped into each other, and even more importantly - who crossed the finish line first. We need to have server authority, but each Client also needs reliable predictions about where the other players are.
First-Person Shooters (FPS) are games where multiple players join opposing teams and shoot each other. You will often win by either eliminating the opposite team, exploding a bomb, or running out the timer.
Good communication between players is often essential in winning. Serious players will have voice communication, but its also good to have in-game comms to easily communicate tactics. In coherence there is the concept of Client Connections which you can use to easily send messages between players. It can also be used to communicate game state changes e.g., "The bomb has been planted".
When building your level there may be certain objects that should be duplicated across Clients. You want to have a duplicate of each player on every Client, but for something like doors which can be opened or closed, you only want one "shared" door across all Clients. For this to happen you need to understand Uniqueness and Lifetime. Using those concepts, you can make sure that a given objects is persistent on the scene, and that only one exists.
Similar to doors, the bomb is also unique. The difference is that the bomb is spawned and only 1 bomb can exist in the game at any time. Doors are also unique, but multiple instances of a door asset can exist, just not at the same place. To understand more, read about Setting up a global counter. This is the same principle of having a Prefab that is uniquely identified.
Online competitive multiplayer games are tricky to get exactly right, and there is no "right" solution. It's a constant tradeoff between cheat protection, latency, client prediction, etc. You need to do further research to decide on the solution that best suits you. One thing you definitely need to learn about is client vs server authority.
In most MMOs you control a character, interact with other players and group up with other players to clear dungeons. Here's a few networking considerations for anyone creating something similar.
In a MMO the world needs to be persistent. Any given user can join and leave a world at any given time and we want their changes to be persistent. Which NPCs was killed, which treasures were looted, which items are available on the action house, etc. In order to achieve this, you need to run a in the which will make sure the world state is saved even if no players are logged in.
Given that there can be a large amount of players distributed over a very large area, we don't really care about the ones in all the different areas. By not sending information about players far from the player itself, we can significantly limit the amount of data sent over the network. When using coherence you can use the to set a bounding box in which we replicate data from networked entities - anything outside of it is ignored.
Even within a there might be further room to optimize. When having a large amount of networked entities, you might want to prioritize those that are closer. Our solution to this is called . Using this you are able to control values such compression, value range and sample rate in order to hit the optimization sweet spot.
To make sure that all users experience an identical game world at any given time, we need a Simulator to be responsible for taking decisions for the AI, triggering events, etc. In coherence we support launching your game with any number of taking responsibility for the various parts of your game.
A common part of all MMO's are instanced areas where a smaller group of players enters together and completes a set of tasks. It does not make much sense to run these instances as a part of the World Replication Server. The idea is that it can be possible to spin up a separate server for each group who enters such an instance. In coherence we offer this through the . This allows you to have a shared world, as well as any number of instances for a specific area for a subset of players.
For turn-based games, the requirements for networking can be quite different from other, more fast-paced games. You are only interested in changes to the game state, and don't really need more granularity than that. Let's take chess as an example.
You don't really need a player character so in order to process input you don't really need a CoherenceSync object. You could use a Client Connection Prefab if you want to have an easy way to implement chat.
You might want to have a Simulator to process everything if you want cheat protection, but for a game such as this it could also be viable to simply opt for client-side simulation and then have one of the Clients have authority over the game controller. That is the default setting when adding a CoherenceSync Component. Each client can then talk to the game controller using Commands.
Fighting games come in many shapes and forms. Usually they involve 2 or more players fighting each other. The players can kick, punch, block, grab and trigger intricate combos for extra damage. Often this type of game relies on quick reactions to the opponent's movement.
For a fighting game, we need a reliable game state regardless of user ping. It needs to be deterministic. For example, if two players press the kick button a few milliseconds apart, the Simulator needs to be able to figure out which player is the one doing the kicking, and which is the one getting kicked. Our solution is called input queues and the setup is described in great detail here. The key idea is that only the input is being processed by the Client, and the Simulator is responsible for deciding the outcome. The Simulator stores a queue of inputs, which is then used to decide on the correct order of actions.
If you want to synchronize more than just the root of the Game Object, e.g. if you want to have precise replication of ragdoll on all Clients, you need to create bindings to more that just the root transform. We support deep bindings which allow you to select any object in the hierarchy and synchronize whatever is needed.
Quick exploration and recommendations for different game genres
This section introduces you to coherence features and terminology by using well-known genres and game types as examples. Each example will come with a list of considerations and how we propose to use coherence to achieve a similar result. As you well know, game creation is a complex process, so the list is far from exhaustive, but aims to highlight pitfalls, suggest solutions and generally just provide you with a starting point when trying to create a multiplayer game with coherence in the context of a game type you are working on.
This section is a beginner-friendly exploration into familiarizing with coherence's terminology and networking mindset, and by no means is representative of a production-ready architecture proposal.