@indiegems/gem-web-sdk 21.0.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.
@@ -1,6 +1,6 @@
1
1
  # The browser surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v21.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` 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` |
@@ -4032,9 +4038,10 @@ config names them as steps.
4032
4038
  | `gem_auth_lost` | — | — |
4033
4039
  | `gem_graphics_context_lost` | `gpu`, `host`, `route` | `context_ms`, `hidden`, `nth_loss` |
4034
4040
 
4035
- `gem_graphics_context_lost` is the browser taking a WebGL context away —
4036
- usually a GPU driver fault, sized per device across every game
4037
- (`analytics/graphics.ts` lists the dimension values).
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).
4038
4045
 
4039
4046
  <a id="platform_events"></a>
4040
4047
 
@@ -7667,21 +7674,26 @@ that can wear them.
7667
7674
  ## GemFrame.requestShare
7668
7675
 
7669
7676
  ```ts
7670
- requestShare(params: readonly { key: string; value: string }[]): boolean
7677
+ requestShare(params: readonly { key: string; value: string }[], requestId?: string): boolean
7671
7678
  ```
7672
7679
 
7673
7680
  Ask the arcade to share a link to your game, opened with these launch
7674
7681
  parameters. The arcade builds the link and shows its own share sheet, copy
7675
- 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.
7676
7684
 
7677
7685
  Prefer `gem.share.request`, which checks each key and value against the
7678
- arcade's rules and throws on the one that would be refused. This one checks
7679
- only the message's bounds, sends only while connected, and only to an
7680
- 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.
7681
7689
 
7682
- | Parameter | Type |
7683
- | --- | --- |
7684
- | `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. |
7685
7697
 
7686
7698
  **Returns.** whether the message left the frame — `false` before the bridge is
7687
7699
  up, for an arcade that does not handle share, and past this frame's own
@@ -11446,6 +11458,25 @@ every account on the device shares it, and it can vanish at any time. A
11446
11458
  game must boot correctly from `null`. Progress belongs in `gem.me.saves`;
11447
11459
  a setting that must follow the player belongs in `gem.me.settings`.
11448
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
+
11449
11480
  <a id="gem-moments"></a>
11450
11481
 
11451
11482
  ## Gem.moments
@@ -11542,14 +11573,19 @@ the click handler, because `request` throws once it has gone false:
11542
11573
  shareButton.hidden = !gem.share.available;
11543
11574
  shareButton.onclick = () => {
11544
11575
  if (!gem.share.available) return;
11545
- 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
+ });
11546
11581
  };
11547
11582
  ```
11548
11583
 
11549
11584
  - **Call it synchronously from the click** — never from a timer, after an
11550
11585
  `await`, or on a game event.
11551
- - **Never gate progress or a reward on sharing.** You are told nothing
11552
- 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.
11553
11589
  - **No personal identifiers in `params`.** The link is public.
11554
11590
  - **The share text is the arcade's own**; your game supplies none.
11555
11591
 
@@ -12965,6 +13001,152 @@ whichever transport won, so your game code does not branch.
12965
13001
 
12966
13002
  **Guides.** [dedicated-server-flow](../dedicated-server-flow.md)
12967
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
+
12968
13150
  <a id="gemmatchservermodule"></a>
12969
13151
 
12970
13152
  ## GemMatchServerModule
@@ -15104,6 +15286,102 @@ a Buy button mostly does not write one.
15104
15286
  | --- | --- |
15105
15287
  | `req` | `PurchaseRequest` |
15106
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
+
15107
15385
  <a id="avatar3dpurchaserequest"></a>
15108
15386
 
15109
15387
  ## Avatar3dPurchaseRequest
@@ -15141,7 +15419,7 @@ must carry a price in it.
15141
15419
  ## PurchaseRefusalCode
15142
15420
 
15143
15421
  ```ts
15144
- 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"
15145
15423
  ```
15146
15424
 
15147
15425
  Every reason a purchase can be refused, on either purchase path.
@@ -15170,6 +15448,12 @@ Every reason a purchase can be refused, on either purchase path.
15170
15448
  - `already_owned` — the player already owns the 3D avatar
15171
15449
  `gem.avatars3d.purchase` asked for; nothing was charged. Only that call
15172
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.
15173
15457
  - `recipe_on_cooldown`, `recipe_max_uses_exceeded`, `item_max_stack_exceeded`,
15174
15458
  `recipe_costs_unmet`, `quantity_invalid` — the recipe or item refused this
15175
15459
  purchase, before any charge.
@@ -15941,6 +16225,44 @@ Your own launch parameters, exactly as they should reach your game when the
15941
16225
  link is opened — the keys you read back from `location.search`. At most 16,
15942
16226
  in the order given. Omit it to share your game with no deep link.
15943
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
+
15944
16266
  <a id="shareapi"></a>
15945
16267
 
15946
16268
  ## ShareApi
@@ -15971,24 +16293,33 @@ that a share will happen: the arcade decides that, and does not say.
15971
16293
  ## ShareApi.request
15972
16294
 
15973
16295
  ```ts
15974
- request(request?: ShareRequest): void
16296
+ request(request?: ShareRequest): Promise<void>
15975
16297
  ```
15976
16298
 
15977
16299
  Ask the arcade to share a link that opens your game with `params`. Call it
15978
- synchronously from your own Share button's click handler. It returns
15979
- nothing, and nothing ever comes back — not even whether the player shared —
15980
- 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.
15981
16303
 
15982
16304
  | Parameter | Type |
15983
16305
  | --- | --- |
15984
16306
  | `request` | `ShareRequest` |
15985
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
+
15986
16314
  **Throws.** `Error` when [ShareApi.available](#shareapi-available) is false, and `TypeError`,
15987
16315
  naming the parameter, for one the arcade would refuse: more than 16, a
15988
16316
  key that is not a letter followed by up to 63 letters, digits, `_` or
15989
- `-`, a key the arcade reserves for itself, or a value that is not a
15990
- string, is over 512 characters, or holds a control, format or unpaired
15991
- 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.
15992
16323
 
15993
16324
  <a id="playertext"></a>
15994
16325
 
@@ -1,6 +1,6 @@
1
1
  # The server surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/sdk` v21.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` 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