Plugins overview
This page explains the plugin concept in Open Play: packages that offer game-specific commands, queries, and realtime modules without adding a game name to the core. Here you see how you connect to a game’s logic beyond the core modules (character, economy, store…) and what is not supported today.
What is a plugin
A plugin is a package that runs inside the Open Play server and defines these three surfaces:
| Surface | What it gives | How it is called |
|---|---|---|
| Command | A state-changing, durable, replay-safe operation (for example claim a reward, complete a delivery) | HTTP POST or the realtime Command frame: calling plugins |
| Query | A read-only read (for example the active delivery, the catalog) | HTTP GET or POST |
| Realtime module | Live input and state broadcast (movement, room, scene) | /v1/realtime/ws: realtime protocol |
Every plugin publishes a schema document (artifact): it describes which commands, queries, and modules exist with which input and output schemas, which identity can call them, and the retry rule. The SDKs’ typed bindings are generated from this document: bindings.
Commands are committed in a single database transaction: the command’s effect, its result, its event, and the replay record are written together or not at all. Realtime transient state, on the other hand, is kept only for speed and is not the authority for durable outcomes such as payment, XP, items, or rewards.
Today’s state: only trusted, compiled plugins
Warning
Loading third-party plugins is not available yet. Plugins are code (Rust) compiled into the Open Play server itself and are considered trusted code. As a game developer you cannot upload your own plugin from the panel or the API; sandboxed execution, resource metering, and signed distribution are a future design and do not work today.
You connect your own game logic today in these ways:
- Rules (the Rules screen in the panel): automations bound to character events. See game rules.
- Webhooks: Open Play notifies your own server of events. See the webhooks guide.
- Your own server + a server key: run your own logic on your own server and call the core REST endpoints. See the endpoint reference.
Plugins that ship in the repository:
| Plugin | Version | What for | Surface |
|---|---|---|---|
package-ride | 1.44.0 | A delivery game: driving, quests, race bets, scene | 36 commands, 33 queries, 3 realtime modules |
arena | 1.0.0 | A minimal example: a single movement module | 0 commands, 0 queries, 1 realtime module |
These come with the server; you can see which ones are enabled in your environment on the Plugins screen in the panel (Plugins).
Per-environment state
A plugin is in a separate state for each environment:
| State | Commands | Queries |
|---|---|---|
Enabled (Enabled) | accepted | accepted |
Read-only (ReadOnly) | rejected | accepted |
Draining (Draining) | new commands rejected, running work finishes | accepted |
Disabled (Disabled) | rejected | rejected |
A rejected call gets 403 and forbidden (errors). The same result is also seen when the plugin version granted to the environment does not match the version on the server: if the server was updated with a new plugin version, the environment’s plugin grant must also be moved to that version. If you get an unexpected 403 forbidden, first look at the plugin’s state and version in the panel.
In addition, if the product module plugins is disabled, all /v1/plugins/... and realtime endpoints return 404 and module_disabled (Game settings: modules).
Access by identity
Every operation has an access value in the schema document:
access | Who calls |
|---|---|
player | The player session (a cookie or a Bearer session token) |
server | Only a server key; not visible in the player client |
public | A GET query that requires no identity (only x-crx-env is needed) |
An unspecified or unknown value falls to the safe side (player). A plugin cannot be called with a client API key embedded in the client: it gets 401. Details: calling plugins.
Next step
- To call commands and queries, see calling plugins.
- To generate a typed client and pin the schema version, see bindings.
- To write a new plugin for your own server, see writing a plugin.