@indiegems/gem-web-sdk 20.1.0 → 21.1.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 (66) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +1 -0
  3. package/brand/ticket-hero-128.png +0 -0
  4. package/brand/ticket-hero-256.png +0 -0
  5. package/brand/ticket-hero-384.png +0 -0
  6. package/brand/ticket-hero-512.png +0 -0
  7. package/brand/ticket-hero-768.png +0 -0
  8. package/brand/ticket-icon-20-1.5x.png +0 -0
  9. package/brand/ticket-icon-20-1x.png +0 -0
  10. package/brand/ticket-icon-20-2x.png +0 -0
  11. package/brand/ticket-icon-20-3x.png +0 -0
  12. package/brand/ticket-icon-32-1.5x.png +0 -0
  13. package/brand/ticket-icon-32-1x.png +0 -0
  14. package/brand/ticket-icon-32-2x.png +0 -0
  15. package/brand/ticket-icon-32-3x.png +0 -0
  16. package/brand/ticket-icon-ingame-20-1.5x.png +0 -0
  17. package/brand/ticket-icon-ingame-20-1x.png +0 -0
  18. package/brand/ticket-icon-ingame-20-2x.png +0 -0
  19. package/brand/ticket-icon-ingame-20-3x.png +0 -0
  20. package/brand/ticket-icon-ingame-32-1.5x.png +0 -0
  21. package/brand/ticket-icon-ingame-32-1x.png +0 -0
  22. package/brand/ticket-icon-ingame-32-2x.png +0 -0
  23. package/brand/ticket-icon-ingame-32-3x.png +0 -0
  24. package/brand/ticket-pile-1-128.png +0 -0
  25. package/brand/ticket-pile-1-256.png +0 -0
  26. package/brand/ticket-pile-1-384.png +0 -0
  27. package/brand/ticket-pile-1-512.png +0 -0
  28. package/brand/ticket-pile-1-768.png +0 -0
  29. package/brand/ticket-pile-2-128.png +0 -0
  30. package/brand/ticket-pile-2-256.png +0 -0
  31. package/brand/ticket-pile-2-384.png +0 -0
  32. package/brand/ticket-pile-2-512.png +0 -0
  33. package/brand/ticket-pile-2-768.png +0 -0
  34. package/dist/conformance.d.ts +1 -1
  35. package/dist/dev-tools.d.ts +1 -0
  36. package/dist/function.d.ts +11 -3
  37. package/dist/game.d.ts +79 -12
  38. package/dist/gem-web-sdk.bridge.js +2 -2
  39. package/dist/gem-web-sdk.conformance.js +3 -3
  40. package/dist/gem-web-sdk.dev-tools.js +2 -0
  41. package/dist/gem-web-sdk.esm.js +3 -3
  42. package/dist/gem-web-sdk.function.js +3 -3
  43. package/dist/gem-web-sdk.game.js +3 -3
  44. package/dist/gem-web-sdk.min.js +3 -3
  45. package/dist/gem-web-sdk.sdk.js +3 -3
  46. package/dist/gem-web-sdk.server.js +2 -2
  47. package/dist/index.d.ts +103 -48
  48. package/dist/sdk.d.ts +79 -12
  49. package/docs/analytics.md +12 -0
  50. package/docs/api/api-reference-function.md +14 -2
  51. package/docs/api/api-reference-game.md +357 -21
  52. package/docs/api/api-reference-server.md +1 -1
  53. package/docs/api/reference.json +413 -16
  54. package/docs/arcade-economy.md +2 -2
  55. package/docs/brand-art.md +65 -16
  56. package/docs/changelog.md +40 -0
  57. package/docs/game-economy-tutorial.md +6 -3
  58. package/docs/getting-started.md +122 -30
  59. package/docs/graphics-route.md +188 -0
  60. package/docs/inventory-and-catalogs.md +69 -27
  61. package/docs/manifest.json +23 -18
  62. package/docs/server-bundles.md +3 -3
  63. package/docs/what-a-game-must-do.md +33 -2
  64. package/package.json +5 -1
  65. package/schema/bridge.v1.json +263 -12
  66. package/schema/capabilities.public.json +26 -0
