Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 157 additions & 70 deletions docs/documentation/api/Lobby.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,123 @@
# Lobby

### React components
The [Server](/api/Server) hosts the Lobby REST API that can be used to create
and join matches. It is particularly useful when you want to
authenticate clients to prove that they have the right to send
actions on behalf of a player.

Authenticated matches are created with server-side tokens for each player.
You can create a match with the `create` API call, and join a player to a
match with the `join` API call.

A match that is authenticated will not accept moves from a client on behalf
of a player without the appropriate credential token.

Use the `create` API call to create a match that requires credential tokens.
When you call the `join` API, you can retrieve the credential token for a
particular player.

## Clients

<!-- tabs:start -->
### **Plain JS**

boardgame.io provides a lightweight wrapper around the Fetch API to simplify
using a Lobby API server from the client.


```js
import { LobbyClient } from 'boardgame.io/client';

You can use the lobby component with the code below:
const lobbyClient = new LobbyClient({ server: 'http://localhost:8000' });

lobbyClient.listGames()
.then(console.log) // => ['chess', 'tic-tac-toe']
.catch(console.error);
```

### **React**

The React lobby component provides a more high-level client, including UI
for listing, joining, and creating matches.

```js
import { Lobby } from 'boardgame.io/react';
import { TicTacToe } from './Game';
import { TicTacToeBoard } from './Board';

<Lobby
gameServer={`https://${window.location.hostname}:8000`}
lobbyServer={`https://${window.location.hostname}:8000`}
gameComponents={importedGames}
gameComponents={[
{ game: TicTacToe, board: TicTacToeBoard }
]}
/>;
```

`importedGames` is an array of objects with these fields:
`gameComponents` expects an array of objects with these fields:

- `game`: The boardgame.io `Game` definition.
- `game`: A boardgame.io `Game` definition.
- `board`: The React component that will render the board.

### Server-side API
<!-- tabs:end -->

The [Server](/api/Server) hosts the Lobby REST API that can be used to create and join matches. It is particularly useful when you want to
authenticate clients to prove that they have the right to send
actions on behalf of a player.
## REST API

### Listing available game types

#### GET `/games`

Returns an array of names for the games this server is running.

#### Using a LobbyClient instance

```js
const games = await lobbyClient.listGames();
```

Authenticated games are created with server-side tokens for each player. You can create a match with the `create` API call, and join a player to a match with the `join` API call.
### Listing all matches for a given game

A game that is authenticated will not accept moves from a client on behalf of a player without the appropriate credential token.
#### GET `/games/{name}`

Use the `create` API call to create a match that requires credential tokens. When you call the `join` API, you can retrieve the credential token for a particular player.
Returns all match instances of the game named `name`.

#### Configuration
Returns an array of `matches`. Each instance has fields:

You can pass `lobbyConfig` to configure the Lobby API
during server startup:
- `matchID`: the ID of the match instance.

- `players`: the list of seats and players that have joined the game, if any.

- `setupData` (optional): custom object that was passed to the game `setup` function.

#### Using a LobbyClient instance

```js
server.run({ port: 8000, lobbyConfig });
const { matches } = await lobbyClient.listMatches('tic-tac-toe');
```

Options are:
### Getting a specific match by its ID

#### GET `/games/{name}/{id}`

- `apiPort`: If specified, it runs the Lobby API in a separate Koa server on this port. Otherwise, it shares the same Koa server runnning on the default boardgame.io `port`.
- `apiCallback`: Called when the Koa server is ready. Only applicable if `apiPort` is specified.
Returns a match instance given its matchID.

Returns a match instance. Each instance has fields:

- `matchID`: the ID of the match instance.

- `players`: the list of seats and players that have joined the match, if any.

#### Creating a match
- `setupData` (optional): custom object that was passed to the game `setup` function.

#### Using a LobbyClient instance

```js
const match = await lobbyClient.getMatch('tic-tac-toe', 'matchID');
```

##### POST `/games/{name}/create`
### Creating a match

#### POST `/games/{name}/create`

Creates a new authenticated match for a game named `name`.

Expand All @@ -61,85 +131,93 @@ Accepts three parameters:

Returns `matchID`, which is the ID of the newly created game instance.

#### Joining a game
#### Using a LobbyClient instance

```js
const { matchID } = await lobbyClient.createMatch('tic-tac-toe', {
numPlayers: 2
});
```

### Joining a match

##### POST `/games/{name}/{id}/join`
#### POST `/games/{name}/{id}/join`

Allows a player to join a particular match instance `id` of a game named `name`.

Accepts three JSON body parameters:

- `playerID` (required): the ordinal player in the game that is being joined (0, 1...).
- `playerID` (required): the ordinal player in the match that is being joined (`'0'`, `'1'`...).

- `playerName` (required): the display name of the player joining the game.
- `playerName` (required): the display name of the player joining the match.

- `data` (optional): additional information associated to the player.
- `data` (optional): additional metadata to associate with the player.

Returns `playerCredentials` which is the token this player will require to authenticate their actions in the future.

#### Update a player's information
#### Using a LobbyClient instance

##### POST `/games/{name}/{id}/update`
```js
const { playerCredentials } = await lobbyClient.joinMatch(
'tic-tac-toe',
'matchID',
{
playerID: '0',
playerName: 'Alice',
}
);
```

### Updating a player’s metadata

#### POST `/games/{name}/{id}/update`

Rename and/or update additional information of a user in the match instance `id` of a game named `name` previously joined by the player.
Rename and/or update additional metadata for a player in the match instance `id` of a game named `name` previously joined by the player.

Accepts four parameters, requires at least one of the two optional parameters:

- `playerID` (required): the ID used by the player in the game (0,1...).
- `playerID` (required): the ID used by the player in the match (0,1...).

- `crendentials` (required): the authentication token of the player.
- `credentials` (required): the authentication token of the player.

- `newName` (optional): the new name of the player.

- `data` (optional): additional information associated to the player.
- `data` (optional): additional metadata to associate with the player.

#### Using a LobbyClient instance

```js
await lobbyClient.updatePlayer('tic-tac-toe', 'matchID', {
playerID: '0',
credentials: 'playerCredentials',
newName: 'Al',
});
```

#### Leaving a match
### Leaving a match

##### POST `/games/{name}/{id}/leave`
#### POST `/games/{name}/{id}/leave`

Leave the match instance `id` of a game named `name` previously joined by the player.

Accepts two parameters, all required:

- `playerID`: the ID used by the player in the game (0, 1...).
- `playerID`: the ID used by the player in the match (0, 1...).

- `credentials`: the authentication token of the player.

#### Listing all match instances of a given game

##### GET `/games/{name}`

Returns all match instances of the game named `name`.

Returns an array of `matches`. Each instance has fields:

- `matchID`: the ID of the match instance.

- `players`: the list of seats and players that have joined the game, if any.
#### Using a LobbyClient instance

- `setupData` (optional): custom object that was passed to the game `setup` function.

#### Getting specific instance of a match by its ID

##### GET `/games/{name}/{id}`

Returns a match instance given its matchID.

Returns a match instance. Each instance has fields:

- `matchID`: the ID of the match instance.

- `players`: the list of seats and players that have joined the game, if any.

- `setupData` (optional): custom object that was passed to the game `setup` function.

#### Client Authentication

All actions for an authenticated game require an additional payload field `credentials`, which must be the given secret associated with the player.
```js
await lobbyClient.leaveMatch('tic-tac-toe', 'matchID', {
playerID: '0',
credentials: 'playerCredentials',
});
```

#### Playing again
### Playing again

##### POST `/games/{name}/{id}/playAgain`
#### POST `/games/{name}/{id}/playAgain`

- `{name}` (required): the name of the game being played again.

Expand All @@ -149,12 +227,21 @@ Given a previous match, generates a match ID where users should go if they want

Accepts these parameters:

- `playerID` (required): the player ID of the player on the previous game.
- `playerID` (required): the player ID of the player in the previous match.

- `credentials` (required): player's credentials.

`numPlayers` (optional): the number of players. Defaults to the `numPlayers` value of the previous room.
- `numPlayers` (optional): the number of players. Defaults to the `numPlayers` value of the previous match.

`setupData` (optional): custom object that was passed to the game `setup` function. Defaults to the `setupData` object of the previous room.
- `setupData` (optional): custom object that was passed to the game `setup` function. Defaults to the `setupData` object of the previous room.

Returns `nextMatchID`, which is the ID of the newly created match that the user should go to play again.

#### Using a LobbyClient instance

```js
const { nextMatchID } = await lobbyClient.playAgain('tic-tac-toe', 'matchID', {
playerID: '0',
credentials: 'playerCredentials',
});
```
21 changes: 21 additions & 0 deletions docs/documentation/api/Server.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@ server.run(8000);
server.run(8000, () => console.log("server running..."));
```

#### With custom Lobby settings

You can pass `lobbyConfig` to configure the Lobby API during server startup:

```js
const lobbyConfig = {
apiPort: 8080,
apiCallback: () => console.log('Running Lobby API on port 8080...'),
};

server.run({ port: 8000, lobbyConfig });
```

Options are:

- `apiPort`: If specified, it runs the Lobby API in a separate Koa server on
this port. Otherwise, it shares the same Koa server running on the default
boardgame.io `port`.
- `apiCallback`: Called when the Koa server is ready. Only applicable if
`apiPort` is specified.

#### With HTTPS

```js
Expand Down
3 changes: 2 additions & 1 deletion packages/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
*/

import { Client } from '../src/client/client';
import { LobbyClient } from '../src/lobby/client';

export { Client };
export { Client, LobbyClient };
Loading