PrismatiXEngine
UI and extensionsPresentation

UI, menus, and TSX authoring

Edit the starter menu, understand Actions and routes, and author native screens with React-free TSX.

繁體中文

1. Edit the existing title screen first

The starter's Content/UI/Title.pxui is a PrismatiXUIScene JSON document containing nodes, a rootId, viewport dimensions, and stable identities. Start with the nodes named Title, Start, and Load. Edit their text, accessibility labels, and layout instead of regenerating every identity in the document.

parentId forms the node tree, order orders siblings, and runtimeType selects a native control. layout follows the engine's layout contract, not browser CSS. The root has a null parentId; keep the root and parent relationships valid when restructuring the screen.

2. Buttons call Actions

The starter Start button uses this onClick descriptor:

{
  "id": "game.start",
  "arguments": {}
}

game.start, save.open, load.open, backlog.open, and settings.open are built-in Actions used by the default Player UI. Reuse them instead of implementing a new save system merely to open the Load screen. onClick contains an Action descriptor, not a JavaScript function or source-code string.

Story commands and UI Actions have separate registration interfaces. An extension's commands are called from Story; its actions are called by UI. Similar names do not make them interchangeable.

3. Routes map to screens

The project's uiEntryPoints maps a route name to its UI source:

{
  "uiEntryPoints": {
    "title": "Content/UI/Title.pxui"
  }
}

This is a merge fragment: preserve other routes. Story can use [ui route=save operation=push]. Extensions expose ctx.ui.push, replace, back, showModal, and closeModal. Stack navigation and modal presentation have different semantics; do not open every screen in the same way.

A new custom route needs a corresponding screen. Registering a transition or an Action does not create a gallery or credits screen automatically.

4. Author the title screen in TSX

TSX is an authoring format, not a React runtime. Keep the original Title.pxui as a backup and create Content/UI/Title.tsx:

/** @jsxImportSource @prismatix/authoring-sdk */
import { Button, Scene, Text, VBox } from '@prismatix/authoring-sdk';

export default (
  <Scene name="First Light Title" width={1280} height={720}>
    <VBox name="Root" fill style={{ background: '#16182AFF' }}>
      <Text name="Heading">First Light</Text>
      <Button name="Start" size={[240, 64]} action="game.start">
        Start game
      </Button>
      <Button name="Load" size={[240, 64]} action="load.open">
        Load progress
      </Button>
    </VBox>
  </Scene>
);

Set uiEntryPoints.title to Content/UI/Title.tsx. Do not register both TSX and JSON sources that produce the same output path. The CLI type-checks and evaluates the default export, then lowers it to canonical .pxui data. The Player does not execute TSX.

prismatix validate my-game
prismatix dev my-game

The module must default-export a Scene/Component value or a function that returns one. HTML elements, React hooks, DOM APIs, and arbitrary CSS are not drop-in equivalents. For reusable components, use the SDK's Component contract and register their source through uiComponents.

5. Bind data instead of duplicating it

SDK Text supports native bindings:

<Text name="Heading" bind={{ text: 'locale.ui.welcome' }}>
  Welcome
</Text>

Add "ui.welcome": "Welcome" to the locale document's strings. The binding is a data path, not arbitrary runtime JavaScript. Custom HUDs should use the native session, choices, backlog, and settings models. Extensions can observe snapshots with APIs such as ctx.session.observeDialogue; see Runtime APIs. Do not rebuild a separate copy of Story state every frame.

6. Route transitions and usability

An extension with runtime and UI capabilities can register a transition:

ctx.ui.setTransition('title', 'hud', {
  preset: 'crossfade',
  durationSeconds: 0.45,
});

Built-in presets are none, fade, crossfade, slide-left, and slide-right. The ctx object comes from the extension tutorial; this code does not belong inside UI JSON. Test input, back navigation, loading, and window closure while transitions are active.

After editing UI, check keyboard focus, accessibility labels, focus order, larger text, long translations, returning from Save/Load, and closing modals. Compilation establishes valid data, not a usable or unclipped layout.

Build-time trust boundary

The CLI evaluates TSX modules in Node.js. Build only projects and dependencies you trust. The QuickJS runtime sandbox does not make arbitrary build-time code safe.

Sources: Starter Title, TSX example, CLI TSX loading, Runtime SDK.

On this page