tag

#performance

15 items (2 guides · 13 fixes)

guides
fixes
26.07.08e
"A frame-budget method for stylized s&box scenes"

Census tris × instances before decimating; prefer BoxCollider over ModelCollider for decorative props.

26.07.22
"A low sun in a street canyon leaves the ground unshadowed"

At single-digit sun elevation a street canyon gets no direct ground light, so nothing on the ground casts a visible shadow while the cascade is billed in full; fix it with sun azimuth, not renderer flags.

26.07.08e
"Chunked mesh generation is math-bound, not draw-call-bound"

For a chunked runtime-mesh generator, REGEN (single-threaded generation CPU) is the binding resource, not fps or draw calls. Quartering the chunk count produces zero regen change; the lever is threading the passes.

26.07.08e
"Collider choice that actually costs you"

BoxCollider is cheap and follows WorldScale; Capsule/ModelCollider don't scale with WorldScale and ModelCollider is costly on clutter.

26.07.08e
"Decimating AI meshes without wrecking them"

Census tris × instances first: silhouette fails before UVs; inject usemtl after scripted OBJ export.

26.07.08e
"Disabling per-instance shadows on ModelRenderer"

ModelRenderer.CastShadows doesn't exist as a settable property: use renderer.SceneObject.Flags.CastShadows instead.

26.07.22
"Editor play mode is hard-capped at 60 fps: cvars won't lift it"

Editor-embedded play mode pins at exactly 60 fps regardless of cvars. The cap is the compositor's vsync on the editor window, not the engine frame sync. Under the cap even the p50 pins to 16.67 ms: read the tail (p99, worst frame, over-budget count), not the median.

26.07.22
"Editor vsync hides physics cost: time the step directly"

Frame fps pins at 60 in the editor regardless of physics load: implement IScenePhysicsEvents.PrePhysicsStep/PostPhysicsStep with a Stopwatch to get the true, vsync-free CPU cost of the solver step.

26.07.22
"FrameStats and PerformanceStats are accessible from game code: no engine benchmark system needed"

Sandbox.Diagnostics.FrameStats and PerformanceStats are whitelist-clean and reachable from game-assembly components: build a relative perf probe without any engine benchmark API. Raw GC.GetAllocatedBytesForCurrentThread/GC.CollectionCount are SB1000-blocked in-editor; use PerformanceStats instead.

26.07.08e
"Heavy work without frame hitches"

GameTask.RunInThreadAsync for parse/math; main thread only for engine objects; Yield every N items for loading UI.

26.07.08e
"Razor panel mounted before a sync call never paints: budget frames, not ticks"

A loading screen mounted right before a synchronous multi-second call never paints: one consumed tick isn't enough; gate the block on a frame counter (~6 frames) so the Razor pipeline finishes mount → style → layout → paint.

26.07.18
"Sandbox.Decal scales to thousands: the bound is fill rate, not a hard cap"

Sandbox.Decal instances are lightweight scene objects with no hard engine cap, so a persistent-paint system can hold thousands. The failure mode is a gradual frame-time sag driven by fill-rate/overdraw, never a crash cliff. Bound it with a convar-backed ring buffer and bench for your target hardware.

26.07.22
"Sandbox.Json.Serialize always writes indented JSON"

Sandbox.Json.Serialize always emits pretty-printed JSON and exposes no public option to disable it: every network payload pays a whitespace tax. Re-drive the same serializer through a compact writer for a 41–56% size cut.

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord