Network sync if packets get lost..how?

Started by
9 comments, last by bogdanontanu 23 years, 7 months ago
Hi I am working at a RTS Multiplayer game. I have reached the network sync phase of the project. I am using DirectPlay So i have a problem: First i sync all computers by sending a SYNC_MSG from server and waiting until all PC in game answer the sync...with a ACK_SYNC message This is slow i know...but is the most easy way to do it for a start... (i get only 10fps max like this because of lag even over local network ...ugh...i will have to do smthng later) If packets are not lost from client to server it works ok/slow. But if packets are lost i have big problems. If server messages are lost he will know because no ACK_SYNC will come back but a slave PC has no way to know if his ACK_SYNC message has reached the server.... U see my problem? i cant resend an ACK to ACK because i go in an infinite logical loop.... Have u guys any ideeas about sincro of multiple PCs so they are at the same frame all the time over the network? How the hell do i deal with lost packets? Thx Bogdan
obysoft
Advertisement
Have you set guaranteed messages? Try DPlay->Send() using the DPSEND_GUARANTEED flag... that might help, but will certainly slow down transfers.



MatrixCubed
Yes i have tryed but they do their BEST try to send...but if they still fail....and this happens...

Also is too damn slow... u cant get 10fps at max...

I was thinking at a way to send fast nonguaranteed msg and to detect if they fail....to fall back to a waiting loop or smthing resyncing just in error....

But this is way complicated
Maybe u guys have some ideeas

Bogdan
obysoft
I''m using DPlay with gurenteed and can pull over 100fps with the server (depending on the computer) The problem isn''t the packet speed. It''s how many you''re sending and how big they are. It could also be your render loop.

The only way the server pulls over 100 is in windowed mode to avoid having to be in sync with the monitor. The render is also quick with it just being text to show client information.

The client speed generally achieves a little over 20.

If you''re trying to send packets every frame, that''s your first problem. You need to figure out how to send packets as little as possible and let the clients fill in the blanks. Next problem is compressing packets prior to them being sent.

This is the whole trick:

g_pDP->Send( g_LocalPlayerDPID, 1, DPSEND_GUARANTEED, &msgWave, sizeof(msgWave)-65536+2 );

That tells direct play that out of 65536 bytes available in the message struct, I only want to send the two I need. The struct is just an unsigned char message[65536]



Ben





About the speed:
============================

This is not main problem but if KalvinB talk it up:

Yes i am sending at every frame, but very little data: about 16 dwords and i have a 33fps rate on the server and a 24 fps rate on a client machine before sync.

Now when i sysnc them at every frame (and i have to do so to send units commands) i get 10fps on both machines and a well syncronized frame number on each machine
(render loops are big but they dont get in the way at 10fps )

Now i wonder how do u KalvinB get 100fps on a machine and 20 on another if they are in syncro? eh and just a text on the screen is fun not really a game is it?

However with a latency of 30ms over a local network and at least 2 packets per frame (send/receive) i dont think u cant get more then 50fps IMHO

That is if u sync every frame.

I know i will have to sync every 10 frames or smthing ... but as i said before this was only for testing my game logic over network...
And syncing from time to time is far more harder to do...if u also have 100 units moving and attacking each other all over the map like i have

Now about my original Q: about packets lost:
=============================================

I think u cant just hope that DP_Send_guaranteed will do the job for u....on a real network packets are eventually lost...thats what DPlay DPSim Tool does is it not....?

So i was asking what do u do if packets get lost and a PC will think he can do a comand while the other will not do it...

Obviousely u have to never reach that point because if so a FATAL desync has occured and u have to disconect one of the PCs just to keep game in sync

But my ideea is u cant just send ACK to ACK messages as this logical quiz will never end : because the second ACK messgage can also be lost ... and so on...u never really know if a message is SAFELY send do u?

Quiz i how to know that a message has ABSOLUTELY SAFE reached his target in a real network and having a game run at least at 20fps

U see real network (internet i mean) has a latency of 100 up to 300 ms at best (US vs Europe .. so 10 to 5 fps max) and u cant play ur game only with ur next door friend can u?

Or the same country in US

Bogdan


Edited by - bogdanontanu on September 10, 2000 6:26:20 PM
obysoft
Yes you can be For Sure that data was sent. Here is what I think you are thinking.

1). When you send a message say client to server, you send it garranteed, the client then waits for the return reply from the server. But how does the server know the client got its return reply, only way for the server to know is for the client to send a reply back saying it got its original replay and then the loop starts. But this is not so.

2). Here is what you should be thinking. Client sends garranteed message to the server, server sends a reply back saying it got the message. Now when the client gets the reply back, it then sends the next message of info, which the server is waiting for. The server will know the client got the reply if the client sends it another packet of data.

Now if the client does not get the garranteed reply back, it then sends the initial message again. But if the client does get the garranteed reply back, it then sends another message of garranteed data, but now if the server does not get this 2nd message, then the server will send back the reply to the original message packet and assuming the client gets the reply back again, it then knows the 2nd packet it sent didnt go through so it tries to send the 2nd message packet again. And of course if the client or server dont get either of them again then the connection has been broken mostlikely.

