Skip to main content

Documentation Index

Fetch the complete documentation index at: https://v5.rpgjs.dev/llms.txt

Use this file to discover all available pages before exploring further.

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:
import { provideClientModules } from '@rpgjs/client'
import { PrebuiltGui } from '@rpgjs/common'
import MyDialog from './gui/my-dialog.ce'

export default {
  providers: [
    provideClientModules([
      {
        gui: [
          {
            id: PrebuiltGui.Dialog,
            component: MyDialog,
          },
        ],
      },
    ]),
  ],
}
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. This page focuses on CanvasEngine .ce replacements; for Vue-specific examples, see Vue.js integration.

Component Interface

CanvasEngine GUI components receive:
PropDescription
dataSignal containing the object sent by the server. Read it with data().
onFinish(value?)Closes the GUI and resolves the server-side promise when the GUI was opened with waitingAction.
onInteraction(name, payload?)Sends an action to the server without closing the GUI.
For example, this CanvasEngine component can replace the built-in dialog box:
<DOMContainer width="100%" height="100%">
  <div class="my-dialog" data-position={position()}>
    @if (speaker()) {
      <strong>{speaker()}</strong>
    }

    <p>{message()}</p>

    @if (choices().length) {
      <div class="choices">
        @for ((choice, index) of choices()) {
          <button click={selectChoice(index)}>
            {choice.text}
          </button>
        }
      </div>
    }
    @else {
      <button click={continueDialog()}>Continue</button>
    }
  </div>
</DOMContainer>

<script>
  import { computed } from "canvasengine";

  const { data, onFinish } = defineProps();

  const message = computed(() => data().message || "");
  const choices = computed(() => data().choices || []);
  const speaker = computed(() => data().speaker || "");
  const position = computed(() => data().position || "bottom");

  function selectChoice(index) {
    return function() {
      onFinish(index);
    };
  }

  function continueDialog() {
    return function() {
      onFinish();
    };
  }
</script>
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.

Dialog Box

ContractValue
IDPrebuiltGui.Dialog / rpg-dialog
Server APIsplayer.showText(), player.showChoices()
Close withonFinish(index?)
Data:
FieldTypeDescription
messagestringText to display.
choices{ text: string }[]Choice labels. The original server-side value is not sent to the client.
position'top', 'middle', or 'bottom'Dialog placement. Defaults to bottom.
fullWidthbooleanWhether the dialog should use the full screen width.
autoClosebooleanWhether the dialog may close automatically.
typewriterEffectbooleanWhether the text should reveal progressively.
speakerstringSpeaker label.
face{ id: string; expression?: string }Faceset spritesheet ID and expression.
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. CanvasEngine example:
<DOMContainer width="100%" height="100%">
  <div class="dialog">
    <p>{data().message}</p>

    @for ((choice, index) of data().choices || []) {
      <button click={selectChoice(index)}>{choice.text}</button>
    }

    @if (!(data().choices || []).length) {
      <button click={closeText()}>Continue</button>
    }
  </div>
</DOMContainer>

<script>
  const { data, onFinish } = defineProps();

  function selectChoice(index) {
    return function() {
      onFinish(index);
    };
  }

  function closeText() {
    return function() {
      onFinish();
    };
  }
</script>
ContractValue
IDPrebuiltGui.MainMenu / rpg-main-menu
Server APIplayer.callMainMenu(options)
Close withonInteraction('exit') or onFinish()
Data:
FieldTypeDescription
menus{ id; label; disabled? }[]Menu entries. Default IDs are items, skills, equip, options, save, exit.
itemsMenuItem[]Inventory entries with id, name, description, quantity, icon, stats, type, usable, equipped.
equipsMenuItem[]Inventory entries whose type is weapon or armor.
skills{ id; name; description; spCost }[]Player skills.
saveLoadobjectSave overlay data, usually { mode: 'save', canSave, showAutoSlot, autoSlotIndex, autoSlotLabel }.
playerStatsobjectCurrent stats such as atk, pdef, sdef, str, dex, int, agi, maxHp, maxSp.
expForNextlevelnumberEXP target for the next level.
Interactions:
InteractionPayloadServer behavior
useItem{ id }Calls player.useItem(id) and refreshes menu data.
equipItem{ id, equip }Calls player.equip(id, equip) and refreshes menu data.
openSavenoneCloses the main menu and opens rpg-save in save mode.
exitnoneCloses the menu and resolves with 'exit'.
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

ContractValue
IDPrebuiltGui.Shop / rpg-shop
Server APIplayer.callShop(options)
Close withonFinish()
Data:
FieldTypeDescription
itemsShopItem[]Items available to buy.
sellItemsShopItem[]Player inventory items available to sell.
playerParamsobjectCurrent player stats used to compare item modifiers.
messagestringMerchant message.
face{ id: string; expression?: string }Merchant faceset.
ShopItem includes id, name, description, price, icon, type, optional stats, optional quantity, and equipped. Interactions:
InteractionPayloadServer behavior
buyItem{ id, nb }Calls player.buyItem(id, nb) and refreshes shop data.
sellItem{ id, nb }Adds gold, removes inventory items, and refreshes shop data.

Save and Load

ContractValue
IDPrebuiltGui.Save / rpg-save
Server APIsplayer.showSave(), player.showLoad(), player.showSaveLoad()
Close withonFinish(index?)
Data:
FieldTypeDescription
slots`(SaveSlotnull)[]`Save metadata without the snapshot field. Empty slots are null.
mode'save' or 'load'Selects save or load behavior.
showAutoSlotbooleanWhether to display an auto-save entry.
autoSlotIndexnumberSlot index used by the auto-save entry.
autoSlotLabelstringLabel for the auto-save entry.
Server interactions:
InteractionPayloadServer behavior
save{ index }Saves into the slot and closes with the selected index.
load{ index }Loads the slot and closes with the selected index.
select{ index }Alias handled according to the current mode.
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

ContractValue
IDPrebuiltGui.TitleScreen / rpg-title-screen
Server APIplayer.gui('rpg-title-screen').open(options) when used from the server
Close withonInteraction('select', selection) or local hide logic
Data:
FieldTypeDescription
entries{ id; label; disabled? }[]Selectable actions. Defaults to start and load.
titlestringMain title.
subtitlestringSubtitle.
versionstringVersion label.
showPressStartbooleanOption reserved by the server contract.
saveLoadobjectData passed to rpg-save when using local load behavior.
localActionsbooleanIf true, built-in title actions hide the title or open save/load locally.
Interaction:
InteractionPayload
select{ id, index, entry }

Game Over

ContractValue
IDPrebuiltGui.Gameover / rpg-gameover
Server APIplayer.callGameover(options)
Close withonInteraction('select', selection) or local hide logic
Data:
FieldTypeDescription
entries{ id; label; disabled? }[]Selectable actions. Defaults to title and load.
titlestringMain title.
subtitlestringSubtitle.
saveLoadobjectData passed to rpg-save when using local load behavior.
localActionsbooleanIf true, built-in actions display the title screen or save/load locally.
Interaction:
InteractionPayload
select{ id, index, entry }

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:
FieldTypeDescription
faceset{ id: string; expression?: string }Optional face displayed next to player status.
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.