Step Callback Functions v7 - nodeGame/nodegame GitHub Wiki

Overview

The step callback is defined in the cb (callback) step property. The step callback is executed after the step has been initialized and its frame (if one is defined) fully loaded. The user cannot interact with the page until the execution of the step callback is finished.

Step callbacks have two purposes:

  • handling user interaction with the page,
  • terminating the step with node.done()

Implementation

As any other step property, the step callback is defined by extending a step of the game sequence using the Stager API.

stager.extendStep('instructions', {
    cb: function() {
        console.log('I am the step callback.');
        console.log('I decide when terminate this step!');
        // The user clicks a button with id "read" when he/she finished
        // reading the instructions page and we proceed to the next step.
        var button = W.gid('read');
        button.onclick = function() {
            node.done();
        };
    }
});

Handling user interaction

In a step callback the game developer usually makes use of the Window API to handle the interaction of the user with the page and of the Client API to exchange game messages and perform other game-related tasks.

Note: Compared to Stager API, which begins with stager, the Window API begins with W. The Stager is used to create the game sequence before the game starts, while the Window is used to manipulate the page when the game is running. Notice that the Stager API accepts callbacks which may contain other APIs, but they are not executed at the time in which they are created, only later. On the browser, nodeGame runs through the stages defined by the Stager API and executes all callback functions and, for instance, Window commands.

The API is available through the following objects:

  • node: it is the higher-level container of all operations. Contains methods to connect/disconnect from a server, send and receive messages, and a reference to the prototypes of all nodeGame classes.
  • node.game: it is the context of execution of the step callback functions (in other words, the this reference is a pointer to node.game). Contains the memory database and the player list and methods to control the flow of the game.
  • node.window (shortcut W): it is available when the step callback is executed in the browser and it exposes methods to manipulate the browser's window.
  • node.widgets: contains methods to load and manage widgets (some widgets are available only in the browser).
  • node.timer: contains methods to set timers and emit random events.

Summary of the most common API operations

  • Sending game messages:
    // node.say

    // Sends a message labeled 'Hello!' to the game room's logic.
    node.say('Hello!');
    // Send a message labeled 'offer' to a certain receiver,
    // with a data value equal to 100.
    node.say('offer', receiverId, 100);
  • Registering event listeners:
   // node.on.data

   // Listens to incoming message of type 'data'
   // For example, node.say sends messages of type 'data'.

   node.on.data('Hello!', function(msg) {
       console.log('Somebody says hello: ', msg.from);
   });   

   // node.on

   // Listens to local events

   node.on('TIMEUP', function() {
       console.log('The timer expired.');
   });

Important! An event listener registered inside a step callback function catches events generated in the same step. More details here.

  • Setting a timer:
   // Creates a timer that will emit after 10 seconds
   // the local event 'TIMEUP'.
   var timer = node.timer.createTimer(10000);
   timer.start();
  • Accessing the game dataset (usually on the logic client type):
   // Select all offers greater than 10.
   var db = node.game.memory.select('offer', '>' 10).fetch();
  • Accessing the list of connected (on the logic client type):
   // Sends a message to all connected players.
   node.game.pl.each(function(p) {
       node.say('Hi!', p.id);
   });

Terminating the step: the node.done() procedure

After calling node.done() the following steps are evaluated:

  1. If defined, the done callback is triggered. If not, go to step 2. The done callback can modify the parameters passed to node.done() or prevent the step from terminating, if conditions are not satisfied. The done callback is defined as a step property:
stager.extendStep('mystep', {
    // Done callback.
    done: function(data) {
        var value = data.offer;

        // In this example, value is equal to 10 (see the cb function).
        if (value < 0) {
            // Return false to prevent the step from ending.
            alert('Negative values not allowed');
            return false;
        }
        if (value < 10) {
            // Modify the return value if needed.
            return data.offer = value * 2;
        }
        // Do nothing to keep value as it is.
    },
    // Step callback.
    cb: function() {
        // User actions omitted.
        node.done({ offer: 10 });
    }
});
  1. If no done callback is defined, or if one is defined and it does not return false, the steps ends.

  2. The parameter passed to node.done() (possibly modified by the done callback) are sent to the server inside a done message (below more details).

  3. The state of the client is marked DONE, and no other action is possible in this step.

  4. Depending on the synchronization rule of the step, the game will enter into the next step or wait for all the players to be done (default).

Done messages

The done message is sent from a client and stored in the internal database of the logic. It contains the parameters passed to node.done() and other important information such as the player id, the time passed within the step, if a timeup event happened, the role and the partner (if any).

// Client side (player.js).
node.done({ offer: 100 });

// Server side (logic.js).
// The message was saved into the memory and can be accessed.
node.game.memory.select('done').first();

{
    // Time from the beginning of the step.
    time: 10313,
    //  Flag indicating if timer for the step expired.
    timeup: false,
    // Flag indicating that this is a DONE message.
    done: true,
    // The role of the player in the step (as assigned by the matcher).
    role: 'BIDDER',
    // The partner of the player in the step (as assigned by the matcher).
    partner: "adaf4b65868hdegdeldkpoij222109",
    // The sender of the message.
    player: "f18a4b6560d145008e6f951154d74d86",
    // The stage when the DONE message created.
    stage: {
                stage: 1,
                step: 1,
                round: 1
            },
    // The parameter passed to node.done
    offer: 100,
    // A unique timestamp when the message was inserted in the database.
    timestamp: 1440000935392
}

Timeup events

If a timer is defined as a step property (or in the settings) when it expires it will invoke the timeup function. The default timeup function invokes node.done() and triggers the procedure above.

Specifying a default callback

Notice that if the callback property (cb) of a step is not defined nor extended, the default callback is applied. The default callback just prints the name of the step and nothing else.

It is possible to overwrite the default callback with a custom one:

stager.setDefaultCallback(function() {
    console.log('I am the new default callback!');
});

The default callback is inserted into all steps that did not define one when the stager gets finalized (when the game runs or by calling stager.getState())

Next Topics

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