@netforge/tabletop 0.1.0 → 0.2.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.
Files changed (3) hide show
  1. package/README.md +53 -5
  2. package/package.json +24 -9
  3. package/src/boot.ts +1 -1
package/README.md CHANGED
@@ -1,7 +1,55 @@
1
1
  # @netforge/tabletop
2
2
 
3
- The client kit the board-style Net Forge templates share (tower defense,
4
- idle, card battler, monster collector): the room connection and input clock
5
- for rules genres, the styled 3D stage, the store, stake and gear wiring, and
6
- the HUD shell. Used by `@netforge/template-*` clients; see
7
- `@netforge/kit-play` to run one on your own computer.
3
+ The shared client kit for the Net Forge board-style game templates (tower defense, idle, card battler and monster collector): the room connection and input clock for rules genres, the styled 3D stage, the store, stake and gear wiring, and the HUD shell.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @netforge/tabletop
9
+ ```
10
+
11
+ Node 20 or later. The package ships TypeScript source (ES modules) for a bundler such as Vite. It is used by template clients (`@netforge/template-tower`, `template-idle`, `template-cards`, `template-collector`). Game code in `src/game.ts` never imports it.
12
+
13
+ ## Example
14
+
15
+ A board template's client boots with one call. This is the shape the tower defense client uses:
16
+
17
+ ```ts
18
+ import { bootBoard } from "@netforge/tabletop";
19
+ import { GAME_VERSION, PLACE, TEMPLATE, towerAdapter, towerManifest } from "@netforge/template-tower";
20
+
21
+ const app = await bootBoard({
22
+ adapter: towerAdapter(),
23
+ manifest: towerManifest(),
24
+ template: TEMPLATE,
25
+ place: PLACE,
26
+ version: GAME_VERSION,
27
+ labels: { title: "COGSPIRE", rules: {}, skus: {}, upgrades: {}, loading: "Winding the spire", help: "Click a tile to build" },
28
+ theme, // HudTheme: accent, gold, ink, dim, panel, bg, font, display, radius
29
+ coin: { name: "Cog", symbol: "COG", logo: null },
30
+ cosmetics: {},
31
+ swatch: () => "#c9a15a",
32
+ ground: { w: 20, h: 12 },
33
+ // plus the template's own draw, input and autopilot hooks (see BoardBootOptions)
34
+ });
35
+ ```
36
+
37
+ ## Key API
38
+
39
+ - `bootBoard(options)`: connects to the room, builds the stage and the HUD, and wires the store, stake and gear for a rules genre.
40
+ - `joinBoard(adapter, join)` and `InputClock`: the room connection and the input clock for rules genres; `roomsEndpoint(params)` picks the room server from the page URL.
41
+ - `BoardStage` and `fallbackShape`: the styled 3D stage and placeholder shapes.
42
+ - `Hud`, `wireStore`, `$` and `cssColor`: the HUD shell and store panel.
43
+ - `wireStake`, `wireGear`, `gearOf` and `wirePot`: the buy-in run, losable gear and pots.
44
+ - `mockKit`: the in-page store backend used for local play.
45
+ - `hostFlags`, `namedPlayer`, `onHostPlayer`, `postReady`, `storeNote`: how a page talks to the Net Forge studio or to kit play when it is embedded.
46
+
47
+ To run a board game locally, use `@netforge/kit-play`.
48
+
49
+ ## Docs
50
+
51
+ - https://forge.netnet.capital/docs/packages/tabletop
52
+
53
+ ## License
54
+
55
+ MIT. See `LICENSE` and `NOTICE`.
package/package.json CHANGED
@@ -1,11 +1,25 @@
1
1
  {
2
2
  "name": "@netforge/tabletop",
3
- "version": "0.1.0",
4
- "description": "The client kit the board-style templates share (tower defense, idle, card battler, monster collector): the room connection and input clock for rules genres, the styled 3D stage, the Kit store, stake and gear wiring, and the HUD shell.",
3
+ "version": "0.2.0",
4
+ "description": "Shared client kit for Net Forge board-style game templates (tower defense, idle, card battler, monster collector): room connection, input clock, 3D stage, store and HUD.",
5
+ "keywords": [
6
+ "game-engine",
7
+ "multiplayer",
8
+ "browser-game",
9
+ "threejs",
10
+ "tower-defense",
11
+ "card-game",
12
+ "idle-game",
13
+ "monster-collector",
14
+ "typescript",
15
+ "gamedev",
16
+ "net-forge"
17
+ ],
5
18
  "license": "MIT",
6
19
  "type": "module",
7
20
  "exports": {
8
- ".": "./src/index.ts"
21
+ ".": "./src/index.ts",
22
+ "./package.json": "./package.json"
9
23
  },
10
24
  "files": [
11
25
  "src",
@@ -14,22 +28,26 @@
14
28
  "NOTICE",
15
29
  "LICENSE"
16
30
  ],
31
+ "sideEffects": false,
17
32
  "publishConfig": {
18
33
  "access": "public"
19
34
  },
35
+ "homepage": "https://forge.netnet.capital/docs/packages/tabletop",
36
+ "bugs": {
37
+ "url": "https://github.com/netnetdev/net-forge/issues"
38
+ },
20
39
  "repository": {
21
40
  "type": "git",
22
41
  "url": "git+https://github.com/netnetdev/net-forge.git",
23
42
  "directory": "packages/tabletop"
24
43
  },
25
- "homepage": "https://github.com/netnetdev/net-forge/tree/main/packages/tabletop#readme",
26
44
  "engines": {
27
45
  "node": ">=20"
28
46
  },
29
47
  "dependencies": {
30
48
  "three": "0.186.1",
31
- "@netforge/asset-library": "0.1.0",
32
- "@netforge/engine": "0.1.0"
49
+ "@netforge/asset-library": "0.2.0",
50
+ "@netforge/engine": "0.2.0"
33
51
  },
34
52
  "devDependencies": {
35
53
  "@types/node": "22.20.1",
@@ -37,9 +55,6 @@
37
55
  "typescript": "5.8.3",
38
56
  "vitest": "3.2.7"
39
57
  },
40
- "bugs": {
41
- "url": "https://github.com/netnetdev/net-forge/issues"
42
- },
43
58
  "scripts": {
44
59
  "typecheck": "tsc -p tsconfig.json",
45
60
  "test": "vitest run --passWithNoTests"
package/src/boot.ts CHANGED
@@ -167,7 +167,7 @@ export async function bootBoard<S>(o: BoardBootOptions<S>): Promise<BoardApp<S>>
167
167
  if (friendRoomId && conn.roomId !== friendRoomId) setTimeout(() => hud.toast("Room full, new room"), 500);
168
168
  if (conn.welcome.version !== o.version) setTimeout(() => hud.toast("Update ready. Reload."), 800);
169
169
  const autopilot = params.get("autopilot") === "1";
170
- const linkFor = (base: string) => `${base}?room=${conn.roomId}${place !== o.place ? `&place=${encodeURIComponent(place)}` : ""}${params.has("server") ? `&server=${encodeURIComponent(endpoint)}` : ""}`;
170
+ const linkFor = (base: string) => `${base}?room=${conn.roomId}${place !== o.place ? `&place=${encodeURIComponent(place)}` : ""}${params.has("server") ? `&server=${encodeURIComponent(endpoint)}` : ""}${params.has("game") ? `&game=${encodeURIComponent(params.get("game") ?? "")}` : ""}`;
171
171
  const keep = ["autopilot", "webgl", "stats", "style", "preview", "shapes", "host", "coin", "title", "player", "library"].filter((k) => params.has(k)).map((k) => `&${k}=${encodeURIComponent(params.get(k) ?? "")}`).join("");
172
172
  history.replaceState(null, "", `${linkFor(location.pathname)}${keep}`);
173
173