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
| Class | Role |
|---|---|
UWebOverlaySubsystem | GameInstanceSubsystem — manages all overlay instances, persists across levels |
UWebOverlay | Individual overlay wrapping an SWebBrowser widget with transparent background |
UWebOverlayBridge | JavaScript ↔ C++ bridge bound as window.ue.grids.* |
UOverlayContentServer | Localhost 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.
- Preload —
UWebOverlaySubsystem::PreloadOverlay(Id, Url, ZOrder)creates a hidden, non-interactive overlay marked as persistent - Load — CEF loads the HTML/JS/CSS; the bridge bootstrap script is injected at load completion
- Show —
UWebOverlay::Show()sets the overlay visible + interactive (optionally withSetCapturesInput(true)for modal input) - Communicate — C++ sends messages via
SendMessage(EventName, JsonPayload). JS sends messages back viagrids.send(event, data). Messages can be sent at any time, even while hidden - Hide —
UWebOverlay::Hide()hides the overlay and releases input, but the browser and JS context stay alive - 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:
- Create —
UWebOverlaySubsystem::CreateOverlay(Id, Url, ZOrder)creates a newUWebOverlay - Load — CEF loads the page and injects the bridge bootstrap
- Communicate — Same messaging API as persistent overlays
- Destroy —
UWebOverlaySubsystem::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:
| Command | Description |
|---|---|
grids.overlay.open <name> | Opens an overlay from Content/Overlays/<name>/index.html |
grids.overlay.close <name> | Closes (destroys) a specific overlay |
grids.overlay.closeall | Closes all overlays |
grids.overlay.send <name> <event> <json> | Sends a JSON message to a specific overlay |
grids.overlay.list | Lists all currently active overlays |