This is a Yahtzee clone server written in GO.
It currently provides:
- Multiple concurrent games (tables) via the
?table=[Alphanumeric value]
url parameter - Bots that simulate players
- Auto moves for players that do not move in time
-
You may call the public api at https://fujitzee.carr-designs.com/
-
Alternatively, clone and run the server locally:
go run .
A game client will perform the following actions:
- Call
/tables
to present a list of tables to join.
- There is no specific call to join a table. Simply retrieving the state for a table will cause the player to join that table.
- In a loop (waiting for players to ready up):
- Call
/state?player=X&table=Y
to retrieve the latest state - Call
/ready?player=X&table=Y
to toggle if that player is ready or not
- Call
- Once all players have readied up, a count down starts and then gameplay begins. Players may unready to abort the countdown.
- In a loop:
- Call
/state?player=X&table=Y
to retrieve that latest state - Call
/roll/[KEEP]?player=X&table=Y
to roll dice, keeping the specified index of dice to keep - Call
/score/[INDEX]?player=X&table=Y
with an index from validScores to score for that round
- Call
- If the player wishes to exit the game, the client should call
/leave?player=X&table=Y
Retrieve the list of tables by calling /tables
.
DEVELOPER TIP - Call /tables?dev=1
to retrieve a list of hidden tables for developer usage. You can test your client using these "dev*" tables without impacting live player facing games on the public server.
A list of objects with the following properties will be returned:
t
- Table id. Pass this as thetable
url parameter to other calls.n
- Friendly name of table to show in a list for the player to choosep
- Number of players currently connected. 0 if none.m
- Number of max available player slots available. Once a game as begun, this will match the current players connected (a player cannot join mid-game to play, but can watch).
Example response of /tables
call
[{
"t":"basement",
"n":"The Basement",
"p":3,
"m":8
},{
"t":"ai2",
"n":"AI Room - 2 bots",
"p":0,
"m":6
}, ...]
These tables are psuedo real time. Call /state
will run any housekeeping tasks (bot or player auto-move). Since a call to /state
is required to advance the game, a table with bots in it will not actually play until one or more clients are connected and calling /state
. Each player has a limited amount of time to make a move before the server makes a move on their behalf.
- The game is over when all score locations have been filled in (13 rounds of rolling). The next game will begin automatically after a few seconds.
- The game is waiting on more players when round 0 is sent.
- Clients should call
/leave
when a player exits the game or table, rather than rely on the server to eventually drop the player due to inactivity.
You can view the state as-is by calling /view
.
/state
- Advance forward (AI/Game Logic) and return updated state/ready
- Toggle if this player is ready. When joining a table that does not have game in progress, all connected players must ready up to start./roll/[keepRoll]
- Re-roll when it is your player's turn, specifying to either keep or roll the dice at that index.0
means keep and1
means re-roll. For example:- Given roll
11234
, to keep the ones, call/roll/00111
. - Given roll
11234
, to keep "1234" and only roll the first die, call/roll/10000
. - Given roll
31363
, to keep the threes and roll the 1 and 6, call/roll/01010
.
- Given roll
/score/[index]
- Score the specified index from valid scores arrayvs[]
for the current player. The value invs[]
for that index must be0
or greater.-1
indicates an invalid score index (already scored previously), and will not result in a score./leave
- Leave the table. Each client should call this when a player exits the game/view?table=N
- View the current state as-is without advancing, as formatted json. Useful for debugging in a browser alongside the client. NOTE: If you call this for an uninitated game, a different randomly initiated game will be returned every time. Onlytable
query parameter is required./tables
- Returns a list of available REAL tables along with player information. No query parameters are required/updateLobby
- Use to manually force a refresh of state to the Lobby. No query parameters are required.
All paths accept GET or POST for ease of use.
All paths require the query parameters below, unless otherwise specified.
TABLE=[Alphanumeric]
- Required - Use to play in an isolated game. Case insensitive.PLAYER=[Alphanumeric]
- Required for Real - Player's name. Treated as case insensitive unique ID.
RAW=1
- Optional - Use to return key[byte 0]value[byte 0] pairs instead of json output - similar to FujiNet json parsing, with 0x00 used as delimiter instead of line endUC=1
- Optional - Use with raw, to make the result data upper caseLC=1
- Optional - Use with raw, to make the result data lower case
This is focused on a low nested structure and speed of parsing for 8-bit clients.
A client centric state is returned. This means the player array will always start with your client's player first, though all clients will see all players in the same order.
Keys are single character, lower case, to make parsing easier on 8-bit clients. Array keys are 2 character.
(TBD)
{
"p": "ERIC's turn",
"r": 1,
"l": 1,
"a": 0,
"m": 25,
"v": 0,
"d": "15466",
"pl": [
{
"n": "ERIC",
"a": "E",
"sc": [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
},
{
"n": "1AI Clyd",
"a": "1",
"sc": [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
},
{
"n": "2AI Jim",
"a": "2",
"sc": [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
}
],
"vs": [1,0,0,0,5,18,-1,-1,24,0,0,0,0,24,0]
}