UI
The engine’s UI primitives are the only way to draw text, panels, buttons, bars, pictures and controls, each with the house look built in. A raw HTML element inside a game is a lint finding. A game overrides through a variant the engine defines or a className that shows in the diff, and passes a colour, a size or a place that comes from data, such as an item’s rarity colour, as a style on Text, Button, Panel, Image or Slider.
The set: Hud, Panel, Modal, Window; Text, Heading, Bar, Counter, Icon, Image; Button, Joystick, Tap, ActionBar; Draggable and DropTarget; Slider, NumberField, TextField, Select and Toggle; FloatingText, Billboard. The menus, the loading screen, a Bar, an accent or pane Button and the other coloured parts draw from the theme tokens, which a game sets once in its stylesheet or takes from a shipped theme; a primitive’s parts take a class each.
Each one has a story in the Storybook.
What stays a game’s own
Section titled “What stays a game’s own”A few kinds of UI have no primitive, and a game draws them as raw elements behind an eslint-disable-next-line no-restricted-syntax that says why:
- A cell that double-clicks or shows a tooltip on hover, which Button’s press does not cover.
- A tooltip placed by its measured height.
- A bar, a cell or a shade written through a ref each frame rather than rendered; Bar takes a value.
- A stick that floats where the finger lands; Joystick stands in a slot.
- A canvas the game draws on each frame, such as a minimap.
- A colour picker.
- An empty decorative box, where Text needs words.
Where UI sits
Section titled “Where UI sits”UI sits at any level and the engine hoists it to the screen. The level decides what it reads and how long it lives; see the table. This page is the one that cuts across levels, because Panel appears at every one.
A Panel names a slot and an order, never a position. Slots are the four corners, four edges and centre; each stacks its children, so overlap is impossible. A Hud carries a slot Panel to the screen from any level. A Panel with anchor follows its entity in the world.
Window
Section titled “Window”A Window is a bag, a character sheet or a shop: several open at once over the game, which keeps playing. It opens in a slot, and the player moves it by its title bar.
A Modal draws over the whole screen, from any level. The engine keeps one modal stack and the top one draws, so two chests open at once show one, then the other. A modal pauses the world only when it passes pause.
The engine re-exports nothing from three. A game that needs it imports from @spawnite/engine/three, so the MCP and a lint rule see every place a game went under the engine.
Outside a game
Section titled “Outside a game”A game imports the primitives from @spawnite/engine. An app outside a game, or a design system that wraps the primitives in its own look, imports from @spawnite/ui:
@spawnite/uiexports the components and the motion, withpalette,gripPointer,PointerGripOptionsandtrackPageHide. Import@spawnite/ui/styles.cssonce in the application.@spawnite/ui/controlsexportsSlider,NumberField,TextField,SelectandTogglewithout the stylesheet, for a design system that wraps them in its own look.@spawnite/ui/motionexports the shared timing without the stylesheet:springs,tapandpress, andsettleEase, a quick start that settles, for a tween’stransition.ease.@spawnite/ui/tooltipexportsTooltipwithout the stylesheet.@spawnite/ui/brandexports the brand marks without the stylesheet.
Tooltip is the behaviour of a tooltip with no look of its own: a short delay, then at once for the next control along a row, a portal, placement inside the screen’s edges, reduced motion, and a press that toggles it on a phone. A design system wraps it and passes its look as className, as the devtools do.
Devtools panel
Section titled “Devtools panel”A component declares what the debugger shows for its entity with useDevtoolsPanel: readouts, fields and buttons, which the devtools draw in the inspector and over a pinned entity in the world.
The samples on Game, Scene, World and Entity show a Panel at each level and a Modal inside an entity.