Define a command
Create one factory for your game state and event registry:advance still controls whose turn it is. .isAvailable() adds a rule for when the active player should see the command.
Availability and validation
Use the two checks for different questions:.isAvailable()answers “should this command be offered now?” It powersgetAvailableCommands()in the client..validate()answers “is this exact attempt legal?” It returns a stable rejectionreasonthat the frontend can handle.
.validate(). Availability can change between rendering a button and submitting the command.
Validation can also return structured metadata:
Execute the change
.execute() receives mutable game, the validated command, deterministic rng, and typed emitEvent when your factory has an event registry.
Use rng for random outcomes:
Guide the frontend with discovery
Discovery lets the UI ask the engine for legal choices before it sends a command. This is useful when options depend on hidden or changing state.nextInput. The completed input must match the command schema.
Put commands in stages
Control when and by whom commands can run.