gum-service

$npx mdskill add vchelaru/Gum/gum-service

Initialize Gum UI runtime for game projects.

  • Manages lifecycle of MonoGame, Raylib, KNI, and FNA game environments.
  • Handles deferred queues, hot reloads, and root container operations.
  • Prevents double initialization errors through singleton pattern enforcement.
  • Clears shared static state and resets renderable delegates on teardown.

SKILL.md

.github/skills/gum-serviceView on GitHub ↗
---
name: gum-service
description: Reference guide for GumService — the runtime entry point for MonoGame/Raylib/KNI/FNA games. Load this when working on GumService initialization, Uninitialize, DeferredQueue, hot reload, or the Root/PopupRoot/ModalRoot containers.
---

# GumService Reference

## What It Is

`GumService` is the runtime-facing API that game developers use to initialize, update, and draw Gum UI. It lives in `MonoGameGum/GumService.cs` (compiled for XNALIKE, RAYLIB via `#if`).

**Not the CLI.** `Gum.Cli` / `Gum.ProjectServices` are separate tools for headless project validation and codegen.

## Lifecycle

```
GumService.Default.Initialize(game)   // one-time setup
  ↓ per frame:
GumService.Default.Update(gameTime)
GumService.Default.Draw()
  ↓ on teardown (optional):
GumService.Default.Uninitialize()
```

`Initialize` throws if called twice without an intervening `Uninitialize`.

## Singleton Pattern

`Default` is lazily initialized via `??=`. `Uninitialize()` sets `_default = null`, so after teardown `GumService.Default` creates a **fresh instance** — any stored reference to the old instance is now orphaned.

## Uninitialize — Non-Obvious Details

`Uninitialize()` resets a large amount of shared static state across multiple singletons. Key things it does that are surprising:

- Nulls `GraphicalUiElement.SetPropertyOnRenderable`, `AddRenderableToManagers`, etc. — delegates wired by `FormsUtilities.InitializeDefaults`
- Calls `ElementSaveExtensions.ClearRegistrations()` — clears `RegisterGueInstantiation` / `RegisterDefaultInstantiationType` callbacks
- Calls `LoaderManager.Self.DisposeAndClear()` — disposes GPU content and empties the cache
- Nulls and removes `FrameworkElement.PopupRoot` and `FrameworkElement.ModalRoot` from managers
- Resets `FileManager.RelativeDirectory` to `"Content/"` (only meaningful if a project was loaded)
- Calls `_systemManagers.Renderer.Uninitialize()` (XNALIKE only)
- Sets `_default = null` — next access to `Default` creates a new `GumService`

`FormsUtilities.Uninitialize()` is `internal`; tests access it via `InternalsVisibleTo`.

## Roots

| Property | Purpose |
|----------|---------|
| `Root` | Main scene container; sized to canvas on each `Update` |
| `PopupRoot` | Overlaid above Root; for non-modal popups |
| `ModalRoot` | Topmost layer; blocks input to everything below |

`PopupRoot` and `ModalRoot` are `FrameworkElement` statics, not instance fields — they are shared across all `GumService` instances.

## Key Files

| File | Purpose |
|------|---------|
| `MonoGameGum/GumService.cs` | Main class |
| `MonoGameGum/Forms/FormsUtilities.cs` | Input/cursor/gamepad setup; `Uninitialize()` lives here |
| `GumRuntime/ElementSaveExtensions.GumRuntime.cs` | `ClearRegistrations()` called during Uninitialize |
| `RenderingLibrary/Content/LoaderManager.cs` | `DisposeAndClear()` called during Uninitialize |
| `Tests/MonoGameGum.Tests.V2/GumServiceUninitializeTests.cs` | Tests for GPU-accessible Uninitialize behavior |
| `Tests/Gum.ProjectServices.Tests/UninitializeTests.cs` | Tests for non-GPU Uninitialize behavior |

## Testing Split

Uninitialize tests are split across two projects because `FormsUtilities`, `LoaderManager`, and `ElementSaveExtensions` don't all require a GPU:

- `Gum.ProjectServices.Tests` — `LoaderManager`, `ElementSaveExtensions`, `ObjectFinder` (no GPU needed)
- `MonoGameGum.Tests.V2` — `FormsUtilities`, root containers, `FrameworkElement` statics (require test setup with a mock `SystemManagers`)

More from vchelaru/Gum

SkillDescription
bump-nuget-versionBump the NuGet package versions for all 12 Gum projects (11 libraries + GumCli). Queries NuGet to check if a version exists for today, then sets the new version to YYYY.M.D.V where V increments from the latest published version today (or starts at 1). Creates a release branch named ReleaseCode_YYYY_M_D_V, commits the changes, and pushes. Run this before triggering the nuget release workflow.
gum-cliReference guide for GumCli — the headless command-line tool for Gum projects. Load this when working on gumcli commands (new, check, codegen, codegen-init), Gum.ProjectServices, HeadlessErrorChecker, ProjectLoader, HeadlessCodeGenerationService, CodeGenerationAutoSetupService, or the FormsTemplateCreator.
gum-docs-writingReference guide for writing Gum documentation in GitBook markdown. Load when writing or editing docs/ files, adding pages to SUMMARY.md, using GitBook hints/figures, linking between pages, or adding images.
gum-forms-behaviorsCovers Gum's behaviors system and the design-time → runtime Forms wrapping lifecycle. Load this when working on BehaviorSave, ElementBehaviorReference, StandardFormsBehaviorNames, FormsUtilities.RegisterFromFileFormRuntimeDefaults, DefaultFromFileXxxRuntime classes, or when investigating why Forms properties cannot be set at design time in the Gum tool.
gum-forms-controlsReference guide for Forms controls — classes inheriting from FrameworkElement. Load this when working on Button, CheckBox, ListBox, ComboBox, TextBox, ScrollViewer, or any class in Gum.Forms.Controls (or FlatRedBall.Forms.Controls). Also load when working on FrameworkElement itself, the Visual/InteractiveGue relationship, state machines, DefaultVisuals, or ReactToVisualChanged.
gum-forms-default-visualsReference guide for Forms DefaultVisuals — the code-only visual classes that back Forms controls. Load when working on ButtonVisual, any *Visual class in DefaultVisuals/, Styling, DefaultFormsTemplates registration, or building custom code-only Forms visuals.
gum-forms-itemscontrolReference guide for ItemsControl and ListBox — the Items/ListBoxItems relationship, templates, InnerPanel sync, and gotchas. Load this when working on ItemsControl, ListBox, ListBoxItem, VisualTemplate, FrameworkElementTemplate, Items collection behavior, ListBoxItems desync, or adding/removing items from a list box.
gum-layout>
gum-layout-engine>
gum-localizationReference guide for Gum's runtime localization system — ILocalizationService, CSV/RESX loading, Text vs TextNoTranslate paths, Forms control localization patterns, and gotchas.