The trick here is that you can send a message saying you got the reply not by sending another reply but by sending another message of data. This way you can have a continuous stream of data and it is 100% garanteed.

Possibility
Now i wonder how do u KalvinB get 100fps on a machine and 20 on another if they are in syncro? eh and just a text on the screen is fun not really a game is it?

___________

They look in sync because there''s a wait flag at the server side. Instead of syncing frames, I sync moves. Each client displays the move at it''s own rate. If one client is lagging, it''ll skip frames on that client so as to not force other computers to wait for someone with a slow modem and/or PC.

The server keeps track of all the clients and current game state. You don''t play the server. If two people want to play it takes three computers. It''s an ISO engine btw. And not ASCII though I can render however I want.

It''s not possible to sync the frame rate because the server has to send and handle information from everyone. That''s why I have to keep the frame rate high by displaying only text.
__________
However with a latency of 30ms over a local network and at least 2 packets per frame (send/receive) i dont think u cant get more then 50fps IMHO

That is if u sync every frame.
____________

My packets are all below 8bytes. And they''re sent once per move.

I tried syncing once by having the server send exact positions every frame to every client. If a client was slow frames were skipped but the positions would all be the same. If the client was fast,it would render the same frame multiple times. They were in sync but it was a pathetic sight over a modem connection. It would be rendering 15fps but looked like 5. That was with one client.

You''re going to have to change your method to smaller and fewer packets and avoid exact syncing.
_________

I know i will have to sync every 10 frames or smthing ... but as i said before this was only for testing my game logic over network...
And syncing from time to time is far more harder to do...if u also have 100 units moving and attacking each other all over the map like i have

____________
It''s not a problem if you''re sending actions instead of positions and stuff. Like for mine the client sends the server a destination point. The server has the AI and gives the appropriate directions to move one at a time as the client completes them. All clients get the same command but the server doesn''t wait for them. If they get behind, each move packet also contains locations that are current.

On any client, characters from faster computers will appear to jump from cell to cell and characters from slower computers will stall before moving again. This keeps people from wanting to PK the shmuck with the P75 and 14.4 modem so they can enjoy the game at a real frame rate.

To deal with any potential packet loss, I keep all messages less than 10bytes as much as possible and send as few as possible.

a dword is 8bytes and times 16, you''re sending 128bytes per frame. No wonder your game drags. A 56k modem actually sends at most about 5.6kbytes per second max. Usually between 3 or 4. So you''re pretty much maxing your modem at 44.8 fps with just one character. You have to divide that by the number of characters getting commands.

I tried having messages that had set types and I found converting everything into base 256 (smallest type size) was alot easier and wastes zero space. If you only need to send a variable value 200. You don''t need a dword. If you send across 1000, you can do that in 2 chars which is 75% compression for your packet right there. You can tell dplay to send 3bytes of an 8byte dword but it''s trickier than converting everything to a char.

To give you an idea of the difference, I do about 13bytes total per character per move. Client command is about 5 and server command is about 7. You do 128bytes per character per frame.

Hope I''m of help on the packet info side. That''s as much a problem you need to work on as packet loss.

Ben

Hmmm

Most of the things u say make sense...

However some do not:
1.Size does count! yes i know that. I send only interface (mouse/keyboard) actions every frame and i think i can get it down do less dwords....but u see i was testing my game ONLY over LOCAL Network...so i figured out that an 128 bytes packet will not be that big...after all i KNOW that packets cant get smaller then approx 1.5K on a IPX or TCP/IP local Network
But YES i think smaller packets are req for the modem.This is only the PPP part...

2.Now packets WILL Get LOST whatever u do...i am sorry to point it out but there is an article on GamaSutra (and none found here )from a developer of XWing vx Tie witch documents a lots of the problems we talk here
So bottom line u have to go to nonguaranteed packets to do the job esp over the INET u have to go UDP (after all all major games do) And so u have to make ur own protocol...

Thats what i was Asking in the first place:
=============================================
-Wat kinda of user defined protocol u guys are using to send messages and how do we deal with lost packets ?

Here it comes handy ur good ideea about second packet beeing the ACK for first packet....but does it stops here....i hope i does but i have to find out myself to belive

There are also other tricks like delaying the actions until they are really ACK on all PC...

3. Maybe u can jump from one pos to another in a 3D FPS...can u really ?.... but in a RTS u just CANT... u have to have a perfect syncro between all PC or else units will:
-not get damage
-go throught walls,etc
-after a time u will have 2 diffrent games


3.On the Server/Client :
I didnt understood in the first place that the 100fps PC was a dedicate server SORRY please excuse...

If i may help u here:
Dont send "per move actions" just send the user interface clicks and keyboard actions...then make all PCs render teh actions / world in syncro... You will save enormouse bandwidts esp i u have 100+ units in ur game always. Like i have

Maybe game loop will become mor complex...but its rewarding in the end...when u hit Internet

