@indiegems/gem-web-sdk 17.0.0 → 18.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.
@@ -1,6 +1,6 @@
1
1
  # The browser surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v17.0.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
3
+ Generated from `@indiegems/gem-web-sdk/sdk` v18.0.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
4
4
 
5
5
  `@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/game` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
6
6
 
@@ -6969,6 +6969,37 @@ A corner of your frame, for `gem.setGemCorner`: where you would like the
6969
6969
  arcade's Gem button to sit. `'top-left'` is where it sits unless you ask.
6970
6970
  Physical corners: `'top-left'` is the top-left in every language.
6971
6971
 
6972
+ <a id="menustyle"></a>
6973
+
6974
+ ## MenuStyle
6975
+
6976
+ ```ts
6977
+ interface MenuStyle
6978
+ ```
6979
+
6980
+ Two colours for the arcade's own screens over your game, for
6981
+ `gem.setMenuStyle`: each exactly `#rrggbb`. The arcade works out the rest.
6982
+
6983
+ <a id="menustyle-ground"></a>
6984
+
6985
+ ## MenuStyle.ground
6986
+
6987
+ ```ts
6988
+ readonly ground: string
6989
+ ```
6990
+
6991
+ The colour the arcade's surfaces are built on, such as `'#1b2a4a'`.
6992
+
6993
+ <a id="menustyle-accent"></a>
6994
+
6995
+ ## MenuStyle.accent
6996
+
6997
+ ```ts
6998
+ readonly accent: string
6999
+ ```
7000
+
7001
+ The one highlight, at least 3:1 against `ground`, such as `'#ffb300'`.
7002
+
6972
7003
  <a id="framestate"></a>
6973
7004
 
6974
7005
  ## FrameState
@@ -7346,6 +7377,29 @@ its control.
7346
7377
  up, for an arcade that cannot move its control, for a value that is not
7347
7378
  one of the four corners, and past this frame's own limit.
7348
7379
 
7380
+ <a id="gemframe-setmenustyle"></a>
7381
+
7382
+ ## GemFrame.setMenuStyle
7383
+
7384
+ ```ts
7385
+ setMenuStyle(style: MenuStyle | null): boolean
7386
+ ```
7387
+
7388
+ Give the arcade's own screens over your game two colours to wear, or
7389
+ `null` to hand them back to the player's style: the whole answer each
7390
+ time, the latest one winning.
7391
+
7392
+ Prefer `gem.setMenuStyle`, which checks the colours and holds them across
7393
+ a reconnect. This one sends only while connected, and only to an arcade
7394
+ that can wear them.
7395
+
7396
+ | Parameter | Type |
7397
+ | --- | --- |
7398
+ | `style` | `MenuStyle \| null` |
7399
+
7400
+ **Returns.** whether the message left the frame: `false` before the bridge is
7401
+ up, for an arcade that cannot wear them, and past this frame's own limit.
7402
+
7349
7403
  <a id="gemframe-requestshare"></a>
7350
7404
 
7351
7405
  ## GemFrame.requestShare
@@ -12019,6 +12073,45 @@ with a warning on the console, and changes nothing.
12019
12073
  up (the corner is held and sent when it connects), under an embedder that
12020
12074
  cannot move its control, and for a value that is not a corner.
12021
12075
 
12076
+ <a id="gem-setmenustyle"></a>
12077
+
12078
+ ## Gem.setMenuStyle
12079
+
12080
+ ```ts
12081
+ setMenuStyle(style: MenuStyle | null): boolean
12082
+ ```
12083
+
12084
+ Give the arcade's own screens over your game your colours, so they match
12085
+ it: on the Gem Arcade, the burger button, the Gem menu and its pages, and
12086
+ every Arcade pop-up over the running game.
12087
+
12088
+ ```js
12089
+ gem.setMenuStyle({ ground: '#1b2a4a', accent: '#ffb300' });
12090
+ gem.setMenuStyle(null); // back to the player's own style
12091
+ ```
12092
+
12093
+ **Colours only.** `ground` is what the arcade's surfaces are built on and
12094
+ `accent` its one highlight; the arcade works out the text, rims, button
12095
+ shapes and fonts, so its screens stay readable on any ground.
12096
+
12097
+ **The Arcade refuses colours it cannot use.** Each must be exactly
12098
+ `#rrggbb`, and `accent` must reach 3:1 contrast against `ground`. Anything
12099
+ else is ignored, with a warning on the console giving the measured ratio:
12100
+ the last colours stand, nothing is sent, and this returns `false`.
12101
+
12102
+ **Your colours win over the player's chosen style while your game runs**,
12103
+ and the player's style comes back when it ends. It is screen state, not a
12104
+ toggle: each call is the whole answer, so you may change it between levels.
12105
+ Call it at boot, so your colours arrive with the first screen.
12106
+
12107
+ | Parameter | Type | Description |
12108
+ | --- | --- | --- |
12109
+ | `style` | `MenuStyle \| null` | The two colours, or `null` to hand back to the player's style. |
12110
+
12111
+ **Returns.** `true` when the arcade was told now; `false` before the bridge is
12112
+ up (the colours are held and sent when it connects), under an embedder
12113
+ that cannot wear them, and for colours it would refuse.
12114
+
12022
12115
  <a id="gem-reportframe"></a>
