I spent the last month or so writing a gameplay server in C#. I was originally using a TCP library, but decided to switch to reliable UDP since it would give me the the guarantees of TCP but with the option to send things unreliably as well. I'm using a library called LiteNetLib: https://github.com/RevenantX/LiteNetLib.
This is some footage of several bots running around to test multiplayer movement. I've imposed a limit of 8 players per zone, so I'm running 8 separate clients here to test the worst-case scenario. The 7 I'm not controlling directly are being controlled by client code that assigns them a new random direction every 3 seconds.
There's some anomalies in the rendering of players from the server, such as jumping around or blinking. Since the world is very large, I repeatedly reset the map to the origin of Unity's coordinate system. This adds a difficulty I wouldn't otherwise have with rendering environmental objects: I have to shift all of them every time the world shifts. For objects that are moving, it's particularly difficult to keep them moving smoothly during a shift. I've worked out most of the kinks, but occasionally it still happens. I'll have to do some testing to figure out what conditions are causing it.
I spent a great deal of time trying to minimize bandwidth consumption. Generally this means not sending data when you don't need to, compressing data to the smallest possible format, combining multiple messages into a single message when you can, and throttling how frequently you send updates.
To only send necessary updates, I implemented a data staleness system on the server which keeps track of what information every player knows about every other player, and sends them data about another player only when their current knowledge about them is stale.
To reduce the size of data being sent I made certain design decisions, such as making zones 256x256 tiles in size, which allows me to store player positions in 2 bytes. I also have a slot system for zone instances, where I use every bit of a single byte as a boolean indicating whether a player occupies that "slot" in the zone. This allows me to send player data based on their slot position rather than their player ID, which currently is 2 byes in size. It may seem like a minor increase in efficiency considering that 2 bytes and 1 bit are both very small, but with large volumes of network traffic it will generate huge savings.
To combine messages I have a message queuing system that stores all messages that need to be sent to a player, and then every server tick sends as many of them as possible in one message. This prevents wasting bandwidth on the 28 byte UDP header that accompanies every packet. I also batch information about players in each zone into a single message, which helps cut down the size of player state broadcasts (particularly of movement updates, which are the most frequently sent type of message).
During my original tests I ran the server at 10hz, but as I tested the effects of latency, 20hz seemed to provide a better experience and didn't impact bandwidth as much as I expected. In retrospect, it makes sense that it wouldn't, since the game is tile-based. In a non-tile-based game, player movement resolution is mainly dependent on server tick. In a tile-based game it's mainly dependent on player movement speed. Movement from one tile to another takes roughly 100-150ms depending on the distance, so the frequency at which position data is broadcast isn't greatly affected by the server tick rate. A 60hz server and a 10hz server would be broadcasting position updates at similar rates. Latency, however, is affected by tick rate, so a faster tick rate gives large benefits for little cost.
The next major step in this project is probably going to be the implementation of an NPC/mob system. The game currently has no server-controlled entities, and doesn't keep track of much of the game state. Almost all of that is handled client-side. So it's going to be a brand new system that operates differently from how everything works currently.
portfolio: http://apiotrow.github.io/
blog: http://apiotrow.github.io/blog/
github: https://github.com/apiotrow
twitter: / apiotwork
contact: [email protected]
Смотрите видео Multiplayer networking with UDP server in Unity3D онлайн без регистрации, длительностью часов минут секунд в хорошем качестве. Это видео добавил пользователь apiotwork 16 Февраль 2019, не забудьте поделиться им ссылкой с друзьями и знакомыми, на нашем сайте его посмотрели 2,650 раз и оно понравилось 31 людям.