Synchronization v7 - nodeGame/nodegame GitHub Wiki

  • status: complete (in refactor, it may change in next release)
  • version: 7.x

Overview

By default, players are waiting for a message to step from the logic, which is orchestrating the synchronization by centrally bookkeeping the state of the game.

However, it is possible to alter this behavior for the entire game or for individual stages and steps, by applying a step-rule. Different step-rules can be applied at each step, giving a powerful tool to achieve synchronization among connected clients.

Step-rules

A step-rule is a function specifying the condition for entering into the next step. For example, a step-rule may force a player to wait for all others to finish the same step, while another one could allow a player to step forward freely until the next synchronization checkpoint.

Step-rules are triggered by certain events, such as node.done(), or when the client receives a state update by another player, or if explicitly requested to do so.

Applying step rules

Step-rules are applied directly to steps and stages in the definition of the game sequence. For example:

const ngc = require('nodegame-client');
const stepRules = ngc.stepRules;

// Stager definition.

stager.extendStep('mystep', {
    stepRule: stepRules.WAIT
});

will force a client to wait for an explicit command to step from the server. This is the default step-rule for players in all steps and it does not need to be specified.

If you would like the players to step automatically when node.done() is called you should specify the SOLO step-rule.

// Stager definition.

stager.extendStep('mystep', {
    stepRule: stepRules.SOLO
});

The default step-rule of the logic is OTHERS_SYNC_STEP, that is waiting for all the connected players to have finished the current step; when this happens the logic steps and sends the message to synchronously step to all connected players.

Default Step Rules

(in refactor, it may change in next release.)

General rules

These rules can be applied to any client:

  • WAIT: waits for a message from server to step.
  • SOLO: advances freely through the steps, regardless of other connected players.

Rules that require knowledge of the state of the game

These rules can be applied to the logic, or to players if the channel is configured to send player updates (see example below).

  • OTHERS_SYNC_STEP: waits for all players to finish the current step.
  • OTHERS_SYNC_STAGE: waits for all players to finish the current stage. Note: you still need to break stage, see example below.
  • SYNC_STEP: waits for all players (including the client itself) to have terminated the current step.
  • SYNC_STAGE: waits for all players (including the client itself) to have terminated the last step of current stage.

Custom step-rules

A step-rule function must return TRUE to make the client enter the next step, or FALSE to make the client wait. It accept four input parameters:

  • step {object} The current game step
  • stageLevel {number} The current stage level (100 = DONE)
  • pl {PlayerList} A reference to the list of connected players
  • game {Game} A reference to the whole game object

For example:

function myStepRule(step, myStageLevel, pl, game) {
   if (myStageLevel !== node.constants.stageLevels.DONE) return false;
   if (!pl.isStepDone(step)) return false;
   return true;
}

returns TRUE only if the client itself and all other connected players are DONE.

Examples

Single/concurrent game play

To create a game in which players play independently from each other (for instance a labeling task), simply add the line below to both player.js and logic.js:

// Set the default step rule for all the stages.
// Assuming you have at the top: const ngc = require('nodegame-client');
stager.setDefaultStepRule(ngc.stepRules.SOLO);

The players will now step freely through the game steps, while the logic remain on the first stage (1.1-1).

These settings may require to adjust your code. In the logic, you should insert all your event listeners in the init function of the game, while in the player you may use node.say to signal specific game events (for instance, game ends).

The logic can listen to individual players changing steps with the following listener:

node.on.data('done', function(msg) {
    console.log('Client ' + msg.from + ' finished stage ' + msg.stage);
});

In addition, you should disable the wait screen on players (because they are not waiting for other players):

// Inside the init function of player.js
W.init({ waitScreen: false });

Sometimes in single-player games, you may want to create just one logic for all clients. If so, add this option to the waitroom.setings.js file:

DISPATCH_TO_SAME_ROOM: true

Single/concurrent game play in one stage only.

Say you have a stage with three steps:

In player.js:

    stager.extendStep('step1', {
        stepRule: stepRules.SOLO,
    });

    stager.extendStep('step2', {
        stepRule: stepRules.SOLO,
    });

    stager.extendStep('step3', {
        stepRule: stepRules.WAIT,
    });

In logic.js

    stager.extendStep('step1', {
        stepRule: stepRules.OTHERS_SYNC_STAGE,
        cb: function() {
            // Prevents to go to next step, instead goes to next stage.
            node.game.breakStage(true);
        }
    });

Decentralized synchronization

In logic.js, disable synchronization and set default step rule to SOLO.

   const ngc = require('nodegame-client');
   const stepRules = ngc.stepRules;
   
   stager.setDefaultProperty('syncStepping', false);

   stager.setDefaultStepRule(stepRules.SOLO);

In channel/channel.settings.js, update settings to notify players of connections and change of state by other players.

    notify: {

        // When a player connects / disconnects.
        onConnect: true,

        // When a player changes a stage / step.
        onStageUpdate: true,

        // When the 'LOADED' stageLevel is fired (useful to sync players)
        onStageLoadedUpdate: true,

        // When any change of stageLevel happens (e.g. INIT, CALLBACK_EXECUTED)
        // Notice: generates a lot of overhead of messages.
        onStageLevelUpdate: false,

    }

In player.js, pick the relevant step rules for each step/stage:

   const ngc = require('nodegame-client');
   const stepRules = ngc.stepRules;
   
   stager.setDefaultStepRule(stepRules.SYNC_STEP);

Sources

Go Back to

⚠️ **GitHub.com Fallback** ⚠️