The bridge model
Define the C# contract that exposes state, actions, and events to Solid.
The bridge connects your Unity game to your Solid UI. You define it in C#; Loom generates matching TypeScript types.
| Direction | Bridge member | Use it for |
|---|---|---|
| C# to UI | State properties | Current values: health, inventory, selected screen |
| UI to C# | [BridgeAction] methods | User requests: start, equip, purchase, cancel |
| C# to UI | Event<T> properties | One-shot reactions: damage flash, toast, sound |
Health belongs in state so the UI can read it after a reload. A damage flash belongs in an event because replaying it after a reload would be misleading. Use an action for a request from the UI, such as clicking Heal.
Define the bridge
using Loom;
[Bridge]
public partial class UIBridge : LoomBridgeBase
{
public int Health { get; set; } = 100;
[BridgeAction]
public void Heal()
{
Health = 100;
}
public Event<DamageEvent> TookDamage { get; } = new();
}
public sealed class DamageEvent
{
public int Amount { get; set; }
}
The class must be partial and inherit LoomBridgeBase. Loom allows one [Bridge] root per project. Group related values in nested state objects, such as Player or Inventory.
Public properties are state; public Event<T> properties are events. Only
methods tagged [BridgeAction] are callable from the UI. The attribute also
works on methods of nested state DTOs.
Read and call from Solid
Inside a component under BridgeProvider:
import { useBridge } from '@loomgui/bridge';
export function HealthPanel() {
const bridge = useBridge();
return (
<div>
<span>{bridge.health}</span>
<button onClick={() => void bridge.heal()}>Heal</button>
</div>
);
}
C# assignments update the UI. Names become camelCase, and action calls always return promises. The starter configures the provider for you; see UI startup APIs for its contract.
Control exposed members
Use [BridgeIgnore] to exclude a public property from the bridge:
[BridgeIgnore]
public string InternalDebugName { get; set; } = "";
Use [BridgeName] when an exposed name must differ from the C# name:
[BridgeName("hp")]
public int Health { get; set; }
Change the contract
Stop Play mode before changing members, DTOs, enum values, or action
signatures. Loom automatically regenerates the UI contract after Unity
recompiles C#. Update UI/src/bridge.ts mocks to match, and restart an already
running dev server. Do not hand-edit files in UI/generated/.
Continue with State and collections, Actions, Events, and DTO rules.