Actions
Expose public C# methods that the UI can call through generated TypeScript action proxies.
Actions are public C# methods tagged [BridgeAction]. A public method without the attribute stays internal, only [BridgeAction] methods are exposed.
Every generated TypeScript action returns a promise, including actions backed by
synchronous C# methods.
[BridgeAction]
public void StartGame()
{
CurrentScreen = GameScreen.Hud;
}
await bridge.startGame();
Parameters
Actions can take any number of parameters:
[BridgeAction]
public void SetVolume(float value)
{
Volume = value;
}
[BridgeAction]
public void MovePlayer(int x, int y, float speed)
{
// ...
}
await bridge.setVolume(0.8);
await bridge.movePlayer(3, 4, 1.5);
You can also group related values in a DTO, handy when the set of fields evolves (new fields don’t change the call signature):
public sealed class BuyItemRequest
{
public string Sku { get; set; } = "";
public int Quantity { get; set; }
}
[BridgeAction]
public PurchaseResult BuyItem(BuyItemRequest request)
{
// ...
}
Return values
Actions may return a value:
[BridgeAction]
public int GetCoins()
{
return Coins;
}
The UI receives a promise:
const coins = await bridge.getCoins();
Async work
Use async actions when the game operation is asynchronous:
[BridgeAction]
public async Task<Profile> LoadProfile()
{
return await ProfileService.LoadAsync();
}
Keep actions focused on user intent. Long-running work should update bridge state as it progresses so the UI can show loading or error states.
Nested actions
[BridgeAction] also goes on a method of a nested state DTO. The action surfaces
at its dotted path on the bridge, mirroring the C# structure:
public sealed class BootState
{
public float Progress { get; set; }
[BridgeAction]
public void SetProgress(float value) => Progress = value;
}
await bridge.boot.setProgress(0.5);
Errors
If an action throws, the UI promise rejects. Handle expected failures in the UI:
try {
await bridge.buyItem({ sku, quantity: 1 });
} catch (error) {
setError(String(error));
}