@antha/multiplayer-p2p-authoritative-host 0.13.0 → 0.14.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.
|
@@ -6,15 +6,15 @@ import { P2pAuthoritativeHostMultiplayerController, type P2pAuthoritativeHostMul
|
|
|
6
6
|
*
|
|
7
7
|
* @category Internal
|
|
8
8
|
*/
|
|
9
|
-
export type AnthaMultiplayerP2pAuthoritativeHostState<Input extends JsonCompatibleValue = any,
|
|
9
|
+
export type AnthaMultiplayerP2pAuthoritativeHostState<Input extends JsonCompatibleValue = any, MultiplayerGameState extends JsonCompatibleValue = any> = {
|
|
10
10
|
/** P2p-authoritative-host controller state. */
|
|
11
11
|
multiplayerP2pAuthoritativeHost: {
|
|
12
12
|
/** Controller used to drive singleplayer or multiplayer state sync. */
|
|
13
|
-
multiplayerController: P2pAuthoritativeHostMultiplayerController<Input,
|
|
13
|
+
multiplayerController: P2pAuthoritativeHostMultiplayerController<Input, MultiplayerGameState>;
|
|
14
14
|
/** Current backend API and room connection state. */
|
|
15
15
|
connectionState: ApiAndRoomConnectionState;
|
|
16
16
|
/** Latest state emitted by the multiplayer controller. */
|
|
17
|
-
currentState:
|
|
17
|
+
currentState: MultiplayerGameState;
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
@@ -22,10 +22,10 @@ export type AnthaMultiplayerP2pAuthoritativeHostState<Input extends JsonCompatib
|
|
|
22
22
|
*
|
|
23
23
|
* @category Internal
|
|
24
24
|
*/
|
|
25
|
-
export type AnthaMultiplayerP2pAuthoritativeHostOptions<Input extends JsonCompatibleValue = any,
|
|
25
|
+
export type AnthaMultiplayerP2pAuthoritativeHostOptions<Input extends JsonCompatibleValue = any, MultiplayerGameState extends JsonCompatibleValue = any> = SelectFrom<P2pAuthoritativeHostMultiplayerControllerParams<Input, MultiplayerGameState>, {
|
|
26
26
|
applyInput: true;
|
|
27
27
|
createInitialState: true;
|
|
28
|
-
}> & PartialWithUndefined<SelectFrom<P2pAuthoritativeHostMultiplayerControllerParams<Input,
|
|
28
|
+
}> & PartialWithUndefined<SelectFrom<P2pAuthoritativeHostMultiplayerControllerParams<Input, MultiplayerGameState>, {
|
|
29
29
|
acceptConnection: true;
|
|
30
30
|
gameId: true;
|
|
31
31
|
shouldAcceptInput: true;
|
|
@@ -36,4 +36,4 @@ export type AnthaMultiplayerP2pAuthoritativeHostOptions<Input extends JsonCompat
|
|
|
36
36
|
*
|
|
37
37
|
* @category Main
|
|
38
38
|
*/
|
|
39
|
-
export declare function createAnthaMultiplayerP2pAuthoritativeHostMod<const Input extends JsonCompatibleValue = any, const
|
|
39
|
+
export declare function createAnthaMultiplayerP2pAuthoritativeHostMod<const Input extends JsonCompatibleValue = any, const MultiplayerGameState extends JsonCompatibleValue = any>(options: Readonly<AnthaMultiplayerP2pAuthoritativeHostOptions<Input, MultiplayerGameState>>): import("@antha/engine").AnthaMod<NoInfer<AnthaMultiplayerP2pAuthoritativeHostState<NoInfer<Input>, NoInfer<MultiplayerGameState>>>>;
|
|
@@ -16,9 +16,9 @@ export declare enum P2pAuthoritativeHostMessageType {
|
|
|
16
16
|
*
|
|
17
17
|
* @category Internal
|
|
18
18
|
*/
|
|
19
|
-
export type P2pAuthoritativeHostStateSnapshot<
|
|
19
|
+
export type P2pAuthoritativeHostStateSnapshot<MultiplayerGameState extends JsonCompatibleValue> = {
|
|
20
20
|
sequence: number;
|
|
21
|
-
state:
|
|
21
|
+
state: MultiplayerGameState;
|
|
22
22
|
} & PartialWithUndefined<{
|
|
23
23
|
/** Identifies the state request that this snapshot fulfills. */
|
|
24
24
|
stateSyncId: SocketMessageId;
|
|
@@ -28,7 +28,7 @@ export type P2pAuthoritativeHostStateSnapshot<State extends JsonCompatibleValue>
|
|
|
28
28
|
*
|
|
29
29
|
* @category Internal
|
|
30
30
|
*/
|
|
31
|
-
export type StateEventDetail<Input extends JsonCompatibleValue,
|
|
31
|
+
export type StateEventDetail<Input extends JsonCompatibleValue, MultiplayerGameState extends JsonCompatibleValue> = P2pAuthoritativeHostStateSnapshot<MultiplayerGameState> & PartialWithUndefined<{
|
|
32
32
|
clientId: ClientId;
|
|
33
33
|
input: Input;
|
|
34
34
|
}>;
|
|
@@ -37,7 +37,7 @@ export type StateEventDetail<Input extends JsonCompatibleValue, State extends Js
|
|
|
37
37
|
*
|
|
38
38
|
* @category Internal
|
|
39
39
|
*/
|
|
40
|
-
export type P2pAuthoritativeHostMessage<Input extends JsonCompatibleValue,
|
|
40
|
+
export type P2pAuthoritativeHostMessage<Input extends JsonCompatibleValue, MultiplayerGameState extends JsonCompatibleValue> = {
|
|
41
41
|
type: P2pAuthoritativeHostMessageType.Input;
|
|
42
42
|
input: Input;
|
|
43
43
|
} | {
|
|
@@ -45,53 +45,53 @@ export type P2pAuthoritativeHostMessage<Input extends JsonCompatibleValue, State
|
|
|
45
45
|
stateSyncId: SocketMessageId;
|
|
46
46
|
} | ({
|
|
47
47
|
type: P2pAuthoritativeHostMessageType.StateSnapshot;
|
|
48
|
-
} & StateEventDetail<Input,
|
|
48
|
+
} & StateEventDetail<Input, MultiplayerGameState>);
|
|
49
49
|
/**
|
|
50
50
|
* Game-specific logic for an authoritative-host connection.
|
|
51
51
|
*
|
|
52
52
|
* @category Internal
|
|
53
53
|
*/
|
|
54
|
-
export type P2pAuthoritativeHostGameDefinition<Input extends JsonCompatibleValue,
|
|
54
|
+
export type P2pAuthoritativeHostGameDefinition<Input extends JsonCompatibleValue, MultiplayerGameState extends JsonCompatibleValue> = {
|
|
55
55
|
/** Create the initial game state before singleplayer or multiplayer starts. */
|
|
56
|
-
createInitialState: () =>
|
|
56
|
+
createInitialState: () => MultiplayerGameState;
|
|
57
57
|
/** Apply an accepted input to the current authoritative state. */
|
|
58
58
|
applyInput: (params: Readonly<{
|
|
59
59
|
clientId: ClientId;
|
|
60
60
|
input: Readonly<Input>;
|
|
61
|
-
state: Readonly<
|
|
62
|
-
}>) =>
|
|
61
|
+
state: Readonly<MultiplayerGameState>;
|
|
62
|
+
}>) => MultiplayerGameState;
|
|
63
63
|
/** Return `false` to reject an input before it changes authoritative state. */
|
|
64
64
|
shouldAcceptInput?: (params: Readonly<{
|
|
65
65
|
clientId: ClientId;
|
|
66
66
|
input: Readonly<Input>;
|
|
67
|
-
state: Readonly<
|
|
67
|
+
state: Readonly<MultiplayerGameState>;
|
|
68
68
|
}>) => boolean | undefined;
|
|
69
69
|
/** Advance authoritative state from elapsed time without a player input. */
|
|
70
70
|
tick?: (params: Readonly<{
|
|
71
71
|
elapsedMs: number;
|
|
72
|
-
state: Readonly<
|
|
73
|
-
}>) =>
|
|
72
|
+
state: Readonly<MultiplayerGameState>;
|
|
73
|
+
}>) => MultiplayerGameState;
|
|
74
74
|
};
|
|
75
75
|
/**
|
|
76
76
|
* Constructor parameters for {@link P2pAuthoritativeHostMultiplayerController}.
|
|
77
77
|
*
|
|
78
78
|
* @category Internal
|
|
79
79
|
*/
|
|
80
|
-
export type P2pAuthoritativeHostMultiplayerControllerParams<Input extends JsonCompatibleValue,
|
|
80
|
+
export type P2pAuthoritativeHostMultiplayerControllerParams<Input extends JsonCompatibleValue, MultiplayerGameState extends JsonCompatibleValue> = {
|
|
81
81
|
/**
|
|
82
82
|
* A unique string id that represents your game so that your lobby server can serve multiple
|
|
83
83
|
* games at once. Your lobby server will need to know this game id ahead of time and match it to
|
|
84
84
|
* your frontend's origin.
|
|
85
85
|
*/
|
|
86
86
|
gameId: string;
|
|
87
|
-
} & P2pAuthoritativeHostGameDefinition<Input,
|
|
87
|
+
} & P2pAuthoritativeHostGameDefinition<Input, MultiplayerGameState> & PartialWithUndefined<{
|
|
88
88
|
/**
|
|
89
89
|
* This is fired when a WebRTC peer attempts to connect to the host client. Return `true` to
|
|
90
90
|
* accept the connection. Return `false` to reject it.
|
|
91
91
|
*
|
|
92
92
|
* @default accept all connections
|
|
93
93
|
*/
|
|
94
|
-
acceptConnection?: ((connectingClientId: ClientId, controller: P2pAuthoritativeHostMultiplayerController<Input,
|
|
94
|
+
acceptConnection?: ((connectingClientId: ClientId, controller: P2pAuthoritativeHostMultiplayerController<Input, MultiplayerGameState>) => MaybePromise<boolean>) | undefined;
|
|
95
95
|
}>;
|
|
96
96
|
declare const ControllerStateEvent_base: (new (eventInitDict: {
|
|
97
97
|
bubbles?: boolean;
|
|
@@ -111,23 +111,23 @@ declare const ControllerStateEvent_base: (new (eventInitDict: {
|
|
|
111
111
|
*
|
|
112
112
|
* @category Events
|
|
113
113
|
*/
|
|
114
|
-
export declare class ControllerStateEvent<
|
|
115
|
-
detail: Readonly<StateEventDetail<Input,
|
|
116
|
-
constructor(eventInitDict: TypedCustomEventInit<Readonly<StateEventDetail<Input,
|
|
114
|
+
export declare class ControllerStateEvent<MultiplayerGameState extends JsonCompatibleValue, Input extends JsonCompatibleValue = any> extends ControllerStateEvent_base {
|
|
115
|
+
detail: Readonly<StateEventDetail<Input, MultiplayerGameState>>;
|
|
116
|
+
constructor(eventInitDict: TypedCustomEventInit<Readonly<StateEventDetail<Input, MultiplayerGameState>>>);
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
119
|
* All events emitted by this controller.
|
|
120
120
|
*
|
|
121
121
|
* @category Internal
|
|
122
122
|
*/
|
|
123
|
-
export type AllP2pAuthoritativeHostMultiplayerControllerEvents<Input extends JsonCompatibleValue,
|
|
123
|
+
export type AllP2pAuthoritativeHostMultiplayerControllerEvents<Input extends JsonCompatibleValue, MultiplayerGameState extends JsonCompatibleValue> = ControllerStateEvent<MultiplayerGameState, Input> | ControllerRoomListEvent | ControllerClientEvent | ControllerConnectionEvent;
|
|
124
124
|
/**
|
|
125
125
|
* An all-in-one controller for singleplayer or p2p-authoritative-host multiplayer game state.
|
|
126
126
|
*
|
|
127
127
|
* @category Main
|
|
128
128
|
*/
|
|
129
|
-
export declare class P2pAuthoritativeHostMultiplayerController<Input extends JsonCompatibleValue = any,
|
|
130
|
-
protected readonly params: P2pAuthoritativeHostMultiplayerControllerParams<Input,
|
|
129
|
+
export declare class P2pAuthoritativeHostMultiplayerController<Input extends JsonCompatibleValue = any, MultiplayerGameState extends JsonCompatibleValue = any> extends ListenTarget<AllP2pAuthoritativeHostMultiplayerControllerEvents<Input, MultiplayerGameState>> {
|
|
130
|
+
protected readonly params: P2pAuthoritativeHostMultiplayerControllerParams<Input, MultiplayerGameState>;
|
|
131
131
|
/** All events emitted by this controller. */
|
|
132
132
|
static readonly events: {
|
|
133
133
|
ControllerStateEvent: typeof ControllerStateEvent;
|
|
@@ -143,14 +143,14 @@ export declare class P2pAuthoritativeHostMultiplayerController<Input extends Jso
|
|
|
143
143
|
RoomRejectionError: typeof RoomRejectionError;
|
|
144
144
|
};
|
|
145
145
|
/** Core multiplayer room controller that owns API, room polling, signaling, and transport. */
|
|
146
|
-
readonly roomController: MultiplayerRoomController<P2pAuthoritativeHostMessage<Input,
|
|
146
|
+
readonly roomController: MultiplayerRoomController<P2pAuthoritativeHostMessage<Input, MultiplayerGameState>>;
|
|
147
147
|
protected readonly localClientId: ClientId;
|
|
148
|
-
protected roomConnection: MultiplayerRoomConnection<P2pAuthoritativeHostMessage<Input,
|
|
149
|
-
protected currentState:
|
|
148
|
+
protected roomConnection: MultiplayerRoomConnection<P2pAuthoritativeHostMessage<Input, MultiplayerGameState>> | undefined;
|
|
149
|
+
protected currentState: MultiplayerGameState;
|
|
150
150
|
protected currentSequence: number;
|
|
151
151
|
protected pendingStateSyncId: SocketMessageId | undefined;
|
|
152
152
|
protected singleplayer: boolean;
|
|
153
|
-
constructor(params: P2pAuthoritativeHostMultiplayerControllerParams<Input,
|
|
153
|
+
constructor(params: P2pAuthoritativeHostMultiplayerControllerParams<Input, MultiplayerGameState>);
|
|
154
154
|
/** Current p2p-authoritative-host connection, exposed for compatibility checks. */
|
|
155
155
|
get currentConnection(): this | undefined;
|
|
156
156
|
/** The current client id. */
|
|
@@ -199,7 +199,7 @@ export declare class P2pAuthoritativeHostMultiplayerController<Input extends Jso
|
|
|
199
199
|
*/
|
|
200
200
|
getAllClientIds(): ClientId[];
|
|
201
201
|
/** Get the latest local state view. */
|
|
202
|
-
getState():
|
|
202
|
+
getState(): MultiplayerGameState;
|
|
203
203
|
/** Initialize multiplayer API access without opening a room or starting host pings. */
|
|
204
204
|
initMultiplayer(params: Readonly<MultiplayerInitParams>): Promise<void>;
|
|
205
205
|
/** Start local play without contacting the multiplayer API. This can later open into a room. */
|
|
@@ -217,40 +217,40 @@ export declare class P2pAuthoritativeHostMultiplayerController<Input extends Jso
|
|
|
217
217
|
/** Join or create a room. */
|
|
218
218
|
joinOrCreateRoom(room: Readonly<RoomInput>): Promise<void>;
|
|
219
219
|
/** Join through the core room controller after its candidate connection is state-synchronized. */
|
|
220
|
-
protected joinRoom(room: Readonly<RoomInput>): Promise<MultiplayerRoomConnection<P2pAuthoritativeHostMessage<Input,
|
|
220
|
+
protected joinRoom(room: Readonly<RoomInput>): Promise<MultiplayerRoomConnection<P2pAuthoritativeHostMessage<Input, MultiplayerGameState>>>;
|
|
221
221
|
/** Leave the current room or single player connection. */
|
|
222
222
|
leaveRoom(): void;
|
|
223
223
|
/** Forward core room-controller events into this state-sync controller. */
|
|
224
224
|
protected listenToRoomController(): void;
|
|
225
225
|
/** Attach an established room transport and publish the current state view. */
|
|
226
|
-
protected attachMultiplayerRoomConnection(roomConnection: Readonly<MultiplayerRoomConnection<P2pAuthoritativeHostMessage<Input,
|
|
226
|
+
protected attachMultiplayerRoomConnection(roomConnection: Readonly<MultiplayerRoomConnection<P2pAuthoritativeHostMessage<Input, MultiplayerGameState>>>): void;
|
|
227
227
|
/** Apply received inputs on the host or received state snapshots on member clients. */
|
|
228
|
-
protected handleReceivedMessage(sourceClientId: ClientId, message: Readonly<P2pAuthoritativeHostMessage<Input,
|
|
228
|
+
protected handleReceivedMessage(sourceClientId: ClientId, message: Readonly<P2pAuthoritativeHostMessage<Input, MultiplayerGameState>>): void;
|
|
229
229
|
/** Attach and synchronize a candidate room before the core controller commits to it. */
|
|
230
|
-
protected prepareRoomConnection(roomConnection: Readonly<MultiplayerRoomConnection<P2pAuthoritativeHostMessage<Input,
|
|
230
|
+
protected prepareRoomConnection(roomConnection: Readonly<MultiplayerRoomConnection<P2pAuthoritativeHostMessage<Input, MultiplayerGameState>>>): Promise<void>;
|
|
231
231
|
/** Validate and apply an input against the current authoritative state. */
|
|
232
232
|
protected applyInput({ clientId, input, }: Readonly<{
|
|
233
233
|
clientId: ClientId;
|
|
234
234
|
input: Readonly<Input>;
|
|
235
235
|
}>): void;
|
|
236
236
|
/** Publish a new authoritative state that was not caused by a player input. */
|
|
237
|
-
protected updateState(state:
|
|
237
|
+
protected updateState(state: MultiplayerGameState): void;
|
|
238
238
|
/** Publish a new authoritative state caused by a player input. */
|
|
239
239
|
protected updateStateFromInput({ clientId, input, state, }: Readonly<{
|
|
240
240
|
clientId: ClientId;
|
|
241
241
|
input: Readonly<Input>;
|
|
242
|
-
state:
|
|
242
|
+
state: MultiplayerGameState;
|
|
243
243
|
}>): void;
|
|
244
244
|
/** Dispatch the typed state event to local listeners. */
|
|
245
|
-
protected dispatchState(detail: Readonly<StateEventDetail<Input,
|
|
245
|
+
protected dispatchState(detail: Readonly<StateEventDetail<Input, MultiplayerGameState>>): void;
|
|
246
246
|
/** Broadcast a state snapshot when the local client is the host. */
|
|
247
|
-
protected sendStateSnapshot(detail: Readonly<StateEventDetail<Input,
|
|
247
|
+
protected sendStateSnapshot(detail: Readonly<StateEventDetail<Input, MultiplayerGameState>>): void;
|
|
248
248
|
/** Create a network message from state event detail. */
|
|
249
|
-
protected createStateSnapshotMessage(detail: Readonly<StateEventDetail<Input,
|
|
249
|
+
protected createStateSnapshotMessage(detail: Readonly<StateEventDetail<Input, MultiplayerGameState>>, stateSyncId?: SocketMessageId | undefined): P2pAuthoritativeHostMessage<Input, MultiplayerGameState>;
|
|
250
250
|
/** Create the local state event detail for the current sequence and state. */
|
|
251
251
|
protected createStateEventDetail(source?: Readonly<PartialWithUndefined<{
|
|
252
252
|
clientId: ClientId;
|
|
253
253
|
input: Readonly<Input>;
|
|
254
|
-
}>>): StateEventDetail<Input,
|
|
254
|
+
}>>): StateEventDetail<Input, MultiplayerGameState>;
|
|
255
255
|
}
|
|
256
256
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antha/multiplayer-p2p-authoritative-host",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "P2P authoritative-host multiplayer strategy for the Antha engine.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vir",
|
|
@@ -36,19 +36,19 @@
|
|
|
36
36
|
"test:docs": "virmator docs check"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@augment-vir/assert": "^32.2.
|
|
40
|
-
"@augment-vir/common": "^32.2.
|
|
39
|
+
"@augment-vir/assert": "^32.2.4",
|
|
40
|
+
"@augment-vir/common": "^32.2.4",
|
|
41
41
|
"typed-event-target": "^4.3.3"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@augment-vir/test": "^32.2.
|
|
44
|
+
"@augment-vir/test": "^32.2.4",
|
|
45
45
|
"@web/dev-server-esbuild": "^2.0.0",
|
|
46
46
|
"@web/test-runner": "^1.0.0",
|
|
47
47
|
"@web/test-runner-playwright": "^1.0.0",
|
|
48
48
|
"istanbul-smart-text-reporter": "^1.1.5"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@antha/multiplayer-core": "^0.
|
|
51
|
+
"@antha/multiplayer-core": "^0.14.0"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=22"
|