Send weapon fire in a phisic world

Hi all, im using UDP to send data client to server and viceversa, it works fine for send the position of players, but not for send fire data.
My game is like a “Worms” game, but not turned based, and the weapons can fire pretty fast.
When i fire, a bullet is created in scenario and it is managed from phisic.
Now im using this system:
CLIENT: when press fire button, if he can fire he send fire data to server(type of weapons and angle of fire).
SERVER:receive data and send it at all clients.
CLIENT:receive data from server and if there are any fire action process it whit data(type of weapaons and angle of fire).

The problem is that i can lose some packet, and so some client have a bullet and some client nothing.This is a big problem becouse my world is destroyed under the fire!(like worms).
Another problem is latency, the position of player is process in local but the fire is process whit latency, so if i fire and move my player, i can see my bullet fire bheind me!

for reliable fire you either have to build a layer on top of UDP that kinda does what TCP does, or just use TCP in the first place.

As for the latency, welcome to the club, we’re all dealing with it, and you basicly have to decide whether you want to live with it, or invent a smart system that works around the issue in some clever way.

Search the forums a bit, as this topic is discussed quite regularly.

Thank for reply!

Another question, whit UDP protocol what is the best way to send data every time?
Example, i have to send player position, so the client send him position at server each gameLopp cycle(whit 60 fps, the time of loop is 16ms), and server can:

  1. send data at all clients as soon as receive data from a client,
  2. when receive data from client store it in an array and after a period send array at all clients
    Whit first system the byte to send is few(32 byte) but this data have to send every time, whit second system the byte depend on number of clients connected but it can be send whit pause period(for example every 30 ms).

What is the best way?

Ouch, sending an update every game cycle is a really bad idea. In fact, for simplicity it might be a good idea to create a separate loop in another thread that handles sending of updates. I’ve got a system that handles this (in the game loop or in its own thread) in JGN as well as support for reliable UDP if you’re interested:

http://javagamenetworking.dev.java.net

If nothing else it might be something to look at to get some ideas for your implementation.

don’t know about UDP, but for TCP I think max number of messages you can send is 10 per second. Beyond that TCP starts to merge them … at least in my case. I’m strugeling about it also, so far I got to this: record every events in game in past few frames (my game is 60 fps, so thats for past ~6 fps if sending 10 msgs in a sec), then send that to server, server then starts to process those events. This methed enforces lag, but it’s the most precise one I could find searching the forum / net. Now I’m stuck with how to ping problem since TCP merges packets which couses delay and incorrect latency time reported… bah I’ll soon ask for help about this surely.

Simply disable that feature:

channel.socket().setTcpNoDelay(true);

And then you can manage merging yourself. At least that’s what I do in JGN. Messages are queued up and then when update is called messages are merged together to form optimal packet sizes to be sent out and then pieced back together similarly on the other side. This keeps the painful lag from occurring yet does not sacrifice the efficiency the feature was intended for.

So the best way is send data only when occour an update? the problem is that in my game there are always update…so i have to send data every cycle game…

If i send only 10 messages for second, animation arent’ smootly, or not?

My problem i think is the bandwith…to send player position and situation i have to send an object of 150 bytes.
To send fire action i have to send an object whit 130 bytes.
Becouse the player situation change every game cycle, and there are often a fire action, i have to send a lot of bytes every time…

That’s a lot of bytes for a simple update…why so much?

I send 3D synchronization data with physics synchronization in a game I did not too long ago and it wasn’t nearly that much data and was synchronizing more than 10 times per second. In JGN there is an Updater class that allows you to specify how frequently you want synchronization data to be sent, so it essentially removes all the complexity of things such as this.

I cant use JGN, i can only use native sun libreries…

My packets size is so bigger becouse its are a serialized object, so i take a lot of bytes…

I dont understand…if i send data only 10-20 time for second, i can see a player in a wrong positon, so if i see a player in a worng position i can fire to kill he but i cant kill becouse its arent’ here!

Look up “dead reckoning” that helps somewhat with that.

Generally speaking it’s just the inacting of Newton’s first law:

[quote]An object at rest tends to stay at rest and an object in motion tends to stay in motion with the same speed and in the same direction unless acted upon by an unbalanced force.
[/quote]
So if an object is moving at a certain direction at a certain speed if there is a delay in receiving an update from the server it will continue in that direction at the speed since it is most likely that it will continue like that. If you’ve ever had connection problems with Battlefield 2 it’s pretty interesting to see that tank that was rolling towards you keep going despite mountains, buildings, etc. in the way.

mmm but i think dead reckoning is no good for my game, look this:

http://img77.imageshack.us/img77/2729/immagineec1.gif

My game is 2d action game, in this situation if the client(Player) press foreward the player move at direction.
So i see the player move, but if the client stop to press foreward but i have untill receive the update i see player move again foreward!
So i will see player in the wrong position,impossible for my game!