12023
12116
 
12024
12117
  ## Gem.reportFrame
@@ -1,6 +1,6 @@
1
1
  # The server surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v17.0.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
3
+ Generated from `@indiegems/gem-web-sdk/sdk` v18.0.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
4
4
 
5
5
  `@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/server` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
6
6
 
@@ -2,7 +2,7 @@
2
2
  "schema_version": 2,
3
3
  "source": {
4
4
  "repo": "IndieGems/gem-web-sdk",
5
- "version": "17.0.0"
5
+ "version": "18.0.0"
6
6
  },
7
7
  "entries": [
8
8
  {
@@ -8304,6 +8304,54 @@
8304
8304
  "defaultValue": null,
8305
8305
  "guides": []
8306
8306
  },
8307
+ {
8308
+ "id": "MenuStyle",
8309
+ "name": "MenuStyle",
8310
+ "anchor": "menustyle",
8311
+ "group": "frame",
8312
+ "signature": "interface MenuStyle",
8313
+ "documented": true,
8314
+ "summary": "Two colours for the arcade's own screens over your game, for\n`gem.setMenuStyle`: each exactly `#rrggbb`. The arcade works out the rest.",
8315
+ "deprecated": null,
8316
+ "params": [],
8317
+ "returns": null,
8318
+ "throws": null,
8319
+ "example": null,
8320
+ "defaultValue": null,
8321
+ "guides": []
8322
+ },
8323
+ {
8324
+ "id": "MenuStyle.ground",
8325
+ "name": "ground",
8326
+ "anchor": "menustyle-ground",
8327
+ "group": "frame",
8328
+ "signature": "readonly ground: string",
8329
+ "documented": true,
8330
+ "summary": "The colour the arcade's surfaces are built on, such as `'#1b2a4a'`.",
8331
+ "deprecated": null,
8332
+ "params": [],
8333
+ "returns": null,
8334
+ "throws": null,
8335
+ "example": null,
8336
+ "defaultValue": null,
8337
+ "guides": []
8338
+ },
8339
+ {
8340
+ "id": "MenuStyle.accent",
8341
+ "name": "accent",
8342
+ "anchor": "menustyle-accent",
8343
+ "group": "frame",
8344
+ "signature": "readonly accent: string",
8345
+ "documented": true,
8346
+ "summary": "The one highlight, at least 3:1 against `ground`, such as `'#ffb300'`.",
8347
+ "deprecated": null,
8348
+ "params": [],
8349
+ "returns": null,
8350
+ "throws": null,
8351
+ "example": null,
8352
+ "defaultValue": null,
8353
+ "guides": []
8354
+ },
8307
8355
  {
8308
8356
  "id": "FrameState",
8309
8357
  "name": "FrameState",
@@ -8684,6 +8732,29 @@
8684
8732
  "defaultValue": null,
8685
8733
  "guides": []
8686
8734
  },
8735
+ {
8736
+ "id": "GemFrame.setMenuStyle",
8737
+ "name": "setMenuStyle",
8738
+ "anchor": "gemframe-setmenustyle",
8739
+ "group": "frame",
8740
+ "signature": "setMenuStyle(style: MenuStyle | null): boolean",
8741
+ "documented": true,
8742
+ "summary": "Give the arcade's own screens over your game two colours to wear, or\n`null` to hand them back to the player's style: the whole answer each\ntime, the latest one winning.\n\nPrefer `gem.setMenuStyle`, which checks the colours and holds them across\na reconnect. This one sends only while connected, and only to an arcade\nthat can wear them.",
8743
+ "deprecated": null,
8744
+ "params": [
8745
+ {
8746
+ "name": "style",
8747
+ "type": "MenuStyle | null",
8748
+ "optional": false,
8749
+ "summary": null
8750
+ }
8751
+ ],
8752
+ "returns": "whether the message left the frame: `false` before the bridge is\n up, for an arcade that cannot wear them, and past this frame's own limit.",
8753
+ "throws": null,
8754
+ "example": null,
8755
+ "defaultValue": null,
8756
+ "guides": []
8757
+ },
8687
8758
  {
8688
8759
  "id": "GemFrame.requestShare",
8689
8760
  "name": "requestShare",
@@ -13364,6 +13435,29 @@
13364
13435
  "defaultValue": null,
13365
13436
  "guides": []
13366
13437
  },
13438
+ {
13439
+ "id": "Gem.setMenuStyle",
13440
+ "name": "setMenuStyle",
13441
+ "anchor": "gem-setmenustyle",
13442
+ "group": "start",
13443
+ "signature": "setMenuStyle(style: MenuStyle | null): boolean",
13444
+ "documented": true,
13445
+ "summary": "Give the arcade's own screens over your game your colours, so they match\nit: on the Gem Arcade, the burger button, the Gem menu and its pages, and\nevery Arcade pop-up over the running game.\n\n```js\ngem.setMenuStyle({ ground: '#1b2a4a', accent: '#ffb300' });\ngem.setMenuStyle(null); // back to the player's own style\n```\n\n**Colours only.** `ground` is what the arcade's surfaces are built on and\n`accent` its one highlight; the arcade works out the text, rims, button\nshapes and fonts, so its screens stay readable on any ground.\n\n**The Arcade refuses colours it cannot use.** Each must be exactly\n`#rrggbb`, and `accent` must reach 3:1 contrast against `ground`. Anything\nelse is ignored, with a warning on the console giving the measured ratio:\nthe last colours stand, nothing is sent, and this returns `false`.\n\n**Your colours win over the player's chosen style while your game runs**,\nand the player's style comes back when it ends. It is screen state, not a\ntoggle: each call is the whole answer, so you may change it between levels.\nCall it at boot, so your colours arrive with the first screen.",
13446
+ "deprecated": null,
13447
+ "params": [
13448
+ {
13449
+ "name": "style",
13450
+ "type": "MenuStyle | null",
13451
+ "optional": false,
13452
+ "summary": "The two colours, or `null` to hand back to the player's style."
13453
+ }
13454
+ ],
13455
+ "returns": "`true` when the arcade was told now; `false` before the bridge is\n up (the colours are held and sent when it connects), under an embedder\n that cannot wear them, and for colours it would refuse.",
13456
+ "throws": null,
13457
+ "example": null,
13458
+ "defaultValue": null,
13459
+ "guides": []
13460
+ },
13367
13461
  {
13368
13462
  "id": "Gem.reportFrame",
13369
13463
  "name": "reportFrame",
package/docs/changelog.md CHANGED
@@ -16,6 +16,19 @@ 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
+ ## 18.0.0
20
+
21
+ Upgrading from 17.0.0. Impact: required.
22
+
23
+ ### Rebuild
24
+
25
+ - The set of capability names a game can query has a new member, menuStyle. Recompiling is enough, but if your code handles every capability name exhaustively, add a case for the new one.
26
+ - The frame message type has a new member for menu style, and the list of messages a game frame sends to the Arcade now includes gem.menuStyle. Recompiling is enough, but code that handles every message exhaustively needs a case for the new message.
27
+
28
+ ### New capability
29
+
30
+ - A game can now hand the Arcade its own colours for the Arcade menu by calling Gem.setMenuStyle with a MenuStyle value. Check for the menuStyle capability first, since an older Arcade will not act on it. The same call is also available on the frame object.
31
+
19
32
  ## 17.0.0
20
33
 
21
34
  *Written from the API facts alone; no summary was generated for this release.*
@@ -50,7 +50,7 @@ either way.
50
50
  ```jsonc
51
51
  // package.json
52
52
  "dependencies": {
53
- "@indiegems/gem-web-sdk": "17.0.0"
53
+ "@indiegems/gem-web-sdk": "18.0.0"
54
54
  }
55
55
  ```
56
56
 
@@ -48,8 +48,8 @@
48
48
  },
49
49
  {
50
50
  "file": "changelog.md",
51
- "sha256": "b795d5ed73558a4d355196971fb4bd9689ca15d38fd01d9a67b4cf6c0e8ff25d",
52
- "updated": "2026-10-30T14:09:44Z"
51
+ "sha256": "bd5cfd2b2d1d1989a8407e147ce29165caada49f78bcd0d708ded1babe98fc09",
52
+ "updated": "2026-10-30T15:46:14Z"
53
53
  },
54
54
  {
55
55
  "file": "daily-challenges.md",
@@ -78,8 +78,8 @@
78
78
  },
79
79
  {
80
80
  "file": "getting-started.md",
81
- "sha256": "a69a8be43e655a71717c1d15ff3e9136103c17eebd9074c2f3dab4fad07d2689",
82
- "updated": "2026-10-30T14:09:44Z"
81
+ "sha256": "67a444eb6e1cbf0bbf9af6309db48ae44e9c03a692df60a35c12e604cb646065",
82
+ "updated": "2026-10-30T15:46:14Z"
83
83
  },
84
84
  {
85
85
  "file": "inventory-and-catalogs.md",
@@ -138,8 +138,8 @@
138
138
  },
139
139
  {
140
140
  "file": "server-bundles.md",
141
- "sha256": "d00bc2ea3896c2e262619bf87b2892dd954c9ef87d37dfb5881bb6ef7439401a",
142
- "updated": "2026-10-30T14:09:44Z"
141
+ "sha256": "8c2ff15c97a0eb09c9a50ae78b5e728635a478ee879a8aa788b82ca7de387eee",
142
+ "updated": "2026-10-30T15:46:14Z"
143
143
  },
144
144
  {
145
145
  "file": "serverless-functions-js.md",
@@ -163,8 +163,8 @@
163
163
  },
164
164
  {
165
165
  "file": "what-a-game-must-do.md",
166
- "sha256": "9d6f2121306bfee8b886d9555a644faa843d16f0c5200e257698336d747136b1",
167
- "updated": "2026-10-29T21:40:17Z"
166
+ "sha256": "8faa9ef2cef2a5eb73cf95d7c52af914325c2bc26834625c9cb4b5748eecc616",
167
+ "updated": "2026-10-30T14:09:09Z"
168
168
  }
169
169
  ]
