# (async, static) join(parameters) → {Promise}

Join a Croquet session.

Joins a session by instantiating the root model (for a new session) or resuming from a snapshot, then constructs the view root instance.

The appId identifies each Croquet app. It must be a globally unique identifier following the Android convention, e.g. "com.example.myapp". Each dot-separated segment must start with a letter, and only letters, digits, and underscores are allowed.

The session name identifies individual sessions within an app. You can use it for example to create different sessions for different users. That is, a user in session "ABC" will not see a user in "DEF". One simple way to create unique sessions is via Croquet.App.autoSession() which will use or generate a random name in the query part (?...) of the current url. (If you use a constant, then all users will end up in the same session. This is what we do in some of our tutorials for simplicity, but actual apps should manage sessions.)

The session password is used for end-to-end encryption of all data leaving the client. If your app does not need to protect user data, you will still have to provide a constant dummy password. One simple way to have individual passwords is via Croquet.App.autoPassword() which will use or generate a random password in the hash part (#...) of the current url.

A session id is created from the given session name, and a hash of all the registered Model classes and Constants. This ensures that only users running the exact same source code end up in the same session, which is a prerequisite for perfectly replicated computation.

The session id is used to connect to a reflector. If there is no ongoing session, an instance of the model class is created (which in turn typically creates a number of submodels). Otherwise, the previously stored modelRoot is deserialized from the snapshot, along with all additional models.

That root model instance is passed to the constructor of your root view class. The root view should set up the input and output operations of your application, and create any additional views as to match the application state as found in the models.

Then the Croquet main loop is started (unless you pass in a step: "manual" parameter, e.g. for WebXR, see example below). This uses requestAnimationFrame() for continuous updating. Each step of the main loop executes in three phases:

  1. Simulation: the models execute the events received via the reflector, and the future messages up to the latest time stamp received from the reflector. The events generated in this phase are put in a queue for the views to consume.
  2. Event Processing: the queued events are processed by calling the view's event handlers. The views typically use these events to modify some view state, e.g. moving a DOM element or setting some attribute of a Three.js object.
  3. Updating/Rendering: The view root's update() method is called after all the queued events have been processed. In some applications, the update method will do nothing (e.g. DOM elements are rendered after returning control to the browser). When using other UI frameworks (e.g. Three.js), this is the place to perform the actual rendering. Also, polling input and other tasks that should happen in every frame should be placed here.
Name Type Description
parameters Object
Name Type Attributes Description
apiKey String

API key (from

appId String

unique application identifier as dot-separated words (e.g. "com.example.myapp")

name String

a name for this session (e.g. "123abc")

password String

a password for this session (used for end-to-end encryption of messages and snapshots)

model Model

the root Model class for your app

view View <nullable>

the root View class for your app, if any

options Object <nullable>

options passed into the root model's init() function (no default)

step String <nullable>

"auto" (default) for automatic stepping via requestAnimationFrame(), or "manual" to leave it as the application's responsibility to call the session's step() function regularly (see WebXR example below)

tps Number <nullable>

ticks per second generated by reflector when no messages are sent by any user (a value of 1/30 or below will result in one tick every 30s; max 60 per second; default 20)

autoSleep Number | Boolean <nullable>

number of seconds of app being hidden (e.g., in a tab that is behind others) before it should go dormant - disconnecting from the reflector, and staying that way until it is made visible again (0 or false mean the app will never voluntarily go dormant; true means default value of 10s; otherwise any non-negative number)

rejoinLimit Number <nullable>

time in milliseconds until view is destroyed after a disconnection, to allow for short network glitches to be smoothly passed over (default 1000)

eventRateLimit Number <nullable>

maximum number of events (single or bundled) sent to reflector per second (1 to 60; default 20)

debug String | Array.<String>

array, or comma-separated string, containing one or more of the following values to enable console logging of the corresponding details:

value description
"session" session ID and connections/disconnections
"messages" received from reflector, after decryption (cf. encrypted messages visible in a WebSocket debugger)
"sends" sent to reflector, before encryption (cf. encrypted messages visible in a WebSocket debugger)
"snapshot" snapshot stats
"data" data API stats
"hashing" code hashing to derive session ID/persistentId
"subscribe" subscription additions/removals
"classes" class registrations
"ticks" each tick received

Promise that resolves to an object describing the session:

    id,           // session id
    view,         // view instance
    step(time),   // function for "manual" stepping
    leave(),      // function for leaving the session


  • view is an instance of the supplied view class, or of Croquet.View if no view class was given
  • step(time) should be invoked regularly if you selected manual stepping, to nudge it to process the latest events from the reflector or generated internally. The time argument is expected to be in milliseconds, monotonically increasing - for example, the time received by a function passed to window.requestAnimationFrame.
  • leave() is an async function for requesting immediate, permanent disconnection from the session.

auto name, password, and main loop

    apiKey: "your_api_key",                 // paste from
    appId: "com.example.myapp",             // namespace for session names
    name: Croquet.App.autoSession(),        // session via URL arg
    password: Croquet.App.autoPassword(),   // password via URL arg
    model: MyRootModel,
    view: MyRootView,
    debug: ["session"],

manual name, password, and WebXR main loop

Croquet.Session.join({ apiKey: "your_api_key", appId: "com.example.myapp", name: "abc", password: "password", model: MyRootModel, view: MyRootView, step: "manual"}).then(session => {
    function xrAnimFrame(time, xrFrame) {