glitch-javascript-sdk 3.2.32 → 3.3.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.
@@ -433,6 +433,246 @@ export interface MultiplayerVoicePollRequest {
433
433
  limit?: number;
434
434
  exclude_self?: boolean;
435
435
  }
436
+ export type MultiplayerRealmStatus = 'active' | 'locked' | 'maintenance' | 'full' | 'offline';
437
+ export type MultiplayerZoneType = 'overworld' | 'city' | 'dungeon' | 'raid' | 'arena' | 'instanced';
438
+ export type MultiplayerInstanceKind = 'persistent' | 'dynamic' | 'dungeon' | 'raid' | 'arena';
439
+ export type MultiplayerInstanceState = 'provisioning' | 'active' | 'draining' | 'closed';
440
+ export type MultiplayerPresenceStatus = 'online' | 'in_queue' | 'in_world' | 'away' | 'offline';
441
+ export type MultiplayerMatchmakingStatus = 'queued' | 'matched' | 'canceled' | 'expired' | 'timed_out';
442
+ export type MultiplayerBanScope = 'title' | 'realm' | 'lobby' | 'server' | 'voice';
443
+ export type MultiplayerBanSource = 'manual' | 'report' | 'anticheat' | 'automated';
444
+ export type MultiplayerRealtimeScopeType = 'lobby' | 'voice' | 'zone' | 'instance';
445
+ /** A persistent world copy (shard). */
446
+ export interface MultiplayerRealm {
447
+ id: string;
448
+ title_id: string;
449
+ name: string;
450
+ slug?: string | null;
451
+ region?: string | null;
452
+ status: MultiplayerRealmStatus;
453
+ population_cap: number;
454
+ current_population: number;
455
+ recommended: boolean;
456
+ ruleset: MultiplayerMetadata;
457
+ metadata: MultiplayerMetadata;
458
+ last_activity_at?: string | null;
459
+ created_at?: string | null;
460
+ updated_at?: string | null;
461
+ }
462
+ /** A named area within a realm (map/continent/dungeon template). */
463
+ export interface MultiplayerZone {
464
+ id: string;
465
+ title_id: string;
466
+ realm_id: string;
467
+ zone_key: string;
468
+ display_name: string;
469
+ zone_type: MultiplayerZoneType;
470
+ is_instanced: boolean;
471
+ max_players_per_instance: number;
472
+ min_instances: number;
473
+ grid_cell_size: number;
474
+ coordinates_bounds: MultiplayerMetadata;
475
+ metadata: MultiplayerMetadata;
476
+ created_at?: string | null;
477
+ updated_at?: string | null;
478
+ }
479
+ /** A runtime copy of a zone, optionally bound to a game server. */
480
+ export interface MultiplayerInstance {
481
+ id: string;
482
+ title_id: string;
483
+ realm_id: string;
484
+ zone_id: string;
485
+ server_id?: string | null;
486
+ instance_kind: MultiplayerInstanceKind;
487
+ state: MultiplayerInstanceState;
488
+ layer: number;
489
+ difficulty?: string | null;
490
+ max_players: number;
491
+ current_players: number;
492
+ metadata: MultiplayerMetadata;
493
+ last_heartbeat_at?: string | null;
494
+ expires_at?: string | null;
495
+ created_at?: string | null;
496
+ updated_at?: string | null;
497
+ server?: MultiplayerServer | null;
498
+ }
499
+ /** Authoritative location of a player. */
500
+ export interface MultiplayerPresence {
501
+ id: string;
502
+ title_id: string;
503
+ player_id: string;
504
+ user_id?: string | null;
505
+ realm_id?: string | null;
506
+ zone_id?: string | null;
507
+ instance_id?: string | null;
508
+ party_id?: string | null;
509
+ display_name?: string | null;
510
+ status: MultiplayerPresenceStatus;
511
+ rich_status?: string | null;
512
+ pos_x?: number | null;
513
+ pos_y?: number | null;
514
+ pos_z?: number | null;
515
+ heading?: number | null;
516
+ grid_cell?: string | null;
517
+ metadata: MultiplayerMetadata;
518
+ last_heartbeat_at?: string | null;
519
+ expires_at?: string | null;
520
+ }
521
+ export interface MultiplayerMatchmakingTicket {
522
+ id: string;
523
+ title_id: string;
524
+ queue: string;
525
+ player_id: string;
526
+ user_id?: string | null;
527
+ party: string[];
528
+ attributes: MultiplayerMetadata;
529
+ skill?: number | null;
530
+ region?: string | null;
531
+ status: MultiplayerMatchmakingStatus;
532
+ match_id?: string | null;
533
+ assignment?: MultiplayerMetadata | null;
534
+ queued_at?: string | null;
535
+ matched_at?: string | null;
536
+ expires_at?: string | null;
537
+ }
538
+ export interface MultiplayerBan {
539
+ id: string;
540
+ title_id: string;
541
+ scope: MultiplayerBanScope;
542
+ scope_id?: string | null;
543
+ player_id: string;
544
+ user_id?: string | null;
545
+ issued_by?: string | null;
546
+ source: MultiplayerBanSource;
547
+ reason?: string | null;
548
+ metadata: MultiplayerMetadata;
549
+ expires_at?: string | null;
550
+ }
551
+ export interface MultiplayerRealmListParams {
552
+ region?: string;
553
+ status?: MultiplayerRealmStatus;
554
+ recommended?: boolean;
555
+ limit?: number;
556
+ }
557
+ export interface MultiplayerCreateRealmRequest {
558
+ name: string;
559
+ slug?: string;
560
+ region?: string;
561
+ status?: MultiplayerRealmStatus;
562
+ population_cap?: number;
563
+ recommended?: boolean;
564
+ ruleset?: MultiplayerMetadata;
565
+ metadata?: MultiplayerMetadata;
566
+ }
567
+ export interface MultiplayerUpdateRealmRequest extends Partial<MultiplayerCreateRealmRequest> {
568
+ }
569
+ export interface MultiplayerZoneListParams {
570
+ zone_type?: MultiplayerZoneType;
571
+ limit?: number;
572
+ }
573
+ export interface MultiplayerCreateZoneRequest {
574
+ zone_key: string;
575
+ display_name: string;
576
+ zone_type?: MultiplayerZoneType;
577
+ is_instanced?: boolean;
578
+ max_players_per_instance?: number;
579
+ min_instances?: number;
580
+ grid_cell_size?: number;
581
+ coordinates_bounds?: MultiplayerMetadata;
582
+ metadata?: MultiplayerMetadata;
583
+ }
584
+ export interface MultiplayerInstanceListParams {
585
+ state?: MultiplayerInstanceState;
586
+ limit?: number;
587
+ }
588
+ export interface MultiplayerEnterZoneRequest {
589
+ player_id?: string;
590
+ realm_id: string;
591
+ zone_id: string;
592
+ server_id?: string;
593
+ party_id?: string;
594
+ instance_kind?: MultiplayerInstanceKind;
595
+ difficulty?: string;
596
+ display_name?: string;
597
+ rich_status?: string;
598
+ pos_x?: number;
599
+ pos_y?: number;
600
+ pos_z?: number;
601
+ heading?: number;
602
+ metadata?: MultiplayerMetadata;
603
+ instance_metadata?: MultiplayerMetadata;
604
+ ttl_minutes?: number;
605
+ }
606
+ export interface MultiplayerEnterZoneResponse {
607
+ instance: MultiplayerInstance;
608
+ presence: MultiplayerPresence;
609
+ }
610
+ export interface MultiplayerUpdatePresenceRequest {
611
+ player_id?: string;
612
+ status?: MultiplayerPresenceStatus;
613
+ rich_status?: string;
614
+ pos_x?: number;
615
+ pos_y?: number;
616
+ pos_z?: number;
617
+ heading?: number;
618
+ ttl_minutes?: number;
619
+ }
620
+ export interface MultiplayerLeaveWorldRequest {
621
+ player_id?: string;
622
+ }
623
+ export interface MultiplayerInstancePresenceParams {
624
+ grid_cell?: string;
625
+ radius?: number;
626
+ limit?: number;
627
+ }
628
+ export interface MultiplayerEnqueueTicketRequest {
629
+ player_id?: string;
630
+ queue: string;
631
+ party?: string[];
632
+ attributes?: MultiplayerMetadata;
633
+ skill?: number;
634
+ region?: string;
635
+ ttl_seconds?: number;
636
+ }
637
+ export interface MultiplayerCancelTicketParams {
638
+ player_id?: string;
639
+ }
640
+ export interface MultiplayerBanListParams {
641
+ scope?: MultiplayerBanScope;
642
+ player_id?: string;
643
+ source?: MultiplayerBanSource;
644
+ active_only?: boolean;
645
+ limit?: number;
646
+ }
647
+ export interface MultiplayerCreateBanRequest {
648
+ player_id: string;
649
+ scope?: MultiplayerBanScope;
650
+ scope_id?: string;
651
+ user_id?: string;
652
+ source?: MultiplayerBanSource;
653
+ reason?: string;
654
+ metadata?: MultiplayerMetadata;
655
+ expires_at?: string;
656
+ }
657
+ export interface MultiplayerDeleteBanResponse {
658
+ deleted: boolean;
659
+ }
660
+ export interface MultiplayerRealtimeScope {
661
+ type: MultiplayerRealtimeScopeType;
662
+ id: string;
663
+ }
664
+ export interface MultiplayerRealtimeNegotiateRequest {
665
+ player_id?: string;
666
+ scopes?: MultiplayerRealtimeScope[];
667
+ }
668
+ export interface MultiplayerRealtimeNegotiateResponse {
669
+ protocol: string;
670
+ url: string | null;
671
+ configured: boolean;
672
+ groups: string[];
673
+ access_token: string | null;
674
+ expires_at: string | null;
675
+ }
436
676
  /**
437
677
  * Steam-style multiplayer APIs for Glitch titles.
438
678
  *
@@ -867,5 +1107,183 @@ declare class Multiplayer {
867
1107
  * @param params Optional player_id for title-token clients.
868
1108
  */
