Advertisement

Physics Server / Lag Compensation / Out of sync..

Started by February 27, 2017 03:43 PM
17 comments, last by hplus0603 7 years, 8 months ago

Hey everyone,

So I tried to make a picture showing my problem:

LG8g0MT.png

I have a gameserver, but was curious if I need to run a physics engine on the server? I've been following some tutorials online and created some attack animations with a character and would love to create some sort of fighting online side scrolling game.

I know that the client is just supposed to be a dummy sending signals to a host server, however if my host server is not created with my game engine of choice (in this case, Godot's) but (nodejs, c++, elixir, etc), would it still be possible? I just don't know how to handle lag latency compensation. For example, since the character uses set_linear_velocity with a acceleration variable... The amount of time the command actually reaches other players, will have moved the character further than his actual value. That is, if we don't have a "host" managing where everyone really is?

Does this kind of make sense? I'm pretty all over the place. --

I've done simple point and click games with tweens that were multiplayer and it's fairly simple. But when the physics become involved, my brain explodes! Thanks in advance

Your problem doesn't actually exist, at least not in the way that you've formulated it. If Player 2 is always 150ms away from the server and Player 1 is always 50ms away, then it takes 200ms (plus some overhead) for the information to travel from Player 2 to Player 1. This total latency is constant and therefore nothing gets out of sync - if Player 2 presses the key, holds it down for 5 seconds, then releases the key, Player 1 will see Player 1 moving left for 5 seconds, just 200ms after it actually happened.

Of course, where this falls down is that those figures of 150 and 50 are not actually constant at all. They fluctuate over time depending on network traffic. So Player 2 moving for 5 seconds might appear, to player 1, as 4 seconds, or 6 seconds. It might even appear that way to the server.

Generally speaking, you do need a basics physics simulation on the server, or at least "have a "host" managing where everyone really is". You can't just broadcast out state changes for the reason above. I'd love to do my usual thing of recommending the simplest possible approach here, but I'm not confident it would work for a game in a genre that traditionally expects pixel-perfect combat resolution, and where 200ms is an eternity.

Advertisement

Of course, where this falls down is that those figures of 150 and 50 are not actually constant at all. They fluctuate over time depending on network traffic. So Player 2 moving for 5 seconds might appear, to player 1, as 4 seconds, or 6 seconds. It might even appear that way to the server.

Oh lord, this is exactly what I was trying to convey! So glad I am getting help on this, I've always wondered how to solve it.

"have a "host" managing where everyone really is".

Yeah, I think I'm going to do this then. Just run some type of host server to keep track of players locations and whatnot when they give the server a command. I can mess with client prediction stuff to smooth it out, but I need to definitely kink out the host server so it's at least somewhat in sync of positions and whatnot

However, it's hard because I'm using Godot as the client side physics engine. And I'm not sure if I can replicate EXACT details of how their physics world is simulated in an actual server network code world.

Like yeah, I can use a little physics server library netcode now that will work for left,right,top,down,jumping, etc. However the gravity and all that stuff, acceleration, imply_pulse commands and stuff that I use for dynamic combat in Godot is not something I can port over to a network server. Well, I could but I'm not smart enough :P

Also, is it possible to just send the state of players to the server? This would help bigly for performance, but result in massive cheating I imagine. But then again.. That doesn't solve the problem you've stated above without a host.

I need to stop thinking that I don't need a host.. I know for a fact I need a host. Losing my damn mind :o

It's possible to get away without a full physics simulation on the server, providing you have enough logic to be able to verify that what you're being sent is legitimate. It's common (although not standard) for clients to send their character's position to the server, and for the server to either accept that data or reject it. This works well for simple position updates (e.g. in an MMO), but significantly less well when trying to do full physics, where it is probably impractical to spot invalid data.

Sometimes it's practical to simply run the same engine on the server, but Godot looks to be quite under-developed when it comes to networking, and the only example I could find completely omitted any sort of physics.

150 and 50 are not actually constant at all

This is why games introduce additional latency on the receiving side, in a de-jitter buffer. If your jitter is +/- 50 ms, then with a 50 ms de-jitter buffer, you'll end up with latencies of 200 and 100 ms. The increase in latency is a worthwhile price to pay for making sure you have valid data. (And if someone misses that latency window, you can treat that packet as lost.)

Separately: You don't HAVE to run physics on the server. You don't even HAVE to have a server. It all depends on what kind of gameplay you're intending to build, how important consistency is, how cheap your simulation is (so how much you can re-play per step) and so forth.

For a few options, look at:

http://gafferongames.com/2004/12/28/zen-of-networked-physics/

http://www.gamasutra.com/view/news/177508/The_lagfighting_techniques_behind_GGPOs_netcode.php

http://www.gamasutra.com/view/feature/131503/1500_archers_on_a_288_network_.php

They have different approaches, because they build different kinds of games.

enum Bool { True, False, FileNotFound };

Thanks hplus and Kylotan. This forum is pretty damn helpful.. for me just being a new user and you guys responding within minutes.

I've gone ahead with a 10-15 messages per second timer. It basically sends x, y and some other small information to the server. Then, the server broadcasts that data (once its properly checked), to the other players in the map at that same rate.

Then, I use lerping in my fixed_process in Godot and it's actually starting to come along nicely. There is a tiny delay but I can increase the msgs per second for a little bit more reactiveness but it seems fine for now.

Positives of this?

  • No physics server. (A positive for me as I cannot code it!) is what I mean

Possible Negatives:

  • Fly hacking (although, I can try to check the difference between movements on server, but meh)
  • Extremely bandwidth intensive? This, I don't know but I'm thinking I'm going to need to spin up more game instances, which is fine

And the server still acts as a host. It will obviously store the players last location in a variable, so when new players join the game they know where they are.

However, this means if the player (client) isn't sending those update packets to the server, sadly they will need to be disconnected. Obviously I'll give a little bit of leeway of the amount as people who lag it might disconnect them falsely

That won't be a problem as anyone who is doing that, is probably fiddling around doing something dirty. Yeah, this is probably not the best way to handle this but with my knowledge the physics server will never get coded. Especially when it has to correspond to Godot's physics.

I think I am starting to grasp my head around this though. It's probably not ideal but for a small indie game I think it'll be fine?

Advertisement

The sort of updates you're talking about won't be anywhere near a bandwidth problem for a typical number of players. So don't worry about that.

Whether it's sufficient for a small indie game or not is down to other factors. Are you planning on taking people's money for it? If so, you'll want to consider how those people will feel if a cheater ruins their experience. I would suggest implementing at least a few basic checks, such as confirming that maximum velocity isn't exceeded (with some degree of tolerance - again, consider the jitter) and rudimentary collision detection against walls, platforms, etc.

Fifteen movement commands per second is fine. I think that's what original Halo used (or perhaps it was 10 ?)

The bandwidth usage is usually not a problem if you use simple packets. Sending x,y,flags as 32-bit integers or floats would be 12 bytes per message, plus some framing overhead (type, length, perhaps client clock information, etc.) You will want to turn on TCP_NODELAY on your socket if you haven't already, to remove the built-in TCP send buffering delay, too.

Generally, you will see more bandwidth being used by the server, as it will send N updates to N players, for N-squared bandwidth usage. If you have 100 players, 16 bytes per player, and 48 bytes of overhead, that's 16*100+48 == 1648 bytes per packet per player times 15 per second equals 1648*100*15 == 2.5 MB/second (25 Mbit/second roughly.)

If you have these 100 players online all the time for a month, that's 6.5 TB. You can easily find hosting that allows you to send that amount of data for under a hundred bucks a month.

If that's too much for you, then the first obvious solution is that getting 100 simultaneous players is actually hard, form a marketing point of view :-) Because bandwidth is N-squared in number of interacting players, 10 simultaneous players will generate 1/100th as much data -- 65 GB/month, or 0.25 Mbit/s. (Well, plus overhead -- 32 KB/sec, or about 81 GB/month, with overhead.)

The second is to reduce the count of players interacting. You may not need to send updates about players that are very far away all that often, or not at all, to other players. (The word for this is "interest management") But you probably have a fair bit to go before that even becomes a problem :-)

enum Bool { True, False, FileNotFound };

Wow, you guys are loaded with information. Much more than I can ever attain. Am bookmarking this thread for future references.

Now, I was thinking a bit about this overnight. What if I made it so I still have a host, items are server-side, cooldowns, etc all the same as before. Except there is a catch. What if player movement was done via P2P? This would drastically remove some overhead, right?

Obviously this would open a yuuge can of worms in terms of fly hacking. But, this would drastically remove the overhead, and make the game seem even smoother than how I am currently interpolating x,y positions.

However, there has to be a big drawback to this which I'm probably not thinking of... :ph34r:

Four problems with P2P movement:

- The server still needs to know where players are so that it knows who you can target for actions.

- Not all home routers work with P2P gaming setups.

- Every player needs to upload their movements to ALL the other players. This means that every player sends N packets AND receives N packets for each time step. This ends up being more bandwidth use overall, by far, and can easily overwhelm clients with poor upload speeds.

- With P2P systems, players get the IP address of all other players, which leads to bad behavior such as "rage booting."

Bandwidth from server to players is cheap, and the robustness of a central service is typically totally worth it! If you have 100 players online at the same time all the time, chances are you'll be making more than enough money to pay for the server resources :-)

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement