Web Overlay System

The overlay system is the core technology that enables web-based UIs in Grids. It uses Chromium Embedded Framework (CEF) via Unreal's SWebBrowser widget to render transparent web pages directly on top of the game viewport.

Architecture

Core C++ Classes

ClassRole
UWebOverlaySubsystemGameInstanceSubsystem — manages all overlay instances, persists across levels
UWebOverlayIndividual overlay wrapping an SWebBrowser widget with transparent background
UWebOverlayBridgeJavaScript ↔ C++ bridge bound as window.ue.grids.*
UOverlayContentServerLocalhost HTTP server on port 9735 serving overlay files from Content/Overlays/

Overlay Lifecycle

Overlays have two lifecycle models:

Persistent (Preloaded)

Most overlays are preloaded at startup — the SWebBrowser page loads in the background while hidden, so toggling them on/off is nearly instant with no CEF load latency. Their JavaScript context stays alive, which means they can receive events (e.g. chat messages) even while hidden.

  1. PreloadUWebOverlaySubsystem::PreloadOverlay(Id, Url, ZOrder) creates a hidden, non-interactive overlay marked as persistent
  2. Load — CEF loads the HTML/JS/CSS; the bridge bootstrap script is injected at load completion
  3. ShowUWebOverlay::Show() sets the overlay visible + interactive (optionally with SetCapturesInput(true) for modal input)
  4. Communicate — C++ sends messages via SendMessage(EventName, JsonPayload). JS sends messages back via grids.send(event, data). Messages can be sent at any time, even while hidden
  5. HideUWebOverlay::Hide() hides the overlay and releases input, but the browser and JS context stay alive
  6. Show again — Calling Show() again is instant — no page reload, state is preserved

Built-in preloaded overlays: chat, asset-browser, settings, build-editor, zone-manager.

Ephemeral (Create/Destroy)

Short-lived overlays like context menus are created on demand and destroyed when dismissed:

  1. CreateUWebOverlaySubsystem::CreateOverlay(Id, Url, ZOrder) creates a new UWebOverlay
  2. Load — CEF loads the page and injects the bridge bootstrap
  3. Communicate — Same messaging API as persistent overlays
  4. DestroyUWebOverlaySubsystem::DestroyOverlay(Id) fully removes the overlay and frees memory

Built-in ephemeral overlays: context-menu, zone-loading.

When the JS side calls grids.close(), persistent overlays are automatically hidden instead of destroyed.

Rendering

Overlays are added to a Slate SOverlay container at Z-order 1000 in the viewport. Multiple overlays stack by their Z-order value. Each overlay is individually toggleable between interactive (EVisibility::Visible) and pass-through (EVisibility::HitTestInvisible) modes.

Content Server

The UOverlayContentServer runs a local HTTP server on localhost:9735 that serves static files from Content/Overlays/. Each overlay lives in its own subdirectory:

Content/Overlays/
├── asset-browser/
│   ├── index.html
│   └── assets/
│       ├── index-xxx.js
│       └── index-xxx.css
├── context-menu/
│   └── ...
├── notifications/
│   └── ...
├── zone-loading/
│   └── ...
└── my-custom-overlay/
    └── ...

The server includes path safety checks (no directory traversal, no null bytes) and serves files with correct MIME types.

Console Commands

For debugging and testing, the following console commands are available:

CommandDescription
grids.overlay.open <name>Opens an overlay from Content/Overlays/<name>/index.html
grids.overlay.close <name>Closes (destroys) a specific overlay
grids.overlay.closeallCloses all overlays
grids.overlay.send <name> <event> <json>Sends a JSON message to a specific overlay
grids.overlay.listLists all currently active overlays