@disko-game/room
The Node room-host API, generated from the package declarations.
@disko-game/room exports the classes Room, Player and DiskoError and
the types below. It runs on Node.js 22 or later, as ESM only, with a prebuilt
native addon for seven platforms. The guides start at
Room.launch & options.
Classes
Room
A hosted room. Launch one with Room.launch. Properties are read-only and always current: they are updated before the event that reports a change is delivered. Every method returns a Promise that settles when the engine applied the command; commands on one room apply in call order.
| Member | Description |
|---|---|
permissions | room.permissions: resolvers of the game's permissions. |
actions | room.actions: Room management player and room actions. |
options | room.options: Room management option rows. |
bans | room.bans: the room's bans. |
static launch() | Launches a room: validates the options, binds the WebTransport endpoint, loads the initial game into Ready, fetches the master's ticket verification key, and registers the hosting lease. Any failure rejects with a DiskoError and releases every resource. A room never appears in discovery without a loaded game. |
id | 32 lowercase hex digits. |
url | The public WebTransport URL. |
link | <play>/?room=<id>, shareable. |
state | Lifecycle state. |
game | The loaded game and the permissions it declares. |
players | Connected players, including spectators, in join order. |
name | The advertised name. |
description | The advertised description. |
public | Listed in the directory. |
guests | Admits players without an account. |
location | Declared coordinates, or null. |
capacity | Admitted players. |
on() | Subscribes to a built-in event or a game event game:<name>. Handlers run on the main thread in subscription order. Unknown built-in names throw a TypeError. |
off() | Removes one subscription. |
load() | Replaces the game. Resolves once the new game is Ready; players stay connected and the new game starts fresh. On failure the previous game keeps running. |
start() | Starts a fresh game instance. Resolves when Running. |
stop() | Stops the game. Resolves when Ready. A faulted game recovers fresh. |
pause() | Holds the running game at its current boundary. |
resume() | Continues the paused game. |
send() | Sends a visible message: text from the room, or { author?, content, sound? }. Resolves with the message identity. |
emit() | Sends an event to the game, delivered on its next eligible turn. Resolves when queued. payload must be JSON-serializable. |
setName() | Replaces the advertised name. |
setDescription() | Replaces the advertised description; "" clears it. |
setPublic() | Lists or unlists the room. Direct links keep working. |
setGuests() | Admits or refuses new guests. Connected guests stay. |
setLocation() | Declares coordinates, or clears them with null. |
close() | Closes the room: stops accepting players and disconnects everyone with the reason, releases the directory lease, stops the engine, then emits close. Idempotent; never rejects. |
DiskoError
Every rejection of the room-host API. code is stable; the message is human text that is not a stable contract.
| Member | Description |
|---|---|
code | Stable error code. |
problems | Problems, for game_invalid and game_build_failed. |
Player
A player connected to the room, including spectators. A player object belongs to one connection: after leaving, connected is false and a returning person is a new player.
| Member | Description |
|---|---|
id | Stable for the connection. |
account | An opaque account id, or null for guests. |
isOwner | Signed in with the account that owns the room. Guests never are. |
name | Resolved under the loaded game's name policy. |
connected | false after the player left or was disconnected. |
play() | Asks the game to make this player a participant. |
spectate() | Moves this player to the spectators. |
setPresentation() | Sets how clients render this player's name: in the player list, the player detail view, chat and ui.playerName. |
kick() | Disconnects this player, showing them the reason. They may rejoin. |
ban() | Bans this player for the room's lifetime and disconnects them. Signed-in players are banned by account, guests by an engine-held network identity the room never sees. |
Room policy
room.permissions
room.permissions: resolvers of the game's permissions.
| Member | Description |
|---|---|
resolve | Registers a resolver for one permission name, or, without a name, for every permission the loaded game declares. A named resolver takes precedence. Registering again replaces it. |
remove | Removes the resolver of one name, or the catch-all without a name. |
refresh | Marks decisions stale so resolvers are asked again, after the room's own facts changed. Omitted fields mean every player or permission. |
room.actions
room.actions: Room management player and room actions.
| Member | Description |
|---|---|
player | Defines or replaces a player action. |
room | Defines or replaces a room action. |
remove | Removes an action. |
refresh | Asks visible again after the room's facts changed. |
room.options
room.options: Room management option rows.
| Member | Description |
|---|---|
toggle | A label and a toggle. |
choice | A label and one of a closed set of choices. |
number | A label and a bounded number. |
text | A label and bounded text. |
set | Sets an option's value; every viewer sees it live. |
remove | Removes an option. |
room.bans
room.bans: the room's bans.
| Member | Description |
|---|---|
list | The current bans. |
import | Restores a ban from the sealed export of this room. |
Types
ChatRequestEvent
Payload of chat-request. Nothing is shown unless the room sends it.
| Member | Description |
|---|---|
id | Room-assigned request identity. |
player | The sender. |
text | Plain text. |
CloseEvent
Payload of close.
| Member | Description |
|---|---|
reason | The given reason, "controller_overloaded" when the event queue filled, or "engine_error" after a native engine failure. |
CloseOptions
Options of Room.close.
| Member | Description |
|---|---|
reason | Shown to players and reported in close. Default "closed". |
DirectoryEvent
Payload of directory.
| Member | Description |
|---|---|
status | After "rejected" the room keeps running but is no longer advertised or joinable through the directory. |
error | Why a publication failed. |
GameEventName
A game event: game:<name> from game.emit(<name>, payload).
GameFaultEvent
Payload of game-fault. The room keeps serving players and chat.
| Member | Description |
|---|---|
message | The error message. |
stack | The stack, in package paths. |
phase | "start", "tick" or "event". |
GameInfo
The loaded game.
| Member | Description |
|---|---|
reference | "ns/slug@version" of a registry release, or null. |
path | The absolute path of a local game, or null. |
digest | blake3:<hex>: exactly what the room runs. |
GameLoadedEvent
Payload of game-loaded.
| Member | Description |
|---|---|
deprecation | A deprecated release's notice, or null. |
Handler
An event handler. It may be async; the room never waits for it, and it never catches its errors.
JsonValue
A JSON value, frozen.
LoadedGame
The loaded game and the permissions it declares.
| Member | Description |
|---|---|
permissions | Permissions the game declares, in declaration order. |
LoadOptions
Options of Room.load.
| Member | Description |
|---|---|
players | The new game's name policy. |
Message
A structured room message.
| Member | Description |
|---|---|
author | A connected player, or omitted for the room. |
content | Text, or 1-32 spans; at most 2048 bytes of text. |
sound | Default "normal". |
PlayerEvent
Payload of player-join and player-leave.
RoomEvents
Built-in events and their payloads.
RoomState
Lifecycle state of a room.
StateEvent
Payload of state.
| Member | Description |
|---|---|
reason | "finished", "stopped" or "fault" where it applies. |
DiskoErrorCode
Stable error codes of the room-host API.
invalid_option: a badlaunchoption or setter value; the message names it. -invalid_state: a lifecycle method called in the wrong state. -invalid_message: a badsendargument. -invalid_event: a bademitargument. -unauthorized: disko-master rejected the room id or token. -game_not_found: an unknown release, or a private release without access. -game_removed: a release that was taken down. -game_invalid: the game failed the release checks; seeproblems. -game_build_failed: a local project failed to build; seeproblems. -game_start_failed: the game script threw during top-level evaluation or exceeded its startup limits; the message includes the stack. -registry_unavailable: the registry or disko-master could not be reached, or another instance's hosting lease stayed live forleaseSecondsplus a margin whilelaunchwaited for it. -listen_failed: the address is in use or not bindable. -certificate_invalid: the certificate or key did not parse or match. -closed: the room is closed.
DiskoErrorOptions
Options of the DiskoError constructor.
| Member | Description |
|---|---|
problems | Release-check or build problems. |
cause | The underlying error. |
Problem
One build or validation problem, in the shape shared by the CLI, the registry and room hosts.
code is stable. message is human text that states the fix; it is not a stable contract. line and column are 1-based and present only for source positions (columns count UTF-16 code units).
| Member | Description |
|---|---|
code | Stable machine-readable code, for example import_unresolved. |
path | Project or package path the problem concerns. |
line | 1-based line. |
column | 1-based column in UTF-16 code units. |
message | What is wrong and how to fix it. |
docs | The documentation page for code. |
BanOptions
Options of Player.ban.
| Member | Description |
|---|---|
reason | Shown to the player, at most 256 UTF-8 bytes. |
PlayerColor
Palette roles a room may give a player's name.
Presentation
Room-set presentation of a player's name. null clears a field.
| Member | Description |
|---|---|
color | A client palette role, never an arbitrary color. |
badge | One short label, at most 12 characters, for example "Admin". |
ActionConfirm
A confirmation before an action runs: true asks to confirm, and { reason: true } also offers one optional text field, such as "Reason".
ActionRefresh
Options of room.actions.refresh.
| Member | Description |
|---|---|
viewer | Only this viewer; omitted, every viewer. |
BanEntry
An opaque ban entry. It never contains an address or an account.
| Member | Description |
|---|---|
id | Identity for this room's lifetime. |
kind | "account" or "guest". |
name | The player's name at ban time. |
reason | The ban reason. |
sealed | A sealed export: store it and pass it to room.bans.import after a restart of the same room to restore the ban. |
lift() | Lifts this ban. |
ChoiceOptionDefinition
A choice option row.
| Member | Description |
|---|---|
choices | 1-32 distinct choices. |
NumberOptionDefinition
A number option row.
| Member | Description |
|---|---|
min | Inclusive minimum. |
max | Inclusive maximum. |
step | Optional positive step from the minimum. |
OptionChoice
A choice of a choice option.
| Member | Description |
|---|---|
value | Submitted value, 1-32 UTF-8 bytes. |
label | Displayed label. |
OptionContext
What visible and editable of an option receive.
| Member | Description |
|---|---|
viewer | The player viewing the Room management modal. |
OptionDefinition
Fields every option row shares.
| Member | Description |
|---|---|
label | Row label, 1-48 UTF-8 bytes. |
value | The current value. |
visible | Which viewers see the row. Omitted: everyone. |
editable | Which viewers may change the value. Omitted: nobody; a visible row that is not editable shows its value read-only. |
change | Accepts a viewer's change after visible and editable are checked again. Throwing rejects it: the row keeps its value and the viewer sees the error message. Every viewer sees an accepted value live. |
PermissionDeclaration
A permission a game declares.
| Member | Description |
|---|---|
name | The game's name for it, for example "manage-match". |
label | A human label for room owners. |
default | The game's decision when the room makes none. |
PermissionRequest
What a permission resolver receives.
| Member | Description |
|---|---|
player | The player the decision is for. |
permission | The permission being decided. |
game | Every permission the loaded game declares. |
PermissionResolver
Decides one permission for one player: true grants it, false denies it, and undefined keeps the game's default. It may be async. Errors are not caught (they reach Node's uncaughtException), and the game's default applies to that decision.
PlayerActionContext
What visible of a player action receives.
| Member | Description |
|---|---|
viewer | The player viewing the Room management modal. |
target | The player whose detail view lists the action. |
PlayerActionDefinition
A player action, shown in a player's detail view.
| Member | Description |
|---|---|
label | Button label, 1-48 UTF-8 bytes. |
confirm | Optional confirmation. |
visible | Which viewers see the action for which targets. Omitted: everyone. |
run | Runs the action after visible is checked again. Throwing rejects it, and the error message is shown to the viewer. |
RoomActionContext
What visible of a room action receives.
| Member | Description |
|---|---|
viewer | The player viewing the Room management modal. |
RoomActionDefinition
A room action, shown in the Actions section.
| Member | Description |
|---|---|
label | Button label, 1-48 UTF-8 bytes. |
confirm | Optional confirmation. |
visible | Which viewers see the action. Omitted: everyone. |
run | Runs the action after visible is checked again. Throwing rejects it, and the error message is shown to the viewer. |
TextOptionDefinition
A text option row.
| Member | Description |
|---|---|
maxLength | Maximum UTF-8 bytes, at most 128. |
secret | The value is never delivered to viewers. |
MessageSound
Whole-message sound category the client plays.
MessageSpan
One styled substring of a room message.
| Member | Description |
|---|---|
text | Non-empty text. |
color | #rrggbb or #rrggbbaa. |
weight | Suggested weight. Default "normal". |
style | Suggested style. Default "normal". |
Certificate
A certificate identity as PEM strings, not file paths.
| Member | Description |
|---|---|
certificatePem | The certificate chain, leaf first. |
privateKeyPem | The PKCS#8 private key of the leaf certificate. |
Endpoints
Base URLs of the disko services. Local development passes *.localhost.
| Member | Description |
|---|---|
api | disko-master API host. Default https://api.disko.ooo. |
registry | Registry host. Default https://registry.disko.ooo. |
play | Web client, for room links. Default https://play.disko.ooo. |
GameSource
A game to load: a release reference, or a local directory or .tgz.
HostOptions
The launch options a host function receives from disko dev or its own entry point: credentials, the game, and the network options. The host function passes them through to Room.launch.
LaunchOptions
Options of Room.launch. Unknown keys reject with invalid_option.
| Member | Description |
|---|---|
id | 32 lowercase hex digits: a room identity from the Creator Portal, or a test room. |
token | The room's hosting token. It is never logged, never exposed on the Room, and sent only to disko-master. |
name | 1-96 UTF-8 bytes, not blank, no control characters. |
game | "ns/slug@version", or { path } of a local directory or .tgz. |
players | The name policy of the initial game. |
description | At most 1024 UTF-8 bytes. Default "". |
public | Listed in the directory. Default true. Test rooms are never listed. |
guests | Admit players without an account. Default true. |
location | Declared coordinates, or null. Default null. |
password | 1-4096 UTF-8 bytes, or null for no password. Default null. |
capacity | Admitted players, 1-65535. Default 64. |
listen | UDP/HTTP3 bind address. Default "0.0.0.0:4433". Only when omitted, a taken port falls back to the next free one up to 4532. An explicit port is used exactly; port 0 picks a random free port. |
publicUrl | The WebTransport URL players connect to. Derived when omitted: from the bound address when listen names a host, otherwise from the address disko-master observes for this host. |
transportPath | WebTransport request path. Default "/room". |
certificate | A certificate chain and key. Without it the room uses a self-signed ECDSA P-256 certificate valid for 13 days, rotated every 6 days. |
endpoints | Service base URLs. Default: the production hosts. |
cacheDir | The release cache, keyed by digest. Default: the OS cache directory + /disko-game/releases. |
leaseSeconds | Directory lease duration, 5-300 seconds. Default 30. |
logging | Native engine logging. |
limits | Resource limit overrides. |
Limits
Resource limits; omitted fields keep the server defaults.
| Member | Description |
|---|---|
pendingHandshakes | Connections allowed while admission is pending. Default 64. |
streamBootstrapTimeoutMs | Deadline for a player's first control stream. Default 5000. |
mailbox | Room mailbox entries. Default 256. |
inboundQueueFrames | Decoded frames staged per player. Default 128. |
inboundFramesPerSecond | Sustained frames per second per player. Default 240. |
inboundFrameBurst | Frame burst per player. Default 480. |
resumeRetained | Interrupted sessions kept for resume. Default 64. |
resumeGraceMs | Resume window. Default 15000. |
checkpointChunkBytes | Checkpoint chunk payload bytes. Default 16384. |
eventQueue | Events waiting for the main thread. When full, chat requests get a retryable backpressure answer and any other event closes the room with controller_overloaded. Default 4096. |
Location
Declared coordinates, used only for directory distance sorting.
| Member | Description |
|---|---|
latitude | Degrees, within ±90. |
longitude | Degrees, within ±180. |
LoggingOptions
Native engine logging.
| Member | Description |
|---|---|
filter | A tracing filter. disko names every engine target. Default "disko=info". Logging is process-wide: the first room to launch installs it. |
format | "pretty" (the default) or "json". Records go to stderr. |
PlayersOptions
How a game names players.
| Member | Description |
|---|---|
name | "display" (the default) uses the account's display name, or a guest's chosen name. "username" uses the verified username; guests keep their chosen name. |