Client and Server

Verbatim about Server

Verbatim about Server

In the previous part, we looked at the differences between single-player games and multiplayer games and various classifications of multiplayer games, among which the vector of further narration was outlined – network multiplayer. In this part, the immersion in the designated direction will continue. And the guests of this issue will be the concepts of “client” and “server” – who they are to each other and what they are.

  1. Introduction

  2. Singleplayer and Multiplayer

  3. -> Client and Server


Server

In a very general sense:

A server is a computing unit that performs certain service functions.

What functions can there be:
– data storage;
– Query Processing;
– network resource management;
– etc.

Depending on their functions, servers can be of different types:
– file servers;
– web servers;
– DNS servers;
– mail servers;
– etc.

Each project uses its own set of servers of different types, and servers of the same type can duplicate or complement each other, depending on the load from users.

“Aggregate states” of the server:
separate computerconfigured to perform its functions;
virtual machineemulating a separate computer;
containerperforming server functions;
server applicationrunning on a computer configured for this purpose.

Scheme of the first three "states of aggregation"

Scheme of the first three “states of aggregation”

In my practice in game development, the most common “servers” used are server applications as executable files or docker containersdepending on the configuration of the environment in which they are planned to be launched. This, in particular, allows such servers to be launched on a local computer for local testing.

In game development, there is also a set of the most frequently used server types.

Meta server

The most common type of server. Many games are limited to it. And some do not use it at all.

The meta server provides centralized management and coordination of game processes and acts as an intermediary between the various components of the game: clients, master servers, profile servers, game servers, etc.

Simplified diagram of interaction with the meta-server

Simplified diagram of interaction with the meta-server

Main function: coordination between other servers and services with specific responsibilities.
But the smaller the scale of the project, the less you want to support the park of these various servers. Therefore, the meta-server can take some of the responsibilities (or all) for itself.

Possible functions of the meta-server:
– player authorization;
– distribution of players across other servers and services;
– interaction with the master server;
– interaction with the profile server;
– searching for players to play together;
– processing of game events;
– validation of player actions;
– payment processing;
– etc.

Profile-server

The profile server is designed to store and manage player data.

Roughly speaking, this is a layer for working with an external database or the database itself. The database can be some DBMS, a data storage service or a custom solution, built even on randomly recording everything in a single file.

Profile server functions:
– secure storage of user and game data;
– synchronization of user data between sessions and between different players' devices, allowing them to continue playing where they left off, regardless of the device they are using.

Implementation options:
– a separate server or service that communicates through a meta-server;
– a separate server or service with which clients communicate directly (if there is no meta-server);
– the responsibility of the meta-server directly.

Simplified scheme of interaction with a profile server without a meta-server

Simplified scheme of interaction with a profile server without a meta-server

Game server

The game server is designed to provide multiplayer interaction.

If the previous types of servers were quite general and had no direct relation to multiplayer, then this one has the most direct relation.

Game server tasks:
– the ability for several players to participate in one game session at the same time;
– exchange of information between players about their actions and their condition;
– management of the state of the game world that is not controlled by players;
– Providing a dedicated trusted secure node that will support fair gameplay and provide protection from cheaters.

Game server functions:
– processing of data received from clients;
– transfer of received data to other players;
– ensuring synchronization of the game process;
– control of the logic of the game process;
– ensuring protection against fraud;
– managing players' access rights;
– storing the game state;
– maintaining statistics;
– etc.

The game server usually provides work one specific gaming session within the framework CoreGame. When a server is shut down, the game session for all players on that server will end. Therefore, games with long game sessions may require backup mechanismwhen a game server writes game data to some connected storage before shutting down or during its operation, in order to be able to restore the game session after a planned (or not) reboot of the game server or its replacement with another one.

When MMO games offer you to choose a server, they offer you to choose game serverwhich supports long gaming sessions designed for a large number of players.

Selecting a server in World of Warcraft

Selecting a server in World of Warcraft

Each individual match in any Counter-Strike is a separate game session on a separate game server, which can either be selected independently or requested from the master server or meta-server. Match is over -> session ends -> game server stops working.

Counter Strike gaming session

Counter Strike gaming session

For games, usually asynchronous, with simple server logic that does not require many resources, you can try to implement support multiple parallel gaming sessions on one game server. Or even implement these sessions within the meta-server. I have not tried this in my practice, I admit it is possible, but I do not find this idea convenient and justified.

Let me remind you that a server is not necessarily a separate computer. You can run a meta-server, a master server, and several game servers on one machine. Managing game sessions in isolation from each other is, at the very least, easier.

Master server

The master server is a specialized server that is used to help users find game servers.