170
170
  }
@@ -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/v17.0.0/gem-web-sdk.tgz
84
- curl -fsSL https://downloads.gemarcade.com/sdk/v17.0.0/gem-web-sdk.tgz.sri
83
+ curl -fsSL -O https://downloads.gemarcade.com/sdk/v18.0.0/gem-web-sdk.tgz
84
+ curl -fsSL https://downloads.gemarcade.com/sdk/v18.0.0/gem-web-sdk.tgz.sri
85
85
  openssl dgst -sha384 -binary gem-web-sdk.tgz | openssl base64 -A
86
86
  ```
87
87
 
@@ -971,6 +971,35 @@ read the rectangles, so the arcade sends it none and instead raises `insets.top`
971
971
  `--gem-safe-top` — past the bottom of the row. That game keeps working, at the cost of a full-width
972
972
  band; upgrading gives the band back.
973
973
 
974
+ ### Matching the Arcade to your game: `gem.setMenuStyle`
975
+
976
+ The burger button and everything the Arcade draws over your game wear the player's Arcade style
977
+ until you say otherwise. To make them match your game, give the Arcade two colours:
978
+
979
+ ```js
980
+ gem.setMenuStyle({ ground: '#1b2a4a', accent: '#ffb300' }); // at boot, with your first screen
981
+ gem.setMenuStyle(null); // back to the player's own style
982
+ ```
983
+
984
+ - **Colours only.** `ground` is what the Arcade's surfaces are built on and `accent` is its one
985
+ highlight. The Arcade works out the text, rims, button shapes and fonts, so its screens stay
986
+ readable on any ground.
987
+ - **What the Arcade refuses.** Each colour must be exactly `#rrggbb`, and `accent` must reach 3:1
988
+ contrast against `ground`. Anything else is ignored, with a warning on the console giving the
989
+ measured ratio: the last colours stand, nothing is sent, and the call returns `false`.
990
+ - **What wears your colours.** The burger button, the Gem menu and its pages, and every Arcade
991
+ pop-up over your running game, purchase sheets included. They do not reach the Arcade's other
992
+ screens.
993
+ - **Your colours win while your game runs.** They replace the style the player chose, and that
994
+ style comes back when your game ends.
995
+ - **It is screen state, not a toggle**: each call is the whole answer, held before the Arcade
996
+ connects and sent again after any reconnect, so you may change it between levels. A change the
997
+ Arcade receives while its menu or a pop-up is open waits until that closes.
998
+
999
+ `gem.setMenuStyle` returns `true` when the Arcade was told, and `false` before it connects, under an
1000
+ embedder that cannot wear your colours, and for colours it would refuse. On `false` from an embedder
1001
+ there is nothing else to do: never draw a look-alike of its menu.
1002
+
974
1003
  ## Which store-page experiment brought this player in: cohorts
