Jump to content

  • Log In with Google      Sign In   
  • Create Account


General Questions About Networking in FPS Games


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Medo3337   Members   -  Reputation: 665

Like
0Likes
Like

Posted 19 January 2013 - 11:21 PM

Hi,

 

I'm just getting started into networking for FPS game, I have few questions:

 

1. How exactly should I send the game data from the server to the clients? Should I gather information about everything in the game and send it in one single packet?

 

2. What data format I can use to send the game data?

 

3. How do I send information about particles? like for example explosion, fire or smoke? should I send the position of each particle vertex? or just send a command to the clients to create the particles (what type, position, etc...) without sending any further information about it? I guess this could be a problem since UDP data is not guaranteed to arrive.



Sponsor:

#2 Deortuka   Members   -  Reputation: 493

Like
1Likes
Like

Posted 20 January 2013 - 11:52 AM

1. You will send the the data from the server to the client via sockets. It would be wise to make sure the only information you send is updates. For example, you send a power up's position to a client and now that client will see that power up at that location. The only time you will need to update the position of that power up to that client again is if it has moved. This approach will help minimize the bandwidth needed by the server.

 

2. This is entirely up to you. A good start is to send everything in "messages". For example, a player position message would be sent as:

[PLAYER_POSITION_MESSAGE]
[
    [PLAYER ID] (32 bits)
    [POSITION_X] (32 bits)
    [POSITION_Y] (32 bits)
]

 

3. You do not want to send information like this from the server. You would want to send a message like above with the information needed to replicate the effect (ex. effect type, position, etc.) and let the client take that information to create the effect. In fact, this is the only way that the server should even know about effects. The individual particles (or anything else that is not strictly "gameplay" related) should never be handled by the server. You will also need to have the server "number" it's outgoing messages to address the not guaranteed issue. Clients test the number of the incoming packet against the number of the last received in order to tell if it should be processed or discarded.

 

I seriously over simplified the answers to your questions, but the overall idea really is that simple. I hope this helps.



#3 Medo3337   Members   -  Reputation: 665

Like
0Likes
Like

Posted 21 January 2013 - 12:55 AM

Okay, starting from number 1:

Should I gather all the information and send them like this (each message contain all the commands):

// One single packet:
[PLAYER_POSITION_MESSAGE]
[
[PLAYER ID] (32 bits)
[POSITION_X] (32 bits)
[POSITION_Y] (32 bits)
[POSITION_Z] (32 bits)
];

[PLAYER_POSITION_MESSAGE]
[
[PLAYER ID] (32 bits)
[POSITION_X] (32 bits)
[POSITION_Y] (32 bits)
[POSITION_Z] (32 bits)
];

[PLAYER_POSITION_MESSAGE]
[
[PLAYER ID] (32 bits)
[POSITION_X] (32 bits)
[POSITION_Y] (32 bits)
[POSITION_Z] (32 bits)
]

[Particle]
[
[PARTICLE_TYPE] (32 bits)
[PARTICLE_X] (32 bits)
[PARTICLE_Y] (32 bits)
[PARTICLE_Z] (32 bits)
]

 

OR should I send one command per message instead:


// Only one single command per message
[PLAYER_POSITION_MESSAGE]
[
[PLAYER ID] (32 bits)
[POSITION_X] (32 bits)
[POSITION_Y] (32 bits)
[POSITION_Z] (32 bits)
]

2. Can I send binary data instead of plain text? I don't want the data to be readable by human.

 

3. The problem that I think of is that data sent over UDP is not guaranteed to arrive each time, so when I send particles command for example I only send it ONCE and if it didn't arrive to the client that will be a problem.



#4 Deortuka   Members   -  Reputation: 493

Like
1Likes
Like

Posted 21 January 2013 - 05:56 AM

1. You definitely want to pack as much information as you can (but not too much) per send call. So that is a yes to sending multiple commands per message. It will take some tweaking and testing on your part to get an optimal number of commands to send per message. I recommend sending as much as you possibly can and start cutting back if you begin to have bandwidth issues.

 

2. Sending binary data is in fact the best way to do it. Strings have to be converted into binary form to be sent through a socket and then converted back into string on the receiving end.

 

3. Well the numbering system I described works both ways. The server numbers outgoing packets so that the client will know if it is relevant or if it is old and needs to be discarded. The client should also let the server know the number of the last packet it received when it sends it's data to the server. This way the server knows if it should resend an old packet or not. This requires that your server save a copy of the last few packets sent out.

You could take this a step farther and have the server label packets as critical or optional. This way if an optional packet (say for instance spark effect) has not been acknowledged as being received as a client, it will not be resent. However, a critical packet (such as a "player died" notification) will be resent if the client didn't acknowledge receiving it. This will prevent the the client from interacting with something that shouldn't be there (and in return sending messages to the server about that interaction).

 

To re-simplify things:

1. Server keeps track of connected clients.

2. For each client, server has a vector of the last 10 (random number i picked out) packets sent to that client.

3. When server sends a packet (which should contain as many messages as possible) to a client it "numbers" it and adds it to that vector (over-writing the oldest one to prevent unnecessary heap allocations)

4. When server receives a packet from a client (which should contain the number of the packet last received on that client's end) it checks the "last packet received" number in it.

5. When server is ready to send information to a client, it determines if it should resend one or more old packets (stored in the vector described in #2) and sends those old packets along with any newer ones (all as one combined packet) to the client.

 

I hope this clears things up a bit.



#5 Medo3337   Members   -  Reputation: 665

Like
0Likes
Like

Posted 21 January 2013 - 12:13 PM

1. Okay, I'm still unsure what is the appropriate number of commands per message to start with, I mean should I send in average 100 command per message? Another important question is: should the server DELAY between messages or keep sending all the time without delaying?

 

2. What I mean by "binary data" is that I want to send the command as unreadable data (not plain text) for example: sending a structure, so something like:

 

3. So that means the client should notify the server for each critical message sent from the server, but what if the client notification of the received message got lost as well?



#6 Deortuka   Members   -  Reputation: 493

Like
0Likes
Like

Posted 21 January 2013 - 02:35 PM

1. This will be the number of "events" since the last server update/frame. For example, if two players moved and one explosion was created since the last update, you would send three messages in one packet (two player positions and one explosion). There is no "appropriate" number of messages to send. You just send what needs to be sent. If, and only if, you encounter bandwidth problems, you will start to split large packets into smaller ones.

 

2. Data must be sent through sockets in binary form. You can even encrypt the data before sending, and decrypt it on the receiving end.

 

3. Yes, the client should acknowledge the last packet received so that the server can know if a packet must be resent. All data that the client sends to the server should be considered non-critical. If the server does not receive a message from a particular client, its no big deal. Just go with the packets that are received from the client. Should so much time go without receiving a packet from a client, just consider that client timed-out and drop them.

It is true that UDP packets are not guaranteed, but it is safe to assume that your packets will reach their destination. This system of numbering and acknowledging packets is just a safe guard. There are a lot of little "gotchas", but try to not dig deeper than what is necessary until you have a stronger understanding of what's going on.

Just start out by sending and receiving data. Once you have accomplished this, then start addressing the what ifs.



#7 ankhd   Members   -  Reputation: 1072

Like
0Likes
Like

Posted 31 January 2013 - 04:49 AM

the network protocol will have a max packet size unless your using tcp/ip then you just stream it say 512 chuncks.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS