Networking concepts as applied to Weapon Fire

Most of the aspects of game networking seem pretty straight-forward and although there are many ways to accomplish the same task and it’s debatable about what is better, I need some direction with respect to handling weapon fire in fast-paced games. As I see it there are a few options here:

  • Each player have the maximum number of “shots” out at a time objects that get reused and synchronize their position when they are visible
  • Send an event for non-tracking weapons that simply say that “player n fired his lasers as such and such time” and then apply that to all the clients respectively
  • Send an event creating a new “laser shot” that will register the new object on each client and then synchronize position as it goes

I’m thinking for non-tracking weapons the best way to go is going to be option #2 and for tracking weapons option #1. Does anyone else have differing opinions here or an entirely better way of thinking about it?

Maybe it comes down to how you want to time things, will you let the client’s shot happen when it happened on his computer, or when the server found out about it, or an average?

What about the client who got shot? If he dodged the rocket on his computer, but on the shooter’s computer, who saw the target get shot since the dodge movement wasn’t recieved in time due to the lag, who’s reality will the server honour?

All the games I’ve written thus far have been running an instance of the entire game on the server as well so that it has the definitive answer. It is in charge of what happens and how. If there’s any “decisions” to be made, the client puts out a request and the server will tell it how it is. This resolves any concurrency issues that may occur.

Sure, but what does the client do in the meantime while it sends the request, then waits for the decision? It has to improvise if there’s to be no stuttering, especially with that setup where you’re waiting for twice the lag-time.

Its timing issues like this that i’ve found hardest.

For tracking shots, rather than sync positions maybe it’s better to sync vectors. That way you know where the shot is going during the times you aren’t getting its position.

For situations like this yo ureall have only tewo choices…

(1) Let the shooter decide and risk cheating

(2) Let the server be authoratative and have lag.

Now you can CHEAT by combining these techniques. The client egernates visual feedback immediately but the actual results happen on the server. The problem ofcourse is what happens when client and server disagree? eg client thinks i ts a hit, server thinks its a misss…

The worst case for soemthign like this is a game wher one shot kills. Thats justa mess, plain and simple.

\A better case is where N shots kill, then the l;aw of averages has some time to work and you can HOPE that most of the time it ends up about the same.

The BEST case is where an unknown number of shots kills-- for instance where each attack does a hidden, variable amount of damage. Then there is no way for the player to tell if the client and the server ever really disagreed so long as the client is showing a reasonably close numebr of hist and misses as comaprd to whats going on on the server.

I laid all this out, oh, closing on ten years ago at GDC in my first TEN “Lessons from the front” talk.

Jeff,

So have Client1 who fires his weapons be authoritative for the weapon shot, sending the info to the server letting him know shots were fired, the server then relays that to the other clients. Client2 who is being shot at gets the info and is authoritative for the damage when a hit occurs and sends back a message to the server letting him know that he was hit and his current shield status?

Or would it be better for Client1 to tell the server it is firing (while in the meantime on Client1’s screen it actually fires), then the server relays all the information to the other clients, then the server detects that Client2 given the detected collision with the weapon fire to Client2 has been hit, relays to Client2 that he has been hit and should be updated. Client2 would also detect he was hit as well and would make appropriate damage on his end, but the server would be authoritative and would verify that the hit actually did occur and if it is different from what Client2 understood then it would be adjusted as necessary. What do you think about that idea? That would keep any clients from being able to cheat, but at the same time could cause some resynching evils.

Thanks for the insights, and is there any textual copy of that “Lessons from the front” talk I could get my hands on? :wink:

You dodge behind a wall, I change wearons, and shoot the space you were standing in

With client-side immediate update:

you see “I dodged the rocket - saw it go RIGHT PAST ME”
I see “I shot him! With a rocket! In the FACE!”

One of two things happens, depending upon which action got precedence when the server simulated it all:

Outcome A:

you die. “WTF?OMG THIS SUCKS!”

Outcome B:

I run past the corner to pick up my loot you just dropped, and the Very-Much-Not-Dead you shoots me at point blank range. “WTF? OMG THIS SUCKS!”

With server-triggered delayed/confirmed update:

One of two things happens, depending upon which action got precedence when the server simulated it all:

Outcome A:

you see “WTF? There’s a rocket coming AT MY FACE! MOVE! MOVE!” … (you die) “WTF? OMG THIS SUCKS!”
I see you die. “HAHHAHAHA!”

Outcome B:

you see the rocket fly past you, popout, and shoot me. “HAHAHAHA!”
I see “WTF? He’s standing there! SHOOT, DAMNIT!” … (I die) “WTF? OMG THIS SUCKS!”

There is no solution, other than as Jeff pointed out the “client can’t tell if you lived or died until later on, such that if it guesses wrong hit/miss, it will “believably” display the other one once corrected by the server, without having to resurrect / assassinate another player”

I think these issues are not explicit to weapon’s fire either - though I think this has bene explained several times before on these forums.

The scenarios above for weapons fire equally work for dodging. I fire a rocket, my client sees the opponent in one location - my rocket hits. The server sees the client in another slightly different location - the rocket doesn’t hit (this would be even true if the rockets were magically synchonised in some way).

Absolute truth. It’s all about shaping the reality on the client so they believe the corrections you make to the initial guesses are all part of the game.

Kev

…and if you want real pain, try working out how you’re going to do that with a full in-game physics simulation running off Ageia PhysX cards ;D

Which brings us back round to where we started the other thread on this stuff :wink: Networked synchronised physics is close to impossible

Kev

So the client should never be responsible for important events such as death? The client can fire and see the explosion, but the other player doesn’t die unless the server says so? Otherwise one of the clients can get jipped, right?

BTW, my Roll-A-Rama game did a pretty good job of networked synchronized physics. Worked pretty well for the most part except collisions would sometimes get missed.

You just have to ensure your clients only give you a view of the game running on the server.

All logic happens on the server, what the client sees is either what the server sent, or what it expects.

The process of firing a bullet:

CLIENT: click mouse
CLIENT: send shot-data to server
CLIENT: [expects -> servers sends ‘bullet fired event’] so just visualize/render that
SERVER: receives shot-data, validates it
SERVER: broadcast ‘bullet fired event’
CLIENT: ignore event, as it was expects
OTHER_CLIENT: process event
CLIENT: with it’s own logic tries to guess whether the bullet will hit anything eventually, visualize that, don’t handle the logic of it
OTHER_CLIENT: with it’s own logic tries to guess whether the bullet will hit anything eventually, visualize that, don’t handle the logic of it

[bullet eventually hits something]

SERVER: handle the logic of the event (hit/miss)
SERVER: broadcast that event (miss/hit)
CLIENT: if the guess was right, ignore the event, otherwise process
OTHER_CLIENT: if the guess was right, ignore the event, otherwise process

It’s basicly the client being proactive, without applying the logic of the expected results, until the server updates a certain state.