@rbxts/replecs 0.4.0-rc.1 → 0.4.0-rc.2.ts.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.
@@ -0,0 +1,297 @@
1
+ import type { Entity, Id, InferComponent, Pair, Tag, World } from "@rbxts/jecs";
2
+
3
+ declare namespace Replecs {
4
+ export type SerdesTable<T = any> =
5
+ | {
6
+ bytespan?: number;
7
+ includes_variants?: false;
8
+ serialize: (value: T) => buffer;
9
+ deserialize: (buffer: buffer) => T;
10
+ }
11
+ | {
12
+ bytespan?: number;
13
+ includes_variants: true;
14
+ serialize: (value: T) => LuaTuple<[buffer, defined[] | undefined]>;
15
+ deserialize: (buffer: buffer, blobs: defined[] | undefined) => T;
16
+ };
17
+
18
+ export type Serdes<T = any> = SerdesTable<T>;
19
+
20
+ export interface Preprocessor<B = any, A = any> {
21
+ serialize: (value: B) => A;
22
+ deserialize: (value: A) => B;
23
+ }
24
+
25
+ export interface DeltaSerializer<T = any, D = T> {
26
+ snapshot?: (value: T) => T;
27
+ delta: (old: T, curr: T) => D;
28
+ apply: (curr: T, delta: D) => T;
29
+ }
30
+
31
+ type MemberFilterMap = Map<Player, boolean>;
32
+ export type MemberFilterPredicate = (player: Player) => boolean;
33
+ type MemberFilter =
34
+ | Player
35
+ | MemberFilterMap
36
+ | MemberFilterPredicate
37
+ | Record<string, never>
38
+ | undefined;
39
+ type Member = unknown;
40
+
41
+ export interface SharedInfo<T> {
42
+ lookup: Record<string, T>;
43
+ keys: string[];
44
+ indexes: T[];
45
+ members: Map<T, number>;
46
+ }
47
+ export interface HandleContext {
48
+ entity_id: number;
49
+ component: <T>(component: Entity<T>) => T;
50
+ target: (relation: Id, index?: number) => Entity | undefined;
51
+ pair_value: <T>(relation: Id<T>, target: Entity) => T | undefined;
52
+ has_pair: (relation: Id, target: Entity) => boolean;
53
+
54
+ entity: (server_entity: number) => Entity | undefined;
55
+ has: (tag: Entity) => boolean;
56
+ }
57
+ export interface CustomId {
58
+ identifier: string;
59
+ handle_callback: (ctx: HandleContext) => Entity;
60
+ handle(handler: (ctx: HandleContext) => Entity): void;
61
+ }
62
+
63
+ export interface Shared {
64
+ components: SharedInfo<Entity>;
65
+ custom_ids: SharedInfo<CustomId>;
66
+ serdes: Map<Id, SerdesTable>;
67
+ }
68
+ interface HandshakeSerdesInfo {
69
+ includes_variants?: boolean;
70
+ bytespan?: number;
71
+ }
72
+
73
+ export interface HandshakeInfo {
74
+ components: Record<string, boolean>;
75
+ custom_ids: Record<string, boolean>;
76
+ serdes: Record<string, HandshakeSerdesInfo>;
77
+ }
78
+
79
+ export interface Components {
80
+ shared: Tag;
81
+ networked: Entity<MemberFilter>;
82
+ reliable: Entity<MemberFilter>;
83
+ unreliable: Entity<MemberFilter>;
84
+ once: Entity<MemberFilter>;
85
+ relation: Entity<MemberFilter>;
86
+
87
+ serdes: Entity<SerdesTable>;
88
+ custom: Entity;
89
+ custom_handler: Entity<(value: any) => Entity>;
90
+
91
+ Shared: Tag;
92
+ Networked: Entity<MemberFilter>;
93
+ Reliable: Entity<MemberFilter>;
94
+ Unreliable: Entity<MemberFilter>;
95
+ Once: Entity<MemberFilter>;
96
+ Relation: Entity<MemberFilter>;
97
+
98
+ Serdes: Entity<SerdesTable>;
99
+ Custom: Entity;
100
+ CustomHandler: Entity<(value: any) => Entity>;
101
+ }
102
+
103
+ interface SerializationOptions {
104
+ set_serdes<T extends Id>(
105
+ component: InferComponent<T>,
106
+ serdes: SerdesTable<T>,
107
+ ): void;
108
+ remove_serdes(component: Id): void;
109
+
110
+ set_preprocessor<T extends Id, A = any>(
111
+ component: T,
112
+ preprocessor: Preprocessor<InferComponent<T>, A>,
113
+ ): void;
114
+ remove_preprocessor(component: Id): void;
115
+
116
+ set_delta_serializer<T extends Id, D = InferComponent<T>>(
117
+ component: T,
118
+ delta: DeltaSerializer<InferComponent<T>, D>,
119
+ ): void;
120
+ remove_delta_serializer(component: Id): void;
121
+ }
122
+
123
+ export interface ClientImp extends SerializationOptions {}
124
+
125
+ export interface Client extends ClientImp {
126
+ world: World;
127
+ inited?: boolean;
128
+
129
+ is_replicating: boolean;
130
+ after_replication_callbacks: (() => void)[];
131
+
132
+ components: Components;
133
+ shared: Shared;
134
+
135
+ init(world?: World): void;
136
+ destroy(): void;
137
+ handle_global(handler: (id: number) => Entity): void;
138
+ get_server_entity(client_entity: Entity): number | undefined;
139
+ get_client_entity(server_entity: number): Entity | undefined;
140
+
141
+ register_entity(entity: Entity, server_entity: number): void;
142
+ unregister_entity(entity: Entity): void;
143
+
144
+ after_replication(callback: () => void): void;
145
+ added(callback: (entity: Entity) => void): () => void;
146
+
147
+ hook<T>(
148
+ action: "changed",
149
+ relation: Pair<MemberFilter, T>,
150
+ callback: (entity: Entity, id: Id<T>, value: T) => void,
151
+ ): () => void;
152
+ hook<T>(
153
+ action: "removed",
154
+ relation: Pair<MemberFilter, T>,
155
+ callback: (entity: Entity, id: Id<T>) => void,
156
+ ): () => void;
157
+ hook(
158
+ action: "deleted",
159
+ entity: Entity,
160
+ callback: (entity: Entity) => void,
161
+ ): () => void;
162
+
163
+ override<T>(
164
+ action: "changed",
165
+ relation: Pair<MemberFilter, T>,
166
+ callback: (entity: Entity, id: Id<T>, value: T) => void,
167
+ ): () => void;
168
+ override<T>(
169
+ action: "removed",
170
+ relation: Pair<MemberFilter, T>,
171
+ callback: (entity: Entity, id: Id<T>) => void,
172
+ ): () => void;
173
+ override(
174
+ action: "deleted",
175
+ entity: Entity,
176
+ callback: (entity: Entity) => void,
177
+ ): () => void;
178
+
179
+ encode_component(component: Entity): number;
180
+ decode_component(encoded: number): Entity | undefined;
181
+ get_shared_count(): number;
182
+
183
+ register_custom_id(custom_id: CustomId): void;
184
+
185
+ apply_updates(buf: buffer, all_variants?: defined[][]): void;
186
+ apply_unreliable(buf: buffer, all_variants?: defined[][]): void;
187
+ apply_full(buf: buffer, variants?: defined[]): void;
188
+ apply_entity(buf: buffer, all_variants?: defined[][]): void;
189
+
190
+ generate_handshake(): HandshakeInfo;
191
+ verify_handshake(
192
+ handshake: HandshakeInfo,
193
+ ): LuaTuple<[true]> | LuaTuple<[false, string]>;
194
+ }
195
+
196
+ export interface ServerImp extends SerializationOptions {
197
+ set_networked(entity: Entity, filter?: MemberFilter): void;
198
+ set_reliable(
199
+ entity: Entity,
200
+ component: Entity,
201
+ filter?: MemberFilter,
202
+ ): void;
203
+ set_unreliable(
204
+ entity: Entity,
205
+ component: Entity,
206
+ filter?: MemberFilter,
207
+ ): void;
208
+ set_once(entity: Entity, component: Entity, filter?: MemberFilter): void;
209
+ set_pair(entity: Entity, id: Pair, filter?: MemberFilter): void;
210
+ set_unreliable_pair(entity: Entity, id: Pair, filter?: MemberFilter): void;
211
+ set_relation(entity: Entity, relation: Entity, filter?: MemberFilter): void;
212
+
213
+ stop_networked(entity: Entity): void;
214
+ stop_reliable(entity: Entity, component: Entity): void;
215
+ stop_unreliable(entity: Entity, component: Entity): void;
216
+ stop_once(entity: Entity, component: Entity): void;
217
+ stop_pair(entity: Entity, id: Pair): void;
218
+ stop_unreliable_pair(entity: Entity, id: Pair): void;
219
+ stop_relation(entity: Entity, relation: Entity): void;
220
+
221
+ /** Marks a reliable/once component dirty so its current value replicates again. */
222
+ force_change(entity: Entity, component: Entity): void;
223
+
224
+ set_global(entity: Entity, global_id: number): void;
225
+ remove_global(entity: Entity): void;
226
+ set_custom(entity: Entity, handler: Entity | CustomId): void;
227
+ remove_custom(entity: Entity): void;
228
+ }
229
+
230
+ export interface Server extends ServerImp {
231
+ world: World;
232
+ inited?: boolean;
233
+
234
+ components: Components;
235
+ shared: Shared;
236
+
237
+ init(world?: World): void;
238
+ destroy(): void;
239
+
240
+ encode_component(component: Entity): number;
241
+ decode_component(encoded: number): Entity | undefined;
242
+ get_shared_count(): number;
243
+
244
+ register_custom_id(custom_id: CustomId): void;
245
+
246
+ get_full(player: Player): LuaTuple<[buffer, defined[]]>;
247
+ collect_entity(
248
+ entity: Entity,
249
+ ): IterableFunction<LuaTuple<[Player, buffer, defined[][] | undefined]>>;
250
+ collect_updates(): IterableFunction<
251
+ LuaTuple<[Player, buffer, defined[][] | undefined]>
252
+ >;
253
+ collect_unreliable(): IterableFunction<
254
+ LuaTuple<[Player, buffer, defined[][] | undefined]>
255
+ >;
256
+
257
+ register_player(player: Player): void;
258
+ remove_player(player: Player): void;
259
+ mark_player_ready(player: Player): void;
260
+ is_player_ready(player: Player): boolean;
261
+
262
+ add_player_alias(client: Player, alias: defined): void;
263
+ remove_player_alias(alias: defined): void;
264
+
265
+ generate_handshake(): HandshakeInfo;
266
+ verify_handshake(
267
+ handshake: HandshakeInfo,
268
+ ): LuaTuple<[true]> | LuaTuple<[false, string]>;
269
+ }
270
+
271
+ export interface ReplecsLib extends SerializationOptions {
272
+ client: Client;
273
+ server: Server;
274
+ components: Components;
275
+
276
+ after_replication(callback: () => void): void;
277
+ register_custom_id(custom_id: CustomId): void;
278
+ }
279
+
280
+ export interface Replecs extends Components {
281
+ VERSION: string;
282
+ /** Client cap used to size the server bitmasks. Read at `create` / `create_server`. */
283
+ MAX_CLIENTS: number;
284
+
285
+ create: (world?: World) => ReplecsLib;
286
+ create_server: (world?: World) => Server;
287
+ create_client: (world?: World) => Client;
288
+ create_custom_id: (
289
+ identifier: string,
290
+ handler?: (ctx: HandleContext) => Entity,
291
+ ) => CustomId;
292
+ }
293
+ }
294
+
295
+ declare const Replecs: Replecs.Replecs;
296
+
297
+ export = Replecs;
@@ -216,7 +216,6 @@ export type Server = ServerImp & {
216
216
  last_active_bitmask: Bitmask,
217
217
  newly_active_bitmask: Bitmask,
218
218
  newly_unactive_bitmask: Bitmask,
219
- pending_active: Set<Player>,
220
219
 
221
220
  entity_bitmask_deltas: BitmaskDeltas,
222
221
  component_bitmask_deltas: BitmaskDeltas,
@@ -2456,15 +2455,6 @@ local function collect_updates_groups(self: Server): Map<MaskHash, SerializeGrou
2456
2455
  local newly_active = self.newly_active_bitmask
2457
2456
  local newly_unactive = self.newly_unactive_bitmask
2458
2457
 
2459
- local client_indexes = self.registry.client_indexes
2460
- for player in self.pending_active do
2461
- local index = client_indexes[player]
2462
- if index then
2463
- bitmasks.set(active, index)
2464
- end
2465
- end
2466
- table.clear(self.pending_active)
2467
-
2468
2458
  bitmasks.exclude(active, last_active, newly_active)
2469
2459
  bitmasks.exclude(last_active, active, newly_unactive)
2470
2460
 
@@ -3596,10 +3586,10 @@ function server.mark_player_ready(self: Server, player: Player)
3596
3586
  registry:register_client(player)
3597
3587
 
3598
3588
  local index = registry.client_indexes[player]
3599
- if index and bitmasks.test(self.client_active_bitmask, index) then
3589
+ if not index then
3600
3590
  return
3601
3591
  end
3602
- self.pending_active[player] = true
3592
+ bitmasks.set(self.client_active_bitmask, index)
3603
3593
  end
3604
3594
 
3605
3595
  function server.is_player_ready(self: Server, player: Player): boolean
@@ -3681,7 +3671,6 @@ function server.remove_player(self: Server, player: Player)
3681
3671
  end
3682
3672
  end
3683
3673
 
3684
- self.pending_active[player] = nil
3685
3674
  registry:remove_client_aliases(player)
3686
3675
  registry:unregister_client(player)
3687
3676
  end
@@ -3914,7 +3903,6 @@ function server.create(world: World?, components: types.Components?, max_clients
3914
3903
  self.last_active_bitmask = buffer.create(self.bitmask_size)
3915
3904
  self.newly_active_bitmask = buffer.create(self.bitmask_size)
3916
3905
  self.newly_unactive_bitmask = buffer.create(self.bitmask_size)
3917
- self.pending_active = {}
3918
3906
 
3919
3907
  self.entity_bitmask_deltas = {
3920
3908
  added = buffer.create(self.bitmask_size),
@@ -1 +1 @@
1
- return "v0.4.0-rc.1"
1
+ return "0.4.0-rc.2.ts.1"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/replecs",
3
- "version": "0.4.0-rc.1",
3
+ "version": "0.4.0-rc.2.ts.1",
4
4
  "description": "Replication library for Jecs",
5
5
  "main": "out/init.luau",
6
6
  "types": "out/index.d.ts",
@@ -21,8 +21,7 @@
21
21
  "out",
22
22
  "!**/*.spec.lua",
23
23
  "!**/*.spec.d.ts",
24
- "!**/*.tsbuildinfo",
25
- "!out/replecs/index.d.ts"
24
+ "!**/*.tsbuildinfo"
26
25
  ],
27
26
  "scripts": {
28
27
  "serve": "rojo sourcemap serve.project.json -o sourcemap.json --watch && rojo serve serve.project.json"