# Hot Reload

## Introduction

Gum supports hot reload for rapid UI iteration during development. When hot reload is enabled, changes saved in the Gum tool are automatically reflected in your running game without restarting. This lets you adjust layouts, resize elements, change colors, and modify component structure while seeing results immediately.

Hot reload watches for changes to Gum project files (`.gumx`, `.gusx`, `.gucx`, `.gutx`) and font files (`.fnt`) and reconstructs the element tree when changes are detected.

## Enabling Hot Reload

Call `EnableHotReload` after initializing Gum, passing the absolute path to your **source** `.gumx` file — not the copy in your `bin/Content` folder.

```csharp
// Initialize
var gumProject = GumUI.Initialize(this, "GumProject/GumProject.gumx");

GumUI.EnableHotReload(
    @"c:\Users\YourName\source\YourGame\Content\GumProject\GumProject.gumx");
```

{% hint style="info" %}
The path must point to the original `.gumx` file that the Gum tool edits. If you point to the `bin/Content` copy, changes saved in the Gum tool will not be detected because that copy is only updated on build.
{% endhint %}

Once enabled, hot reload is fully automatic. `GumService` processes pending reloads during its `Update` call each frame, so no additional code is needed.

<figure><img src="/files/cs9nBtmGWtpTVo6FbdEK" alt=""><figcaption><p>Gum at runtime (top) updating in realtime to changes in the tool (bottom)</p></figcaption></figure>

## What Gets Reloaded

Hot reload monitors the following Gum file types:

| Extension | Description                  |
| --------- | ---------------------------- |
| `.gumx`   | Gum project file             |
| `.gusx`   | Screen definitions           |
| `.gucx`   | Component definitions        |
| `.gutx`   | Standard element definitions |
| `.fnt`    | Bitmap font definitions      |

When any of these files change, Gum reloads the project in place: it diffs the new definitions against the live visual tree and updates only what changed. This covers variable edits (move, resize, color, state changes) as well as structural changes — instances added by copy/paste, instances deleted, instances whose `BaseType` was changed, and instance reorders.

Children added at runtime by your game code are left untouched. Hot reload identifies "design-time" children by their `Tag` — when Gum creates a visual from an `InstanceSave`, it stores the `InstanceSave` in `Tag`. Anything without an `InstanceSave` `Tag` is treated as runtime-owned and skipped.

When a reload is triggered, Gum automatically copies all `.fnt` and `.png` files from the source project's `FontCache/` directory to the bin-side `FontCache/` directory, and evicts cached fonts so they are reloaded from disk.

### What Is Not Reloaded

Hot reload is focused on Gum element definitions. The following are **not** automatically reloaded:

* **Textures and images** — If you change a `.png` file, the cached texture is still used. Restart the game to pick up texture changes.
* **Animation files** — `.ganx` animation definitions are not reloaded.
* **Runtime state on existing instances** — Any properties set programmatically at runtime (e.g., changing `Text` or `Width` in code) are overwritten when the corresponding design-time variables are re-applied. Only values defined in the Gum project are restored. See [Preserving Runtime State](#preserving-runtime-state) below for the recommended pattern.

### Known Limitation: Cleared Tags

If your code clears (`= null`) or replaces the `Tag` on a visual that was created from an `InstanceSave`, hot reload can no longer recognize it as a design-time child. It is treated as runtime-owned: not removed, not retyped, and not duplicated when the corresponding `InstanceSave` is still present in the project. The parent's qualified-name variables (`MyInstance.X`, etc.) still flow through to it by `Name`, so visible variables continue to update.

## Platform Support

{% hint style="info" %}
Hot reload requires loose project files on disk; it does not watch inside `.gumpkg` bundles. If a sibling `.gumpkg` exists alongside the loose `.gumx`, the loose path wins (see [pack](/gum/cli/cli/pack.md)) and watchers fire normally. A bundle-only deployment (no loose `.gumx`) loads at startup but cannot hot-reload.

If hot reload from a `.gumpkg` (e.g. for a hot-swap-on-deploy workflow) would be useful to you, let us know on [Discord](https://discord.gg/EvqwmSQuBz) or file an issue on [GitHub](https://github.com/vchelaru/Gum/issues) — real usage reports help us prioritize.
{% endhint %}

Hot reload is available on desktop platforms:

* MonoGame
* KNI
* FNA
* Raylib

Hot reload is **not available** on iOS or Android. Calls to `EnableHotReload` are excluded at compile time on these platforms.

## How It Works

When `EnableHotReload` is called, Gum creates a `FileSystemWatcher` on the directory containing your `.gumx` file (including subdirectories). When a watched file is saved:

1. The change is detected and a 200ms debounce timer starts. Additional changes within that window reset the timer, so rapid saves (such as the Gum tool writing multiple files at once) are coalesced into a single reload.
2. On the next `GumService.Update` call after the debounce window, Gum reloads the project from disk.
3. Gum walks the live visual tree and, for each visual that matches a project element by name, reconciles its design-time children with the new `Instances` list (adding, removing, retyping, and reordering as needed) and re-applies the new default-state variables. Runtime-added children are left in place.

{% hint style="warning" %}
Re-applying design-time variables overwrites values your code set on those same properties at runtime. If your game writes to UI elements after creation (e.g., populating a label with a score, hiding a panel), that code needs to run again after a reload.
{% endhint %}

## Preserving Runtime State

Hot reload rebuilds elements from the Gum project, so values your code wrote at runtime are not preserved. The recommended pattern is to subscribe to the `HotReloadCompleted` event and re-apply any runtime state your game relies on.

`HotReloadCompleted` fires after Gum has finished rebuilding the element tree but before the next frame draws, so changes made in the handler are visible immediately.

```csharp
// Initialize
GumUI.HotReloadCompleted += ReapplyRuntimeState;

void ReapplyRuntimeState()
{
    // Hide UI that should not be visible at this point in the game.
    _winOverlay.IsVisible = false;

    // Re-populate dynamic content driven by game state.
    _scoreLabel.Text = _player.Score.ToString();

    // Re-bind anything that was wired up after element creation.
    _inventoryListBox.ItemsSource = _player.Inventory;
}
```

{% hint style="info" %}
Only re-apply state that originated in your code. Values authored in the Gum tool are already restored by the reload itself.
{% endhint %}

Common things to re-apply in a `HotReloadCompleted` handler:

* Visibility of overlays, modals, or panels that were hidden or shown by game code.
* Text values that reflect game state (scores, names, timers, currency).
* Data bindings or `ItemsSource` assignments on `ListBox`, `ComboBox`, etc.
* Event handler subscriptions on buttons or other interactive elements, if they were attached to specific instances rather than registered through Forms.

If your game has a single screen-level "apply current state to UI" method, calling it from `HotReloadCompleted` is usually the simplest approach.

## Disabling Hot Reload

Hot reload is automatically stopped when `GumService.Uninitialize()` is called. There is no separate method to disable it without uninitializing the entire Gum service. Since hot reload is a development-time feature, the simplest approach is to only call `EnableHotReload` in debug builds:

```csharp
// Initialize
var gumProject = GumUI.Initialize(this, "GumProject/GumProject.gumx");

#if DEBUG
GumUI.EnableHotReload(
    @"c:\Users\YourName\source\YourGame\Content\GumProject\GumProject.gumx");
#endif
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flatredball.com/gum/code/hot-reload.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
