Skip to main content

Prebuilt GUI Contracts

RPGJS prebuilt GUIs are regular GUI entries registered with fixed IDs. You can replace their visual implementation with your own CanvasEngine component by registering a GUI with the same ID. The server API stays the same. For example, player.showText() still opens rpg-dialog, but your component receives the dialog data and decides how to render it.

Register a Replacement

Create a .ce file and register it with the prebuilt ID you want to replace:
The last component registered for an ID wins. A CanvasEngine replacement removes any Vue entry with the same ID, and a Vue replacement removes the built-in CanvasEngine component. Declare renderer: 'canvas' for .ce registrations; registrations without a renderer still use legacy component-shape detection for compatibility. This page focuses on CanvasEngine .ce replacements; for Vue-specific examples, see Vue.js integration.

Component Interface

CanvasEngine GUI components receive: For example, this CanvasEngine component can replace the built-in dialog box:
Use onFinish() when the server is waiting for a final answer, such as a dialog choice. Use onInteraction() for actions that should keep the GUI open, such as buying an item or equipping gear.

Character Select

Data contains actors, title, subtitle, selectedActorId, and allowCancel. Each Actor presentation contains id, optional name, optional description, and optional graphic and faceset spritesheet IDs. A custom renderer must return an Actor ID from this list; the server ignores unknown IDs and keeps the GUI open. The promise resolves to the original server-owned Actor, not the client payload, and never calls setActor() implicitly.

Input

The prebuilt input GUI renders either an HTML input or textarea. Server-owned validation keeps the GUI open when a submitted value is invalid. Projects can replace the component by registering another GUI with the same ID, but the replacement must use the interactions above so validation still runs on the authoritative server. Data:
An optional empty number and an explicit cancellation both resolve to null. Text, password, email, and textarea inputs resolve to strings. Default button labels and validation errors use rpg.input.* translation keys. Game-level i18n messages can override them; explicit confirmText and cancelText options take precedence for one form.

Dialog Box

Data: To return a choice, call onFinish(index) where index is the selected choice index. For text without choices, call onFinish() when the player dismisses the dialog. For a dialog input, use onInteraction('submit', { value }) and onInteraction('cancel'). This keeps parsing and validation on the server and allows invalid submissions to update input.errorKey without closing the GUI. CanvasEngine example:

Hotbar

Data: Each presentation slot contains index, type, entry, name, description, icon, quantity, cost, badge, usable, cooldownMs, readyAt, activation, locked, and lockedHint when applicable. Empty slots use type: "empty" and entry: null. Interactions: Custom components should render only the received presentation and send these interactions. They must not consume inventory, SP, or apply gameplay effects on the client. For color, spacing, and typography changes, prefer the native hotbar theme variables over a replacement. Data: Interactions: The built-in client also applies optimistic updates for useItem and equipItem. Custom Vue and CanvasEngine replacements can use the same interaction names and still benefit from those reducers.

Shop

Data: ShopItem includes id, name, description, price, icon, type, optional stats, optional quantity, and equipped. Interactions:

Save and Load

Data: Server interactions: The built-in save-load.ce also uses SaveClientService directly for local save/load UI flows. A replacement can use either the server interactions above or its own client service flow, depending on the game architecture.

Title Screen

Data: Interaction:

Game Over

Data: Interaction:

HUD and Notifications

HudComponent and NotificationComponent are also GUI components, but they are less driven by a server payload than the modal GUIs above. HUD data: The HUD reads the current player from the client engine for hp, sp, max values, and level. Notifications use PrebuiltGui.Notification / rpg-notification, but the built-in component reads engine.notificationManager.stack() instead of a direct data payload. Custom notification UIs should use the same notification manager if they need the existing player.showNotification() behavior.