Master server functions:
– receiving special signals with information from active game servers — heartbeat;
– formation and storage of lists of active servers by various parameters: modes, maps, modifications, etc.;
– monitoring game servers, tracking their occupancy and availability;
– issuing a list of available servers upon request to clients or a meta-server;
– creation and launch of new game servers.

Implementation options:
– a separate server or service that communicates through a meta-server;
– a separate server or service with which clients communicate directly (if there is no meta-server);
– the responsibility of the meta-server directly.

Simplified scheme of interaction with the master server without a meta-server

Simplified scheme of interaction with the master server without a meta-server


Client

The client is the game itself on the user's device.

Main client functions (in the context of multiplayer):
– receiving input from the user;
– processing of received data;
– transfer of data to the server and/or other clients;
– receiving and processing responses from the server and/or other clients;
– rendering of gameplay based on current game data.

In some general sense, using MVP terms:

  • Server: This Model (owns the game data and implements business logic).

  • Client: This View (receives input and renders the game) And Presenter (processes input, interacts with the model, and updates the view).

In single-player modes/games, all three MVPs are located on one node – on the client.

Client-server interaction scheme in terms of MVP

Client-server interaction scheme in terms of MVP

Why exactly the model goes to the server:

  • There is no need to render anything on the server.

  • Input can only be received from a specific user who owns only his own client.

  • A game is, first and foremost, data and manipulation of that data. In order to distribute the gameplay across multiple clients, the data on which the gameplay is built must be shared.

  • For multi-user work with data, it is necessary to ensure the sequence and order of access to this data.

  • Data must be reliable. To maintain reliability, it is necessary to validate actions with data and not allow clients to exceed their authority and capabilities.
    The best way to do this is: a reliable copy of the data from all clients should be moved to a location where the data will not be directly accessible by these clients.

On clients, you can form a proxy model with a data cache, which will allow you to execute read requests efficiently from the local cache, instead of constant requests to the server. But then you will need to take care of timely updating the cache with relevant data.


Synchronizing data on the client

There is a problem, touched upon in the previous article, of network delays in data exchange between distributed nodes (more details in the following articles). Therefore, the faster the game, the faster the data must be transmitted. The slower the data goes, the faster it loses its relevance.

If the connection quality is insufficient, synchronization of local data will take too long. Because of this, the game will lose responsiveness (input lag), and the player will always observe actions that are no longer relevant.

Simplified diagram of connecting clients to the server

Simplified diagram of connecting clients to the server

To compensate for delays, a lot of different techniques are used (more details in the following articles). Because of this, in reality, the MVP boundaries of division of responsibilities described above are often blurred:

  • Somewhere clients have a copy of the server business logic for local simulation and quick response to player input.

  • Somewhere the server tries to act ahead, predicting and simulating the player's input in advance.

  • Somewhere, only the most important gameplay-specific part of the data is considered reliable and is managed by the server, while the remaining data is processed in their local models by the clients themselves.
    (this is about authority over data, more on that later)

Due to the distance between players and the resulting delays, achieving perfectly identical gameplay between clients almost impossible. Two different clients will still see some variation of the current events in the game session on their screen. And since they are usually remote from each other, they most likely will not even know about it.

The main task of the developer: make the gameplay as responsive and smooth as possible, minimize state differences between clients, and ensure consistency in the most sensitive areas.

If some element of the game does not affect the gameplay, then it is not scary if for some players its state does not synchronize on time and correctly.

Example: some tree falling from an explosion that does not create collisions with players may fall later or earlier, to the right or to the left – this will not affect the gameplay, only the visual experience.

But counting a fatal hit on target is a very important moment that needs to be synchronized between clients as reliably and quickly as possible.
First of all, between those who participate in this process.
The second is between those who observe this process.
In the third – between all the others.


Client and Server Implementation

Figuratively, we have discussed what a server is and what a client is. Now let's discuss what they are in terms of implementation. I am familiar with two options.

Client and Server are separate projects

Advantages:
✅ You can choose any favorite technology with a set of favorite libraries, regardless of the engine in which the game is developed. Any programming languages ​​that provide the ability to write server applications are suitable: Python, Java, .NET, Node.js, PHP and etc.
✅ This is a lightweight solution, since the server application will contain only the necessary dependencies laid down by the developer and the technology itself.
✅ You can use a ready-made template, a ready-made framework, or implement the server entirely on your own, which will allow you to control the maximum number of aspects of the application.
✅ It is possible to implement specific work scenarios. For example, implementation of support for several game sessions in parallel.

Flaws:
❌ Implementation of the server will require additional time for development and further support. As well as additional expertise in the selected technology.
❌ Codebase duplication may occur, as multiplayer games typically have a layer of common logic and common data that must be shared between the server and the client. If the server and client are written using different languages ​​and incompatible technologies, there may be a need to duplicate some of the codebase for the client and server.
❌ It will be difficult to abandon the written server if it is necessary to change the “connection topology” in the future and switch to a server-less option. What options are available will be described in future articles.

