Dead Reckoning - Client/Server game - How to handle keystrokes

978 views Asked by At

I've read a few articles about dead reckoning, but it's still a bit confusing to me. I'm pretty sure I understand the concept of point-and-click movement, but how would I update keystroke movement between the client and server, when the end-point of the movement is unknown?

How would you estimate where the player is going (server-side) if there is no end-point?

2

There are 2 answers

0
Brad The Developer On

Let's start with dead reckoning. Try to think about it on a straight line where there is no left or right movement.

You are at point A and want to get to point B. You know the distance to point B so you can compute how much acceleration and velocity it will take to get there. Dead Reckoning works the other way. You are at point A and will move at a set speed to get near point B.

In the video game world they use this method all the time. So don't think about it as you're moving to point B you're just moving towards point B in increments because in like a FPS your point B will constantly moving. When in fact its really only moving in increments in the direction of point B.

Once you get moving forward then you can start worrying about left/right and up/down which will follow the same principle just in different directions.

As for implementing this you have 2 options.

One way, you could make this calculation on the client side then send the new position to the server. Then update what everyone else sees on screen.

The other way which I think is better you can make all these calculations on the server side and just receive an update where you ended up. X-Box live makes one of the consoles the host so that machine is running all the software and the external users are just firing events. This is why you'll hear people complain about having an unfair host advantage.

Now let's look at some code. This script comes from the Unity Sdk standard install package.

/// This script moves the character controller forward 
/// and sideways based on the arrow keys.
/// It also jumps when pressing space.
/// Make sure to attach a character controller to the same game object.
/// It is recommended that you make only one call to Move or SimpleMove per frame.  

var speed : float = 6.0; 
var jumpSpeed : float = 8.0;
var gravity : float = 20.0;
private var moveDirection : Vector3 = Vector3.zero;
function Update() {
    var controller : CharacterController = GetComponent(CharacterController);
    if (controller.isGrounded) {
        // We are grounded, so recalculate
        // move direction directly from axes
        moveDirection = Vector3(Input.GetAxis("Horizontal"), 0,
                                Input.GetAxis("Vertical"));
        moveDirection = transform.TransformDirection(moveDirection);
        moveDirection *= speed;

        if (Input.GetButton ("Jump")) {
            moveDirection.y = jumpSpeed;
        }
    }
    // Apply gravity
    moveDirection.y -= gravity * Time.deltaTime;

    // Move the controller
    controller.Move(moveDirection * Time.deltaTime);
}

So in this example we have speed which is set to a constant. So when moving in a direction we will travel in that Vector at a constant rate with no care about where point B is located.

Jump speed is how fast will we move in the y axis in the positive direction and gravity in the negative direction stopping at point 0.

So, How can you use this? You could build a server script that executes a move action and have a client side controller that passes the direction information to the server.

So lets say on the client side action is key press down, you send a call to the server to move you in the direction selection and the server will keep you moving you in that direction until action key press up or a change in direction from another input.

I hope this helped.

2
user3079666 On

Let's see... I understand you know how to code, but not what, am I right?

You can feed the keystrokes directly to the server and let it do all the work. The server has no need to know where you are heading, it has your coordinates and direction and that's all it will need, unless you have server-handled AI. In the later case, you can do something similar to raycasting in Unity, start checking what is straight ahead and see if it is anything of interest, if so you know the potential destination.

It is safe to constantly send back to the client all his data, so it is always up to date. If you believe this will strain your connection you can do that every 50ms or as often as you believe is safe, and for smooth function estimate everything on the client side too. Make sure the server does all the collision detection and all the mechanics not related to the UI, or else the game will be prone to client-side malfunction or malicious tampering.

If you do have to look at where the player might be going, you can use a few approaches, you could either have a number of virtual cubes in the world which keep track of what is inside them, which will simplify finding what's ahead in terms of resources, or you could check everything there is, which is rather heavy on the machine, but this adds some other complexities too. In the first case do not forget to stop looking once you hit an obstacle.

You can also calculate the angle between the player's direction and other items of importance to check what else might be on his mind.

The question about UDP has already been answered, plus I'm sure Wikipedia has a helpful book on UDP and TCP, I have nothing to add.

The explanation of dead reckoning was also quite satisfactory, I hope I added other angles to the concept.

I hope I helped, if you need any clarifications or any other help feel free to contact me, if I was less than unhelpful then feel free to downvote, I study computer engineering and am creating my second game for PC so maybe I have ran into some problem already and can share the knowledge.