menu_bookDocumentation

s&box Hotload System: How Code Reloading Works, SkipHotload, ConVar Persistence, and NetworkObject.OnHotload

calendar_today May 4, 2026 schedule ~2 min read person patrickjr verified 50

s&box Hotload System: How Code Reloading Works

s&box supports live code reloading (hotload) without restarting the game. Understanding how it works helps avoid common hotload bugs.

What Hotload Does

When you save a C# file in the editor, the compiler recompiles the assembly. The hotload system then:

  1. Stops worker threads
  2. Calls PreSwap callbacks (e.g., unregistering event handlers)
  3. Runs Hotload.UpdateReferences() — walks all live instances and upgrades them to use the new assembly's types
  4. Calls OnSuccess callbacks (e.g., re-registering event handlers, rebuilding network tables)
  5. Restarts worker threads

Fast Hotload

hotload_fast = true (default) enables experimental fast hotloads when only method bodies change — no instance upgrading needed, just method replacement.

[SkipHotload] Attribute

Mark a class with [SkipHotload] to prevent the hotload system from trying to upgrade its instances. Use this for classes that hold native handles or are otherwise unsafe to upgrade.

ConVar Values Survive Hotload

ConVar values are "remembered" before the assembly is unloaded and restored after the new assembly is loaded. This means your [ConVar] properties keep their values across hotloads.

NetworkObject.OnHotload

When a hotload occurs, NetworkObject.OnHotload() is called on all networked objects. This rebuilds the NetworkTable (data table for [Sync] properties) because property metadata may have changed.

What Can Break During Hotload

  • Static fields: The hotload system walks static fields of watched assemblies (Sandbox.Engine, Sandbox.System) to find instances to upgrade. Static fields holding instances of hotloaded types will be upgraded.
  • Delegates: Delegate upgraders handle method references that point to old assembly methods.
  • Skipped types: JsonNode, JsonElement, JsonObject, JsonArray, ExceptionDispatchInfo, NodeLibrary are skipped for safety/performance.
  • Types taking too long: If a single type takes >500ms AND >80% of total hotload time, an error is logged.

Hotload Log Levels

CODE
hotload_log 0  // no logging (default)
hotload_log 1  // simple: instance count and time
hotload_log 2  // verbose: per-type timing breakdown
Was this helpful?