Commands allow you to modify game state on your World Engine shard. This guide covers everything from basic command sending to advanced patterns with TypeScript interfaces and error handling.
The simplest command sends data to modify game state:
Basic Command
Copy
import { shard } from './shard'export async function spawnPlayer() { const { error } = await shard.sendCommand({ name: 'player-spawn', payload: { // TODO: when persona is implemented, we might not need to send auth id and name argus_auth_id: 'abc123', argus_auth_name: 'John Doe', x: 100, y: 200, }, }) if (error) { console.error(error) return { error } } return { success: true }}
This command creates a new player entity with the specified properties.
For better type safety and maintainability, declare command interfaces that match your Cardinal command structs:
Type Safety
Copy
import { shard } from './shard'// Sync with your Cardinal PlayerSpawnCommand structinterface SpawnPlayerCommand { name: 'player-spawn' payload: { argus_auth_id: string argus_auth_name: string x: number y: number }}export async function spawnPlayer({ authId, name, x, y,}: { authId: string name: string x: number y: number}) { const { error } = await shard.sendCommand({ name: 'player-spawn', payload: { argus_auth_id: authId, argus_auth_name: name, x, y, }, } satisfies SpawnPlayerCommand) // TypeScript will validate the structure if (error) return { error } return { success: true }}
TypeScript Tip: The satisfies operator ensures your command object matches the interface
without losing type inference. This catches typos and structural mismatches at compile time.
Most commands require user authentication. Here’s how to integrate with Argus Auth:
With Argus Auth
Copy
import { world } from './sdk'import { shard } from './shard'interface SpawnPlayerCommand { name: 'player-spawn' payload: { argus_auth_id: string argus_auth_name: string x: number y: number }}export async function spawnPlayer({ x, y }: { x: number; y: number }) { const user = world.auth.getUser() if (!user) { return { error: 'No Argus ID user found, are you not logged into Argus ID?' } } const { id, name } = user return shard.sendCommand({ name: 'player-spawn', payload: { argus_auth_id: id, argus_auth_name: name, x, y }, } satisfies SpawnPlayerCommand)}
Always declare interfaces that match your Cardinal command structs
Use satisfies for compile-time type checking
Check for errors in the response
Keep payload structure consistent with your Go structs
Use descriptive command names that match your Cardinal system names
Cardinal Command Struct Example
Your TypeScript interfaces should match your Go command structs:
Cardinal Command Struct Example
Copy
type PlayerSpawnCommand struct { cardinal.BaseCommand ArgusAuthID string `json:"argus_auth_id"` ArgusAuthName string `json:"argus_auth_name"` Position struct { X int `json:"x"` Y int `json:"y"` } `json:"position"`}func (c PlayerSpawnCommand) Name() string { return "player-spawn"}