Clutter is here! 🌴🌴 Performance boosts 🚀, UI rendering overhaul, main menu polish 💅 and more Sandbox features!
Clutter system — the clutter/scatter tool and system has been moved in-engine
CSS outline property — outline draws outside a panel's border without affecting layout, matching web standards
Multithreaded UI rendering — UI can now render off the main thread
New main menu front page — redesigned around flatgrass, refreshed navbar and footer
ContentBlock row scroll buttons — left/right scroll arrows appear on hover as an alternative to drag-scrolling
DepthTextureRef on RenderTargetHandle — lets you access the depth buffer of a render target in command lists, not just the colour buffer
Improved UI drag & drop — new OnDragEnter, OnDragLeave, and OnDrop panel events matching standard web behaviour
AdvancedDropdown — ComponentTypeSelector abstracted into a reusable dropdown that supports foldered menus
SerializedProperty.GetCustomizable() — creates a customisable copy of a property with an overridable display name and other metadata
MemberDescription.DeclaringType — exposes the type that declared the member
Json.Serialize / Json.Deserialize — low-level methods plus object/Type overloads for use with IJsonConvert
Package.MountAsync() — public API equivalent of the internal PackageManager.InstallAsync
Json.Patch, Json.CalculateDifferences, Json.ApplyPatch and related types are now public, along with GameObject.DiffObjectDefinitions and Scene.SerializeProperties()
TestAppSystem exposed to user unit test projects, replacing the old Application.InitUnitTest flow
Vector2Int and Vector3Int added to TryToType
Mirror tool now supports mirroring any selected object type, not just meshes
UI rendering now uses command lists — panels only rebuild their command lists when something actually changes, reducing per-frame work
Audio mixing allocations reduced — temp lists are reused in-place and the occlusion sort predicate is cached as a static
CommandList attribute access — switched from ConcurrentDictionary to a regular dictionary, cheaper and avoids expensive clears
Cluster lighting — Cluster::Query now takes a screen-space position instead of world-space, which was unstable near cluster boundaries
Razor incremental processing — only re-runs RazorProcessor on changed files and reuses SyntaxTree instances, speeding up hot reloads
Debug overlay visual clarity — render stats grouped into categories, timing fixed to CPU/GPU order, new metrics added, low-signal rows removed. Thanks @darkfated
SerializedProperty.TryGetAsObject now returns a SerializedObject of the actual runtime derived type, not just the declared property type
Close game if Steam is not running — instead of cryptic errors, the game now exits cleanly with a clear message
Error reports now correctly embed user information
Editor unit tests can now reference built-in tool packages (Shader Graph, Action Graph, Hammer, Movie Maker)
DetermineHuman not checking the base model first, breaking dresser clothing for characters with a base model
PropertySignal.Compile(timeRange) not clamping the first/last blocks to the requested time range, causing "blocks must not overlap" errors when compiling Movie Maker recordings
:last-child pseudo-class updating a frame late when adding child panels
Cancelling a purchase incorrectly showing "You purchased X!" after the 20-second timeout
DefaultMaterialGroup not working for .vmdl files exported from MeshComponent
Clothing properties not serializing to JSON when marked internal — free clothes referenced by resource ID now save correctly
ScenePanel — render scenes are now kicked off during Tick, decoupling them from the render texture step.
CBaseFileSystem::AddSymLink overwriting the target path of an existing symlink
NavArea toggling behaving incorrectly due to stale MakeDirty usage
The M key resetting the active mapping subtool when merging vertices
Editor splash screen losing its taskbar window icon
Minor prefab serialisation and instance ID edge cases
An array pool use-after-free exploit — game code's ArrayPool.Shared usages are remapped to Sandbox.PublicArrayPool to prevent reading memory from other sandboxed games
Missing HTTP redirect URL validation — redirects are now manually followed so blacklisted local URLs cannot be reached through redirect chains
Hammer entity placement always inserting info_player_start instead of the selected entity type. Thanks @Kaikenny
Gizmo.Hitbox.Sphere behaving differently from all other hitbox functions, causing rotation gizmo priority and clickability issues. Thanks @nixxquality
Dropping Clutter is huge for S&box too!.