869
1109
  static deleteFavorite<T = MultiplayerDeleteFavoriteResponse>(title_id: string, favorite_id: string, params?: MultiplayerDeleteFavoriteParams): AxiosPromise<Response<T>>;
1110
+ /**
1111
+ * List realms (persistent world shards) so a player can choose where to log in.
1112
+ *
1113
+ * @param title_id Title UUID.
1114
+ * @param params Optional region/status filters; recommended realms sort first.
1115
+ * @example
1116
+ * Multiplayer.listRealms('title-uuid', { region: 'us-central', status: 'active' });
1117
+ */
1118
+ static listRealms<T = MultiplayerRealm[]>(title_id: string, params?: MultiplayerRealmListParams): AxiosPromise<Response<T>>;
1119
+ /**
1120
+ * Create a realm. Requires a title administrator JWT.
1121
+ *
1122
+ * @param title_id Title UUID.
1123
+ * @param data Realm configuration.
1124
+ * @example
1125
+ * Multiplayer.createRealm('title-uuid', { name: 'Aurora', region: 'us-central', population_cap: 5000, recommended: true });
1126
+ */
1127
+ static createRealm<T = MultiplayerRealm>(title_id: string, data: MultiplayerCreateRealmRequest): AxiosPromise<Response<T>>;
1128
+ /**
1129
+ * Retrieve a single realm.
1130
+ *
1131
+ * @param title_id Title UUID.
1132
+ * @param realm_id Realm UUID.
1133
+ */
1134
+ static showRealm<T = MultiplayerRealm>(title_id: string, realm_id: string): AxiosPromise<Response<T>>;
1135
+ /**
1136
+ * Update a realm (status, population cap, ruleset). Requires a title admin JWT.
1137
+ *
1138
+ * @param title_id Title UUID.
1139
+ * @param realm_id Realm UUID.
1140
+ * @param data Fields to update.
1141
+ */
1142
+ static updateRealm<T = MultiplayerRealm>(title_id: string, realm_id: string, data: MultiplayerUpdateRealmRequest): AxiosPromise<Response<T>>;
1143
+ /**
1144
+ * List the zones defined for a realm.
1145
+ *
1146
+ * @param title_id Title UUID.
1147
+ * @param realm_id Realm UUID.
1148
+ * @param params Optional zone_type filter.
1149
+ */
1150
+ static listZones<T = MultiplayerZone[]>(title_id: string, realm_id: string, params?: MultiplayerZoneListParams): AxiosPromise<Response<T>>;
1151
+ /**
1152
+ * Create a zone in a realm. Requires a title administrator JWT.
1153
+ *
1154
+ * @param title_id Title UUID.
1155
+ * @param realm_id Realm UUID.
1156
+ * @param data Zone configuration, including interest-management grid cell size.
1157
+ * @example
1158
+ * Multiplayer.createZone('title-uuid', 'realm-uuid', {
1159
+ * zone_key: 'ashfall_valley',
1160
+ * display_name: 'Ashfall Valley',
1161
+ * zone_type: 'overworld',
1162
+ * max_players_per_instance: 100,
1163
+ * grid_cell_size: 64
1164
+ * });
1165
+ */
1166
+ static createZone<T = MultiplayerZone>(title_id: string, realm_id: string, data: MultiplayerCreateZoneRequest): AxiosPromise<Response<T>>;
1167
+ /**
1168
+ * List the active/other instances (runtime copies) of a zone.
1169
+ *
1170
+ * @param title_id Title UUID.
1171
+ * @param zone_id Zone UUID.
1172
+ * @param params Optional state filter.
1173
+ */
1174
+ static listInstances<T = MultiplayerInstance[]>(title_id: string, zone_id: string, params?: MultiplayerInstanceListParams): AxiosPromise<Response<T>>;
1175
+ /**
1176
+ * Retrieve a single instance.
1177
+ *
1178
+ * @param title_id Title UUID.
1179
+ * @param instance_id Instance UUID.
1180
+ */
1181
+ static showInstance<T = MultiplayerInstance>(title_id: string, instance_id: string): AxiosPromise<Response<T>>;
1182
+ /**
1183
+ * List players present in an instance. Pass grid_cell (and optional radius) to
1184
+ * receive only players in the caller's area of interest — the key to keeping
1185
+ * per-player fan-out bounded regardless of how populated the zone is.
1186
+ *
1187
+ * @param title_id Title UUID.
1188
+ * @param instance_id Instance UUID.
1189
+ * @param params grid_cell "cx:cy" and radius (0-4) to scope the query.
1190
+ * @example
1191
+ * Multiplayer.listInstancePresence('title-uuid', 'instance-uuid', { grid_cell: '12:8', radius: 1 });
1192
+ */
1193
+ static listInstancePresence<T = MultiplayerPresence[]>(title_id: string, instance_id: string, params?: MultiplayerInstancePresenceParams): AxiosPromise<Response<T>>;
1194
+ /**
1195
+ * Enter a zone. The backend places the player into an active instance with
1196
+ * capacity (creating a new layer if all are full), enforces bans and realm
1197
+ * capacity, and upserts presence. Returns the instance and presence so the
1198
+ * client can connect and subscribe to the instance's real-time group.
1199
+ *
1200
+ * @param title_id Title UUID.
1201
+ * @param data Realm/zone target plus optional spawn position and metadata.
1202
+ * @example
1203
+ * Multiplayer.enterZone('title-uuid', {
1204
+ * player_id: 'steam:765...',
1205
+ * realm_id: 'realm-uuid',
1206
+ * zone_id: 'zone-uuid',
1207
+ * pos_x: 128.0, pos_z: 64.0
1208
+ * });
1209
+ */
1210
+ static enterZone<T = MultiplayerEnterZoneResponse>(title_id: string, data: MultiplayerEnterZoneRequest): AxiosPromise<Response<T>>;
1211
+ /**
1212
+ * Update presence (position, heading, rich status) and refresh the TTL. Call
1213
+ * on a movement interval and on notable state changes.
1214
+ *
1215
+ * @param title_id Title UUID.
1216
+ * @param data New position/status for the player.
1217
+ */
1218
+ static updatePresence<T = MultiplayerPresence>(title_id: string, data: MultiplayerUpdatePresenceRequest): AxiosPromise<Response<T>>;
1219
+ /**
1220
+ * Leave the world. Frees the player's instance slot and realm population.
1221
+ *
1222
+ * @param title_id Title UUID.
1223
+ * @param data Optional player_id for title-token clients.
1224
+ */
1225
+ static leaveWorld<T = MultiplayerPresence>(title_id: string, data?: MultiplayerLeaveWorldRequest): AxiosPromise<Response<T>>;
1226
+ /**
1227
+ * Enqueue a matchmaking ticket. Idempotent per (queue, player): an existing
1228
+ * open ticket is returned rather than duplicated, so retries are safe. Poll
1229
+ * the ticket or subscribe to `matchmaking.matched` for the assignment.
1230
+ *
1231
+ * @param title_id Title UUID.
1232
+ * @param data Queue name plus optional party, skill, region, and attributes.
1233
+ * @example
1234
+ * Multiplayer.enqueueTicket('title-uuid', { player_id: 'steam:765...', queue: 'ranked_2v2', skill: 1840, region: 'us-central' });
1235
+ */
1236
+ static enqueueTicket<T = MultiplayerMatchmakingTicket>(title_id: string, data: MultiplayerEnqueueTicketRequest): AxiosPromise<Response<T>>;
1237
+ /**
1238
+ * Poll a matchmaking ticket. A queued ticket past its TTL is reported as
1239
+ * `timed_out`; a matched ticket carries the connection `assignment`.
1240
+ *
1241
+ * @param title_id Title UUID.
1242
+ * @param ticket_id Ticket UUID.
1243
+ */
1244
+ static showTicket<T = MultiplayerMatchmakingTicket>(title_id: string, ticket_id: string): AxiosPromise<Response<T>>;
1245
+ /**
1246
+ * Cancel a queued matchmaking ticket.
1247
+ *
1248
+ * @param title_id Title UUID.
1249
+ * @param ticket_id Ticket UUID.
1250
+ */
1251
+ static cancelTicket<T = MultiplayerMatchmakingTicket>(title_id: string, ticket_id: string): AxiosPromise<Response<T>>;
1252
+ /**
1253
+ * Negotiate a real-time push connection. Returns the authorized group names
1254
+ * and the push endpoint. When SignalR/Web PubSub is configured, an
1255
+ * access_token scoped to those groups is included; otherwise `configured` is
1256
+ * false and the client should fall back to the polling endpoints.
1257
+ *
1258
+ * @param title_id Title UUID.
1259
+ * @param data Optional player_id and the scopes (lobby/voice/zone/instance) to subscribe to.
1260
+ * @example
1261
+ * Multiplayer.negotiateRealtime('title-uuid', { player_id: 'steam:765...', scopes: [{ type: 'instance', id: 'instance-uuid' }] });
1262
+ */
1263
+ static negotiateRealtime<T = MultiplayerRealtimeNegotiateResponse>(title_id: string, data?: MultiplayerRealtimeNegotiateRequest): AxiosPromise<Response<T>>;
1264
+ /**
1265
+ * List bans for a title. Requires a title administrator JWT.
1266
+ *
1267
+ * @param title_id Title UUID.
1268
+ * @param params Optional scope/player/source filters and active_only.
1269
+ */
1270
+ static listBans<T = MultiplayerBan[]>(title_id: string, params?: MultiplayerBanListParams): AxiosPromise<Response<T>>;
1271
+ /**
1272
+ * Ban a player at a scope (title/realm/lobby/server/voice). Requires a title
1273
+ * administrator JWT. Omit expires_at for a permanent ban.
1274
+ *
1275
+ * @param title_id Title UUID.
1276
+ * @param data Ban target and scope.
1277
+ * @example
1278
+ * Multiplayer.createBan('title-uuid', { player_id: 'steam:765...', scope: 'title', reason: 'Cheating: aimbot' });
1279
+ */
1280
+ static createBan<T = MultiplayerBan>(title_id: string, data: MultiplayerCreateBanRequest): AxiosPromise<Response<T>>;
1281
+ /**
1282
+ * Lift a ban. Requires a title administrator JWT.
1283
+ *
1284
+ * @param title_id Title UUID.
1285
+ * @param ban_id Ban UUID.
1286
+ */
1287
+ static deleteBan<T = MultiplayerDeleteBanResponse>(title_id: string, ban_id: string): AxiosPromise<Response<T>>;
870
1288
  }
