Jump to content
  • Advertisement
Sign in to follow this  
PolycountProductions

How should "player A shot box/ground/player B/enemyY" handled in multiplayer game?

This topic is 3553 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm working on my multiplayer code, and have currently approached the network issues by having a bit similar idea that Quake 3 uses (http://trac.bookofhook.com/bookofhook/trac.cgi/wiki/Quake3Networking). I use UDP: client are sending inputs to server, server is updating the world and sending packets containing state info to clients - and so far things work pretty nicely. I can adjust health, positions, player classes, carried objects etc. but there's still bit mystery when it comes to shooting stuff. Currently I have class called 'netobject' which state's are put in a packet that's sent to client. Netobject can be things like 'building', 'box', 'player' etc. Anything there is in the world. For health/movement/stuff-mentioned-above I use 'object state'. When object is at position A, and has health N - then it's easy for clients to set up the values after getting state updates from the server. (1) I wonder how shooting objects should be done? Should it be tied somehow into 'user input'? or 'object state'? Or perhaps some sort of 'event message'? Or what? I was considering doing some sort of 'event' messages, that would be put inside packets. In these events one could say that "player A is shooting from location X/Y/Z and hits object 'ground' in location X/Y/Z at time [millisecs]" Then clients could ACK these events, and server would keep sending them until they are ACKed (or perhaps after certain period of time they could be deleted: no point sending info that 'player A shot something 3 seconds ago'.) (2) I haven't decided whether to give client authority over shooting (I'm making a cooperative game, so cheating wouldn't perhaps be that big issue, and it could mean better performance for clients even with slower network), but that's not a big deal. Either I (a) send client input to server, which will tell from which position the client really shot stuff, or (b) I will tell server (when sending input packet) from which location the shot was done, and whether it hit something. Just want to mention this here. (3) What about throwing objects? Or picking up? Would it make sense to do 'throwing event' or 'picking up event' kind of messages as well? Currently I do 'picking up' so that I change the netobject state ('netobject A is attached to netobject B') and when client receives the 'netobject A's state, he can immediately attach the netobject to B if it isn't already attached). Picking up could be handled with events, but not sure if 'events' is reasonable thing to do in a first place. Help me out people. How would you suggest handling shooting (and for example throwing) things? I'm especially concerned on my question #1. (Oh, and my game is not super-fast paced FPS, but rather a top-downish view pretty-fastish done shooting game where you also barricade and pile up stuff - and kill zombies :))

Share this post


Link to post
Share on other sites
Advertisement
I would just use it as a Object State, just update it every time the player shoots, something or someone

I would set the shooting like this

Client: Can I shoot this?
-Sends Packet-
Server: Sorry that's a Wall
-Sends Packet-
Client: Oh ok how about this?
-Sends Packet-
Server: Sure can here is the [XYZ]
-Sends Packet-

Basicly the Server just keeps the Shootable values on the server an the client just asks whether or not it can be shot or thrown at.

Don't get mad at me if this is not what you were looking for or if I completely just screwed up lol, I know the theory behind the thing not how to program it directly =p

~ARC

Share this post


Link to post
Share on other sites
Hmm, I'm afraid this approach would kill the bandwidth. Consider player who is shooting with a machine gun... there would be just too many packets to send (...and anyways, I'm sending max 20 packets per sec)

Thanks for the help though.

Share this post


Link to post
Share on other sites
the way quake3 works on that subject is prediction and server corrections. Clients stack their inputs and send them to the server, who reconstruct the client movement / aim. Then the server can detect if a client accurately shot something or not. if the client movement is invalid (i.e. client bumped into another player), the server sends a correction packet, and the client rewinds his stack and playback the inputs from there.

to combat packet loss, clients send duplicates of inputs. Look at gaffer's article on networked physics.

