How to make networked fast-paced physics game less laggy

I’m working on a very simple game where players use their mouse to kick around a soccerball, trying to get the ball into the other team’s net. (pictured below)

I’m using Unet and Unity 5.6.0f3

When two instances on the same machine, the lag is passable. When running on two different machines (on the same network) the lag is too much.

For my NetworkManager settings, channel 0 is Reliable Sequenced, and I’ve made the Max Delay extremely low (1e-20).

Players, are colliders with triggers that follow the mouse exactly, and when the Ball enters a trigger it starts a ‘Kick’ function on the server to add velocity to the Ball. I’ve tried using colliders that aren’t triggers but the delay/wonkiness was much higher than it is with the ‘trigger kicking’ method.

The Ball is a rigidbody2d with a collider with continuous collision detection that never sleeps, with a NetworkTransform attached to sync he Rigidbody2d. The network transform does not do any interpolating, as when I tried that the Ball became super jittery.

Both Players and Balls both have their NetworkTransform sendrates maxed out (29/sec). I’ve also checked the game is running at a fairly high framerate (~300 fps), and the physics and velocity iterations is fairly high (200).

For players/balls that aren’t local I’ve separated the art from their physics object, so other players on your screen lerp smoothly to where they should be.

I know it’s impossible to make a networked game truly lag-free, but I’m hoping I can make it unnoticeable. I’m considering replacing the networktransforms with writing my own low-level message passing in the hopes that this will reduce the delay, but any advice on how to approach this would be appreciated.

Not to discourage you, but your core gameplay is going to be a real nightmare to do the netcode for. Like you’re kicking the ball ‘nicely’ in the video but IRL players will just hug the ball with their mouse. People can move the mouse REALLY fast. You’re going to have quite a challenge making this not look & feel bad over the net if you’re going to give players such a high degree of twitchy control I think. Especially considering they’re fighting over the same networked object.

That said - if you’re using UNET, you’re going to want to look into relay server alternatives. There’s a NAT traversal plugin on the asset store that will let your players directly connect to each other instead of having to flow traffic through the relay server. This will help eliminate as much latency as possible.

& if you’re game is more than two players, you can further reduce latency if you do more of a p2p mesh where every client is connected to each other and can send mouse coordinates directly to each other. Unet’s default pattern is slow for this type of thing. Clients have to send their mouse coordinates to the server, then the server bounces those coordinates to other clients - it’s slow.

you could write a custom network transform, but you’re not going to gain a ton for a super twitchy game like this I think.

1 Like

Indeed, the idea may not be feasible, but I’ll try a bit more.

If two machines are using the same network (LAN hosting), does UNET send all of network messages to some remote unity relay server first, then relays them back to the desired machine? Or does that only happen if you’re not hosting on a local network.

Using peer to peer connections is definitely a great idea, and passing between several clients/machines would be too slow.

Thanks for your suggestions, robochase.

It’s totally feasible, don’t worry about that side of it. Ultimately, mutliplayer/network programming is all about looking at what it is that you need to network and figuring out the best way to do it. Since bandwidth is the most scarce and limited resource right now (when we look at the availability across devices and around the world) the challenge is to make sure that you can send data over the network as infrequently as possible, and send the smallest amount of data that you can.

As mentioned already, you’re setting yourself a challenge but only because what you are doing isn’t an FPS game, which is what we expect people to be making these days and ultimately what the HLAPI supports pretty well. The moment you want to do something a little more unique or that pushes technology to it’s limits you’re going to struggle to use the HLAPI. So to start you off, avoid the HLAPI as much as you possibly can, and get cozy with the LLAPI side of things.