871
1289
  export default Multiplayer;
package/dist/esm/index.js CHANGED
@@ -19058,6 +19058,28 @@ var MultiplayerRoute = /** @class */ (function () {
19058
19058
  listFavorites: { url: '/titles/{title_id}/multiplayer/favorites', method: HTTP_METHODS.GET },
19059
19059
  addFavorite: { url: '/titles/{title_id}/multiplayer/favorites', method: HTTP_METHODS.POST },
19060
19060
  deleteFavorite: { url: '/titles/{title_id}/multiplayer/favorites/{favorite_id}', method: HTTP_METHODS.DELETE },
19061
+ // MMO world layer: realms, zones, instances, presence.
19062
+ listRealms: { url: '/titles/{title_id}/multiplayer/realms', method: HTTP_METHODS.GET },
19063
+ createRealm: { url: '/titles/{title_id}/multiplayer/realms', method: HTTP_METHODS.POST },
19064
+ showRealm: { url: '/titles/{title_id}/multiplayer/realms/{realm_id}', method: HTTP_METHODS.GET },
19065
+ updateRealm: { url: '/titles/{title_id}/multiplayer/realms/{realm_id}', method: HTTP_METHODS.PUT },
19066
+ listZones: { url: '/titles/{title_id}/multiplayer/realms/{realm_id}/zones', method: HTTP_METHODS.GET },
19067
+ createZone: { url: '/titles/{title_id}/multiplayer/realms/{realm_id}/zones', method: HTTP_METHODS.POST },
19068
+ listInstances: { url: '/titles/{title_id}/multiplayer/zones/{zone_id}/instances', method: HTTP_METHODS.GET },
19069
+ showInstance: { url: '/titles/{title_id}/multiplayer/instances/{instance_id}', method: HTTP_METHODS.GET },
19070
+ listInstancePresence: { url: '/titles/{title_id}/multiplayer/instances/{instance_id}/presence', method: HTTP_METHODS.GET },
19071
+ enterZone: { url: '/titles/{title_id}/multiplayer/world/enter', method: HTTP_METHODS.POST },
19072
+ updatePresence: { url: '/titles/{title_id}/multiplayer/world/presence', method: HTTP_METHODS.POST },
19073
+ leaveWorld: { url: '/titles/{title_id}/multiplayer/world/leave', method: HTTP_METHODS.POST },
19074
+ // Ticketed matchmaking.
19075
+ enqueueTicket: { url: '/titles/{title_id}/multiplayer/matchmaking/tickets', method: HTTP_METHODS.POST },
19076
+ showTicket: { url: '/titles/{title_id}/multiplayer/matchmaking/tickets/{ticket_id}', method: HTTP_METHODS.GET },
19077
+ cancelTicket: { url: '/titles/{title_id}/multiplayer/matchmaking/tickets/{ticket_id}', method: HTTP_METHODS.DELETE },
19078
+ // Real-time negotiate + trust/moderation.
19079
+ negotiateRealtime: { url: '/titles/{title_id}/multiplayer/realtime/negotiate', method: HTTP_METHODS.POST },
19080
+ listBans: { url: '/titles/{title_id}/multiplayer/bans', method: HTTP_METHODS.GET },
19081
+ createBan: { url: '/titles/{title_id}/multiplayer/bans', method: HTTP_METHODS.POST },
19082
+ deleteBan: { url: '/titles/{title_id}/multiplayer/bans/{ban_id}', method: HTTP_METHODS.DELETE },
19061
19083
  };
19062
19084
  return MultiplayerRoute;
19063
19085
  }());
