Tips on preventing lagging on Unity legacy multiplayer?

Some of my players are experiencing problems with lagging in my racing game. It uses legacy Network views and master server.

What I have is this:

  1. I always connect the players with useNat set to true. (both with Network.Initialize and Network.Connect)
  2. Position of cars in synchronized with Network Views with synchronization set to “unreliable”
  3. Key strokes are sent every frame or so from client to server with RPC functions.
  4. Speed and position information are sent to clients every frame with RPC functions.

I am experiencing lagging even if the players are in the same room. If it is really bad the client cars don’t even move presumably because the unreliable data packets are being dumped.

(I noticed I had the shadows of the cars synchronized set to “Reliable Data compressed”, they seem to work better).

I thought that if people were in the same room then they would get linked directly to each other?

So I thought… should I set all network views to “reliable data compressed”? They would at least move. Or would this make it even more laggy? What’s your experience? Also, does it matter what country the Nat punch-through server is on?

Thanks.

Reliable packets are guaranteed to be delivered as long as there is a connection. If a reliable packet is dropped or just not received, the machine that sent it will resend it after enough times goes by. I know UNET has a buffer of reliable messages that can overflow causing errors, so I’d assume that legacy networking does too.

Generally though, you want the stuff that needs constant updating (like positions, input states, etc) to be sent with unreliable packets. If one gets dropped, it’s no biggie as the next one is coming right up. Unreliable packets are also usually smaller packets, and thus get transported faster through the internet.

Reliable packets on the other hand, should only really be used for the stuff that needs to be synchronized no matter what, like when a player shoots or picks up an item. If it’s something that happens infrequently (movement updates happen as frequently as possible), it’s probably better in a reliable packet. They are bigger usually than unreliable packets, and thus can move a tiny bit slower than unreliable and possibly have a higher chance of getting lost I believe.

As for your question in bold, that depends on if you used a local IP address or the one given to you by your ISP I think. I have no idea how far your data travels if you use your public IP, but using a local IP your data would only go from the machine that sent it, to your router, and then to the receiving machine.

As for your cars lagging, you’ll need some interpolation and smoothing (and probably some prediction) in order to get them to look smoother when lag is occurring. You should be able to find some good tutorials and practices online to get you started, but for the most part everyone’s game is different and thus the methods use need to be different as well.

As for your shadows though, those would probably be much better off being rendered by each client as you really need to make sure you are sending as little data as possible, and as infrequently as possible. If you intend lots of people to play your game, you’ll need to work with DSL and satellite connections. People will also complain about using up too much bandwidth if they have a data cap.

Thanks for your reply.

The problem is that with the unreliable packets, it seems like they have low priority vs say the RPC calls. It looks like on a bad internet connection nearly all unreliable packets are being deliberately dropped perhaps to make room for the reliable packets. (Is this in fact true?) This causes the cars to not move at all. This looks very bad. I would prefer that they were laggy but at least moved!

Related is that when people review my game they often have lots going on with the internet such as Skyping over the internet or screencasting. If the unreliable packets are being dropped to free up for these things, it means that that while my game is beeing screencast for a review the cars will not even move and I will get a very bad review with 100,000 views on YouTube!

I have about 18 Network Views synchronizing game object positions (is this too much?)

Does anyone have any real-world experience on this matter? I would be interested to know.

P.S.

Does Nat punch through link up computer by their local IP? I can’t understand why some Americans in the same room would be experiencing lagging problems? Unless, as I suspect they are using the internet for other things too, so unreliable packets are being dropped? Or is the signal from one computer going to Europe and back again for example?

If I just assume a minimum level of broadband speed would it be better to set all Network views to reliable? Synchronizing 18 transforms of gameobjects does not seem like a lot of data, compared to say, streaming a movie.

I can’t help you with all the lower level stuff and NAT punchthrough, but I can tell you that you seriously need to work with as little data as possible.

Movie streaming can use tons of bandwidth because you don’t require precise inputs, and they’re able to buffer enough of the movie in advance in case they start dropping packets. With games, people expect instantaneous results when they press a button which is why networked games usually have client-side prediction.

I have no idea how much data a single Network View would use per second, but whatever it is you can multiply it by 18 and have an assumption of how much it uses. It would be much better if you could profile how much data you’re using.

As for an example though, coming from the XNA guidelines you only had 8Kbps to work with on Xbox 360. This included voice chat, which was something like 2-300 bytes per person, and all of the overhead each packet had because of packet headers. It’s obviously much greater than that now since with games like Battlefield you can have 64 players in a match, but engines like Frostbite’s or 343i’s (for Halo) are very, very optimized and only send data about the objects that the client needs to know about. If something is really far away and/or behind a wall, it is updated much less frequently than the player right beside you. If that object comes into view, than it gets updated more often.

I’m sure there’s very specific improvements you could do while networking a racing game (like making cars that a client has no chance of seeing update less frequently). But still, assuming that someone is running on a constant 20Mbps connection limits your game to not being able to be played by people with worse connections.

Thanks. It looks like this is happening:

  1. all RPC calls to the host (mainly just sending client input) are getting through fine.
  2. networkviews and RPC calls to client are stalling (maybe because there is more data going that way?)

Would there be any reason why host-to-client calls would be slower? Or just that there is too much data being sent?

Also, is there any good way to debug/profile unity legacy network code?

Things I’m going to try:
Change Network.sendRate from 50 to 25.
Remove some NetworkViews from shadows and calculate them client side.
Remove some other NetworkViews.
Only send speedometer information to client 4 times a second. Combine this with other RPCs.

I realised that I was sending RPCs in the Update() function which could possibly be being called up to 100 times a second! Very bad!!! This would potentially mean that for faster computers with higher frame-rates would be even more laggy! I changed this so it only sends them 25 times a second.

The recommendation is 15 times a second. But I decided to use 25 times a second without interpolation.