Hey all :)
I'm making a top-down multiplayer shooter and am having some netcode issues. Basically the important elements are:
1) client-server model.
2) top-down movement where players can instantly change direction (up, down, left, right).
3) bullets have travel time. They are not instantaneous.
4) The mouse controls a target allowing players to aim in any direction.
Check ">this video to get a quick idea of what I mean. Now, I've created a lovely little diagram to show the issue I'm talking about.
Imagine that on the server two enemies are running exactly alongside eachother in the same direction. Suppose they both have a ping of 200. They SHOULD be aiming slightly infront of the other, so their bullets (which are not instantaneous) will hit the enemy. However, they won't do this. On the client they don't see themself directly next to their enemy, but much further ahead. So what they do is aim backwards, just slighting ahead of where they perceive the enemy to be. What ends up happening then is the two players would continue running alongside eachother, thinking they're shooting directly into their enemy and wondering why he's not dying. Whereas in actual fact on the server they just look like two idiots shooting backwards forever :p
They see their own position ahead of where they actually are on the server because of client side prediction. And they see their enemy behind of where it actually is on the server due to the lag (and lack of extrapolation).
So this is the basic issue. I know that I can extrapolate the enemies position forward to where it is on the server, and that will solve half the issue. But because players can instantly change direction this results in a lot of overshooting and weird looking warping. Does anyone have any suggestions about the best way to deal with this instant direction changing extrapolation?
And even if I do somehow get extrapolation of the other players working, what about my own character? He's still further ahead than the server thinks he is and will continue to aim backwards.
Anyway, I'd be interested to hear your thoughts on this no doubt common issue.
Cheers!
Ben.
Two enemies running alongside eachother. Shooting problem.
First off, I'd like to say that your game looks fantastic! [wow] You seriously need to get in touch with Valve and get your game on Steam as an indie.
But back on topic, shouldn't the blue client be predicting the red player as well, so that both of them would appear next to each other on both clients (and ahead of the server)? As for handling instantaneous direction changes, that's not really something client-side prediction can deal with very well since it assumes your motion is fairly deterministic and, well, predictable :)
But back on topic, shouldn't the blue client be predicting the red player as well, so that both of them would appear next to each other on both clients (and ahead of the server)? As for handling instantaneous direction changes, that's not really something client-side prediction can deal with very well since it assumes your motion is fairly deterministic and, well, predictable :)
Thanks man, really appreciate it. Don't think Steam would work though because the game is free. But who knows :)
The netcode and motion is deterministic. So a client will see his own character move instantly when he changes direction and there's no warping or anything. But yes, right now I'm not extrapolating the red player ahead at all. I suppose I could extrapolate him forward by blue's FULL round-trip time, half to account for red's lag behind the server, and the other half to account for blue's lag ahead of the server. But that can be pretty huge and in a real match where players strafe around eachother (unlike this theoretical situation), enemy players are going to be warping all over the place, and I'm not sure if this is going to make it any easier to hit an enemy. It certainly isn't going to look as good.
I guess I'm just looking for some advice, maybe there are some tricks of the trade to make the warpyness less noticable. I was thinking of something like.. if blue's client detects that red has been moving in the same direction for X ticks, begin to extrapolate him further forward. But as soon as red changes direction, stop extrapolating until his motion becomes more stable again. At the very least, this would allow you to snipe an enemy who's running in a straight line in the distance. But it wouldn't do so well when you're up close strafing around eachother with shotguns.
The netcode and motion is deterministic. So a client will see his own character move instantly when he changes direction and there's no warping or anything. But yes, right now I'm not extrapolating the red player ahead at all. I suppose I could extrapolate him forward by blue's FULL round-trip time, half to account for red's lag behind the server, and the other half to account for blue's lag ahead of the server. But that can be pretty huge and in a real match where players strafe around eachother (unlike this theoretical situation), enemy players are going to be warping all over the place, and I'm not sure if this is going to make it any easier to hit an enemy. It certainly isn't going to look as good.
I guess I'm just looking for some advice, maybe there are some tricks of the trade to make the warpyness less noticable. I was thinking of something like.. if blue's client detects that red has been moving in the same direction for X ticks, begin to extrapolate him further forward. But as soon as red changes direction, stop extrapolating until his motion becomes more stable again. At the very least, this would allow you to snipe an enemy who's running in a straight line in the distance. But it wouldn't do so well when you're up close strafing around eachother with shotguns.
Quote:Original post by bencelot
The netcode and motion is deterministic. So a client will see his own character move instantly when he changes direction and there's no warping or anything. But yes, right now I'm not extrapolating the red player ahead at all. I suppose I could extrapolate him forward by blue's FULL round-trip time, half to account for red's lag behind the server, and the other half to account for blue's lag ahead of the server. But that can be pretty huge and in a real match where players strafe around eachother (unlike this theoretical situation), enemy players are going to be warping all over the place, and I'm not sure if this is going to make it any easier to hit an enemy. It certainly isn't going to look as good.
I'm not sure that RTT would factor in to the prediction. Basically all you would be doing is extrapolating forward based on red's last known position, and how long its been since you last received a server update for red. So if you're using a linear model, red's predicted position would be P + V*T, where P is their last known position, V is red's velocity (calculated using a history of red's positions and update times), and T is the time since the last server update. No matter what the latency, if two players are moving at the same speed in the same direction long enough to stabilize their histories, the predicted position should match the server updates when they get send down. In a game like yours that has a lot of circle strafing and non-linear movement, you might be able to get away with a non-linear approach like splines or arcs to predict the position. It also sounds like you might also have a different notion of what "extrapolation" is than I do, so let me know if I sound crazy right now :)
Yeah, I'm probably using the term incorrectly. Never been good with terms :p
Surely you need to factor in blue's latency when determining red's position. Suppose red is running along and when he reaches position 100, the server sends out an update saying his position x = 100 and he is moving to the right. Suppose he's moving with a velocity of 100 units/s and blue has a ping of 200, meaning it takes 100ms for the server message to arrive at blue's computer. 100ms later the packet arrives in blue's computer, just as on the server red reaches 110. Surely then, in order for blue to match up red's position with where it actually is on the server (x = 110), he has to take the x=100 value from the packet, and extrapolate it forward by 100ms at the known player velocity of 100units/s. Using your linear equation: x = 100 + 0.1*100. = 110. This works regardless of the tick rate. The server could be sending packets out a million times a second, but you shouldn't extrapolate forward by a millionth of a second.
So that would be extrapolating by half the round trip time, which in the diagram would bring red up to the blue line (in line with his location on the server), but then I'm guessing I'd need to extrapolate again by the other half of the round trip time, to catch red up to where blue sees himself, so blue aims horizontally towards red, and not backwards.
Surely you need to factor in blue's latency when determining red's position. Suppose red is running along and when he reaches position 100, the server sends out an update saying his position x = 100 and he is moving to the right. Suppose he's moving with a velocity of 100 units/s and blue has a ping of 200, meaning it takes 100ms for the server message to arrive at blue's computer. 100ms later the packet arrives in blue's computer, just as on the server red reaches 110. Surely then, in order for blue to match up red's position with where it actually is on the server (x = 110), he has to take the x=100 value from the packet, and extrapolate it forward by 100ms at the known player velocity of 100units/s. Using your linear equation: x = 100 + 0.1*100. = 110. This works regardless of the tick rate. The server could be sending packets out a million times a second, but you shouldn't extrapolate forward by a millionth of a second.
So that would be extrapolating by half the round trip time, which in the diagram would bring red up to the blue line (in line with his location on the server), but then I'm guessing I'd need to extrapolate again by the other half of the round trip time, to catch red up to where blue sees himself, so blue aims horizontally towards red, and not backwards.
have a look at this =), it's about how valve solves this problem
http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
Ahh cheers oggs. I probably should've mentioned this but I've read that already. It was actually very helpful and I'm using a similar system. The main difference however is that CS has instantaneous bullets, so they can just save all the positions and rewind back and see if the shot would've hit. I can't do that as my bullets take time to travel, which means I'd have to resimulate the entire gamestate for every single shot fired which I think would be too intensive.
However, I think I've got it all worked out.
1) Extrapolate red's position based on half blue's round trip time. I know I was talking about full round trip time before but I don't think that's right. For starters, it doubles the warpiness effect (when they change direction) and I don't think full round trip time should be used anyway. Now, red appears to blue where red actually is in the server. The only thing left to do is take care of blue's ping ahead of the server...
2) Adjusting bullet speeds due to lag. Based on the ping, I'm slightly slowing down the bullet speed on the client and speeding it up slightly on the server. By adjusting the bullet speeds I can compensate for blue's ping to the server. Blue will see his bullets travel slightly slower and will therefor naturally aim further infront of a moving target so his bullets appear to hit it. Meanwhile, the server is slightly speeding his bullets up to complete the lag compensation. While I could do all the speedup/slowdown on just the server/client, I've decided split the bullet speed over both the client and the server so it's not too noticable for either. This seems to work pretty well, especially if you're shooting over long ranges.
However, I think I've got it all worked out.
1) Extrapolate red's position based on half blue's round trip time. I know I was talking about full round trip time before but I don't think that's right. For starters, it doubles the warpiness effect (when they change direction) and I don't think full round trip time should be used anyway. Now, red appears to blue where red actually is in the server. The only thing left to do is take care of blue's ping ahead of the server...
2) Adjusting bullet speeds due to lag. Based on the ping, I'm slightly slowing down the bullet speed on the client and speeding it up slightly on the server. By adjusting the bullet speeds I can compensate for blue's ping to the server. Blue will see his bullets travel slightly slower and will therefor naturally aim further infront of a moving target so his bullets appear to hit it. Meanwhile, the server is slightly speeding his bullets up to complete the lag compensation. While I could do all the speedup/slowdown on just the server/client, I've decided split the bullet speed over both the client and the server so it's not too noticable for either. This seems to work pretty well, especially if you're shooting over long ranges.
Quote:I can't do that as my bullets take time to travel, which means I'd have to resimulate the entire gamestate for every single shot fired which I think would be too intensive.
If you store the position of the objects, you just look it up, rather than re-simulate.
If an object then gets shot, you can apply the damage "now" instead of the time step at which it was hit, to avoid having to re-simulate a divergent path from the time of the impact.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement