@crowdedkingdomstudios/crowdyjs 5.0.0 → 5.0.1
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/README.md +46 -26
- package/dist/generated/graphql.d.ts +17 -0
- package/dist/generated/graphql.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ Auth and user reads always target `managementUrl`. Everything else targets `http
|
|
|
65
65
|
## Game-loop lifecycle
|
|
66
66
|
|
|
67
67
|
1. Authenticate with `client.auth.login()` or restore a previous token through `client.session.restore()`.
|
|
68
|
-
2. Subscribe to UDP proxy notifications with `client.udp.subscribe()` (the SDK
|
|
68
|
+
2. Subscribe to UDP proxy notifications with `client.udp.subscribe(handlers, appId)` — `appId` is **required** (the SDK opens the realtime socket on demand and scopes it to that app).
|
|
69
69
|
3. Join a chunk by sending an initial actor update.
|
|
70
70
|
4. Send actor, voxel, text, audio, and client-event updates through `client.udp` or the higher-level `client.world(appId)` helpers.
|
|
71
71
|
5. Call `client.udp.disconnect()` when leaving the world.
|
|
@@ -76,43 +76,63 @@ Auth and user reads always target `managementUrl`. Everything else targets `http
|
|
|
76
76
|
When a player is about to join an app, query its routing fields on the management API first:
|
|
77
77
|
|
|
78
78
|
```graphql
|
|
79
|
-
query AppForRouting($
|
|
80
|
-
app(
|
|
79
|
+
query AppForRouting($appId: BigInt!) {
|
|
80
|
+
app(appId: $appId) {
|
|
81
81
|
appId
|
|
82
82
|
splitMode
|
|
83
|
+
deploymentTarget
|
|
83
84
|
gameApiUrl
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
```
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
`gameApiUrl` is populated for **both** dedicated (`splitMode`) and shared
|
|
90
|
+
(`deploymentTarget: "shared"`) apps. When it's set, build a **second**
|
|
91
|
+
`CrowdyClient` with `httpUrl: gameApiUrl` (and the matching `wsUrl`) **sharing the
|
|
92
|
+
same `tokenStore` as the first client**, then drive gameplay through that client.
|
|
93
|
+
Apps with no `gameApiUrl` keep working against the default `httpUrl` you
|
|
94
|
+
configured.
|
|
89
95
|
|
|
90
96
|
## Realtime notifications
|
|
91
97
|
|
|
98
|
+
`subscribe` takes the handlers **and a required `appId`** (second argument). The
|
|
99
|
+
Game API scopes the realtime session to that app and rejects an app-agnostic
|
|
100
|
+
subscription with a `RealtimeConnectionEvent` (`code: 'APP_ID_REQUIRED'`). Run
|
|
101
|
+
one client per app (sharing the same `tokenStore`) when a player is in multiple
|
|
102
|
+
apps at once.
|
|
103
|
+
|
|
92
104
|
```ts
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
const appId = '1';
|
|
106
|
+
|
|
107
|
+
const unsubscribe = client.udp.subscribe(
|
|
108
|
+
{
|
|
109
|
+
actorUpdate: (event) => {
|
|
110
|
+
console.log(event.uuid, event.state);
|
|
111
|
+
},
|
|
112
|
+
voxelUpdate: (event) => { /* ... */ },
|
|
113
|
+
text: (event) => { /* ... */ },
|
|
114
|
+
audio: (event) => { /* ... */ },
|
|
115
|
+
clientEvent: (event) => { /* ... */ },
|
|
116
|
+
serverEvent: (event) => { /* ... */ },
|
|
117
|
+
singleActorMessage: (event) => {
|
|
118
|
+
// A direct actor-to-actor message addressed to you.
|
|
119
|
+
console.log(event.uuid, event.payload); // payload is base64
|
|
120
|
+
},
|
|
121
|
+
genericError: (event) => {
|
|
122
|
+
console.warn(event.sequenceNumber, event.errorCode);
|
|
123
|
+
},
|
|
124
|
+
connectionEvent: (event) => {
|
|
125
|
+
console.warn(event.code, event.message);
|
|
126
|
+
},
|
|
127
|
+
error: (error) => {
|
|
128
|
+
console.error(error.code, error.message);
|
|
129
|
+
},
|
|
111
130
|
},
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
appId,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Or use the world helper, which passes its appId automatically:
|
|
135
|
+
// client.world(appId).subscribe(handlers);
|
|
116
136
|
|
|
117
137
|
client.realtime.onStatus((status) => {
|
|
118
138
|
console.log('realtime:', status);
|
|
@@ -1663,6 +1663,12 @@ export type JoinSessionInput = {
|
|
|
1663
1663
|
role?: InputMaybe<Scalars['String']['input']>;
|
|
1664
1664
|
sessionId: Scalars['String']['input'];
|
|
1665
1665
|
};
|
|
1666
|
+
export type LinkAppToEnvironmentInput = {
|
|
1667
|
+
appId: Scalars['BigInt']['input'];
|
|
1668
|
+
/** Environment slug (cks_environments.slug) to link the app to. */
|
|
1669
|
+
environmentSlug: Scalars['String']['input'];
|
|
1670
|
+
orgId: Scalars['BigInt']['input'];
|
|
1671
|
+
};
|
|
1666
1672
|
export type ListVoxelUpdatesByDistanceInput = {
|
|
1667
1673
|
appId: Scalars['BigInt']['input'];
|
|
1668
1674
|
centerCoordinate: ChunkCoordinatesInput;
|
|
@@ -1776,6 +1782,8 @@ export type Mutation = {
|
|
|
1776
1782
|
leaveChannel: Scalars['Boolean']['output'];
|
|
1777
1783
|
/** Leave a team. */
|
|
1778
1784
|
leaveTeam: Scalars['Boolean']['output'];
|
|
1785
|
+
/** Links an unlinked app to an existing environment for split-mode routing. Refuses shared apps and apps already linked elsewhere. */
|
|
1786
|
+
linkAppToEnvironment: App;
|
|
1779
1787
|
login: AuthResponse;
|
|
1780
1788
|
logout: Scalars['Boolean']['output'];
|
|
1781
1789
|
logoutAllDevices: Scalars['Boolean']['output'];
|
|
@@ -2067,6 +2075,9 @@ export type MutationLeaveChannelArgs = {
|
|
|
2067
2075
|
export type MutationLeaveTeamArgs = {
|
|
2068
2076
|
groupId: Scalars['BigInt']['input'];
|
|
2069
2077
|
};
|
|
2078
|
+
export type MutationLinkAppToEnvironmentArgs = {
|
|
2079
|
+
input: LinkAppToEnvironmentInput;
|
|
2080
|
+
};
|
|
2070
2081
|
export type MutationLoginArgs = {
|
|
2071
2082
|
loginUserInput: LoginUserInput;
|
|
2072
2083
|
};
|
|
@@ -2551,6 +2562,7 @@ export type Query = {
|
|
|
2551
2562
|
environmentDatacenters: Array<CksOvhDatacenter>;
|
|
2552
2563
|
/** Customer-selectable instance flavors in the datacenter with current availability and customer pricing. */
|
|
2553
2564
|
environmentFlavors: Array<CksOvhFlavor>;
|
|
2565
|
+
environmentForwardVersions: Array<CksEnvironmentVersion>;
|
|
2554
2566
|
/** Pricing quote for the selected flavors. Fails if any flavor is unavailable, hidden, or lacks customer pricing. */
|
|
2555
2567
|
environmentQuote: CksEnvironmentQuote;
|
|
2556
2568
|
/** Per-app usage totals for apps linked to an environment. */
|
|
@@ -2786,6 +2798,10 @@ export type QueryEffectiveQuotaArgs = {
|
|
|
2786
2798
|
export type QueryEnvironmentFlavorsArgs = {
|
|
2787
2799
|
datacenter: Scalars['String']['input'];
|
|
2788
2800
|
};
|
|
2801
|
+
export type QueryEnvironmentForwardVersionsArgs = {
|
|
2802
|
+
orgId: Scalars['BigInt']['input'];
|
|
2803
|
+
slug: Scalars['String']['input'];
|
|
2804
|
+
};
|
|
2789
2805
|
export type QueryEnvironmentQuoteArgs = {
|
|
2790
2806
|
input: EnvironmentQuoteInput;
|
|
2791
2807
|
};
|
|
@@ -3028,6 +3044,7 @@ export type RedeployEnvironmentInput = {
|
|
|
3028
3044
|
deployMode?: InputMaybe<RedeployDeployMode>;
|
|
3029
3045
|
orgId: Scalars['BigInt']['input'];
|
|
3030
3046
|
slug: Scalars['String']['input'];
|
|
3047
|
+
version?: InputMaybe<Scalars['String']['input']>;
|
|
3031
3048
|
};
|
|
3032
3049
|
export type RegisterUserInput = {
|
|
3033
3050
|
email: Scalars['String']['input'];
|