975
1004
 
976
1005
  **You need this only if you run an A/B experiment on your store page and want the game to match
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indiegems/gem-web-sdk",
3
- "version": "17.0.0",
3
+ "version": "18.0.0",
4
4
  "description": "postMessage bridge contract between gem-web and browser-playable games",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -3145,6 +3145,64 @@
3145
3145
  "rateLimit": { "perMinute": 12 }
3146
3146
  },
3147
3147
 
3148
+ {
3149
+ "type": "gem.menuStyle",
3150
+ "direction": "frameToParent",
3151
+ "transport": "port",
3152
+ "$comment": [
3153
+ "The colours the game would like the arcade's own screens over it to wear,",
3154
+ "so they match the game: in the Gem Arcade, the burger button, the Gem menu",
3155
+ "and its pages, and every Arcade pop-up over the running game. With no",
3156
+ "message at all those screens wear the player's own Arcade style.",
3157
+ "",
3158
+ "TWO COLOURS, BOTH OR NEITHER. `ground` is the colour the arcade's surfaces",
3159
+ "are built on and `accent` its one highlight. A message with neither hands",
3160
+ "the arcade back to the player's own style; a message with only one is",
3161
+ "refused by the parent. The parent works out everything else, text, rims,",
3162
+ "button shapes and fonts, so a game can never make its screens unreadable.",
3163
+ "",
3164
+ "SCREEN STATE, NOT A TOGGLE, like `gem.gemCorner`. Each message is the whole",
3165
+ "answer and the latest one wins, so a game may change it between levels.",
3166
+ "The SDK holds it from before the bridge is up and re-sends it after every",
3167
+ "handshake, so a parent that reconnects wears what the game had asked.",
3168
+ "",
3169
+ "THE PARENT DECIDES, AND IT CHECKS AGAIN. The frame is untrusted, so a",
3170
+ "parent checks both values itself before a byte of them reaches a style:",
3171
+ "exactly `#` and six hexadecimal digits, and at least 3:1 WCAG contrast",
3172
+ "between `accent` and `ground`. On failure it keeps the screens as they",
3173
+ "are and tells the game nothing; the SDK refuses the same values on the",
3174
+ "game's side, where a developer sees why. A format of its own is not used",
3175
+ "for the hex, because a parent built on an older contract refuses a format",
3176
+ "it does not know.",
3177
+ "",
3178
+ "ON THE PARENT'S TERMS. In the Gem Arcade the game's colours win over the",
3179
+ "player's chosen style for as long as that game runs, a change that arrives",
3180
+ "while one of the arcade's surfaces is open waits for it to close, and the",
3181
+ "player's own style comes back when the game ends.",
3182
+ "",
3183
+ "A PRESENTATION REQUEST ONLY, and not an authorization control. Cosmetic:",
3184
+ "nothing may key a trust decision on it.",
3185
+ "",
3186
+ "Gated by `menuStyle`: sent only to a parent that advertised it. To any",
3187
+ "other, `gem.setMenuStyle` returns false."
3188
+ ],
3189
+ "fields": {
3190
+ "ground": {
3191
+ "kind": "string",
3192
+ "maxLength": 7,
3193
+ "optional": true,
3194
+ "$comment": "`#rrggbb`, the colour the arcade's surfaces are built on. Absent with `accent` to clear."
3195
+ },
3196
+ "accent": {
3197
+ "kind": "string",
3198
+ "maxLength": 7,
3199
+ "optional": true,
3200
+ "$comment": "`#rrggbb`, the one highlight, at least 3:1 against `ground`. Absent with `ground` to clear."
3201
+ }
3202
+ },
3203
+ "rateLimit": { "perMinute": 12 }
3204
+ },
3205
+
3148
3206
  {
3149
3207
  "type": "gem.settingsDeclare",
3150
3208
  "direction": "frameToParent",
@@ -302,6 +302,12 @@
302
302
  "gem.requestStoreOfferSheet",
303
303
  "gem.storeOfferSheetResult"
304
304
  ]
305
+ },
306
+ "menuStyle": {
307
+ "implemented": true,
308
+ "gates": [
309
+ "gem.menuStyle"
310
+ ]
305
311
  }
306
312
  }
307
313
  }