@indiegems/gem-web-sdk 23.3.0 → 24.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.
@@ -2,7 +2,7 @@
2
2
  "schema_version": 2,
3
3
  "source": {
4
4
  "repo": "IndieGems/gem-web-sdk",
5
- "version": "23.3.0"
5
+ "version": "24.0.0"
6
6
  },
7
7
  "entries": [
8
8
  {
@@ -77,6 +77,10 @@
77
77
  "key": "store",
78
78
  "title": "The Arcade Store, for real money"
79
79
  },
80
+ {
81
+ "key": "payout-preview",
82
+ "title": "Showing a platform payout: preview, upsells and receipts"
83
+ },
80
84
  {
81
85
  "key": "branding",
82
86
  "title": "The platform branding: logo, wordmark, currency marks"
@@ -5589,9 +5593,9 @@
5589
5593
  "name": "kind",
5590
5594
  "anchor": "arcadeoffer-kind",
5591
5595
  "group": "store",
5592
- "signature": "readonly kind: \"gem_pack\" | \"boost\" | \"pass\" | \"bundle\"",
5596
+ "signature": "readonly kind: ArcadeOfferKind",
5593
5597
  "documented": true,
5594
- "summary": "What sort of thing it is.",
5598
+ "summary": "What sort of thing it is: `coin_pack`, `boost`, `pass` or `bundle` — or\n`gem_pack`, which is deprecated: Gems are being retired, and a pack of\nCoins is `coin_pack`. Keep a `default` arm. See\n[the deprecation policy](../deprecation-policy.md).",
5595
5599
  "deprecated": null,
5596
5600
  "params": [],
5597
5601
  "returns": null,
@@ -5671,7 +5675,7 @@
5671
5675
  "group": "store",
5672
5676
  "signature": "readonly grant?: { currency: string; amount: number }",
5673
5677
  "documented": true,
5674
- "summary": "For a Gem pack: the platform currency and the amount it grants.",
5678
+ "summary": "For a Coin pack: the platform currency and the amount it grants.",
5675
5679
  "deprecated": null,
5676
5680
  "params": [],
5677
5681
  "returns": null,
@@ -5687,7 +5691,7 @@
5687
5691
  "group": "store",
5688
5692
  "signature": "readonly currency: string",
5689
5693
  "documented": true,
5690
- "summary": "The platform currency's exact slug, e.g. `GEMS`.",
5694
+ "summary": "The platform currency's exact slug, e.g. `ARCADE_TICKETS` for Coins.",
5691
5695
  "deprecated": null,
5692
5696
  "params": [],
5693
5697
  "returns": null,
@@ -5712,6 +5716,166 @@
5712
5716
  "defaultValue": null,
5713
5717
  "guides": []
5714
5718
  },
5719
+ {
5720
+ "id": "ArcadeOffer.pass",
5721
+ "name": "pass",
5722
+ "anchor": "arcadeoffer-pass",
5723
+ "group": "store",
5724
+ "signature": "readonly pass?: string",
5725
+ "documented": true,
5726
+ "summary": "For a pass, or a bundle carrying one: the pass's slug, such as `vip` — the\nslug `gem.me.passes` reports and [StoreApi.showPass](api-reference-game.md#storeapi-showpass) takes. Absent\nfor everything else, and on an older Arcade.",
5727
+ "deprecated": null,
5728
+ "params": [],
5729
+ "returns": null,
5730
+ "throws": null,
5731
+ "example": null,
5732
+ "defaultValue": null,
5733
+ "guides": []
5734
+ },
5735
+ {
5736
+ "id": "ArcadeOffer.earnMultipliers",
5737
+ "name": "earnMultipliers",
5738
+ "anchor": "arcadeoffer-earnmultipliers",
5739
+ "group": "store",
5740
+ "signature": "readonly earnMultipliers: readonly ArcadeOfferEarnMultiplier[]",
5741
+ "documented": true,
5742
+ "summary": "For an offer that makes the player earn a platform currency faster while\nthey hold it: one entry per currency. Empty when it boosts nothing.\n\nThe platform's own figure, for `gem.gameConfig.preview` to work out what\nholding it would add. **Never multiply a reward by it yourself**: the\npreview rounds the way the platform pays.",
5743
+ "deprecated": null,
5744
+ "params": [],
5745
+ "returns": null,
5746
+ "throws": null,
5747
+ "example": null,
5748
+ "defaultValue": null,
5749
+ "guides": []
5750
+ },
5751
+ {
5752
+ "id": "ArcadeOfferKind",
5753
+ "name": "ArcadeOfferKind",
5754
+ "anchor": "arcadeofferkind",
5755
+ "group": "store",
5756
+ "signature": "type ArcadeOfferKind = \"coin_pack\" | \"gem_pack\" | \"boost\" | \"pass\" | \"bundle\"",
5757
+ "documented": true,
5758
+ "summary": "What sort of SKU an [ArcadeOffer](api-reference-game.md#arcadeoffer) is. `gem_pack` is deprecated: Gems\nare being retired, and a pack of Coins is `coin_pack`.",
5759
+ "deprecated": null,
5760
+ "params": [],
5761
+ "returns": null,
5762
+ "throws": null,
5763
+ "example": null,
5764
+ "defaultValue": null,
5765
+ "guides": []
5766
+ },
5767
+ {
5768
+ "id": "ArcadeOfferEarnMultiplier",
5769
+ "name": "ArcadeOfferEarnMultiplier",
5770
+ "anchor": "arcadeofferearnmultiplier",
5771
+ "group": "store",
5772
+ "signature": "interface ArcadeOfferEarnMultiplier",
5773
+ "documented": true,
5774
+ "summary": "One currency an [ArcadeOffer](api-reference-game.md#arcadeoffer) boosts while it is held.",
5775
+ "deprecated": null,
5776
+ "params": [],
5777
+ "returns": null,
5778
+ "throws": null,
5779
+ "example": null,
5780
+ "defaultValue": null,
5781
+ "guides": []
5782
+ },
5783
+ {
5784
+ "id": "ArcadeOfferEarnMultiplier.currencySlug",
5785
+ "name": "currencySlug",
5786
+ "anchor": "arcadeofferearnmultiplier-currencyslug",
5787
+ "group": "store",
5788
+ "signature": "readonly currencySlug: string",
5789
+ "documented": true,
5790
+ "summary": "The currency's slug, e.g. `ARCADE_TICKETS`.",
5791
+ "deprecated": null,
5792
+ "params": [],
5793
+ "returns": null,
5794
+ "throws": null,
5795
+ "example": null,
5796
+ "defaultValue": null,
5797
+ "guides": []
5798
+ },
5799
+ {
5800
+ "id": "ArcadeOfferEarnMultiplier.multiplierBp",
5801
+ "name": "multiplierBp",
5802
+ "anchor": "arcadeofferearnmultiplier-multiplierbp",
5803
+ "group": "store",
5804
+ "signature": "readonly multiplierBp: number",
5805
+ "documented": true,
5806
+ "summary": "Basis points: `10000` is 1x, `15000` is 1.5x. An integer, so the preview\nrounds exactly as the platform does.",
5807
+ "deprecated": null,
5808
+ "params": [],
5809
+ "returns": null,
5810
+ "throws": null,
5811
+ "example": null,
5812
+ "defaultValue": null,
5813
+ "guides": []
5814
+ },
5815
+ {
5816
+ "id": "ShowPassOutcome",
5817
+ "name": "ShowPassOutcome",
5818
+ "anchor": "showpassoutcome",
5819
+ "group": "store",
5820
+ "signature": "interface ShowPassOutcome",
5821
+ "documented": true,
5822
+ "summary": "What [StoreApi.showPass](api-reference-game.md#storeapi-showpass) resolves with: an [ArcadeOutcome](api-reference-game.md#arcadeoutcome), plus\nwhether a fresh read shows the pass held.",
5823
+ "deprecated": null,
5824
+ "params": [],
5825
+ "returns": null,
5826
+ "throws": null,
5827
+ "example": null,
5828
+ "defaultValue": null,
5829
+ "guides": []
5830
+ },
5831
+ {
5832
+ "id": "ShowPassOutcome.outcome",
5833
+ "name": "outcome",
5834
+ "anchor": "showpassoutcome-outcome",
5835
+ "group": "store",
5836
+ "signature": "readonly outcome: ArcadeOutcomeKind",
5837
+ "documented": true,
5838
+ "summary": "What happened: `ok`, `declined` or `unavailable`. Branch on this.",
5839
+ "deprecated": null,
5840
+ "params": [],
5841
+ "returns": null,
5842
+ "throws": null,
5843
+ "example": null,
5844
+ "defaultValue": null,
5845
+ "guides": []
5846
+ },
5847
+ {
5848
+ "id": "ShowPassOutcome.reason",
5849
+ "name": "reason",
5850
+ "anchor": "showpassoutcome-reason",
5851
+ "group": "store",
5852
+ "signature": "readonly reason?: string",
5853
+ "documented": true,
5854
+ "summary": "Why, as a machine code — `busy`, `cancelled`, `not_found`, `pending`,\n`store_off`, `sign_in_required` and more. OPEN-ENDED: the arcade may send a\ncode this SDK has never heard of, so keep a `default` arm and never show a\ncode to a player. Absent when there is nothing to add.\n\nThree are the SDK's own, answered without asking the arcade:\n`unsupported` (the arcade here does not offer this), `invalid_argument`\n(the SDK refused what you passed) and `busy` (another ask of the same kind\nis still open). `error` means no reliable answer arrived — the ask never\nleft, the wait ran out, the bridge closed or the arcade had none. For\n`gem.store.purchase` that makes the outcome UNKNOWN, not a refusal: the\nplayer may have paid.",
5855
+ "deprecated": null,
5856
+ "params": [],
5857
+ "returns": null,
5858
+ "throws": null,
5859
+ "example": null,
5860
+ "defaultValue": null,
5861
+ "guides": []
5862
+ },
5863
+ {
5864
+ "id": "ShowPassOutcome.held",
5865
+ "name": "held",
5866
+ "anchor": "showpassoutcome-held",
5867
+ "group": "store",
5868
+ "signature": "readonly held: boolean",
5869
+ "documented": true,
5870
+ "summary": "Whether a fresh read of `gem.me.passes` showed the pass held once the\nsheet closed. `true` exactly when `outcome` is `ok` with no `reason`: a\nrecipe the game runs next gets the pass's bonus.",
5871
+ "deprecated": null,
5872
+ "params": [],
5873
+ "returns": null,
5874
+ "throws": null,
5875
+ "example": null,
5876
+ "defaultValue": null,
5877
+ "guides": []
5878
+ },
5715
5879
  {
5716
5880
  "id": "StoreOffersOutcome",
5717
5881
  "name": "StoreOffersOutcome",
@@ -5815,7 +5979,7 @@
5815
5979
  "group": "store",
5816
5980
  "signature": "interface StoreApi",
5817
5981
  "documented": true,
5818
- "summary": "**Real money.** The Arcade Store's own Gem packs, Boosts, passes and bundles,\nbought with the player's money through the Arcade Store's own checkout.\n`gem.store` is one of these. To spend Gems or Coins on your game's own items,\nuse `gem.purchases`.",
5982
+ "summary": "**Real money.** The Arcade Store's own Coin packs, Boosts, passes and bundles,\nbought with the player's money through the Arcade Store's own checkout.\n`gem.store` is one of these. To spend Coins on your game's own items, use\n`gem.purchases`. Only the Arcade sells Coins: a game never sells currency\nfor money.",
5819
5983
  "deprecated": null,
5820
5984
  "params": [],
5821
5985
  "returns": null,
@@ -5831,7 +5995,7 @@
5831
5995
  "group": "store",
5832
5996
  "signature": "readonly available: boolean",
5833
5997
  "documented": true,
5834
- "summary": "Whether the Arcade Store answers here, synchronously. Draw your own \"Get\nGems\" button only when it is true.",
5998
+ "summary": "Whether the Arcade Store answers here, synchronously. Draw your own \"Get\nCoins\" button only when it is true.",
5835
5999
  "deprecated": null,
5836
6000
  "params": [],
5837
6001
  "returns": null,
@@ -5863,7 +6027,7 @@
5863
6027
  "group": "store",
5864
6028
  "signature": "offers(): Promise<StoreOffersOutcome>",
5865
6029
  "documented": true,
5866
- "summary": "What the store sells this player here: names, art and the rail's own\nprices. `unavailable` / `sign_in_required` for a guest (offer\n`gem.account.requestSignIn`), `unavailable` / `store_off` where the store\nis withheld. Re-read on resume: what is on sale can change.",
6030
+ "summary": "What the store sells this player here: names, art and the rail's own\nprices. A guest is answered too: buying takes them through sign-up first,\nin the Arcade's own screens. `unavailable` / `store_off` where the store is\nwithheld. An older Arcade answers a guest `unavailable` /\n`sign_in_required`. Re-read on resume: what is on sale can change.",
5867
6031
  "deprecated": null,
5868
6032
  "params": [],
5869
6033
  "returns": "Always resolves; never rejects.",
@@ -5902,7 +6066,7 @@
5902
6066
  "group": "store",
5903
6067
  "signature": "showOffer(skuId: string): Promise<ArcadeOutcome>",
5904
6068
  "documented": true,
5905
- "summary": "Ask the arcade to show one SKU from [StoreApi.offers](api-reference-game.md#storeapi-offers) in its own\nsheet, over your paused and hidden game: its art, what the player gets, a\nsale if one is on, and, for a pass the player already holds, how long it\nhas left. The sheet's Buy opens the same checkout as\n[StoreApi.purchase](api-reference-game.md#storeapi-purchase). Like `purchase`, it needs no press.\n\nUse it for an offer you would have to hardcode a pitch for: VIP and other\npasses, and bundles. Your button only needs to say what it opens. Draw a\nGem pack yourself and use `purchase` instead. Check\n[StoreApi.showOfferAvailable](api-reference-game.md#storeapi-showofferavailable) first, and that the SKU is in `offers`.\n\nIt answers exactly as `purchase` does, with one addition: `declined` /\n`cancelled` also covers the player leaving the sheet without pressing Buy,\nand you are not told which of the two they closed. Do not ask again\nunprompted; the player's next press opens it again. `unavailable` / `unsupported`\nmeans this Arcade does not draw the sheet, and nothing was sent.\n`unavailable` / `error` means **the outcome is unknown**: re-read balances\nand inventory through `gem.me`, and keep listening with\n[StoreApi.onSettled](api-reference-game.md#storeapi-onsettled).\n\nNO TIMEOUT: it waits for as long as the arcade is connected, because a\nplayer may read a sheet and pay for as long as they like.",
6069
+ "summary": "Ask the arcade to show one SKU from [StoreApi.offers](api-reference-game.md#storeapi-offers) in its own\nsheet, over your paused and hidden game: its art, what the player gets, a\nsale if one is on, and, for a pass the player already holds, how long it\nhas left. The sheet's Buy opens the same checkout as\n[StoreApi.purchase](api-reference-game.md#storeapi-purchase). Like `purchase`, it needs no press.\n\nUse it for an offer you would have to hardcode a pitch for: VIP and other\npasses, and bundles. Your button only needs to say what it opens. Draw a\nCoin pack yourself and use `purchase` instead. For a pass, call\n[StoreApi.showPass](api-reference-game.md#storeapi-showpass) with its slug. Check\n[StoreApi.showOfferAvailable](api-reference-game.md#storeapi-showofferavailable) first, and that the SKU is in `offers`.\n\nIt answers exactly as `purchase` does, with one addition: `declined` /\n`cancelled` also covers the player leaving the sheet without pressing Buy,\nand you are not told which of the two they closed. Do not ask again\nunprompted; the player's next press opens it again. `unavailable` / `unsupported`\nmeans this Arcade does not draw the sheet, and nothing was sent.\n`unavailable` / `error` means **the outcome is unknown**: re-read balances\nand inventory through `gem.me`, and keep listening with\n[StoreApi.onSettled](api-reference-game.md#storeapi-onsettled).\n\nNO TIMEOUT: it waits for as long as the arcade is connected, because a\nplayer may read a sheet and pay for as long as they like.",
5906
6070
  "deprecated": null,
5907
6071
  "params": [
5908
6072
  {
@@ -5918,6 +6082,52 @@
5918
6082
  "defaultValue": null,
5919
6083
  "guides": []
5920
6084
  },
6085
+ {
6086
+ "id": "StoreApi.showPass",
6087
+ "name": "showPass",
6088
+ "anchor": "storeapi-showpass",
6089
+ "group": "store",
6090
+ "signature": "showPass(slug: string): Promise<ShowPassOutcome>",
6091
+ "documented": true,
6092
+ "summary": "Show a pass by its slug in the Arcade's own sheet, over your paused game.\nPass it `upsell.pass` straight from `gem.gameConfig.preview`, never a\nliteral. Sugar over [StoreApi.offers](api-reference-game.md#storeapi-offers) and [StoreApi.showOffer](api-reference-game.md#storeapi-showoffer):\nit finds the offer whose `pass` is `slug` and shows that. A guest is taken\nthrough sign-up first, then back to the sheet.\n\n- `ok`, `held: true` — **a fresh read of `gem.me.passes` shows the pass\n held.** Run the recipe or claim now, and the pass's bonus applies.\n- `ok` / `pending`, `held: false` — the player paid, and the pass has not\n arrived yet (Ask to Buy, a slow payment). Run the recipe now, without\n the bonus: the platform holds nothing back for later.\n- `declined` — they closed the sheet. Run the recipe as it is, and don't\n ask again at this reward moment.\n- `unavailable` / `not_found` — the pass is not on sale to this player\n here, or this Arcade is too old to say which offer is a pass, and\n nothing opened. `unavailable` / `unsupported` — this Arcade draws no\n sheet. Run the recipe as it is.\n- `unavailable` / `error` — **the outcome is unknown, and the player may\n have paid.** Run the recipe; `gem.me.passes.on('changed')` hears the\n pass if it arrives.\n\nNO TIMEOUT on the sheet, as with `showOffer`. After a paid `ok` it reads\n`gem.me.passes` for about ten seconds before it settles for `pending`.",
6093
+ "deprecated": null,
6094
+ "params": [
6095
+ {
6096
+ "name": "slug",
6097
+ "type": "string",
6098
+ "optional": false,
6099
+ "summary": null
6100
+ }
6101
+ ],
6102
+ "returns": "Always resolves; never rejects.",
6103
+ "throws": null,
6104
+ "example": null,
6105
+ "defaultValue": null,
6106
+ "guides": []
6107
+ },
6108
+ {
6109
+ "id": "StoreApi.passOnSale",
6110
+ "name": "passOnSale",
6111
+ "anchor": "storeapi-passonsale",
6112
+ "group": "store",
6113
+ "signature": "passOnSale(slug: string): Promise<boolean>",
6114
+ "documented": true,
6115
+ "summary": "Whether the pass `slug` is on sale to this player here, so\n[StoreApi.showPass](api-reference-game.md#storeapi-showpass) would open it. For a screen that sells a pass\noutside a reward moment, such as a \"VIP perks\" panel; at a reward moment,\n`gem.gameConfig.preview`'s `upsells` already says so. `false` where the\nstore is off, for a player the platform won't sell it to, after the\nplayer declined its sheet twice today, and on an older Arcade. A player\nwho holds the pass may still read `true`: the sheet adds time.",
6116
+ "deprecated": null,
6117
+ "params": [
6118
+ {
6119
+ "name": "slug",
6120
+ "type": "string",
6121
+ "optional": false,
6122
+ "summary": null
6123
+ }
6124
+ ],
6125
+ "returns": "Always resolves; never rejects.",
6126
+ "throws": null,
6127
+ "example": null,
6128
+ "defaultValue": null,
6129
+ "guides": []
6130
+ },
5921
6131
  {
5922
6132
  "id": "StoreApi.onSettled",
5923
6133
  "name": "onSettled",
@@ -7858,6 +8068,374 @@
7858
8068
  "defaultValue": null,
7859
8069
  "guides": []
7860
8070
  },
8071
+ {
8072
+ "id": "PreviewTarget",
8073
+ "name": "PreviewTarget",
8074
+ "anchor": "previewtarget",
8075
+ "group": "payout-preview",
8076
+ "signature": "type PreviewTarget = { recipe: string } | { progression: string; add?: number }",
8077
+ "documented": true,
8078
+ "summary": "What to preview: a recipe, or a progression with the delta the game is about\nto apply. A config id, never an amount and never a pass.\n\n- `{ recipe: 'open_chest' }` — the recipe's grants, its roll, its bonuses,\n and the platform payouts of any progression it adds to.\n- `{ progression: 'run_complete' }` — the progression's `on_complete`\n payouts, \"if it completes\".\n- `{ progression: 'puzzles_cleared', add: 3 }` — its `on_add` payouts for\n that delta, and its `on_complete` payouts if it completes.\n\nIds and slugs are both accepted, as everywhere in `gem.gameConfig`.",
8079
+ "deprecated": null,
8080
+ "params": [],
8081
+ "returns": null,
8082
+ "throws": null,
8083
+ "example": null,
8084
+ "defaultValue": null,
8085
+ "guides": []
8086
+ },
8087
+ {
8088
+ "id": "PreviewGrant",
8089
+ "name": "PreviewGrant",
8090
+ "anchor": "previewgrant",
8091
+ "group": "payout-preview",
8092
+ "signature": "type PreviewGrant = { kind: \"item\"; itemId: string; quantity: number } | { kind: \"currency\"; currencyId: string; amount: number } | { kind: \"roll\"; lootTableId: string; count: number }",
8093
+ "documented": true,
8094
+ "summary": "One thing a claim grants in your game. A roll is a count of rolls from a loot\ntable, never what they land on: never show a locked roll's outcome.",
8095
+ "deprecated": null,
8096
+ "params": [],
8097
+ "returns": null,
8098
+ "throws": null,
8099
+ "example": null,
8100
+ "defaultValue": null,
8101
+ "guides": []
8102
+ },
8103
+ {
8104
+ "id": "UnmetRequirement",
8105
+ "name": "UnmetRequirement",
8106
+ "anchor": "unmetrequirement",
8107
+ "group": "payout-preview",
8108
+ "signature": "interface UnmetRequirement",
8109
+ "documented": true,
8110
+ "summary": "One requirement a bonus has that the player does not meet: where it is, and its kind.",
8111
+ "deprecated": null,
8112
+ "params": [],
8113
+ "returns": null,
8114
+ "throws": null,
8115
+ "example": null,
8116
+ "defaultValue": null,
8117
+ "guides": []
8118
+ },
8119
+ {
8120
+ "id": "UnmetRequirement.index",
8121
+ "name": "index",
8122
+ "anchor": "unmetrequirement-index",
8123
+ "group": "payout-preview",
8124
+ "signature": "readonly index: number",
8125
+ "documented": true,
8126
+ "summary": "Its position in the bonus's `requires`.",
8127
+ "deprecated": null,
8128
+ "params": [],
8129
+ "returns": null,
8130
+ "throws": null,
8131
+ "example": null,
8132
+ "defaultValue": null,
8133
+ "guides": []
8134
+ },
8135
+ {
8136
+ "id": "UnmetRequirement.kind",
8137
+ "name": "kind",
8138
+ "anchor": "unmetrequirement-kind",
8139
+ "group": "payout-preview",
8140
+ "signature": "readonly kind: string",
8141
+ "documented": true,
8142
+ "summary": "Its kind, such as `holds_pass`. Never the pass or the item it names.",
8143
+ "deprecated": null,
8144
+ "params": [],
8145
+ "returns": null,
8146
+ "throws": null,
8147
+ "example": null,
8148
+ "defaultValue": null,
8149
+ "guides": []
8150
+ },
8151
+ {
8152
+ "id": "BonusPreview",
8153
+ "name": "BonusPreview",
8154
+ "anchor": "bonuspreview",
8155
+ "group": "payout-preview",
8156
+ "signature": "interface BonusPreview",
8157
+ "documented": true,
8158
+ "summary": "One `bonuses` entry, and whether this player gets it.",
8159
+ "deprecated": null,
8160
+ "params": [],
8161
+ "returns": null,
8162
+ "throws": null,
8163
+ "example": null,
8164
+ "defaultValue": null,
8165
+ "guides": []
8166
+ },
8167
+ {
8168
+ "id": "BonusPreview.id",
8169
+ "name": "id",
8170
+ "anchor": "bonuspreview-id",
8171
+ "group": "payout-preview",
8172
+ "signature": "readonly id: string",
8173
+ "documented": true,
8174
+ "summary": "The bonus's id, as you configured it.",
8175
+ "deprecated": null,
8176
+ "params": [],
8177
+ "returns": null,
8178
+ "throws": null,
8179
+ "example": null,
8180
+ "defaultValue": null,
8181
+ "guides": []
8182
+ },
8183
+ {
8184
+ "id": "BonusPreview.grants",
8185
+ "name": "grants",
8186
+ "anchor": "bonuspreview-grants",
8187
+ "group": "payout-preview",
8188
+ "signature": "readonly grants: readonly PreviewGrant[]",
8189
+ "documented": true,
8190
+ "summary": "What it grants.",
8191
+ "deprecated": null,
8192
+ "params": [],
8193
+ "returns": null,
8194
+ "throws": null,
8195
+ "example": null,
8196
+ "defaultValue": null,
8197
+ "guides": []
8198
+ },
8199
+ {
8200
+ "id": "BonusPreview.eligible",
8201
+ "name": "eligible",
8202
+ "anchor": "bonuspreview-eligible",
8203
+ "group": "payout-preview",
8204
+ "signature": "readonly eligible: boolean | \"unknown\"",
8205
+ "documented": true,
8206
+ "summary": "`true` — every requirement holds now. `false` — at least one does not\n(see `unmet`). `'unknown'` — one the browser cannot see, such as owning a\nplatform item; never a guess. Advisory: the run decides.",
8207
+ "deprecated": null,
8208
+ "params": [],
8209
+ "returns": null,
8210
+ "throws": null,
8211
+ "example": null,
8212
+ "defaultValue": null,
8213
+ "guides": []
8214
+ },
8215
+ {
8216
+ "id": "BonusPreview.unmet",
8217
+ "name": "unmet",
8218
+ "anchor": "bonuspreview-unmet",
8219
+ "group": "payout-preview",
8220
+ "signature": "readonly unmet: readonly UnmetRequirement[]",
8221
+ "documented": true,
8222
+ "summary": "The requirements that do not hold. Empty unless `eligible` is `false`.",
8223
+ "deprecated": null,
8224
+ "params": [],
8225
+ "returns": null,
8226
+ "throws": null,
8227
+ "example": null,
8228
+ "defaultValue": null,
8229
+ "guides": []
8230
+ },
8231
+ {
8232
+ "id": "PassUpsell",
8233
+ "name": "PassUpsell",
8234
+ "anchor": "passupsell",
8235
+ "group": "payout-preview",
8236
+ "signature": "interface PassUpsell",
8237
+ "documented": true,
8238
+ "summary": "What holding one pass would add to a claim.",
8239
+ "deprecated": null,
8240
+ "params": [],
8241
+ "returns": null,
8242
+ "throws": null,
8243
+ "example": null,
8244
+ "defaultValue": null,
8245
+ "guides": []
8246
+ },
8247
+ {
8248
+ "id": "PassUpsell.pass",
8249
+ "name": "pass",
8250
+ "anchor": "passupsell-pass",
8251
+ "group": "payout-preview",
8252
+ "signature": "readonly pass: string",
8253
+ "documented": true,
8254
+ "summary": "The pass's slug: what `gem.store.showPass` takes.",
8255
+ "deprecated": null,
8256
+ "params": [],
8257
+ "returns": null,
8258
+ "throws": null,
8259
+ "example": null,
8260
+ "defaultValue": null,
8261
+ "guides": []
8262
+ },
8263
+ {
8264
+ "id": "PassUpsell.name",
8265
+ "name": "name",
8266
+ "anchor": "passupsell-name",
8267
+ "group": "payout-preview",
8268
+ "signature": "readonly name: string",
8269
+ "documented": true,
8270
+ "summary": "The store's own name for it, localized. Show this, never your own word for it.",
8271
+ "deprecated": null,
8272
+ "params": [],
8273
+ "returns": null,
8274
+ "throws": null,
8275
+ "example": null,
8276
+ "defaultValue": null,
8277
+ "guides": []
8278
+ },
8279
+ {
8280
+ "id": "PassUpsell.offer",
8281
+ "name": "offer",
8282
+ "anchor": "passupsell-offer",
8283
+ "group": "payout-preview",
8284
+ "signature": "readonly offer: ArcadeOffer",
8285
+ "documented": true,
8286
+ "summary": "The pass's offer, as `gem.store.offers` lists it.",
8287
+ "deprecated": null,
8288
+ "params": [],
8289
+ "returns": null,
8290
+ "throws": null,
8291
+ "example": null,
8292
+ "defaultValue": null,
8293
+ "guides": []
8294
+ },
8295
+ {
8296
+ "id": "PassUpsell.platformGrants",
8297
+ "name": "platformGrants",
8298
+ "anchor": "passupsell-platformgrants",
8299
+ "group": "payout-preview",
8300
+ "signature": "readonly platformGrants: readonly { currencySlug?: string; currencyId?: string; total: number; extra: number; ifComplete?: true }[]",
8301
+ "documented": true,
8302
+ "summary": "Each payout this pass would raise: the new `total`, and the `extra` over now.",
8303
+ "deprecated": null,
8304
+ "params": [],
8305
+ "returns": null,
8306
+ "throws": null,
8307
+ "example": null,
8308
+ "defaultValue": null,
8309
+ "guides": []
8310
+ },
8311
+ {
8312
+ "id": "PassUpsell.bonuses",
8313
+ "name": "bonuses",
8314
+ "anchor": "passupsell-bonuses",
8315
+ "group": "payout-preview",
8316
+ "signature": "readonly bonuses: readonly { id: string; grants: readonly PreviewGrant[] }[]",
8317
+ "documented": true,
8318
+ "summary": "The bonuses this pass would make eligible.",
8319
+ "deprecated": null,
8320
+ "params": [],
8321
+ "returns": null,
8322
+ "throws": null,
8323
+ "example": null,
8324
+ "defaultValue": null,
8325
+ "guides": []
8326
+ },
8327
+ {
8328
+ "id": "ConfigPreview",
8329
+ "name": "ConfigPreview",
8330
+ "anchor": "configpreview",
8331
+ "group": "payout-preview",
8332
+ "signature": "interface ConfigPreview",
8333
+ "documented": true,
8334
+ "summary": "What [PreviewTarget](api-reference-game.md#previewtarget) would give this player now, and what each pass would add.",
8335
+ "deprecated": null,
8336
+ "params": [],
8337
+ "returns": null,
8338
+ "throws": null,
8339
+ "example": null,
8340
+ "defaultValue": null,
8341
+ "guides": []
8342
+ },
8343
+ {
8344
+ "id": "ConfigPreview.grants",
8345
+ "name": "grants",
8346
+ "anchor": "configpreview-grants",
8347
+ "group": "payout-preview",
8348
+ "signature": "readonly grants: readonly PreviewGrant[]",
8349
+ "documented": true,
8350
+ "summary": "Your game's own grants: items, game currencies, rolls.",
8351
+ "deprecated": null,
8352
+ "params": [],
8353
+ "returns": null,
8354
+ "throws": null,
8355
+ "example": null,
8356
+ "defaultValue": null,
8357
+ "guides": []
8358
+ },
8359
+ {
8360
+ "id": "ConfigPreview.platformGrants",
8361
+ "name": "platformGrants",
8362
+ "anchor": "configpreview-platformgrants",
8363
+ "group": "payout-preview",
8364
+ "signature": "readonly platformGrants: readonly PlatformGrantPreview[]",
8365
+ "documented": true,
8366
+ "summary": "One per platform payout that would fire.",
8367
+ "deprecated": null,
8368
+ "params": [],
8369
+ "returns": null,
8370
+ "throws": null,
8371
+ "example": null,
8372
+ "defaultValue": null,
8373
+ "guides": []
8374
+ },
8375
+ {
8376
+ "id": "ConfigPreview.bonuses",
8377
+ "name": "bonuses",
8378
+ "anchor": "configpreview-bonuses",
8379
+ "group": "payout-preview",
8380
+ "signature": "readonly bonuses: readonly BonusPreview[]",
8381
+ "documented": true,
8382
+ "summary": "One per `bonuses` entry, in config order.",
8383
+ "deprecated": null,
8384
+ "params": [],
8385
+ "returns": null,
8386
+ "throws": null,
8387
+ "example": null,
8388
+ "defaultValue": null,
8389
+ "guides": []
8390
+ },
8391
+ {
8392
+ "id": "ConfigPreview.upsells",
8393
+ "name": "upsells",
8394
+ "anchor": "configpreview-upsells",
8395
+ "group": "payout-preview",
8396
+ "signature": "readonly upsells: readonly PassUpsell[]",
8397
+ "documented": true,
8398
+ "summary": "One per pass on sale here, not held, that would change this answer. Empty\nmeans show no upsell: no pass would add anything, or none is on sale to\nthis player (a minor, a store that is off, a pass declined twice today, or\nalready held).",
8399
+ "deprecated": null,
8400
+ "params": [],
8401
+ "returns": null,
8402
+ "throws": null,
8403
+ "example": null,
8404
+ "defaultValue": null,
8405
+ "guides": []
8406
+ },
8407
+ {
8408
+ "id": "PreviewError",
8409
+ "name": "PreviewError",
8410
+ "anchor": "previewerror",
8411
+ "group": "failures",
8412
+ "signature": "class PreviewError",
8413
+ "documented": true,
8414
+ "summary": "Why `gem.gameConfig.preview` could not work out an answer.",
8415
+ "deprecated": null,
8416
+ "params": [],
8417
+ "returns": null,
8418
+ "throws": null,
8419
+ "example": null,
8420
+ "defaultValue": null,
8421
+ "guides": []
8422
+ },
8423
+ {
8424
+ "id": "PreviewError.code",
8425
+ "name": "code",
8426
+ "anchor": "previewerror-code",
8427
+ "group": "failures",
8428
+ "signature": "readonly code: \"unsupported\" | \"not_found\" | \"invalid_argument\"",
8429
+ "documented": true,
8430
+ "summary": "`not_found` — the config has no recipe or progression by that id or\nslug; `invalid_argument` — the target is not `{ recipe }` or\n`{ progression, add? }` with a positive whole `add`; `unsupported` —\nnot in a browser game (a function or a server runs the recipe and reads\nthe receipt).",
8431
+ "deprecated": null,
8432
+ "params": [],
8433
+ "returns": null,
8434
+ "throws": null,
8435
+ "example": null,
8436
+ "defaultValue": null,
8437
+ "guides": []
8438
+ },
7861
8439
  {
7862
8440
  "id": "GemLookSpeed",
7863
8441
  "name": "GemLookSpeed",
@@ -8496,13 +9074,13 @@
8496
9074
  "guides": []
8497
9075
  },
8498
9076
  {
8499
- "id": "GamePass",
8500
- "name": "GamePass",
8501
- "anchor": "gamepass",
8502
- "group": "saves",
8503
- "signature": "interface GamePass",
9077
+ "id": "PlatformGrantSource",
9078
+ "name": "PlatformGrantSource",
9079
+ "anchor": "platformgrantsource",
9080
+ "group": "payout-preview",
9081
+ "signature": "type PlatformGrantSource = { source: \"pass\"; pass: string; amount: number } | { source: \"boost\"; amount: number }",
8504
9082
  "documented": true,
8505
- "summary": "One pass games may see, and whether this player holds it. Listed whether they\nhold it or not, and this is everything a game learns about it.",
9083
+ "summary": "Where the part of a payout above its base comes from.",
8506
9084
  "deprecated": null,
8507
9085
  "params": [],
8508
9086
  "returns": null,
@@ -8512,13 +9090,13 @@
8512
9090
  "guides": []
8513
9091
  },
8514
9092
  {
8515
- "id": "GamePass.pass",
8516
- "name": "pass",
8517
- "anchor": "gamepass-pass",
8518
- "group": "saves",
8519
- "signature": "readonly pass: string",
9093
+ "id": "PlatformGrantPreview",
9094
+ "name": "PlatformGrantPreview",
9095
+ "anchor": "platformgrantpreview",
9096
+ "group": "payout-preview",
9097
+ "signature": "interface PlatformGrantPreview",
8520
9098
  "documented": true,
8521
- "summary": "The pass's offering slug, such as `vip`. Stable and not localized: key on this.",
9099
+ "summary": "One platform payout — Coins, today — as the preview expects it or a receipt\nreports it, in one shape, so \"you will earn\" and \"you earned\" render with one\ncomponent.",
8522
9100
  "deprecated": null,
8523
9101
  "params": [],
8524
9102
  "returns": null,
@@ -8528,13 +9106,13 @@
8528
9106
  "guides": []
8529
9107
  },
8530
9108
  {
8531
- "id": "GamePass.held",
8532
- "name": "held",
8533
- "anchor": "gamepass-held",
8534
- "group": "saves",
8535
- "signature": "readonly held: boolean",
9109
+ "id": "PlatformGrantPreview.currencySlug",
9110
+ "name": "currencySlug",
9111
+ "anchor": "platformgrantpreview-currencyslug",
9112
+ "group": "payout-preview",
9113
+ "signature": "readonly currencySlug?: string",
8536
9114
  "documented": true,
8537
- "summary": "Whether the player holds it right now.",
9115
+ "summary": "The currency's slug, e.g. `ARCADE_TICKETS`. Absent when unknown.",
8538
9116
  "deprecated": null,
8539
9117
  "params": [],
8540
9118
  "returns": null,
@@ -8544,13 +9122,29 @@
8544
9122
  "guides": []
8545
9123
  },
8546
9124
  {
8547
- "id": "GamePass.endsAt",
8548
- "name": "endsAt",
8549
- "anchor": "gamepass-endsat",
8550
- "group": "saves",
8551
- "signature": "readonly endsAt: string | null",
9125
+ "id": "PlatformGrantPreview.currencyId",
9126
+ "name": "currencyId",
9127
+ "anchor": "platformgrantpreview-currencyid",
9128
+ "group": "payout-preview",
9129
+ "signature": "readonly currencyId?: string",
8552
9130
  "documented": true,
8553
- "summary": "When the player stops holding it, RFC 3339 in UTC, grace and any queued\nperiod included. `null` when it is not held, and when it is held with no\nend, so read [GamePass.held](api-reference-game.md#gamepass-held) first: `null` alone never means ended.",
9131
+ "summary": "The currency's id, when it is known.",
9132
+ "deprecated": null,
9133
+ "params": [],
9134
+ "returns": null,
9135
+ "throws": null,
9136
+ "example": null,
9137
+ "defaultValue": null,
9138
+ "guides": []
9139
+ },
9140
+ {
9141
+ "id": "PlatformGrantPreview.base",
9142
+ "name": "base",
9143
+ "anchor": "platformgrantpreview-base",
9144
+ "group": "payout-preview",
9145
+ "signature": "readonly base: number",
9146
+ "documented": true,
9147
+ "summary": "What a player with no pass and no Boost gets.",
8554
9148
  "deprecated": null,
8555
9149
  "params": [],
8556
9150
  "returns": null,
@@ -8559,6 +9153,93 @@
8559
9153
  "defaultValue": null,
8560
9154
  "guides": []
8561
9155
  },
9156
+ {
9157
+ "id": "PlatformGrantPreview.total",
9158
+ "name": "total",
9159
+ "anchor": "platformgrantpreview-total",
9160
+ "group": "payout-preview",
9161
+ "signature": "readonly total: number",
9162
+ "documented": true,
9163
+ "summary": "What this player gets: `base` plus `breakdown`.",
9164
+ "deprecated": null,
9165
+ "params": [],
9166
+ "returns": null,
9167
+ "throws": null,
9168
+ "example": null,
9169
+ "defaultValue": null,
9170
+ "guides": []
9171
+ },
9172
+ {
9173
+ "id": "PlatformGrantPreview.breakdown",
9174
+ "name": "breakdown",
9175
+ "anchor": "platformgrantpreview-breakdown",
9176
+ "group": "payout-preview",
9177
+ "signature": "readonly breakdown: readonly PlatformGrantSource[]",
9178
+ "documented": true,
9179
+ "summary": "The part above `base`, and what it is from. Empty when `total` is `base`.",
9180
+ "deprecated": null,
9181
+ "params": [],
9182
+ "returns": null,
9183
+ "throws": null,
9184
+ "example": null,
9185
+ "defaultValue": null,
9186
+ "guides": []
9187
+ },
9188
+ {
9189
+ "id": "PlatformGrantPreview.ifComplete",
9190
+ "name": "ifComplete",
9191
+ "anchor": "platformgrantpreview-ifcomplete",
9192
+ "group": "payout-preview",
9193
+ "signature": "readonly ifComplete?: true",
9194
+ "documented": true,
9195
+ "summary": "`true` for an `on_complete` payout in a preview: it pays only if this\nclaim completes the progression. Absent otherwise, and on a receipt.",
9196
+ "deprecated": null,
9197
+ "params": [],
9198
+ "returns": null,
9199
+ "throws": null,
9200
+ "example": null,
9201
+ "defaultValue": null,
9202
+ "guides": []
9203
+ },
9204
+ {
9205
+ "id": "EarningsApi",
9206
+ "name": "EarningsApi",
9207
+ "anchor": "earningsapi",
9208
+ "group": "payout-preview",
9209
+ "signature": "interface EarningsApi",
9210
+ "documented": true,
9211
+ "summary": "`gem.earnings`: what a payout was, in the shape `gem.gameConfig.preview`\nsays it would be.",
9212
+ "deprecated": null,
9213
+ "params": [],
9214
+ "returns": null,
9215
+ "throws": null,
9216
+ "example": null,
9217
+ "defaultValue": null,
9218
+ "guides": []
9219
+ },
9220
+ {
9221
+ "id": "EarningsApi.fromReceipt",
9222
+ "name": "fromReceipt",
9223
+ "anchor": "earningsapi-fromreceipt",
9224
+ "group": "payout-preview",
9225
+ "signature": "fromReceipt(change: unknown): Promise<PlatformGrantPreview | null>",
9226
+ "documented": true,
9227
+ "summary": "Turn one `platform_grant` change from an order's receipt into a\n[PlatformGrantPreview](api-reference-game.md#platformgrantpreview): `base` is what a player with no pass and no\nBoost would have got under the same limits, `total` what this player got,\nand `breakdown` the pass's or the Boost's part, even when a limit trimmed\nthe payout. Draw \"you earned\" with the component that drew \"you will\nearn\". Resolves `null` for any other kind of change.\n\n**This and `preview` are the only way to show a platform payout.** Never\nmultiply by `gem.player.boost`, and never copy a config amount into your\ngame.",
9228
+ "deprecated": null,
9229
+ "params": [
9230
+ {
9231
+ "name": "change",
9232
+ "type": "unknown",
9233
+ "optional": false,
9234
+ "summary": null
9235
+ }
9236
+ ],
9237
+ "returns": "Always resolves; never rejects.",
9238
+ "throws": null,
9239
+ "example": null,
9240
+ "defaultValue": null,
9241
+ "guides": []
9242
+ },
8562
9243
  {
8563
9244
  "id": "PassesEvent",
8564
9245
  "name": "PassesEvent",
@@ -12033,6 +12714,22 @@
12033
12714
  }
12034
12715
  ]
12035
12716
  },
12717
+ {
12718
+ "id": "GemPlayer.isGuest",
12719
+ "name": "isGuest",
12720
+ "anchor": "gemplayer-isguest",
12721
+ "group": "player",
12722
+ "signature": "readonly isGuest: boolean",
12723
+ "documented": true,
12724
+ "summary": "Whether the Arcade says this player is a **guest it can sign up here**.\n\n`true` only when the Arcade said so. `false` for a player with a full\naccount, on a surface that offers no sign-up, and when the Arcade did not\nsay — an older Arcade — so `false` is never proof of an account. That\nmakes it the test for a sign-up gift: offer one only while this is\n`true`, and the gift can never reach a player who already has an account.\n\nIt changes when a guest signs up in place: `gem.player` is pushed again,\nand `onPlayer` hears it.\n\n```js\nconst gem = createGem({ onPlayer: (player) => (signUpGift.hidden = !player.isGuest) });\n```\n\nFor drawing only, like everything on `gem.player`: what a sign-up earns\nis granted by your function or server, which reads the account itself.",
12725
+ "deprecated": null,
12726
+ "params": [],
12727
+ "returns": null,
12728
+ "throws": null,
12729
+ "example": null,
12730
+ "defaultValue": null,
12731
+ "guides": []
12732
+ },
12036
12733
  {
12037
12734
  "id": "GemPlayer.playerId",
12038
12735
  "name": "playerId",
@@ -13415,6 +14112,22 @@
13415
14112
  "defaultValue": null,
13416
14113
  "guides": []
13417
14114
  },
14115
+ {
14116
+ "id": "Gem.earnings",
14117
+ "name": "earnings",
14118
+ "anchor": "gem-earnings",
14119
+ "group": "start",
14120
+ "signature": "readonly earnings: EarningsApi",
14121
+ "documented": true,
14122
+ "summary": "What a platform payout was: `gem.earnings.fromReceipt(change)` turns a\nreceipt's `platform_grant` change into the shape `gem.gameConfig.preview`\ngives, so \"you will earn\" and \"you earned\" draw with one component.",
14123
+ "deprecated": null,
14124
+ "params": [],
14125
+ "returns": null,
14126
+ "throws": null,
14127
+ "example": null,
14128
+ "defaultValue": null,
14129
+ "guides": []
14130
+ },
13418
14131
  {
13419
14132
  "id": "Gem.purchases",
13420
14133
  "name": "purchases",
@@ -16660,6 +17373,86 @@
16660
17373
  "defaultValue": null,
16661
17374
  "guides": []
16662
17375
  },
17376
+ {
17377
+ "id": "GamePass",
17378
+ "name": "GamePass",
17379
+ "anchor": "gamepass",
17380
+ "group": "saves",
17381
+ "signature": "interface GamePass",
17382
+ "documented": true,
17383
+ "summary": "One pass games may see, and whether this player holds it. Listed whether they\nhold it or not, and this is everything a game learns about it.",
17384
+ "deprecated": null,
17385
+ "params": [],
17386
+ "returns": null,
17387
+ "throws": null,
17388
+ "example": null,
17389
+ "defaultValue": null,
17390
+ "guides": []
17391
+ },
17392
+ {
17393
+ "id": "GamePass.pass",
17394
+ "name": "pass",
17395
+ "anchor": "gamepass-pass",
17396
+ "group": "saves",
17397
+ "signature": "readonly pass: string",
17398
+ "documented": true,
17399
+ "summary": "The pass's offering slug, such as `vip`. Stable and not localized: key on this.",
17400
+ "deprecated": null,
17401
+ "params": [],
17402
+ "returns": null,
17403
+ "throws": null,
17404
+ "example": null,
17405
+ "defaultValue": null,
17406
+ "guides": []
17407
+ },
17408
+ {
17409
+ "id": "GamePass.held",
17410
+ "name": "held",
17411
+ "anchor": "gamepass-held",
17412
+ "group": "saves",
17413
+ "signature": "readonly held: boolean",
17414
+ "documented": true,
17415
+ "summary": "Whether the player holds it right now.",
17416
+ "deprecated": null,
17417
+ "params": [],
17418
+ "returns": null,
17419
+ "throws": null,
17420
+ "example": null,
17421
+ "defaultValue": null,
17422
+ "guides": []
17423
+ },
17424
+ {
17425
+ "id": "GamePass.daysLeft",
17426
+ "name": "daysLeft",
17427
+ "anchor": "gamepass-daysleft",
17428
+ "group": "saves",
17429
+ "signature": "readonly daysLeft: number",
17430
+ "documented": true,
17431
+ "summary": "Whole days the player keeps it, rounded up so a pass with any time left\nreads at least `1`, and **capped at 7**: `7` means \"7 or more\", and is\nalso what a pass held with no end reads. `0` when it is not held. Show\n`7` as \"7+ days left\", never as an exact end.",
17432
+ "deprecated": null,
17433
+ "params": [],
17434
+ "returns": null,
17435
+ "throws": null,
17436
+ "example": null,
17437
+ "defaultValue": null,
17438
+ "guides": []
17439
+ },
17440
+ {
17441
+ "id": "GamePass.endsAt",
17442
+ "name": "endsAt",
17443
+ "anchor": "gamepass-endsat",
17444
+ "group": "saves",
17445
+ "signature": "readonly endsAt: string | null",
17446
+ "documented": true,
17447
+ "summary": "When the player stops holding it, RFC 3339 in UTC, grace and any queued\nperiod included. `null` when it is not held, and when it is held with no\nend, so read [GamePass.held](api-reference-game.md#gamepass-held) first: `null` alone never means ended.",
17448
+ "deprecated": "Use [GamePass.daysLeft](api-reference-game.md#gamepass-daysleft). An exact instant is a value two\ngames could match to link one player's identities, so the platform will\nstop sending it; it reads `null` then. See\n[the deprecation policy](../deprecation-policy.md).",
17449
+ "params": [],
17450
+ "returns": null,
17451
+ "throws": null,
17452
+ "example": null,
17453
+ "defaultValue": null,
17454
+ "guides": []
17455
+ },
16663
17456
  {
16664
17457
  "id": "PlatformCurrencyAccess",
16665
17458
  "name": "PlatformCurrencyAccess",
@@ -18015,6 +18808,52 @@
18015
18808
  "defaultValue": null,
18016
18809
  "guides": []
18017
18810
  },
18811
+ {
18812
+ "id": "GemServerHost.passes",
18813
+ "name": "passes",
18814
+ "anchor": "gemserverhost-passes",
18815
+ "group": "match",
18816
+ "signature": "passes(playerId: string): Promise<GemServerHostRead>",
18817
+ "documented": true,
18818
+ "summary": "Ask the platform half which game-visible passes a player in this match\nholds: the match pass read, made with the allocation's own proof.\n\nMAY BE ABSENT on older platform images, exactly as `endMatch` may, and a\nlisten host never has it. `gem.match.playerPasses(playerId)` is this call;\nyou rarely call it yourself.\n\nResolves with what the platform answered — see [GemServerHostRead](api-reference-game.md#gemserverhostread)\n— and rejects only when the platform half could not be asked at all.",
18819
+ "deprecated": null,
18820
+ "params": [
18821
+ {
18822
+ "name": "playerId",
18823
+ "type": "string",
18824
+ "optional": false,
18825
+ "summary": null
18826
+ }
18827
+ ],
18828
+ "returns": null,
18829
+ "throws": null,
18830
+ "example": null,
18831
+ "defaultValue": null,
18832
+ "guides": []
18833
+ },
18834
+ {
18835
+ "id": "GemServerHost.boost",
18836
+ "name": "boost",
18837
+ "anchor": "gemserverhost-boost",
18838
+ "group": "match",
18839
+ "signature": "boost(playerId: string): Promise<GemServerHostRead>",
18840
+ "documented": true,
18841
+ "summary": "Ask the platform half for a player's Boost, for display: the match boost\nread, made with the allocation's own proof.\n\nMAY BE ABSENT on older platform images and on a listen host.\n`gem.match.playerBoost(playerId)` is this call; you rarely call it\nyourself. Resolves and rejects as [GemServerHost.passes](api-reference-game.md#gemserverhost-passes) does.",
18842
+ "deprecated": null,
18843
+ "params": [
18844
+ {
18845
+ "name": "playerId",
18846
+ "type": "string",
18847
+ "optional": false,
18848
+ "summary": null
18849
+ }
18850
+ ],
18851
+ "returns": null,
18852
+ "throws": null,
18853
+ "example": null,
18854
+ "defaultValue": null,
18855
+ "guides": []
18856
+ },
18018
18857
  {
18019
18858
  "id": "GemServerHost.log",
18020
18859
  "name": "log",
@@ -18061,6 +18900,54 @@
18061
18900
  "defaultValue": null,
18062
18901
  "guides": []
18063
18902
  },
18903
+ {
18904
+ "id": "GemServerHostRead",
18905
+ "name": "GemServerHostRead",
18906
+ "anchor": "gemserverhostread",
18907
+ "group": "match",
18908
+ "signature": "interface GemServerHostRead",
18909
+ "documented": true,
18910
+ "summary": "What the platform half answered to a player read it made for this match:\nthe HTTP status and the decoded JSON body, untouched.\n\nThe runtime adds only the allocation's proof, which never enters the bundle\nprocess; the SDK reads the body and turns a refusal into a `GemApiError`, so\na runtime never has to know what the route's answer means.",
18911
+ "deprecated": null,
18912
+ "params": [],
18913
+ "returns": null,
18914
+ "throws": null,
18915
+ "example": null,
18916
+ "defaultValue": null,
18917
+ "guides": []
18918
+ },
18919
+ {
18920
+ "id": "GemServerHostRead.status",
18921
+ "name": "status",
18922
+ "anchor": "gemserverhostread-status",
18923
+ "group": "match",
18924
+ "signature": "readonly status: number",
18925
+ "documented": true,
18926
+ "summary": "The HTTP status the platform answered with.",
18927
+ "deprecated": null,
18928
+ "params": [],
18929
+ "returns": null,
18930
+ "throws": null,
18931
+ "example": null,
18932
+ "defaultValue": null,
18933
+ "guides": []
18934
+ },
18935
+ {
18936
+ "id": "GemServerHostRead.body",
18937
+ "name": "body",
18938
+ "anchor": "gemserverhostread-body",
18939
+ "group": "match",
18940
+ "signature": "readonly body: unknown",
18941
+ "documented": true,
18942
+ "summary": "The decoded JSON body, or `null` when there was none.",
18943
+ "deprecated": null,
18944
+ "params": [],
18945
+ "returns": null,
18946
+ "throws": null,
18947
+ "example": null,
18948
+ "defaultValue": null,
18949
+ "guides": []
18950
+ },
18064
18951
  {
18065
18952
  "id": "GemServerBundle",
18066
18953
  "name": "GemServerBundle",
@@ -27049,6 +27936,173 @@
27049
27936
  "defaultValue": null,
27050
27937
  "guides": []
27051
27938
  },
27939
+ {
27940
+ "id": "PlatformGrantSource",
27941
+ "name": "PlatformGrantSource",
27942
+ "anchor": "platformgrantsource",
27943
+ "group": "match",
27944
+ "signature": "type PlatformGrantSource = { source: \"pass\"; pass: string; amount: number } | { source: \"boost\"; amount: number }",
27945
+ "documented": true,
27946
+ "summary": "Where the part of a payout above its base comes from.",
27947
+ "deprecated": null,
27948
+ "params": [],
27949
+ "returns": null,
27950
+ "throws": null,
27951
+ "example": null,
27952
+ "defaultValue": null,
27953
+ "guides": []
27954
+ },
27955
+ {
27956
+ "id": "PlatformGrantPreview",
27957
+ "name": "PlatformGrantPreview",
27958
+ "anchor": "platformgrantpreview",
27959
+ "group": "match",
27960
+ "signature": "interface PlatformGrantPreview",
27961
+ "documented": true,
27962
+ "summary": "One platform payout — Coins, today — as the preview expects it or a receipt\nreports it, in one shape, so \"you will earn\" and \"you earned\" render with one\ncomponent.",
27963
+ "deprecated": null,
27964
+ "params": [],
27965
+ "returns": null,
27966
+ "throws": null,
27967
+ "example": null,
27968
+ "defaultValue": null,
27969
+ "guides": []
27970
+ },
27971
+ {
27972
+ "id": "PlatformGrantPreview.currencySlug",
27973
+ "name": "currencySlug",
27974
+ "anchor": "platformgrantpreview-currencyslug",
27975
+ "group": "match",
27976
+ "signature": "readonly currencySlug?: string",
27977
+ "documented": true,
27978
+ "summary": "The currency's slug, e.g. `ARCADE_TICKETS`. Absent when unknown.",
27979
+ "deprecated": null,
27980
+ "params": [],
27981
+ "returns": null,
27982
+ "throws": null,
27983
+ "example": null,
27984
+ "defaultValue": null,
27985
+ "guides": []
27986
+ },
27987
+ {
27988
+ "id": "PlatformGrantPreview.currencyId",
27989
+ "name": "currencyId",
27990
+ "anchor": "platformgrantpreview-currencyid",
27991
+ "group": "match",
27992
+ "signature": "readonly currencyId?: string",
27993
+ "documented": true,
27994
+ "summary": "The currency's id, when it is known.",
27995
+ "deprecated": null,
27996
+ "params": [],
27997
+ "returns": null,
27998
+ "throws": null,
27999
+ "example": null,
28000
+ "defaultValue": null,
28001
+ "guides": []
28002
+ },
28003
+ {
28004
+ "id": "PlatformGrantPreview.base",
28005
+ "name": "base",
28006
+ "anchor": "platformgrantpreview-base",
28007
+ "group": "match",
28008
+ "signature": "readonly base: number",
28009
+ "documented": true,
28010
+ "summary": "What a player with no pass and no Boost gets.",
28011
+ "deprecated": null,
28012
+ "params": [],
28013
+ "returns": null,
28014
+ "throws": null,
28015
+ "example": null,
28016
+ "defaultValue": null,
28017
+ "guides": []
28018
+ },
28019
+ {
28020
+ "id": "PlatformGrantPreview.total",
28021
+ "name": "total",
28022
+ "anchor": "platformgrantpreview-total",
28023
+ "group": "match",
28024
+ "signature": "readonly total: number",
28025
+ "documented": true,
28026
+ "summary": "What this player gets: `base` plus `breakdown`.",
28027
+ "deprecated": null,
28028
+ "params": [],
28029
+ "returns": null,
28030
+ "throws": null,
28031
+ "example": null,
28032
+ "defaultValue": null,
28033
+ "guides": []
28034
+ },
28035
+ {
28036
+ "id": "PlatformGrantPreview.breakdown",
28037
+ "name": "breakdown",
28038
+ "anchor": "platformgrantpreview-breakdown",
28039
+ "group": "match",
28040
+ "signature": "readonly breakdown: readonly PlatformGrantSource[]",
28041
+ "documented": true,
28042
+ "summary": "The part above `base`, and what it is from. Empty when `total` is `base`.",
28043
+ "deprecated": null,
28044
+ "params": [],
28045
+ "returns": null,
28046
+ "throws": null,
28047
+ "example": null,
28048
+ "defaultValue": null,
28049
+ "guides": []
28050
+ },
28051
+ {
28052
+ "id": "PlatformGrantPreview.ifComplete",
28053
+ "name": "ifComplete",
28054
+ "anchor": "platformgrantpreview-ifcomplete",
28055
+ "group": "match",
28056
+ "signature": "readonly ifComplete?: true",
28057
+ "documented": true,
28058
+ "summary": "`true` for an `on_complete` payout in a preview: it pays only if this\nclaim completes the progression. Absent otherwise, and on a receipt.",
28059
+ "deprecated": null,
28060
+ "params": [],
28061
+ "returns": null,
28062
+ "throws": null,
28063
+ "example": null,
28064
+ "defaultValue": null,
28065
+ "guides": []
28066
+ },
28067
+ {
28068
+ "id": "EarningsApi",
28069
+ "name": "EarningsApi",
28070
+ "anchor": "earningsapi",
28071
+ "group": "match",
28072
+ "signature": "interface EarningsApi",
28073
+ "documented": true,
28074
+ "summary": "`gem.earnings`: what a payout was, in the shape `gem.gameConfig.preview`\nsays it would be.",
28075
+ "deprecated": null,
28076
+ "params": [],
28077
+ "returns": null,
28078
+ "throws": null,
28079
+ "example": null,
28080
+ "defaultValue": null,
28081
+ "guides": []
28082
+ },
28083
+ {
28084
+ "id": "EarningsApi.fromReceipt",
28085
+ "name": "fromReceipt",
28086
+ "anchor": "earningsapi-fromreceipt",
28087
+ "group": "match",
28088
+ "signature": "fromReceipt(change: unknown): Promise<PlatformGrantPreview | null>",
28089
+ "documented": true,
28090
+ "summary": "Turn one `platform_grant` change from an order's receipt into a\n[PlatformGrantPreview](api-reference-server.md#platformgrantpreview): `base` is what a player with no pass and no\nBoost would have got under the same limits, `total` what this player got,\nand `breakdown` the pass's or the Boost's part, even when a limit trimmed\nthe payout. Draw \"you earned\" with the component that drew \"you will\nearn\". Resolves `null` for any other kind of change.\n\n**This and `preview` are the only way to show a platform payout.** Never\nmultiply by `gem.player.boost`, and never copy a config amount into your\ngame.",
28091
+ "deprecated": null,
28092
+ "params": [
28093
+ {
28094
+ "name": "change",
28095
+ "type": "unknown",
28096
+ "optional": false,
28097
+ "summary": null
28098
+ }
28099
+ ],
28100
+ "returns": "Always resolves; never rejects.",
28101
+ "throws": null,
28102
+ "example": null,
28103
+ "defaultValue": null,
28104
+ "guides": []
28105
+ },
27052
28106
  {
27053
28107
  "id": "FunctionInvokeOptions",
27054
28108
  "name": "FunctionInvokeOptions",
@@ -27398,6 +28452,86 @@
27398
28452
  "defaultValue": null,
27399
28453
  "guides": []
27400
28454
  },
28455
+ {
28456
+ "id": "GamePass",
28457
+ "name": "GamePass",
28458
+ "anchor": "gamepass",
28459
+ "group": "match",
28460
+ "signature": "interface GamePass",
28461
+ "documented": true,
28462
+ "summary": "One pass games may see, and whether this player holds it. Listed whether they\nhold it or not, and this is everything a game learns about it.",
28463
+ "deprecated": null,
28464
+ "params": [],
28465
+ "returns": null,
28466
+ "throws": null,
28467
+ "example": null,
28468
+ "defaultValue": null,
28469
+ "guides": []
28470
+ },
28471
+ {
28472
+ "id": "GamePass.pass",
28473
+ "name": "pass",
28474
+ "anchor": "gamepass-pass",
28475
+ "group": "match",
28476
+ "signature": "readonly pass: string",
28477
+ "documented": true,
28478
+ "summary": "The pass's offering slug, such as `vip`. Stable and not localized: key on this.",
28479
+ "deprecated": null,
28480
+ "params": [],
28481
+ "returns": null,
28482
+ "throws": null,
28483
+ "example": null,
28484
+ "defaultValue": null,
28485
+ "guides": []
28486
+ },
28487
+ {
28488
+ "id": "GamePass.held",
28489
+ "name": "held",
28490
+ "anchor": "gamepass-held",
28491
+ "group": "match",
28492
+ "signature": "readonly held: boolean",
28493
+ "documented": true,
28494
+ "summary": "Whether the player holds it right now.",
28495
+ "deprecated": null,
28496
+ "params": [],
28497
+ "returns": null,
28498
+ "throws": null,
28499
+ "example": null,
28500
+ "defaultValue": null,
28501
+ "guides": []
28502
+ },
28503
+ {
28504
+ "id": "GamePass.daysLeft",
28505
+ "name": "daysLeft",
28506
+ "anchor": "gamepass-daysleft",
28507
+ "group": "match",
28508
+ "signature": "readonly daysLeft: number",
28509
+ "documented": true,
28510
+ "summary": "Whole days the player keeps it, rounded up so a pass with any time left\nreads at least `1`, and **capped at 7**: `7` means \"7 or more\", and is\nalso what a pass held with no end reads. `0` when it is not held. Show\n`7` as \"7+ days left\", never as an exact end.",
28511
+ "deprecated": null,
28512
+ "params": [],
28513
+ "returns": null,
28514
+ "throws": null,
28515
+ "example": null,
28516
+ "defaultValue": null,
28517
+ "guides": []
28518
+ },
28519
+ {
28520
+ "id": "GamePass.endsAt",
28521
+ "name": "endsAt",
28522
+ "anchor": "gamepass-endsat",
28523
+ "group": "match",
28524
+ "signature": "readonly endsAt: string | null",
28525
+ "documented": true,
28526
+ "summary": "When the player stops holding it, RFC 3339 in UTC, grace and any queued\nperiod included. `null` when it is not held, and when it is held with no\nend, so read [GamePass.held](api-reference-server.md#gamepass-held) first: `null` alone never means ended.",
28527
+ "deprecated": "Use [GamePass.daysLeft](api-reference-server.md#gamepass-daysleft). An exact instant is a value two\ngames could match to link one player's identities, so the platform will\nstop sending it; it reads `null` then. See\n[the deprecation policy](../deprecation-policy.md).",
28528
+ "params": [],
28529
+ "returns": null,
28530
+ "throws": null,
28531
+ "example": null,
28532
+ "defaultValue": null,
28533
+ "guides": []
28534
+ },
27401
28535
  {
27402
28536
  "id": "Clock",
27403
28537
  "name": "Clock",
@@ -27982,6 +29116,22 @@
27982
29116
  "defaultValue": null,
27983
29117
  "guides": []
27984
29118
  },
29119
+ {
29120
+ "id": "GemServerHostRead",
29121
+ "name": "GemServerHostRead",
29122
+ "anchor": "gemserverhostread",
29123
+ "group": "host",
29124
+ "signature": "interface GemServerHostRead",
29125
+ "documented": true,
29126
+ "summary": "What the platform half answered to a player read it made for this match:\nthe HTTP status and the decoded JSON body, untouched.\n\nThe runtime adds only the allocation's proof, which never enters the bundle\nprocess; the SDK reads the body and turns a refusal into a `GemApiError`, so\na runtime never has to know what the route's answer means.",
29127
+ "deprecated": null,
29128
+ "params": [],
29129
+ "returns": null,
29130
+ "throws": null,
29131
+ "example": null,
29132
+ "defaultValue": null,
29133
+ "guides": []
29134
+ },
27985
29135
  {
27986
29136
  "id": "SendOptions",
27987
29137
  "name": "SendOptions",
@@ -28297,6 +29447,118 @@
28297
29447
  "defaultValue": null,
28298
29448
  "guides": []
28299
29449
  },
29450
+ {
29451
+ "id": "MatchBoostMultiplier",
29452
+ "name": "MatchBoostMultiplier",
29453
+ "anchor": "matchboostmultiplier",
29454
+ "group": "match",
29455
+ "signature": "interface MatchBoostMultiplier",
29456
+ "documented": true,
29457
+ "summary": "One platform currency's Boost, as a dedicated server reads it.",
29458
+ "deprecated": null,
29459
+ "params": [],
29460
+ "returns": null,
29461
+ "throws": null,
29462
+ "example": null,
29463
+ "defaultValue": null,
29464
+ "guides": []
29465
+ },
29466
+ {
29467
+ "id": "MatchBoostMultiplier.currencySlug",
29468
+ "name": "currencySlug",
29469
+ "anchor": "matchboostmultiplier-currencyslug",
29470
+ "group": "match",
29471
+ "signature": "readonly currencySlug: string",
29472
+ "documented": true,
29473
+ "summary": "The currency's slug, e.g. `GEMS` or `ARCADE_TICKETS`.",
29474
+ "deprecated": null,
29475
+ "params": [],
29476
+ "returns": null,
29477
+ "throws": null,
29478
+ "example": null,
29479
+ "defaultValue": null,
29480
+ "guides": []
29481
+ },
29482
+ {
29483
+ "id": "MatchBoostMultiplier.multiplier",
29484
+ "name": "multiplier",
29485
+ "anchor": "matchboostmultiplier-multiplier",
29486
+ "group": "match",
29487
+ "signature": "readonly multiplier: number",
29488
+ "documented": true,
29489
+ "summary": "How much faster the player earns it right now: `2` is 2x, `1` is not boosted.",
29490
+ "deprecated": null,
29491
+ "params": [],
29492
+ "returns": null,
29493
+ "throws": null,
29494
+ "example": null,
29495
+ "defaultValue": null,
29496
+ "guides": []
29497
+ },
29498
+ {
29499
+ "id": "MatchPlayerBoost",
29500
+ "name": "MatchPlayerBoost",
29501
+ "anchor": "matchplayerboost",
29502
+ "group": "match",
29503
+ "signature": "interface MatchPlayerBoost",
29504
+ "documented": true,
29505
+ "summary": "A player's Boost, as a dedicated server reads it — **for display only**,\nexactly as `gem.player.boost` is in the browser.\n\n⚠️ **Show it; never gate on it.** Nothing a player can do, reach or win may\ndepend on whether they are boosted. To gate on something a player paid for,\ngate on a pass: `gem.match.playerPasses`.",
29506
+ "deprecated": null,
29507
+ "params": [],
29508
+ "returns": null,
29509
+ "throws": null,
29510
+ "example": null,
29511
+ "defaultValue": null,
29512
+ "guides": []
29513
+ },
29514
+ {
29515
+ "id": "MatchPlayerBoost.active",
29516
+ "name": "active",
29517
+ "anchor": "matchplayerboost-active",
29518
+ "group": "match",
29519
+ "signature": "readonly active: boolean",
29520
+ "documented": true,
29521
+ "summary": "Whether any currency earns faster than 1x right now.",
29522
+ "deprecated": null,
29523
+ "params": [],
29524
+ "returns": null,
29525
+ "throws": null,
29526
+ "example": null,
29527
+ "defaultValue": null,
29528
+ "guides": []
29529
+ },
29530
+ {
29531
+ "id": "MatchPlayerBoost.multipliers",
29532
+ "name": "multipliers",
29533
+ "anchor": "matchplayerboost-multipliers",
29534
+ "group": "match",
29535
+ "signature": "readonly multipliers: readonly MatchBoostMultiplier[]",
29536
+ "documented": true,
29537
+ "summary": "One entry per boostable platform currency, boosted or not.",
29538
+ "deprecated": null,
29539
+ "params": [],
29540
+ "returns": null,
29541
+ "throws": null,
29542
+ "example": null,
29543
+ "defaultValue": null,
29544
+ "guides": []
29545
+ },
29546
+ {
29547
+ "id": "MatchPlayerBoost.expiresInDays",
29548
+ "name": "expiresInDays",
29549
+ "anchor": "matchplayerboost-expiresindays",
29550
+ "group": "match",
29551
+ "signature": "readonly expiresInDays?: number",
29552
+ "documented": true,
29553
+ "summary": "Whole days until the soonest boosted currency drops back to 1x, rounded up\nand **capped at 7** (`7` means \"7 or more\"). Absent when nothing is boosted.",
29554
+ "deprecated": null,
29555
+ "params": [],
29556
+ "returns": null,
29557
+ "throws": null,
29558
+ "example": null,
29559
+ "defaultValue": null,
29560
+ "guides": []
29561
+ },
28300
29562
  {
28301
29563
  "id": "PlayerText",
28302
29564
  "name": "PlayerText",
@@ -28805,7 +30067,7 @@
28805
30067
  "name": "match",
28806
30068
  "anchor": "gemserver-match",
28807
30069
  "group": "api",
28808
- "signature": "readonly match: { end: null; setBackfill: null; reportPlayers: null }",
30070
+ "signature": "readonly match: { end: null; setBackfill: null; reportPlayers: null; playerPasses: null; playerBoost: null }",
28809
30071
  "documented": true,
28810
30072
  "summary": "Ending the match.\n\n`end()` is HOW A SERVER-AUTHORITATIVE GAME FINISHES. It tells the platform\nthe match is over; the platform then tells the runtime, and your server\nwinds down through its ordinary shutdown. You do not stop the process\nyourself.\n\nIt always means THIS match — the id is already known, so there is nothing to\npass and no way to end someone else's.\n\nThe platform half makes the request, not your process: it holds the proof\nthat this server is the one allocated to the match, which the platform\nrequires. On a platform image too old to offer that, `end()` throws rather\nthan sending a request without the proof.",
28811
30073
  "deprecated": null,
@@ -28897,6 +30159,80 @@
28897
30159
  "defaultValue": null,
28898
30160
  "guides": []
28899
30161
  },
30162
+ {
30163
+ "id": "GemServer.match.playerPasses",
30164
+ "name": "playerPasses",
30165
+ "anchor": "gemserver-match-playerpasses",
30166
+ "group": "api",
30167
+ "signature": "playerPasses(playerId: string, signal?: AbortSignal): Promise<readonly GamePass[]>",
30168
+ "documented": true,
30169
+ "summary": "Which game-visible passes a player in this match holds, in the shape\n`gem.me.passes.list()` gives in the browser: one entry per pass the\nplatform marked visible to games, held or not, with `held` and\n`daysLeft`.\n\n**This is what to gate on** — a VIP door, a VIP-only mode. `held` is\nexactly what a `requires: holds_pass` requirement on the same slug\ndecides. Read it when the player joins and again when you need it; it is\nnot pushed.",
30170
+ "deprecated": null,
30171
+ "params": [
30172
+ {
30173
+ "name": "playerId",
30174
+ "type": "string",
30175
+ "optional": false,
30176
+ "summary": "A player in THIS match. Anyone else is refused\n `not_found` (`player_not_in_match`) and nothing about them is read."
30177
+ },
30178
+ {
30179
+ "name": "signal",
30180
+ "type": "AbortSignal",
30181
+ "optional": true,
30182
+ "summary": "Not used — the platform half bounds its own request."
30183
+ }
30184
+ ],
30185
+ "returns": null,
30186
+ "throws": "When the platform image running this server predates the hook, or\n on a listen host (a player's browser hosting a P2P match), which holds no\n allocation proof. A `GemApiError` when the platform refuses, including\n `forbidden` (`client_permission_denied`) until the platform grants game\n servers the pass read.",
30187
+ "example": "```js\nconst vip = (await gem.match.playerPasses(playerId)).find((p) => p.pass === 'vip');\nif (vip?.held) openVipLounge(playerId);\n```",
30188
+ "defaultValue": null,
30189
+ "guides": []
30190
+ },
30191
+ {
30192
+ "id": "GemServer.match.playerBoost",
30193
+ "name": "playerBoost",
30194
+ "anchor": "gemserver-match-playerboost",
30195
+ "group": "api",
30196
+ "signature": "playerBoost(playerId: string, signal?: AbortSignal): Promise<MatchPlayerBoost>",
30197
+ "documented": true,
30198
+ "summary": "A player's Boost, **for display only** — \"2x Coins\" on a results screen.\nNever gate content, difficulty, matchmaking or power on it; gate on a pass\nwith `playerPasses`.",
30199
+ "deprecated": null,
30200
+ "params": [
30201
+ {
30202
+ "name": "playerId",
30203
+ "type": "string",
30204
+ "optional": false,
30205
+ "summary": "A player in THIS match."
30206
+ },
30207
+ {
30208
+ "name": "signal",
30209
+ "type": "AbortSignal",
30210
+ "optional": true,
30211
+ "summary": "Not used — the platform half bounds its own request."
30212
+ }
30213
+ ],
30214
+ "returns": null,
30215
+ "throws": "As `playerPasses` does.",
30216
+ "example": null,
30217
+ "defaultValue": null,
30218
+ "guides": []
30219
+ },
30220
+ {
30221
+ "id": "GemServer.earnings",
30222
+ "name": "earnings",
30223
+ "anchor": "gemserver-earnings",
30224
+ "group": "api",
30225
+ "signature": "readonly earnings: EarningsApi",
30226
+ "documented": true,
30227
+ "summary": "What a platform payout was: `earnings.fromReceipt(change)` turns a\n`platform_grant` change from a receipt into the shape the browser's payout\npreview gives — `base`, `total`, and the pass's or the Boost's part — to\nsend to the player whose screen draws it.\n\nA server has no read of the platform's currencies, so the answer carries\n`currencyId` and no `currencySlug`; the browser's `gem.earnings` fills the\nslug in.",
30228
+ "deprecated": null,
30229
+ "params": [],
30230
+ "returns": null,
30231
+ "throws": null,
30232
+ "example": null,
30233
+ "defaultValue": null,
30234
+ "guides": []
30235
+ },
28900
30236
  {
28901
30237
  "id": "GemServer.analytics",
28902
30238
  "name": "analytics",
@@ -29626,6 +30962,52 @@
29626
30962
  "defaultValue": null,
29627
30963
  "guides": []
29628
30964
  },
30965
+ {
30966
+ "id": "GemServerHost.passes",
30967
+ "name": "passes",
30968
+ "anchor": "gemserverhost-passes",
30969
+ "group": "host",
30970
+ "signature": "passes(playerId: string): Promise<GemServerHostRead>",
30971
+ "documented": true,
30972
+ "summary": "Ask the platform half which game-visible passes a player in this match\nholds: the match pass read, made with the allocation's own proof.\n\nMAY BE ABSENT on older platform images, exactly as `endMatch` may, and a\nlisten host never has it. `gem.match.playerPasses(playerId)` is this call;\nyou rarely call it yourself.\n\nResolves with what the platform answered — see [GemServerHostRead](api-reference-server.md#gemserverhostread)\n— and rejects only when the platform half could not be asked at all.",
30973
+ "deprecated": null,
30974
+ "params": [
30975
+ {
30976
+ "name": "playerId",
30977
+ "type": "string",
30978
+ "optional": false,
30979
+ "summary": null
30980
+ }
30981
+ ],
30982
+ "returns": null,
30983
+ "throws": null,
30984
+ "example": null,
30985
+ "defaultValue": null,
30986
+ "guides": []
30987
+ },
30988
+ {
30989
+ "id": "GemServerHost.boost",
30990
+ "name": "boost",
30991
+ "anchor": "gemserverhost-boost",
30992
+ "group": "host",
30993
+ "signature": "boost(playerId: string): Promise<GemServerHostRead>",
30994
+ "documented": true,
30995
+ "summary": "Ask the platform half for a player's Boost, for display: the match boost\nread, made with the allocation's own proof.\n\nMAY BE ABSENT on older platform images and on a listen host.\n`gem.match.playerBoost(playerId)` is this call; you rarely call it\nyourself. Resolves and rejects as [GemServerHost.passes](api-reference-server.md#gemserverhost-passes) does.",
30996
+ "deprecated": null,
30997
+ "params": [
30998
+ {
30999
+ "name": "playerId",
31000
+ "type": "string",
31001
+ "optional": false,
31002
+ "summary": null
31003
+ }
31004
+ ],
31005
+ "returns": null,
31006
+ "throws": null,
31007
+ "example": null,
31008
+ "defaultValue": null,
31009
+ "guides": []
31010
+ },
29629
31011
  {
29630
31012
  "id": "GemServerHost.log",
29631
31013
  "name": "log",
@@ -29672,6 +31054,38 @@
29672
31054
  "defaultValue": null,
29673
31055
  "guides": []
29674
31056
  },
31057
+ {
31058
+ "id": "GemServerHostRead.status",
31059
+ "name": "status",
31060
+ "anchor": "gemserverhostread-status",
31061
+ "group": "host",
31062
+ "signature": "readonly status: number",
31063
+ "documented": true,
31064
+ "summary": "The HTTP status the platform answered with.",
31065
+ "deprecated": null,
31066
+ "params": [],
31067
+ "returns": null,
31068
+ "throws": null,
31069
+ "example": null,
31070
+ "defaultValue": null,
31071
+ "guides": []
31072
+ },
31073
+ {
31074
+ "id": "GemServerHostRead.body",
31075
+ "name": "body",
31076
+ "anchor": "gemserverhostread-body",
31077
+ "group": "host",
31078
+ "signature": "readonly body: unknown",
31079
+ "documented": true,
31080
+ "summary": "The decoded JSON body, or `null` when there was none.",
31081
+ "deprecated": null,
31082
+ "params": [],
31083
+ "returns": null,
31084
+ "throws": null,
31085
+ "example": null,
31086
+ "defaultValue": null,
31087
+ "guides": []
31088
+ },
29675
31089
  {
29676
31090
  "id": "HostTokenSourceOptions.clock",
29677
31091
  "name": "clock",
@@ -30205,7 +31619,7 @@
30205
31619
  "name": "match",
30206
31620
  "anchor": "gemmatchserver-match",
30207
31621
  "group": "start",
30208
- "signature": "readonly match: { end: null; setBackfill: null; reportPlayers: null }",
31622
+ "signature": "readonly match: { end: null; setBackfill: null; reportPlayers: null; playerPasses: null; playerBoost: null }",
30209
31623
  "documented": true,
30210
31624
  "summary": "Ending the match.\n\n`end()` is HOW A SERVER-AUTHORITATIVE GAME FINISHES. It tells the platform\nthe match is over; the platform then tells the runtime, and your server\nwinds down through its ordinary shutdown. You do not stop the process\nyourself.\n\nIt always means THIS match — the id is already known, so there is nothing to\npass and no way to end someone else's.\n\nThe platform half makes the request, not your process: it holds the proof\nthat this server is the one allocated to the match, which the platform\nrequires. On a platform image too old to offer that, `end()` throws rather\nthan sending a request without the proof.",
30211
31625
  "deprecated": null,
@@ -30297,6 +31711,80 @@
30297
31711
  "defaultValue": null,
30298
31712
  "guides": []
30299
31713
  },
31714
+ {
31715
+ "id": "GemMatchServer.match.playerPasses",
31716
+ "name": "playerPasses",
31717
+ "anchor": "gemmatchserver-match-playerpasses",
31718
+ "group": "start",
31719
+ "signature": "playerPasses(playerId: string, signal?: AbortSignal): Promise<readonly GamePass[]>",
31720
+ "documented": true,
31721
+ "summary": "Which game-visible passes a player in this match holds, in the shape\n`gem.me.passes.list()` gives in the browser: one entry per pass the\nplatform marked visible to games, held or not, with `held` and\n`daysLeft`.\n\n**This is what to gate on** — a VIP door, a VIP-only mode. `held` is\nexactly what a `requires: holds_pass` requirement on the same slug\ndecides. Read it when the player joins and again when you need it; it is\nnot pushed.",
31722
+ "deprecated": null,
31723
+ "params": [
31724
+ {
31725
+ "name": "playerId",
31726
+ "type": "string",
31727
+ "optional": false,
31728
+ "summary": "A player in THIS match. Anyone else is refused\n `not_found` (`player_not_in_match`) and nothing about them is read."
31729
+ },
31730
+ {
31731
+ "name": "signal",
31732
+ "type": "AbortSignal",
31733
+ "optional": true,
31734
+ "summary": "Not used — the platform half bounds its own request."
31735
+ }
31736
+ ],
31737
+ "returns": null,
31738
+ "throws": "When the platform image running this server predates the hook, or\n on a listen host (a player's browser hosting a P2P match), which holds no\n allocation proof. A `GemApiError` when the platform refuses, including\n `forbidden` (`client_permission_denied`) until the platform grants game\n servers the pass read.",
31739
+ "example": "```js\nconst vip = (await gem.match.playerPasses(playerId)).find((p) => p.pass === 'vip');\nif (vip?.held) openVipLounge(playerId);\n```",
31740
+ "defaultValue": null,
31741
+ "guides": []
31742
+ },
31743
+ {
31744
+ "id": "GemMatchServer.match.playerBoost",
31745
+ "name": "playerBoost",
31746
+ "anchor": "gemmatchserver-match-playerboost",
31747
+ "group": "start",
31748
+ "signature": "playerBoost(playerId: string, signal?: AbortSignal): Promise<MatchPlayerBoost>",
31749
+ "documented": true,
31750
+ "summary": "A player's Boost, **for display only** — \"2x Coins\" on a results screen.\nNever gate content, difficulty, matchmaking or power on it; gate on a pass\nwith `playerPasses`.",
31751
+ "deprecated": null,
31752
+ "params": [
31753
+ {
31754
+ "name": "playerId",
31755
+ "type": "string",
31756
+ "optional": false,
31757
+ "summary": "A player in THIS match."
31758
+ },
31759
+ {
31760
+ "name": "signal",
31761
+ "type": "AbortSignal",
31762
+ "optional": true,
31763
+ "summary": "Not used — the platform half bounds its own request."
31764
+ }
31765
+ ],
31766
+ "returns": null,
31767
+ "throws": "As `playerPasses` does.",
31768
+ "example": null,
31769
+ "defaultValue": null,
31770
+ "guides": []
31771
+ },
31772
+ {
31773
+ "id": "GemMatchServer.earnings",
31774
+ "name": "earnings",
31775
+ "anchor": "gemmatchserver-earnings",
31776
+ "group": "start",
31777
+ "signature": "readonly earnings: EarningsApi",
31778
+ "documented": true,
31779
+ "summary": "What a platform payout was: `earnings.fromReceipt(change)` turns a\n`platform_grant` change from a receipt into the shape the browser's payout\npreview gives — `base`, `total`, and the pass's or the Boost's part — to\nsend to the player whose screen draws it.\n\nA server has no read of the platform's currencies, so the answer carries\n`currencyId` and no `currencySlug`; the browser's `gem.earnings` fills the\nslug in.",
31780
+ "deprecated": null,
31781
+ "params": [],
31782
+ "returns": null,
31783
+ "throws": null,
31784
+ "example": null,
31785
+ "defaultValue": null,
31786
+ "guides": []
31787
+ },
30300
31788
  {
30301
31789
  "id": "GemMatchServer.analytics",
30302
31790
  "name": "analytics",
@@ -32335,6 +33823,173 @@
32335
33823
  "defaultValue": null,
32336
33824
  "guides": []
32337
33825
  },
33826
+ {
33827
+ "id": "PlatformGrantSource",
33828
+ "name": "PlatformGrantSource",
33829
+ "anchor": "platformgrantsource",
33830
+ "group": "player",
33831
+ "signature": "type PlatformGrantSource = { source: \"pass\"; pass: string; amount: number } | { source: \"boost\"; amount: number }",
33832
+ "documented": true,
33833
+ "summary": "Where the part of a payout above its base comes from.",
33834
+ "deprecated": null,
33835
+ "params": [],
33836
+ "returns": null,
33837
+ "throws": null,
33838
+ "example": null,
33839
+ "defaultValue": null,
33840
+ "guides": []
33841
+ },
33842
+ {
33843
+ "id": "PlatformGrantPreview",
33844
+ "name": "PlatformGrantPreview",
33845
+ "anchor": "platformgrantpreview",
33846
+ "group": "player",
33847
+ "signature": "interface PlatformGrantPreview",
33848
+ "documented": true,
33849
+ "summary": "One platform payout — Coins, today — as the preview expects it or a receipt\nreports it, in one shape, so \"you will earn\" and \"you earned\" render with one\ncomponent.",
33850
+ "deprecated": null,
33851
+ "params": [],
33852
+ "returns": null,
33853
+ "throws": null,
33854
+ "example": null,
33855
+ "defaultValue": null,
33856
+ "guides": []
33857
+ },
33858
+ {
33859
+ "id": "PlatformGrantPreview.currencySlug",
33860
+ "name": "currencySlug",
33861
+ "anchor": "platformgrantpreview-currencyslug",
33862
+ "group": "player",
33863
+ "signature": "readonly currencySlug?: string",
33864
+ "documented": true,
33865
+ "summary": "The currency's slug, e.g. `ARCADE_TICKETS`. Absent when unknown.",
33866
+ "deprecated": null,
33867
+ "params": [],
33868
+ "returns": null,
33869
+ "throws": null,
33870
+ "example": null,
33871
+ "defaultValue": null,
33872
+ "guides": []
33873
+ },
33874
+ {
33875
+ "id": "PlatformGrantPreview.currencyId",
33876
+ "name": "currencyId",
33877
+ "anchor": "platformgrantpreview-currencyid",
33878
+ "group": "player",
33879
+ "signature": "readonly currencyId?: string",
33880
+ "documented": true,
33881
+ "summary": "The currency's id, when it is known.",
33882
+ "deprecated": null,
33883
+ "params": [],
33884
+ "returns": null,
33885
+ "throws": null,
33886
+ "example": null,
33887
+ "defaultValue": null,
33888
+ "guides": []
33889
+ },
33890
+ {
33891
+ "id": "PlatformGrantPreview.base",
33892
+ "name": "base",
33893
+ "anchor": "platformgrantpreview-base",
33894
+ "group": "player",
33895
+ "signature": "readonly base: number",
33896
+ "documented": true,
33897
+ "summary": "What a player with no pass and no Boost gets.",
33898
+ "deprecated": null,
33899
+ "params": [],
33900
+ "returns": null,
33901
+ "throws": null,
33902
+ "example": null,
33903
+ "defaultValue": null,
33904
+ "guides": []
33905
+ },
33906
+ {
33907
+ "id": "PlatformGrantPreview.total",
33908
+ "name": "total",
33909
+ "anchor": "platformgrantpreview-total",
33910
+ "group": "player",
33911
+ "signature": "readonly total: number",
33912
+ "documented": true,
33913
+ "summary": "What this player gets: `base` plus `breakdown`.",
33914
+ "deprecated": null,
33915
+ "params": [],
33916
+ "returns": null,
33917
+ "throws": null,
33918
+ "example": null,
33919
+ "defaultValue": null,
33920
+ "guides": []
33921
+ },
33922
+ {
33923
+ "id": "PlatformGrantPreview.breakdown",
33924
+ "name": "breakdown",
33925
+ "anchor": "platformgrantpreview-breakdown",
33926
+ "group": "player",
33927
+ "signature": "readonly breakdown: readonly PlatformGrantSource[]",
33928
+ "documented": true,
33929
+ "summary": "The part above `base`, and what it is from. Empty when `total` is `base`.",
33930
+ "deprecated": null,
33931
+ "params": [],
33932
+ "returns": null,
33933
+ "throws": null,
33934
+ "example": null,
33935
+ "defaultValue": null,
33936
+ "guides": []
33937
+ },
33938
+ {
33939
+ "id": "PlatformGrantPreview.ifComplete",
33940
+ "name": "ifComplete",
33941
+ "anchor": "platformgrantpreview-ifcomplete",
33942
+ "group": "player",
33943
+ "signature": "readonly ifComplete?: true",
33944
+ "documented": true,
33945
+ "summary": "`true` for an `on_complete` payout in a preview: it pays only if this\nclaim completes the progression. Absent otherwise, and on a receipt.",
33946
+ "deprecated": null,
33947
+ "params": [],
33948
+ "returns": null,
33949
+ "throws": null,
33950
+ "example": null,
33951
+ "defaultValue": null,
33952
+ "guides": []
33953
+ },
33954
+ {
33955
+ "id": "EarningsApi",
33956
+ "name": "EarningsApi",
33957
+ "anchor": "earningsapi",
33958
+ "group": "player",
33959
+ "signature": "interface EarningsApi",
33960
+ "documented": true,
33961
+ "summary": "`gem.earnings`: what a payout was, in the shape `gem.gameConfig.preview`\nsays it would be.",
33962
+ "deprecated": null,
33963
+ "params": [],
33964
+ "returns": null,
33965
+ "throws": null,
33966
+ "example": null,
33967
+ "defaultValue": null,
33968
+ "guides": []
33969
+ },
33970
+ {
33971
+ "id": "EarningsApi.fromReceipt",
33972
+ "name": "fromReceipt",
33973
+ "anchor": "earningsapi-fromreceipt",
33974
+ "group": "player",
33975
+ "signature": "fromReceipt(change: unknown): Promise<PlatformGrantPreview | null>",
33976
+ "documented": true,
33977
+ "summary": "Turn one `platform_grant` change from an order's receipt into a\n[PlatformGrantPreview](api-reference-function.md#platformgrantpreview): `base` is what a player with no pass and no\nBoost would have got under the same limits, `total` what this player got,\nand `breakdown` the pass's or the Boost's part, even when a limit trimmed\nthe payout. Draw \"you earned\" with the component that drew \"you will\nearn\". Resolves `null` for any other kind of change.\n\n**This and `preview` are the only way to show a platform payout.** Never\nmultiply by `gem.player.boost`, and never copy a config amount into your\ngame.",
33978
+ "deprecated": null,
33979
+ "params": [
33980
+ {
33981
+ "name": "change",
33982
+ "type": "unknown",
33983
+ "optional": false,
33984
+ "summary": null
33985
+ }
33986
+ ],
33987
+ "returns": "Always resolves; never rejects.",
33988
+ "throws": null,
33989
+ "example": null,
33990
+ "defaultValue": null,
33991
+ "guides": []
33992
+ },
32338
33993
  {
32339
33994
  "id": "CurrencyBalance",
32340
33995
  "name": "CurrencyBalance",
@@ -34375,70 +36030,6 @@
34375
36030
  "defaultValue": null,
34376
36031
  "guides": []
34377
36032
  },
34378
- {
34379
- "id": "GamePass",
34380
- "name": "GamePass",
34381
- "anchor": "gamepass",
34382
- "group": "player",
34383
- "signature": "interface GamePass",
34384
- "documented": true,
34385
- "summary": "One pass games may see, and whether this player holds it. Listed whether they\nhold it or not, and this is everything a game learns about it.",
34386
- "deprecated": null,
34387
- "params": [],
34388
- "returns": null,
34389
- "throws": null,
34390
- "example": null,
34391
- "defaultValue": null,
34392
- "guides": []
34393
- },
34394
- {
34395
- "id": "GamePass.pass",
34396
- "name": "pass",
34397
- "anchor": "gamepass-pass",
34398
- "group": "player",
34399
- "signature": "readonly pass: string",
34400
- "documented": true,
34401
- "summary": "The pass's offering slug, such as `vip`. Stable and not localized: key on this.",
34402
- "deprecated": null,
34403
- "params": [],
34404
- "returns": null,
34405
- "throws": null,
34406
- "example": null,
34407
- "defaultValue": null,
34408
- "guides": []
34409
- },
34410
- {
34411
- "id": "GamePass.held",
34412
- "name": "held",
34413
- "anchor": "gamepass-held",
34414
- "group": "player",
34415
- "signature": "readonly held: boolean",
34416
- "documented": true,
34417
- "summary": "Whether the player holds it right now.",
34418
- "deprecated": null,
34419
- "params": [],
34420
- "returns": null,
34421
- "throws": null,
34422
- "example": null,
34423
- "defaultValue": null,
34424
- "guides": []
34425
- },
34426
- {
34427
- "id": "GamePass.endsAt",
34428
- "name": "endsAt",
34429
- "anchor": "gamepass-endsat",
34430
- "group": "player",
34431
- "signature": "readonly endsAt: string | null",
34432
- "documented": true,
34433
- "summary": "When the player stops holding it, RFC 3339 in UTC, grace and any queued\nperiod included. `null` when it is not held, and when it is held with no\nend, so read [GamePass.held](api-reference-function.md#gamepass-held) first: `null` alone never means ended.",
34434
- "deprecated": null,
34435
- "params": [],
34436
- "returns": null,
34437
- "throws": null,
34438
- "example": null,
34439
- "defaultValue": null,
34440
- "guides": []
34441
- },
34442
36033
  {
34443
36034
  "id": "PassesEvent",
34444
36035
  "name": "PassesEvent",
@@ -38603,6 +40194,86 @@
38603
40194
  "defaultValue": null,
38604
40195
  "guides": []
38605
40196
  },
40197
+ {
40198
+ "id": "GamePass",
40199
+ "name": "GamePass",
40200
+ "anchor": "gamepass",
40201
+ "group": "player",
40202
+ "signature": "interface GamePass",
40203
+ "documented": true,
40204
+ "summary": "One pass games may see, and whether this player holds it. Listed whether they\nhold it or not, and this is everything a game learns about it.",
40205
+ "deprecated": null,
40206
+ "params": [],
40207
+ "returns": null,
40208
+ "throws": null,
40209
+ "example": null,
40210
+ "defaultValue": null,
40211
+ "guides": []
40212
+ },
40213
+ {
40214
+ "id": "GamePass.pass",
40215
+ "name": "pass",
40216
+ "anchor": "gamepass-pass",
40217
+ "group": "player",
40218
+ "signature": "readonly pass: string",
40219
+ "documented": true,
40220
+ "summary": "The pass's offering slug, such as `vip`. Stable and not localized: key on this.",
40221
+ "deprecated": null,
40222
+ "params": [],
40223
+ "returns": null,
40224
+ "throws": null,
40225
+ "example": null,
40226
+ "defaultValue": null,
40227
+ "guides": []
40228
+ },
40229
+ {
40230
+ "id": "GamePass.held",
40231
+ "name": "held",
40232
+ "anchor": "gamepass-held",
40233
+ "group": "player",
40234
+ "signature": "readonly held: boolean",
40235
+ "documented": true,
40236
+ "summary": "Whether the player holds it right now.",
40237
+ "deprecated": null,
40238
+ "params": [],
40239
+ "returns": null,
40240
+ "throws": null,
40241
+ "example": null,
40242
+ "defaultValue": null,
40243
+ "guides": []
40244
+ },
40245
+ {
40246
+ "id": "GamePass.daysLeft",
40247
+ "name": "daysLeft",
40248
+ "anchor": "gamepass-daysleft",
40249
+ "group": "player",
40250
+ "signature": "readonly daysLeft: number",
40251
+ "documented": true,
40252
+ "summary": "Whole days the player keeps it, rounded up so a pass with any time left\nreads at least `1`, and **capped at 7**: `7` means \"7 or more\", and is\nalso what a pass held with no end reads. `0` when it is not held. Show\n`7` as \"7+ days left\", never as an exact end.",
40253
+ "deprecated": null,
40254
+ "params": [],
40255
+ "returns": null,
40256
+ "throws": null,
40257
+ "example": null,
40258
+ "defaultValue": null,
40259
+ "guides": []
40260
+ },
40261
+ {
40262
+ "id": "GamePass.endsAt",
40263
+ "name": "endsAt",
40264
+ "anchor": "gamepass-endsat",
40265
+ "group": "player",
40266
+ "signature": "readonly endsAt: string | null",
40267
+ "documented": true,
40268
+ "summary": "When the player stops holding it, RFC 3339 in UTC, grace and any queued\nperiod included. `null` when it is not held, and when it is held with no\nend, so read [GamePass.held](api-reference-function.md#gamepass-held) first: `null` alone never means ended.",
40269
+ "deprecated": "Use [GamePass.daysLeft](api-reference-function.md#gamepass-daysleft). An exact instant is a value two\ngames could match to link one player's identities, so the platform will\nstop sending it; it reads `null` then. See\n[the deprecation policy](../deprecation-policy.md).",
40270
+ "params": [],
40271
+ "returns": null,
40272
+ "throws": null,
40273
+ "example": null,
40274
+ "defaultValue": null,
40275
+ "guides": []
40276
+ },
38606
40277
  {
38607
40278
  "id": "PlatformCurrencyAccess",
38608
40279
  "name": "PlatformCurrencyAccess",
@@ -40640,6 +42311,22 @@
40640
42311
  "defaultValue": null,
40641
42312
  "guides": []
40642
42313
  },
42314
+ {
42315
+ "id": "GemFunction.earnings",
42316
+ "name": "earnings",
42317
+ "anchor": "gemfunction-earnings",
42318
+ "group": "start",
42319
+ "signature": "readonly earnings: EarningsApi",
42320
+ "documented": true,
42321
+ "summary": "What a platform payout was: `earnings.fromReceipt(change)` turns a\n`platform_grant` change from a receipt into the shape the browser's payout\npreview gives — `base`, `total`, and the pass's or the Boost's part — to\nreturn to the game that draws it.",
42322
+ "deprecated": null,
42323
+ "params": [],
42324
+ "returns": null,
42325
+ "throws": null,
42326
+ "example": null,
42327
+ "defaultValue": null,
42328
+ "guides": []
42329
+ },
40643
42330
  {
40644
42331
  "id": "GemFunction.profiles",
40645
42332
  "name": "profiles",