@indiegems/gem-web-sdk 9.1.4 → 10.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 +13 -0
- package/dist/function.d.ts +1 -1
- package/dist/game.d.ts +72 -21
- package/dist/gem-web-sdk.esm.js +2 -2
- package/dist/gem-web-sdk.function.js +2 -2
- 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.js +1 -1
- package/dist/index.d.ts +71 -23
- package/dist/sdk.d.ts +72 -21
- package/docs/api/api-reference-game.md +281 -1
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +274 -1
- package/docs/changelog.md +13 -0
- package/docs/daily-challenges.md +123 -1
- package/docs/getting-started.md +1 -1
- package/docs/manifest.json +10 -10
- package/docs/rooms-and-matches.md +128 -4
- package/docs/server-bundles.md +2 -2
- package/package.json +1 -1
package/dist/sdk.d.ts
CHANGED
|
@@ -157,6 +157,11 @@ type AffixSelection = {
|
|
|
157
157
|
"pool": AffixPoolRef;
|
|
158
158
|
"respect_groups"?: boolean;
|
|
159
159
|
};
|
|
160
|
+
type BackfillPolicy = "fill_existing_first" | "prefer_new_match";
|
|
161
|
+
type BackfillSettings = {
|
|
162
|
+
"enabled": boolean;
|
|
163
|
+
"policy"?: BackfillPolicy;
|
|
164
|
+
};
|
|
160
165
|
type Boundary = {
|
|
161
166
|
"boundary"?: string;
|
|
162
167
|
"reset_time"?: string;
|
|
@@ -230,11 +235,20 @@ type LevelDefinition = {
|
|
|
230
235
|
"rewards"?: RecipeOperation[];
|
|
231
236
|
"threshold": number;
|
|
232
237
|
};
|
|
238
|
+
type MatchmakingSettings = {
|
|
239
|
+
"backfill"?: null | BackfillSettings;
|
|
240
|
+
"cluster_stagger_seconds"?: number;
|
|
241
|
+
"enabled": boolean;
|
|
242
|
+
"fill_window_seconds"?: number;
|
|
243
|
+
"strategy"?: MatchmakingStrategy;
|
|
244
|
+
"ticket_expiry_seconds"?: number | null;
|
|
245
|
+
};
|
|
246
|
+
type MatchmakingStrategy = "fifo";
|
|
233
247
|
type OrderBySpec = {
|
|
234
248
|
"column": RunValueColumn;
|
|
235
249
|
"direction": SortDirection;
|
|
236
250
|
};
|
|
237
|
-
type OrderSource$1 = "real_money_purchase" | "real_money_refund" | "full_game_purchase" | "full_game_refund" | "platform_purchase" | "reward" | "admin" | "system" | "promo" | "game_consume" | "play" | "recipe" | "transfer" | "platform_funded_game_inventory_purchase" | "earning_reset";
|
|
251
|
+
type OrderSource$1 = "real_money_purchase" | "real_money_refund" | "full_game_purchase" | "full_game_refund" | "platform_purchase" | "reward" | "admin" | "system" | "promo" | "game_consume" | "play" | "recipe" | "transfer" | "platform_funded_game_inventory_purchase" | "earning_reset" | "test_account_provision" | "developer_grant";
|
|
238
252
|
type OverflowBehavior$1 = "fail" | "clamp" | "allow";
|
|
239
253
|
type PityEffect = "guarantee_tier" | {
|
|
240
254
|
"weight_boost": {
|
|
@@ -452,6 +466,7 @@ type SnapshotGameRoomTemplate = {
|
|
|
452
466
|
"id": string;
|
|
453
467
|
"idle_timeout_seconds"?: number | null;
|
|
454
468
|
"match_type": string;
|
|
469
|
+
"matchmaking"?: null | MatchmakingSettings;
|
|
455
470
|
"max_match_duration_seconds"?: number | null;
|
|
456
471
|
"max_players": number;
|
|
457
472
|
"min_players": number;
|
|
@@ -523,6 +538,7 @@ type SnapshotProgression = {
|
|
|
523
538
|
"display_name"?: string | null;
|
|
524
539
|
"icon_url"?: string | null;
|
|
525
540
|
"id": string;
|
|
541
|
+
"localized"?: Record<string, unknown>;
|
|
526
542
|
"progression_type": string;
|
|
527
543
|
"slug"?: string | null;
|
|
528
544
|
"sort_order": number;
|
|
@@ -560,6 +576,7 @@ type SnapshotRewardedPlacement = {
|
|
|
560
576
|
"grants": SnapshotRewardGrant[];
|
|
561
577
|
"max_held"?: number | null;
|
|
562
578
|
"max_per_day"?: number | null;
|
|
579
|
+
"min_watch_secs"?: number | null;
|
|
563
580
|
"placement": string;
|
|
564
581
|
"reward_class": string;
|
|
565
582
|
"without_ads": string;
|
|
@@ -1524,26 +1541,6 @@ interface ClusterTarget {
|
|
|
1524
1541
|
readonly id: string;
|
|
1525
1542
|
readonly pressure: string;
|
|
1526
1543
|
}
|
|
1527
|
-
type RoomArgScalar = string | number | boolean;
|
|
1528
|
-
type RoomArgValue$1 = RoomArgScalar | readonly RoomArgScalar[];
|
|
1529
|
-
type RoomArgs = Readonly<Record<string, RoomArgValue$1>>;
|
|
1530
|
-
type RoomArgType$1 = "string" | "int" | "float" | "bool" | (string & {});
|
|
1531
|
-
interface RoomArgEntry {
|
|
1532
|
-
readonly name: string;
|
|
1533
|
-
readonly type: RoomArgType$1;
|
|
1534
|
-
readonly list: boolean;
|
|
1535
|
-
readonly required: boolean;
|
|
1536
|
-
readonly mutable: boolean;
|
|
1537
|
-
readonly fixed?: RoomArgValue$1;
|
|
1538
|
-
readonly default?: RoomArgValue$1;
|
|
1539
|
-
readonly description?: string;
|
|
1540
|
-
readonly allowed?: readonly RoomArgScalar[];
|
|
1541
|
-
readonly min?: number;
|
|
1542
|
-
readonly max?: number;
|
|
1543
|
-
readonly minItems?: number;
|
|
1544
|
-
readonly maxItems?: number;
|
|
1545
|
-
readonly maxLength?: number;
|
|
1546
|
-
}
|
|
1547
1544
|
type DedicatedServerFailure = "timeout" | "aborted" | "allocation_failed" | "no_server_ready" | "start_rate_limited" | "p2p_unavailable" | "unsupported_protocol" | "credential_expired" | "credential_reused" | "join_rate_limited" | "signaling_unavailable" | "signaling_failed" | "offer_refused" | "invalid_sdp" | "media_refused" | "connection_failed" | "join_refused" | "match_ended" | "misconfigured";
|
|
1548
1545
|
declare class DedicatedServerError extends Error {
|
|
1549
1546
|
readonly reason: DedicatedServerFailure;
|
|
@@ -1652,6 +1649,26 @@ interface TransportAdvert {
|
|
|
1652
1649
|
declare function readTemplateTransports(value: unknown): readonly TransportKind[] | null;
|
|
1653
1650
|
declare function readTransportAdvert(settings: unknown, forMatch?: string): TransportAdvert | null;
|
|
1654
1651
|
declare function webTransportAvailable(): boolean;
|
|
1652
|
+
type RoomArgScalar = string | number | boolean;
|
|
1653
|
+
type RoomArgValue$1 = RoomArgScalar | readonly RoomArgScalar[];
|
|
1654
|
+
type RoomArgs = Readonly<Record<string, RoomArgValue$1>>;
|
|
1655
|
+
type RoomArgType$1 = "string" | "int" | "float" | "bool" | (string & {});
|
|
1656
|
+
interface RoomArgEntry {
|
|
1657
|
+
readonly name: string;
|
|
1658
|
+
readonly type: RoomArgType$1;
|
|
1659
|
+
readonly list: boolean;
|
|
1660
|
+
readonly required: boolean;
|
|
1661
|
+
readonly mutable: boolean;
|
|
1662
|
+
readonly fixed?: RoomArgValue$1;
|
|
1663
|
+
readonly default?: RoomArgValue$1;
|
|
1664
|
+
readonly description?: string;
|
|
1665
|
+
readonly allowed?: readonly RoomArgScalar[];
|
|
1666
|
+
readonly min?: number;
|
|
1667
|
+
readonly max?: number;
|
|
1668
|
+
readonly minItems?: number;
|
|
1669
|
+
readonly maxItems?: number;
|
|
1670
|
+
readonly maxLength?: number;
|
|
1671
|
+
}
|
|
1655
1672
|
type RoomStatus = "open" | "in_game" | "closed" | (string & {});
|
|
1656
1673
|
type MatchConnectionState = "disconnected" | "connecting" | "connected" | "suspended";
|
|
1657
1674
|
type MatchSessionPhase = "none" | "starting" | "ready" | "connected" | "suspended" | "ended" | (string & {});
|
|
@@ -1749,6 +1766,38 @@ interface RoomOperationError {
|
|
|
1749
1766
|
readonly message: string;
|
|
1750
1767
|
readonly retryable: boolean;
|
|
1751
1768
|
}
|
|
1769
|
+
interface QueueForMatchOptions {
|
|
1770
|
+
readonly templateSlugs: readonly string[];
|
|
1771
|
+
readonly partyId?: string;
|
|
1772
|
+
readonly signal?: AbortSignal;
|
|
1773
|
+
}
|
|
1774
|
+
type MatchTicketStatus = "queued" | "matched" | "expired" | "cancelled" | "failed" | "lost" | "unavailable";
|
|
1775
|
+
type MatchTicketOutcome = {
|
|
1776
|
+
readonly status: "matched";
|
|
1777
|
+
readonly room: Room;
|
|
1778
|
+
} | {
|
|
1779
|
+
readonly status: "expired";
|
|
1780
|
+
readonly reason: string;
|
|
1781
|
+
} | {
|
|
1782
|
+
readonly status: "cancelled";
|
|
1783
|
+
readonly reason: string;
|
|
1784
|
+
} | {
|
|
1785
|
+
readonly status: "failed";
|
|
1786
|
+
readonly reason: string;
|
|
1787
|
+
} | {
|
|
1788
|
+
readonly status: "lost";
|
|
1789
|
+
} | {
|
|
1790
|
+
readonly status: "unavailable";
|
|
1791
|
+
};
|
|
1792
|
+
interface MatchTicket {
|
|
1793
|
+
readonly id: string;
|
|
1794
|
+
readonly status: MatchTicketStatus;
|
|
1795
|
+
readonly partySize: number;
|
|
1796
|
+
readonly queuedAt: number;
|
|
1797
|
+
readonly expiresAt: number;
|
|
1798
|
+
readonly outcome: Promise<MatchTicketOutcome>;
|
|
1799
|
+
cancel(): Promise<MatchTicketOutcome>;
|
|
1800
|
+
}
|
|
1752
1801
|
interface CreateRoomOptions {
|
|
1753
1802
|
readonly name: string;
|
|
1754
1803
|
readonly maxPlayers?: number;
|
|
@@ -1891,6 +1940,7 @@ interface RoomManager {
|
|
|
1891
1940
|
join(roomId: string, options?: JoinRoomOptions): Promise<Room>;
|
|
1892
1941
|
joinByCode(code: string, options?: JoinRoomOptions): Promise<Room>;
|
|
1893
1942
|
quickJoin(options: QuickJoinOptions): Promise<Room>;
|
|
1943
|
+
queueForMatch(options: QueueForMatchOptions): Promise<MatchTicket>;
|
|
1894
1944
|
list(options?: ListRoomsOptions): Promise<RoomPage>;
|
|
1895
1945
|
myRooms(signal?: AbortSignal): Promise<readonly RoomSummary[]>;
|
|
1896
1946
|
leave(options?: {
|
|
@@ -1916,6 +1966,7 @@ interface RoomManager {
|
|
|
1916
1966
|
}): Promise<void>;
|
|
1917
1967
|
readonly gameId: string | null;
|
|
1918
1968
|
readonly currentRoom: Room | null;
|
|
1969
|
+
readonly currentTicket: MatchTicket | null;
|
|
1919
1970
|
readonly currentMatch: ReadyMatch | null;
|
|
1920
1971
|
readonly matchConnectionState: MatchConnectionState;
|
|
1921
1972
|
readonly matchSession: MatchSession;
|
|
@@ -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` v10.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
|
|
|
@@ -14668,6 +14668,58 @@ session — [RoomManager.leaveAll](#roommanager-leaveall) is what clears those.
|
|
|
14668
14668
|
|
|
14669
14669
|
**Returns.** The room joined or created.
|
|
14670
14670
|
|
|
14671
|
+
<a id="roommanager-queueformatch"></a>
|
|
14672
|
+
|
|
14673
|
+
## RoomManager.queueForMatch
|
|
14674
|
+
|
|
14675
|
+
```ts
|
|
14676
|
+
queueForMatch(options: QueueForMatchOptions): Promise<MatchTicket>
|
|
14677
|
+
```
|
|
14678
|
+
|
|
14679
|
+
Queue for a match with other players, and get a ticket to wait on.
|
|
14680
|
+
|
|
14681
|
+
FOR A MODE THAT NEEDS A FULL LOBBY BEFORE IT STARTS. The platform holds the
|
|
14682
|
+
player in a queue until it has enough players for one of the templates you
|
|
14683
|
+
named, then makes the room, seats everyone and starts the match — nobody
|
|
14684
|
+
hosts and nobody presses start. For a drop-in mode, where a player should
|
|
14685
|
+
be in a room at once and others join around them, use
|
|
14686
|
+
[RoomManager.quickJoin](#roommanager-quickjoin) instead.
|
|
14687
|
+
|
|
14688
|
+
This call answers as soon as the player is queued. What happens next is on
|
|
14689
|
+
the ticket: await [MatchTicket.outcome](#matchticket-outcome), and when it says `matched`
|
|
14690
|
+
this manager is already in the room — `joined` has fired and the match
|
|
14691
|
+
events follow as for any other room.
|
|
14692
|
+
|
|
14693
|
+
A PLAYER MAY QUEUE FROM INSIDE A ROOM — a hub, or a social lobby they wait
|
|
14694
|
+
in. When the ticket is matched the manager moves to the match's room:
|
|
14695
|
+
`currentRoom` becomes it and `joined` fires. The seat in the room they
|
|
14696
|
+
queued from is kept on the platform, not given up, so when the match is
|
|
14697
|
+
over `join()` with that room's id puts them back in it. If the tab closes
|
|
14698
|
+
before they go back, the SDK leaves both rooms.
|
|
14699
|
+
|
|
14700
|
+
What it does refuse is a second thing in flight: while a ticket waits,
|
|
14701
|
+
`create`, `join`, `joinByCode`, `quickJoin` and another `queueForMatch`
|
|
14702
|
+
refuse until it ends or is cancelled.
|
|
14703
|
+
|
|
14704
|
+
CLOSING THE TAB CANCELS THE TICKET. The SDK sends the cancel as the page
|
|
14705
|
+
goes away, so a player who left is not matched into a lobby they will
|
|
14706
|
+
never arrive in.
|
|
14707
|
+
|
|
14708
|
+
| Parameter | Type | Description |
|
|
14709
|
+
| --- | --- | --- |
|
|
14710
|
+
| `options` | `QueueForMatchOptions` | The templates the player accepts. |
|
|
14711
|
+
|
|
14712
|
+
**Returns.** The ticket, still `queued` unless a lobby was waiting for exactly
|
|
14713
|
+
this player.
|
|
14714
|
+
|
|
14715
|
+
**Throws.** `GemApiError` when the platform refuses the ticket. Two refusals
|
|
14716
|
+
are worth their own branch, by [GemApiError.code](#gemapierror-code):
|
|
14717
|
+
`already_queued` — this player, or someone in their party, is already
|
|
14718
|
+
on a ticket, possibly in another tab or another game — and
|
|
14719
|
+
`matchmaking_unavailable`, which means matchmaking is turned off or not
|
|
14720
|
+
answering. Tell the player; do not loop on it, and do not quietly
|
|
14721
|
+
substitute `quickJoin`, which puts them in a different kind of room.
|
|
14722
|
+
|
|
14671
14723
|
<a id="roommanager-list"></a>
|
|
14672
14724
|
|
|
14673
14725
|
## RoomManager.list
|
|
@@ -15002,6 +15054,20 @@ The room this player is in, or `null`. Kept fresh for you.
|
|
|
15002
15054
|
Read it whenever you render the lobby rather than caching it — the manager
|
|
15003
15055
|
updates it as players join, ready up and leave, and emits events as it does.
|
|
15004
15056
|
|
|
15057
|
+
<a id="roommanager-currentticket"></a>
|
|
15058
|
+
|
|
15059
|
+
## RoomManager.currentTicket
|
|
15060
|
+
|
|
15061
|
+
```ts
|
|
15062
|
+
readonly currentTicket: MatchTicket | null
|
|
15063
|
+
```
|
|
15064
|
+
|
|
15065
|
+
The matchmaking ticket this player is waiting on, or `null`.
|
|
15066
|
+
|
|
15067
|
+
Set from the moment [RoomManager.queueForMatch](#roommanager-queueformatch) answers until the
|
|
15068
|
+
ticket ends — so it is `null` again by the time a matched ticket's room is
|
|
15069
|
+
[RoomManager.currentRoom](#roommanager-currentroom).
|
|
15070
|
+
|
|
15005
15071
|
<a id="roommanager-currentmatch"></a>
|
|
15006
15072
|
|
|
15007
15073
|
## RoomManager.currentMatch
|
|
@@ -15212,6 +15278,220 @@ Stop polling and drop every listener.
|
|
|
15212
15278
|
Call this when tearing your game down. It does not leave the room — use
|
|
15213
15279
|
[RoomManager.leave](#roommanager-leave) or `gem.exit()` for that.
|
|
15214
15280
|
|
|
15281
|
+
<a id="queueformatchoptions"></a>
|
|
15282
|
+
|
|
15283
|
+
## QueueForMatchOptions
|
|
15284
|
+
|
|
15285
|
+
```ts
|
|
15286
|
+
interface QueueForMatchOptions
|
|
15287
|
+
```
|
|
15288
|
+
|
|
15289
|
+
What you pass to `gem.rooms.queueForMatch(...)`.
|
|
15290
|
+
|
|
15291
|
+
NAME EVERY MODE THE PLAYER WILL ACCEPT. The ticket waits for all of them at
|
|
15292
|
+
once and is matched under whichever fills first, so "any mode" is one ticket
|
|
15293
|
+
naming several templates rather than several tickets — a player can only be
|
|
15294
|
+
on one.
|
|
15295
|
+
|
|
15296
|
+
```js
|
|
15297
|
+
const ticket = await gem.rooms.queueForMatch({ templateSlugs: ['duel', 'brawl'] });
|
|
15298
|
+
```
|
|
15299
|
+
|
|
15300
|
+
**Guides.** [rooms-and-matches](../rooms-and-matches.md)
|
|
15301
|
+
|
|
15302
|
+
<a id="queueformatchoptions-templateslugs"></a>
|
|
15303
|
+
|
|
15304
|
+
## QueueForMatchOptions.templateSlugs
|
|
15305
|
+
|
|
15306
|
+
```ts
|
|
15307
|
+
readonly templateSlugs: readonly string[]
|
|
15308
|
+
```
|
|
15309
|
+
|
|
15310
|
+
The room templates this player accepts, by slug — one to eight of them.
|
|
15311
|
+
|
|
15312
|
+
EVERY ONE MUST HAVE MATCHMAKING TURNED ON in your game config. A template
|
|
15313
|
+
without it refuses the whole ticket rather than being skipped, so a typo
|
|
15314
|
+
is an error you see and not a mode nobody is ever matched into.
|
|
15315
|
+
|
|
15316
|
+
<a id="queueformatchoptions-partyid"></a>
|
|
15317
|
+
|
|
15318
|
+
## QueueForMatchOptions.partyId
|
|
15319
|
+
|
|
15320
|
+
```ts
|
|
15321
|
+
readonly partyId?: string
|
|
15322
|
+
```
|
|
15323
|
+
|
|
15324
|
+
A party to queue as one unit. Normally omit it — the SDK brings the
|
|
15325
|
+
player's party along when they lead one, exactly as a room call does.
|
|
15326
|
+
|
|
15327
|
+
A party is seated together or not at all. If it gains or loses a member
|
|
15328
|
+
while it waits, the ticket ends `cancelled` with reason `party_changed`.
|
|
15329
|
+
|
|
15330
|
+
<a id="queueformatchoptions-signal"></a>
|
|
15331
|
+
|
|
15332
|
+
## QueueForMatchOptions.signal
|
|
15333
|
+
|
|
15334
|
+
```ts
|
|
15335
|
+
readonly signal?: AbortSignal
|
|
15336
|
+
```
|
|
15337
|
+
|
|
15338
|
+
Cancel the request that creates the ticket.
|
|
15339
|
+
|
|
15340
|
+
Only that request. Once you hold a ticket, [MatchTicket.cancel](#matchticket-cancel) is
|
|
15341
|
+
what takes the player out of the queue.
|
|
15342
|
+
|
|
15343
|
+
<a id="matchticketstatus"></a>
|
|
15344
|
+
|
|
15345
|
+
## MatchTicketStatus
|
|
15346
|
+
|
|
15347
|
+
```ts
|
|
15348
|
+
type MatchTicketStatus = "queued" | "matched" | "expired" | "cancelled" | "failed" | "lost" | "unavailable"
|
|
15349
|
+
```
|
|
15350
|
+
|
|
15351
|
+
Where a ticket is: `queued` while it waits, and anything else for good.
|
|
15352
|
+
|
|
15353
|
+
- `matched` — the player is seated and the match is starting.
|
|
15354
|
+
- `expired` — it waited too long, or stopped being kept alive.
|
|
15355
|
+
- `cancelled` — the player backed out, or their party changed.
|
|
15356
|
+
- `failed` — the platform formed a match and could not start it, repeatedly.
|
|
15357
|
+
- `lost` — the platform no longer has the ticket. Queue again.
|
|
15358
|
+
- `unavailable` — matchmaking is turned off or not answering.
|
|
15359
|
+
|
|
15360
|
+
<a id="matchticketoutcome"></a>
|
|
15361
|
+
|
|
15362
|
+
## MatchTicketOutcome
|
|
15363
|
+
|
|
15364
|
+
```ts
|
|
15365
|
+
type MatchTicketOutcome = { status: "matched"; room: Room } | { status: "expired"; reason: string } | { status: "cancelled"; reason: string } | { status: "failed"; reason: string } | { status: "lost" } | { status: "unavailable" }
|
|
15366
|
+
```
|
|
15367
|
+
|
|
15368
|
+
How a ticket ended. Branch on `status`.
|
|
15369
|
+
|
|
15370
|
+
ONLY `matched` CARRIES A ROOM, and by the time you see it the SDK is already
|
|
15371
|
+
in that room: `gem.rooms.currentRoom` is it, `joined` has fired, and the
|
|
15372
|
+
match events follow as they do for any other room.
|
|
15373
|
+
|
|
15374
|
+
Every other ending leaves the player in no room and on no ticket, free to
|
|
15375
|
+
queue again. None of them is retried for you, and nothing falls back to
|
|
15376
|
+
`quickJoin` — a game that wants either does it on purpose.
|
|
15377
|
+
|
|
15378
|
+
`reason` says why, where the platform gave one: `timed_out` or
|
|
15379
|
+
`heartbeat_lapsed` for `expired`, `requested` or `party_changed` for
|
|
15380
|
+
`cancelled`, `handoff_failed` for `failed`. Treat a value you do not
|
|
15381
|
+
recognise as the status alone.
|
|
15382
|
+
|
|
15383
|
+
<a id="matchticket"></a>
|
|
15384
|
+
|
|
15385
|
+
## MatchTicket
|
|
15386
|
+
|
|
15387
|
+
```ts
|
|
15388
|
+
interface MatchTicket
|
|
15389
|
+
```
|
|
15390
|
+
|
|
15391
|
+
A place in the matchmaking queue — what `gem.rooms.queueForMatch(...)`
|
|
15392
|
+
answers with.
|
|
15393
|
+
|
|
15394
|
+
You do not keep it alive; the SDK does, for as long as it waits. What you do
|
|
15395
|
+
with it is wait for [MatchTicket.outcome](#matchticket-outcome), and offer the player a
|
|
15396
|
+
button that calls [MatchTicket.cancel](#matchticket-cancel).
|
|
15397
|
+
|
|
15398
|
+
```js
|
|
15399
|
+
const ticket = await gem.rooms.queueForMatch({ templateSlugs: ['duel'] });
|
|
15400
|
+
showSearching({ onCancel: () => ticket.cancel() });
|
|
15401
|
+
|
|
15402
|
+
const outcome = await ticket.outcome;
|
|
15403
|
+
if (outcome.status === 'matched') enterMatch(outcome.room);
|
|
15404
|
+
else backToMenu(outcome.status);
|
|
15405
|
+
```
|
|
15406
|
+
|
|
15407
|
+
**Guides.** [rooms-and-matches](../rooms-and-matches.md)
|
|
15408
|
+
|
|
15409
|
+
<a id="matchticket-id"></a>
|
|
15410
|
+
|
|
15411
|
+
## MatchTicket.id
|
|
15412
|
+
|
|
15413
|
+
```ts
|
|
15414
|
+
readonly id: string
|
|
15415
|
+
```
|
|
15416
|
+
|
|
15417
|
+
The ticket's id. For logs and bug reports; nothing you call takes it.
|
|
15418
|
+
|
|
15419
|
+
<a id="matchticket-status"></a>
|
|
15420
|
+
|
|
15421
|
+
## MatchTicket.status
|
|
15422
|
+
|
|
15423
|
+
```ts
|
|
15424
|
+
readonly status: MatchTicketStatus
|
|
15425
|
+
```
|
|
15426
|
+
|
|
15427
|
+
Where the ticket is right now. Changes once, from `queued` to how it ended.
|
|
15428
|
+
|
|
15429
|
+
<a id="matchticket-partysize"></a>
|
|
15430
|
+
|
|
15431
|
+
## MatchTicket.partySize
|
|
15432
|
+
|
|
15433
|
+
```ts
|
|
15434
|
+
readonly partySize: number
|
|
15435
|
+
```
|
|
15436
|
+
|
|
15437
|
+
How many players the ticket seats: 1, or the size of the party.
|
|
15438
|
+
|
|
15439
|
+
<a id="matchticket-queuedat"></a>
|
|
15440
|
+
|
|
15441
|
+
## MatchTicket.queuedAt
|
|
15442
|
+
|
|
15443
|
+
```ts
|
|
15444
|
+
readonly queuedAt: number
|
|
15445
|
+
```
|
|
15446
|
+
|
|
15447
|
+
When the ticket joined the queue, in Unix seconds.
|
|
15448
|
+
|
|
15449
|
+
<a id="matchticket-expiresat"></a>
|
|
15450
|
+
|
|
15451
|
+
## MatchTicket.expiresAt
|
|
15452
|
+
|
|
15453
|
+
```ts
|
|
15454
|
+
readonly expiresAt: number
|
|
15455
|
+
```
|
|
15456
|
+
|
|
15457
|
+
When the ticket gives up if it is still waiting, in Unix seconds. Good for
|
|
15458
|
+
a countdown; the platform decides the length, per template.
|
|
15459
|
+
|
|
15460
|
+
<a id="matchticket-outcome"></a>
|
|
15461
|
+
|
|
15462
|
+
## MatchTicket.outcome
|
|
15463
|
+
|
|
15464
|
+
```ts
|
|
15465
|
+
readonly outcome: Promise<MatchTicketOutcome>
|
|
15466
|
+
```
|
|
15467
|
+
|
|
15468
|
+
How the ticket ends. Settles exactly once, and RESOLVES for every ending
|
|
15469
|
+
the platform reports — matched, expired, cancelled and the rest are
|
|
15470
|
+
outcomes to branch on, not errors to catch.
|
|
15471
|
+
|
|
15472
|
+
It rejects in one case only: the ticket was matched and the SDK could not
|
|
15473
|
+
read the room it was seated in. The player holds a seat then, so
|
|
15474
|
+
`gem.rooms.myRooms()` shows the room and `gem.rooms.join(id)` enters it.
|
|
15475
|
+
|
|
15476
|
+
<a id="matchticket-cancel"></a>
|
|
15477
|
+
|
|
15478
|
+
## MatchTicket.cancel
|
|
15479
|
+
|
|
15480
|
+
```ts
|
|
15481
|
+
cancel(): Promise<MatchTicketOutcome>
|
|
15482
|
+
```
|
|
15483
|
+
|
|
15484
|
+
Take the player — and their party — out of the queue.
|
|
15485
|
+
|
|
15486
|
+
A CANCEL CAN LOSE THE RACE, and then the answer is `matched`. A ticket the
|
|
15487
|
+
platform has already seated is never undone, so read the outcome this
|
|
15488
|
+
returns rather than assuming: when it says `matched` the player is in a
|
|
15489
|
+
room, and backing out is `gem.rooms.leave()`.
|
|
15490
|
+
|
|
15491
|
+
Safe to call more than once, and after the ticket has ended.
|
|
15492
|
+
|
|
15493
|
+
**Returns.** The same promise as [MatchTicket.outcome](#matchticket-outcome).
|
|
15494
|
+
|
|
15215
15495
|
<a id="roomstatus"></a>
|
|
15216
15496
|
|
|
15217
15497
|
## RoomStatus
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The server surface — API reference
|
|
2
2
|
|
|
3
|
-
Generated from `@indiegems/gem-web-sdk/sdk`
|
|
3
|
+
Generated from `@indiegems/gem-web-sdk/sdk` v10.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/server` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
|
|
6
6
|
|