Skip to main content
forge-ui is the client-side UI layer every screen is built on. It manages WebUI views (HTML/CSS/JS pages), routes messages between Lua and the page, owns an input-mode stack so screens cooperate over mouse/keyboard capture, and provides toasts and a HUD mount. UI is client-side. You call these exports from your package’s client scripts.

Views

A view is a WebUI page you create, show, message, and destroy.
ExportSignature
CreateViewCreateView(id, url, opts)
DestroyViewDestroyView(id)
ShowView / HideViewShowView(id) / HideView(id)
SetZ / BringToFrontstacking order
SendSend(id, channel, payload), Lua → page
Subscribe / UnsubscribeSubscribe(id, channel, handler), page → Lua
RequestRequest(id, channel, payload), request/response round-trip
DestroyView clears the view’s bridge subscriptions. If you re-open a view without destroying the old one, the Subscribe dedup guard skips re-registering its handlers and its buttons go dead on the second open.
Lua array-tables serialize to JS as objects ({"1":...}). In page JS, normalize with a toArray() helper before calling .forEach.

Input modes

Screens push an input mode while open and pop it when closed, so capture is well-behaved when several UIs overlap.
ExportSignature
PushInputMode / PopInputModemanage the capture stack
IsCapturingInputIsCapturingInput()

Notifications & HUD

ExportSignature
NotifyNotify({ level, text, durationMs }), a toast. level is info|success|warn|error
BroadcastBroadcast(notify), toast to all clients (server-callable)
MountHud / UnmountHudmount a persistent HUD overlay
GetTheme / SetThemeread or override theme tokens
exports["forge-ui"]:Notify({ level = "success", text = "Quest complete!", durationMs = 3000 })

Testing pattern

UI logic that can be unit-tested lives in pure shared/ modules (input stack, notify formatting, form-schema validation) and is covered by forge-tests; the WebUI rendering itself is verified in Play-In-Editor.