about bandwith, serialized objects take much more space then just raw data they contain. I use NIO and only send data I need (x pos, y pos, speed and such) in ByteBuffer and it dosen’t take much bandwith, 4B for single Integer or Float, 2B for Short… When your data arrives you can create object you need with them.

So since you cannot send message every frame your problem is what to do between messages. As sunsett said, you can try to simulate movement until next message arrives and then correct mistakes. This is hard to do good (I tried) since player can quickly change direction and speed between updates so when his message arrives at server correction is clearly visible. You can develop that further to make correction not visible but that is hard, I went for simpler way and implemented forced lag I mention earlier so everything stays smooth and correct.
About collision and such, you’ll need to do actual collision on just server becouse client can simulate wrong data and make a fake collision or something similar, I’ve done it so the server process all collision and sends them to client which then applies it. You can also make visual collision on client but not do actual calculations of stuff until server confirms it. All this is game dependat and you must find the best way to solve it.

@sunsett
tnx for that tcp method… I thought merging in TCP is low level, TCP protocol controlled and that you can’t control it even in native code. Maybe I manage to fix my data laging now.

EDIT:
about your picture blow, that could never happen if you write good code
Let’s see, client starts to move forward towards the hill and sends a message with his info, server recieves the message and starts to move the local client towards the hill. Lets say next message dosen’t arrive before local client reaches the hill. As server moves local client towards the hill it gets collided with the hill and server stops moving it. So on both client and server you can preserve terrain collision. Remember your player on server isn’t just a image, it’s an real object just as much as on client’s machine.

Yes server can stop player, but i cant see the rela player position too…i see player stopped before hill but in rela player is on the hill!

I dont say this for the lag, becouse a lag is a real problem, but for update time, if im update my postion 20 time per second there a lot of delay from update to update…

20 times a second is a LOT of updates…if you’re seeing “delay” then you’re not actually receiving updates 20 times per second…I can update 5 times per second and only be moderately choppy…one of the JGN demos does that. Feel free to try it out and crank up the updates to 20 times per second and I guarantee you won’t be able to see any delays.

Thank guy, now i write something to try this system.
Thank again.

@sunsett
5 updates per second is 200ms pause, your game must be slow paced if it’s hardly noticable. On the other hand I have 2d soccer game, player can move fast in every direction so it’s noticable even in 10 ups, but only noticable (ugly to see player receving corrections of few pixels in x and y).

@blow
you missed the point… if on server player must go up, he wil go up. Same as on the client. He’s not ghost, sending direction dosen’t mean where his image should be drawn, it’s the same as you control your player on client machine but you use keyboard and player on server uses messages he got from client. When you press forward your player will go forward, if the reaches the hill he will go forward climbing the hill… messages will come to player on server that he must go forward, he will also reach the hill and also climb the hill as a normal player would. Remember, he’s not a image or ghost, he’s your muppet on some other computer and acts like you do on your computer, just receives commands differently.

EDIT: good luck with implementation, it will take you time to learn it and tweak it though

Okay, so maybe “hardly noticeable” was an exageration, but it opens two JFrames with a box on each side and when one window is focused you can use the keyboard to move around the box and vice-versa. It’s just a simple example of doing updates and I simply opted to do fewer updates so you can see them occur visually.

Feel free to bump it up to 1,000 if you want…it will take it. :slight_smile:

Another thing, for player i have understand that both client and server can move it and detect its collision, but for the bullets? Bullets can move very very very fast, and i can fire 20-30 bullet for second(think machine gun) how can i render all bullets in local client and how can detect his collision accurately in all clients at the same manner?
I think is impossible send for each bullet its postion,direction and speed… so how can i say at all clients where are bullets?

There is something I read yesterday in Game Programming Gems 3 (its 3 I think) about networking.

  1. Use TCP if you need packets to arrive and dont send redundant data.
    Current position, direction and speed is redundant. You send that every now and then, so if one drops it doesnt matter But this only applies in shooters where you move single entities.
    If you send unique data like “shot from x direction d”, you need it to arrive, so use TCP.
    If you send positions of shots every update, it doesnt matter if it drops, youll send an update next frame.

  2. Only what the server says is real is real to the players. So if anything shoots, it sends a message “i shot direction d” to the server. The server replies ok or not ok. In the meantime, the shot is displayed but is “unofficial”. If the shot gets denied, it disappears. If values like position are corrected, it warps. The server decides if it hits and does damage.

Consequences:

  • Sometimes things might jump, when the server replies different than the client simulates, but we speek of maybe a few hundred ms. The jump wouldnt be too big depending on speed. The time between player input and server correction is less than 1 sec, usually.
  • Events like damage appear delayed. You might have notet this in multiplayer RTS already, that a unit losses HPs half a second after an attack hit.Sometimes units even die with latency.

-JAW