[Edited by - oliii on October 23, 2008 6:14:11 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by oliii
the way quake3 works on that subject is prediction and server corrections. Clients stack their inputs and send them to the server, who reconstruct the client movement / aim. Then the server can detect if a client accurately shot something or not. if the client movement is invalid (i.e. client bumped into another player), the server sends a correction packet, and the client rewinds his stack and playback the inputs from there.

to combat packet loss, clients send duplicates of inputs. Look at gaffer's article on networked physics.

Thanks oliii.

So everything is input based? State + inputs => new state + inputs => and so on...

I think in Gaffer's article it was mentioned that you will ignore old input / dropped packets. Basically, would this would that if guy who shoots 5 times (like frames 1-5), and 1 packet is dropped, first packet arrives too late, then server will update only the 3 shots?

Still not sure how those '3 shots' should be told to other clients? If server send a world state snapshot, then it means server is not sending state for every frame - but rather for example once per 5 frames (or similar). If client shoots 5 times in 5 frames (and 3 shots are successfully got by the server), then server's snapshot will contain only the latest state ("5th frame", not "frames 1-5") which server broadcasts to clients. <= End result would be that client who shot 5 times could see 5 shots (since it can predict the result), server would simulate 3 shots, but the rest of the players would see only 1 shot since the server's latest state.

Or... would it mean that server also ties 'user input' commands into these state messages, so that the other clients can run the 3 (successfully got) shooting inputs?

Share this post


Link to post
Share on other sites
Quote:
Original post by PolycountProductions
Still not sure how those '3 shots' should be told to other clients? If server send a world state snapshot, then it means server is not sending state for every frame - but rather for example once per 5 frames (or similar). If client shoots 5 times in 5 frames (and 3 shots are successfully got by the server), then server's snapshot will contain only the latest state ("5th frame", not "frames 1-5") which server broadcasts to clients. <= End result would be that client who shot 5 times could see 5 shots (since it can predict the result), server would simulate 3 shots, but the rest of the players would see only 1 shot since the server's latest state.

The state is not whether someone has fired during that frame. That's an instantaneous event, which changes the state. The state itself would include all projectiles in the environment, in this case 3 of them. If the projectiles don't typically live long enough to appear in a state snapshot, either you need to update more often or you just treat them as instantaneous events that need propagating independently.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
The state is not whether someone has fired during that frame. That's an instantaneous event, which changes the state. The state itself would include all projectiles in the environment, in this case 3 of them. If the projectiles don't typically live long enough to appear in a state snapshot, either you need to update more often or you just treat them as instantaneous events that need propagating independently.


Thanks for the help. I'm not quite sure how those events should be treated on the client side though...

Let's suppose one bullet lives for 1 frame (instant hit), and let's suppose that during 50 millisecs period there's 3 bullets. State update that occurs at 50 millisecs, so basically server does the shooting of those 3 bullets.

Next, in these 'world state snapshots', server would include '3 bullets' ("shots by player A from position P to position T at time N" etc.)

How would client then treat this info? He gets the snapshot, updates the world, and then realizes that "3 bullets were shot within the last 50+lag milliseconds". Would it mean that client would just simply launch all bullets simultaneously from correct positions, meanwhile the player character is running 1 meter (the distance he can move in 50+ milliseconds) away?

(I'm reading source networking over and over but I'm missing something :) - the movement alone sounds understandable, but the moment shooting begins, I start to wonder how it should be done to get those events play correctly.)

Share this post


Link to post
Share on other sites
Quote:
Original post by PolycountProductions

(I'm reading source networking over and over but I'm missing something :) - the movement alone sounds understandable, but the moment shooting begins, I start to wonder how it should be done to get those events play correctly.)


You can't play them correctly since everything has already happened. You try to show something reasonable.

To validate correctness, instead of inplace simulation advancement, server keeps track of past states. So whenever simulation is advanced by one tick, you store old state and keep it around for a while. After all clients have been shown to have advanced past a certain state, you can discard it.

When player's action arrives, you find when that action was triggered, then find matching old state at that time. Then, calculate everything based on that state. If needed, restart entire simulation from that state to update for changes (may lead to warping or other inconsistencies).

Meanwhile, client may choose to simulate actions regardless of whether they are valid or not (showing blood, bullets, etc.), but not getting the results. So shooting something will show damage on screen, but it will take a while until this damage is applied (or it may be simulated, and later compensated/confirmed after server gives its ok).

This model isn't entirely accurate and may not even be entirely fair under certain circumstances, but it's simple and relatively light-weight.

When it comes to displaying other players' actions, one way is to speed up their time to catch up with local view. So if you receive actions from a player that is 200ms behind, you could replay all those actions over 20ms. This isn't accurate, but tends to keep things reasonable.

Sometimes, actions that can be performed are designed with this in mind (time between shots, projectile behavior, etc.).

[Edited by - Antheus on October 24, 2008 8:39:34 AM]

Share this post


Link to post
Share on other sites
The client is just a console, that only send a stream of inputs to the server, who has full authority on everything.

What the client can do is predict events.

1) He thinks he fired 10 bullets, so let the bullet fly on the client, except they will not produce damage, they are just for show. Similarly, he thinks he moved to the right, then let him move to the right instantly.

2) When the server received the command 'move right', he will move the player right if he can. If the player cannot move right (blocked), then a correction packet is sent to re-sync the client.

the case 1) can be demonstrated in Counterstrike. You have a special command that stops client prediction on gun firing. That's what really happens on the server side when you fire your gun. If you allow prediction, your gun will fire normally, *but* what you shoot may not be the same on the server. Hence the glitches such as firing through walls, shooting someone but it's not registering (at least straight away), ect...

The case 2) can also be demonstrated in CS. If you bump into another player, you will see yourself wobble about, this is the server correction kicking in. This is because you cannot predict accurately the position of OTHER players on clients and server.

all this is done via stacking inputs and client-side predictions on the client, sending those inputs and predictions to the server to be verified.

The server re-runs those inputs locally, and compare the predictions with what he calculated.

If there is a mismatch, he sends a correction packet.

Client receives the correction, apply the correction to the offending state, and re-calculate his states stored in his stack from that point forward.

Share this post


Link to post
Share on other sites
Yeh, I'm aware that client is pretty dumb and 'thinks' what occured.

Number #1 is clear, no problem with that...

...but what about if there's server + two players. How can player A know when player B was shooting (think the '3 shots' example above)?

Thanks again!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!