The s&box UI system is built on a CSS-like layout engine (Yoga) combined with a Razor-compatible render tree. You write panels in C# orDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/facepunch/sbox-public/llms.txt
Use this file to discover all available pages before exploring further.
.razor files, style them with SCSS, and attach them to your scene through ScreenPanel or WorldPanel components. This page explains how the system fits together and how to wire it up to your game.
Core concepts
The UI hierarchy has three layers:Panel— the base building block. Every visible UI element is aPanelor a subclass of it.RootPanel— aPanelthat owns a layout pass and a command list for rendering.PanelComponent/ScreenPanel/WorldPanel— scene components that connect panels to the engine’s render pipeline.
Panel
Panel is the base class for all UI elements. It manages layout, styling, events, and the Razor render tree.
Creating a panel in C#
Styling
Styles can be set programmatically or via SCSS loaded throughStyleSheet.Load:
| Pseudo-class | Flag | When active |
|---|---|---|
:hover | PseudoClass.Hover | Mouse is over the panel |
:active | PseudoClass.Active | Panel is pressed |
:focus | PseudoClass.Focus | Panel has keyboard focus |
:intro | PseudoClass.Intro | Panel was just added (entry animation) |
:outro | PseudoClass.Outro | Panel is being removed (exit animation) |
Tick
Panel.Tick() is called every frame and is the equivalent of Update for UI elements. Override it to update panel state:
Visibility and input
Deferred invocation
Coordinate helpers
Razor panels (PanelComponent)
The recommended way to build UI is throughPanelComponent subclasses paired with .razor template files. The engine re-renders the Razor tree whenever BuildHash() returns a different value than the previous frame.
Create the component
Create a C# class that inherits from
PanelComponent. Place a .razor file with the same name alongside it.Write the Razor template
The
.razor file describes the panel’s content using HTML-like syntax. The SCSS file (same name) applies styles.Triggering a re-render
CallStateHasChanged() to mark the tree dirty and force a rebuild on the next frame:
Lifecycle callbacks
| Method | When called |
|---|---|
OnTreeFirstBuilt() | Once, after the first Razor render |
OnTreeBuilt() | After every subsequent render |
OnHotloaded() | After hot-reload |
OnParentChanged() | When the panel’s parent changes |
LanguageChanged() | When the game language switches |
RootPanel
RootPanel is the layout root that every tree must have. You rarely create it directly — ScreenPanel and WorldPanel create one for you.
Key members:
screenHeight / 1080.0f, keeping UI consistent across resolutions.
ScreenPanel
ScreenPanel is a scene component that renders its child PanelComponent hierarchy as a flat screen-space HUD.
Properties
| Property | Default | Description |
|---|---|---|
Opacity | 1.0 | Overall alpha of this panel layer. |
Scale | 1.0 | Manual scale multiplier. |
AutoScreenScale | true | Automatically scale based on screen resolution. |
ScaleStrategy | ConsistentHeight | ConsistentHeight keeps 1080p reference; FollowDesktopScaling uses OS DPI. |
ZIndex | 100 | Render order relative to other ScreenPanel layers. |
TargetCamera | null | If set, renders only for this camera. |
Wiring up a HUD
GameObject. ScreenPanel becomes the root, and MyHud attaches to it automatically because PanelComponent.EnsureParentPanel walks up the hierarchy looking for an IRootPanelComponent.
A scene can have multiple
ScreenPanel components with different ZIndex values for layered HUDs (for example, a game HUD at 100 and a chat overlay at 200).WorldPanel
WorldPanel is a scene component that renders its child PanelComponent hierarchy as a texture projected into 3D world space. It inherits from Renderer, so it participates in scene culling.
Properties
| Property | Default | Description |
|---|---|---|
PanelSize | 512×512 | The pixel dimensions of the panel canvas. |
RenderScale | 1.0 | Scales the physical size in world units. |
LookAtCamera | false | Rotates the panel to face the active camera each frame. |
HorizontalAlign | Center | Left / Center / Right pivot. |
VerticalAlign | Center | Top / Center / Bottom pivot. |
InteractionRange | 1000 | Maximum distance from which players can interact with the panel. |
Example setup
WorldPanel creates an internal Sandbox.UI.WorldPanel in the scene world, applies the GameObject’s transform, and renders all attached PanelComponent children into it.
Event handling
Panels fire strongly-typed mouse events. Override them in aPanel subclass or respond to them in a PanelComponent:
OnMouseDown, OnMouseUp, OnMouseMove, OnMouseOver, OnMouseOut, OnMouseWheel.
Next steps
Rendering pipeline
Understand how CameraComponent and the Graphics class drive rendering.
Custom shaders
Write HLSL shaders and use ComputeShader from C#.