The problem of common dependencies and their duplication in context Unity decide as follows:
– Client code base in Unity written in C#.
– To implement the server, use .NET Core on C#.
– Common dependencies are allocated to a separate assembly or a separate C# project.
– The client and server projects connect to themselves a module with common dependencies or use the collected ones dll with them.

Scheme of the client and server implemented as separate projects

Scheme of the client and server implemented as separate projects

The option with a server allocated as a separate application is quite convenient to use mainly for non-game servers. But for game servers in asynchronous games, this option can also be successful. It gives more control, flexibility and testability and does not exclude the possibility of reuse in other projects.

Such a server does not have to be implemented entirely independently, but can be implemented using cloud backend services that provide a ready-made infrastructure, where the developer only needs to write methods for processing incoming requests (We will talk about such services in more detail in a separate article).

If you need a game server for synchronous play, it will be more convenient to use another method of implementing the server.

Client and Server – one project

Almost everyone provides a similar method of implementation Netcode libraries For Unity. Working in Unity project work is underway on both client and server logic. Depending on the work style, this can be either grouped into separate modules within the project or not have a strict division. Then branching structures are used within the logic to determine the current side of execution and launch the corresponding work scenarios.

Advantages:
✅ Instead of two or three projects – one, which in some sense simplifies development.
✅ The problem of duplicating logic and common dependencies is solved by itself, since everything necessary for all parties to the implementation is already in one project.
✅ It is quite easy to abandon the server. The server logic is already written in the required language and is in the target project – it is enough to adapt it and include it in client scenarios.

Flaws:
❌ Server – a full-fledged game on a client engine. That is, in addition to the server code from CoreGame at a minimum, the engine itself with its dependencies will go there, and at a maximum, the rest of the game with MetaGame and other things.
❌ To prevent unnecessary dependencies from going to the server, you need to constantly monitor them and organize the project so that at the assembly stage, everything unnecessary has the opportunity not to get into the build.
❌ The client and server usually have different configurations for the final build, especially in the context of CI/CD, so different build scenarios need to be implemented and supported.
❌ If ready-made is used Netcode librarythen one server will only serve one game session. The more parallel sessions, the more servers need to be turned on.

Scheme of client and server implemented as one project

Scheme of client and server implemented as one project

What are the consequences of leaking extra dependencies to the server:

  • The server will have extra logic running, which will create an excessive load: from barely noticeable to quite significant.

  • The server will have extra data and extra assets that will increase its size and, in the worst case, the amount of RAM consumed.

  • The server simply may not build due to specific client dependencies, so if you don’t monitor this, you may get an unpleasant surprise or even more than one at the time of build.

  • The more computing resources a server requires, the more powerful and expensive the computing device configurations that will need to be rented or purchased to run it.

Similarly, server dependencies can also “leak” to the client and cause similar problems.

This type of implementation is a convenient option for developing game servers, which is used most often, at least according to my observations.

In general, it can be used to implement a meta-server, and not only in multiplayer projects.
In my opinion, this can be justified in cases where there is no experience in developing server applications, but the project needs to be done quickly.
But this way you can lose lightness, flexibility, simplicity (the meta-server has a lot of specific logic that may have little in common with the client) and testability.
After all, you will have to test not a regular server application, for which there is a rich set of tools, but, roughly speaking, game on Unitywhich may limit the possibilities and convenience.


Conclusion

The topic of servers and clients does not end here. This is only the information necessary for further progress. It has become difficult to maintain a linear narrative in this article. In order not to go “in other directions”, many references to future publications were added. For the sake of integrity, I will try to stick to one designated topic in each work.

Accordingly, in the following articles you can expect an analysis of data synchronization problems, ways to organize client and server connections, options for in-game interaction, ways to combat network delays, examples of current game backend services and building the infrastructure of a game project as a whole.

There are still many undisclosed topics ahead. You can follow the release of new articles on multiplayer and more in my blog at VK / Telegram / Dtf / Zenwhere I share my findings, thoughts, insights, announcements and news.


Content

Useful resources on the topic:
– Bare Metal vs Virtual Machines vs Containers: dev.to
– MasterServer: How it works: 333Networks
– What is a Game Server and How Does it Work: ServerMania
– Tacticool's Meta-Server Architecture: Habr.Pixonic
– War Robots Server Infrastructure: Habr.Pixonic
– Fast paced shooter: technologies and approaches: Habr.Pixonic
– The second half of the development of a new mobile PvP: Habr.Pixonic

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *