In the previous post, I wrote a list of the main tasks that have already been done and that still have to be completed. Now I will go through them in more detail.
This is where you start a multiplayer game and wait for other players. In general, lobby in the second part is structurally the same as in the first part. Of course, interface design has been changed for the new style. But there is one significant difference. In the first part, you could only run a multiplayer game for an already created world. Therefore, to start playing with a friend, you first had to create a world in a singleplayer mode, exit it and reconnect to it with a friend. At the same time, the friend did not have the opportunity to customize his character specifically for this game. Now you can choose the option to play a new game with a friend, and the friend will be able to set the appearance of his character. This part of the work turned out to be the easiest, since all the code for the lobby is a separate small structure, not connected in any way with the network code of the main game. It was not difficult to think through its architecture at all.
After the game is selected and all players are ready, you need to start loading the world. But first you need to create and run the core of the network code - the server for the player who created the game and the client for the rest of the players. I decided not to make a big difference between the server and the client, since I wanted the roles to be changed and clients could sometimes take on some of the server's tasks. This is necessary in order to loosen the strict affection between players to make easier for them travelling the worlds independently of each other. Therefore, the game does not have a server as such. There is only a client, although for the player who created the game, this client still performs slightly more functions than others - it controls game saving, generates new locations, resolves access conflicts and monitors data streams to be consistent. Despite the fact that there is no server as such, I will still use this word for the player who created the game.
When the client is running and configured, the world starts loading. And there is also one important difference from the first part of the game. Previously, clients received all the necessary information about the world over the network from the server every time. Now the client receives the world files only on the first launch. It saves them to itself and in subsequent connections it requests from the server only the changes that have occurred to the world. This allows to reduce the amount of transmitted data several times and significantly speed up the loading of the game.
Initially, I started designing network code so that it would run in a separate thread in parallel with main game. This would avoid delays in the data messages exchange at the moments when the computer is very busy, for example, by loading resources when changing locations. However, I quickly realized this approach would be difficult to implement, since Unity doesn't allow working with resources in parallel threads. You can bypass these limitations, but the complexity of the code will increase significantly. Therefore, I decided to try launching the client in the main thread of the game and break those moments in the download, when the game is freezing, into smaller parts. A rather painstaking work was done, but in the end I managed to make sure that during loading the game does not freeze for more than 0.1 seconds, which is quite an acceptable delay for multiplayer.
In addition to this problem, there were a number of auxiliary tasks needed to be implemented before starting to make the main network code: packets grouping, delayed dispatch, allocating areas for generating unique IDs between clients, organizing different data streams for auxiliary and main packages. This is a very large number of small tasks, but their design and implementation took a very long time. Perhaps also because these tasks are purely technical and difficult to visualize in your imagination. There were times when I didn't write a single line of code for several days, but just walked from corner to corner or laid on the couch, forming in my head a picture of how the interaction of game objects should be built. But finally this stage was successfully passed and it was possible to move on.
That's all for now.
The item "Synchronization of buildings" from the list of tasks (from the previous post) has moved to the finished tasks. This includes the instant addition, removal and relocation of buildings, as well as their use (except for time-consuming processes, as these tasks relate to the item "Synchronization of crafting and building").