Thread: Networking Protocol

  1. #1
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879

    Networking Protocol

    Hey everyone,
    I have a problem. I made a game that uses Winsock to network between two computers. The original protocol that I used was this (using TCP/IP):

    -Send the player keys that are pressed
    -Receive the opponent player's keys that are pressed
    -Continue with another frame of the game

    Then I upgraded the game, to include 3 or more players, and changed the protocol to this:

    -Send player keys that are pressed to a server computer
    -If you are server, receive the keys from each of the other computers
    -If you are server, send off to each client the number of packets to receive
    -If you are server, Send to each client the keys of each other client
    -(for everyone) Receive the number of packets, then receive the packets, and update, draw another frame, etc.

    Problem with this one is, it's horribly horribly slow (as in about 4 frames per second) even on a LAN. Does anyone have any suggestions on how to improve this? Do I need to switch to a system like "send data with timestamp and execute command after a delay"? Or do I need to switch to UDP somehow or something like that?

    **Note: Game networking tutorial links also welcome
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    How about doing it all in async. That is, just run the game and only worry about other players' key presses when they arrive.

    >>-(for everyone) Receive the number of packets, then receive the packets<<

    Maybe do this in another thread so the game loop continues. When a packet(s) arrive you deal with it and update the key states. Until then you consider the keys in question 'stuck down'.

    If you do this you will know the client is sending and receiving key states at maximum rate and you will only have to worry about optimising the server.

    I have no idea if this would work but it sounds like you are wating several round trips of the network between each frame.

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Hmm, I would do that, but the problem then is game synchronization. Then, while someone got shot on one screen, due to lag, the same person might be on the complete other side of the screen and be completely unharmed. Of course, I could treat it as playing with really really bad computer AI (), but that would defeat the point of multiplayer.

    I tried solving this before by implementing a sort of latency feature, sending "KeyEvent" structures which have member variables telling what frame to execute in, what key to manipulate and what state it should be set to, in conjunction with a frame counter in the main loop. So when a key is pressed, a KeyEvent is added to a global vector, and an identical copy is sent to the server (which relays it to each client except the one that sent it). The problem was, one computer may run slower than another, and if too many frames pass before the key event is received, then the games once again go out of sync; and I can't think of any "undo" feature that will move the game back a few frames and re-update taking the key event into account. But overall, would this be a good approach to use, providing I take extra steps to ensure synchronization? (before, I just had it quit if the games went out of sync)
    Last edited by Hunter2; 11-29-2003 at 11:47 AM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > -If you are server, Send to each client the keys of each other client
    Have you calculated the number of messages which get sent in response to each new client which joins the game?
    It's a geometric progression, which means it gets big in a hurry.

    > Or do I need to switch to UDP somehow or something like that?
    For me, I would
    - merge all the actions received within a small amout of time at the server.
    - use UDP broadcast to send just ONE message to the network and have all clients pick that up.

    If you make both the clients and the server tolerant of the occasional missed message, then you can just use UDP and save an awful lot of protocol overhead for TCP.
    The reason you can do this is that you should only be interested in the latest information. There is little point waiting around for some old info, if it's going to be obsolete within a few milliseconds.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>use UDP broadcast to send just ONE message to the network and have all clients pick that up

    Hmm, didn't know I could do that. Thanks, I'll look into it **EDIT: Just thought, then, wouldn't I need to add a check to see if each client received the data?

    Just one thing that still remains unsolved (as far as I can see): How do I fix the problem of synchronization with one computer running too slow, and another running full speed?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #6
    30 Helens Agree neandrake's Avatar
    Join Date
    Jan 2002
    Posts
    640
    Your game is time-based? Check out the OpenGL tutorials at www.gametutorials.com and read up on the Time Based Movement. Also, wouldn't key movements be tedious? Why not send positions and such. Let the clients do the calculations for determining the other players, allowing for smaller packets to be sent, gameplay will speed way up.
    Environment: OS X, GCC / G++
    Codes: Java, C#, C/C++
    AOL IM: neandrake, Email: neandrake (at) gmail (dot) com

  7. #7
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    It's frame based (with a slower-downer in the main loop that Sleep()'s the game if it's going too fast). One day I'll make something time-based, but not today

    Like you suggested, I was thinking of sending positions and such like the commercial games do it (?), but then I couldn't think of a way to keep things synchronized (there it is again ) I guess if I spent a few minutes thinking about it I woulda come up with something, but this way seemed to work so well (I adapted it from a single-machine game with two players on 1 keyboard, so this way needed the least changes), and it was decently fast anyways when I made the 2-machine version.

    I'm going to drive out and buy a book on networking this week (or this month... I hope), since I'm having trouble with finding/following good in-depth tutorials on UDP/raw sockets and their usage. I'm now fluctuating between the (send positions/damage/etc.) and (send keypresses + timestamp) methods. Any additional input would be greatly appreciated
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Why don't you just get ethereal installed on (preferably) a separate machine, then setup a network game and see what happens.

    Or get the source code for older versions of games like DOOM which had network play in them which worked rather well over dialup modems, so a LAN should be no problem.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    The problem here is syncronazation. This is the concern of all games. And the answer has 2 prongs.

    basicly dead recononing, and averaging. On important events like bullet hits, deaths etc, the server makes the final say so on who was where. For other things, you just average where player one thinks he is, and player 2 thinks player one is.

    Heres soem highlights from a relevant article at gamasutra, since dyou have to register (free) to see content:

    Table 2. How to Overcome Latency

    Decouple the communications from your game:

    Place blocking communications calls in a separate thread or use asynchronous communications calls.
    Never await incoming data from another player before allowing game play to continue.
    Use predicting, interpolating, and reconciling later to improve game play.
    When using prediction, transmit not just position information, but also velocity and acceleration.
    Latch or queue user input (for example, keystrokes) until the next time communications data is to be sent. If you use the more traditional method of checking the keyboard at regular intervals during the game loop and perform this checking only at moments before sending data to the network, you will be prone to missing user input.
    Hide latencies in other game elements:

    Schedule events in the future if you want them to happen simultaneously for all users.
    Require multiple shots to kill someone, and minimize the number of all-or-nothing, deterministic, latency-sensitive events.
    Make rockets take a long time in the air (and reconcile the outcome while the rocket is flying).
    Require time to move from one location to another (don't allow any instantaneous teleporters).
    Make players, ships, and other objects move in ways that facilitate prediction. For example, build inertia into the way entities in your game move.
    Use your imagination to incorporate latency within the context of your game concept.
    Table 3. Techniques to Conserve Bandwidth

    Compress your game and speech data.
    Send data asynchronously--that is, only when needed, rather than at regular intervals.
    Prioritize your data; then, think of your bandwidth resource as a fixed resource and budget according to your priorities. This way, if there is too much demand for bandwidth, you degrade game play gracefully. Prioritizing data and allocating bandwidth accordingly also allows for better interoperation between 14.4k, 28.8k, ISDN, and other qualities of bandwidth.
    Use a multicasting or customized game server.
    Cache information about other players locally.
    Cluster repetitious game events (for example, a machine gun firing) into a small number of messages, rather than hundreds of messages.
    Have AI live on the local client machines, and send over only the random seeds and checksums to control the AI.
    Use teams and consider having players on the same team divide responsibilities so only one player needs to send data on behalf of the entire team. For example, multiple players can ride in a single tank that is controlled by just one player.
    Don’t allow everyone to see everyone else. One simple way to do this is to subdivide the game world (for example, into sectors or rooms) and restrict communication among players based on the subdivisions
    go here http://www.gamasutra.com/features/19970905/ng_01.htm for the article, and sign up, gamasutra is a must read!
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  10. #10
    30 Helens Agree neandrake's Avatar
    Join Date
    Jan 2002
    Posts
    640
    If you look at the time-based tutorial at GameTutorials, it isn't alot of code to add. It would also help to know what kind of game this is (I think we're all assuming FPS since network communication _must_ be fast). Also, if you find a good book, please tell me. PM me or something.
    Environment: OS X, GCC / G++
    Codes: Java, C#, C/C++
    AOL IM: neandrake, Email: neandrake (at) gmail (dot) com

  11. #11
    30 Helens Agree neandrake's Avatar
    Join Date
    Jan 2002
    Posts
    640
    Also, I was thinking about this, not sure what the problems would be, but I'd like your input. Have the clients not update the scene unless data is received from the server. When a key is pressed, a packet is sent to the server which echos it to all clients, then all clients get the updated data and update their scenes accordingly. Again, as I write this, it starts to sound like a bad idea. I'm not too good with TCP and such, and I'm guessing there would be lots of lag or something.
    Environment: OS X, GCC / G++
    Codes: Java, C#, C/C++
    AOL IM: neandrake, Email: neandrake (at) gmail (dot) com

  12. #12
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >>Place blocking communications calls in a separate thread or use asynchronous communications calls.
    Never await incoming data from another player before allowing game play to continue.
    Use predicting, interpolating, and reconciling later to improve game play. <<

    Hey, this is what I said! Seriously, I don't think the problem has a 'solution'.

    You either wait between each frame for everything to be communicated, in which case your game runs at a significantly slower speed than the slowest client or you accept that there will be some lag. If the server is well optimised and the packets are small the lag should be unnoticeable on a lan.

  13. #13
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Wow, thanks for all the info everyone! I don't check my email for a day, and I come back to find 999 replies

    Thanks alot for the article, dbgtgoten, neandrake for the idea, anonytmouse for the summary, and Salem for the DOOM idea! Sadly, I'm in the middle of exams right now so I won't be able to get into any of it for about a week and a half, but I'll post some more questions when I do have time to work on this.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  14. #14
    Registered User
    Join Date
    Aug 2003
    Posts
    23
    Hi, I've just started learning directplay, and I think that agrees with what some people said, you only want the latest info, anything that has timed out gets dropped, also you need threads, this means you keep running your game and the players positions get updated as the info arrives, - you can't be waiting around until everyones info has arrived before you go to the next game loop.

  15. #15
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>also you need threads
    Nope. It's called select()... But I get what you're saying anyways

    >>you can't be waiting around until everyones info has arrived
    Given the structure that I'm using currently (I haven't gotten a chance to change it yet), I DO have to get everyone's info. Otherwise you'll be wondering why the guy's slashing his sword at the wall all the time, grappling the ground, and aiming in the wrong direction. But, again, point taken I gotta change the game structure.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. FTP program
    By jakemott in forum Linux Programming
    Replies: 14
    Last Post: 10-06-2008, 01:58 PM
  2. networking comfirmation
    By rEtard in forum Networking/Device Communication
    Replies: 1
    Last Post: 07-20-2005, 03:59 PM
  3. Making my own networking protocol
    By EvBladeRunnervE in forum Networking/Device Communication
    Replies: 8
    Last Post: 08-21-2003, 08:30 PM
  4. Beyond MFC : COM || Networking
    By kuphryn in forum Windows Programming
    Replies: 5
    Last Post: 04-25-2002, 04:28 PM
  5. C++: Reference Book, GUI, Networking & Beyond
    By kuphryn in forum C++ Programming
    Replies: 4
    Last Post: 11-10-2001, 08:03 PM