Defining Commands
Commands are plain Go structs that embedBaseCommand and implement the Command interface. This interface requires a single Name() method that returns a unique string identifier.
Handling Commands
Just like with components, you must register a command type with the world beforeStartGame. The service only accepts commands that are registered:
Different systems can handle the same command type. This is useful for when you want a single
command to trigger multiple game logic and/or side effects.
Iterating Over Commands
Usew.Commands[T]() to loop through all commands of type T received this tick. Each iteration yields a CommandContext whose fields hold the command data and metadata.
To access the command’s payload, read the Payload field:
Senders
Every command knows who sent it, which you can use for authorization checks like verifying entity ownership. A sender is either a player or another shard:cmd.Player()returns the player ID andtruewhen a client sent the command. Cardinal takes the ID from the client’s auth token, so a client cannot claim to be another player. Player IDs are the same on every shard of a project.cmd.Shard()returns the sending shard’s address (<project>.<shard_id>, such asmy-game.matchmaking) andtruewhen another shard sent the command withw.SendToShard.cmd.Sender()returns either one, for code that doesn’t care which, such as logs.
Sending Commands
Use the client SDK to send commands to the server:- Unity C#
- TypeScript
Command-Reply Pattern
Commands are asynchronous by design. When you send a command, you receive an acknowledgment, but not the result of the command’s execution. If you need a result, you typically emit an event from the system that processes the command and subscribe to it from the client. Some command types are more synchronous in nature, like updating game config, where every command has a corresponding result event. For these cases, use the synchronous command method, which handles the temporary event subscription for you and returns the result event directly:- Unity C#
- TypeScript
w.SendTo(playerID, event), using the player ID from cmd.Player(). A targeted reply answers only that player’s pending requests for that event name, while w.Broadcast answers every player’s.
Inter-Shard Commands
In a multi-shard setup, you can send commands from within a system to another shard. This allows you to trigger systems in other shards or coordinate game state.Defining Shard Targets
To send an inter-shard command, construct anOtherWorld value for each destination and pass it into the system:
The convention is to place this in
pkg/other_worlds/other_world.go.OtherWorld represents a specific remote shard and is used to route commands to the correct destination.
Sending Inter-Shard Commands
Use the world’sSendToShard to dispatch a command to another shard. Pass the destination OtherWorld and the command you want to send:
RegisterCommand and reads it with w.Commands[T]().
The target shard must register the command type you’re sending. If the type is not registered
there, the target rejects the command and it is not delivered.