Fixed-time step

The first thing that we'll update in our server's code is the game loop, and the first thing that it'll do differently is that it will no longer have the concept of delta times. In addition, we will need to queue up all input from each client between update cycles so that we have the data to update the game state with, when we run the physics update.

Since we're now using a consistent time step, we have no need to keep track of delta times on the server. As a result, the server also has no concept of delta times from the clients' perspective.

For example, imagine a racing game where a player is driving at, say, 300 pixels per second. Suppose this particular client is running the game at a frequency of 60 frames per second. Provided that the car maintained a steady speed during the entire second, then after 60 frames, the car will have travelled 300 pixels. Additionally, during each frame the car will have travelled an average of 5 pixels.

Now, suppose that the server's game loop is configured to run at a frequency of 10 frames per second, or once every 100 milliseconds. The car will now travel further per frame (30 pixels instead of 5 pixels), but in the end, it will also be 300 pixels further than where it started one second ago.

Fixed-time step

In summary, while the clients will still need to track how long it takes to process a single frame in order for all the clients to run at the same speed, regardless of how fast or slow different computers run the game loop, the server's game loop doesn't care about any of this because it doesn't need to.

// ch4/snake-ch4/share/tick.js

var tick = function (delay) {
    var _delay = delay;
    var timer;

    if (typeof requestAnimationFrame === 'undefined') {
        timer = function (cb) {
            setImmediate(function () {
                cb(_delay);
            }, _delay);
        }
    } else {
        timer = window.requestAnimationFrame;
    }

    return function (cb) {
        return timer(cb);
    }
};

module.exports = tick;

Here, we first update our tick module that we built for the purpose of reusing code in the server code as well as in the code that is shipped to the browser. Note the use of setImmediate instead of setTimeout, which will perform theoretically faster since the callback is scheduled earlier in the execution queue.

In addition, observe how we export the wrapper tick function instead of the closure that it returns. This way we can configure the server's timer before exporting the function.

Finally, since the delta time is now predictable and consistent, we no longer need the tick's variable to simulate the passage of time. Now, we can just pass the interval value directly into the callback function after each tick.

// ch4/snake-ch4/share/game.js

var tick = require('./tick.js'),
tick = tick(100);

var Game = function (fps) {
    this.fps = fps;
    this.delay = 1000 / this.fps;
    this.lastTime = 0;
    this.raf = 0;

    this.onUpdate = function (delta) {
    };

    this.onRender = function () {
    };
};

Game.prototype.update = function (delta) {
    this.onUpdate(delta);
};

Game.prototype.render = function () {
    this.onRender();
};

Game.prototype.loop = function (now) {
    this.raf = tick(this.loop.bind(this));

    var delta = now - this.lastTime;
    if (delta >= this.delay) {
        this.update(delta);
        this.render();
        this.lastTime = now;
    }
};

The only difference that you will notice here is that the tick module is called with the frequency it is being passed in, so we can configure how fast we wish it to run.

Note

You may wonder why we selected the possibly arbitrary number of 10 updates per second for the server's game loop. Remember that our goal is to make our players believe that they're actually playing an awesome game together with other players.

The way in which we can achieve this illusion of real-time game play is by carefully hand-tuning the server to update fast enough so that the accuracy is not too far off and slow enough so that the clients can move in such a way that the lag is not too noticeable.

You need to find the balance between the authoritative server that provides accurate game state versus the client's ability to provide a responsive experience to the player. The more often you update the clients with data from the server's update cycle, the less accurate your simulation will be; this depend on how much data the simulation had to process and possibly drop data along the way in order to keep up with the high update frequency. Similarly, the less often you update the clients with data from the server's update cycle, the less responsive the client will feel, since it'll need to wait longer on the server before it knows for sure what the correct game state should be.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.96.86