Sonstiges: Developer Diary - The Creation of a 3DS/Switch Game
Michael Grönert, am 26.12.2016, Seite 12 von 18
Part 12: Network Gaming
Today we dare to tackle a huge topic: Multiplayer via network connection. This concerns games locally via WiFi with the 3DS, in the LAN (on the PC) and over the internet (on the PC). Thanks to my experience in game development, I realize it’s never too soon to start implementing a multiplayer mode as many processes need to be prepared for it. I do not want to promise at this point either that the game will really have a multiplayer mode at release or what its scope will be, as I've seen many developers fail to do so, which can result in delays or even cutting down or removing the mode entirely. With my explanations below it may also be a bit more understandable why this is. Nevertheless, I first need a plan in which direction the multiplayer should go, which is to be tested later. And I don’t want to avoid any efforts and risks, so I try the best that I can imagine. Optimal would be a coop mode for the entire game with all imaginable liberties. A player should be able to enter the game and the associated world of another at any time and be subject to only a few restrictions there - comparable to Minecraft. If one player is busy with a minigame, another should be able to watch and and join it. In addition, players should be able to communicate with each other.
Unity vs. 3DS
Our development environment Unity also offers a suitable solution for network multiplayer. There are tutorials and sample projects available that will help you get to know this solution better. It is a fairly comprehensive package for creating and managing network games with useful tools that you can use often. This includes, for example, a lobby in which the players can meet before a game starts or even during gameplay. At this level, you do not have to deal well with the underlying technique, such as using the TCP a> and UDP. Unfortunately, this system can not be used on the 3DS since certain guidelines must be followed. Our solution allows you to establish direct connections to other participants or to use a paid service from Unity which manages the matchmaking. With the 3DS on the other hand, we are obliged to connect to Nintendo's servers first, which perform security checks before a game can be started and this thwarts our solution. In fact, we learn from sample code for connections between 3DS systems that everything has to be handled at a significantly lower level. Here we have to take care of the creation and sending of data packages ourselves.
I will not explain this issue in more detail here. But I've decided for myself that I'll implement 3DS connectivity in parallel with the higher Unity variant, just initially limited to only for local WiFi games rather than using the Internet. For some of you, it may have been looking strange that a lot of 3DS games offer a local multiplayer but do no online capabilities. As you can imagine now, this is likely to have more reasons than having to "just" pay more for network infrastructure or having to design the games for higher latencies.
Starting a game
Let us first consider the non-3DS variant. In this case, we use the lobby provided by Unity for players to meet and prepare. The player who hosts the game, in other words creates and makes it available to others, lands first in the lobby. Other players connecting to it via IP address also land in the lobby. Until the host starts the game, all participants can set a name and a color. Finished players can mark themselves as "ready" when they are ready. Then the host can start the game. I changed the whole thing a bit so that players can now join after the game has already started.
Multiplayer lobby on PC
Since it is no longer common to enter IP addresses manually today, you want to offer the user an automated game search. By that I mean to give a game or lobby room a name and then the user can select from a list of games or search for that name. To realize this, however, another computer is needed - a server that stands somewhere and manages this list. In other words, further effort and additional costs. As already mentioned, Unity offers a paid service for this purpose. This one then takes the work and costs for an own server system. On the 3DS, we limit ourselves as I said first on local multiplayer via WiFi. In theory, it can be implemented in the same way here because the big difference only takes place on a lower level. Currently, however, there are only very minimalist GUI buttons without great design or comfort, so it's not worth mentioning.
Communication between the devices
After participants have found each other, they must communicate constantly with each other. The host acts as an intermediary between all other players who have no direct contact with each other. This already starts in the lobby - when a third player joins, the host tells him about the second player and the second one about the newcomer. Once the game has started and each participant has his own character that he can control, the communication is extended to the states of these characters. Each player must therefore send the current position to the host and this will be distributed to the other participants, if any. In addition, one also wants to see in which direction a player looks and whether he is walking or standing. Most importantly, one must remember that sending this information takes time, especially because not all players communicate directly with each other. This delivery time (latency = delay time, see also Ping) depends on many factors and can vary greatly. This and the temporal density of the information means that players seem to jump from one point to the next. Therefore, the player movements have to be interpolated. This means that each PC or device should try to predict the movements of all non-local participants to avoid jerky behaviour. In our case, this is even relatively easy since it is sufficient to transmit movement direction and movement speed. The deviations are so minimal that a player can not perceive this if the ping is not too high. From the movement information we can then derive the line of sight and the walking animation.
With the Unity variant, this can be achieved very easily. Objects for which this functionality is to be implemented, such as the characters of the players, only need corresponding prefabricated components. So our player gets a "Network Identity", which says that it is an object that needs to be synchronized with other network participants. This identity is assigned to a network connection so that appropriate players can control it. In addition there is a "Network Transform" script, which synchronizes transformations of this object. This script can be used to set how often and with what granularity which information should be adapted. In our case, this would be the movement, consisting of direction and speed, and the rotation of the object.
For the 3DS variant we have to manage this manually. To do this, we read out the values mentioned in certain time periods and encode them in bytes. This means that we use mathematical functions to map the values of our movements and rotations to natural numbers greater than zero which do not exceed a certain maximum. Of course, some accuracy is lost because we can not represent arbitrary complex numbers. These bytes are then forwarded in packets via the corresponding connections. On the other hand, these are decoded again and mapped back to the desired number ranges.
An old 3DS XL and a New 3DS XL are connected for playing.
Just from this article, you can’t really tell the required effort and complexity to solve problems and difficulties. But that's exactly how it should be in the context of this developer's diary. In any case, I have needed some time for these tasks and I can not spend too much time without working on the actual content. Currently I can do a lot more than is described here. You can already see something in the screenshot above - there is a chat system through which you can use to exchange texts and even smileys. A sent smiley also briefly appears a little bit larger above the head of the sender. It should reflect the current emotion of the user. Another feature is that you can see which minigame another player is currently in. If someone is busy with a game, everyone else sees the game's icon above their head. Meanwhile, while standing next to this player, others can use the action button to get more detailed information. At this point it should then be possible to join this minigame if it offers such a function. But for this to be possible, there is still a lot that needs to be done. Of course, our first minigame "Gong" is a great example for up to three other players to join us. However, minigames also need a kind of small lobby and several adjustments. With “Gong”, the paddles have to be assigned to the participants. In multiplayer, the experience system and the achievements must be handled differently. You can not easily award experience points to somebody who plays against another person because this could easily be used for cheating.
That should have been enough for network multiplayer for now. In the next diary entry, we will get to some artificial companionship but I would not like to reveal more about that yet. See you next time!
Do you prefer to read this diary in the developer's mother tongue? Then click here to read this diary entry in the original German language!