@indiegems/gem-web-sdk 9.1.2 → 9.1.4
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/CHANGELOG.md +12 -0
- package/README.md +1 -2
- package/dist/gem-web-sdk.esm.js +1 -1
- package/dist/gem-web-sdk.function.js +1 -1
- package/dist/gem-web-sdk.game.js +1 -1
- package/dist/gem-web-sdk.min.js +1 -1
- package/dist/gem-web-sdk.sdk.js +1 -1
- package/dist/gem-web-sdk.server.js +1 -1
- package/docs/api/api-reference-game.md +2564 -2564
- package/docs/api/api-reference-server.md +706 -706
- package/docs/api/reference.json +518 -1927
- package/docs/changelog.md +12 -0
- package/docs/getting-started.md +5 -5
- package/docs/manifest.json +10 -10
- package/docs/platform-rules.md +2 -2
- package/docs/server-bundles.md +4 -4
- package/docs/serverless-functions-js.md +29 -1
- package/package.json +1 -1
package/docs/changelog.md
CHANGED
|
@@ -16,6 +16,18 @@ Its entries are grouped under up to five headings:
|
|
|
16
16
|
- **Rebuild**: a type changed. Recompile against the new version; code that compiles today keeps compiling unless the entry says otherwise.
|
|
17
17
|
- **New capability**: something a game can now do. Nothing changes unless you use it.
|
|
18
18
|
|
|
19
|
+
## 9.1.4
|
|
20
|
+
|
|
21
|
+
Upgrading from 9.1.3. Impact: none.
|
|
22
|
+
|
|
23
|
+
Nothing in this release asks anything of a game.
|
|
24
|
+
|
|
25
|
+
## 9.1.3
|
|
26
|
+
|
|
27
|
+
Upgrading from 9.1.2. Impact: none.
|
|
28
|
+
|
|
29
|
+
Nothing in this release asks anything of a game.
|
|
30
|
+
|
|
19
31
|
## 9.1.2
|
|
20
32
|
|
|
21
33
|
Upgrading from 9.1.1. Impact: none.
|
package/docs/getting-started.md
CHANGED
|
@@ -50,7 +50,7 @@ either way.
|
|
|
50
50
|
```jsonc
|
|
51
51
|
// package.json
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@indiegems/gem-web-sdk": "9.1.
|
|
53
|
+
"@indiegems/gem-web-sdk": "9.1.4"
|
|
54
54
|
}
|
|
55
55
|
```
|
|
56
56
|
|
|
@@ -248,12 +248,12 @@ Once it is open:
|
|
|
248
248
|
- **Fullscreen covers it.** Leave fullscreen to see it again.
|
|
249
249
|
|
|
250
250
|
The panel is also reachable from inside your game — see
|
|
251
|
-
[GemDevTools.open](
|
|
251
|
+
[GemDevTools.open](api/api-reference-game.md#gemdevtools-open), which answers
|
|
252
252
|
`false` for a session that was not granted it rather than throwing — though it does reject if a
|
|
253
253
|
panel it _is_ allowed to open fails to load, so catch it either way.
|
|
254
254
|
|
|
255
255
|
If you put your own button on it, gate the button on
|
|
256
|
-
[`onDevToolsPermissionChange`](
|
|
256
|
+
[`onDevToolsPermissionChange`](api/api-reference-game.md#gemoptions-ondevtoolspermissionchange)
|
|
257
257
|
rather than checking anything at boot:
|
|
258
258
|
|
|
259
259
|
```js
|
|
@@ -559,5 +559,5 @@ credential made for a build pipeline can upload and promote, and cannot delete.
|
|
|
559
559
|
items, shops or loot. Start with **[the shop tutorial](game-economy-tutorial.md)** to build one.
|
|
560
560
|
- **[Rooms and the match lifecycle](rooms-and-matches.md)** — if it is multiplayer.
|
|
561
561
|
|
|
562
|
-
The [API reference](
|
|
563
|
-
|
|
562
|
+
The [API reference](api/api-reference-game.md) has every symbol the SDK publishes, with
|
|
563
|
+
signatures and descriptions; the [server half](api/api-reference-server.md) is beside it.
|
package/docs/manifest.json
CHANGED
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
"file": "changelog.md",
|
|
36
|
-
"sha256": "
|
|
37
|
-
"updated": "2026-10-
|
|
36
|
+
"sha256": "6333e652b2c3ffade4ced6759436b8ab3dcb95b25a43c1bd82fe9a6f23fd8a7d",
|
|
37
|
+
"updated": "2026-10-10T01:45:03Z"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"file": "cross-promotion.md",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"file": "getting-started.md",
|
|
71
|
-
"sha256": "
|
|
72
|
-
"updated": "2026-10-
|
|
71
|
+
"sha256": "22fab7f0fd67966239c38541a8620ac7fe614f100b96df3e94570b573d4a9f61",
|
|
72
|
+
"updated": "2026-10-10T01:45:03Z"
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"file": "inventory-and-catalogs.md",
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
95
|
"file": "platform-rules.md",
|
|
96
|
-
"sha256": "
|
|
97
|
-
"updated": "2026-10-
|
|
96
|
+
"sha256": "b259bcebc6ae12b1db9c7279a6e2adb174af9d60090bf31001e23616f6423fbf",
|
|
97
|
+
"updated": "2026-10-10T00:12:33Z"
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
"file": "player-sign-in.md",
|
|
@@ -123,13 +123,13 @@
|
|
|
123
123
|
},
|
|
124
124
|
{
|
|
125
125
|
"file": "server-bundles.md",
|
|
126
|
-
"sha256": "
|
|
127
|
-
"updated": "2026-10-
|
|
126
|
+
"sha256": "bc59062fefb7c17986671e2a8b6b86b714d1c7e9774956a3df98adcef38a7fd2",
|
|
127
|
+
"updated": "2026-10-10T01:45:03Z"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"file": "serverless-functions-js.md",
|
|
131
|
-
"sha256": "
|
|
132
|
-
"updated": "2026-10-
|
|
131
|
+
"sha256": "56588d50d5a59f066164565470663f8f9da03fe85d98a96d3754e6ec14eb9fac",
|
|
132
|
+
"updated": "2026-10-10T00:12:33Z"
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
"file": "serverless-functions.md",
|
package/docs/platform-rules.md
CHANGED
|
@@ -295,12 +295,12 @@ them to do something is.
|
|
|
295
295
|
Both of these are working code in this repository. Neither was linked from anywhere until this page
|
|
296
296
|
existed, which is how integrators end up rebuilding them.
|
|
297
297
|
|
|
298
|
-
-
|
|
298
|
+
- **`examples/e2e/` — the bridge, end to end, in a real browser.** A real
|
|
299
299
|
parent page and a real game frame, served from two different origins, exchanging a real
|
|
300
300
|
`MessagePort`. `pnpm e2e` builds the artifacts and serves it. This is the thing to run when a
|
|
301
301
|
handshake is not landing and you need to know whether the problem is the SDK or your page:
|
|
302
302
|
`?sandbox=strict` reproduces the sandbox failure on demand.
|
|
303
|
-
-
|
|
303
|
+
- **`examples/server-bundle/echo.mjs` — a complete dedicated
|
|
304
304
|
server for a match, in one file.** The lifecycle a bundle implements and the first message on the
|
|
305
305
|
channel, running. Its contract is [`server-bundles.md`](server-bundles.md).
|
|
306
306
|
|
package/docs/server-bundles.md
CHANGED
|
@@ -80,8 +80,8 @@ To check the download yourself: the package npm serves is, byte for byte, the fi
|
|
|
80
80
|
also publishes on its download host, with the hash beside it:
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
curl -fsSL -O https://downloads.gemarcade.com/sdk/v9.1.
|
|
84
|
-
curl -fsSL https://downloads.gemarcade.com/sdk/v9.1.
|
|
83
|
+
curl -fsSL -O https://downloads.gemarcade.com/sdk/v9.1.4/gem-web-sdk.tgz
|
|
84
|
+
curl -fsSL https://downloads.gemarcade.com/sdk/v9.1.4/gem-web-sdk.tgz.sri
|
|
85
85
|
openssl dgst -sha384 -binary gem-web-sdk.tgz | openssl base64 -A
|
|
86
86
|
```
|
|
87
87
|
|
|
@@ -261,7 +261,7 @@ other version-skew member on `host`:
|
|
|
261
261
|
| `leave` | `cause` — why the connection ended, as the runtime saw it; `superseded` means the same player is already back on a newer connection and the `join` that says so follows at once |
|
|
262
262
|
| `message` | `reliable` / `ordered` — [the delivery class the sender asked for](#delivery-classes-the-flags-are-the-senders-request); `sessionId`; `playerNumber` |
|
|
263
263
|
|
|
264
|
-
A complete working example is
|
|
264
|
+
A complete working example is `examples/server-bundle/echo.mjs`
|
|
265
265
|
— a chat relay in one file, exercising every lifecycle method, the startup reads and most of the
|
|
266
266
|
runtime surface. This repo's suite drives it against the contract below, so it is a starting point
|
|
267
267
|
rather than a sketch.
|
|
@@ -493,7 +493,7 @@ and inherits none of that, which is why the example above loops around it.
|
|
|
493
493
|
|
|
494
494
|
A complete, runnable version of this — with the slot's access rules, the room template that makes a
|
|
495
495
|
dedicated server exist at all, and a real match's logs — is
|
|
496
|
-
|
|
496
|
+
`examples/server-saves/` in the SDK repository. It refuses the
|
|
497
497
|
upload outright where the snippet above merely skips an unexpected header, because a grant naming
|
|
498
498
|
something else is a platform bug worth surfacing rather than working around.
|
|
499
499
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Serverless functions in JavaScript
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**The platform does not run JavaScript functions yet.** This page describes how one is written
|
|
4
|
+
and how it behaves; today a function you publish is a WebAssembly component, as
|
|
5
|
+
[serverless-functions.md](serverless-functions.md) describes.
|
|
4
6
|
|
|
5
7
|
A serverless function can be written in JavaScript or TypeScript instead of Rust: the language your
|
|
6
8
|
game is already written in, so the verification code in your browser game moves into a function
|
|
@@ -12,6 +14,32 @@ what it may change, its limits, channels, and calling it from your game holds he
|
|
|
12
14
|
page covers only what is different: how you write one, how the SDK behaves inside it, and how
|
|
13
15
|
publishing checks it.
|
|
14
16
|
|
|
17
|
+
**JavaScript suits light work; heavy computation belongs in a component.** The platform's engine
|
|
18
|
+
runs JavaScript without a JIT, so the same work takes many times longer than in a WebAssembly
|
|
19
|
+
component, and the gap is smallest on a call that does little and widest on sustained computation.
|
|
20
|
+
Checking a claim, looking a record up or making a small state update finishes well inside a call's
|
|
21
|
+
limits in either language. Replaying a run to verify it, or ranking a large board, is where the gap
|
|
22
|
+
decides whether the call finishes: the CPU limit is the same for both, so JavaScript runs out of it
|
|
23
|
+
on work a component finishes many times over, and the call fails with `function_failed` and
|
|
24
|
+
`cpu_budget_exceeded`. A game has one function per channel, so the heaviest thing it does decides
|
|
25
|
+
the language. Measured with each running as the platform runs it, the same algorithm in JavaScript
|
|
26
|
+
and in Rust:
|
|
27
|
+
|
|
28
|
+
| The work | The component was faster by |
|
|
29
|
+
| --------------------------------------------------------------------------------- | --------------------------------- |
|
|
30
|
+
| A function that only returns its input, which measures the engine's cost per call | about 20 times |
|
|
31
|
+
| A loop of 20,000 integer steps | about 20 times |
|
|
32
|
+
| Ranking a daily leaderboard of 10,000 players | about 60 times |
|
|
33
|
+
| Numeric benchmarks: n-body, spectral-norm, fannkuch-redux and binary-trees | from about 30 to nearly 200 times |
|
|
34
|
+
| The numeric benchmarks and the leaderboard, on average | about 80 times |
|
|
35
|
+
|
|
36
|
+
**Your game's speed in a browser is no guide.** The same JavaScript under V8, the engine in Chrome,
|
|
37
|
+
measured with Node.js on the numeric benchmarks and the leaderboard, ran about 100 times faster than
|
|
38
|
+
on the platform's engine once its JIT had warmed up, which is a little faster than the component,
|
|
39
|
+
and about 7 times faster on its first call. With its JIT switched off it was still about 5 times
|
|
40
|
+
faster. Before you rely on a heavy check, invoke it on `dev` with input as large as a real
|
|
41
|
+
player's.
|
|
42
|
+
|
|
15
43
|
## 1. The contract
|
|
16
44
|
|
|
17
45
|
The same as a component's: bytes in, bytes out, one fresh instance per call, nothing kept between
|