Gum gum-forms-behaviors
Covers 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.
git clone https://github.com/vchelaru/Gum
T=$(mktemp -d) && git clone --depth=1 https://github.com/vchelaru/Gum "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/gum-forms-behaviors" ~/.claude/skills/vchelaru-gum-gum-forms-behaviors && rm -rf "$T"
.claude/skills/gum-forms-behaviors/SKILL.mdGum Forms Behaviors
What Behaviors Are
Behaviors are named capability contracts stored as
.behx XML files in the project's Behaviors/ folder. Each behavior (BehaviorSave) declares:
- A
(e.g.Name
)"ButtonBehavior" - Required visual state
(with state names like Enabled/Disabled/Highlighted/Pushed)Categories - Optional
andRequiredVariablesRequiredInstances - A
path pointing to the default visual (e.g.DefaultImplementation
)"Controls/ButtonStandard"
An
ElementSave (component or screen) opts into a behavior via a List<ElementBehaviorReference>, where each reference holds only a BehaviorName string. This is the signal used at runtime to select which Forms control wraps the visual.
The Wrapping Lifecycle
At project load time, call order is:
-
iterates every component in the loadedFormsUtilities.RegisterFromFileFormRuntimeDefaults()
, checks each component'sGumProjectSave
list against constants inBehaviors
, and callsStandardFormsBehaviorNames
for each match.ElementSaveExtensions.RegisterGueInstantiationType(component.Name, typeof(DefaultFromFileXxxRuntime)) -
(inDefaultFromFileXxxRuntime
) is anMonoGameGum/Forms/DefaultFromFileVisuals/
subclass selected as the runtime type. ItsInteractiveGue
override fires after the full visual tree is instantiated. InsideAfterFullCreation()
, the runtime setsAfterFullCreation()
(passing itself as the visual), completing the pairing.FormsControlAsObject = new Button(this) -
fires on the Forms control when itsReactToVisualChanged()
is assigned. The control caches named child references (Visual
) andVisual.GetGraphicalUiElementByName(...)
subscribes to input events and callsbase.ReactToVisualChanged()
.UpdateState()
The
DefaultFromFileXxxRuntime classes exist solely to bridge the file-loading path into the Forms object model. They are distinct from the DefaultVisuals classes (which serve the code-only construction path).
Behavior → Forms Control Mapping
StandardFormsBehaviorNames constants → DefaultFromFile runtime registered:
| Behavior name constant | Runtime type |
|---|---|
| |
| |
| |
| |
| |
| / |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
The Property Promotion Gap
The Gum tool operates at the visual layer — layout, colors, fonts, dimensions saved as
VariableSave entries. The Forms behavioral layer (state, data, interaction) is added entirely at runtime. No bridge exists between them.
Concrete examples of Forms properties with no Gum variable equivalent:
/Button.Text
— visual has aLabel.Text
child, but no top-level "Text" variable on the componentTextInstance
/CheckBox.IsChecked
— runtime-only boolean, not representable in the save fileToggleButton.IsChecked
— initial text cannot be authored in the toolTextBox.Text
,Slider.Minimum
,Slider.Maximum
— numeric range exists only on the Forms controlSlider.Value
,ListBox.SelectionMode
,ListBox.DisplayMemberPath
— entirely runtime constructsItemsControl.Items
Why this gap exists: The visual save model (
VariableSave) has no notion of Forms semantics. The Gum tool has no awareness of which Forms properties correspond to which visual structure. The wrapping is a pure runtime event.
Impact: Game code must set all behavioral defaults in code after loading, even properties that logically belong to component design.
Key Files
| Path | Purpose |
|---|---|
| Behavior definition model () |
| Per-element reference holding only |
| String constants for all standard behavior names |
| list on components/screens |
| — drives the mapping |
| classes — creates Forms objects |
| back-link property |