Chapter VII
Transferring Input Data
Now that we have our input from our clients, we must now find a effective way to transfer it to the server. Unlike a single player game where we don't have to worry about force changes, in multiplayer since we have to send the forces to the server over the LAN or internet, we want to make sure we are sending the least amount of data possible and yet make sure that the server has the correct forces for each player's movement action.
Once again, there are many possible ways to do this, but here is the one I came up with from some of my earlier multiplayer testing scripts that I think works quite well. What I figured out after some testing was that in most code I had seen was that the clients were sending the force values of the clients every frame. So if we had a FPS (frames per second) of 60, that means each client would be sending 60 force updates per second to the server. I also found that the network didn't handle this well except on LAN.
I finally had a moment of insight, "Why am I sending a force update every frame?" 95% of the time or greater the force values are actually the same as they were last frame unless someone is just tapping all the movement keys, even then he can't tap seperate keys 60 times per second. So what figured out to do was to save the forces at the end of every frame into a variable such as force_x_old, force_y_old, and force_z_old (if applicable), then the next frame I would get the new forces off the client's inputs and the check if the forces were the same as last frame. If the forces were the same as last frame there was not any reason to send them to the server becuase they had not changed.
So if a player is just standing, all of his forces equal 0, as long as he is standing there is no need to send any force data to the server. I found that the only time forces really need to be sent is when a player goes from standing to walking, walking to running, etc. Let's say that the player is going from standing to walking, his force_x starts at zero and ends up at one. So there is a need to send the force_x until force_x = 1 is reached. Now once force_x = 1 is reached and the player continues to walk, his force_x remains at one and there is once again no reason to send any force data until he stops walking by either releasing key and goes to stand or hits the key for run.
By using this method you will find over time that the actual number of forces being sent to the server from a client will approach zero. I must mention that if you use this method is necessary to send your data reliable, because a missed packet could result in the server thinking that a player is still walking when he is actually standing, etc.
Now that we understand the foundation on which our force data transfer is based upon, let's add the code to input_scan() to make it happen.
function input_scan()
{
// only send changed skill values, so we need variable to store old values
var force_x_old;
var force_y_old;
These variables will hold our saved last forces. Then at the beginning of every frame cycle we save our old force, then set our new force to zero and then the new force will be set based on the player's input. If the player gives no input for that force then the force will remain zero.
while (1)
{
// if player has been created get inputs for him
if (player)
{
force_x_old = player.force_x; //store old force values
force_y_old = player.force_y;
player.force_x = 0; // set force to 0 until we get key input
player.force_y = 0;
// <w> or <cursur up> moves forward
if ((key_w == 1)||(key_cuu == 1))
{
player.force_x = 1;
}
All we have left to add now is our if statement that checks if any forces have changed and if a force has changed we send it to the server if our connection mode is a Client. If we are the Host, we do not need to send the forces to ourself, because, "Hey! We are the server."
//player.force_x = key_force.y; // get force x
//player.force_y = -key_force.x; // get force y
//player.force_z = 0; // force z always 0 for now
// if any forces have changed, send new forces to server
if(player.force_x != force_x_old || player.force_y != force_y_old)
{
// if client, send forces to server, if we are single/host/server values need not
// be sent
if(connection == 2)
{
send_skill(player.force_x,SEND_VEC); // send force vec to server
}
}
}
wait(1);
This is the statement that makes it all work, if(player.force_x != force_x_old || player.force_y != force_y_old).
Then we send all the forces reliably as a vector, send_skill(player.force_x,SEND_VEC); // send force vec to server.
Note: If you are using a z force, make sure you save force_z_old before you get new z force and make sure you include it in the if statement too, || player.force_z != force_z_old.
I know you are just loving these easy chapters. In the next chapter we will turn up the difficulty a notch.
Previous Page Contents Next Page