@indiegems/gem-web-sdk 9.1.4 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/function.d.ts +1 -1
- package/dist/game.d.ts +88 -22
- package/dist/gem-web-sdk.bridge.js +1 -1
- 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 +2 -2
- package/dist/index.d.ts +85 -23
- package/dist/sdk.d.ts +88 -22
- package/docs/api/api-reference-game.md +396 -16
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +395 -5
- package/docs/changelog.md +26 -0
- package/docs/daily-challenges.md +123 -1
- package/docs/getting-started.md +6 -6
- package/docs/manifest.json +14 -14
- package/docs/rooms-and-matches.md +128 -4
- package/docs/server-bundles.md +2 -2
- package/docs/vibration.md +8 -3
- package/docs/what-a-game-must-do.md +103 -25
- package/package.json +1 -1
- package/schema/bridge.v1.json +74 -5
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;
|
|
@@ -1973,6 +2024,13 @@ interface GemPrefs$1 {
|
|
|
1973
2024
|
readonly muted: boolean;
|
|
1974
2025
|
readonly showFrameStats?: boolean;
|
|
1975
2026
|
readonly locale: string;
|
|
2027
|
+
readonly recommended?: {
|
|
2028
|
+
volume: number;
|
|
2029
|
+
batterySaver: boolean;
|
|
2030
|
+
keyboardLayout: "wasd" | "arrows";
|
|
2031
|
+
gamepadConfirm: "south" | "east";
|
|
2032
|
+
vibration: boolean;
|
|
2033
|
+
};
|
|
1976
2034
|
}
|
|
1977
2035
|
interface GemCohorts$1 {
|
|
1978
2036
|
readonly gem: typeof PROTOCOL;
|
|
@@ -4385,6 +4443,14 @@ interface GemPrefs {
|
|
|
4385
4443
|
readonly muted: boolean;
|
|
4386
4444
|
readonly showFrameStats: boolean;
|
|
4387
4445
|
readonly locale: string;
|
|
4446
|
+
readonly recommended: GemRecommendedSettings | null;
|
|
4447
|
+
}
|
|
4448
|
+
interface GemRecommendedSettings {
|
|
4449
|
+
readonly volume: number;
|
|
4450
|
+
readonly batterySaver: boolean;
|
|
4451
|
+
readonly keyboardLayout: "wasd" | "arrows";
|
|
4452
|
+
readonly gamepadConfirm: "south" | "east";
|
|
4453
|
+
readonly vibration: boolean;
|
|
4388
4454
|
}
|
|
4389
4455
|
interface GemCohort {
|
|
4390
4456
|
readonly experimentId: string;
|
|
@@ -4487,4 +4553,4 @@ interface ExitAnalytics {
|
|
|
4487
4553
|
}
|
|
4488
4554
|
declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
|
|
4489
4555
|
declare function createGem(options?: GemOptions): Gem;
|
|
4490
|
-
export { ARCADE_EMBEDDERS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection$1 as AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Base64String, type BootMark, type BootTimeline, type BroadcastOptions, type BytesResponse, CONDITIONAL_HEADERS, type Challenge, type ChallengeWindow, ChallengesApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType$1 as EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameApi, type GameConfig, type GameMenu, type GameMenuItem, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemDevTools, type GemErrorReason, GemFrame, GemFunctionError, type GemIdentity, type GemInsets, type GemMatchApi, type GemMatchServer, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemReservedArea, GemSaveError, type GemServer, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerIdentity, type GemServerLifecycle, type GemServerOptions, type GemServerProfile, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type HostTokenSource, type HostTokenSourceOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MessageMeta, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge$1 as PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry$1 as ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RequestOptions, type RewardCue, type RewardedStatus, type RoomArgValue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerApi, type ServerBundleHost, type ServerTokenGrant, type SessionEndReason, type ShareApi, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SnapshotCurrency, type SnapshotItem, type TokenGrant, type Transport, type TransportAdvert, type TransportKind, TransportRefusal, type TransportRequest, type TransportResponse, UNRELIABLE_CHANNEL_LABEL, type VersionedGetOptions, type VersionedResponse, type VibrationApi, type WalletVisibleOptions, asPlayerText, createBootTimeline, createGem, createGemServer, createHostTokenSource, createMatchServer, defineServer, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, systemClock, text, toBase64, webTransportAvailable };
|
|
4556
|
+
export { ARCADE_EMBEDDERS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection$1 as AnalyticsRejection, type AnalyticsValue, AuthError, type AuthFailure, type AuthState, type Base64String, type BootMark, type BootTimeline, type BroadcastOptions, type BytesResponse, CONDITIONAL_HEADERS, type Challenge, type ChallengeWindow, ChallengesApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType$1 as EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameApi, type GameConfig, type GameMenu, type GameMenuItem, type GameServerLink, type Gem, GemApiError, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemDevTools, type GemErrorReason, GemFrame, GemFunctionError, type GemIdentity, type GemInsets, type GemMatchApi, type GemMatchServer, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServer, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerIdentity, type GemServerLifecycle, type GemServerOptions, type GemServerProfile, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type HostTokenSource, type HostTokenSourceOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MessageMeta, type MultiTransportSession, PLATFORM_EVENTS, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge$1 as PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry$1 as ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RequestOptions, type RewardCue, type RewardedStatus, type RoomArgValue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerApi, type ServerBundleHost, type ServerTokenGrant, type SessionEndReason, type ShareApi, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SnapshotCurrency, type SnapshotItem, type TokenGrant, type Transport, type TransportAdvert, type TransportKind, TransportRefusal, type TransportRequest, type TransportResponse, UNRELIABLE_CHANNEL_LABEL, type VersionedGetOptions, type VersionedResponse, type VibrationApi, type WalletVisibleOptions, asPlayerText, createBootTimeline, createGem, createGemServer, createHostTokenSource, createMatchServer, defineServer, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, systemClock, text, toBase64, webTransportAvailable };
|
|
@@ -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.1.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
|
|
4
4
|
|
|
5
5
|
`@indiegems/gem-web-sdk/sdk` is the one import a game writes, wherever its code runs. `@indiegems/gem-web-sdk/game` exports exactly the symbols on this page and nothing else, for a build that wants only this half.
|
|
6
6
|
|
|
@@ -6733,6 +6733,10 @@ checklist.
|
|
|
6733
6733
|
here so the two agree, and see [Gem.reportMuted](#gem-reportmuted) for the other
|
|
6734
6734
|
direction.
|
|
6735
6735
|
|
|
6736
|
+
**`recommended` changing is advice changing.** Apply it only to a setting
|
|
6737
|
+
the player has not chosen in your game; never overwrite their own choice
|
|
6738
|
+
with it.
|
|
6739
|
+
|
|
6736
6740
|
<a id="gemoptions-oncohorts"></a>
|
|
6737
6741
|
|
|
6738
6742
|
## GemOptions.onCohorts
|
|
@@ -7175,6 +7179,10 @@ not for your game — respecting them is part of what a game must do.
|
|
|
7175
7179
|
They can change mid-session, so read them when you need them rather than
|
|
7176
7180
|
caching at boot.
|
|
7177
7181
|
|
|
7182
|
+
`recommended` is the exception: the player's Arcade-wide defaults, which
|
|
7183
|
+
your game may start its own settings from or ignore — never a reason to
|
|
7184
|
+
overwrite a choice the player made in your game.
|
|
7185
|
+
|
|
7178
7186
|
**Guides.** [what-a-game-must-do](../what-a-game-must-do.md)
|
|
7179
7187
|
|
|
7180
7188
|
<a id="gemprefs-reducedmotion"></a>
|
|
@@ -7227,6 +7235,100 @@ Use it to pick your game's language, and pass it to
|
|
|
7227
7235
|
[text.compare](#text-compare) when sorting names — that call has no other way to
|
|
7228
7236
|
learn a locale.
|
|
7229
7237
|
|
|
7238
|
+
<a id="gemprefs-recommended"></a>
|
|
7239
|
+
|
|
7240
|
+
## GemPrefs.recommended
|
|
7241
|
+
|
|
7242
|
+
```ts
|
|
7243
|
+
readonly recommended: GemRecommendedSettings | null
|
|
7244
|
+
```
|
|
7245
|
+
|
|
7246
|
+
The player's Arcade-wide defaults for this device — a volume, battery
|
|
7247
|
+
saver, a keyboard layout, the gamepad's confirm button and vibration — or
|
|
7248
|
+
`null` when the Arcade did not send them.
|
|
7249
|
+
|
|
7250
|
+
**Recommendations only; the player's own choice in your game wins.** Start
|
|
7251
|
+
a setting from here while the player has made no choice of their own for
|
|
7252
|
+
it, and never overwrite one they made because this changed:
|
|
7253
|
+
|
|
7254
|
+
```js
|
|
7255
|
+
const saved = gem.deviceSettings.current ?? {};
|
|
7256
|
+
const volume = saved.volume ?? gem.prefs?.recommended?.volume ?? 100;
|
|
7257
|
+
```
|
|
7258
|
+
|
|
7259
|
+
Unlike `muted` and `reducedMotion`, nothing here is applied for you, and
|
|
7260
|
+
nothing obliges you to use it. See the guide's "Game settings" section.
|
|
7261
|
+
|
|
7262
|
+
<a id="gemrecommendedsettings"></a>
|
|
7263
|
+
|
|
7264
|
+
## GemRecommendedSettings
|
|
7265
|
+
|
|
7266
|
+
```ts
|
|
7267
|
+
interface GemRecommendedSettings
|
|
7268
|
+
```
|
|
7269
|
+
|
|
7270
|
+
The player's Arcade-wide defaults for this device, as `gem.prefs.recommended`.
|
|
7271
|
+
|
|
7272
|
+
The player sets these once in the Arcade's Settings, and every game that
|
|
7273
|
+
reads them starts in the right place. They are advice: a game may ignore
|
|
7274
|
+
them, and a choice the player made in your game always beats them.
|
|
7275
|
+
|
|
7276
|
+
**Guides.** [what-a-game-must-do](../what-a-game-must-do.md)
|
|
7277
|
+
|
|
7278
|
+
<a id="gemrecommendedsettings-volume"></a>
|
|
7279
|
+
|
|
7280
|
+
## GemRecommendedSettings.volume
|
|
7281
|
+
|
|
7282
|
+
```ts
|
|
7283
|
+
readonly volume: number
|
|
7284
|
+
```
|
|
7285
|
+
|
|
7286
|
+
The volume the player wants, as a percentage from 0 to 100. A level, not a
|
|
7287
|
+
mute — `gem.prefs.muted` is the mute.
|
|
7288
|
+
|
|
7289
|
+
<a id="gemrecommendedsettings-batterysaver"></a>
|
|
7290
|
+
|
|
7291
|
+
## GemRecommendedSettings.batterySaver
|
|
7292
|
+
|
|
7293
|
+
```ts
|
|
7294
|
+
readonly batterySaver: boolean
|
|
7295
|
+
```
|
|
7296
|
+
|
|
7297
|
+
The player asked games to save power on this device: a lower frame rate,
|
|
7298
|
+
fewer effects, a lower resolution.
|
|
7299
|
+
|
|
7300
|
+
<a id="gemrecommendedsettings-keyboardlayout"></a>
|
|
7301
|
+
|
|
7302
|
+
## GemRecommendedSettings.keyboardLayout
|
|
7303
|
+
|
|
7304
|
+
```ts
|
|
7305
|
+
readonly keyboardLayout: "wasd" | "arrows"
|
|
7306
|
+
```
|
|
7307
|
+
|
|
7308
|
+
Which keys the player expects to move with: `'wasd'` or `'arrows'`.
|
|
7309
|
+
|
|
7310
|
+
<a id="gemrecommendedsettings-gamepadconfirm"></a>
|
|
7311
|
+
|
|
7312
|
+
## GemRecommendedSettings.gamepadConfirm
|
|
7313
|
+
|
|
7314
|
+
```ts
|
|
7315
|
+
readonly gamepadConfirm: "south" | "east"
|
|
7316
|
+
```
|
|
7317
|
+
|
|
7318
|
+
Which gamepad face button the player expects to confirm with, by position:
|
|
7319
|
+
`'south'` (the bottom button, A on an Xbox controller) or `'east'` (the
|
|
7320
|
+
right one, B on an Xbox controller). The other one goes back.
|
|
7321
|
+
|
|
7322
|
+
<a id="gemrecommendedsettings-vibration"></a>
|
|
7323
|
+
|
|
7324
|
+
## GemRecommendedSettings.vibration
|
|
7325
|
+
|
|
7326
|
+
```ts
|
|
7327
|
+
readonly vibration: boolean
|
|
7328
|
+
```
|
|
7329
|
+
|
|
7330
|
+
Whether the player wants vibration and controller rumble.
|
|
7331
|
+
|
|
7230
7332
|
<a id="gemcohort"></a>
|
|
7231
7333
|
|
|
7232
7334
|
## GemCohort
|
|
@@ -7536,8 +7638,10 @@ What your game adds to the arcade's menu — see `gem.setMenu`.
|
|
|
7536
7638
|
readonly onSettings?: () => void
|
|
7537
7639
|
```
|
|
7538
7640
|
|
|
7539
|
-
Open your settings screen.
|
|
7540
|
-
|
|
7641
|
+
Open your settings screen. Another embedder may show a Settings entry that
|
|
7642
|
+
calls it, but **the Gem Arcade no longer does**: draw a settings button of
|
|
7643
|
+
your own, always (top-right is the recommendation). Passing this is still
|
|
7644
|
+
accepted and harmless.
|
|
7541
7645
|
|
|
7542
7646
|
<a id="gamemenu-items"></a>
|
|
7543
7647
|
|
|
@@ -8484,25 +8588,21 @@ for one: the arcade takes every figure from the platform. If this returns
|
|
|
8484
8588
|
setMenu(menu: GameMenu): boolean
|
|
8485
8589
|
```
|
|
8486
8590
|
|
|
8487
|
-
Put
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
problem — and, once you call this, how they open **your** settings.
|
|
8591
|
+
Put up to four entries of your own in the arcade's menu. The arcade keeps
|
|
8592
|
+
one menu button over your game: it is how a player leaves, mutes, goes
|
|
8593
|
+
fullscreen, reports a problem and changes their Arcade-wide settings.
|
|
8491
8594
|
|
|
8492
8595
|
```js
|
|
8493
|
-
|
|
8494
|
-
onSettings: () => settingsScreen.open(),
|
|
8596
|
+
gem.setMenu({
|
|
8495
8597
|
items: [{ id: 'how-to-play', label: t('How to play'), onSelect: () => help.open() }],
|
|
8496
8598
|
});
|
|
8497
|
-
ownSettingsButton.hidden = inArcadeMenu;
|
|
8498
8599
|
```
|
|
8499
8600
|
|
|
8500
|
-
**
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
around inside your game.
|
|
8601
|
+
**Your settings are not in it: draw your own settings button, always** —
|
|
8602
|
+
top-right is the recommendation. `onSettings` is still accepted, and
|
|
8603
|
+
another embedder may show an entry for it, but the Gem Arcade no longer
|
|
8604
|
+
shows a Settings entry, so a game whose settings open only from there has
|
|
8605
|
+
none a player can reach.
|
|
8506
8606
|
|
|
8507
8607
|
**It is screen state, not a toggle.** Each call is the whole answer and
|
|
8508
8608
|
replaces the last, so call it again when the entries change — a new
|
|
@@ -14668,6 +14768,58 @@ session — [RoomManager.leaveAll](#roommanager-leaveall) is what clears those.
|
|
|
14668
14768
|
|
|
14669
14769
|
**Returns.** The room joined or created.
|
|
14670
14770
|
|
|
14771
|
+
<a id="roommanager-queueformatch"></a>
|
|
14772
|
+
|
|
14773
|
+
## RoomManager.queueForMatch
|
|
14774
|
+
|
|
14775
|
+
```ts
|
|
14776
|
+
queueForMatch(options: QueueForMatchOptions): Promise<MatchTicket>
|
|
14777
|
+
```
|
|
14778
|
+
|
|
14779
|
+
Queue for a match with other players, and get a ticket to wait on.
|
|
14780
|
+
|
|
14781
|
+
FOR A MODE THAT NEEDS A FULL LOBBY BEFORE IT STARTS. The platform holds the
|
|
14782
|
+
player in a queue until it has enough players for one of the templates you
|
|
14783
|
+
named, then makes the room, seats everyone and starts the match — nobody
|
|
14784
|
+
hosts and nobody presses start. For a drop-in mode, where a player should
|
|
14785
|
+
be in a room at once and others join around them, use
|
|
14786
|
+
[RoomManager.quickJoin](#roommanager-quickjoin) instead.
|
|
14787
|
+
|
|
14788
|
+
This call answers as soon as the player is queued. What happens next is on
|
|
14789
|
+
the ticket: await [MatchTicket.outcome](#matchticket-outcome), and when it says `matched`
|
|
14790
|
+
this manager is already in the room — `joined` has fired and the match
|
|
14791
|
+
events follow as for any other room.
|
|
14792
|
+
|
|
14793
|
+
A PLAYER MAY QUEUE FROM INSIDE A ROOM — a hub, or a social lobby they wait
|
|
14794
|
+
in. When the ticket is matched the manager moves to the match's room:
|
|
14795
|
+
`currentRoom` becomes it and `joined` fires. The seat in the room they
|
|
14796
|
+
queued from is kept on the platform, not given up, so when the match is
|
|
14797
|
+
over `join()` with that room's id puts them back in it. If the tab closes
|
|
14798
|
+
before they go back, the SDK leaves both rooms.
|
|
14799
|
+
|
|
14800
|
+
What it does refuse is a second thing in flight: while a ticket waits,
|
|
14801
|
+
`create`, `join`, `joinByCode`, `quickJoin` and another `queueForMatch`
|
|
14802
|
+
refuse until it ends or is cancelled.
|
|
14803
|
+
|
|
14804
|
+
CLOSING THE TAB CANCELS THE TICKET. The SDK sends the cancel as the page
|
|
14805
|
+
goes away, so a player who left is not matched into a lobby they will
|
|
14806
|
+
never arrive in.
|
|
14807
|
+
|
|
14808
|
+
| Parameter | Type | Description |
|
|
14809
|
+
| --- | --- | --- |
|
|
14810
|
+
| `options` | `QueueForMatchOptions` | The templates the player accepts. |
|
|
14811
|
+
|
|
14812
|
+
**Returns.** The ticket, still `queued` unless a lobby was waiting for exactly
|
|
14813
|
+
this player.
|
|
14814
|
+
|
|
14815
|
+
**Throws.** `GemApiError` when the platform refuses the ticket. Two refusals
|
|
14816
|
+
are worth their own branch, by [GemApiError.code](#gemapierror-code):
|
|
14817
|
+
`already_queued` — this player, or someone in their party, is already
|
|
14818
|
+
on a ticket, possibly in another tab or another game — and
|
|
14819
|
+
`matchmaking_unavailable`, which means matchmaking is turned off or not
|
|
14820
|
+
answering. Tell the player; do not loop on it, and do not quietly
|
|
14821
|
+
substitute `quickJoin`, which puts them in a different kind of room.
|
|
14822
|
+
|
|
14671
14823
|
<a id="roommanager-list"></a>
|
|
14672
14824
|
|
|
14673
14825
|
## RoomManager.list
|
|
@@ -15002,6 +15154,20 @@ The room this player is in, or `null`. Kept fresh for you.
|
|
|
15002
15154
|
Read it whenever you render the lobby rather than caching it — the manager
|
|
15003
15155
|
updates it as players join, ready up and leave, and emits events as it does.
|
|
15004
15156
|
|
|
15157
|
+
<a id="roommanager-currentticket"></a>
|
|
15158
|
+
|
|
15159
|
+
## RoomManager.currentTicket
|
|
15160
|
+
|
|
15161
|
+
```ts
|
|
15162
|
+
readonly currentTicket: MatchTicket | null
|
|
15163
|
+
```
|
|
15164
|
+
|
|
15165
|
+
The matchmaking ticket this player is waiting on, or `null`.
|
|
15166
|
+
|
|
15167
|
+
Set from the moment [RoomManager.queueForMatch](#roommanager-queueformatch) answers until the
|
|
15168
|
+
ticket ends — so it is `null` again by the time a matched ticket's room is
|
|
15169
|
+
[RoomManager.currentRoom](#roommanager-currentroom).
|
|
15170
|
+
|
|
15005
15171
|
<a id="roommanager-currentmatch"></a>
|
|
15006
15172
|
|
|
15007
15173
|
## RoomManager.currentMatch
|
|
@@ -15212,6 +15378,220 @@ Stop polling and drop every listener.
|
|
|
15212
15378
|
Call this when tearing your game down. It does not leave the room — use
|
|
15213
15379
|
[RoomManager.leave](#roommanager-leave) or `gem.exit()` for that.
|
|
15214
15380
|
|
|
15381
|
+
<a id="queueformatchoptions"></a>
|
|
15382
|
+
|
|
15383
|
+
## QueueForMatchOptions
|
|
15384
|
+
|
|
15385
|
+
```ts
|
|
15386
|
+
interface QueueForMatchOptions
|
|
15387
|
+
```
|
|
15388
|
+
|
|
15389
|
+
What you pass to `gem.rooms.queueForMatch(...)`.
|
|
15390
|
+
|
|
15391
|
+
NAME EVERY MODE THE PLAYER WILL ACCEPT. The ticket waits for all of them at
|
|
15392
|
+
once and is matched under whichever fills first, so "any mode" is one ticket
|
|
15393
|
+
naming several templates rather than several tickets — a player can only be
|
|
15394
|
+
on one.
|
|
15395
|
+
|
|
15396
|
+
```js
|
|
15397
|
+
const ticket = await gem.rooms.queueForMatch({ templateSlugs: ['duel', 'brawl'] });
|
|
15398
|
+
```
|
|
15399
|
+
|
|
15400
|
+
**Guides.** [rooms-and-matches](../rooms-and-matches.md)
|
|
15401
|
+
|
|
15402
|
+
<a id="queueformatchoptions-templateslugs"></a>
|
|
15403
|
+
|
|
15404
|
+
## QueueForMatchOptions.templateSlugs
|
|
15405
|
+
|
|
15406
|
+
```ts
|
|
15407
|
+
readonly templateSlugs: readonly string[]
|
|
15408
|
+
```
|
|
15409
|
+
|
|
15410
|
+
The room templates this player accepts, by slug — one to eight of them.
|
|
15411
|
+
|
|
15412
|
+
EVERY ONE MUST HAVE MATCHMAKING TURNED ON in your game config. A template
|
|
15413
|
+
without it refuses the whole ticket rather than being skipped, so a typo
|
|
15414
|
+
is an error you see and not a mode nobody is ever matched into.
|
|
15415
|
+
|
|
15416
|
+
<a id="queueformatchoptions-partyid"></a>
|
|
15417
|
+
|
|
15418
|
+
## QueueForMatchOptions.partyId
|
|
15419
|
+
|
|
15420
|
+
```ts
|
|
15421
|
+
readonly partyId?: string
|
|
15422
|
+
```
|
|
15423
|
+
|
|
15424
|
+
A party to queue as one unit. Normally omit it — the SDK brings the
|
|
15425
|
+
player's party along when they lead one, exactly as a room call does.
|
|
15426
|
+
|
|
15427
|
+
A party is seated together or not at all. If it gains or loses a member
|
|
15428
|
+
while it waits, the ticket ends `cancelled` with reason `party_changed`.
|
|
15429
|
+
|
|
15430
|
+
<a id="queueformatchoptions-signal"></a>
|
|
15431
|
+
|
|
15432
|
+
## QueueForMatchOptions.signal
|
|
15433
|
+
|
|
15434
|
+
```ts
|
|
15435
|
+
readonly signal?: AbortSignal
|
|
15436
|
+
```
|
|
15437
|
+
|
|
15438
|
+
Cancel the request that creates the ticket.
|
|
15439
|
+
|
|
15440
|
+
Only that request. Once you hold a ticket, [MatchTicket.cancel](#matchticket-cancel) is
|
|
15441
|
+
what takes the player out of the queue.
|
|
15442
|
+
|
|
15443
|
+
<a id="matchticketstatus"></a>
|
|
15444
|
+
|
|
15445
|
+
## MatchTicketStatus
|
|
15446
|
+
|
|
15447
|
+
```ts
|
|
15448
|
+
type MatchTicketStatus = "queued" | "matched" | "expired" | "cancelled" | "failed" | "lost" | "unavailable"
|
|
15449
|
+
```
|
|
15450
|
+
|
|
15451
|
+
Where a ticket is: `queued` while it waits, and anything else for good.
|
|
15452
|
+
|
|
15453
|
+
- `matched` — the player is seated and the match is starting.
|
|
15454
|
+
- `expired` — it waited too long, or stopped being kept alive.
|
|
15455
|
+
- `cancelled` — the player backed out, or their party changed.
|
|
15456
|
+
- `failed` — the platform formed a match and could not start it, repeatedly.
|
|
15457
|
+
- `lost` — the platform no longer has the ticket. Queue again.
|
|
15458
|
+
- `unavailable` — matchmaking is turned off or not answering.
|
|
15459
|
+
|
|
15460
|
+
<a id="matchticketoutcome"></a>
|
|
15461
|
+
|
|
15462
|
+
## MatchTicketOutcome
|
|
15463
|
+
|
|
15464
|
+
```ts
|
|
15465
|
+
type MatchTicketOutcome = { status: "matched"; room: Room } | { status: "expired"; reason: string } | { status: "cancelled"; reason: string } | { status: "failed"; reason: string } | { status: "lost" } | { status: "unavailable" }
|
|
15466
|
+
```
|
|
15467
|
+
|
|
15468
|
+
How a ticket ended. Branch on `status`.
|
|
15469
|
+
|
|
15470
|
+
ONLY `matched` CARRIES A ROOM, and by the time you see it the SDK is already
|
|
15471
|
+
in that room: `gem.rooms.currentRoom` is it, `joined` has fired, and the
|
|
15472
|
+
match events follow as they do for any other room.
|
|
15473
|
+
|
|
15474
|
+
Every other ending leaves the player in no room and on no ticket, free to
|
|
15475
|
+
queue again. None of them is retried for you, and nothing falls back to
|
|
15476
|
+
`quickJoin` — a game that wants either does it on purpose.
|
|
15477
|
+
|
|
15478
|
+
`reason` says why, where the platform gave one: `timed_out` or
|
|
15479
|
+
`heartbeat_lapsed` for `expired`, `requested` or `party_changed` for
|
|
15480
|
+
`cancelled`, `handoff_failed` for `failed`. Treat a value you do not
|
|
15481
|
+
recognise as the status alone.
|
|
15482
|
+
|
|
15483
|
+
<a id="matchticket"></a>
|
|
15484
|
+
|
|
15485
|
+
## MatchTicket
|
|
15486
|
+
|
|
15487
|
+
```ts
|
|
15488
|
+
interface MatchTicket
|
|
15489
|
+
```
|
|
15490
|
+
|
|
15491
|
+
A place in the matchmaking queue — what `gem.rooms.queueForMatch(...)`
|
|
15492
|
+
answers with.
|
|
15493
|
+
|
|
15494
|
+
You do not keep it alive; the SDK does, for as long as it waits. What you do
|
|
15495
|
+
with it is wait for [MatchTicket.outcome](#matchticket-outcome), and offer the player a
|
|
15496
|
+
button that calls [MatchTicket.cancel](#matchticket-cancel).
|
|
15497
|
+
|
|
15498
|
+
```js
|
|
15499
|
+
const ticket = await gem.rooms.queueForMatch({ templateSlugs: ['duel'] });
|
|
15500
|
+
showSearching({ onCancel: () => ticket.cancel() });
|
|
15501
|
+
|
|
15502
|
+
const outcome = await ticket.outcome;
|
|
15503
|
+
if (outcome.status === 'matched') enterMatch(outcome.room);
|
|
15504
|
+
else backToMenu(outcome.status);
|
|
15505
|
+
```
|
|
15506
|
+
|
|
15507
|
+
**Guides.** [rooms-and-matches](../rooms-and-matches.md)
|
|
15508
|
+
|
|
15509
|
+
<a id="matchticket-id"></a>
|
|
15510
|
+
|
|
15511
|
+
## MatchTicket.id
|
|
15512
|
+
|
|
15513
|
+
```ts
|
|
15514
|
+
readonly id: string
|
|
15515
|
+
```
|
|
15516
|
+
|
|
15517
|
+
The ticket's id. For logs and bug reports; nothing you call takes it.
|
|
15518
|
+
|
|
15519
|
+
<a id="matchticket-status"></a>
|
|
15520
|
+
|
|
15521
|
+
## MatchTicket.status
|
|
15522
|
+
|
|
15523
|
+
```ts
|
|
15524
|
+
readonly status: MatchTicketStatus
|
|
15525
|
+
```
|
|
15526
|
+
|
|
15527
|
+
Where the ticket is right now. Changes once, from `queued` to how it ended.
|
|
15528
|
+
|
|
15529
|
+
<a id="matchticket-partysize"></a>
|
|
15530
|
+
|
|
15531
|
+
## MatchTicket.partySize
|
|
15532
|
+
|
|
15533
|
+
```ts
|
|
15534
|
+
readonly partySize: number
|
|
15535
|
+
```
|
|
15536
|
+
|
|
15537
|
+
How many players the ticket seats: 1, or the size of the party.
|
|
15538
|
+
|
|
15539
|
+
<a id="matchticket-queuedat"></a>
|
|
15540
|
+
|
|
15541
|
+
## MatchTicket.queuedAt
|
|
15542
|
+
|
|
15543
|
+
```ts
|
|
15544
|
+
readonly queuedAt: number
|
|
15545
|
+
```
|
|
15546
|
+
|
|
15547
|
+
When the ticket joined the queue, in Unix seconds.
|
|
15548
|
+
|
|
15549
|
+
<a id="matchticket-expiresat"></a>
|
|
15550
|
+
|
|
15551
|
+
## MatchTicket.expiresAt
|
|
15552
|
+
|
|
15553
|
+
```ts
|
|
15554
|
+
readonly expiresAt: number
|
|
15555
|
+
```
|
|
15556
|
+
|
|
15557
|
+
When the ticket gives up if it is still waiting, in Unix seconds. Good for
|
|
15558
|
+
a countdown; the platform decides the length, per template.
|
|
15559
|
+
|
|
15560
|
+
<a id="matchticket-outcome"></a>
|
|
15561
|
+
|
|
15562
|
+
## MatchTicket.outcome
|
|
15563
|
+
|
|
15564
|
+
```ts
|
|
15565
|
+
readonly outcome: Promise<MatchTicketOutcome>
|
|
15566
|
+
```
|
|
15567
|
+
|
|
15568
|
+
How the ticket ends. Settles exactly once, and RESOLVES for every ending
|
|
15569
|
+
the platform reports — matched, expired, cancelled and the rest are
|
|
15570
|
+
outcomes to branch on, not errors to catch.
|
|
15571
|
+
|
|
15572
|
+
It rejects in one case only: the ticket was matched and the SDK could not
|
|
15573
|
+
read the room it was seated in. The player holds a seat then, so
|
|
15574
|
+
`gem.rooms.myRooms()` shows the room and `gem.rooms.join(id)` enters it.
|
|
15575
|
+
|
|
15576
|
+
<a id="matchticket-cancel"></a>
|
|
15577
|
+
|
|
15578
|
+
## MatchTicket.cancel
|
|
15579
|
+
|
|
15580
|
+
```ts
|
|
15581
|
+
cancel(): Promise<MatchTicketOutcome>
|
|
15582
|
+
```
|
|
15583
|
+
|
|
15584
|
+
Take the player — and their party — out of the queue.
|
|
15585
|
+
|
|
15586
|
+
A CANCEL CAN LOSE THE RACE, and then the answer is `matched`. A ticket the
|
|
15587
|
+
platform has already seated is never undone, so read the outcome this
|
|
15588
|
+
returns rather than assuming: when it says `matched` the player is in a
|
|
15589
|
+
room, and backing out is `gem.rooms.leave()`.
|
|
15590
|
+
|
|
15591
|
+
Safe to call more than once, and after the ticket has ended.
|
|
15592
|
+
|
|
15593
|
+
**Returns.** The same promise as [MatchTicket.outcome](#matchticket-outcome).
|
|
15594
|
+
|
|
15215
15595
|
<a id="roomstatus"></a>
|
|
15216
15596
|
|
|
15217
15597
|
## RoomStatus
|