@crowdedkingdoms/crowdyjs 8.3.0 → 8.4.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/README.md +60 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/stores/actors.d.ts +316 -0
- package/dist/stores/actors.d.ts.map +1 -0
- package/dist/stores/actors.js +506 -0
- package/dist/stores/chunks.d.ts +180 -0
- package/dist/stores/chunks.d.ts.map +1 -0
- package/dist/stores/chunks.js +378 -0
- package/dist/stores/codec.d.ts +109 -0
- package/dist/stores/codec.d.ts.map +1 -0
- package/dist/stores/codec.js +186 -0
- package/dist/stores/durable.d.ts +144 -0
- package/dist/stores/durable.d.ts.map +1 -0
- package/dist/stores/durable.js +246 -0
- package/dist/stores/errors.d.ts +69 -0
- package/dist/stores/errors.d.ts.map +1 -0
- package/dist/stores/errors.js +87 -0
- package/dist/stores/inbox.d.ts +184 -0
- package/dist/stores/inbox.d.ts.map +1 -0
- package/dist/stores/inbox.js +326 -0
- package/dist/stores/index.d.ts +186 -0
- package/dist/stores/index.d.ts.map +1 -0
- package/dist/stores/index.js +109 -0
- package/dist/stores/keys.d.ts +52 -0
- package/dist/stores/keys.d.ts.map +1 -0
- package/dist/stores/keys.js +76 -0
- package/dist/stores/model.d.ts +81 -0
- package/dist/stores/model.d.ts.map +1 -0
- package/dist/stores/model.js +163 -0
- package/dist/stores/session.d.ts +119 -0
- package/dist/stores/session.d.ts.map +1 -0
- package/dist/stores/session.js +116 -0
- package/dist/stores/ticker.d.ts +44 -0
- package/dist/stores/ticker.d.ts.map +1 -0
- package/dist/stores/ticker.js +127 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -106,6 +106,7 @@ If `managementUrl` is omitted, the SDK falls back to `httpUrl` for backwards-com
|
|
|
106
106
|
| `client.udp` | UDP proxy subscriptions + spatial mutations (`sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendTextPacket`, `sendClientEvent`). |
|
|
107
107
|
| `client.realtime` | Connection status, manual `connect()` / `disconnect()`, `onStatus()` listener. |
|
|
108
108
|
| `client.world(appId)` | Higher-level helpers for browser games (`actor.join`, `actor.sendState`, `actor.sendText`). |
|
|
109
|
+
| `createWorldSession(client, appId, config)` (from `@crowdedkingdoms/crowdyjs/stores`) | World Stores: opt-in, SDK-managed game state — typed codecs (`structCodec` binary DSL), your own actor with a 5 Hz send loop (`session.self`), a remote-actor registry with lanes/history/staleness (`session.actors`), attributed send errors (`session.errors`), a chunk/voxel cache with realtime merge + worldgen write-back (`session.chunks`), channel/direct-message inboxes + a typed event router, host tracking, typed save/avatar state, and a game-model container mirror. Only configured stores exist (compile-time + runtime); unimported stores tree-shake away. |
|
|
109
110
|
| `client.kit(appId)` | Game Kit: ready-made mappings of game concepts onto the game model — `kit.inventory`, `kit.objects` (lockable doors/chests with custom permissions), `kit.npcs`, `kit.plots` (buy/rent land with transactional, replication-enforced grid grants), and the genre layers `kit.economy` (wallets/shops/trades/market), `kit.progression` (xp/skills/achievements/rating), `kit.loot`, `kit.quests`, `kit.combat`, `kit.matches` (session lobbies/turns/scores with notify-to-pull channels), `kit.decks` (hidden hands), `kit.worldsim` (clock/nodes/crops/waves), `kit.social` (parties/guilds/chat over teams+channels), `kit.leaderboards`, `kit.features` (tier gates) — plus blueprint builders + `kit.deploy(...)` for the admin "load the rules" step. |
|
|
110
111
|
|
|
111
112
|
**Studio-admin surface** (privileged; drive with a server-side / studio token, grouped under `client.admin`):
|
|
@@ -269,6 +270,65 @@ await actor.sendToActor(
|
|
|
269
270
|
|
|
270
271
|
The world helpers are thin wrappers over `client.udp.*` with the appId pre-bound — convenient for browser games. Advanced callers can always use `client.udp.*` with the generated GraphQL input types directly.
|
|
271
272
|
|
|
273
|
+
## World Stores
|
|
274
|
+
|
|
275
|
+
The core client is a thin transport; the **World Stores** layer
|
|
276
|
+
(`@crowdedkingdoms/crowdyjs/stores`, 8.4+) adds the source-of-truth data
|
|
277
|
+
structures every game otherwise hand-writes: actor registries, chunk/voxel
|
|
278
|
+
caches, error attribution, message inboxes, host tracking, and typed
|
|
279
|
+
durable-state wrappers — all driven by ONE shared `udpNotifications`
|
|
280
|
+
subscription and ONE scheduler.
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
import {
|
|
284
|
+
createWorldSession, structCodec, f32, u8, jsonCodec, workerTicker,
|
|
285
|
+
} from '@crowdedkingdoms/crowdyjs/stores';
|
|
286
|
+
|
|
287
|
+
// Describe your replication state ONCE (48-byte binary layouts, declaratively):
|
|
288
|
+
const poseCodec = structCodec({
|
|
289
|
+
x: f32(), y: f32(), z: f32(), yaw: f32(),
|
|
290
|
+
flags: u8(), held: u8(),
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const session = createWorldSession(game, appId, {
|
|
294
|
+
ticker: workerTicker(), // keep 5 Hz sends even in backgrounded tabs
|
|
295
|
+
self: { codec: poseCodec, initialState: { x: 0, y: 0, z: 0, yaw: 0, flags: 0, held: 0 } },
|
|
296
|
+
actors: { codec: poseCodec, staleAfterMs: 12_000, historySize: 2 },
|
|
297
|
+
errors: true,
|
|
298
|
+
chunks: { voxelStateCodec: jsonCodec<MyVoxelMeta>() },
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// Your actor: uuid minted + persisted, presence sent at 5 Hz with
|
|
302
|
+
// send-on-change dedup; just update the typed state from your game loop.
|
|
303
|
+
await session.self.join({ x: '0', y: '0', z: '0' });
|
|
304
|
+
session.self.patchState({ x: 12.5, yaw: 1.57 });
|
|
305
|
+
console.log(session.self.status, session.self.lastAck?.state);
|
|
306
|
+
|
|
307
|
+
// Everyone else: typed, self-filtered, staleness-managed — render from it.
|
|
308
|
+
for (const actor of session.actors.list()) {
|
|
309
|
+
render(actor.uuid, actor.state, actor.samples); // samples → interpolation
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Terrain: cached, hydrated, realtime-merged, optimistically editable.
|
|
313
|
+
await session.chunks.ensureAround({ x: 0, y: 0, z: 0 }, 3);
|
|
314
|
+
await session.chunks.setVoxel({ chunk: { x: 0, y: 0, z: 0 }, x: 1, y: 2, z: 3, voxelType: 7 });
|
|
315
|
+
|
|
316
|
+
// Server-reported send errors, attributed to what you sent:
|
|
317
|
+
session.errors.onError((e) => console.warn(e.errorCode, e.send?.kind));
|
|
318
|
+
|
|
319
|
+
session.dispose();
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Every store is **opt-in twice over**: only configured stores are constructed
|
|
323
|
+
(and only they exist on the session's TYPE — `session.host` without
|
|
324
|
+
`host: ...` in the config is a compile error), and the layer lives behind the
|
|
325
|
+
`./stores` subpath with `"sideEffects": false`, so unimported stores never
|
|
326
|
+
reach your bundle. Reads are synchronous snapshots and writes happen on
|
|
327
|
+
WebSocket events (not `requestAnimationFrame`), so render loops read freely
|
|
328
|
+
and a backgrounded tab keeps ingesting updates; pass `workerTicker()` to also
|
|
329
|
+
keep timer-driven sends at full rate while hidden. See the
|
|
330
|
+
[World Stores guide](https://docs.crowdedkingdoms.com/crowdyjs/stores).
|
|
331
|
+
|
|
272
332
|
## Game Kit
|
|
273
333
|
|
|
274
334
|
`client.kit(appId)` maps traditional game concepts onto the abstract game
|
package/dist/index.d.ts
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
* or internal tooling, never an untrusted browser.
|
|
46
46
|
*/
|
|
47
47
|
/** The published package version. Mirrors `package.json`. */
|
|
48
|
-
export declare const VERSION = "8.
|
|
48
|
+
export declare const VERSION = "8.4.0";
|
|
49
49
|
export { LbCookieStore } from './lb-cookie-store.js';
|
|
50
50
|
export { CrowdyClient, createCrowdyClient, type CrowdyClientConfig, } from './crowdy-client.js';
|
|
51
51
|
export { BrowserLocalStorageTokenStore, SessionStore, type SessionListener, type TokenStore, } from './session.js';
|
|
@@ -53,6 +53,7 @@ export { GraphQLClient, GraphQLTransport, type GraphQLClientConfig, } from './cl
|
|
|
53
53
|
export { RealtimeClient, type RealtimeConfig, type RealtimeStatus, type SpatialNotification, type UdpNotification, type UdpNotificationHandlers, } from './realtime.js';
|
|
54
54
|
export { WorldClient, ActorClient, type ActorOptions } from './world.js';
|
|
55
55
|
export { CombatKit, DecksKit, EconomyKit, FeaturesKit, GameKitClient, InventoryKit, LeaderboardsKit, LootKit, MatchesKit, NpcsKit, ObjectsKit, PlotsKit, ProgressionKit, QuestsKit, SocialKit, WorldsimKit, andPolicies, combatBlueprint, combatNames, composeBlueprints, decksBlueprint, decksNames, economyBlueprint, economyCurrencyFn, economyNames, featureGate, guildBlueprint, guildNames, inventoryBlueprint, inventoryNames, kitInvoke, kitPolicyJson, leaderboardsBlueprint, leaderboardsNames, lockBlueprint, lockNames, lootBlueprint, lootNames, lootRollFn, matchesBlueprint, matchesNames, mergeBlueprints, npcBehaviorFunctionName, npcBlueprint, ownerEqualsCaller, ownerMirrorProperty, ownerEquals, plotBlueprint, plotNames, progressionBlueprint, progressionNames, questsBlueprint, questsNames, toKitInvokeResult, trustedAuthorityFields, worldsimBlueprint, worldsimNames, type CombatBlueprintOptions, type CombatKitOptions, type CombatNames, type DecksBlueprintOptions, type DecksKitOptions, type DecksNames, type EconomyBlueprintOptions, type EconomyKitOptions, type EconomyNames, type GameKitDomains, type GameKitOptions, type GuildBlueprintOptions, type GuildNames, type InventoryBlueprintOptions, type InventoryKitOptions, type InventoryNames, type KitAchievementDef, type KitAchievementUnlock, type KitAutomationSpec, type KitAutomationTriggerSpec, type KitBlueprint, type KitCard, type KitChatMessage, type KitCombatant, type KitCrop, type KitGroupWithChannel, type KitDeployResult, type KitInvokePolicy, type KitInvokeResult, type KitItemStack, type KitLeaderboardEntry, type KitLootRoll, type KitMarketListing, type KitMatch, type KitMatchScore, type KitNpc, type KitOwnerIdKind, type KitPlot, type KitProgress, type KitQuestDef, type KitQuestProgress, type KitResourceNode, type KitSelectorSpec, type KitShopListing, type KitSkillDef, type KitSkillRank, type KitStatusEffect, type KitTradeOffer, type KitTrustedAuthority, type KitWallet, type KitWaveSpawner, type LeaderboardsBlueprintOptions, type LeaderboardsKitOptions, type LeaderboardsNames, type KitWorldState, type LockAuthority, type LockBlueprintOptions, type LockNames, type LootBlueprintOptions, type LootDropSpec, type LootEntrySpec, type LootKitOptions, type LootNames, type LootTableSpec, type MatchesBlueprintOptions, type MatchesKitOptions, type MatchesNames, type MergedBlueprints, type NpcBehaviorSpec, type NpcBehaviorTrigger, type NpcBlueprintOptions, type NpcsKitOptions, type ObjectsKitOptions, type PlotBlueprintOptions, type PlotNames, type PlotsKitOptions, type ProgressionBlueprintOptions, type ProgressionKitOptions, type ProgressionNames, type QuestAdvanceSpec, type QuestsBlueprintOptions, type QuestsKitOptions, type QuestsNames, type SelectorPermissionPredicate, type SocialKitOptions, type WorldsimBlueprintOptions, type WorldsimKitOptions, type WorldsimNames, } from './kit/index.js';
|
|
56
|
+
export type { StateCodec, Ticker, WorldSession, WorldSessionConfig, WorldStoresClient, } from './stores/index.js';
|
|
56
57
|
export { CrowdyError, CrowdyGraphQLError, CrowdyHttpError, CrowdyNetworkError, CrowdyProtocolError, CrowdyRealtimeError, CrowdyTimeoutError, } from './errors.js';
|
|
57
58
|
export { SequenceAllocator, decodeBase64, encodeBase64, generateCrowdyUuid, validateChunkCoordinates, validateCrowdyUuid, } from './utils.js';
|
|
58
59
|
export type { BigInt, ChunkCoordinates, VoxelCoordinates, ActorUpdateNotification, ActorUpdateResponse, VoxelUpdateNotification, VoxelUpdateResponse, ClientAudioNotification, ClientTextNotification, ClientEventNotification, ServerEventNotification, GenericErrorResponse, ActorUpdateHandler, ActorUpdateResponseHandler, VoxelUpdateHandler, VoxelUpdateResponseHandler, ClientAudioHandler, ClientTextHandler, ClientEventHandler, ServerEventHandler, GenericErrorHandler, UnsubscribeFn, } from './types.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
* or internal tooling, never an untrusted browser.
|
|
46
46
|
*/
|
|
47
47
|
/** The published package version. Mirrors `package.json`. */
|
|
48
|
-
export const VERSION = '8.
|
|
48
|
+
export const VERSION = '8.4.0';
|
|
49
49
|
export { LbCookieStore } from './lb-cookie-store.js';
|
|
50
50
|
export { CrowdyClient, createCrowdyClient, } from './crowdy-client.js';
|
|
51
51
|
export { BrowserLocalStorageTokenStore, SessionStore, } from './session.js';
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Actor stores — the SDK-managed bookkeeping every multiplayer game
|
|
3
|
+
* otherwise hand-writes: your own actor's identity, typed state, and send
|
|
4
|
+
* loop ({@link LocalActorStore}), created via {@link attachLocalActor} on a
|
|
5
|
+
* world session.
|
|
6
|
+
*/
|
|
7
|
+
import type { ChunkCoordinatesInput } from '../generated/graphql.js';
|
|
8
|
+
import type { UdpNotificationHandlers } from '../realtime.js';
|
|
9
|
+
import type { StateCodec } from './codec.js';
|
|
10
|
+
import type { WorldSessionContext } from './session.js';
|
|
11
|
+
/** The notification type delivered for actor updates (incl. your own echo). */
|
|
12
|
+
export type ActorUpdateEcho = Parameters<NonNullable<UdpNotificationHandlers['actorUpdate']>>[0];
|
|
13
|
+
/** The error notification type. */
|
|
14
|
+
export type GenericErrorEcho = Parameters<NonNullable<UdpNotificationHandlers['genericError']>>[0];
|
|
15
|
+
/** Where the local actor's 32-char uuid lives across page loads. */
|
|
16
|
+
export interface UuidStore {
|
|
17
|
+
load(): string | null;
|
|
18
|
+
save(uuid: string): void;
|
|
19
|
+
}
|
|
20
|
+
/** Keep the uuid for this tab session only (a fresh actor per reload). */
|
|
21
|
+
export declare function memoryUuidStore(): UuidStore;
|
|
22
|
+
/**
|
|
23
|
+
* Persist the uuid in `localStorage` so the player keeps a stable actor
|
|
24
|
+
* identity across reloads (the convention games converge on). Falls back to
|
|
25
|
+
* {@link memoryUuidStore} behavior outside the browser.
|
|
26
|
+
*/
|
|
27
|
+
export declare function localStorageUuidStore(key?: string): UuidStore;
|
|
28
|
+
/** Why a send happened — recorded on {@link SentActorUpdate}. */
|
|
29
|
+
export type SendReason = 'join' | 'move' | 'interval' | 'keyframe' | 'manual' | 'visibility' | 'refresh';
|
|
30
|
+
/** The record of the most recent outbound actor update. */
|
|
31
|
+
export interface SentActorUpdate<T> {
|
|
32
|
+
/** The typed state that was sent. */
|
|
33
|
+
state: T;
|
|
34
|
+
/** The encoded (base64) wire form. */
|
|
35
|
+
encoded: string;
|
|
36
|
+
chunk: ChunkCoordinatesInput;
|
|
37
|
+
sequenceNumber: number;
|
|
38
|
+
sentAt: number;
|
|
39
|
+
reason: SendReason;
|
|
40
|
+
}
|
|
41
|
+
/** The record of the most recent server-applied echo of our own update. */
|
|
42
|
+
export interface AckedActorUpdate<T> {
|
|
43
|
+
/** The typed state decoded from the echo. */
|
|
44
|
+
state: T;
|
|
45
|
+
/** The raw self-echo notification. */
|
|
46
|
+
notification: ActorUpdateEcho;
|
|
47
|
+
receivedAt: number;
|
|
48
|
+
}
|
|
49
|
+
/** The record of the most recent send error attributed to this actor. */
|
|
50
|
+
export interface ActorSendError {
|
|
51
|
+
errorCode: string;
|
|
52
|
+
sequenceNumber: number;
|
|
53
|
+
receivedAt: number;
|
|
54
|
+
}
|
|
55
|
+
/** Lifecycle of the local actor's replication. */
|
|
56
|
+
export type LocalActorStatus = 'idle' | 'pending' | 'acked' | 'error';
|
|
57
|
+
/** Options for {@link attachLocalActor}. */
|
|
58
|
+
export interface LocalActorConfig<T> {
|
|
59
|
+
/** Codec between your typed replication state and the base64 wire form. */
|
|
60
|
+
codec: StateCodec<T>;
|
|
61
|
+
/** The state sent until {@link LocalActorStore.setState} changes it. */
|
|
62
|
+
initialState: T;
|
|
63
|
+
/** Explicit 32-char uuid (wins over `uuidStore`). */
|
|
64
|
+
uuid?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Where the minted uuid persists. Defaults to {@link memoryUuidStore};
|
|
67
|
+
* pass {@link localStorageUuidStore} for a stable identity across reloads.
|
|
68
|
+
*/
|
|
69
|
+
uuidStore?: UuidStore;
|
|
70
|
+
/**
|
|
71
|
+
* Send-loop cadence in ms. Defaults to **200 (5 Hz)** — the proven
|
|
72
|
+
* cadence for player presence. Set `0` or `false` to disable the loop and
|
|
73
|
+
* drive {@link LocalActorStore.sendNow} yourself. Runs on the session
|
|
74
|
+
* {@link Ticker}: pass `workerTicker()` to `createWorldSession` to hold
|
|
75
|
+
* the rate in backgrounded tabs.
|
|
76
|
+
*/
|
|
77
|
+
sendIntervalMs?: number | false;
|
|
78
|
+
/**
|
|
79
|
+
* Skip loop sends whose encoded state is byte-identical to the last send.
|
|
80
|
+
* Defaults to true. Explicit sends (`sendNow`, `join`, `moveTo`) always go
|
|
81
|
+
* out.
|
|
82
|
+
*/
|
|
83
|
+
sendOnChange?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* With `sendOnChange`, still force a keyframe send after this many ms of
|
|
86
|
+
* dedup silence so presence never starves. Defaults to 3000.
|
|
87
|
+
*/
|
|
88
|
+
keyframeEveryMs?: number;
|
|
89
|
+
/** Default replication radius in chunk units (0-8). */
|
|
90
|
+
distance?: number;
|
|
91
|
+
/** Default replication decay algorithm (0-5). */
|
|
92
|
+
decayRate?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Re-send presence when the browser tab becomes visible again (timers may
|
|
95
|
+
* have been throttled while hidden). Defaults to true in browsers.
|
|
96
|
+
*/
|
|
97
|
+
refreshOnVisibility?: boolean;
|
|
98
|
+
/** Clock override for tests. Defaults to `Date.now`. */
|
|
99
|
+
now?: () => number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The SDK-managed **local actor**: identity (minted + persisted uuid), typed
|
|
103
|
+
* replication state, current chunk, an automatic 5 Hz send loop with
|
|
104
|
+
* send-on-change dedup, and queryable send bookkeeping — {@link lastSent},
|
|
105
|
+
* {@link lastAck} (the server-applied self-echo), {@link lastError}, and
|
|
106
|
+
* {@link status}. Replaces the hand-written codec + sender + uuid plumbing
|
|
107
|
+
* every game rebuilds.
|
|
108
|
+
*
|
|
109
|
+
* Reads are synchronous; all record updates happen on WebSocket events, so
|
|
110
|
+
* the render loop can query freely regardless of tab visibility.
|
|
111
|
+
*/
|
|
112
|
+
export declare class LocalActorStore<T> {
|
|
113
|
+
private readonly ctx;
|
|
114
|
+
private readonly config;
|
|
115
|
+
/** This actor's 32-char wire id. */
|
|
116
|
+
readonly uuid: string;
|
|
117
|
+
private currentState;
|
|
118
|
+
private currentChunk;
|
|
119
|
+
private lastSentRecord;
|
|
120
|
+
private lastAckRecord;
|
|
121
|
+
private lastErrorRecord;
|
|
122
|
+
private readonly inFlight;
|
|
123
|
+
private readonly sequences;
|
|
124
|
+
private readonly now;
|
|
125
|
+
constructor(ctx: WorldSessionContext, config: LocalActorConfig<T>);
|
|
126
|
+
/** The current typed replication state (what the loop sends). */
|
|
127
|
+
get state(): T;
|
|
128
|
+
/** The actor's current chunk (null before {@link join}). */
|
|
129
|
+
get chunk(): ChunkCoordinatesInput | null;
|
|
130
|
+
/** The most recent outbound update (typed + encoded + seq + timestamp). */
|
|
131
|
+
get lastSent(): SentActorUpdate<T> | null;
|
|
132
|
+
/** The most recent server-applied self-echo. */
|
|
133
|
+
get lastAck(): AckedActorUpdate<T> | null;
|
|
134
|
+
/** The most recent send error attributed to this actor. */
|
|
135
|
+
get lastError(): ActorSendError | null;
|
|
136
|
+
/**
|
|
137
|
+
* Replication lifecycle: `idle` (nothing sent), `pending` (sent, no echo
|
|
138
|
+
* yet), `acked` (echo at or after the last send), `error` (an error
|
|
139
|
+
* arrived after the last send).
|
|
140
|
+
*/
|
|
141
|
+
get status(): LocalActorStatus;
|
|
142
|
+
/** Update the typed state; the next loop tick (or `sendNow`) sends it. */
|
|
143
|
+
setState(state: T): void;
|
|
144
|
+
/** Merge a partial update into the typed state (object states only). */
|
|
145
|
+
patchState(patch: Partial<T>): void;
|
|
146
|
+
/**
|
|
147
|
+
* Enter a chunk: records it as the actor's current chunk and immediately
|
|
148
|
+
* sends presence there. (The first message to a brand-new chunk may be
|
|
149
|
+
* dropped server-side while grid permissions load — if {@link status}
|
|
150
|
+
* stays `pending`, call {@link refresh}.)
|
|
151
|
+
*/
|
|
152
|
+
join(chunk: ChunkCoordinatesInput, state?: T): Promise<void>;
|
|
153
|
+
/** Move to another chunk and immediately send presence there. */
|
|
154
|
+
moveTo(chunk: ChunkCoordinatesInput): Promise<void>;
|
|
155
|
+
/** Send the current state now, bypassing dedup. */
|
|
156
|
+
sendNow(): Promise<void>;
|
|
157
|
+
/** Re-register presence (reconnects, tab return, dropped first join). */
|
|
158
|
+
refresh(reason?: SendReason): Promise<void>;
|
|
159
|
+
/** One send-loop tick: dedup unchanged state, keyframe when quiet. */
|
|
160
|
+
private tick;
|
|
161
|
+
private send;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Attach a {@link LocalActorStore} to a world session context. Prefer the
|
|
165
|
+
* `self` key of `createWorldSession`'s config; use this directly for custom
|
|
166
|
+
* compositions.
|
|
167
|
+
*/
|
|
168
|
+
export declare function attachLocalActor<T>(ctx: WorldSessionContext, config: LocalActorConfig<T>): LocalActorStore<T>;
|
|
169
|
+
/** One timestamped state sample of a remote actor (newest first in history). */
|
|
170
|
+
export interface RemoteActorSample<T> {
|
|
171
|
+
state: T;
|
|
172
|
+
chunk: ChunkCoordinatesInput;
|
|
173
|
+
/** Server-stamped epoch ms of the update. */
|
|
174
|
+
epochMillis: number;
|
|
175
|
+
/** Local receive time (ms). */
|
|
176
|
+
receivedAt: number;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* A tracked remote actor. The object identity is **stable** across updates
|
|
180
|
+
* (fields mutate in place), so render code can hold references; check the
|
|
181
|
+
* lane's `revision` for cheap change detection.
|
|
182
|
+
*/
|
|
183
|
+
export interface RemoteActor<T> {
|
|
184
|
+
readonly uuid: string;
|
|
185
|
+
/** The latest decoded state. */
|
|
186
|
+
state: T;
|
|
187
|
+
/** The chunk of the latest update. */
|
|
188
|
+
chunk: ChunkCoordinatesInput;
|
|
189
|
+
/** Replication radius of the latest update. */
|
|
190
|
+
distance: number;
|
|
191
|
+
/** Server-stamped epoch ms of the latest update. */
|
|
192
|
+
epochMillis: number;
|
|
193
|
+
/** Local receive time of the latest update (ms). */
|
|
194
|
+
receivedAt: number;
|
|
195
|
+
/**
|
|
196
|
+
* Recent samples, newest first (length ≤ `historySize`) — the data an
|
|
197
|
+
* interpolating renderer needs without keeping its own buffers.
|
|
198
|
+
*/
|
|
199
|
+
samples: Array<RemoteActorSample<T>>;
|
|
200
|
+
}
|
|
201
|
+
/** Options for {@link attachRemoteActors}. */
|
|
202
|
+
export interface RemoteActorsConfig<T> {
|
|
203
|
+
/** Codec between the base64 wire state and the typed actor state. */
|
|
204
|
+
codec: StateCodec<T>;
|
|
205
|
+
/**
|
|
206
|
+
* The local actor's uuid (or a getter), filtered out as the self-echo.
|
|
207
|
+
* `createWorldSession` wires this automatically from `config.self`.
|
|
208
|
+
*/
|
|
209
|
+
selfUuid?: string | (() => string | null);
|
|
210
|
+
/**
|
|
211
|
+
* Actors quieter than this are considered gone: excluded from reads and
|
|
212
|
+
* physically reaped (with `onLeave`) by the reap timer. Defaults to
|
|
213
|
+
* 12 000 ms. `false` disables staleness entirely.
|
|
214
|
+
*/
|
|
215
|
+
staleAfterMs?: number | false;
|
|
216
|
+
/**
|
|
217
|
+
* Reap-timer cadence (physically deletes stale records and fires
|
|
218
|
+
* `onLeave`). Defaults to 1000 ms; `false` relies on read-time filtering +
|
|
219
|
+
* manual {@link RemoteActorStore.reap} only. Reads are always correct
|
|
220
|
+
* regardless — staleness is ALSO computed at read time, so a throttled
|
|
221
|
+
* timer can never serve stale actors.
|
|
222
|
+
*/
|
|
223
|
+
reapIntervalMs?: number | false;
|
|
224
|
+
/** Samples kept per actor for interpolation. Defaults to 2. */
|
|
225
|
+
historySize?: number;
|
|
226
|
+
/**
|
|
227
|
+
* Named lanes routing one decoded notification to the first matching
|
|
228
|
+
* sub-registry — e.g. `{ players: (s) => !(s.flags & 2), mobs: (s) => !!(s.flags & 2) }`
|
|
229
|
+
* lets a player renderer and a mob system share the stream without
|
|
230
|
+
* double-decoding. Omit for a single implicit lane.
|
|
231
|
+
*/
|
|
232
|
+
lanes?: Record<string, (state: T, notification: ActorUpdateEcho) => boolean>;
|
|
233
|
+
/** Clock override for tests. Defaults to `Date.now`. */
|
|
234
|
+
now?: () => number;
|
|
235
|
+
}
|
|
236
|
+
/** One lane's registry of remote actors. */
|
|
237
|
+
export declare class RemoteActorLane<T> {
|
|
238
|
+
private readonly historySize;
|
|
239
|
+
private readonly staleAfterMs;
|
|
240
|
+
private readonly now;
|
|
241
|
+
private readonly actors;
|
|
242
|
+
private readonly joinListeners;
|
|
243
|
+
private readonly updateListeners;
|
|
244
|
+
private readonly leaveListeners;
|
|
245
|
+
private revisionValue;
|
|
246
|
+
constructor(historySize: number, staleAfterMs: number | false, now: () => number);
|
|
247
|
+
/** Bumped on every change — poll it cheaply from a render loop. */
|
|
248
|
+
get revision(): number;
|
|
249
|
+
/** Live actors (stale ones filtered at read time), unordered. */
|
|
250
|
+
list(): Array<RemoteActor<T>>;
|
|
251
|
+
/** One live actor, or undefined when unknown/stale. */
|
|
252
|
+
get(uuid: string): RemoteActor<T> | undefined;
|
|
253
|
+
/** Live actor count. */
|
|
254
|
+
get count(): number;
|
|
255
|
+
/** A new actor appeared. @returns off. */
|
|
256
|
+
onJoin(listener: (actor: RemoteActor<T>) => void): () => void;
|
|
257
|
+
/** An actor's state updated (fires after `onJoin` for the first update). @returns off. */
|
|
258
|
+
onUpdate(listener: (actor: RemoteActor<T>) => void): () => void;
|
|
259
|
+
/** An actor went stale and was reaped (or the store was cleared). @returns off. */
|
|
260
|
+
onLeave(listener: (actor: RemoteActor<T>) => void): () => void;
|
|
261
|
+
/** Apply one decoded update (internal). */
|
|
262
|
+
apply(uuid: string, state: T, chunk: ChunkCoordinatesInput, distance: number, epochMillis: number): void;
|
|
263
|
+
/** Physically delete stale records, firing `onLeave` for each. */
|
|
264
|
+
reap(): void;
|
|
265
|
+
/** Drop every record (fires `onLeave` for each live one). */
|
|
266
|
+
clear(): void;
|
|
267
|
+
private isStale;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* The SDK-managed **remote actor registry**: subscribes to `actorUpdate`,
|
|
271
|
+
* decodes each notification ONCE, filters the local self-echo, and maintains
|
|
272
|
+
* per-actor records with timestamped sample history, staleness, and
|
|
273
|
+
* join/update/leave events. With `lanes`, one decoded stream feeds several
|
|
274
|
+
* consumers (players vs mobs) without double-decoding.
|
|
275
|
+
*
|
|
276
|
+
* Reads are synchronous and always live-filtered (staleness is computed at
|
|
277
|
+
* read time), so render loops can query at any cadence — including after a
|
|
278
|
+
* backgrounded tab resumes.
|
|
279
|
+
*/
|
|
280
|
+
export declare class RemoteActorStore<T> {
|
|
281
|
+
private readonly config;
|
|
282
|
+
private readonly lanes;
|
|
283
|
+
private readonly laneFilters;
|
|
284
|
+
private readonly defaultLane;
|
|
285
|
+
private decodeFailureCount;
|
|
286
|
+
constructor(ctx: WorldSessionContext, config: RemoteActorsConfig<T>);
|
|
287
|
+
/** A named lane's registry (throws for unknown names). */
|
|
288
|
+
lane(name: string): RemoteActorLane<T>;
|
|
289
|
+
/** Live actors across every lane (the default lane when none configured). */
|
|
290
|
+
list(): Array<RemoteActor<T>>;
|
|
291
|
+
/** One live actor, searched across lanes. */
|
|
292
|
+
get(uuid: string): RemoteActor<T> | undefined;
|
|
293
|
+
/** Live actor count across lanes. */
|
|
294
|
+
get count(): number;
|
|
295
|
+
/** Sum of lane revisions — poll it cheaply from a render loop. */
|
|
296
|
+
get revision(): number;
|
|
297
|
+
/** Notifications whose state failed to decode (foreign layouts). */
|
|
298
|
+
get decodeFailures(): number;
|
|
299
|
+
/** A new actor appeared (default/single-lane sugar; use `lane()` with lanes). */
|
|
300
|
+
onJoin(listener: (actor: RemoteActor<T>) => void): () => void;
|
|
301
|
+
/** An actor updated. */
|
|
302
|
+
onUpdate(listener: (actor: RemoteActor<T>) => void): () => void;
|
|
303
|
+
/** An actor was reaped. */
|
|
304
|
+
onLeave(listener: (actor: RemoteActor<T>) => void): () => void;
|
|
305
|
+
/** Physically delete stale records in every lane. */
|
|
306
|
+
reap(): void;
|
|
307
|
+
/** Drop every record in every lane. */
|
|
308
|
+
clear(): void;
|
|
309
|
+
private everyLane;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Attach a {@link RemoteActorStore} to a world session context. Prefer the
|
|
313
|
+
* `actors` key of `createWorldSession`'s config.
|
|
314
|
+
*/
|
|
315
|
+
export declare function attachRemoteActors<T>(ctx: WorldSessionContext, config: RemoteActorsConfig<T>): RemoteActorStore<T>;
|
|
316
|
+
//# sourceMappingURL=actors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actors.d.ts","sourceRoot":"","sources":["../../src/stores/actors.ts"],"names":[],"mappings":"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"}
|