Advertisement

Multiplayer Movement Problem

Started by June 06, 2016 10:54 AM
5 comments, last by Kylotan 8 years, 5 months ago

Hi everyone!

I'm working on the movement server for my game, and ran into a big problem.

Here is the pseudo code:


pMoveSpeed = 5;
if (Movement_Keys.a == 1)
{
pSprite.x -= pMoveSpeed;
}

Holding down a moves a player towards the left. And this is for w,s,d too. This is inside the game loop.

When the player pushes down the a key this data gets sent:

(last number is the amount of frames passed in the update func)

--- POS a1,200

When the player releases the a key, this gets sent:

--- POS a0,250

As you can see, the player released the key 50 frames after. Which I then use this frame on the server, to multiply the pMoveSpeed variable to determine the players location.

This works well.. But there is only one problem.

My game is instance based like Diablo 2. So, players can join a game, go to their dungeon, etc.

When the player is holding down a, and let's say someone joins the game. The server actually has no idea where that player is at, because he hasn't released a yet. Is there a way around this?

Edit: The server knows where the origin of that player is at (Map starting position), but the time elapsed when the player is holding a, and the time it takes for the player to join will result in unsynchronized positions

Surely the whole point of your system is that the server can guess where the player is based on what was pressed earlier, right? It doesn't need to wait for the key to be released to know how long the player has been moving for. So it can send the estimate to whoever needs it.

There are a lot of other problems involved in this sort of "just send the inputs" approach to handling online movement, regarding whether you can trust the client, whether internet lag affects position estimates, etc, but it's been covered in a bunch of other threads so I won't repeat myself here.

Advertisement

Surely the whole point of your system is that the server can guess where the player is based on what was pressed earlier, right? It doesn't need to wait for the key to be released to know how long the player has been moving for. So it can send the estimate to whoever needs it.

There are a lot of other problems involved in this sort of "just send the inputs" approach to handling online movement, regarding whether you can trust the client, whether internet lag affects position estimates, etc, but it's been covered in a bunch of other threads so I won't repeat myself here.

Yeah, unfortunately personally, I don't like this approach. But I heard it's easiest on the server. If you take a look at play.treasurearena.com's websocket data, they are doing this "just send the input" approach as well. This is kinda of where I got that from. Would a good way to combat this problem be to run a game loop on the server?

In the context of your original problem, the presence or absence of a game loop isn't really the issue. At any point where you need to know where a player is, you can look at their last known position and velocity, and use that to deduce where they are now. You can't wait for the key to be released before you start moving the player. You have to note that the player is moving as soon as that first key is pressed.

In the context of your original problem, the presence or absence of a game loop isn't really the issue. At any point where you need to know where a player is, you can look at their last known position and velocity, and use that to deduce where they are now. You can't wait for the key to be released before you start moving the player. You have to note that the player is moving as soon as that first key is pressed.

Hmm. Thanks. I just am not sure how I would update their positions on the server without some type of loop. For example, on the client, it's an arcade physics type of game. So when a player holds down a, they are moving in that direction. So some value must be updated on the server per xxx ms to update their position accordingly? I'm not really sure, but that's the only way to do it so I don't have to wait for them to release the key.. Maybe I am over thinking this?

I just am not sure how I would update their positions on the server without some type of loop.

If it's a physics based simulation, you actually want to update the simulation using a loop, and you want the physics time step size to be the same on all clients and server.

Another option is to keep a priority queue of commands sorted by time. Each time someone needs the state of the world, resolve all the events that have a time less than the time that you're querying for. This will update the world "on demand" as needed.

enum Bool { True, False, FileNotFound };
Advertisement

I just am not sure how I would update their positions on the server without some type of loop. For example, on the client, it's an arcade physics type of game. So when a player holds down a, they are moving in that direction. So some value must be updated on the server per xxx ms to update their position accordingly? I'm not really sure, but that's the only way to do it so I don't have to wait for them to release the key.. Maybe I am over thinking this?

Yes, you're overthinking it.

Currently, when you receive the key release message, you look at how long it was since the key down point, and that (original position + (time since movement started x velocity)) calculation tells you where the character has now stopped.

The important fact is, that exact same calculation can be used at any time. It doesn't need to wait for the player to have stopped.

But yes, ideally you would be running a simulation on the server. The above still applies, but you basically do it every update instead of just when a client needs a message.

This topic is closed to new replies.

Advertisement