@indiegems/gem-web-sdk 7.5.0 → 7.7.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 +886 -0
- package/README.md +1 -0
- package/dist/function.d.ts +994 -0
- package/dist/game.d.ts +26 -5
- package/dist/gem-web-sdk.bridge.js +1 -1
- package/dist/gem-web-sdk.esm.js +1 -1
- package/dist/gem-web-sdk.function.js +3 -0
- package/dist/gem-web-sdk.game.js +2 -2
- package/dist/gem-web-sdk.min.js +2 -2
- package/dist/gem-web-sdk.sdk.js +2 -2
- package/dist/gem-web-sdk.server-api.js +1 -1
- package/dist/gem-web-sdk.server.js +2 -2
- package/dist/sdk.d.ts +62 -11
- package/dist/server-api.d.ts +33 -6
- package/dist/server.d.ts +36 -6
- package/docs/analytics.md +2 -3
- package/docs/api/api-reference-game.md +392 -41
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +377 -20
- package/docs/changelog.md +886 -0
- package/docs/daily-challenges.md +14 -2
- package/docs/getting-started.md +8 -6
- package/docs/leaderboards.md +140 -0
- package/docs/manifest.json +24 -14
- package/docs/server-bundles.md +2 -2
- package/docs/serverless-functions-js.md +139 -0
- package/docs/serverless-functions.md +35 -5
- package/docs/what-a-game-must-do.md +39 -26
- package/package.json +7 -2
- package/schema/bridge.v1.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The browser surface — API reference
|
|
2
2
|
|
|
3
|
-
Generated from `@indiegems/gem-web-sdk/sdk` v7.
|
|
3
|
+
Generated from `@indiegems/gem-web-sdk/sdk` v7.7.0. Every symbol below links to its page on the Gem Arcade developer site.
|
|
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
|
|
|
@@ -4613,11 +4613,11 @@ type FrameState = "waiting" | "connected" | "refused" | "closed"
|
|
|
4613
4613
|
|
|
4614
4614
|
Where the bridge to the arcade stands.
|
|
4615
4615
|
|
|
4616
|
-
`waiting` is the state a game boots in and
|
|
4617
|
-
|
|
4618
|
-
`
|
|
4619
|
-
|
|
4620
|
-
|
|
4616
|
+
`waiting` is the state a game boots in: framed, and its parent has not
|
|
4617
|
+
answered yet. `connected` is the only state in which the arcade is
|
|
4618
|
+
listening. `refused` is final: the page that framed this game is not one it
|
|
4619
|
+
accepts (its origin is not in `allowedEmbedders`), or it speaks no protocol
|
|
4620
|
+
version in common. `closed` means a connection existed and ended.
|
|
4621
4621
|
|
|
4622
4622
|
Received by `onStateChange` and resolved by `awaitBridge`, both of which are
|
|
4623
4623
|
documented — so without a name for this union a game could observe the value
|
|
@@ -4655,15 +4655,15 @@ Where the bridge is right now, without waiting.
|
|
|
4655
4655
|
|
|
4656
4656
|
- `waiting` — the arcade has not connected yet. Normal at startup.
|
|
4657
4657
|
- `connected` — the bridge is up and everything works.
|
|
4658
|
-
- `refused` — the
|
|
4658
|
+
- `refused` — final: the page that framed the game is not one it accepts,
|
|
4659
|
+
or no protocol version is shared.
|
|
4659
4660
|
- `closed` — the session has ended.
|
|
4660
4661
|
|
|
4661
4662
|
A snapshot, so it can change immediately after you read it. To wait for the
|
|
4662
4663
|
question to be settled once, use [GemFrame.settled](https://gemarcade.com/developer/api/game#gemframe-settled).
|
|
4663
4664
|
|
|
4664
|
-
A
|
|
4665
|
-
|
|
4666
|
-
bridge.
|
|
4665
|
+
A page that frames the game and never answers leaves it `waiting`, which
|
|
4666
|
+
is the case worth handling: boot anyway, and say there is no session.
|
|
4667
4667
|
|
|
4668
4668
|
## GemFrame.parentSupports
|
|
4669
4669
|
|
|
@@ -4723,10 +4723,9 @@ parsing several megabytes of JavaScript, the offer waits behind that work —
|
|
|
4723
4723
|
and by the time it arrives the connection it carried may already be gone.
|
|
4724
4724
|
Awaiting this first keeps the thread free long enough to accept.
|
|
4725
4725
|
|
|
4726
|
-
THE WAIT IS BOUNDED ON PURPOSE, because
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
this is.
|
|
4726
|
+
THE WAIT IS BOUNDED ON PURPOSE, because the page framing your game may
|
|
4727
|
+
never answer, and your game must still start and say so. Proceed on either
|
|
4728
|
+
outcome and read the resolved state to know which kind of boot this is.
|
|
4730
4729
|
|
|
4731
4730
|
```js
|
|
4732
4731
|
const state = await gem.frame.settled();
|
|
@@ -6752,7 +6751,7 @@ readonly reserved: readonly GemReservedArea[]
|
|
|
6752
6751
|
```
|
|
6753
6752
|
|
|
6754
6753
|
Rectangles of your frame the arcade's own controls cover — its Back tab in
|
|
6755
|
-
the top-left corner, and the wallets
|
|
6754
|
+
the top-left corner, and the wallets in the top-right while they are shown (see
|
|
6756
6755
|
`setWalletVisible`). Keep essential UI and touch targets out of them. Empty
|
|
6757
6756
|
when the arcade covers nothing.
|
|
6758
6757
|
|
|
@@ -7019,7 +7018,9 @@ single round trip to the page hosting your game.
|
|
|
7019
7018
|
|
|
7020
7019
|
Rejects rather than resolving `null` if the wait runs out: a session that
|
|
7021
7020
|
cannot sign in cannot do anything else either, and a `null` you might not
|
|
7022
|
-
check is how a game carries on into a failure it could have reported.
|
|
7021
|
+
check is how a game carries on into a failure it could have reported. It
|
|
7022
|
+
rejects at once, without waiting, when the page that framed the game was
|
|
7023
|
+
refused: no token can arrive from it.
|
|
7023
7024
|
|
|
7024
7025
|
| Parameter | Type | Description |
|
|
7025
7026
|
| --- | --- | --- |
|
|
@@ -7042,10 +7043,10 @@ Waits for the connection to the arcade to settle, one way or the other.
|
|
|
7042
7043
|
Resolves with the state it settled into — connected, refused or closed — or
|
|
7043
7044
|
with whatever it had reached by `timeoutMs`, which defaults to 10 seconds.
|
|
7044
7045
|
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7046
|
+
A game is always framed (`createGem` throws [GemUnframedError](https://gemarcade.com/developer/api/game#gemunframederror)
|
|
7047
|
+
otherwise), so this normally resolves `connected` within a moment. It
|
|
7048
|
+
resolves `refused` at once when the page that framed the game is not one it
|
|
7049
|
+
accepts, and `waiting` only when the page framing it never answers.
|
|
7049
7050
|
|
|
7050
7051
|
**Await this in your boot entry before importing your main bundle.** The
|
|
7051
7052
|
arcade hands your game its connection as a one-off delivery rather than
|
|
@@ -7054,9 +7055,10 @@ parsing several megabytes of JavaScript when it arrives, your game can miss
|
|
|
7054
7055
|
it. Awaiting this keeps the thread free through that window; the moment it
|
|
7055
7056
|
resolves, load everything.
|
|
7056
7057
|
|
|
7057
|
-
Carry on whatever it resolves to. `connected` means
|
|
7058
|
-
|
|
7059
|
-
|
|
7058
|
+
Carry on whatever it resolves to. `connected` means a Gem host is
|
|
7059
|
+
listening — the Arcade, the Editor or the dev host on your machine;
|
|
7060
|
+
anything else means no session, which your game has to survive with a
|
|
7061
|
+
message rather than a hang.
|
|
7060
7062
|
|
|
7061
7063
|
| Parameter | Type | Description |
|
|
7062
7064
|
| --- | --- | --- |
|
|
@@ -7075,8 +7077,7 @@ readonly player: GemPlayer | null
|
|
|
7075
7077
|
|
|
7076
7078
|
The player's display identity — the name, handle and avatar you show them.
|
|
7077
7079
|
|
|
7078
|
-
`null` until the arcade sends it,
|
|
7079
|
-
Nothing obliges it to be sent at all, so treat its absence as normal and
|
|
7080
|
+
`null` until the arcade sends it. Nothing obliges it to be sent at all, so treat its absence as normal and
|
|
7080
7081
|
have a fallback: a game with no display name is fine, a game that waits
|
|
7081
7082
|
forever for one is not.
|
|
7082
7083
|
|
|
@@ -7523,8 +7524,8 @@ awaitCohorts(timeoutMs?: number): Promise<GemCohorts | null>
|
|
|
7523
7524
|
|
|
7524
7525
|
The experiment cohorts, waiting up to `timeoutMs` for them.
|
|
7525
7526
|
|
|
7526
|
-
Resolves `null` rather than rejecting
|
|
7527
|
-
|
|
7527
|
+
Resolves `null` rather than rejecting once the wait is out, or at once if
|
|
7528
|
+
the page that framed the game was refused. Use it at the ONE point
|
|
7528
7529
|
your game branches on a cohort — typically
|
|
7529
7530
|
the first run's opening — and give it a short budget: the answer normally
|
|
7530
7531
|
arrives within the first second, and a player kept on a splash screen for a
|
|
@@ -7647,7 +7648,7 @@ ticketStore.onOpen = () => gem.setWalletVisible(true, { only: ['ARCADE_TICKETS']
|
|
|
7647
7648
|
replaces the last. While hidden, the arcade still pops a wallet up for a
|
|
7648
7649
|
moment when something happens to it — a reward you cued, a spend, a
|
|
7649
7650
|
landing — and your state never cancels that. Shown wallets cover part of
|
|
7650
|
-
your frame
|
|
7651
|
+
your frame's top-right corner, which arrives as a rectangle in
|
|
7651
7652
|
`gem.viewport.reserved`; hiding them gives that space back. A wallet the
|
|
7652
7653
|
arcade pops up for a moment floats over your game and moves nothing.
|
|
7653
7654
|
|
|
@@ -7715,9 +7716,9 @@ readonly frame: GemFrame
|
|
|
7715
7716
|
|
|
7716
7717
|
Your game's connection to the arcade.
|
|
7717
7718
|
|
|
7718
|
-
ALWAYS PRESENT, even when nothing is on the other end
|
|
7719
|
-
|
|
7720
|
-
|
|
7719
|
+
ALWAYS PRESENT, even when nothing is on the other end yet: a page that
|
|
7720
|
+
never answers leaves the frame in `waiting`, and a refused one ends it in
|
|
7721
|
+
`refused`, which is the state to read when you want to know whether anyone
|
|
7721
7722
|
ever answered. Do not write a `=== null` branch; it can never run.
|
|
7722
7723
|
|
|
7723
7724
|
**This is where the loading contract lives.** Call `progress()` as your
|
|
@@ -7833,8 +7834,9 @@ Connect your game to the Gem Arcade. This is the one call every game makes.
|
|
|
7833
7834
|
|
|
7834
7835
|
It assembles everything and connects to the arcade that framed your game. The
|
|
7835
7836
|
same code runs on your machine and in production without a flag — but it needs
|
|
7836
|
-
a
|
|
7837
|
-
|
|
7837
|
+
a frame either way. Opened at the top level it throws
|
|
7838
|
+
[GemUnframedError](https://gemarcade.com/developer/api/game#gemunframederror), which says how to run it: in the Arcade, the Editor,
|
|
7839
|
+
or the Gem dev host on your machine (`npm run dev`, signed in to `gemctl`).
|
|
7838
7840
|
|
|
7839
7841
|
One dependency, imported like anything else. The install is at
|
|
7840
7842
|
https://gemarcade.com/developer/docs/getting-started#3-add-the-sdk
|
|
@@ -7989,6 +7991,43 @@ What [LeaderboardsApi.mine](https://gemarcade.com/developer/api/game#leaderboard
|
|
|
7989
7991
|
Separate from [GetLeaderboardOptions](https://gemarcade.com/developer/api/game#getleaderboardoptions) because `limit` has no meaning
|
|
7990
7992
|
there — the global board arrives whole.
|
|
7991
7993
|
|
|
7994
|
+
## LeaderboardPeriod
|
|
7995
|
+
|
|
7996
|
+
[LeaderboardPeriod](https://gemarcade.com/developer/api/game#leaderboardperiod)
|
|
7997
|
+
|
|
7998
|
+
```ts
|
|
7999
|
+
interface LeaderboardPeriod
|
|
8000
|
+
```
|
|
8001
|
+
|
|
8002
|
+
Which period a `per_period` board's result is for.
|
|
8003
|
+
|
|
8004
|
+
A board whose config sets `per_period: true` exists once per period of the
|
|
8005
|
+
challenge its run type names: one board for each day of a daily challenge,
|
|
8006
|
+
each week of a weekly one. Present on a result exactly when the board is one
|
|
8007
|
+
of those; absent — not `null` — on an ordinary board.
|
|
8008
|
+
|
|
8009
|
+
⚠️ **Players on the same date share a board, whatever their time zone.** On
|
|
8010
|
+
a challenge that follows each player's own time zone (the default), a date
|
|
8011
|
+
begins for each player at their own midnight, so one day's board is open for
|
|
8012
|
+
about 50 hours worldwide and the standings can still change after YOUR day
|
|
8013
|
+
has ended. [LeaderboardPeriod.final](https://gemarcade.com/developer/api/game#leaderboardperiod-final) says when they no longer can.
|
|
8014
|
+
|
|
8015
|
+
## PeriodOptions
|
|
8016
|
+
|
|
8017
|
+
[PeriodOptions](https://gemarcade.com/developer/api/game#periodoptions)
|
|
8018
|
+
|
|
8019
|
+
```ts
|
|
8020
|
+
interface PeriodOptions
|
|
8021
|
+
```
|
|
8022
|
+
|
|
8023
|
+
Which period of a `per_period` board to read. Shared by every read.
|
|
8024
|
+
|
|
8025
|
+
Name at most one of [PeriodOptions.periodsBack](https://gemarcade.com/developer/api/game#periodoptions-periodsback) and
|
|
8026
|
+
[PeriodOptions.period](https://gemarcade.com/developer/api/game#periodoptions-period); with neither, the read answers for the current
|
|
8027
|
+
period. On a board that is not `per_period` both are refused with `invalid`
|
|
8028
|
+
rather than ignored — asking an all-time board for yesterday and being
|
|
8029
|
+
handed all time would be a different answer with nothing saying so.
|
|
8030
|
+
|
|
7992
8031
|
## ShowcaseApi
|
|
7993
8032
|
|
|
7994
8033
|
[ShowcaseApi](https://gemarcade.com/developer/api/game#showcaseapi)
|
|
@@ -11011,6 +11050,126 @@ theirs. Use this for display-level comparisons, not for identity.
|
|
|
11011
11050
|
| `a` | `string \| PlayerText` |
|
|
11012
11051
|
| `b` | `string \| PlayerText` |
|
|
11013
11052
|
|
|
11053
|
+
## GemUnframedError
|
|
11054
|
+
|
|
11055
|
+
[GemUnframedError](https://gemarcade.com/developer/api/game#gemunframederror)
|
|
11056
|
+
|
|
11057
|
+
```ts
|
|
11058
|
+
class GemUnframedError
|
|
11059
|
+
```
|
|
11060
|
+
|
|
11061
|
+
Your game was opened without a Gem frame around it.
|
|
11062
|
+
|
|
11063
|
+
Thrown by `createGem` when the page is the top-level document: nothing
|
|
11064
|
+
framed it, so nothing can hand it a player, saves, config or rooms. The SDK
|
|
11065
|
+
needs that frame — the Gem Arcade, the Gem Editor, or the Gem dev host on
|
|
11066
|
+
your own machine — and refuses to start without one rather than running a
|
|
11067
|
+
game that silently has no player.
|
|
11068
|
+
|
|
11069
|
+
You do not construct this. Run the game framed instead: `npm run dev`
|
|
11070
|
+
(`gemctl serve start . --dev`) while you edit, `gemctl serve start .` for a
|
|
11071
|
+
build, signed in to `gemctl` either way. Never open the address the dev
|
|
11072
|
+
server itself prints.
|
|
11073
|
+
|
|
11074
|
+
A unit test that constructs the SDK in a simulated DOM has to give its
|
|
11075
|
+
window a parent of its own, because a simulated top-level window is exactly
|
|
11076
|
+
what this refuses.
|
|
11077
|
+
|
|
11078
|
+
## LeaderboardPeriod.id
|
|
11079
|
+
|
|
11080
|
+
[LeaderboardPeriod.id](https://gemarcade.com/developer/api/game#leaderboardperiod-id)
|
|
11081
|
+
|
|
11082
|
+
```ts
|
|
11083
|
+
readonly id: string
|
|
11084
|
+
```
|
|
11085
|
+
|
|
11086
|
+
The period this board is for: the date for a daily challenge, the Monday
|
|
11087
|
+
for a weekly, the 1st for a monthly (`2026-10-02`), or a cron challenge's
|
|
11088
|
+
start as `2026-10-02T06:00:00Z`.
|
|
11089
|
+
|
|
11090
|
+
**This is the board's identity.** Pass it back as
|
|
11091
|
+
[GetLeaderboardOptions.period](https://gemarcade.com/developer/api/game#getleaderboardoptions-period) to read this same board again later —
|
|
11092
|
+
from a shared link, or a history screen — and key any cache on it.
|
|
11093
|
+
|
|
11094
|
+
## LeaderboardPeriod.localDate
|
|
11095
|
+
|
|
11096
|
+
[LeaderboardPeriod.localDate](https://gemarcade.com/developer/api/game#leaderboardperiod-localdate)
|
|
11097
|
+
|
|
11098
|
+
```ts
|
|
11099
|
+
readonly localDate?: string
|
|
11100
|
+
```
|
|
11101
|
+
|
|
11102
|
+
The period's calendar date, `YYYY-MM-DD` — the same value
|
|
11103
|
+
`gem.challenges.list()` gives as `periodLocalDate` for the challenge, so
|
|
11104
|
+
the two can be compared. Absent for a cron challenge, which has no date.
|
|
11105
|
+
|
|
11106
|
+
## LeaderboardPeriod.startAt
|
|
11107
|
+
|
|
11108
|
+
[LeaderboardPeriod.startAt](https://gemarcade.com/developer/api/game#leaderboardperiod-startat)
|
|
11109
|
+
|
|
11110
|
+
```ts
|
|
11111
|
+
readonly startAt?: number
|
|
11112
|
+
```
|
|
11113
|
+
|
|
11114
|
+
When this period began for the player the read answered for, in Unix
|
|
11115
|
+
seconds. Absent when the read answered for no player — a server or a
|
|
11116
|
+
function that named none — on a challenge that follows each player's own
|
|
11117
|
+
time zone.
|
|
11118
|
+
|
|
11119
|
+
## LeaderboardPeriod.endsAt
|
|
11120
|
+
|
|
11121
|
+
[LeaderboardPeriod.endsAt](https://gemarcade.com/developer/api/game#leaderboardperiod-endsat)
|
|
11122
|
+
|
|
11123
|
+
```ts
|
|
11124
|
+
readonly endsAt?: number
|
|
11125
|
+
```
|
|
11126
|
+
|
|
11127
|
+
When this period ends for that player, in Unix seconds: their own runs stop
|
|
11128
|
+
counting towards this board then.
|
|
11129
|
+
|
|
11130
|
+
⚠️ **Not when the board stops changing.** Players in later time zones are
|
|
11131
|
+
still on this date after it; see [LeaderboardPeriod.closesAt](https://gemarcade.com/developer/api/game#leaderboardperiod-closesat) and
|
|
11132
|
+
[LeaderboardPeriod.final](https://gemarcade.com/developer/api/game#leaderboardperiod-final). Absent exactly when
|
|
11133
|
+
[LeaderboardPeriod.startAt](https://gemarcade.com/developer/api/game#leaderboardperiod-startat) is.
|
|
11134
|
+
|
|
11135
|
+
## LeaderboardPeriod.opensAt
|
|
11136
|
+
|
|
11137
|
+
[LeaderboardPeriod.opensAt](https://gemarcade.com/developer/api/game#leaderboardperiod-opensat)
|
|
11138
|
+
|
|
11139
|
+
```ts
|
|
11140
|
+
readonly opensAt: number
|
|
11141
|
+
```
|
|
11142
|
+
|
|
11143
|
+
When this board started accepting runs from anyone, in Unix seconds. `0`
|
|
11144
|
+
when the platform sent something this SDK could not read.
|
|
11145
|
+
|
|
11146
|
+
## LeaderboardPeriod.closesAt
|
|
11147
|
+
|
|
11148
|
+
[LeaderboardPeriod.closesAt](https://gemarcade.com/developer/api/game#leaderboardperiod-closesat)
|
|
11149
|
+
|
|
11150
|
+
```ts
|
|
11151
|
+
readonly closesAt: number
|
|
11152
|
+
```
|
|
11153
|
+
|
|
11154
|
+
When this board stops accepting runs from anyone, in Unix seconds. `0`
|
|
11155
|
+
when the platform sent something this SDK could not read.
|
|
11156
|
+
|
|
11157
|
+
## LeaderboardPeriod.final
|
|
11158
|
+
|
|
11159
|
+
[LeaderboardPeriod.final](https://gemarcade.com/developer/api/game#leaderboardperiod-final)
|
|
11160
|
+
|
|
11161
|
+
```ts
|
|
11162
|
+
readonly final: boolean
|
|
11163
|
+
```
|
|
11164
|
+
|
|
11165
|
+
`true` once no run can still arrive, so the standings will not change
|
|
11166
|
+
again — stop polling, and say "final" if your screen says anything.
|
|
11167
|
+
|
|
11168
|
+
While it is `false` the standings may change, **including after the
|
|
11169
|
+
viewer's own period has ended**: a "you finished 3rd today" shown at the
|
|
11170
|
+
player's midnight can be wrong an hour later. Say "so far" until this is
|
|
11171
|
+
`true`.
|
|
11172
|
+
|
|
11014
11173
|
## LeaderboardEntry.playerId
|
|
11015
11174
|
|
|
11016
11175
|
[LeaderboardEntry.playerId](https://gemarcade.com/developer/api/game#leaderboardentry-playerid)
|
|
@@ -11108,6 +11267,12 @@ readonly occurredAt: number
|
|
|
11108
11267
|
|
|
11109
11268
|
When the ranked run occurred — Unix seconds.
|
|
11110
11269
|
|
|
11270
|
+
⚠️ **`0` on a `per_period` board whose challenge follows each player's own
|
|
11271
|
+
time zone** (the default `local` boundary). The platform serves no time
|
|
11272
|
+
there: beside the board's date, the time of a run would show which time
|
|
11273
|
+
zones its player could be in. Render no time for `0` rather than 1970.
|
|
11274
|
+
Ranks are unaffected — ties are still broken by the real time.
|
|
11275
|
+
|
|
11111
11276
|
## LeaderboardEntry.entityId
|
|
11112
11277
|
|
|
11113
11278
|
[LeaderboardEntry.entityId](https://gemarcade.com/developer/api/game#leaderboardentry-entityid)
|
|
@@ -11251,6 +11416,20 @@ interval: polling faster re-downloads the same rendering.
|
|
|
11251
11416
|
Absent if the server did not state one. Absent means *unknown*, not
|
|
11252
11417
|
"refreshes constantly" — do not substitute `0` and poll on it.
|
|
11253
11418
|
|
|
11419
|
+
## Leaderboard.period
|
|
11420
|
+
|
|
11421
|
+
[Leaderboard.period](https://gemarcade.com/developer/api/game#leaderboard-period)
|
|
11422
|
+
|
|
11423
|
+
```ts
|
|
11424
|
+
readonly period?: LeaderboardPeriod
|
|
11425
|
+
```
|
|
11426
|
+
|
|
11427
|
+
Which period this result is for, on a board whose config sets
|
|
11428
|
+
`per_period`. Absent on an ordinary board, which ranks every run.
|
|
11429
|
+
|
|
11430
|
+
Once `period.final` is `true` the board no longer changes and need not be
|
|
11431
|
+
polled.
|
|
11432
|
+
|
|
11254
11433
|
## RankedRow.rank
|
|
11255
11434
|
|
|
11256
11435
|
[RankedRow.rank](https://gemarcade.com/developer/api/game#rankedrow-rank)
|
|
@@ -11269,7 +11448,9 @@ readonly rank: number
|
|
|
11269
11448
|
readonly occurredAt: number
|
|
11270
11449
|
```
|
|
11271
11450
|
|
|
11272
|
-
When the ranked run occurred — Unix seconds.
|
|
11451
|
+
When the ranked run occurred — Unix seconds. `0` on a `per_period` board
|
|
11452
|
+
whose challenge follows each player's own time zone, where the platform
|
|
11453
|
+
serves no time; render nothing for it.
|
|
11273
11454
|
|
|
11274
11455
|
## RankedRow.stats
|
|
11275
11456
|
|
|
@@ -11299,7 +11480,9 @@ The run's freeform properties.
|
|
|
11299
11480
|
readonly occurredAt: number
|
|
11300
11481
|
```
|
|
11301
11482
|
|
|
11302
|
-
When the ranked run occurred — Unix seconds.
|
|
11483
|
+
When the ranked run occurred — Unix seconds. `0` on a `per_period` board
|
|
11484
|
+
whose challenge follows each player's own time zone, where the platform
|
|
11485
|
+
serves no time; render nothing for it.
|
|
11303
11486
|
|
|
11304
11487
|
## EntityLeaderboardEntry.properties
|
|
11305
11488
|
|
|
@@ -11461,6 +11644,107 @@ readonly generatedAt: number
|
|
|
11461
11644
|
|
|
11462
11645
|
When this rendering was computed — Unix seconds.
|
|
11463
11646
|
|
|
11647
|
+
## EntityLeaderboard.period
|
|
11648
|
+
|
|
11649
|
+
[EntityLeaderboard.period](https://gemarcade.com/developer/api/game#entityleaderboard-period)
|
|
11650
|
+
|
|
11651
|
+
```ts
|
|
11652
|
+
readonly period?: LeaderboardPeriod
|
|
11653
|
+
```
|
|
11654
|
+
|
|
11655
|
+
Which period these runs are from, on a board whose config sets
|
|
11656
|
+
`per_period`: `entries`, `personalBest` and `totalRuns`
|
|
11657
|
+
are then that ONE period's, not the entity's whole history. Absent on an
|
|
11658
|
+
ordinary board.
|
|
11659
|
+
|
|
11660
|
+
## PeriodOptions.periodsBack
|
|
11661
|
+
|
|
11662
|
+
[PeriodOptions.periodsBack](https://gemarcade.com/developer/api/game#periodoptions-periodsback)
|
|
11663
|
+
|
|
11664
|
+
```ts
|
|
11665
|
+
readonly periodsBack?: number
|
|
11666
|
+
```
|
|
11667
|
+
|
|
11668
|
+
How many periods back to read. `0` — the default — is the current period;
|
|
11669
|
+
`1` is yesterday's board for a daily challenge, last week's for a weekly.
|
|
11670
|
+
|
|
11671
|
+
An integer from 0 to 400. Anything else is a `TypeError` before the
|
|
11672
|
+
request is made.
|
|
11673
|
+
|
|
11674
|
+
## PeriodOptions.period
|
|
11675
|
+
|
|
11676
|
+
[PeriodOptions.period](https://gemarcade.com/developer/api/game#periodoptions-period)
|
|
11677
|
+
|
|
11678
|
+
```ts
|
|
11679
|
+
readonly period?: string
|
|
11680
|
+
```
|
|
11681
|
+
|
|
11682
|
+
The period to read, as an earlier result's [LeaderboardPeriod.id](https://gemarcade.com/developer/api/game#leaderboardperiod-id) —
|
|
11683
|
+
for a board reached from a shared link or a history screen. At most 400
|
|
11684
|
+
periods back.
|
|
11685
|
+
|
|
11686
|
+
⚠️ A period that has not begun for the player is refused, even when it has
|
|
11687
|
+
already begun for players in time zones ahead of theirs.
|
|
11688
|
+
|
|
11689
|
+
## PeriodOptions.playerId
|
|
11690
|
+
|
|
11691
|
+
[PeriodOptions.playerId](https://gemarcade.com/developer/api/game#periodoptions-playerid)
|
|
11692
|
+
|
|
11693
|
+
```ts
|
|
11694
|
+
readonly playerId?: string
|
|
11695
|
+
```
|
|
11696
|
+
|
|
11697
|
+
For a serverless function or a dedicated server: the player whose period
|
|
11698
|
+
to answer for. Their credential names no player, so without this a
|
|
11699
|
+
`per_period` board on each player's own time zone is answered in UTC,
|
|
11700
|
+
which is not that player's day.
|
|
11701
|
+
|
|
11702
|
+
Ignored in the browser, where the read is always for the signed-in player.
|
|
11703
|
+
|
|
11704
|
+
## EntityLeaderboardOptions.periodsBack
|
|
11705
|
+
|
|
11706
|
+
[EntityLeaderboardOptions.periodsBack](https://gemarcade.com/developer/api/game#entityleaderboardoptions-periodsback)
|
|
11707
|
+
|
|
11708
|
+
```ts
|
|
11709
|
+
readonly periodsBack?: number
|
|
11710
|
+
```
|
|
11711
|
+
|
|
11712
|
+
How many periods back to read. `0` — the default — is the current period;
|
|
11713
|
+
`1` is yesterday's board for a daily challenge, last week's for a weekly.
|
|
11714
|
+
|
|
11715
|
+
An integer from 0 to 400. Anything else is a `TypeError` before the
|
|
11716
|
+
request is made.
|
|
11717
|
+
|
|
11718
|
+
## EntityLeaderboardOptions.period
|
|
11719
|
+
|
|
11720
|
+
[EntityLeaderboardOptions.period](https://gemarcade.com/developer/api/game#entityleaderboardoptions-period)
|
|
11721
|
+
|
|
11722
|
+
```ts
|
|
11723
|
+
readonly period?: string
|
|
11724
|
+
```
|
|
11725
|
+
|
|
11726
|
+
The period to read, as an earlier result's [LeaderboardPeriod.id](https://gemarcade.com/developer/api/game#leaderboardperiod-id) —
|
|
11727
|
+
for a board reached from a shared link or a history screen. At most 400
|
|
11728
|
+
periods back.
|
|
11729
|
+
|
|
11730
|
+
⚠️ A period that has not begun for the player is refused, even when it has
|
|
11731
|
+
already begun for players in time zones ahead of theirs.
|
|
11732
|
+
|
|
11733
|
+
## EntityLeaderboardOptions.playerId
|
|
11734
|
+
|
|
11735
|
+
[EntityLeaderboardOptions.playerId](https://gemarcade.com/developer/api/game#entityleaderboardoptions-playerid)
|
|
11736
|
+
|
|
11737
|
+
```ts
|
|
11738
|
+
readonly playerId?: string
|
|
11739
|
+
```
|
|
11740
|
+
|
|
11741
|
+
For a serverless function or a dedicated server: the player whose period
|
|
11742
|
+
to answer for. Their credential names no player, so without this a
|
|
11743
|
+
`per_period` board on each player's own time zone is answered in UTC,
|
|
11744
|
+
which is not that player's day.
|
|
11745
|
+
|
|
11746
|
+
Ignored in the browser, where the read is always for the signed-in player.
|
|
11747
|
+
|
|
11464
11748
|
## EntityLeaderboardOptions.bucket1
|
|
11465
11749
|
|
|
11466
11750
|
[EntityLeaderboardOptions.bucket1](https://gemarcade.com/developer/api/game#entityleaderboardoptions-bucket1)
|
|
@@ -11507,6 +11791,50 @@ readonly signal?: AbortSignal
|
|
|
11507
11791
|
|
|
11508
11792
|
Abort the read.
|
|
11509
11793
|
|
|
11794
|
+
## GetLeaderboardOptions.periodsBack
|
|
11795
|
+
|
|
11796
|
+
[GetLeaderboardOptions.periodsBack](https://gemarcade.com/developer/api/game#getleaderboardoptions-periodsback)
|
|
11797
|
+
|
|
11798
|
+
```ts
|
|
11799
|
+
readonly periodsBack?: number
|
|
11800
|
+
```
|
|
11801
|
+
|
|
11802
|
+
How many periods back to read. `0` — the default — is the current period;
|
|
11803
|
+
`1` is yesterday's board for a daily challenge, last week's for a weekly.
|
|
11804
|
+
|
|
11805
|
+
An integer from 0 to 400. Anything else is a `TypeError` before the
|
|
11806
|
+
request is made.
|
|
11807
|
+
|
|
11808
|
+
## GetLeaderboardOptions.period
|
|
11809
|
+
|
|
11810
|
+
[GetLeaderboardOptions.period](https://gemarcade.com/developer/api/game#getleaderboardoptions-period)
|
|
11811
|
+
|
|
11812
|
+
```ts
|
|
11813
|
+
readonly period?: string
|
|
11814
|
+
```
|
|
11815
|
+
|
|
11816
|
+
The period to read, as an earlier result's [LeaderboardPeriod.id](https://gemarcade.com/developer/api/game#leaderboardperiod-id) —
|
|
11817
|
+
for a board reached from a shared link or a history screen. At most 400
|
|
11818
|
+
periods back.
|
|
11819
|
+
|
|
11820
|
+
⚠️ A period that has not begun for the player is refused, even when it has
|
|
11821
|
+
already begun for players in time zones ahead of theirs.
|
|
11822
|
+
|
|
11823
|
+
## GetLeaderboardOptions.playerId
|
|
11824
|
+
|
|
11825
|
+
[GetLeaderboardOptions.playerId](https://gemarcade.com/developer/api/game#getleaderboardoptions-playerid)
|
|
11826
|
+
|
|
11827
|
+
```ts
|
|
11828
|
+
readonly playerId?: string
|
|
11829
|
+
```
|
|
11830
|
+
|
|
11831
|
+
For a serverless function or a dedicated server: the player whose period
|
|
11832
|
+
to answer for. Their credential names no player, so without this a
|
|
11833
|
+
`per_period` board on each player's own time zone is answered in UTC,
|
|
11834
|
+
which is not that player's day.
|
|
11835
|
+
|
|
11836
|
+
Ignored in the browser, where the read is always for the signed-in player.
|
|
11837
|
+
|
|
11510
11838
|
## GetLeaderboardOptions.bucket1
|
|
11511
11839
|
|
|
11512
11840
|
[GetLeaderboardOptions.bucket1](https://gemarcade.com/developer/api/game#getleaderboardoptions-bucket1)
|
|
@@ -11554,14 +11882,28 @@ A bucketed board (config `bucket_by`) needs exactly its bucket values —
|
|
|
11554
11882
|
faster than the result's `updateFrequencySeconds`; the server regenerates
|
|
11555
11883
|
at that cadence and faster polling re-reads the same rendering.
|
|
11556
11884
|
|
|
11885
|
+
A `per_period` board answers for one period — the current one by default:
|
|
11886
|
+
|
|
11887
|
+
```js
|
|
11888
|
+
const today = await gem.leaderboards.get('daily');
|
|
11889
|
+
const yesterday = await gem.leaderboards.get('daily', { periodsBack: 1 });
|
|
11890
|
+
label(today.period.final ? 'Final standings' : 'Standings so far');
|
|
11891
|
+
```
|
|
11892
|
+
|
|
11557
11893
|
| Parameter | Type | Description |
|
|
11558
11894
|
| --- | --- | --- |
|
|
11559
11895
|
| `leaderboardType` | `string` | The board's id in your game config. |
|
|
11560
11896
|
| `options` | `GetLeaderboardOptions` | |
|
|
11561
11897
|
|
|
11562
|
-
**Throws.** `
|
|
11898
|
+
**Throws.** `TypeError` when `periodsBack` is not an integer from 0 to 400,
|
|
11899
|
+
`period` is not a period id, or both are passed — refused before the
|
|
11900
|
+
request.
|
|
11901
|
+
|
|
11902
|
+
`not_found` when no board with this id is in the channel's active
|
|
11563
11903
|
config, `invalid` when bucket values do not match the board's
|
|
11564
|
-
`bucket_by
|
|
11904
|
+
`bucket_by`, when a period is asked of a board that is not `per_period`
|
|
11905
|
+
(`code` `invalid_period`), or when the period has not begun for the
|
|
11906
|
+
player (`code` `period_not_begun`).
|
|
11565
11907
|
|
|
11566
11908
|
## LeaderboardsApi.friends
|
|
11567
11909
|
|
|
@@ -11592,16 +11934,20 @@ for (const row of board.entries) {
|
|
|
11592
11934
|
}
|
|
11593
11935
|
```
|
|
11594
11936
|
|
|
11937
|
+
On a `per_period` board this takes the same `periodsBack` and `period` as
|
|
11938
|
+
`get`. A friend in another time zone who is on the same date is on
|
|
11939
|
+
the same board.
|
|
11940
|
+
|
|
11595
11941
|
| Parameter | Type |
|
|
11596
11942
|
| --- | --- |
|
|
11597
11943
|
| `leaderboardType` | `string` |
|
|
11598
11944
|
| `options` | `GetLeaderboardOptions` |
|
|
11599
11945
|
|
|
11600
11946
|
**Throws.** `not_found` when no board with this id is in the channel's active
|
|
11601
|
-
config, `invalid` when bucket values do not match the board
|
|
11602
|
-
`
|
|
11603
|
-
view is a player surface, and a game server has no friends. (The
|
|
11604
|
-
`get` declares no such refusal: it needs no viewer.)
|
|
11947
|
+
config, `invalid` when bucket values or a period do not match the board
|
|
11948
|
+
(as on `get`), and `forbidden` in a context with no player — the
|
|
11949
|
+
friend view is a player surface, and a game server has no friends. (The
|
|
11950
|
+
global `get` declares no such refusal: it needs no viewer.)
|
|
11605
11951
|
|
|
11606
11952
|
## LeaderboardsApi.mine
|
|
11607
11953
|
|
|
@@ -11637,6 +11983,11 @@ a `200` with no entries, not an error. If it is *always* empty, see
|
|
|
11637
11983
|
[LeaderboardsApi](https://gemarcade.com/developer/api/game#leaderboardsapi) on where runs come from: a browser cannot submit
|
|
11638
11984
|
one.
|
|
11639
11985
|
|
|
11986
|
+
On a `per_period` board the runs, the personal best and the total are ONE
|
|
11987
|
+
period's — the current one unless `periodsBack` or `period` names another
|
|
11988
|
+
— so `personalBest` is "your best today", and an empty result at the start
|
|
11989
|
+
of a day is the ordinary state.
|
|
11990
|
+
|
|
11640
11991
|
| Parameter | Type |
|
|
11641
11992
|
| --- | --- |
|
|
11642
11993
|
| `leaderboardType` | `string` |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The server surface — API reference
|
|
2
2
|
|
|
3
|
-
Generated from `@indiegems/gem-web-sdk/sdk` v7.
|
|
3
|
+
Generated from `@indiegems/gem-web-sdk/sdk` v7.7.0. Every symbol below links to its page on the Gem Arcade developer site.
|
|
4
4
|
|
|
5
5
|
`@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/server` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
|
|
6
6
|
|