@@ -1,6 +1,6 @@
1
1
  # The browser surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v20.1.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` v21.1.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
 
@@ -1934,6 +1934,12 @@ platform's own refusals arrive as a `GemApiError` whose `code` is its wire
1934
1934
  code — `insufficient_funds`, `recipe_locked`, `price_mismatch`, … Never
1935
1935
  draw a top-up or payment screen of your own for either.
1936
1936
 
1937
+ `guest_upgrade_required` means the player is a guest, and the platform
1938
+ lets only an account spend. TREAT IT LIKE A DECLINE AND DRAW NOTHING: the
1939
+ SDK has already handed the attempt to the arcade, which offers the player
1940
+ an account over your game. The call rejects at once rather than waiting
1941
+ for them; if they make one and buy, [PurchaseApi.onSettled](#purchaseapi-onsettled) hears it.
1942
+
1937
1943
  | Parameter | Type |
1938
1944
  | --- | --- |
1939
1945
  | `request` | `ConfiguredPurchaseRequest` |
@@ -4012,7 +4018,7 @@ How a match was hosted — the closed set `gem_match_started` and
4012
4018
  ## PlatformEventName
4013
4019
 
4014
4020
  ```ts
4015
- type PlatformEventName = "gem_session_start" | "gem_session_end" | "gem_pause" | "gem_resume" | "gem_boot_ready" | "gem_match_started" | "gem_match_ended" | "gem_auth_lost"
4021
+ type PlatformEventName = "gem_session_start" | "gem_session_end" | "gem_pause" | "gem_resume" | "gem_boot_ready" | "gem_match_started" | "gem_match_ended" | "gem_auth_lost" | "gem_graphics_context_lost"
4016
4022
  ```
4017
4023
 
4018
4024
  Every event the SDK emits by itself.
@@ -4030,6 +4036,12 @@ config names them as steps.
4030
4036
  | `gem_boot_ready` | — | `boot_ms` |
4031
4037
  | `gem_match_started` / `gem_match_ended` | `transport` ([MatchTransport](#matchtransport)) | — |
4032
4038
  | `gem_auth_lost` | — | — |
4039
+ | `gem_graphics_context_lost` | `gpu`, `host`, `route` | `context_ms`, `hidden`, `nth_loss` |
4040
+
4041
+ `gem_graphics_context_lost` is the browser taking a WebGL context away, or a
4042
+ WebGPU device (`route` is then `webgpu`) — usually a GPU driver fault, sized
4043
+ per device across every game (`analytics/graphics.ts` lists the dimension
4044
+ values).
4033
4045
 
4034
4046
  <a id="platform_events"></a>
4035
4047
 
@@ -7662,21 +7674,26 @@ that can wear them.
7662
7674
  ## GemFrame.requestShare
7663
7675
 
7664
7676
  ```ts
7665
- requestShare(params: readonly { key: string; value: string }[]): boolean
7677
+ requestShare(params: readonly { key: string; value: string }[], requestId?: string): boolean
7666
7678
  ```
7667
7679
 
7668
7680
  Ask the arcade to share a link to your game, opened with these launch
7669
7681
  parameters. The arcade builds the link and shows its own share sheet, copy
7670
- or Share panel; nothing comes back, not even whether the player shared.
7682
+ or Share panel; nothing about the player comes back, not even whether they
7683
+ shared.
7671
7684
 
7672
7685
  Prefer `gem.share.request`, which checks each key and value against the
7673
- arcade's rules and throws on the one that would be refused. This one checks
7674
- only the message's bounds, sends only while connected, and only to an
7675
- arcade that handles share.
7686
+ arcade's rules, throws on the one that would be refused, and rejects with
7687
+ the arcade's own refusal. This one checks only the message's bounds, sends
7688
+ only while connected, and only to an arcade that handles share.
7676
7689
 
7677
- | Parameter | Type |
7678
- | --- | --- |
7679
- | `params` | `readonly { key: string; value: string }[]` |
7690
+ | Parameter | Type | Description |
7691
+ | --- | --- | --- |
7692
+ | `params` | `readonly { key: string; value: string }[]` | |
7693
+ | `requestId` | `string` | Pass one only to an arcade that advertised
7694
+ `shareResult`, which answers it with one `gem.shareResult` through
7695
+ `onShareResult`; any other arcade ignores it. Omit it and nothing
7696
+ answers. |
7680
7697
 
7681
7698
  **Returns.** whether the message left the frame — `false` before the bridge is
7682
7699
  up, for an arcade that does not handle share, and past this frame's own
@@ -11441,6 +11458,25 @@ every account on the device shares it, and it can vanish at any time. A
11441
11458
  game must boot correctly from `null`. Progress belongs in `gem.me.saves`;
11442
11459
  a setting that must follow the player belongs in `gem.me.settings`.
11443
11460
 
11461
+ <a id="gem-graphics"></a>
11462
+
11463
+ ## Gem.graphics
11464
+
11465
+ ```ts
11466
+ readonly graphics: GraphicsApi
11467
+ ```
11468
+
11469
+ Which renderer to make — WebGPU or WebGL — on this device, and whether
11470
+ the device is listed as broken on WebGL. Ask
11471
+ `gem.graphics.preferredRoute()` just before you make your first renderer.
11472
+
11473
+ WebGL is the answer almost everywhere; `webgpu` only on a listed device,
11474
+ where WebGPU is available. A listed device that ends up on WebGL draws the
11475
+ game's safe WebGL recipe. The list is the platform's, so a new entry
11476
+ reaches your live game without a new build.
11477
+
11478
+ **Guides.** [graphics-route](../graphics-route.md)
11479
+
11444
11480
  <a id="gem-moments"></a>
11445
11481
 
11446
11482
  ## Gem.moments
@@ -11537,14 +11573,19 @@ the click handler, because `request` throws once it has gone false:
11537
11573
  shareButton.hidden = !gem.share.available;
11538
11574
  shareButton.onclick = () => {
11539
11575
  if (!gem.share.available) return;
11540
- gem.share.request({ params: { jar: 'JAR-K7P3QXM', n: '2' } });
11576
+ gem.share.request({ params: { jar: 'JAR-K7P3QXM', n: '2' } }).catch((err) => {
11577
+ // A ShareRefusal: err.reason ('reserved_key', 'round_trip', 'too_long')
11578
+ // and err.key say what to fix. Log it; show the player nothing.
11579
+ console.warn(err);
11580
+ });
11541
11581
  };
11542
11582
  ```
11543
11583
 
11544
11584
  - **Call it synchronously from the click** — never from a timer, after an
11545
11585
  `await`, or on a game event.
11546
- - **Never gate progress or a reward on sharing.** You are told nothing
11547
- back, not even whether the player shared.
11586
+ - **Never gate progress or a reward on sharing.** Nothing about the player
11587
+ comes back, not even whether they shared. The promise rejects only when
11588
+ the arcade refused the share, with a [ShareRefusal](#sharerefusal) naming why.
11548
11589
  - **No personal identifiers in `params`.** The link is public.
11549
11590
  - **The share text is the arcade's own**; your game supplies none.
11550
11591
 
@@ -12960,6 +13001,152 @@ whichever transport won, so your game code does not branch.
12960
13001
 
12961
13002
  **Guides.** [dedicated-server-flow](../dedicated-server-flow.md)
12962
13003
 
13004
+ <a id="gemgraphicsroute"></a>
13005
+
13006
+ ## GemGraphicsRoute
13007
+
13008
+ ```ts
13009
+ type GemGraphicsRoute = "webgpu" | "webgl"
13010
+ ```
13011
+
13012
+ Which renderer to make: `webgpu` or `webgl`.
13013
+
13014
+ <a id="gempreferredroute"></a>
13015
+
13016
+ ## GemPreferredRoute
13017
+
13018
+ ```ts
13019
+ interface GemPreferredRoute
13020
+ ```
13021
+
13022
+ What `gem.graphics.preferredRoute()` answers.
13023
+
13024
+ <a id="gempreferredroute-route"></a>
13025
+
13026
+ ## GemPreferredRoute.route
13027
+
13028
+ ```ts
13029
+ readonly route: GemGraphicsRoute
13030
+ ```
13031
+
13032
+ Which renderer to make. `webgpu` only when `listed` is true and the
13033
+ browser hands out a WebGPU adapter; `webgl` everywhere else.
13034
+
13035
+ <a id="gempreferredroute-listed"></a>
13036
+
13037
+ ## GemPreferredRoute.listed
13038
+
13039
+ ```ts
13040
+ readonly listed: boolean
13041
+ ```
13042
+
13043
+ Whether the platform lists this device as broken on WebGL. When true and
13044
+ `route` is `webgl` (no WebGPU here), or your WebGPU renderer fails to
13045
+ start, draw your safe WebGL recipe — for every listed device today, no
13046
+ shadow maps — on every WebGL canvas the page makes, menus included.
13047
+
13048
+ <a id="gemgraphicsrouteentry"></a>
13049
+
13050
+ ## GemGraphicsRouteEntry
13051
+
13052
+ ```ts
13053
+ interface GemGraphicsRouteEntry
13054
+ ```
13055
+
13056
+ One device that should draw with WebGPU, as the platform's list names it.
13057
+ An absent `route` or `host` matches any.
13058
+
13059
+ <a id="gemgraphicsrouteentry-gpu"></a>
13060
+
13061
+ ## GemGraphicsRouteEntry.gpu
13062
+
13063
+ ```ts
13064
+ readonly gpu: string
13065
+ ```
13066
+
13067
+ The GPU family, e.g. `powervr_d_series`, `adreno`, `mali`.
13068
+
13069
+ <a id="gemgraphicsrouteentry-route"></a>
13070
+
13071
+ ## GemGraphicsRouteEntry.route
13072
+
13073
+ ```ts
13074
+ readonly route?: string
13075
+ ```
13076
+
13077
+ The route WebGL takes there, e.g. `angle_gles` (OpenGL ES),
13078
+ `native_gl` (no ANGLE, as the Arcade's Android app reports) or
13079
+ `angle_vulkan`. Absent matches any route.
13080
+
13081
+ <a id="gemgraphicsrouteentry-host"></a>
13082
+
13083
+ ## GemGraphicsRouteEntry.host
13084
+
13085
+ ```ts
13086
+ readonly host?: string
13087
+ ```
13088
+
13089
+ `android_webview` (an Android app's WebView, the Arcade app's included) or
13090
+ `other`. Absent matches either.
13091
+
13092
+ <a id="preferredrouteoptions"></a>
13093
+
13094
+ ## PreferredRouteOptions
13095
+
13096
+ ```ts
13097
+ interface PreferredRouteOptions
13098
+ ```
13099
+
13100
+ Options for [GraphicsApi.preferredRoute](#graphicsapi-preferredroute).
13101
+
13102
+ <a id="preferredrouteoptions-timeoutms"></a>
13103
+
13104
+ ## PreferredRouteOptions.timeoutMs
13105
+
13106
+ ```ts
13107
+ readonly timeoutMs?: number
13108
+ ```
13109
+
13110
+ The longest the answer may take, in milliseconds. Default 1000, at most
13111
+ 5000. When it runs out, the answer comes from what is known by then.
13112
+
13113
+ <a id="graphicsapi"></a>
13114
+
13115
+ ## GraphicsApi
13116
+
13117
+ ```ts
13118
+ interface GraphicsApi
13119
+ ```
13120
+
13121
+ Which renderer to make. Reached as `gem.graphics`.
13122
+
13123
+ <a id="graphicsapi-preferredroute"></a>
13124
+
13125
+ ## GraphicsApi.preferredRoute
13126
+
13127
+ ```ts
13128
+ preferredRoute(options?: PreferredRouteOptions): Promise<GemPreferredRoute>
13129
+ ```
13130
+
13131
+ Which renderer to make, and whether this device is listed. Ask once, just
13132
+ before you make your first renderer, and follow it for every canvas.
13133
+
13134
+ `route` is `webgl` almost everywhere. It is `webgpu` only on a device the
13135
+ platform lists as broken on WebGL (today the PowerVR D-Series GPU in the
13136
+ Pixel 10, on every route but Vulkan), and only when WebGPU is available
13137
+ there. `listed` is true on such a device: when `route` is `webgl` there,
13138
+ or making the WebGPU renderer fails, draw your safe WebGL recipe.
13139
+
13140
+ Resolves within `timeoutMs` (default 1000 ms) and never rejects; normally
13141
+ at once after `gem.awaitBridge()`. The launch key `gemGraphics=webgpu`,
13142
+ `gemGraphics=safe` or `gemGraphics=webgl` forces the answer, for testing.
13143
+
13144
+ | Parameter | Type | Description |
13145
+ | --- | --- | --- |
13146
+ | `options` | `PreferredRouteOptions` | See [PreferredRouteOptions](#preferredrouteoptions). |
13147
+
13148
+ **Returns.** `{ route, listed }`.
13149
+
12963
13150
  <a id="gemmatchservermodule"></a>
12964
13151
 
12965
13152
  ## GemMatchServerModule
@@ -15099,6 +15286,102 @@ a Buy button mostly does not write one.
15099
15286
  | --- | --- |
15100
15287
  | `req` | `PurchaseRequest` |
15101
15288
 
15289
+ <a id="purchaseapi-onsettled"></a>
15290
+
15291
+ ## PurchaseApi.onSettled
15292
+
15293
+ ```ts
15294
+ onSettled(listener: (settlement: PurchaseSettlement) => void): () => void
15295
+ ```
15296
+
15297
+ Hear about a purchase of yours that completed AFTER its own call answered
15298
+ — returns a function that stops listening.
15299
+
15300
+ The case it exists for: a guest's `gem.me.mutations.purchase` is refused
15301
+ `guest_upgrade_required` (your call rejects at once, and you show
15302
+ nothing), the arcade offers the player an account, and they make one and
15303
+ confirm the arcade's sheet a minute later — or after a reload, when the
15304
+ call that asked is gone. This is how your game hears that it happened.
15305
+
15306
+ THE SDK CONFIRMS IT FIRST. A listener is called only once the platform
15307
+ itself, asked with your game's own token, says the purchase was granted;
15308
+ a claim it cannot confirm is never reported. The player's inventory is
15309
+ re-read either way, so `gem.me.inventory.onChanged` fires too. Treat it
15310
+ like an `ok`: grant feedback, then re-read inventory rather than assuming
15311
+ what landed.
15312
+
15313
+ Hears nothing on an arcade that does not support it (the
15314
+ `purchaseSettled` capability), and never for a purchase an `ok` already
15315
+ reported.
15316
+
15317
+ | Parameter | Type |
15318
+ | --- | --- |
15319
+ | `listener` | `(settlement: PurchaseSettlement) => void` |
15320
+
15321
+ <a id="purchasesettlement"></a>
15322
+
15323
+ ## PurchaseSettlement
15324
+
15325
+ ```ts
15326
+ interface PurchaseSettlement
15327
+ ```
15328
+
15329
+ A purchase of one of your game's own items or recipes that completed after
15330
+ the call that asked for it had answered. What [PurchaseApi.onSettled](#purchaseapi-onsettled)
15331
+ hears.
15332
+
15333
+ <a id="purchasesettlement-kind"></a>
15334
+
15335
+ ## PurchaseSettlement.kind
15336
+
15337
+ ```ts
15338
+ readonly kind: "item" | "recipe"
15339
+ ```
15340
+
15341
+ `item` or `recipe`.
15342
+
15343
+ <a id="purchasesettlement-targetid"></a>
15344
+
15345
+ ## PurchaseSettlement.targetId
15346
+
15347
+ ```ts
15348
+ readonly targetId: string
15349
+ ```
15350
+
15351
+ The item-definition or recipe id that was bought.
15352
+
15353
+ <a id="purchasesettlement-catalogid"></a>
15354
+
15355
+ ## PurchaseSettlement.catalogId
15356
+
15357
+ ```ts
15358
+ readonly catalogId?: string
15359
+ ```
15360
+
15361
+ The recipe's catalog; absent for an item.
15362
+
15363
+ <a id="purchasesettlement-quantity"></a>
15364
+
15365
+ ## PurchaseSettlement.quantity
15366
+
15367
+ ```ts
15368
+ readonly quantity: number
15369
+ ```
15370
+
15371
+ How many were bought. Always 1 for a recipe.
15372
+
15373
+ <a id="purchasesettlement-purchaseid"></a>
15374
+
15375
+ ## PurchaseSettlement.purchaseId
15376
+
15377
+ ```ts
15378
+ readonly purchaseId: string
15379
+ ```
15380
+
15381
+ The platform's own id for this purchase, which the SDK confirmed with the
15382
+ platform before calling you. A handle for logs and support, as on
15383
+ [PurchaseOutcome](#purchaseoutcome)'s `ok`; nothing reads it back.
15384
+
15102
15385
  <a id="avatar3dpurchaserequest"></a>
15103
15386
 
15104
15387
  ## Avatar3dPurchaseRequest
@@ -15136,7 +15419,7 @@ must carry a price in it.
15136
15419
  ## PurchaseRefusalCode
15137
15420
 
15138
15421
  ```ts
15139
- type PurchaseRefusalCode = "unknown_currency" | "currency_not_in_game_payable" | "not_purchasable" | "no_price_in_currency" | "busy" | "cancelled" | "insufficient_funds" | "price_mismatch" | "config_version_stale" | "platform_currency_unavailable" | "not_available" | "recipe_locked" | "already_owned" | "recipe_on_cooldown" | "recipe_max_uses_exceeded" | "item_max_stack_exceeded" | "recipe_costs_unmet" | "quantity_invalid" | "error"
15422
+ type PurchaseRefusalCode = "unknown_currency" | "currency_not_in_game_payable" | "not_purchasable" | "no_price_in_currency" | "busy" | "cancelled" | "insufficient_funds" | "price_mismatch" | "config_version_stale" | "platform_currency_unavailable" | "not_available" | "recipe_locked" | "already_owned" | "guest_upgrade_required" | "recipe_on_cooldown" | "recipe_max_uses_exceeded" | "item_max_stack_exceeded" | "recipe_costs_unmet" | "quantity_invalid" | "error"
15140
15423
  ```
15141
15424
 
15142
15425
  Every reason a purchase can be refused, on either purchase path.
@@ -15165,6 +15448,12 @@ Every reason a purchase can be refused, on either purchase path.
15165
15448
  - `already_owned` — the player already owns the 3D avatar
15166
15449
  `gem.avatars3d.purchase` asked for; nothing was charged. Only that call
15167
15450
  answers it.
15451
+ - `guest_upgrade_required` — the player is playing as a guest, and the
15452
+ platform lets only an account spend. Nothing was charged. TREAT IT EXACTLY
15453
+ LIKE A DECLINE, AND DRAW NOTHING: the arcade offers the player an account
15454
+ itself, over your game, and a sign-up or "log in to buy" screen of your own
15455
+ would be a second one. A game on `gem.me.mutations.purchase` gets it as a
15456
+ `GemApiError` after the SDK has already handed the attempt to the arcade.
15168
15457
  - `recipe_on_cooldown`, `recipe_max_uses_exceeded`, `item_max_stack_exceeded`,
15169
15458
  `recipe_costs_unmet`, `quantity_invalid` — the recipe or item refused this
15170
15459
  purchase, before any charge.
@@ -15936,6 +16225,44 @@ Your own launch parameters, exactly as they should reach your game when the
15936
16225
  link is opened — the keys you read back from `location.search`. At most 16,
15937
16226
  in the order given. Omit it to share your game with no deep link.
15938
16227
 
16228
+ <a id="sharerefusal"></a>
16229
+
16230
+ ## ShareRefusal
16231
+
16232
+ ```ts
16233
+ class ShareRefusal
16234
+ ```
16235
+
16236
+ The arcade refused a share, and why. `gem.share.request`'s promise rejects
16237
+ with it. Fix the params it names: the same share is refused again.
16238
+
16239
+ <a id="sharerefusal-reason"></a>
16240
+
16241
+ ## ShareRefusal.reason
16242
+
16243
+ ```ts
16244
+ readonly reason: string
16245
+ ```
16246
+
16247
+ Why, as a machine code. OPEN-ENDED, so keep a `default` arm:
16248
+
16249
+ - `reserved_key` — [ShareRefusal.key](#sharerefusal-key) is a key the arcade keeps for
16250
+ itself and does not carry in a share link.
16251
+ - `round_trip` — the link the arcade built does not read back as what you
16252
+ asked for, or [ShareRefusal.key](#sharerefusal-key) is too long to carry.
16253
+ - `too_long` — the whole link is over 2 KB. Share fewer or shorter params.
16254
+ - `error` — the arcade refused without saying why.
16255
+
16256
+ <a id="sharerefusal-key"></a>
16257
+
16258
+ ## ShareRefusal.key
16259
+
16260
+ ```ts
16261
+ readonly key?: string
16262
+ ```
16263
+
16264
+ The param key that caused it, exactly as you passed it, when one key did.
16265
+
15939
16266
  <a id="shareapi"></a>
15940
16267
 
15941
16268
  ## ShareApi
@@ -15966,24 +16293,33 @@ that a share will happen: the arcade decides that, and does not say.
15966
16293
  ## ShareApi.request
15967
16294
 
15968
16295
  ```ts
15969
- request(request?: ShareRequest): void
16296
+ request(request?: ShareRequest): Promise<void>
15970
16297
  ```
15971
16298
 
15972
16299
  Ask the arcade to share a link that opens your game with `params`. Call it
15973
- synchronously from your own Share button's click handler. It returns
15974
- nothing, and nothing ever comes back — not even whether the player shared —
15975
- so never gate progress or a reward on it.
16300
+ synchronously from your own Share button's click handler. Nothing about the
16301
+ player ever comes back — not even whether they shared — so never gate
16302
+ progress or a reward on it.
15976
16303
 
15977
16304
  | Parameter | Type |
15978
16305
  | --- | --- |
15979
16306
  | `request` | `ShareRequest` |
15980
16307
 
16308
+ **Returns.** a promise that REJECTS with a [ShareRefusal](#sharerefusal) when the arcade
16309
+ refused the share, naming the reason and the param, and otherwise
16310
+ resolves with nothing. Resolving does not mean the player shared, or saw
16311
+ a sheet at all. An older arcade never refuses out loud, so there it
16312
+ resolves at once.
16313
+
15981
16314
  **Throws.** `Error` when [ShareApi.available](#shareapi-available) is false, and `TypeError`,
15982
16315
  naming the parameter, for one the arcade would refuse: more than 16, a
15983
16316
  key that is not a letter followed by up to 63 letters, digits, `_` or
15984
- `-`, a key the arcade reserves for itself, or a value that is not a
15985
- string, is over 512 characters, or holds a control, format or unpaired
15986
- surrogate character. Nothing is sent when it throws.
16317
+ `-`, a key the arcade keeps for itself, or a value that is not a string,
16318
+ is over 512 characters, or holds a control, format or unpaired surrogate
16319
+ character. Nothing is sent when it throws. Which keys the arcade keeps
16320
+ depends on the arcade: a current one carries reserved keys such as
16321
+ `invite` and refuses only `embedder` (and `_s`, which is not a valid key
16322
+ anyway); an older one refuses all of them.
15987
16323
 
15988
16324
  <a id="playertext"></a>
15989
16325
 
@@ -1,6 +1,6 @@
1
1
  # The server surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v20.1.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` v21.1.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