⬆️ ⬇️

The implementation of multiplayer in the game. Comparison of Game Center, Steamworks and GameSparks features

Games with multiplayer is much more interesting than similar games without it. But the implementation of multiplayer implies the existence of its own server, code that implements network interaction, matchmaking and much more.



Fortunately, there are many ready-made solutions. During the development of my game, I tried the following options:



  1. Game Center (iOS games)
  2. Steamworks (games for Steam)
  3. GameSparks (cross-platform solution)


Under the cut, I'll tell you about each of these options, the main possibilities, difficulties encountered, pros and cons. From the pieces of code, I will refrain. Everything is in the documentation.



Briefly about everything



The listed options are arranged in ascending order of opportunity and flexibility. The complexity of the implementation also increases.

')

1. GameCenter

The easiest and, at the same time, the most meager option. The player presses the button, after which the enemy search window appears. After a certain number of players have accumulated, the match starts. At this point, players get the opportunity to exchange messages. After all players have left the match, the game ends.



2. Steamworks

The functional is divided into two independent parts: matchmaking and messaging. The first half consists of the ability to create rooms in which players can discuss the upcoming match.



The second half is the functionality for direct messaging. Both parts are completely independent. You can send a message to any player at any time, regardless of which rooms he is in.



3. GameSparks

In fact, GameSparks is a full-fledged server, with all the advantages it implies. You can store player data, verify all his actions. There are built-in mechanisms for matchmaking, leaderboards, games, and more.



The first two options are suitable for a simple game with little security requirements. And for a big serious game, of course, you need your own server.



For me, the last option turned out to be the most pleasant in development, since I managed to get rid of many crutches.



A little bit about our game



GalaxyAdmirals is a turn-based space strategy. The gameplay consists of short battles on a hexagonal playing field. Players take turns, element of the random is missing. In essence, this is chess in space.





The game has a campaign of 30 missions. Multiplayer mode is a one-on-one battle with a random opponent.







The game is made on Unity3D.



Game center



general description



Game Center is an iOS application. It displays your achievements in other games: achievements, high score tables. You can add friends, challenge, compare your achievements. The functionality is not great, and the usability of all this, in my opinion, is rather dubious. But the most important thing is that through Game Center you can implement a simple multiplayer.



Integration



Perhaps there are some ready-made plugins, but I wrote my own in Objective C. There is not a lot of code, and it is quite simple.



Implementation



There are three options for implementing multiplayer through the Game Center:



  1. Turn-based.



    This is for turn-based games, like checkers, chess. Players take turns. After each turn, the player receives a message at the Game Center, which is now his turn. However, the game does not have to be launched. Game status is stored in Game Center. Players do not communicate with each other, they communicate only with the server to update the state of the game.



  2. Self-hosted.



    Game Center performs matchmaking only. You have to independently implement multiplayer through your server.



  3. Real-time.



    As the previous example, only messaging occurs through the Game Center relay server. This is what I used. About him in more detail below.


It looks like this. The player presses the button - the search for the enemy starts.





When you start matchmaking, the player passes the following parameters:





Group is the number in which additional information about the match is encoded. Game Center will pick you opponents who have specified the same group as you.



An attribute is a 32-bit number that means the role you want to play. In essence, this is a bitmask. Game Center selects players so that their bit masks, combined by "or", are completely filled with units.



For example, you want to play chess only for whites. Then you pass the mask 0xFFFF0000. A player who wants to play for black must pass 0x0000FFFF. If the player does not care who he is playing for, then he passes the mask filled with units 0xFFFFFFFF. Then the player who wants to play for white will be picked up by an opponent who wants to play for black, or an opponent who does not care who to play for.



After opponents are found, the match starts. The player is returned a list of opponents to whom he can send messages. All players enter the game on an equal footing. They need to agree which of them is player # 1 and who is player # 2. For example, you can sort players by ID. Then both will get the same list.



There is no special “match complete” condition. Players first need to agree among themselves that the game is over, and then each of them is disconnected.



There is an opportunity to send an invitation to your friend. This invitation will be displayed in his Game Center, even if the game is not running. By clicking on the message the game starts. In order for the invitations to work correctly, you have to separately handle two options, when the application is running and when not.



Unfortunately, if the player did not accept the invitation, the player who sent it will never know about it. He will wait for him until he gets bored.



Problems



1. The problem with the end of the match

The functionality works in such a way that you cannot send a message “the game is over, I went,” and then immediately disconnect. In this case, the enemy will not receive your message, and will only see that you have disconnected. Deciding that you fell off, he will assign the victory to himself.



