Advertisement

Entities interaction

Started by August 31, 2015 12:00 PM
11 comments, last by hplus0603 9 years, 2 months ago

hello,

this weekend I went back to an old multiplayer prototype I was working on. For now, I render the world state 100ms back in time, and interpolate the server states to compensate for lag and updating the server-controlled entities smoothly. When the client performs an action, I send the action to the server, roll back the server state to match more or less how the client saw it when performing the action, and execute it. Than I send the response back to the client.

Everything seems to work fine, but I have issue when simulating two players interacting with the same entity. Let's assume the entity is a monster, and both players will level up if they kill it.

Player A has a very slow connection, Player B a very fast one. A attacks, and a few milliseconds later B does the same. As long as B has a faster connection, B gets its event to the server earlier, get it processed, kills the monster, get the response and levels up.

While this is happending, the event from A arrives: the state goes back to when the moster was still alive, the monster gets killed again, and the response is sent back to A and B. A levels up (correctly because he killed the moster first), but than B is in this weird state where he leveled up, but the new server state says it never did and I need to somehow rollback.

How do you guys solve normally situation like this one? I could execute the events as they arrive to the server, without rolling back. But than nothing works decently 'cause my game is an action-packed game and I have to keep lag in consideration. Any suggestion?

Thanks!

In my opinion, the best way to solve it, is to not rewind time on the server. Instead, send actions "for the future" to the server.
Instead, the player with the slower connection sees more delay in their actions.
This does dis-favour players with a slow connection a bit, but that's no different from lower frame rates with slower graphics cards, or whatever.

If you absolutely have to do rewind, then make the side effects of the monster killing happen on a delayed timer.
When monster is killed, set a timer for after the longest amount of time you're willing to rewind.
Once that timer has expired, allocate the XP to whomever is, at that point, marked as the killer of the monster.
I would recommend against this, though, as it will cause lots of hard-to-fix bugs.
enum Bool { True, False, FileNotFound };
Advertisement

In my opinion, the best way to solve it, is to not rewind time on the server. Instead, send actions "for the future" to the server.
Instead, the player with the slower connection sees more delay in their actions.
This does dis-favour players with a slow connection a bit, but that's no different from lower frame rates with slower graphics cards, or whatever.

When you say "for the future", does it mean that I should execute the event as soon as it reaches the server (which in practice will mean executing the even in the future, based on the latency)?

Wouldn't this create collision detection issues potentially? The player will shoot at the place where he sees the monster (up to 100ms back in time) and then will get the action executed when the monster is probably at a different location.

In general, there is no sequence of events/actions that will always look the same to all participants in a distributed simulation like this.
Your only option is to push the latency around, to figure out where it would be "least bad" for it to pop up.
However, you can also solve this in other ways. If it's an RPG, not a FPS, then perhaps you just detect what the targeted entity is, and send "X shoots Y" rather than "X shoots in direction W" to the server.
enum Bool { True, False, FileNotFound };


When you say "for the future", does it mean that I should execute the event as soon as it reaches the server (which in practice will mean executing the even in the future, based on the latency)?

Links with examples of different solutions to this are in the Forum FAQ item #12.

It looks like you are getting close to what Source does, that link is one of several techniques mentioned in FAQ Item #12.


When you say "for the future", does it mean that I should execute the event as soon as it reaches the server (which in practice will mean executing the even in the future, based on the latency)?

Links with examples of different solutions to this are in the Forum FAQ item #12.

It looks like you are getting close to what Source does, that link is one of several techniques mentioned in FAQ Item #12.

I already read the FAQ and most of the linked posts, but I still didn't find anything specific for the topic I'm mentioning :(

In general, there is no sequence of events/actions that will always look the same to all participants in a distributed simulation like this.
Your only option is to push the latency around, to figure out where it would be "least bad" for it to pop up.
However, you can also solve this in other ways. If it's an RPG, not a FPS, then perhaps you just detect what the targeted entity is, and send "X shoots Y" rather than "X shoots in direction W" to the server.

The game I'm prototyping is an ARPG without any notion of targeting. Something similar to Realm of the Mad God to give you an idea.

I wonder what will happen if I only rollback the position of the entities, not their entire state. If they get killed by an event, even if I get another event that was supposed to be executed before the one that killed the entity, I can ignore it - or maybe I could allow entities to be "killed" twice (for a little time frame) as if the two player contributed the same to the last hit.

In general though, my understanding is that there is not a correct solution for the problem, but it really depends a lot on the game design and how precise the system should be.

Advertisement

The problem with 'rolling back, resolving, and patching' is the complexity (conflicts) which can result from the multiple interections and then trying to have the visual experience match.

Can you simply try to delay the final results being rendered so that there is sufficient time to resolve the situation and arbitrate the interactions?

This could be animations of the 'wind up' or 'firing' where as it starts you know (when the players commands are issued) what actions are to then happen sufficiently far ahead to have a reasonably timely enactment of it in the server (or deterministic clientside) and then rendering of the completely arbitrated results. A puff of smoke (or equivalent) to hide the extra delay in the players visulaization if needed....

--------------------------------------------[size="1"]Ratings are Opinion, not Fact

Can you simply try to delay the final results

A common explanation is that bullets take time to travel. They don't teleport.

Muzzle velocity can be different for different weapons.

A rocket-propelled grenade is so slow the time between the mouse click to fire is plenty of time for a round trip to the server and the beginning of a rocket animation visible to everyone. A lagged player may not see the beginning animation but they'll likely see the rocket fly by over the course of multiple seconds.

A rifle shot is about 1000 feet per second in addition to the brief milliseconds for pressure to build and the round to exit the muzzle. A nearby shot has enough time for an immediate trip from server to client, a longer-distance shot, especially a long-range sniper shot, has plenty of time for network communications between when you see the smoke and when the bullet would hit.

Also, you could simply make it so that, if someone tries to roll back a dead entity, you don't roll it back and don't apply the damage.
You should also not animate/show the entity dieing on the client side until the server has decided that it's dead.
That way, the slow client will see themselves shooting the entity, but will see someone else actually killing it, which would be OK.
enum Bool { True, False, FileNotFound };

If delaying the death animation is one option, how do games that show instant death deal with this kind of situation? I guess some of them simply have unsafe authoritative clients, and they live with that (I think that Realm of the Mad God was like that, at least for the first few months)?

Also, is lag compensation than useful mostly when interacting with other player characters? I mean in a PvP like situation?

This topic is closed to new replies.

Advertisement