board-game-engine-react 0.0.21 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -1
- package/dist/board-game-engine-react.cjs +26 -18
- package/dist/board-game-engine-react.mjs +26 -18
- package/package.json +4 -4
- package/src/index.js +1 -2
- package/src/use-gameserver-connection.js +25 -12
- package/vite.config.js +16 -0
- package/vite.harness.config.js +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,85 @@
|
|
|
1
1
|
# Board Game Engine React
|
|
2
2
|
|
|
3
|
-
React
|
|
3
|
+
React library for running games built with [board-game-engine](https://www.npmjs.com/package/board-game-engine). Renders shared boards, personal boards, choices, and game status; connects to a game server or runs in single-player mode.
|
|
4
4
|
|
|
5
|
+
For game rules, state shape, and engine concepts, see the [board-game-engine](https://www.npmjs.com/package/board-game-engine) package.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install board-game-engine-react react
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## API
|
|
18
|
+
|
|
19
|
+
### `Game`
|
|
20
|
+
|
|
21
|
+
Root UI component. Renders the current game state (shared board, personal boards, abstract choices, status). Wrap with a provider that supplies `gameConnection`.
|
|
22
|
+
|
|
23
|
+
```jsx
|
|
24
|
+
import { Game, useGameserverConnection } from 'board-game-engine-react'
|
|
25
|
+
|
|
26
|
+
function App() {
|
|
27
|
+
const gameConnection = useGameserverConnection({
|
|
28
|
+
server: 'https://your-server.com',
|
|
29
|
+
gameId: 'room-1',
|
|
30
|
+
gameRules: myGameRules,
|
|
31
|
+
clientToken: '…',
|
|
32
|
+
// …other options
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Game
|
|
37
|
+
gameConnection={gameConnection}
|
|
38
|
+
loading={<div>Connecting…</div>}
|
|
39
|
+
isSpectator={false}
|
|
40
|
+
/>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Description |
|
|
46
|
+
|-------------------|---------|-------------|
|
|
47
|
+
| `gameConnection` | object | Connection/state object (e.g. from `useGameserverConnection`). |
|
|
48
|
+
| `loading` | node | Rendered while there is no game state (e.g. connecting). |
|
|
49
|
+
| `isSpectator` | boolean | If true, disables making moves. |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### `useGameserverConnection(options)`
|
|
54
|
+
|
|
55
|
+
Hook that creates and maintains a connection to a game server. Returns an object that includes connection state and methods; pass this object as `gameConnection` to `<Game />`.
|
|
56
|
+
|
|
57
|
+
| Option | Type | Description |
|
|
58
|
+
|---------------------|---------|-------------|
|
|
59
|
+
| `server` | string | Game server URL (required unless `singlePlayer`). |
|
|
60
|
+
| `gameId` | string | Room/game id (required unless `singlePlayer`). |
|
|
61
|
+
| `clientToken` | string | Auth token for the client (required unless `singlePlayer`). |
|
|
62
|
+
| `gameRules` | object | Game definition from board-game-engine (for server-driven games). |
|
|
63
|
+
| `boardgameIOGame` | object | boardgame.io game config (alternative to `gameRules`). |
|
|
64
|
+
| `gameName` | string | Game name sent to server. |
|
|
65
|
+
| `boardgamePlayerID` | string | Player id (e.g. `'0'`, `'1'`). |
|
|
66
|
+
| `numPlayers` | number | Number of players. |
|
|
67
|
+
| `debug` | boolean | Enable debug logging. |
|
|
68
|
+
| `singlePlayer` | boolean | If true, run locally without a server (default: `false`). |
|
|
69
|
+
| `enabled` | boolean | If false, skip connecting (default: `true`). |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Styles
|
|
74
|
+
|
|
75
|
+
Import the default styles so the game UI looks correct:
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
import 'board-game-engine-react/dist/board-game-engine-react.css'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Further reading
|
|
84
|
+
|
|
85
|
+
- **[board-game-engine](https://www.npmjs.com/package/board-game-engine)** — Game rules, state, `Client` options, and engine concepts.
|
|
@@ -29,12 +29,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/index.js
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
|
-
Client: () =>
|
|
32
|
+
Client: () => import_board_game_engine2.Client,
|
|
33
33
|
Game: () => Game,
|
|
34
|
+
gameFactory: () => import_board_game_engine2.gameFactory,
|
|
34
35
|
useGameserverConnection: () => useGameserverConnection
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(index_exports);
|
|
37
|
-
var
|
|
38
|
+
var import_board_game_engine2 = require("board-game-engine");
|
|
38
39
|
|
|
39
40
|
// src/components/game/game.js
|
|
40
41
|
var import_react7 = __toESM(require("react"));
|
|
@@ -301,25 +302,26 @@ function Game({ gameConnection, loading, isSpectator }) {
|
|
|
301
302
|
|
|
302
303
|
// src/use-gameserver-connection.js
|
|
303
304
|
var import_react8 = require("react");
|
|
304
|
-
var
|
|
305
|
-
var Client2 = BoardGameEngine.Client;
|
|
305
|
+
var import_board_game_engine = require("board-game-engine");
|
|
306
306
|
var useGameserverConnection = ({
|
|
307
307
|
server,
|
|
308
|
-
|
|
308
|
+
multiplayer,
|
|
309
|
+
matchID,
|
|
309
310
|
gameRules,
|
|
310
311
|
gameName,
|
|
311
312
|
boardgameIOGame,
|
|
312
|
-
|
|
313
|
-
|
|
313
|
+
playerID,
|
|
314
|
+
credentials,
|
|
314
315
|
numPlayers,
|
|
315
316
|
debug,
|
|
316
|
-
singlePlayer = false,
|
|
317
317
|
enabled = true
|
|
318
318
|
}) => {
|
|
319
319
|
const [_, forceUpdate] = (0, import_react8.useReducer)((x) => x + 1, 0);
|
|
320
320
|
const [connection, setConnection] = (0, import_react8.useState)(null);
|
|
321
321
|
(0, import_react8.useEffect)(() => {
|
|
322
|
-
if (!gameRules && !boardgameIOGame ||
|
|
322
|
+
if (!gameRules && !boardgameIOGame || credentials && !(matchID && enabled && server)) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
323
325
|
const options = {
|
|
324
326
|
server,
|
|
325
327
|
numPlayers,
|
|
@@ -327,22 +329,31 @@ var useGameserverConnection = ({
|
|
|
327
329
|
forceUpdate();
|
|
328
330
|
},
|
|
329
331
|
debug,
|
|
330
|
-
|
|
332
|
+
matchID,
|
|
331
333
|
gameRules,
|
|
332
334
|
boardgameIOGame,
|
|
333
335
|
gameName,
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
336
|
+
playerID,
|
|
337
|
+
credentials,
|
|
338
|
+
multiplayer
|
|
337
339
|
};
|
|
338
|
-
const newConnection = new
|
|
340
|
+
const newConnection = new import_board_game_engine.Client(options);
|
|
339
341
|
newConnection.connect();
|
|
340
342
|
setConnection(newConnection);
|
|
341
343
|
return () => {
|
|
342
344
|
connection?.client?.stop();
|
|
343
345
|
setConnection(null);
|
|
344
346
|
};
|
|
345
|
-
}, [
|
|
347
|
+
}, [
|
|
348
|
+
matchID,
|
|
349
|
+
server,
|
|
350
|
+
playerID,
|
|
351
|
+
credentials,
|
|
352
|
+
gameRules,
|
|
353
|
+
boardgameIOGame,
|
|
354
|
+
enabled,
|
|
355
|
+
multiplayer
|
|
356
|
+
]);
|
|
346
357
|
if (connection) {
|
|
347
358
|
return Object.assign(
|
|
348
359
|
connection,
|
|
@@ -352,6 +363,3 @@ var useGameserverConnection = ({
|
|
|
352
363
|
return {};
|
|
353
364
|
}
|
|
354
365
|
};
|
|
355
|
-
|
|
356
|
-
// src/index.js
|
|
357
|
-
var Client4 = BoardGameEngine2.Client;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/index.js
|
|
2
|
-
import
|
|
2
|
+
import { Client as Client2, gameFactory } from "board-game-engine";
|
|
3
3
|
|
|
4
4
|
// src/components/game/game.js
|
|
5
5
|
import React7 from "react";
|
|
@@ -266,25 +266,26 @@ function Game({ gameConnection, loading, isSpectator }) {
|
|
|
266
266
|
|
|
267
267
|
// src/use-gameserver-connection.js
|
|
268
268
|
import { useEffect as useEffect2, useReducer, useState } from "react";
|
|
269
|
-
import
|
|
270
|
-
var Client2 = BoardGameEngine.Client;
|
|
269
|
+
import { Client } from "board-game-engine";
|
|
271
270
|
var useGameserverConnection = ({
|
|
272
271
|
server,
|
|
273
|
-
|
|
272
|
+
multiplayer,
|
|
273
|
+
matchID,
|
|
274
274
|
gameRules,
|
|
275
275
|
gameName,
|
|
276
276
|
boardgameIOGame,
|
|
277
|
-
|
|
278
|
-
|
|
277
|
+
playerID,
|
|
278
|
+
credentials,
|
|
279
279
|
numPlayers,
|
|
280
280
|
debug,
|
|
281
|
-
singlePlayer = false,
|
|
282
281
|
enabled = true
|
|
283
282
|
}) => {
|
|
284
283
|
const [_, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
285
284
|
const [connection, setConnection] = useState(null);
|
|
286
285
|
useEffect2(() => {
|
|
287
|
-
if (!gameRules && !boardgameIOGame ||
|
|
286
|
+
if (!gameRules && !boardgameIOGame || credentials && !(matchID && enabled && server)) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
288
289
|
const options = {
|
|
289
290
|
server,
|
|
290
291
|
numPlayers,
|
|
@@ -292,22 +293,31 @@ var useGameserverConnection = ({
|
|
|
292
293
|
forceUpdate();
|
|
293
294
|
},
|
|
294
295
|
debug,
|
|
295
|
-
|
|
296
|
+
matchID,
|
|
296
297
|
gameRules,
|
|
297
298
|
boardgameIOGame,
|
|
298
299
|
gameName,
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
playerID,
|
|
301
|
+
credentials,
|
|
302
|
+
multiplayer
|
|
302
303
|
};
|
|
303
|
-
const newConnection = new
|
|
304
|
+
const newConnection = new Client(options);
|
|
304
305
|
newConnection.connect();
|
|
305
306
|
setConnection(newConnection);
|
|
306
307
|
return () => {
|
|
307
308
|
connection?.client?.stop();
|
|
308
309
|
setConnection(null);
|
|
309
310
|
};
|
|
310
|
-
}, [
|
|
311
|
+
}, [
|
|
312
|
+
matchID,
|
|
313
|
+
server,
|
|
314
|
+
playerID,
|
|
315
|
+
credentials,
|
|
316
|
+
gameRules,
|
|
317
|
+
boardgameIOGame,
|
|
318
|
+
enabled,
|
|
319
|
+
multiplayer
|
|
320
|
+
]);
|
|
311
321
|
if (connection) {
|
|
312
322
|
return Object.assign(
|
|
313
323
|
connection,
|
|
@@ -317,11 +327,9 @@ var useGameserverConnection = ({
|
|
|
317
327
|
return {};
|
|
318
328
|
}
|
|
319
329
|
};
|
|
320
|
-
|
|
321
|
-
// src/index.js
|
|
322
|
-
var Client4 = BoardGameEngine2.Client;
|
|
323
330
|
export {
|
|
324
|
-
|
|
331
|
+
Client2 as Client,
|
|
325
332
|
Game,
|
|
333
|
+
gameFactory,
|
|
326
334
|
useGameserverConnection
|
|
327
335
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "board-game-engine-react",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "React library for using board-game-engine",
|
|
5
5
|
"main": "./dist/board-game-engine-react.cjs",
|
|
6
6
|
"module": "./dist/board-game-engine-react.mjs",
|
|
@@ -50,8 +50,6 @@
|
|
|
50
50
|
"@babel/preset-react": "",
|
|
51
51
|
"@chromatic-com/storybook": "^3.2.2",
|
|
52
52
|
"@playwright/test": "^1.49.0",
|
|
53
|
-
"esbuild": "^0.24.0",
|
|
54
|
-
"esbuild-plugin-istanbul": "^0.3.0",
|
|
55
53
|
"@storybook/addon-essentials": "^8.4.6",
|
|
56
54
|
"@storybook/addon-interactions": "^8.4.6",
|
|
57
55
|
"@storybook/addon-onboarding": "^8.4.6",
|
|
@@ -70,6 +68,8 @@
|
|
|
70
68
|
"babel-loader": "^8.3.0",
|
|
71
69
|
"babel-plugin-istanbul": "^6.1.1",
|
|
72
70
|
"cross-env": "^7.0.3",
|
|
71
|
+
"esbuild": "^0.24.0",
|
|
72
|
+
"esbuild-plugin-istanbul": "^0.3.0",
|
|
73
73
|
"eslint": "",
|
|
74
74
|
"eslint-config-standard": "",
|
|
75
75
|
"eslint-plugin-import": "",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"vite": "^5.0.0"
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"board-game-engine": "
|
|
97
|
+
"board-game-engine": "file:../board-game-engine",
|
|
98
98
|
"react": "^18.2.0",
|
|
99
99
|
"react-error-boundary": "^3.1.4",
|
|
100
100
|
"react-transition-group": "^4.4.5"
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import './styles.css'
|
|
2
|
-
|
|
2
|
+
export { Client, gameFactory } from 'board-game-engine'
|
|
3
3
|
|
|
4
4
|
export { default as Game } from './components/game/game.js'
|
|
5
5
|
export { useGameserverConnection } from './use-gameserver-connection'
|
|
6
|
-
export const Client = BoardGameEngine.Client
|
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import { useEffect, useReducer, useState } from 'react'
|
|
2
|
-
import
|
|
3
|
-
const Client = BoardGameEngine.Client
|
|
2
|
+
import { Client } from 'board-game-engine'
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
export const useGameserverConnection = ({
|
|
7
6
|
server,
|
|
8
|
-
|
|
7
|
+
multiplayer,
|
|
8
|
+
matchID,
|
|
9
9
|
gameRules,
|
|
10
10
|
gameName,
|
|
11
11
|
boardgameIOGame,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
playerID,
|
|
13
|
+
credentials,
|
|
14
14
|
numPlayers,
|
|
15
15
|
debug,
|
|
16
|
-
singlePlayer = false,
|
|
17
16
|
enabled = true,
|
|
18
17
|
}) => {
|
|
19
18
|
const [_, forceUpdate] = useReducer(x => x + 1, 0)
|
|
20
19
|
const [connection, setConnection] = useState(null)
|
|
21
20
|
|
|
22
21
|
useEffect(() => {
|
|
23
|
-
if (
|
|
22
|
+
if (
|
|
23
|
+
!gameRules && !boardgameIOGame
|
|
24
|
+
|| credentials && !(matchID && enabled && server)
|
|
25
|
+
) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
24
28
|
|
|
25
29
|
const options = {
|
|
26
30
|
server,
|
|
@@ -29,13 +33,13 @@ export const useGameserverConnection = ({
|
|
|
29
33
|
forceUpdate()
|
|
30
34
|
},
|
|
31
35
|
debug,
|
|
32
|
-
|
|
36
|
+
matchID,
|
|
33
37
|
gameRules,
|
|
34
38
|
boardgameIOGame,
|
|
35
39
|
gameName,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
playerID,
|
|
41
|
+
credentials,
|
|
42
|
+
multiplayer
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
const newConnection = new Client(options)
|
|
@@ -48,7 +52,16 @@ export const useGameserverConnection = ({
|
|
|
48
52
|
connection?.client?.stop()
|
|
49
53
|
setConnection(null)
|
|
50
54
|
}
|
|
51
|
-
}, [
|
|
55
|
+
}, [
|
|
56
|
+
matchID,
|
|
57
|
+
server,
|
|
58
|
+
playerID,
|
|
59
|
+
credentials,
|
|
60
|
+
gameRules,
|
|
61
|
+
boardgameIOGame,
|
|
62
|
+
enabled,
|
|
63
|
+
multiplayer,
|
|
64
|
+
])
|
|
52
65
|
|
|
53
66
|
if (connection) {
|
|
54
67
|
return Object.assign(
|
package/vite.config.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { resolve } from 'path'
|
|
2
|
+
import { defineConfig } from 'vite'
|
|
3
|
+
import react from '@vitejs/plugin-react'
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
root: resolve(__dirname, 'test-app'),
|
|
7
|
+
plugins: [react()],
|
|
8
|
+
server: {
|
|
9
|
+
port: 5174,
|
|
10
|
+
},
|
|
11
|
+
resolve: {
|
|
12
|
+
alias: {
|
|
13
|
+
'board-game-engine-react': resolve(__dirname, 'dist/board-game-engine-react.mjs'),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
})
|
package/vite.harness.config.js
CHANGED