Therefore, we have to send additional confirmations, such as "I received your message that the game is over, you can leave."



2. Problem disconnect one of the players

The connection between the players is peer-to-peer. Therefore, if one player loses the Internet, then both receive a message that the enemy has fallen off. In theory, we should award the defeat to the player who fell off and the victory to the player who remained in the game. And the most annoying thing is that there is no way to ask the Game Center who was left in the game and who was disconnected.



To find out, you have to insert crutches. For example, check the connection with the Game Center immediately after disconnecting the enemy (for example, I requested the status of the gamers). If the Game Center does not respond, then we can assume that I fell off, and not the enemy.



But even this may not work. For example, a player may collapse an application. When he deploys the application, the connection with the player will already be broken, but the connection with the Internet will remain and the player may decide that this opponent has fallen off, and not himself. In short, you have to insert additional crutches.



Minuses





Steamworks



general description



Steamworks is Api for integrating your game with the Steam store. It allows you to implement in your game multiplayer, achivki, leaderboards, shopping, storing user data in the cloud.



Integration



Steamworks SDK is written in C ++. Therefore, a wrapper is required for integration into Unity3D. Of the several options I chose at random Steamworks.NET. In principle, the wrapper is not bad, everything integrates well, but later I noticed some strange behavior.



Each function returns a result via a callback of approximately the same type.



protected void OnResult(LobbyEnter_t pCallback, bool failure) 


As you can see, an additional Boolean parameter is passed to the function, which should indicate the failure of the operation. As it turned out, this parameter never returns true. Even if you do something obviously wrong. I do not know if it is a cant Steamworks SDK or Steamworks.NET. I didn’t get a clear answer from the developers and had to get out with the help of crutches.



Implementation



As I wrote above, Steamworks has more flexible matchmaking. Here is a sample list of what you can do:





We used all this functionality in our Steam version.







As can be seen from the screenshot, before the start of the match, you can chat in chat, choose a race for yourself, choose a map and other match parameters.



Not all players are equal. The player who created the room is its owner. If the owner has left the room, then this title is transferred randomly to another player in the room. This player can act as an arbitrator in controversial situations.



Theoretically, the entire game functionality can be implemented right inside the room, store the state of the game right in it. But it all smacks of perversion.



In the incentive, there are no special functions to create a connection between players. You simply send a message to any player. If the connection has not been established before, it is established automatically (the other party must confirm that he wants to communicate with you). If the connection is suddenly broken, then Steam will try to reconnect the connection the next time you send a message.



As in the Game Center, there is no such state as “game over”. Those. players must agree between themselves when the game is considered to be over.



The incentive there is still such an interesting functionality. Suppose you do not multiplayer through Steam, and through their servers. You can register your server with the incentive. The player can get a list of all registered servers. Thus Steam acts as a directory of external servers.



Problems



1. The problem disconnect one of the players.

Unfortunately, as in Game Center, you cannot so easily determine if you or your opponent lost connection to the server. You have to write crutches.



pros





Minuses





Gamesparks



general description



GameSparks is a service that acts as a backend server for games. It allows you to store data, run scripts, has built-in matchmaking, achivok, leaderboards and much more.



Integration



GameSparks integrates into Unity3D using the official plugin. Everything works perfectly.



Implementation



All scripts are written in JavaScript. Therefore, the first thing I did was set up the environment to write in a normal, strictly typed language. I used TypeScript.



Interaction with the server is very simple. We are sending a message to the server. On the server, the script corresponding to this message is triggered. The script reads information from the database, makes changes, and returns the result to us. The script can also send a message to any other user. Everything is very simple and logical.



In principle, GameSparks allows you to implement arbitrarily complex matchmaking. You can, for example, make the room as an incentive. But I decided not to bother, but to use the built-in matchmaking mechanism.



When you start matchmaking, you need to transfer the player's strength (numeric parameter). After that, GameSparks will return opponents whose strength differs from that transmitted by a certain value (in absolute or relative values).



For real-time multiplayer, it is possible to create separate rooms. In this room a script can be run, which is constantly spinning on the server side. But I did not use this functionality. To send messages between players, I used a regular script that simply relayed the message to the right player.



pros





Minuses





Council



Create additional tools to visualize the processes occurring inside your code. For example, I wrote a logging server.





On the left is a log of one player, on the right - the log of another. The arrows draw messages, at what point the message was sent, at what time.

Source: https://habr.com/ru/post/316706/



All Articles