@@ -19558,6 +19580,231 @@ var Multiplayer = /** @class */ (function () {
19558
19580
  Multiplayer.deleteFavorite = function (title_id, favorite_id, params) {
19559
19581
  return Requests.processRoute(MultiplayerRoute.routes.deleteFavorite, undefined, { title_id: title_id, favorite_id: favorite_id }, params);
19560
19582
  };
19583
+ // -----------------------------------------------------------------------
19584
+ // MMO world layer
19585
+ // -----------------------------------------------------------------------
19586
+ /**
19587
+ * List realms (persistent world shards) so a player can choose where to log in.
19588
+ *
19589
+ * @param title_id Title UUID.
19590
+ * @param params Optional region/status filters; recommended realms sort first.
19591
+ * @example
19592
+ * Multiplayer.listRealms('title-uuid', { region: 'us-central', status: 'active' });
19593
+ */
19594
+ Multiplayer.listRealms = function (title_id, params) {
19595
+ return Requests.processRoute(MultiplayerRoute.routes.listRealms, undefined, { title_id: title_id }, params);
19596
+ };
19597
+ /**
19598
+ * Create a realm. Requires a title administrator JWT.
19599
+ *
19600
+ * @param title_id Title UUID.
19601
+ * @param data Realm configuration.
19602
+ * @example
19603
+ * Multiplayer.createRealm('title-uuid', { name: 'Aurora', region: 'us-central', population_cap: 5000, recommended: true });
19604
+ */
19605
+ Multiplayer.createRealm = function (title_id, data) {
19606
+ return Requests.processRoute(MultiplayerRoute.routes.createRealm, data, { title_id: title_id });
19607
+ };
19608
+ /**
19609
+ * Retrieve a single realm.
19610
+ *
19611
+ * @param title_id Title UUID.
19612
+ * @param realm_id Realm UUID.
19613
+ */
19614
+ Multiplayer.showRealm = function (title_id, realm_id) {
19615
+ return Requests.processRoute(MultiplayerRoute.routes.showRealm, undefined, { title_id: title_id, realm_id: realm_id });
19616
+ };
19617
+ /**
19618
+ * Update a realm (status, population cap, ruleset). Requires a title admin JWT.
19619
+ *
19620
+ * @param title_id Title UUID.
19621
+ * @param realm_id Realm UUID.
19622
+ * @param data Fields to update.
19623
+ */
19624
+ Multiplayer.updateRealm = function (title_id, realm_id, data) {
19625
+ return Requests.processRoute(MultiplayerRoute.routes.updateRealm, data, { title_id: title_id, realm_id: realm_id });
19626
+ };
19627
+ /**
19628
+ * List the zones defined for a realm.
19629
+ *
19630
+ * @param title_id Title UUID.
19631
+ * @param realm_id Realm UUID.
19632
+ * @param params Optional zone_type filter.
19633
+ */
19634
+ Multiplayer.listZones = function (title_id, realm_id, params) {
19635
+ return Requests.processRoute(MultiplayerRoute.routes.listZones, undefined, { title_id: title_id, realm_id: realm_id }, params);
19636
+ };
19637
+ /**
19638
+ * Create a zone in a realm. Requires a title administrator JWT.
19639
+ *
19640
+ * @param title_id Title UUID.
19641
+ * @param realm_id Realm UUID.
19642
+ * @param data Zone configuration, including interest-management grid cell size.
19643
+ * @example
19644
+ * Multiplayer.createZone('title-uuid', 'realm-uuid', {
19645
+ * zone_key: 'ashfall_valley',
19646
+ * display_name: 'Ashfall Valley',
19647
+ * zone_type: 'overworld',
19648
+ * max_players_per_instance: 100,
19649
+ * grid_cell_size: 64
19650
+ * });
19651
+ */
19652
+ Multiplayer.createZone = function (title_id, realm_id, data) {
19653
+ return Requests.processRoute(MultiplayerRoute.routes.createZone, data, { title_id: title_id, realm_id: realm_id });
19654
+ };
19655
+ /**
19656
+ * List the active/other instances (runtime copies) of a zone.
19657
+ *
19658
+ * @param title_id Title UUID.
19659
+ * @param zone_id Zone UUID.
19660
+ * @param params Optional state filter.
19661
+ */
19662
+ Multiplayer.listInstances = function (title_id, zone_id, params) {
19663
+ return Requests.processRoute(MultiplayerRoute.routes.listInstances, undefined, { title_id: title_id, zone_id: zone_id }, params);
19664
+ };
19665
+ /**
19666
+ * Retrieve a single instance.
19667
+ *
19668
+ * @param title_id Title UUID.
19669
+ * @param instance_id Instance UUID.
19670
+ */
19671
+ Multiplayer.showInstance = function (title_id, instance_id) {
19672
+ return Requests.processRoute(MultiplayerRoute.routes.showInstance, undefined, { title_id: title_id, instance_id: instance_id });
19673
+ };
19674
+ /**
19675
+ * List players present in an instance. Pass grid_cell (and optional radius) to
19676
+ * receive only players in the caller's area of interest — the key to keeping
19677
+ * per-player fan-out bounded regardless of how populated the zone is.
19678
+ *
19679
+ * @param title_id Title UUID.
19680
+ * @param instance_id Instance UUID.
19681
+ * @param params grid_cell "cx:cy" and radius (0-4) to scope the query.
19682
+ * @example
19683
+ * Multiplayer.listInstancePresence('title-uuid', 'instance-uuid', { grid_cell: '12:8', radius: 1 });
19684
+ */
19685
+ Multiplayer.listInstancePresence = function (title_id, instance_id, params) {
19686
+ return Requests.processRoute(MultiplayerRoute.routes.listInstancePresence, undefined, { title_id: title_id, instance_id: instance_id }, params);
19687
+ };
19688
+ /**
19689
+ * Enter a zone. The backend places the player into an active instance with
19690
+ * capacity (creating a new layer if all are full), enforces bans and realm
19691
+ * capacity, and upserts presence. Returns the instance and presence so the
19692
+ * client can connect and subscribe to the instance's real-time group.
19693
+ *
19694
+ * @param title_id Title UUID.
19695
+ * @param data Realm/zone target plus optional spawn position and metadata.
19696
+ * @example
19697
+ * Multiplayer.enterZone('title-uuid', {
19698
+ * player_id: 'steam:765...',
19699
+ * realm_id: 'realm-uuid',
19700
+ * zone_id: 'zone-uuid',
19701
+ * pos_x: 128.0, pos_z: 64.0
19702
+ * });
19703
+ */
19704
+ Multiplayer.enterZone = function (title_id, data) {
19705
+ return Requests.processRoute(MultiplayerRoute.routes.enterZone, data, { title_id: title_id });
19706
+ };
19707
+ /**
19708
+ * Update presence (position, heading, rich status) and refresh the TTL. Call
19709
+ * on a movement interval and on notable state changes.
19710
+ *
19711
+ * @param title_id Title UUID.
19712
+ * @param data New position/status for the player.
19713
+ */
19714
+ Multiplayer.updatePresence = function (title_id, data) {
19715
+ return Requests.processRoute(MultiplayerRoute.routes.updatePresence, data, { title_id: title_id });
19716
+ };
19717
+ /**
19718
+ * Leave the world. Frees the player's instance slot and realm population.
19719
+ *
19720
+ * @param title_id Title UUID.
19721
+ * @param data Optional player_id for title-token clients.
19722
+ */
19723
+ Multiplayer.leaveWorld = function (title_id, data) {
19724
+ return Requests.processRoute(MultiplayerRoute.routes.leaveWorld, data, { title_id: title_id });
19725
+ };
19726
+ // -----------------------------------------------------------------------
19727
+ // Matchmaking
19728
+ // -----------------------------------------------------------------------
19729
+ /**
19730
+ * Enqueue a matchmaking ticket. Idempotent per (queue, player): an existing
19731
+ * open ticket is returned rather than duplicated, so retries are safe. Poll
19732
+ * the ticket or subscribe to `matchmaking.matched` for the assignment.
19733
+ *
19734
+ * @param title_id Title UUID.
19735
+ * @param data Queue name plus optional party, skill, region, and attributes.
19736
+ * @example
19737
+ * Multiplayer.enqueueTicket('title-uuid', { player_id: 'steam:765...', queue: 'ranked_2v2', skill: 1840, region: 'us-central' });
19738
+ */
19739
+ Multiplayer.enqueueTicket = function (title_id, data) {
19740
+ return Requests.processRoute(MultiplayerRoute.routes.enqueueTicket, data, { title_id: title_id });
19741
+ };
19742
+ /**
19743
+ * Poll a matchmaking ticket. A queued ticket past its TTL is reported as
19744
+ * `timed_out`; a matched ticket carries the connection `assignment`.
19745
+ *
19746
+ * @param title_id Title UUID.
19747
+ * @param ticket_id Ticket UUID.
19748
+ */
19749
+ Multiplayer.showTicket = function (title_id, ticket_id) {
19750
+ return Requests.processRoute(MultiplayerRoute.routes.showTicket, undefined, { title_id: title_id, ticket_id: ticket_id });
19751
+ };
19752
+ /**
19753
+ * Cancel a queued matchmaking ticket.
19754
+ *
19755
+ * @param title_id Title UUID.
19756
+ * @param ticket_id Ticket UUID.
19757
+ */
19758
+ Multiplayer.cancelTicket = function (title_id, ticket_id) {
19759
+ return Requests.processRoute(MultiplayerRoute.routes.cancelTicket, undefined, { title_id: title_id, ticket_id: ticket_id });
19760
+ };
19761
+ // -----------------------------------------------------------------------
19762
+ // Real-time negotiate + trust/moderation
19763
+ // -----------------------------------------------------------------------
19764
+ /**
19765
+ * Negotiate a real-time push connection. Returns the authorized group names
19766
+ * and the push endpoint. When SignalR/Web PubSub is configured, an
19767
+ * access_token scoped to those groups is included; otherwise `configured` is
19768
+ * false and the client should fall back to the polling endpoints.
19769
+ *
19770
+ * @param title_id Title UUID.
19771
+ * @param data Optional player_id and the scopes (lobby/voice/zone/instance) to subscribe to.
19772
+ * @example
19773
+ * Multiplayer.negotiateRealtime('title-uuid', { player_id: 'steam:765...', scopes: [{ type: 'instance', id: 'instance-uuid' }] });
19774
+ */
19775
+ Multiplayer.negotiateRealtime = function (title_id, data) {
19776
+ return Requests.processRoute(MultiplayerRoute.routes.negotiateRealtime, data, { title_id: title_id });
19777
+ };
19778
+ /**
19779
+ * List bans for a title. Requires a title administrator JWT.
19780
+ *
19781
+ * @param title_id Title UUID.
19782
+ * @param params Optional scope/player/source filters and active_only.
19783
+ */
19784
+ Multiplayer.listBans = function (title_id, params) {
19785
+ return Requests.processRoute(MultiplayerRoute.routes.listBans, undefined, { title_id: title_id }, params);
19786
+ };
19787
+ /**
19788
+ * Ban a player at a scope (title/realm/lobby/server/voice). Requires a title
19789
+ * administrator JWT. Omit expires_at for a permanent ban.
19790
+ *
19791
+ * @param title_id Title UUID.
19792
+ * @param data Ban target and scope.
19793
+ * @example
19794
+ * Multiplayer.createBan('title-uuid', { player_id: 'steam:765...', scope: 'title', reason: 'Cheating: aimbot' });
19795
+ */
19796
+ Multiplayer.createBan = function (title_id, data) {
19797
+ return Requests.processRoute(MultiplayerRoute.routes.createBan, data, { title_id: title_id });
19798
+ };
19799
+ /**
19800
+ * Lift a ban. Requires a title administrator JWT.
19801
+ *
19802
+ * @param title_id Title UUID.
19803
+ * @param ban_id Ban UUID.
19804
+ */
19805
+ Multiplayer.deleteBan = function (title_id, ban_id) {
19806
+ return Requests.processRoute(MultiplayerRoute.routes.deleteBan, undefined, { title_id: title_id, ban_id: ban_id });
19807
+ };
19561
19808
  return Multiplayer;
19562
19809
  }());
19563
19810