2
\$\begingroup\$

I am building a 2d multiplayer game with no physics and my own authoritative server. Already have all players getting synced each with other but their movement isn't so smooth yet.

Here is the mechanics:
- player clicks on the screen to move towards the mouse pointer. Client sends action + angle to server
- server calculate new position based on a certain speed and sends it back
- player then moves through interpolation

After reading a lot of articles and play around with few samples code, I still have my doubts about how to get the clock right on both sides.

Would the approach below be suitable for my type of game?
- Run the server at 1000/10
- Run the Client network loop at 1000/60 and the game loop at 1000/60

Also do I need a game loop running in the server at 1000/60?

\$\endgroup\$
1
\$\begingroup\$

The clock speed matters less, as long as you make sure the server and the client game steps are kept in sync. This article by Gary Weiss discusses this issue. Essentially either the game loop on the client or the server be late/early and you need to take care of these discrepancies.

Here's a proposed piece of code he wrote to implement these syncs (in JS):

// the game loop runs with an adjusting setTimeout call
let nextExecTime = null;
let gameLoop = () => {
    let stepStartTime = (new Date()).getTime();
    this.step();

    // delay/hurry the execution of next step if requested.
    // this could happen because of client-server step drift.
    nextExecTime = stepStartTime + this.options.stepPeriod;
    if (this.delayNextStep) {
        nextExecTime += STEP_DELAY_MSEC;
        this.delayNextStep = false;
    } else if (this.hurryNextStep) {
        nextExecTime -= STEP_DELAY_MSEC;
        this.hurryNextStep = false;
    }

    setTimeout(gameLoop, nextExecTime - (new Date()).getTime());
};

// in same cases, setTimeout is ignored by the browser,
// this is known to happen during the first 100ms of a touch event
// on android chrome.  Double-check the game loop using requestAnimationFrame
let gameLoopChecker = () => {
    let currentTime = (new Date()).getTime();
    if (currentTime > nextExecTime) {
        this.step();
        nextExecTime = currentTime + this.options.stepPeriod;
    }
    window.requestAnimationFrame(gameLoopChecker);
};

Note for the sake of transparency: me and Gary are co-developers of an open-source library for multiplayer games in Javascript: Lance

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.