A few additional tips:

  • I mentioned above that networking is about looking at the things that you NEED to network. This is the key to planning and building efficient networking. A good example of this is if you think about a MOBA game where you right-click the screen to move your hero, the wrong thing to do here would be to synchronize the position of your hero on a regular interval (like we do in FPS games). In stead, if you think about things more carefully you’ll realize that all you need to send is the position that the player right-clicked in the game world, and simply send that to everyone so that they can move the hero to the position. This doesn’t work for every type of game but this is an example of thinking about what it is that you NEED to network, and how to cleverly do it

  • if you’re happy with a peer-hosted setup where one of your players acts as a server, then @DeeCeptor 's suggestion to use relay servers and have one of your players host the game is your best shout. However, bear in mind that this will give you inconsistencies and fairly regular issues due to the fact that you will be relying on the hardware of your players. I would personally recommend another solution:

  • you’re going to want a consistent back-end here, something that can handle load consistently and in this case I would opt for a dedicated server to run the server-side of your game. In this case, you know the hardware and you can monitor it’s capabilities etc. This isn’t an easy thing to implement since it looks like you’re going to want matchmaking, and with a dedicated server-side you’d need to implement that on your own. But it will be worth it (IMO)

  • either way, you don’t need everything to be in sync between players and/or players & server! I finished a game some time ago that uses an authoritative layer to authenticate and apply player input on the server-side before finally sending out the updates to all connected clients. That was for a large-scale online game though, so the latency is expected by players and therefore I could get away with the resulting round-trip-time. Recently, I started working on a racing game that is also online and faced similar issues to you where the player needs to be able to control the car without latency issues. It’s high-speed, so imagine trying to turn at a certain point but lag messing up the precision, that would be horrible! So in the racing game the strategy I used was:

  • the client controls the car, moving it/rotating it/stopping when you hit the side etc

  • the client sends position/rotation/speed to the server unreliably

  • the server simply compiles up the updates coming in from clients and sends the out to everyone unreliably

  • so the thing about the above is that in games where you need that responsiveness due to it being fast-paced, you will absolutely want to avoid any sort of authoritative layer having to approve the player input. Control the objects locally and then send the updates to the server for the server to send out these updates to other players. You may be thinking “but what about the latency… it will take a short time to send those updates and therefore the position of the objects will not be the same in other clients” but this isn’t actually a problem because you will be receiving updates from other players with latency too, causing any de-synchronization to be cancelled out. This wont always be perfect though and if you do find situations where it causes visual problems with the game then you may need to implement some sort of client-side prediction based on the current round-trip-time of the server

  • note that the above does open up your game to cheating because you’re basically letting the player send you inputs of where objects are and taking their word for it. If you’re not planning on building a competitive game with official leaderboards etc then don’t worry too much about this. Otherwise, you may need to implement some sort of ad-hoc authentication on the server-side. In the racing game I am working on, each track that players play on has a recorded distance that it takes to get around the track, and also a minimum average speed that we would expect a player to reach. On the server-side, I record the distance and average speed of the cars and if a car starts doing something suspicious the lap time is considered invalid. When you don’t use an authoritative layer to approve > apply > send player input, you have to be clever about how you solve the issue of cheating

Hopefully this helps. Good luck!

4 Likes

All above are great advises and remember rule number 1 - NTC - Never Trust the Client :slight_smile:
There are different ways. For example:

  • players only watching the game - player is only pushing the button asking the server to move him. Server is calculating new position (adding ping etc) and broadcast it to everyone. Players just lerping to it. No synchronization issue. Problem is the latency. Player will see the gap between pushing the button and the action on the screen. So you may allow the player to move on client side but this position later must be validated against what server broadcast to avoid cheating.
    Same with f.g. fire the weapon. Let the player shoot, create sound and particles on client side, but make all calculations, raycasting and validations on server side after the request will come and send result to everyone. Cheater will have nice sounds and sparks but nothing else.
    All validation and calculations must be done on the server side - never thrust the client.
    You don’t need to send camera position to the server, only what interest you is the moment when player spotted someone or shoot and is sending such a request. Then you checking if this is possible that he really did spot other player or hit him making the raycast on the server side with checking positioning and angles. You may add ping into calculations to check where the both players were in the moment when request was created - if you really need such a precise.

Maybe this link can give you few ideas on how to make it less laggy: gafferongames.com/networked-physics/deterministic-lockstep/
Whenever I need to reduce bandwidth I go to this link over and over, gives much inspiration for me.

1 Like

@TomPo a nice elaboration on what I said about avoiding cheating

@Severos_1 deterministic lockstep only really works when the physics simulation is allowed to be different in each client. In the OP’s example, he/she needs the simulation to match in both clients so deterministic lockstep isn’t really a viable strategy. Nice post though!

Well, the link was meant to the whole blog there on network physics, he compares multiple approaches and tells you the good and bad for it, then he combines to come with better solutions.

@donnysobonny Thanks for the very detailed post. I agree that minimizing what needs to be sent over the network is important, though for my very small game the network should be able to handle my very fast transmission of simply player positions and state of the ball (as that’s almost all that I’m sending).
It’s true that players could cheat without an authoritative setup, but since this is a school project I’m not going to worry about that.

@TomPo I’m already doing some separation of graphics and physics, and lerping the graphics to hide the latency.
Since players can’t collide in my game, the big problem is the synchronization of the ‘Ball’ object, which is shared between all players. I could give each client their own local ‘Ball’, which bounces around, and then try to lerp it to where the server thinks it should be, but I could see that becoming far too jittery to be playable. Worth a try though.

@Severos_1 Thanks for linking that article (and site). Looks like a lot of interesting articles on that site. Unfortunately deterministic lockstep wouldn’t be a good match for my game.