@indiegems/gem-web-sdk 15.3.2 → 16.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.
- package/CHANGELOG.md +26 -0
- package/dist/conformance.d.ts +7 -1
- package/dist/game.d.ts +187 -1
- package/dist/gem-web-sdk.bridge.js +2 -2
- package/dist/gem-web-sdk.conformance.js +3 -3
- package/dist/gem-web-sdk.esm.js +3 -3
- package/dist/gem-web-sdk.function.js +3 -3
- package/dist/gem-web-sdk.game.js +3 -3
- package/dist/gem-web-sdk.min.js +3 -3
- package/dist/gem-web-sdk.sdk.js +3 -3
- package/dist/gem-web-sdk.server.js +2 -2
- package/dist/index.d.ts +171 -7
- package/dist/sdk.d.ts +187 -1
- package/docs/api/api-reference-function.md +1 -1
- package/docs/api/api-reference-game.md +762 -3
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +1203 -190
- package/docs/arcade-and-store.md +289 -0
- package/docs/arcade-economy.md +13 -9
- package/docs/changelog.md +26 -0
- package/docs/getting-started.md +5 -3
- package/docs/inventory-and-catalogs.md +8 -4
- package/docs/manifest.json +17 -12
- package/docs/player-text-fields.json +45 -4
- package/docs/server-bundles.md +2 -2
- package/docs/what-a-game-must-do.md +36 -3
- package/package.json +1 -1
- package/schema/bridge.v1.json +735 -5
- package/schema/capabilities.public.json +28 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The browser surface — API reference
|
|
2
2
|
|
|
3
|
-
Generated from `@indiegems/gem-web-sdk/sdk`
|
|
3
|
+
Generated from `@indiegems/gem-web-sdk/sdk` v16.0.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
|
|
4
4
|
|
|
5
5
|
`@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/game` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
|
|
6
6
|
|
|
@@ -3787,6 +3787,725 @@ key.
|
|
|
3787
3787
|
**Throws.** TypeError for an empty key or player id, or a list holding something
|
|
3788
3788
|
other than strings; RangeError for a count or list size outside 1 to 2048.
|
|
3789
3789
|
|
|
3790
|
+
<a id="appstore"></a>
|
|
3791
|
+
|
|
3792
|
+
## AppStore
|
|
3793
|
+
|
|
3794
|
+
```ts
|
|
3795
|
+
type AppStore = "app_store" | "google_play"
|
|
3796
|
+
```
|
|
3797
|
+
|
|
3798
|
+
Which app store a listing is in, so a game can draw the matching badge.
|
|
3799
|
+
|
|
3800
|
+
<a id="applisting"></a>
|
|
3801
|
+
|
|
3802
|
+
## AppListing
|
|
3803
|
+
|
|
3804
|
+
```ts
|
|
3805
|
+
interface AppListing
|
|
3806
|
+
```
|
|
3807
|
+
|
|
3808
|
+
A store listing the arcade can open from here.
|
|
3809
|
+
|
|
3810
|
+
<a id="applisting-store"></a>
|
|
3811
|
+
|
|
3812
|
+
## AppListing.store
|
|
3813
|
+
|
|
3814
|
+
```ts
|
|
3815
|
+
readonly store: AppStore
|
|
3816
|
+
```
|
|
3817
|
+
|
|
3818
|
+
Which store it is in. Never a URL: the arcade builds the link.
|
|
3819
|
+
|
|
3820
|
+
<a id="applinksoutcome"></a>
|
|
3821
|
+
|
|
3822
|
+
## AppLinksOutcome
|
|
3823
|
+
|
|
3824
|
+
```ts
|
|
3825
|
+
interface AppLinksOutcome
|
|
3826
|
+
```
|
|
3827
|
+
|
|
3828
|
+
What [ArcadeApi.appLinks](#arcadeapi-applinks) resolves with. `arcade` and `game` are each
|
|
3829
|
+
present only when [ArcadeApi.openApp](#arcadeapi-openapp) with that target would open a
|
|
3830
|
+
listing here; show the matching button only then.
|
|
3831
|
+
|
|
3832
|
+
<a id="applinksoutcome-arcade"></a>
|
|
3833
|
+
|
|
3834
|
+
## AppLinksOutcome.arcade
|
|
3835
|
+
|
|
3836
|
+
```ts
|
|
3837
|
+
readonly arcade?: AppListing
|
|
3838
|
+
```
|
|
3839
|
+
|
|
3840
|
+
The Gem Arcade app's listing. Absent inside the Gem Arcade app itself.
|
|
3841
|
+
|
|
3842
|
+
<a id="applinksoutcome-game"></a>
|
|
3843
|
+
|
|
3844
|
+
## AppLinksOutcome.game
|
|
3845
|
+
|
|
3846
|
+
```ts
|
|
3847
|
+
readonly game?: AppListing
|
|
3848
|
+
```
|
|
3849
|
+
|
|
3850
|
+
This game's own app's listing, when it has one for this platform.
|
|
3851
|
+
|
|
3852
|
+
<a id="applinksoutcome-outcome"></a>
|
|
3853
|
+
|
|
3854
|
+
## AppLinksOutcome.outcome
|
|
3855
|
+
|
|
3856
|
+
```ts
|
|
3857
|
+
readonly outcome: ArcadeOutcomeKind
|
|
3858
|
+
```
|
|
3859
|
+
|
|
3860
|
+
What happened: `ok`, `declined` or `unavailable`. Branch on this.
|
|
3861
|
+
|
|
3862
|
+
<a id="applinksoutcome-reason"></a>
|
|
3863
|
+
|
|
3864
|
+
## AppLinksOutcome.reason
|
|
3865
|
+
|
|
3866
|
+
```ts
|
|
3867
|
+
readonly reason?: string
|
|
3868
|
+
```
|
|
3869
|
+
|
|
3870
|
+
Why, as a machine code — `busy`, `cancelled`, `not_found`, `pending`,
|
|
3871
|
+
`store_off`, `sign_in_required` and more. OPEN-ENDED: the arcade may send a
|
|
3872
|
+
code this SDK has never heard of, so keep a `default` arm and never show a
|
|
3873
|
+
code to a player. Absent when there is nothing to add.
|
|
3874
|
+
|
|
3875
|
+
Three are the SDK's own, answered without asking the arcade:
|
|
3876
|
+
`unsupported` (the arcade here does not offer this), `invalid_argument`
|
|
3877
|
+
(the SDK refused what you passed) and `busy` (another ask of the same kind
|
|
3878
|
+
is still open). `error` means no reliable answer arrived — the ask never
|
|
3879
|
+
left, the wait ran out, the bridge closed or the arcade had none. For
|
|
3880
|
+
`gem.store.purchase` that makes the outcome UNKNOWN, not a refusal: the
|
|
3881
|
+
player may have paid.
|
|
3882
|
+
|
|
3883
|
+
<a id="gamecard"></a>
|
|
3884
|
+
|
|
3885
|
+
## GameCard
|
|
3886
|
+
|
|
3887
|
+
```ts
|
|
3888
|
+
interface GameCard
|
|
3889
|
+
```
|
|
3890
|
+
|
|
3891
|
+
One game, as an Arcade home tile shows it.
|
|
3892
|
+
|
|
3893
|
+
⚠️ `name`, `tagline`, `shortDescription` and `tags` are **another
|
|
3894
|
+
developer's text**, so they arrive as [PlayerText](#playertext): convert with
|
|
3895
|
+
`text.toPlain()` and render them as text, never as markup. The media URLs are
|
|
3896
|
+
the platform's; your page's CSP must allow its media host for `img-src` and
|
|
3897
|
+
`media-src` (see `docs/arcade-and-store.md`).
|
|
3898
|
+
|
|
3899
|
+
<a id="gamecard-gameid"></a>
|
|
3900
|
+
|
|
3901
|
+
## GameCard.gameId
|
|
3902
|
+
|
|
3903
|
+
```ts
|
|
3904
|
+
readonly gameId: string
|
|
3905
|
+
```
|
|
3906
|
+
|
|
3907
|
+
The game's id: what [ArcadeApi.openGame](#arcadeapi-opengame) takes.
|
|
3908
|
+
|
|
3909
|
+
<a id="gamecard-slug"></a>
|
|
3910
|
+
|
|
3911
|
+
## GameCard.slug
|
|
3912
|
+
|
|
3913
|
+
```ts
|
|
3914
|
+
readonly slug?: string
|
|
3915
|
+
```
|
|
3916
|
+
|
|
3917
|
+
The game's web address, when it has one.
|
|
3918
|
+
|
|
3919
|
+
<a id="gamecard-name"></a>
|
|
3920
|
+
|
|
3921
|
+
## GameCard.name
|
|
3922
|
+
|
|
3923
|
+
```ts
|
|
3924
|
+
readonly name: PlayerText
|
|
3925
|
+
```
|
|
3926
|
+
|
|
3927
|
+
The game's public name. Another developer's text.
|
|
3928
|
+
|
|
3929
|
+
<a id="gamecard-tagline"></a>
|
|
3930
|
+
|
|
3931
|
+
## GameCard.tagline
|
|
3932
|
+
|
|
3933
|
+
```ts
|
|
3934
|
+
readonly tagline: PlayerText
|
|
3935
|
+
```
|
|
3936
|
+
|
|
3937
|
+
One line under the name. Another developer's text; may be empty.
|
|
3938
|
+
|
|
3939
|
+
<a id="gamecard-shortdescription"></a>
|
|
3940
|
+
|
|
3941
|
+
## GameCard.shortDescription
|
|
3942
|
+
|
|
3943
|
+
```ts
|
|
3944
|
+
readonly shortDescription: PlayerText
|
|
3945
|
+
```
|
|
3946
|
+
|
|
3947
|
+
A sentence or two. Another developer's text; may be empty.
|
|
3948
|
+
|
|
3949
|
+
<a id="gamecard-tags"></a>
|
|
3950
|
+
|
|
3951
|
+
## GameCard.tags
|
|
3952
|
+
|
|
3953
|
+
```ts
|
|
3954
|
+
readonly tags: readonly PlayerText[]
|
|
3955
|
+
```
|
|
3956
|
+
|
|
3957
|
+
The game's store tags. Another developer's text.
|
|
3958
|
+
|
|
3959
|
+
<a id="gamecard-iconurl"></a>
|
|
3960
|
+
|
|
3961
|
+
## GameCard.iconUrl
|
|
3962
|
+
|
|
3963
|
+
```ts
|
|
3964
|
+
readonly iconUrl: string
|
|
3965
|
+
```
|
|
3966
|
+
|
|
3967
|
+
The game's icon.
|
|
3968
|
+
|
|
3969
|
+
<a id="gamecard-capsulelandscapeurl"></a>
|
|
3970
|
+
|
|
3971
|
+
## GameCard.capsuleLandscapeUrl
|
|
3972
|
+
|
|
3973
|
+
```ts
|
|
3974
|
+
readonly capsuleLandscapeUrl: string
|
|
3975
|
+
```
|
|
3976
|
+
|
|
3977
|
+
The landscape tile art.
|
|
3978
|
+
|
|
3979
|
+
<a id="gamecard-capsuleportraiturl"></a>
|
|
3980
|
+
|
|
3981
|
+
## GameCard.capsulePortraitUrl
|
|
3982
|
+
|
|
3983
|
+
```ts
|
|
3984
|
+
readonly capsulePortraitUrl: string
|
|
3985
|
+
```
|
|
3986
|
+
|
|
3987
|
+
The portrait tile art.
|
|
3988
|
+
|
|
3989
|
+
<a id="gamecard-previewvideourl"></a>
|
|
3990
|
+
|
|
3991
|
+
## GameCard.previewVideoUrl
|
|
3992
|
+
|
|
3993
|
+
```ts
|
|
3994
|
+
readonly previewVideoUrl?: string
|
|
3995
|
+
```
|
|
3996
|
+
|
|
3997
|
+
The tile's hover clip. Absent when the game has none, and whenever the
|
|
3998
|
+
arcade judges a clip unwelcome: reduced motion, data saver, a phone.
|
|
3999
|
+
|
|
4000
|
+
<a id="gamecard-previewposterurl"></a>
|
|
4001
|
+
|
|
4002
|
+
## GameCard.previewPosterUrl
|
|
4003
|
+
|
|
4004
|
+
```ts
|
|
4005
|
+
readonly previewPosterUrl?: string
|
|
4006
|
+
```
|
|
4007
|
+
|
|
4008
|
+
The still shown before, and instead of, the clip.
|
|
4009
|
+
|
|
4010
|
+
<a id="similargamesoutcome"></a>
|
|
4011
|
+
|
|
4012
|
+
## SimilarGamesOutcome
|
|
4013
|
+
|
|
4014
|
+
```ts
|
|
4015
|
+
interface SimilarGamesOutcome
|
|
4016
|
+
```
|
|
4017
|
+
|
|
4018
|
+
What [ArcadeApi.similarGames](#arcadeapi-similargames) resolves with.
|
|
4019
|
+
|
|
4020
|
+
<a id="similargamesoutcome-games"></a>
|
|
4021
|
+
|
|
4022
|
+
## SimilarGamesOutcome.games
|
|
4023
|
+
|
|
4024
|
+
```ts
|
|
4025
|
+
readonly games: readonly GameCard[]
|
|
4026
|
+
```
|
|
4027
|
+
|
|
4028
|
+
Up to `limit` games, best first. Empty unless `ok` — and an `ok` may be empty too.
|
|
4029
|
+
|
|
4030
|
+
<a id="similargamesoutcome-outcome"></a>
|
|
4031
|
+
|
|
4032
|
+
## SimilarGamesOutcome.outcome
|
|
4033
|
+
|
|
4034
|
+
```ts
|
|
4035
|
+
readonly outcome: ArcadeOutcomeKind
|
|
4036
|
+
```
|
|
4037
|
+
|
|
4038
|
+
What happened: `ok`, `declined` or `unavailable`. Branch on this.
|
|
4039
|
+
|
|
4040
|
+
<a id="similargamesoutcome-reason"></a>
|
|
4041
|
+
|
|
4042
|
+
## SimilarGamesOutcome.reason
|
|
4043
|
+
|
|
4044
|
+
```ts
|
|
4045
|
+
readonly reason?: string
|
|
4046
|
+
```
|
|
4047
|
+
|
|
4048
|
+
Why, as a machine code — `busy`, `cancelled`, `not_found`, `pending`,
|
|
4049
|
+
`store_off`, `sign_in_required` and more. OPEN-ENDED: the arcade may send a
|
|
4050
|
+
code this SDK has never heard of, so keep a `default` arm and never show a
|
|
4051
|
+
code to a player. Absent when there is nothing to add.
|
|
4052
|
+
|
|
4053
|
+
Three are the SDK's own, answered without asking the arcade:
|
|
4054
|
+
`unsupported` (the arcade here does not offer this), `invalid_argument`
|
|
4055
|
+
(the SDK refused what you passed) and `busy` (another ask of the same kind
|
|
4056
|
+
is still open). `error` means no reliable answer arrived — the ask never
|
|
4057
|
+
left, the wait ran out, the bridge closed or the arcade had none. For
|
|
4058
|
+
`gem.store.purchase` that makes the outcome UNKNOWN, not a refusal: the
|
|
4059
|
+
player may have paid.
|
|
4060
|
+
|
|
4061
|
+
<a id="arcadeavailability"></a>
|
|
4062
|
+
|
|
4063
|
+
## ArcadeAvailability
|
|
4064
|
+
|
|
4065
|
+
```ts
|
|
4066
|
+
interface ArcadeAvailability
|
|
4067
|
+
```
|
|
4068
|
+
|
|
4069
|
+
Which arcade features answer here, read synchronously. Decide from these
|
|
4070
|
+
whether to draw a "Get the app" button or a "More games" section at all.
|
|
4071
|
+
|
|
4072
|
+
<a id="arcadeavailability-applinks"></a>
|
|
4073
|
+
|
|
4074
|
+
## ArcadeAvailability.appLinks
|
|
4075
|
+
|
|
4076
|
+
```ts
|
|
4077
|
+
readonly appLinks: boolean
|
|
4078
|
+
```
|
|
4079
|
+
|
|
4080
|
+
[ArcadeApi.appLinks](#arcadeapi-applinks) and [ArcadeApi.openApp](#arcadeapi-openapp) reach the arcade.
|
|
4081
|
+
|
|
4082
|
+
<a id="arcadeavailability-opengame"></a>
|
|
4083
|
+
|
|
4084
|
+
## ArcadeAvailability.openGame
|
|
4085
|
+
|
|
4086
|
+
```ts
|
|
4087
|
+
readonly openGame: boolean
|
|
4088
|
+
```
|
|
4089
|
+
|
|
4090
|
+
[ArcadeApi.openGame](#arcadeapi-opengame) and [ArcadeApi.similarGames](#arcadeapi-similargames) reach the arcade.
|
|
4091
|
+
|
|
4092
|
+
<a id="arcadeapi"></a>
|
|
4093
|
+
|
|
4094
|
+
## ArcadeApi
|
|
4095
|
+
|
|
4096
|
+
```ts
|
|
4097
|
+
interface ArcadeApi
|
|
4098
|
+
```
|
|
4099
|
+
|
|
4100
|
+
The arcade-features surface. `gem.arcade` is one of these.
|
|
4101
|
+
|
|
4102
|
+
<a id="arcadeapi-available"></a>
|
|
4103
|
+
|
|
4104
|
+
## ArcadeApi.available
|
|
4105
|
+
|
|
4106
|
+
```ts
|
|
4107
|
+
readonly available: ArcadeAvailability
|
|
4108
|
+
```
|
|
4109
|
+
|
|
4110
|
+
Which of these features the arcade answers here, synchronously. False
|
|
4111
|
+
before the bridge is up and wherever the arcade does not offer one — the
|
|
4112
|
+
single-game app, for instance, opens no other game.
|
|
4113
|
+
|
|
4114
|
+
<a id="arcadeapi-applinks"></a>
|
|
4115
|
+
|
|
4116
|
+
## ArcadeApi.appLinks
|
|
4117
|
+
|
|
4118
|
+
```ts
|
|
4119
|
+
appLinks(): Promise<AppLinksOutcome>
|
|
4120
|
+
```
|
|
4121
|
+
|
|
4122
|
+
Which app-store listings the arcade can open from here: the Gem Arcade
|
|
4123
|
+
app's and this game's own. A read: call it whenever, and show a button
|
|
4124
|
+
for each listing present.
|
|
4125
|
+
|
|
4126
|
+
**Returns.** Always resolves; never rejects.
|
|
4127
|
+
|
|
4128
|
+
<a id="arcadeapi-openapp"></a>
|
|
4129
|
+
|
|
4130
|
+
## ArcadeApi.openApp
|
|
4131
|
+
|
|
4132
|
+
```ts
|
|
4133
|
+
openApp(target: "arcade" | "game"): Promise<ArcadeOutcome>
|
|
4134
|
+
```
|
|
4135
|
+
|
|
4136
|
+
Open a store listing: the Gem Arcade app's (`'arcade'`) or this game's own
|
|
4137
|
+
(`'game'`). **Call it from the player's press handler** — the arcade
|
|
4138
|
+
refuses an ask no person pressed for, `declined` / `busy`.
|
|
4139
|
+
|
|
4140
|
+
`ok` means it opened, in a new tab or the store app, or (`reason:
|
|
4141
|
+
'handed_off'`) the arcade put up its own QR sheet. The answer comes at
|
|
4142
|
+
that moment, not when the player closes the sheet, so carry on either
|
|
4143
|
+
way; while the sheet is up, another acting call is `declined` / `busy`.
|
|
4144
|
+
|
|
4145
|
+
| Parameter | Type |
|
|
4146
|
+
| --- | --- |
|
|
4147
|
+
| `target` | `"arcade" \| "game"` |
|
|
4148
|
+
|
|
4149
|
+
**Returns.** Always resolves; never rejects.
|
|
4150
|
+
|
|
4151
|
+
<a id="arcadeapi-opengame"></a>
|
|
4152
|
+
|
|
4153
|
+
## ArcadeApi.openGame
|
|
4154
|
+
|
|
4155
|
+
```ts
|
|
4156
|
+
openGame(ref: string): Promise<ArcadeOutcome>
|
|
4157
|
+
```
|
|
4158
|
+
|
|
4159
|
+
Open another game in place of this one, by id or web address. **Call it
|
|
4160
|
+
from the player's press handler.**
|
|
4161
|
+
|
|
4162
|
+
⚠️ On `ok` your game is about to be closed: `onWillTerminate` follows with
|
|
4163
|
+
the ordinary save grace (250 ms). Save before you call this, not after.
|
|
4164
|
+
`declined` / `same_game` names this game; `unavailable` / `not_found` is a
|
|
4165
|
+
game the player cannot open here.
|
|
4166
|
+
|
|
4167
|
+
| Parameter | Type |
|
|
4168
|
+
| --- | --- |
|
|
4169
|
+
| `ref` | `string` |
|
|
4170
|
+
|
|
4171
|
+
**Returns.** Always resolves; never rejects.
|
|
4172
|
+
|
|
4173
|
+
<a id="arcadeapi-similargames"></a>
|
|
4174
|
+
|
|
4175
|
+
## ArcadeApi.similarGames
|
|
4176
|
+
|
|
4177
|
+
```ts
|
|
4178
|
+
similarGames(options?: { limit?: number }): Promise<SimilarGamesOutcome>
|
|
4179
|
+
```
|
|
4180
|
+
|
|
4181
|
+
Games like this one, as Arcade home tiles: up to `limit` (1 to 24, default
|
|
4182
|
+
12), best first. Hide the section when `games` is empty.
|
|
4183
|
+
|
|
4184
|
+
| Parameter | Type |
|
|
4185
|
+
| --- | --- |
|
|
4186
|
+
| `options` | `{ limit?: number }` |
|
|
4187
|
+
|
|
4188
|
+
**Returns.** Always resolves; never rejects.
|
|
4189
|
+
|
|
4190
|
+
<a id="arcadeoutcomekind"></a>
|
|
4191
|
+
|
|
4192
|
+
## ArcadeOutcomeKind
|
|
4193
|
+
|
|
4194
|
+
```ts
|
|
4195
|
+
type ArcadeOutcomeKind = "ok" | "declined" | "unavailable"
|
|
4196
|
+
```
|
|
4197
|
+
|
|
4198
|
+
What the arcade did with an ask, the complete vocabulary: `ok`, `declined`
|
|
4199
|
+
or `unavailable`. Why is in `reason`, which is open-ended.
|
|
4200
|
+
|
|
4201
|
+
<a id="arcadeoutcome"></a>
|
|
4202
|
+
|
|
4203
|
+
## ArcadeOutcome
|
|
4204
|
+
|
|
4205
|
+
```ts
|
|
4206
|
+
interface ArcadeOutcome
|
|
4207
|
+
```
|
|
4208
|
+
|
|
4209
|
+
The answer every `gem.arcade` and `gem.store` call resolves with, before
|
|
4210
|
+
anything specific to the call.
|
|
4211
|
+
|
|
4212
|
+
<a id="arcadeoutcome-outcome"></a>
|
|
4213
|
+
|
|
4214
|
+
## ArcadeOutcome.outcome
|
|
4215
|
+
|
|
4216
|
+
```ts
|
|
4217
|
+
readonly outcome: ArcadeOutcomeKind
|
|
4218
|
+
```
|
|
4219
|
+
|
|
4220
|
+
What happened: `ok`, `declined` or `unavailable`. Branch on this.
|
|
4221
|
+
|
|
4222
|
+
<a id="arcadeoutcome-reason"></a>
|
|
4223
|
+
|
|
4224
|
+
## ArcadeOutcome.reason
|
|
4225
|
+
|
|
4226
|
+
```ts
|
|
4227
|
+
readonly reason?: string
|
|
4228
|
+
```
|
|
4229
|
+
|
|
4230
|
+
Why, as a machine code — `busy`, `cancelled`, `not_found`, `pending`,
|
|
4231
|
+
`store_off`, `sign_in_required` and more. OPEN-ENDED: the arcade may send a
|
|
4232
|
+
code this SDK has never heard of, so keep a `default` arm and never show a
|
|
4233
|
+
code to a player. Absent when there is nothing to add.
|
|
4234
|
+
|
|
4235
|
+
Three are the SDK's own, answered without asking the arcade:
|
|
4236
|
+
`unsupported` (the arcade here does not offer this), `invalid_argument`
|
|
4237
|
+
(the SDK refused what you passed) and `busy` (another ask of the same kind
|
|
4238
|
+
is still open). `error` means no reliable answer arrived — the ask never
|
|
4239
|
+
left, the wait ran out, the bridge closed or the arcade had none. For
|
|
4240
|
+
`gem.store.purchase` that makes the outcome UNKNOWN, not a refusal: the
|
|
4241
|
+
player may have paid.
|
|
4242
|
+
|
|
4243
|
+
<a id="arcadeoffer"></a>
|
|
4244
|
+
|
|
4245
|
+
## ArcadeOffer
|
|
4246
|
+
|
|
4247
|
+
```ts
|
|
4248
|
+
interface ArcadeOffer
|
|
4249
|
+
```
|
|
4250
|
+
|
|
4251
|
+
One SKU the Arcade Store sells to this player, here, right now.
|
|
4252
|
+
|
|
4253
|
+
Show `priceDisplay` **exactly as given**: it is the payment rail's own
|
|
4254
|
+
formatted price in the player's currency. Never parse it, compare it or
|
|
4255
|
+
compute a discount from it. There is no numeric price, no balance and no
|
|
4256
|
+
availability flag — the arcade's sheet explains anything that stops a
|
|
4257
|
+
purchase.
|
|
4258
|
+
|
|
4259
|
+
<a id="arcadeoffer-skuid"></a>
|
|
4260
|
+
|
|
4261
|
+
## ArcadeOffer.skuId
|
|
4262
|
+
|
|
4263
|
+
```ts
|
|
4264
|
+
readonly skuId: string
|
|
4265
|
+
```
|
|
4266
|
+
|
|
4267
|
+
The SKU's id: what [StoreApi.purchase](#storeapi-purchase) takes.
|
|
4268
|
+
|
|
4269
|
+
<a id="arcadeoffer-kind"></a>
|
|
4270
|
+
|
|
4271
|
+
## ArcadeOffer.kind
|
|
4272
|
+
|
|
4273
|
+
```ts
|
|
4274
|
+
readonly kind: "gem_pack" | "boost" | "pass" | "bundle"
|
|
4275
|
+
```
|
|
4276
|
+
|
|
4277
|
+
What sort of thing it is.
|
|
4278
|
+
|
|
4279
|
+
<a id="arcadeoffer-name"></a>
|
|
4280
|
+
|
|
4281
|
+
## ArcadeOffer.name
|
|
4282
|
+
|
|
4283
|
+
```ts
|
|
4284
|
+
readonly name: string
|
|
4285
|
+
```
|
|
4286
|
+
|
|
4287
|
+
The store's own name for it, localized as the store shows it.
|
|
4288
|
+
|
|
4289
|
+
<a id="arcadeoffer-description"></a>
|
|
4290
|
+
|
|
4291
|
+
## ArcadeOffer.description
|
|
4292
|
+
|
|
4293
|
+
```ts
|
|
4294
|
+
readonly description: string
|
|
4295
|
+
```
|
|
4296
|
+
|
|
4297
|
+
What the player gets, in the store's words. May be empty.
|
|
4298
|
+
|
|
4299
|
+
<a id="arcadeoffer-imageurl"></a>
|
|
4300
|
+
|
|
4301
|
+
## ArcadeOffer.imageUrl
|
|
4302
|
+
|
|
4303
|
+
```ts
|
|
4304
|
+
readonly imageUrl?: string
|
|
4305
|
+
```
|
|
4306
|
+
|
|
4307
|
+
The SKU's art, when it has any.
|
|
4308
|
+
|
|
4309
|
+
<a id="arcadeoffer-pricedisplay"></a>
|
|
4310
|
+
|
|
4311
|
+
## ArcadeOffer.priceDisplay
|
|
4312
|
+
|
|
4313
|
+
```ts
|
|
4314
|
+
readonly priceDisplay: string
|
|
4315
|
+
```
|
|
4316
|
+
|
|
4317
|
+
The price, formatted by the payment rail. Show it as given.
|
|
4318
|
+
|
|
4319
|
+
<a id="arcadeoffer-grant"></a>
|
|
4320
|
+
|
|
4321
|
+
## ArcadeOffer.grant
|
|
4322
|
+
|
|
4323
|
+
```ts
|
|
4324
|
+
readonly grant?: { currency: string; amount: number }
|
|
4325
|
+
```
|
|
4326
|
+
|
|
4327
|
+
For a Gem pack: the platform currency and the amount it grants.
|
|
4328
|
+
|
|
4329
|
+
<a id="arcadeoffer-grant-currency"></a>
|
|
4330
|
+
|
|
4331
|
+
## ArcadeOffer.grant.currency
|
|
4332
|
+
|
|
4333
|
+
```ts
|
|
4334
|
+
readonly currency: string
|
|
4335
|
+
```
|
|
4336
|
+
|
|
4337
|
+
The platform currency's exact slug, e.g. `GEMS`.
|
|
4338
|
+
|
|
4339
|
+
<a id="arcadeoffer-grant-amount"></a>
|
|
4340
|
+
|
|
4341
|
+
## ArcadeOffer.grant.amount
|
|
4342
|
+
|
|
4343
|
+
```ts
|
|
4344
|
+
readonly amount: number
|
|
4345
|
+
```
|
|
4346
|
+
|
|
4347
|
+
How much of it the pack grants.
|
|
4348
|
+
|
|
4349
|
+
<a id="storeoffersoutcome"></a>
|
|
4350
|
+
|
|
4351
|
+
## StoreOffersOutcome
|
|
4352
|
+
|
|
4353
|
+
```ts
|
|
4354
|
+
interface StoreOffersOutcome
|
|
4355
|
+
```
|
|
4356
|
+
|
|
4357
|
+
What [StoreApi.offers](#storeapi-offers) resolves with.
|
|
4358
|
+
|
|
4359
|
+
<a id="storeoffersoutcome-outcome"></a>
|
|
4360
|
+
|
|
4361
|
+
## StoreOffersOutcome.outcome
|
|
4362
|
+
|
|
4363
|
+
```ts
|
|
4364
|
+
readonly outcome: ArcadeOutcomeKind
|
|
4365
|
+
```
|
|
4366
|
+
|
|
4367
|
+
What happened: `ok`, `declined` or `unavailable`. Branch on this.
|
|
4368
|
+
|
|
4369
|
+
<a id="storeoffersoutcome-reason"></a>
|
|
4370
|
+
|
|
4371
|
+
## StoreOffersOutcome.reason
|
|
4372
|
+
|
|
4373
|
+
```ts
|
|
4374
|
+
readonly reason?: string
|
|
4375
|
+
```
|
|
4376
|
+
|
|
4377
|
+
Why, as a machine code — `busy`, `cancelled`, `not_found`, `pending`,
|
|
4378
|
+
`store_off`, `sign_in_required` and more. OPEN-ENDED: the arcade may send a
|
|
4379
|
+
code this SDK has never heard of, so keep a `default` arm and never show a
|
|
4380
|
+
code to a player. Absent when there is nothing to add.
|
|
4381
|
+
|
|
4382
|
+
Three are the SDK's own, answered without asking the arcade:
|
|
4383
|
+
`unsupported` (the arcade here does not offer this), `invalid_argument`
|
|
4384
|
+
(the SDK refused what you passed) and `busy` (another ask of the same kind
|
|
4385
|
+
is still open). `error` means no reliable answer arrived — the ask never
|
|
4386
|
+
left, the wait ran out, the bridge closed or the arcade had none. For
|
|
4387
|
+
`gem.store.purchase` that makes the outcome UNKNOWN, not a refusal: the
|
|
4388
|
+
player may have paid.
|
|
4389
|
+
|
|
4390
|
+
<a id="storeoffersoutcome-offers"></a>
|
|
4391
|
+
|
|
4392
|
+
## StoreOffersOutcome.offers
|
|
4393
|
+
|
|
4394
|
+
```ts
|
|
4395
|
+
readonly offers: readonly ArcadeOffer[]
|
|
4396
|
+
```
|
|
4397
|
+
|
|
4398
|
+
What the store sells here, in its own order. Empty unless `ok`.
|
|
4399
|
+
|
|
4400
|
+
<a id="storesettlement"></a>
|
|
4401
|
+
|
|
4402
|
+
## StoreSettlement
|
|
4403
|
+
|
|
4404
|
+
```ts
|
|
4405
|
+
interface StoreSettlement
|
|
4406
|
+
```
|
|
4407
|
+
|
|
4408
|
+
A purchase that answered `ok` / `pending` has settled.
|
|
4409
|
+
|
|
4410
|
+
<a id="storesettlement-skuid"></a>
|
|
4411
|
+
|
|
4412
|
+
## StoreSettlement.skuId
|
|
4413
|
+
|
|
4414
|
+
```ts
|
|
4415
|
+
readonly skuId: string
|
|
4416
|
+
```
|
|
4417
|
+
|
|
4418
|
+
The SKU it was for. Re-read balances and inventory through `gem.me`.
|
|
4419
|
+
|
|
4420
|
+
<a id="storeapi"></a>
|
|
4421
|
+
|
|
4422
|
+
## StoreApi
|
|
4423
|
+
|
|
4424
|
+
```ts
|
|
4425
|
+
interface StoreApi
|
|
4426
|
+
```
|
|
4427
|
+
|
|
4428
|
+
**Real money.** The Arcade Store's own Gem packs, Boosts, passes and bundles,
|
|
4429
|
+
bought with the player's money through the arcade's own purchase sheet.
|
|
4430
|
+
`gem.store` is one of these. To spend Gems or Coins on your game's own items,
|
|
4431
|
+
use `gem.purchases`.
|
|
4432
|
+
|
|
4433
|
+
<a id="storeapi-available"></a>
|
|
4434
|
+
|
|
4435
|
+
## StoreApi.available
|
|
4436
|
+
|
|
4437
|
+
```ts
|
|
4438
|
+
readonly available: boolean
|
|
4439
|
+
```
|
|
4440
|
+
|
|
4441
|
+
Whether the Arcade Store answers here, synchronously. Draw your own "Get
|
|
4442
|
+
Gems" button only when it is true.
|
|
4443
|
+
|
|
4444
|
+
<a id="storeapi-offers"></a>
|
|
4445
|
+
|
|
4446
|
+
## StoreApi.offers
|
|
4447
|
+
|
|
4448
|
+
```ts
|
|
4449
|
+
offers(): Promise<StoreOffersOutcome>
|
|
4450
|
+
```
|
|
4451
|
+
|
|
4452
|
+
What the store sells this player here: names, art and the rail's own
|
|
4453
|
+
prices. `unavailable` / `sign_in_required` for a guest (offer
|
|
4454
|
+
`gem.account.requestSignIn`), `unavailable` / `store_off` where the store
|
|
4455
|
+
is withheld. Re-read on resume: what is on sale can change.
|
|
4456
|
+
|
|
4457
|
+
**Returns.** Always resolves; never rejects.
|
|
4458
|
+
|
|
4459
|
+
<a id="storeapi-purchase"></a>
|
|
4460
|
+
|
|
4461
|
+
## StoreApi.purchase
|
|
4462
|
+
|
|
4463
|
+
```ts
|
|
4464
|
+
purchase(skuId: string): Promise<ArcadeOutcome>
|
|
4465
|
+
```
|
|
4466
|
+
|
|
4467
|
+
Ask the arcade to open its store's purchase sheet for one SKU from
|
|
4468
|
+
[StoreApi.offers](#storeapi-offers). **Call it from the player's press handler** — the
|
|
4469
|
+
arcade refuses an ask no person pressed for, `declined` / `busy`.
|
|
4470
|
+
|
|
4471
|
+
- `ok` — the player paid. Re-read balances and inventory through `gem.me`;
|
|
4472
|
+
nothing here carries an amount. With `reason: 'pending'`, the provider
|
|
4473
|
+
has not settled yet: [StoreApi.onSettled](#storeapi-onsettled) hears when it does.
|
|
4474
|
+
- `declined` — nothing was bought: `cancelled` (the player said no) or
|
|
4475
|
+
`busy`. Return to your screen silently, and do not ask again unprompted.
|
|
4476
|
+
- `unavailable` with `store_off`, `sign_in_required`, `not_found`,
|
|
4477
|
+
`unsupported`, `invalid_argument` or a payment provider's failure code —
|
|
4478
|
+
nothing was bought.
|
|
4479
|
+
- `unavailable` / `error` — **the outcome is unknown, and the player may
|
|
4480
|
+
have paid.** It is what you get when the bridge closes while the sheet
|
|
4481
|
+
is open, or the arcade has no reliable answer. Never tell the player
|
|
4482
|
+
nothing was bought: re-read balances and inventory through `gem.me`,
|
|
4483
|
+
and keep listening with [StoreApi.onSettled](#storeapi-onsettled).
|
|
4484
|
+
|
|
4485
|
+
NO TIMEOUT: it waits for as long as the arcade is connected, because a
|
|
4486
|
+
payment takes as long as it takes.
|
|
4487
|
+
|
|
4488
|
+
| Parameter | Type |
|
|
4489
|
+
| --- | --- |
|
|
4490
|
+
| `skuId` | `string` |
|
|
4491
|
+
|
|
4492
|
+
**Returns.** Always resolves; never rejects.
|
|
4493
|
+
|
|
4494
|
+
<a id="storeapi-onsettled"></a>
|
|
4495
|
+
|
|
4496
|
+
## StoreApi.onSettled
|
|
4497
|
+
|
|
4498
|
+
```ts
|
|
4499
|
+
onSettled(listener: (settlement: StoreSettlement) => void): () => void
|
|
4500
|
+
```
|
|
4501
|
+
|
|
4502
|
+
Hear when a purchase that answered `ok` / `pending` settles, while your
|
|
4503
|
+
game is running. Returns a function that stops listening.
|
|
4504
|
+
|
|
4505
|
+
| Parameter | Type |
|
|
4506
|
+
| --- | --- |
|
|
4507
|
+
| `listener` | `(settlement: StoreSettlement) => void` |
|
|
4508
|
+
|
|
3790
4509
|
<a id="avatar3dprice"></a>
|
|
3791
4510
|
|
|
3792
4511
|
## Avatar3dPrice
|
|
@@ -9751,8 +10470,10 @@ synchronously wherever you render.
|
|
|
9751
10470
|
readonly purchases: PurchaseApi
|
|
9752
10471
|
```
|
|
9753
10472
|
|
|
9754
|
-
Buy one of YOUR OWN items or recipes
|
|
9755
|
-
player's behalf.
|
|
10473
|
+
**Gems and Coins, not real money.** Buy one of YOUR OWN items or recipes
|
|
10474
|
+
with platform currency, on the player's behalf. To sell the Arcade Store's
|
|
10475
|
+
own Gem packs, Boosts and passes for the player's money, use
|
|
10476
|
+
[Gem.store](#gem-store).
|
|
9756
10477
|
|
|
9757
10478
|
This is the platform-owned path: the request crosses the bridge, the parent
|
|
9758
10479
|
always renders the platform purchase sheet in trusted chrome, and the
|
|
@@ -9893,6 +10614,44 @@ shareButton.onclick = () => {
|
|
|
9893
10614
|
|
|
9894
10615
|
**Guides.** [getting-started](../getting-started.md)
|
|
9895
10616
|
|
|
10617
|
+
<a id="gem-arcade"></a>
|
|
10618
|
+
|
|
10619
|
+
## Gem.arcade
|
|
10620
|
+
|
|
10621
|
+
```ts
|
|
10622
|
+
readonly arcade: ArcadeApi
|
|
10623
|
+
```
|
|
10624
|
+
|
|
10625
|
+
The Gem Arcade's own features, asked for from your game: link out to the
|
|
10626
|
+
Gem Arcade app or your game's own app, open another game, and list games
|
|
10627
|
+
like yours as home tiles.
|
|
10628
|
+
|
|
10629
|
+
The game asks; the arcade decides. Nothing you send is a URL, and nothing
|
|
10630
|
+
rejects: every call resolves `{ outcome, reason, … }`. Check
|
|
10631
|
+
[ArcadeApi.available](#arcadeapi-available) before drawing a button, and call `openApp`
|
|
10632
|
+
and `openGame` from the player's press handler.
|
|
10633
|
+
|
|
10634
|
+
**Guides.** [arcade-and-store](../arcade-and-store.md)
|
|
10635
|
+
|
|
10636
|
+
<a id="gem-store"></a>
|
|
10637
|
+
|
|
10638
|
+
## Gem.store
|
|
10639
|
+
|
|
10640
|
+
```ts
|
|
10641
|
+
readonly store: StoreApi
|
|
10642
|
+
```
|
|
10643
|
+
|
|
10644
|
+
**Real money.** The Arcade Store's own Gem packs, Boosts, passes and
|
|
10645
|
+
bundles, sold for the player's money through the arcade's own purchase
|
|
10646
|
+
sheet. To spend Gems or Coins on your game's own items, use
|
|
10647
|
+
[Gem.purchases](#gem-purchases).
|
|
10648
|
+
|
|
10649
|
+
List what the store sells here with `offers()`, show each `priceDisplay`
|
|
10650
|
+
exactly as given, and call `purchase(skuId)` from the player's press. After
|
|
10651
|
+
`ok`, re-read balances through [Gem.me](#gem-me). Nothing rejects.
|
|
10652
|
+
|
|
10653
|
+
**Guides.** [arcade-and-store](../arcade-and-store.md)
|
|
10654
|
+
|
|
9896
10655
|
<a id="gem-avatarpickeravailable"></a>
|
|
9897
10656
|
|
|
9898
10657
|
## Gem.avatarPickerAvailable
|