sggs game protocol
Games are implemented by commands which accept arguments and are expected to write to stdout and return exit codes as described below.
Commands
Commands will be run with current working directory a state directory specific to a single instance of the game.
Locking is dealt with, you may assume that commands will run sequentially.
All output is to stdout.
Internal errors may be written to stderr, they will go in the server log.
There are three kinds of command, split according to what filesystem operations they may use.
Info commands
These commands should not access the filesystem.
describe
Print a one-line description of the game.
help
Print long-form gemtext explanation of how to play the game.
This should discuss the rules, and optionally also detail init arguments and move syntax.
A title line "# Help on $game" will automatically be prepended.
setarg PRE_ARG
PRE_ARG is a user-submitted string describing desired options for the game, or the empty string if the user has not selected any options.
Either return 0 and output ARG, a string which will be passed as an argument to 'init' and 'players',
or exit 1 and output a one-line prompt for input which will be passed as a new PRE_ARG parameter,
or exit 2 and output gemtext (with \n terminated lines), which may use link lines "=> ?[percent-encoded PRE_ARG]" to call setarg with a new parameter.
Whitespace will be stripped from the start and end of output to obtain ARG.
In the case of empty output, ARG is set to the empty string.
It is recommended to use this to denote default options.
In particular, if the game does not accept options, 'setarg' should just exit 0.
players ARG
Output permitted number of players as a single positive integer.
If nothing is output, arbitrarily many players can be tried (the exit code of 'init' can then be used to enforce conditions on the number of players).
Read-only commands
These commands may read from files in the working directory, but not outside it, and may not write to the filesystem.
showstate P
Print gemtext document showing current state for player P,
or for a neutral observer if P=0.
canmove P
Exit 5 if game is over.
Exit 4 if game is running, but player can't move now (or P=0).
Else exit 0, and optionally write gemtext providing links "=> move?[percent-encoded move]" for making a move;
default is "=> move Make move".
winner
Output players who have won, separated by spaces.
Read-write commands
These commands may use arbitrary filesystem operations within the working directory, but not outside it.
init ARG N
ARG is as set by setarg.
N is the number of players.
Set up state and exit 0,
or exit 4 and output an error message if N is bad,
or exit 5 if ARG is bad or there is some other error.
move P MOVE
If MOVE can be interpreted as a currently valid move for player P, update state and exit 0.
Otherwise, exit 1 and output a one-line prompt for input which will be passed as a new MOVE parameter,
or exit 2 and output gemtext (with \n terminated lines), which can contain links "=> ?[percent-encoded move]" for trying a different MOVE parameter,
or exit 4 and output an error.
P is guaranteed to be a valid player.
resign P
Update state to reflect that player P has resigned.
P is guaranteed to be a valid player.
Security checklist
The program must
- not read or write outside of the current directory
- handle user input securely (setarg and move)
- terminate timelily