incanto 0.50.0 → 0.52.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/dist/2d.d.ts +38 -2
- package/dist/2d.js +3 -3
- package/dist/3d.d.ts +4 -3
- package/dist/3d.js +4 -4
- package/dist/{behavior-62q0HWBO.d.ts → behavior-uPEuZrUB.d.ts} +47 -3
- package/dist/{create-game-BLDjy_PW.js → create-game-B_e9hJf7.js} +92 -10
- package/dist/{create-game-DqqxEax1.js → create-game-CGnoypjL.js} +6 -6
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +1 -1
- package/dist/{duplicate-CI9WF_bg.js → duplicate-B-OtSRFL.js} +1 -1
- package/dist/editor.js +1917 -1579
- package/dist/{environment-presets-XFuqu5jv.js → environment-presets-DSZwsKPs.js} +3 -3
- package/dist/{gameplay-DbaI313d.js → gameplay-B6jqvYeM.js} +163 -6
- package/dist/gameplay.d.ts +79 -2
- package/dist/gameplay.js +2 -2
- package/dist/index.d.ts +74 -5
- package/dist/index.js +7 -7
- package/dist/{loader-DwazzlQb.js → loader-B-Gft32x.js} +372 -23
- package/dist/{loader-CeyU_bm1.d.ts → loader-B9iTqs27.d.ts} +1 -1
- package/dist/net.d.ts +15 -410
- package/dist/net.js +1 -822
- package/dist/{pathfinding-C49JSNNq.d.ts → pathfinding-CAR9DjQQ.d.ts} +1 -1
- package/dist/{physics-2d-_9VBOHn6.js → physics-2d-Dns-oZlE.js} +7 -2
- package/dist/{physics-3d-DrpF5hcG.js → physics-3d-BhI0ehpe.js} +8 -3
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-uvaZj1KX.js → register-DVwlnZAZ.js} +20 -266
- package/dist/{register-BNPZYJmd.js → register-Trx7WHnD.js} +3 -3
- package/dist/{registry-IyWCGe4q.js → registry-C7u42TID.js} +23 -1
- package/dist/{replay-DYdy1wb0.d.ts → replay-BU1CCM15.d.ts} +1 -1
- package/dist/{replay-j-m6lJ4W.js → replay-BicPOMX0.js} +214 -2
- package/dist/split-screen-CZ9ccBBQ.js +1267 -0
- package/dist/split-screen-paxkQs_q.d.ts +441 -0
- package/dist/{src-B3HrKuAi.js → src-5gbZO47I.js} +1 -1
- package/dist/{teardown-BKTCzLek.js → teardown-ks3d5W9n.js} +2 -1
- package/dist/{test-D16igj4C.js → test-DAojuFdb.js} +119 -22
- package/dist/test.d.ts +60 -5
- package/dist/test.js +3 -3
- package/dist/vite.js +2 -2
- package/editor/assets/{agent8-t3kl5q9K.js → agent8-CCvckvbw.js} +1 -1
- package/editor/assets/{debug-Bu3eeAlO.js → debug-CLNCOnbc.js} +1 -1
- package/editor/assets/{index-Df5g8ofT.js → index-Cb5Brupb.js} +99 -92
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/skills/incanto-assets.md +4 -1
- package/skills/incanto-building-2d-games.md +6 -1
- package/skills/incanto-editor.md +48 -11
- package/skills/incanto-gameplay-behaviors.md +14 -5
- package/skills/incanto-multiplayer.md +39 -3
- package/skills/incanto-node-reference.md +13 -0
- package/skills/incanto-save-slots.md +134 -12
- package/skills/incanto-verifying-your-game.md +56 -0
- package/templates/agent8-server.ts +79 -2
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/village-quest-3d/package.json +1 -1
- package/dist/register-CB11yp21.js +0 -374
package/dist/net.d.ts
CHANGED
|
@@ -1,58 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as
|
|
1
|
+
import { Dt as Node, d as PropSchema } from "./behavior-uPEuZrUB.js";
|
|
2
|
+
import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen-paxkQs_q.js";
|
|
3
3
|
|
|
4
|
-
//#region src/net/types.d.ts
|
|
5
|
-
type Unsubscribe = () => void;
|
|
6
|
-
/**
|
|
7
|
-
* Incanto's pluggable multiplayer transport contract. The engine speaks ONLY
|
|
8
|
-
* this interface — any backend works by implementing it:
|
|
9
|
-
*
|
|
10
|
-
* - `LoopbackTransport` (built in): in-memory — offline dev, tests, split-screen
|
|
11
|
-
* - `createAgent8Server()` (built in): adapter for `@agent8/gameserver`
|
|
12
|
-
* - your own: Socket.IO, Colyseus, Supabase Realtime, a custom WebSocket server…
|
|
13
|
-
*
|
|
14
|
-
* The room protocol a transport's backend must answer via `remoteFunction`:
|
|
15
|
-
* `joinRoom(roomId?) → roomId` · `leaveRoom(roomId)` · `setMyState(roomId, patch)`
|
|
16
|
-
* (SHALLOW merge) · `patchRoomState(roomId, patch)` · `addEntity(roomId, coll,
|
|
17
|
-
* entity) → id` · `updateEntity(roomId, coll, id, patch)` · `removeEntity(roomId,
|
|
18
|
-
* coll, id)` · `sendEvent(roomId, type, payload)`.
|
|
19
|
-
* (The shape happens to align with @agent8/gameserver's GameServer class, so that
|
|
20
|
-
* adapter is thin — but nothing in the engine depends on that backend.)
|
|
21
|
-
*/
|
|
22
|
-
interface NetworkTransport {
|
|
23
|
-
readonly account: string;
|
|
24
|
-
readonly connected: boolean;
|
|
25
|
-
connect(): Promise<boolean>;
|
|
26
|
-
disconnect(): Promise<void>;
|
|
27
|
-
/** Calls a function defined in the game's server.js (see templates/agent8-server.js). */
|
|
28
|
-
remoteFunction(fn: string, args?: unknown[], opts?: {
|
|
29
|
-
needResponse?: boolean;
|
|
30
|
-
throttle?: number;
|
|
31
|
-
throttleKey?: string;
|
|
32
|
-
}): Promise<unknown>;
|
|
33
|
-
subscribeRoomState(roomId: string, cb: (state: JsonObject) => void): Unsubscribe;
|
|
34
|
-
subscribeRoomMyState(roomId: string, cb: (state: JsonObject) => void): Unsubscribe;
|
|
35
|
-
subscribeRoomAllUserStates(roomId: string, cb: (states: Record<string, JsonObject>) => void): Unsubscribe;
|
|
36
|
-
subscribeRoomCollection(roomId: string, collectionId: string, cb: (entities: Record<string, JsonObject>) => void): Unsubscribe;
|
|
37
|
-
onRoomMessage(roomId: string, type: string, cb: (message: JsonValue) => void): Unsubscribe;
|
|
38
|
-
onRoomUserJoin(roomId: string, cb: (account: string) => void): Unsubscribe;
|
|
39
|
-
onRoomUserLeave(roomId: string, cb: (account: string) => void): Unsubscribe;
|
|
40
|
-
/**
|
|
41
|
-
* GLOBAL (cross-room, persistent) channels — OPTIONAL. A backend that has no
|
|
42
|
-
* global tier (e.g. the fixed `LoopbackHub`) simply omits them; NetworkManager
|
|
43
|
-
* degrades gracefully (its global signals never fire). `LocalGameServer` and the
|
|
44
|
-
* agent8 adapter implement them. Each fires the current value once on subscribe.
|
|
45
|
-
*/
|
|
46
|
-
subscribeGlobalState?(cb: (state: JsonObject) => void): Unsubscribe;
|
|
47
|
-
/** The caller's own global user state. */
|
|
48
|
-
subscribeGlobalMyState?(cb: (state: JsonObject) => void): Unsubscribe;
|
|
49
|
-
subscribeGlobalUserState?(account: string, cb: (state: JsonObject) => void): Unsubscribe;
|
|
50
|
-
subscribeGlobalCollection?(collectionId: string, cb: (entities: Record<string, JsonObject>) => void): Unsubscribe;
|
|
51
|
-
/** An account's currency ledger (`$asset`). */
|
|
52
|
-
subscribeAsset?(account: string, cb: (assets: Record<string, number>) => void): Unsubscribe;
|
|
53
|
-
onGlobalMessage?(type: string, cb: (message: JsonValue) => void): Unsubscribe;
|
|
54
|
-
}
|
|
55
|
-
//#endregion
|
|
56
4
|
//#region src/net/agent8.d.ts
|
|
57
5
|
/**
|
|
58
6
|
* The real transport: wraps `@agent8/gameserver`'s framework-free GameServer
|
|
@@ -76,318 +24,6 @@ declare function createAgent8Server(config?: {
|
|
|
76
24
|
auth?: string;
|
|
77
25
|
}): Promise<NetworkTransport>;
|
|
78
26
|
//#endregion
|
|
79
|
-
//#region src/net/loopback.d.ts
|
|
80
|
-
interface Room {
|
|
81
|
-
users: Map<string, JsonObject>;
|
|
82
|
-
state: JsonObject;
|
|
83
|
-
collections: Map<string, Map<string, JsonObject>>;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* In-memory multiplayer hub implementing the SAME kernel contract as
|
|
87
|
-
* `templates/agent8-server.js` — local split-screen demos, offline development,
|
|
88
|
-
* and headless tests run real multi-client flows without any infrastructure.
|
|
89
|
-
*/
|
|
90
|
-
declare class LoopbackHub {
|
|
91
|
-
private readonly rooms;
|
|
92
|
-
private accountSeq;
|
|
93
|
-
private roomSeq;
|
|
94
|
-
private entitySeq;
|
|
95
|
-
/** Per-room listener registries, keyed by roomId. */
|
|
96
|
-
private readonly listeners;
|
|
97
|
-
createClient(account?: string): LoopbackTransport;
|
|
98
|
-
/** @internal */
|
|
99
|
-
_room(roomId: string): Room;
|
|
100
|
-
/** @internal The server.js kernel, in memory. */
|
|
101
|
-
_call(account: string, fn: string, args: unknown[]): unknown;
|
|
102
|
-
/** @internal */
|
|
103
|
-
_subscribe<K extends keyof LoopbackHub["listeners"]>(kind: K, roomId: string, entry: LoopbackHub["listeners"][K] extends Map<string, Set<infer E>> ? E : never): Unsubscribe;
|
|
104
|
-
/** @internal */
|
|
105
|
-
_snapshotUsers(roomId: string): Record<string, JsonObject>;
|
|
106
|
-
/** @internal */
|
|
107
|
-
_snapshotCollection(roomId: string, collectionId: string): Record<string, JsonObject>;
|
|
108
|
-
/** @internal */
|
|
109
|
-
_snapshotRoomState(roomId: string): JsonObject;
|
|
110
|
-
private fire;
|
|
111
|
-
private fireAllUsers;
|
|
112
|
-
private fireCollection;
|
|
113
|
-
}
|
|
114
|
-
/** A client on a LoopbackHub. Subscriptions fire immediately with a snapshot. */
|
|
115
|
-
declare class LoopbackTransport implements NetworkTransport {
|
|
116
|
-
private readonly hub;
|
|
117
|
-
readonly account: string;
|
|
118
|
-
connected: boolean;
|
|
119
|
-
constructor(hub: LoopbackHub, account: string);
|
|
120
|
-
connect(): Promise<boolean>;
|
|
121
|
-
disconnect(): Promise<void>;
|
|
122
|
-
remoteFunction(fn: string, args?: unknown[]): Promise<unknown>;
|
|
123
|
-
subscribeRoomState(roomId: string, cb: (state: JsonObject) => void): Unsubscribe;
|
|
124
|
-
subscribeRoomMyState(roomId: string, cb: (state: JsonObject) => void): Unsubscribe;
|
|
125
|
-
subscribeRoomAllUserStates(roomId: string, cb: (states: Record<string, JsonObject>) => void): Unsubscribe;
|
|
126
|
-
subscribeRoomCollection(roomId: string, collectionId: string, cb: (entities: Record<string, JsonObject>) => void): Unsubscribe;
|
|
127
|
-
onRoomMessage(roomId: string, type: string, cb: (message: JsonValue) => void): Unsubscribe;
|
|
128
|
-
onRoomUserJoin(roomId: string, cb: (account: string) => void): Unsubscribe;
|
|
129
|
-
onRoomUserLeave(roomId: string, cb: (account: string) => void): Unsubscribe;
|
|
130
|
-
}
|
|
131
|
-
//#endregion
|
|
132
|
-
//#region src/net/local-game-server.d.ts
|
|
133
|
-
/** A user's `server/src/server.ts` `Server` class (or any class with room methods). */
|
|
134
|
-
type ServerClass = new () => object;
|
|
135
|
-
interface LocalGameServerOptions {
|
|
136
|
-
/**
|
|
137
|
-
* The game's `Server` class from `server/src/server.ts` (the v2 structured
|
|
138
|
-
* project). Omit it to fall back to the built-in kernel only — identical to a
|
|
139
|
-
* raw `LoopbackHub`.
|
|
140
|
-
*/
|
|
141
|
-
server?: ServerClass;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Run a multiplayer game's REAL agent8-sdk-v2 `Server` class **locally**, in
|
|
145
|
-
* memory, with NO cloud and NO auth — the preview/dev path.
|
|
146
|
-
*
|
|
147
|
-
* `LoopbackHub` answers only the fixed built-in room protocol (joinRoom,
|
|
148
|
-
* setMyState, collections, events). Real games add server-AUTHORITATIVE rules
|
|
149
|
-
* (`awardPoint`, `castSpell`, `$roomTick` match clocks) in `server/src/server.ts`
|
|
150
|
-
* against the v2 contexts `$sender`/`$global`/`$room`/`$lock`. LocalGameServer
|
|
151
|
-
* runs that exact class body so the whole game — client + server logic — is
|
|
152
|
-
* playable in dev before it ever touches the Agent8 platform. Swap
|
|
153
|
-
* `local.createClient(account)` for `await createAgent8Server()` to go live;
|
|
154
|
-
* nothing else changes.
|
|
155
|
-
*
|
|
156
|
-
* How it stays faithful to the isolated-vm platform:
|
|
157
|
-
* - A FRESH `Server` instance runs per request, so `this.*` never persists.
|
|
158
|
-
* - The v2 globals are injected on `globalThis` for the duration of each call
|
|
159
|
-
* (the SAME `server/src/server.ts` body that reads bare `$room`/`$sender`
|
|
160
|
-
* runs unmodified).
|
|
161
|
-
* - Calls are SERIALIZED through one queue, so a global binding can't leak across
|
|
162
|
-
* another request's `await`s (the platform isolates per request; we serialize).
|
|
163
|
-
* - `$roomTick(deltaMS, roomId)` runs only while a room has users — drive it from
|
|
164
|
-
* the engine: `engine.updated.connect((dt) => local.tick(dt * 1000))`.
|
|
165
|
-
*
|
|
166
|
-
* NOT a substitute for the cloud: no isolated-vm sandboxing, no persistence, no
|
|
167
|
-
* rate limits — a faithful FUNCTIONAL emulator for local play and tests.
|
|
168
|
-
*/
|
|
169
|
-
declare class LocalGameServer {
|
|
170
|
-
private readonly hub;
|
|
171
|
-
private readonly serverClass?;
|
|
172
|
-
/** Each client's current room — binds `$sender.roomId` on later calls. */
|
|
173
|
-
private readonly clientRooms;
|
|
174
|
-
/** All remoteFunction/tick calls run one-at-a-time so injected globals never overlap. */
|
|
175
|
-
private queue;
|
|
176
|
-
/** Per-key mutex backing `$lock`. */
|
|
177
|
-
private readonly locks;
|
|
178
|
-
/** Persistent (process-lifetime) store backing the `$global` + `$asset` contexts. */
|
|
179
|
-
private readonly g_state;
|
|
180
|
-
private readonly g_userStates;
|
|
181
|
-
private readonly g_collections;
|
|
182
|
-
private readonly g_assets;
|
|
183
|
-
private g_seq;
|
|
184
|
-
/** Client-side global/asset subscription registries (fanned out on mutation). */
|
|
185
|
-
private readonly subState;
|
|
186
|
-
private readonly subUser;
|
|
187
|
-
private readonly subColl;
|
|
188
|
-
private readonly subAsset;
|
|
189
|
-
private readonly subMsg;
|
|
190
|
-
constructor(serverClass?: ServerClass);
|
|
191
|
-
/** A client on this server. Distinct `account` per player (default auto-assigned). */
|
|
192
|
-
createClient(account?: string): LocalGameServerTransport;
|
|
193
|
-
private collectionSnapshot;
|
|
194
|
-
private assetSnapshot;
|
|
195
|
-
/** @internal */
|
|
196
|
-
subscribeGlobalState(cb: (s: JsonObject) => void): Unsubscribe;
|
|
197
|
-
/** @internal */
|
|
198
|
-
subscribeGlobalUserState(account: string, cb: (s: JsonObject) => void): Unsubscribe;
|
|
199
|
-
/** @internal */
|
|
200
|
-
subscribeGlobalCollection(id: string, cb: (r: Record<string, JsonObject>) => void): Unsubscribe;
|
|
201
|
-
/** @internal */
|
|
202
|
-
subscribeAsset(account: string, cb: (a: Record<string, number>) => void): Unsubscribe;
|
|
203
|
-
/** @internal Messages are events — no immediate snapshot. */
|
|
204
|
-
onGlobalMessage(account: string, type: string, cb: (m: JsonValue) => void): Unsubscribe;
|
|
205
|
-
private fireState;
|
|
206
|
-
private fireUser;
|
|
207
|
-
private fireColl;
|
|
208
|
-
private fireAsset;
|
|
209
|
-
private fireMsg;
|
|
210
|
-
/**
|
|
211
|
-
* Advance server-driven periodic logic. Calls the `Server`'s `$roomTick(deltaMS,
|
|
212
|
-
* roomId)` once per room that currently has users. No-op without a `$roomTick`.
|
|
213
|
-
*/
|
|
214
|
-
tick(deltaMS: number): Promise<void>;
|
|
215
|
-
/** @internal Dispatch a remoteFunction (serialized). */
|
|
216
|
-
call(account: string, fn: string, args: unknown[]): Promise<unknown>;
|
|
217
|
-
private enqueue;
|
|
218
|
-
private dispatch;
|
|
219
|
-
private runTick;
|
|
220
|
-
/** Install the v2 globals for one dispatch; returns a restorer. */
|
|
221
|
-
private bindGlobals;
|
|
222
|
-
/**
|
|
223
|
-
* The `$global` context — room membership, persistent GLOBAL state/user-state/
|
|
224
|
-
* collections, room management, and global messaging. Backed by an in-memory
|
|
225
|
-
* store that survives between requests (unlike rooms, which the hub clears when
|
|
226
|
-
* empty) — matching the platform's persistent-global / ephemeral-room split.
|
|
227
|
-
*/
|
|
228
|
-
private globalContext;
|
|
229
|
-
/**
|
|
230
|
-
* The `$asset` context — a per-account currency ledger. `burn`/`transfer` throw
|
|
231
|
-
* on an insufficient balance (the documented pattern always checks `has` first),
|
|
232
|
-
* surfacing economy bugs in preview just as the platform would.
|
|
233
|
-
*/
|
|
234
|
-
private assetContext;
|
|
235
|
-
/** The `$room` context, bound to one room — maps onto the hub's kernel primitives. */
|
|
236
|
-
private roomContext;
|
|
237
|
-
private withLock;
|
|
238
|
-
}
|
|
239
|
-
/** Firebase-style query options for `$global`/`$room` collections (preview subset). */
|
|
240
|
-
interface CollectionOptions {
|
|
241
|
-
filters?: {
|
|
242
|
-
field: string;
|
|
243
|
-
operator: string;
|
|
244
|
-
value: JsonValue;
|
|
245
|
-
}[];
|
|
246
|
-
orderBy?: {
|
|
247
|
-
field: string;
|
|
248
|
-
direction?: "asc" | "desc";
|
|
249
|
-
}[];
|
|
250
|
-
limit?: number;
|
|
251
|
-
startAfter?: JsonValue;
|
|
252
|
-
endBefore?: JsonValue;
|
|
253
|
-
}
|
|
254
|
-
/** Construct a local preview server. With no `server`, it equals a raw LoopbackHub. */
|
|
255
|
-
declare function createLocalGameServer(opts?: LocalGameServerOptions): LocalGameServer;
|
|
256
|
-
/**
|
|
257
|
-
* A client of a {@link LocalGameServer}. Subscriptions read the shared in-memory
|
|
258
|
-
* store directly (same fan-out as Loopback); `remoteFunction` routes through the
|
|
259
|
-
* server's serialized dispatch so the game's `Server` class actually runs.
|
|
260
|
-
*/
|
|
261
|
-
declare class LocalGameServerTransport implements NetworkTransport {
|
|
262
|
-
private readonly server;
|
|
263
|
-
private readonly loop;
|
|
264
|
-
readonly account: string;
|
|
265
|
-
connected: boolean;
|
|
266
|
-
constructor(server: LocalGameServer, loop: LoopbackTransport);
|
|
267
|
-
connect(): Promise<boolean>;
|
|
268
|
-
disconnect(): Promise<void>;
|
|
269
|
-
remoteFunction(fn: string, args?: unknown[]): Promise<unknown>;
|
|
270
|
-
subscribeRoomState(roomId: string, cb: (state: JsonObject) => void): Unsubscribe;
|
|
271
|
-
subscribeRoomMyState(roomId: string, cb: (state: JsonObject) => void): Unsubscribe;
|
|
272
|
-
subscribeRoomAllUserStates(roomId: string, cb: (states: Record<string, JsonObject>) => void): Unsubscribe;
|
|
273
|
-
subscribeRoomCollection(roomId: string, collectionId: string, cb: (entities: Record<string, JsonObject>) => void): Unsubscribe;
|
|
274
|
-
onRoomMessage(roomId: string, type: string, cb: (message: JsonValue) => void): Unsubscribe;
|
|
275
|
-
onRoomUserJoin(roomId: string, cb: (account: string) => void): Unsubscribe;
|
|
276
|
-
onRoomUserLeave(roomId: string, cb: (account: string) => void): Unsubscribe;
|
|
277
|
-
subscribeGlobalState(cb: (state: JsonObject) => void): Unsubscribe;
|
|
278
|
-
subscribeGlobalMyState(cb: (state: JsonObject) => void): Unsubscribe;
|
|
279
|
-
subscribeGlobalUserState(account: string, cb: (state: JsonObject) => void): Unsubscribe;
|
|
280
|
-
subscribeGlobalCollection(collectionId: string, cb: (entities: Record<string, JsonObject>) => void): Unsubscribe;
|
|
281
|
-
subscribeAsset(account: string, cb: (assets: Record<string, number>) => void): Unsubscribe;
|
|
282
|
-
onGlobalMessage(type: string, cb: (message: JsonValue) => void): Unsubscribe;
|
|
283
|
-
}
|
|
284
|
-
//#endregion
|
|
285
|
-
//#region src/net/network-manager.d.ts
|
|
286
|
-
interface NetworkManagerOptions {
|
|
287
|
-
/**
|
|
288
|
-
* The transport to speak through — `LoopbackTransport` (offline/dev/tests),
|
|
289
|
-
* `await createAgent8Server()` (agent8 platform), or any custom
|
|
290
|
-
* NetworkTransport implementation. Default: the agent8 adapter.
|
|
291
|
-
*/
|
|
292
|
-
transport?: NetworkTransport;
|
|
293
|
-
/** Room id; default: scene `multiplayer.room` ('auto' = server-assigned). */
|
|
294
|
-
room?: string;
|
|
295
|
-
/** Config for the default agent8 adapter (ignored when `transport` is injected). */
|
|
296
|
-
config?: {
|
|
297
|
-
verse?: string;
|
|
298
|
-
account?: string;
|
|
299
|
-
auth?: string;
|
|
300
|
-
};
|
|
301
|
-
/** Replication send window in ms (default 50; node `network.throttleMs` can lower it). */
|
|
302
|
-
throttleMs?: number;
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Per-engine multiplayer hub: joins a room, exposes the room channels as core
|
|
306
|
-
* Signals, replicates `network: {mode:'owner'}` node props on a throttle
|
|
307
|
-
* window, and resolves registered scenes for NetworkSpawner.
|
|
308
|
-
*/
|
|
309
|
-
declare class NetworkManager {
|
|
310
|
-
readonly account: string;
|
|
311
|
-
readonly roomId: string;
|
|
312
|
-
readonly roomState: Signal<[JsonObject]>;
|
|
313
|
-
readonly allUserStates: Signal<[Record<string, JsonObject>]>;
|
|
314
|
-
readonly userJoined: Signal<[string]>;
|
|
315
|
-
readonly userLeft: Signal<[string]>;
|
|
316
|
-
/**
|
|
317
|
-
* GLOBAL (cross-room, persistent) channels — populated only when the transport
|
|
318
|
-
* supports them (`LocalGameServer`, the agent8 adapter). On a transport without a
|
|
319
|
-
* global tier they stay empty / never fire.
|
|
320
|
-
*/
|
|
321
|
-
readonly globalState: Signal<[JsonObject]>;
|
|
322
|
-
readonly globalMyState: Signal<[JsonObject]>;
|
|
323
|
-
/** The local account's `$asset` ledger. */
|
|
324
|
-
readonly asset: Signal<[Record<string, number>]>;
|
|
325
|
-
/** Latest snapshots for polling consumers (NetworkSpawner). */
|
|
326
|
-
latestUserStates: Record<string, JsonObject>;
|
|
327
|
-
latestRoomState: JsonObject;
|
|
328
|
-
latestGlobalState: JsonObject;
|
|
329
|
-
latestGlobalMyState: JsonObject;
|
|
330
|
-
latestAsset: Record<string, number>;
|
|
331
|
-
private readonly server;
|
|
332
|
-
private readonly engine;
|
|
333
|
-
private readonly throttleMs;
|
|
334
|
-
private readonly subs;
|
|
335
|
-
private readonly messageSignals;
|
|
336
|
-
private readonly collectionSignals;
|
|
337
|
-
private readonly latestCollections;
|
|
338
|
-
private readonly globalMessageSignals;
|
|
339
|
-
private readonly globalCollectionSignals;
|
|
340
|
-
private readonly latestGlobalCollections;
|
|
341
|
-
private readonly scenes;
|
|
342
|
-
private readonly lastSent;
|
|
343
|
-
private sendAccumulator;
|
|
344
|
-
private detachReplication;
|
|
345
|
-
private lastOwner;
|
|
346
|
-
private boundScene;
|
|
347
|
-
static get(engine: Engine): NetworkManager | null;
|
|
348
|
-
static create(engine: Engine, opts?: NetworkManagerOptions): Promise<NetworkManager>;
|
|
349
|
-
private constructor();
|
|
350
|
-
/** Signal for a typed room message (`sendEvent` on any client). */
|
|
351
|
-
message(type: string): Signal<[JsonValue]>;
|
|
352
|
-
/** Signal + snapshot for a room collection (spawned entities). */
|
|
353
|
-
collection(id: string): Signal<[Record<string, JsonObject>]>;
|
|
354
|
-
latestCollection(id: string): Record<string, JsonObject>;
|
|
355
|
-
/** Signal for a typed GLOBAL message (`$global.broadcastToAll`/`sendMessageToUser`). */
|
|
356
|
-
globalMessage(type: string): Signal<[JsonValue]>;
|
|
357
|
-
/** Signal + snapshot for a GLOBAL collection (persistent, cross-room). */
|
|
358
|
-
globalCollection(id: string): Signal<[Record<string, JsonObject>]>;
|
|
359
|
-
latestGlobalCollection(id: string): Record<string, JsonObject>;
|
|
360
|
-
setMyState(patch: JsonObject): Promise<unknown>;
|
|
361
|
-
patchRoomState(patch: JsonObject): Promise<unknown>;
|
|
362
|
-
addEntity(collectionId: string, entity: JsonObject): Promise<unknown>;
|
|
363
|
-
updateEntity(collectionId: string, id: string, patch: JsonObject): Promise<unknown>;
|
|
364
|
-
removeEntity(collectionId: string, id: string): Promise<unknown>;
|
|
365
|
-
sendEvent(type: string, payload: JsonValue): Promise<unknown>;
|
|
366
|
-
/**
|
|
367
|
-
* Invoke a CUSTOM server-authoritative function — a method you added to your
|
|
368
|
-
* `server/src/server.ts` `Server` class (run live on the Agent8 platform, or
|
|
369
|
-
* locally via `createLocalGameServer`). The room id is prepended automatically,
|
|
370
|
-
* matching the `(roomId, …)` shape every server method takes:
|
|
371
|
-
*
|
|
372
|
-
* `manager.call('claimCoin', coinId)` → server `claimCoin(roomId, coinId)`
|
|
373
|
-
*
|
|
374
|
-
* Returns the function's result (use it for server-validated outcomes — a
|
|
375
|
-
* rejected claim, a rolled value). This is THE entry point for game rules the
|
|
376
|
-
* client must not be trusted to compute.
|
|
377
|
-
*/
|
|
378
|
-
call(fn: string, ...args: JsonValue[]): Promise<unknown>;
|
|
379
|
-
/** Register a scene for NetworkSpawner (`"scene": "<key>"`). */
|
|
380
|
-
registerScene(key: string, json: SceneJson): void;
|
|
381
|
-
resolveScene(key: string): SceneJson;
|
|
382
|
-
dispose(): Promise<void>;
|
|
383
|
-
private replicate;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* @internal Applies a replicated flat sync patch (`{'position': …,
|
|
387
|
-
* 'Sprite.animation': …}`) onto a spawned subtree (NetworkSpawner).
|
|
388
|
-
*/
|
|
389
|
-
declare function applySyncPatch(root: Node, patch: JsonObject, setProp: (target: Node, prop: string, value: JsonValue) => void): void;
|
|
390
|
-
//#endregion
|
|
391
27
|
//#region src/net/nodes/network-spawner.d.ts
|
|
392
28
|
/**
|
|
393
29
|
* Materializes a registered scene per remote player or collection entity:
|
|
@@ -411,8 +47,21 @@ declare class NetworkSpawner extends Node {
|
|
|
411
47
|
private readonly spawned;
|
|
412
48
|
private readonly positionTargets;
|
|
413
49
|
private readonly failedKeys;
|
|
50
|
+
private readonly reported;
|
|
414
51
|
override update(dt: number): void;
|
|
415
52
|
private currentEntries;
|
|
53
|
+
/**
|
|
54
|
+
* The replicated fields of one entry.
|
|
55
|
+
*
|
|
56
|
+
* A USER state carries them under `sync` (that is what the owner node sends).
|
|
57
|
+
* A COLLECTION entity is written by your SERVER, which has no reason to know
|
|
58
|
+
* that convention — `addCollectionItem('coins', { position: [x, y] })` is the
|
|
59
|
+
* obvious thing to write, and it used to apply nothing at all. Both work:
|
|
60
|
+
* `sync` when present, otherwise the entity minus the platform's own keys.
|
|
61
|
+
*/
|
|
62
|
+
private patchOf;
|
|
63
|
+
/** Say it ONCE per message — a per-frame repeat would drown the log. */
|
|
64
|
+
private report;
|
|
416
65
|
private setProp;
|
|
417
66
|
private stepInterpolation;
|
|
418
67
|
}
|
|
@@ -424,48 +73,4 @@ declare class NetworkSpawner extends Node {
|
|
|
424
73
|
*/
|
|
425
74
|
declare function registerNodesNet(): void;
|
|
426
75
|
//#endregion
|
|
427
|
-
//#region src/net/split-screen.d.ts
|
|
428
|
-
interface SplitScreenPlayer {
|
|
429
|
-
account: string;
|
|
430
|
-
engine: Engine;
|
|
431
|
-
manager: NetworkManager;
|
|
432
|
-
}
|
|
433
|
-
interface SplitScreenOptions extends LocalGameServerOptions {
|
|
434
|
-
/** The shared scene JSON every panel loads. */
|
|
435
|
-
scene: SceneJson;
|
|
436
|
-
/** Player accounts, one panel each (default ['p1', 'p2']). */
|
|
437
|
-
accounts?: string[];
|
|
438
|
-
/** Called per player to finish wiring (renderer, input, HUD). */
|
|
439
|
-
setup: (player: SplitScreenPlayer, index: number) => void | Promise<void>;
|
|
440
|
-
/** name → scene JSON registered on every panel's NetworkManager. */
|
|
441
|
-
scenes?: Record<string, SceneJson>;
|
|
442
|
-
/** Engine seed base (each panel gets seed + index). */
|
|
443
|
-
seed?: number;
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* N local clients on ONE page sharing ONE in-memory game server — the
|
|
447
|
-
* split-screen preview harness three examples were hand-wiring (~40 lines
|
|
448
|
-
* each). Wires: LocalGameServer + per-player Engine/scene/NetworkManager +
|
|
449
|
-
* the server tick driven from the first panel's clock.
|
|
450
|
-
*
|
|
451
|
-
* const { players, server } = await createSplitScreen({
|
|
452
|
-
* scene: gameJson,
|
|
453
|
-
* server: MyServerClass,
|
|
454
|
-
* scenes: { 'remote-player': remoteJson },
|
|
455
|
-
* setup: ({ engine }, i) => {
|
|
456
|
-
* new Renderer2D({ canvas: canvases[i], engine });
|
|
457
|
-
* engine.input.attachKeyboard(window);
|
|
458
|
-
* engine.start();
|
|
459
|
-
* },
|
|
460
|
-
* });
|
|
461
|
-
*
|
|
462
|
-
* Going live stays the one-line story: replace the transport with
|
|
463
|
-
* `createAgent8Server()` and boot ONE client per browser.
|
|
464
|
-
*/
|
|
465
|
-
declare function createSplitScreen(opts: SplitScreenOptions): Promise<{
|
|
466
|
-
server: ReturnType<typeof createLocalGameServer>;
|
|
467
|
-
players: SplitScreenPlayer[];
|
|
468
|
-
dispose(): void;
|
|
469
|
-
}>;
|
|
470
|
-
//#endregion
|
|
471
76
|
export { type CollectionOptions, LocalGameServer, type LocalGameServerOptions, LocalGameServerTransport, LoopbackHub, LoopbackTransport, NetworkManager, type NetworkManagerOptions, NetworkSpawner, type NetworkTransport, type ServerClass, type SplitScreenOptions, type SplitScreenPlayer, type Unsubscribe, applySyncPatch, createAgent8Server, createLocalGameServer, createSplitScreen, registerNodesNet };
|