I cant use a central server/client model because a server for 10.000 games all over the net is too dammn much cost

4.At last i want to point it out that even a 128bytes message over a local network is god damn slow if something is not done to not syncro at every frame ...i didnt knew that before doing this game oops even I have to learn

Btw. Testing ur modem dosent mean u test TCP/IP at all its just PPP but i think u know that

Thx for help

Bogdan
obysoft
Most of the things u say make sense...

However some do not:

--
I''ve only been using DirectPlay for about 2 months now or less. So I''m faking it alot. I may need to reevaluate my tactics as well in some areas. I''ve been greatly focused on packet size and speed over a modem connection. I''ll focus on packet loss when I get an internet server running.
---

1.Size does count! yes i know that. I send only interface (mouse/keyboard) actions every frame and i think i can get it down do less dwords....but u see i was testing my game ONLY over LOCAL Network...so i figured out that an 128 bytes packet will not be that big...after all i KNOW that packets cant get smaller then approx 1.5K on a IPX or TCP/IP local Network
But YES i think smaller packets are req for the modem.This is only the PPP part...

---
Here''s what I send...player number and event. That''s it. Sometimes some additional information is needed but I try to avoid it. Like if you click the mouse on an object on the screen an event is sent to the server, the server then sends that event to all connected to it and they all then do the action. Not even the client sending the request does the action until the server sends back a response.
---



2.Now packets WILL Get LOST whatever u do...i am sorry to point it out but there is an article on GamaSutra (and none found here )from a developer of XWing vx Tie witch documents a lots of the problems we talk here So bottom line u have to go to nonguaranteed packets to do the job esp over the INET u have to go UDP (after all all major games do) And so u have to make ur own protocol...

---
I''m waiting my for my AMD 700 to get here from Aberdeeninc.com I should then have an internet server running within a week or two. It is possible right now for the client to outrun the server which messes things up. Anywayz, I''ve read the article you mentioned. I''m hoping DPlay in DX7 will suffice. Writing my own protocol I can only imagine will suck. If I get my server before you do, I''ll let you know how it goes. I tried a modem connection and it works flawlessly. It runs just as well as over a LAN. At least with one client.
---

Thats what i was Asking in the first place:
=============================================
-Wat kinda of user defined protocol u guys are using to send messages and how do we deal with lost packets ?

Here it comes handy ur good ideea about second packet beeing the ACK for first packet....but does it stops here....i hope i does but i have to find out myself to belive

There are also other tricks like delaying the actions until they are really ACK on all PC...

3. Maybe u can jump from one pos to another in a 3D FPS...can u really ?.... but in a RTS u just CANT... u have to have a perfect syncro between all PC or else units will:
-not get damage
-go throught walls,etc
-after a time u will have 2 diffrent games

3.On the Server/Client :
I didnt understood in the first place that the 100fps PC was a dedicate server SORRY please excuse...

---
No prob.
---


If i may help u here:
Dont send "per move actions" just send the user interface clicks and keyboard actions...then make all PCs render teh actions / world in syncro... You will save enormouse bandwidts esp i u have 100+ units in ur game always. Like i have

---
I''m set up for 1500. Keyboard hits and mouse clicks are actions. I send a two char player number. Then some bytes of information. The server doesn''t know where you clicked the mouse so the client does the work and just sends the destination. It''s not vital information that has to be kept from being cracked anyway. I''m working to keep my keyboard commands to a minimal.
---


Maybe game loop will become mor complex...but its rewarding in the end...when u hit Internet

---
I can''t wait to see mine over the net.
---

I cant use a central server/client model because a server for 10.000 games all over the net is too dammn much cost

---
client-client would be impossible for more than 4 or 5 users connected to one game. The only pain with the server is that you have to program two things at once sometimes.

I''m guessing you''re doing something like starcraft where one client controls alot of stuff. Mine is where one client controls one player. So we might slightly be apples and oranges on comparing tactics a bit.

Ben

I sent a post last night, but GameDev went down and I couldn''t send it. Grrr...

Basically, though, I said that I don''t know DirectPlay (yet), but using UDP packets I''d do this to guarantee delivery:

1. When sending packets, include a unique ID (the first 4 bytes, say), which can just start at 0 and be incremented for each new message. Store the packet locally in a list of unacknowledged packets with the time you sent it.

2. On receiving a packet (apart from ACKs), send an ACK containing the ID of the received packet.

3. On receiving an ACK packet, remove the message with the same ID from your list of unacknowledged packets. If you don''t recognize the ID, ignore the ACK.

4. Implement a time-out: if no ACK is received within a set time (150ms, say), resend the packet including the same ID.

Also, a couple of general points:

All packets sent have an overhead (I think its 28 bytes) for the IP header, so it is much better to combine small packets and send them together. Remember, however, that overlarge packets (1.5k I think) are not guaranteed to get through. Also, not all packets are essential, so only use the above method if it is vital for that message to get through; much data is out of date after a short time and later data will override it.

I said much more yesterday, but does this help?

Dave

This topic is closed to new replies.

Advertisement