State and collections
State is any public property on your bridge that the UI should render.
public int Coins { get; set; }
public string CurrentScreen { get; set; } = "MainMenu"; Assigning a state property pushes the new value to the UI.
Nested state
Use classes for grouped state that should update per field:
public sealed class PlayerState
{
public string Name { get; set; } = "";
public int Health { get; set; }
}
public PlayerState Player { get; set; } = new(); Initialize nested state before Loom starts. A nested state object that is null during registration cannot be walked until you assign the parent again.
Snapshot collections
Arrays, List<T>, and Dictionary<K,V> use snapshot semantics. Reassign the
whole collection to push a new value:
Items = new List<ItemState>(Items) { newItem }; In-place mutation does not call the property setter:
Items.Add(newItem); // Does not sync by itself. Use snapshots for small lists or values that naturally update as a whole.
Reactive collections
Use ReactiveList<T> or ReactiveMap<K,V> when the UI needs granular changes:
public ReactiveList<QuestState> Quests { get; } = new(); Reactive collections are better for lists or maps that change frequently while preserving item identity.
UI usage
The generated TypeScript state uses camelCase names:
const bridge = useBridge();
bridge.currentScreen;
bridge.player.health;
bridge.quests; Run Loom -> Regenerate Types after changing the C# state shape.