-
Notifications
You must be signed in to change notification settings - Fork 18
Waiting Room v7
- status: complete
- version: 7.x
- follows from: Event Listeners
The waiting room is the component responsible for dispatching new
games when certain criteria are met. It is highly configurable, and
its settings are stored in file waitroom/waitroom.settings.js
.
-
EXECUTION_MODE: (string) The execution mode of the waiting room. Each mode requires different settings, and might interpret the same option in a different way. Available modes:
-
WAIT_FOR_N_PLAYERS
: a new game starts as soon as the desired number of players is connected. -
TIMEOUT
: a date and a time in the future is scheduled (the waiting room still checks whether enough players are connected to start the game). -
WAIT_FOR_DISPATCH
: simply waits indefinitely for a dispatch command from the monitor interface (ideal for Lab experiments).
-
-
POOL_SIZE: (integer|undefined) number of players that must be connected to start a new dispatch. If undefined, it is equal to
GROUP_SIZE
. -
GROUP_SIZE: (integer) When
POOL_SIZE
players are connected, then a group ofGROUP_SIZE
players is formed and moved into a new game room.GROUP_SIZE
must be smaller or equal toPOOL_SIZE
. IfPOOL_SIZE
is larger thanGROUP_SIZE
, then multiple game rooms are be created at the same time. IfPOOL_SIZE
is not an exact multiple ofGROUP_SIZE
, then the players to move inside the new game room/s are randomly selected; those left out continue waiting until conditions for creating new game room are met again. -
CHOSEN_TREATMENT: (string|function|undefined) The name of the treatment to assign to a new game room or one of the following values:
- "treatment_random": a random treatment is chosen.
- "treatment_rotate": treatments are sequentially assigned to new game rooms (see
ROTATION_OFFSET
). - "treatment_latin_square": maximizes randomness in the rotation of treatments (
ROTATION_OFFSET
does not apply). - Undefined defaults to
treatment_random
. - A function that returns the name of the chosen treatment:
function(treatments, roomCounter, groupIdx, dispatchCounter) { // - treatments: array of available treatments. // - roomCounter: total number of room created (it is initialized to // the last created room as loaded in the data folder). // - groupIdx: zero-based group index within same dispatch // (when POOL_SIZE > GROUP_SIZE). // - dispatchCounter: total number of dispatch calls (a dispatch can // send players to an existing room, so it may // differ from roomCounter). return treatments[dispatchCounter % treatments.length]; }
-
ROTATION_OFFSET: (integer > 0) Offsets the rotation when
CHOSEN_TREATMENT
is equal to "treatment_rotate" (Default: 0). -
MAX_WAIT_TIME: (integer|undefined) The maximum number of milliseconds a player is allowed to wait in the waiting room. If set, the player will be disconnected if the timer expires.
-
ON_TIMEOUT: (function) If set, this function will be executed on the clients when the MAX_WAIT_TIME timer expires.
-
ON_TIMEOUT_SERVER: (function) If set, this function will be executed on the server the the MAX_WAIT_TIME timer expires. The context of execution is
WaitingRoom
, and takes as parameter a player object. -
START_DATE: (string|object) Overrides
MAX_WAIT_TIME
. Accepted values are any valid argument toDate
constructor, for example:December 24, 2016 23:59:59
, ornew Date().getTime() + 30000
, -
DISPATCH_TO_SAME_ROOM: (boolean) If TRUE, every new group of players will be added to the same game room -- one per each treatment as returned by
CHOSEN_TREATMENT
. Default, FALSE. Notice: game should be a single-player task, or it must support adding new players while it is running. -
DISCONNECT_IF_NOT_SELECTED: (boolean) If TRUE, it disconnects all clients not selected for a dispatch. (Default: FALSE)
-
PAGE_TITLE: (object) Sets the page title, and optionally adds it at the top of page as well as an H1 element. (Default:
{ title: 'Welcome!', addToBody: true }
) -
ALLOW_PLAY_WITH_BOTS: (boolean) Allows a player to request to start the game immediately with bots. A button is added to the interface. (Default: FALSE)
-
ALLOW_SELECT_TREATMENT: (boolean) Allows a player to select a treatment to start the game. Requires 'ALLOW_PLAY_WITH_BOTS' to be true. A dropdown menu is added to the interface. (Default: FALSE)
-
REMOTE_DISPATCH: (string|object) Redirects participants to a third-party server upon dispatch. If string, it is the redirect address, if object, it takes the following format:
{
// Redirect address.
url: 'https://nodegame.org',
// If TRUE, appends to the redirect address ?t=treatmentName.
addTreatment: true,
// Manipulates the url before remote dispatch. Parameters:
// - url: redirect address after addTreatment is evaluated.
// - treatment: selected treatment.
// - group: array of player ids to dispatch
// - waitRoom: reference to the waitRoom object itself.
preprocess: (url, treatment, group, waitRoom) => {
// Example: adds the group size and the id of all players
// to the redirect address.
let ids = group.join(',');
return url + '&l=' + group.length + '&ids=' + ids;
}
}
All callbacks receive as first parameter the waiting room object itself.
-
ON_OPEN: (function) Callback executed when the waiting room becomes "open". Receives as first parameter the waiting room object itself.
-
ON_CLOSE: (function) Callback executed when the waiting room becomes "close".
-
ON_CONNECT: (function) Callback executed when a client connects. Receives a player object as second parameter.
-
ON_DISCONNECT: (function) Callback executed when a client disconnects. Receives a player object as second parameter.
-
ON_INIT: (function) Callback executed after settings have been parsed.
-
ON_DISPATCH: (function) Callback executed just before starting a new dispatch. Receives the options of the dispatch call as second parameter.
-
ON_DISPATCHED: (function) Callback executed at the end of a dispatch call. Receives the options of the dispatch call as second parameter.
-
ON_FAILED_DISPATCH: (function) Callback executed if a dispatch attempt fails. Receives the options of the dispatch call as second parameter, and an error message as third parameter (when available).
Before every dispatch, all connected clients are pinged to make sure their still responsive.
-
PING_BEFORE_DISPATCH: (boolean) If TRUE, all players are pinged before a dispatch and non-responding clients are disconnected. This option is particularly useful if
POOL_SIZE
is large. Notice: pinging is skipped if mode isWAIT_FOR_N_PLAYERS
andPOOL_SIZE
is 1. (Default: TRUE) -
PING_MAX_REPLY_TIME: (number > 0) The number of milliseconds to wait for a reply from a PING. (Default: 3000)
-
PING_DISPATCH_ANYWAY (boolean): If TRUE, dispatch continues even if disconnections occur during the PING procedure. (Default: FALSE)
-
PLAYER_SORTING: (function) Sorts the order of players before dispatching them. Sorting takes place only if the number of connected players >
GROUP_SIZE
and optionPLAYER_GROUPING
is undefined. Accepted values:- "timesNotSelected": (default) gives priority to players that have not been selected in previous dispatch calls
- undefined: rollback to default choice
- null: no sorting (players are anyway randomly shuffled).
- function: a comparator function implementing a criteria for sorting two objects. E.g:
function timesNotSelected(a, b) { if ((a.timesNotSelected || 0) < b.timesNotSelected) { return -1; } else if ((a.timesNotSelected || 0) > b.timesNotSelected) { return 1; } return 0; }
-
PLAYER_GROUPING: (function) Creates groups of players to be assigned to treatments. This method is alternative to "sorting" and will be invoked only if the number of connected players >
GROUP_SIZE
. For example:function(playerList, groupsRequired) { return [ [ pl1, pl2 ] [ pl3, pl4 ] ]; }
-
blinkTitle: Shown in the browser tab to signal the beginning of the game. False will not blink.
-
waitingForConf: Text displayed while waiting to receive configuration data from server (usually users cannot see this text).
-
executionMode: Shows a text explaining what is going on, depending on the execution mode of the widget.
-
disconnect: Shown when a player is disconnected.
-
waitedTooLong: Shown when the countdown (if defined) expired.
-
notEnoughPlayers: Shown when there are not enough players to start a game.
-
roomClosed: Shown when a player tries to connect, but the waiting room has been already closed
-
tooManyPlayers: Shown temporarily if there are more players than needed by the game.
-
notSelectedClosed: Shown when a game has just stated and a player has not been selected, and he or she cannot participate in other games.
-
notSelectedOpen: Shown when a game has just stated and a player has not been selected, but he or she can still participate in other games.
-
exitCode: Shown when a player has been disconnected, and an exit code might have been provided.
-
playBot: Shown on the button to start the game when option
ALLOW_PLAY_WITH_BOT
is true. -
connectingBots: Shown immediately after the button to start a game is pressed, and stays visible until a new game starts or the wait timeout expires.
-
selectTreatment: Shown as default text of the dropdown menu to select a treatment to begin a new game when option
ALLOW_SELECT_TREATMENT
is true. -
gameTreatments: Shown inside the dropdown menu for treatments that are user-defined.
-
defaultTreatments: Shown inside the dropdown menu for treatments that are common for all games (e.g. 'treatment_rotate').
- dispatch: Notifies players that a game is about to be dispatched
-
logicPath: (string) The path to a custom implementation of the wait room logic.
-
NOTIFY_INTERVAL: (integer > 0) The number of milliseconds to wait to updates to connected clients (Default: 200).
Listening to the waiting room events allows for dynamically changing the waiting room settings. For instance, it is possible to rotate the group size of dispatches or to make the group size treatment-dependent.
This solution is ideal for online experiments because everything is automatized.
EXECUTION_MODE: 'WAIT_FOR_N_PLAYERS',
GROUP_SIZE: 1,
// Here the waiting room starts new treatments sequentially
// with group size 1,2,3,1,2,3....
ON_DISPATCHED: function(waitRoom, dispatchParam) {
// Note: the rotation starts after the first dispatch.
// GROUP_SIZE should be equal to 1 in the main settings.
let sizes = [ 1, 2, 3 ];
let newSizeIdx = waitRoom.numberOfDispatches % sizes.length;
let newSize = sizes[newSizeIdx];
this.GROUP_SIZE = newSize;
this.POOL_SIZE = newSize;
},
Ideal for Lab experiments and testing.
EXECUTION_MODE: 'WAIT_FOR_DISPATCH',
// Here we adjust the group size based on the treatment.
ON_DISPATCH: function(waitRoom, dispatchParam) {
// Treatment chosen by waiting room.
let t = dispatchParam.chosenTreatment;
// Use the treatment variable to control the group size.
if (t === 'no_group') dispatchParam.groupSize = 1;
else if (t === 'small_group') dispatchParam.groupSize = 4;
else if (t === 'large_group') dispatchParam.groupSize = 6;
// Only one group dispatched at the time
// (if not set, as many groups as possible will be dispatched).
dispatchParam.numberOfGames = 1;
// Print updated dispatch parameters.
console.log(dispatchParam);
},
To dispatch, open the Monitor interface, select the waiting room in the Clients pane at the center of the screen.
Underneath the Clients pane, the Waiting Room tile will show up; if you have enough participants connected, select a treatment from the dropdown menu and click on "Dispatch Now".
Optionally, you can adjust the texts of participants not selected by the dispatch using these TEXTS
options:
TEXTS: {
tooManyPlayers: 'Please be patient.',
notSelectedClosed: 'Sorry, you will play next time',
notSelectedOpen: 'Please wait you will play soon',
}
Go back to the wiki Home.
Copyright (C) 2021 Stefano Balietti
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.