@rbxts/replecs 0.1.0-alpha9 → 0.2.0-cdtest.2

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.
@@ -1,52 +1,69 @@
1
1
  local jecs = require "../jecs"
2
+ local customid = require "./customid"
3
+
4
+ export type FunctionFilter = (player: Player) -> boolean
5
+ export type AnyFilter = PlayerFilter | Player
6
+ type Entity<T = any> = jecs.Entity<T>
2
7
 
3
8
  export type PlayerFilter = {
4
9
  [Player]: boolean,
5
10
  }
6
11
 
12
+ export type SharedInfo<T> = {
13
+ lookup: { [string]: T },
14
+ keys: { string },
15
+ indexes: { [number]: T },
16
+ members: { [T]: number },
17
+ }
18
+ export type HandshakeInfo = {
19
+ components: { [string]: boolean },
20
+ custom_ids: { [string]: boolean },
21
+ serdes: { [string]: {
22
+ includes_variants: boolean?,
23
+ bytespan: number?,
24
+ } },
25
+ }
26
+
7
27
  export type Serdes = {
8
28
  includes_variants: boolean?,
29
+ bytespan: number?,
9
30
  serialize: (value: any) -> (buffer, { any }?),
10
31
  deserialize: (buffer, { any }?) -> any,
11
32
  }
12
33
 
13
34
  export type Components = {
14
- shared: jecs.Entity,
15
- networked: jecs.Entity<PlayerFilter?>,
16
- reliable: jecs.Entity,
17
- unreliable: jecs.Entity,
18
- pair: jecs.Entity,
19
-
20
- serdes: jecs.Entity<Serdes>,
21
- bytespan: jecs.Entity<number>,
22
- custom: jecs.Entity,
23
- custom_handler: jecs.Entity<(value: any) -> jecs.Entity>,
24
- global: jecs.Entity<number>,
25
- __alive_tracking__: jecs.Entity,
35
+ shared: Entity,
36
+ networked: Entity<AnyFilter?>,
37
+ reliable: Entity<AnyFilter?>,
38
+ unreliable: Entity<AnyFilter?>,
39
+ pair: Entity<AnyFilter?>,
40
+
41
+ serdes: Entity<Serdes>,
42
+ custom: Entity,
43
+ custom_handler: Entity<(val: any) -> Entity?>,
44
+ global: Entity<number>,
45
+ __alive_tracking__: Entity,
26
46
  }
27
47
 
28
48
  export type Shared = {
29
- lookup: { [string]: jecs.Entity },
30
-
31
- components: { [number]: jecs.Entity },
32
- ids: { [jecs.Entity]: number },
49
+ components: SharedInfo<Entity>,
50
+ custom_ids: SharedInfo<customid.CustomId>,
33
51
 
34
- bytespan: { [jecs.Entity]: number },
35
- serdes: { [jecs.Entity]: Serdes },
52
+ serdes: { [Entity]: Serdes },
36
53
  }
37
54
 
38
55
  export type WorldHooks = {
39
56
  added: (
40
57
  world: jecs.World,
41
- component: jecs.Entity,
42
- fn: (entity: jecs.Entity, id: jecs.Id, value: any) -> ()
58
+ component: Entity,
59
+ fn: (entity: Entity, id: jecs.Id, value: any) -> ()
43
60
  ) -> () -> (),
44
61
  changed: (
45
62
  world: jecs.World,
46
- component: jecs.Entity,
47
- fn: (entity: jecs.Entity, id: jecs.Id, value: any) -> ()
63
+ component: Entity,
64
+ fn: (entity: Entity, id: jecs.Id, value: any) -> ()
48
65
  ) -> () -> (),
49
- removed: (world: jecs.World, component: jecs.Entity, fn: (entity: jecs.Entity, id: jecs.Id) -> ()) -> () -> (),
66
+ removed: (world: jecs.World, component: Entity, fn: (entity: Entity, id: jecs.Id) -> ()) -> () -> (),
50
67
  }
51
68
 
52
69
  return nil
@@ -0,0 +1,39 @@
1
+ local jecs = require "../jecs"
2
+
3
+ type Entity<T = any> = jecs.Entity<T>
4
+ type Id<T = any> = jecs.Id<T>
5
+ type World = jecs.World
6
+
7
+ export type HandleContext = {
8
+ entity_id: number,
9
+ component: <T>(component: Entity<T>) -> T,
10
+ target: (relation: jecs.Id, index: number?) -> Entity?,
11
+ pair_value: <T>(relation: jecs.Id<T>, target: Entity) -> T?,
12
+ has_pair: (relation: jecs.Id, target: Entity) -> boolean,
13
+
14
+ entity: (server_entity: number) -> Entity,
15
+ has: (tag: Entity) -> boolean,
16
+ }
17
+
18
+ export type CustomId = {
19
+ identifier: string,
20
+ handle_callback: ((ctx: HandleContext) -> Entity?)?,
21
+
22
+ handle: (self: CustomId, handler: (ctx: HandleContext) -> Entity?) -> (),
23
+ }
24
+
25
+ local custom_id = {}
26
+
27
+ function custom_id.handle(custom: CustomId, callback: (ctx: HandleContext) -> Entity?)
28
+ custom.handle_callback = callback
29
+ end
30
+
31
+ function create(identifier: string, callback: ((ctx: HandleContext) -> Entity?)?): CustomId
32
+ local handler = {} :: CustomId
33
+ handler.identifier = identifier
34
+ handler.handle_callback = callback
35
+
36
+ return setmetatable(handler, custom_id) :: any
37
+ end
38
+
39
+ return { create = create }
@@ -3,11 +3,13 @@ import type { Entity, Id, Pair, Tag, World } from "@rbxts/jecs";
3
3
  declare namespace Replecs {
4
4
  export type SerdesTable =
5
5
  | {
6
+ bytespan?: number;
6
7
  includes_variants?: false;
7
8
  serialize: (value: any) => buffer;
8
9
  deserialize: (buffer: buffer) => any;
9
10
  }
10
11
  | {
12
+ bytespan?: number;
11
13
  includes_variants: true;
12
14
  serialize: (value: any) => LuaTuple<[buffer, defined[] | undefined]>;
13
15
  deserialize: (buffer: buffer, blobs: defined[] | undefined) => any;
@@ -17,11 +19,41 @@ declare namespace Replecs {
17
19
  type MemberFilter = Player | MemberFilterMap | undefined;
18
20
  type Member = unknown;
19
21
 
20
- interface MaskingController {
21
- register_member(member: Member): void;
22
- unregister_member(member: Member): void;
23
- active_member(member: Member): void;
24
- member_is_active(member: Member): boolean;
22
+ export interface SharedInfo<T> {
23
+ lookup: Record<string, T>;
24
+ keys: string[];
25
+ indexes: [T];
26
+ members: Map<T, number>;
27
+ }
28
+ export interface HandleContext {
29
+ entity_id: number;
30
+ component: <T>(component: Entity<T>) => T;
31
+ target: (relation: Id, index?: number) => Entity | undefined;
32
+ pair_value: <T>(relation: Id<T>, target: Entity) => T | undefined;
33
+ has_pair: (relation: Id, target: Entity) => boolean;
34
+
35
+ entity: (server_entity: number) => Entity | undefined;
36
+ has: (tag: Entity) => boolean;
37
+ }
38
+ export interface CustomId {
39
+ identifier: string;
40
+ handle_callback: (ctx: HandleContext) => Entity;
41
+ handle(handler: (ctx: HandleContext) => Entity): void;
42
+ }
43
+
44
+ export interface Shared {
45
+ components: SharedInfo<Entity>;
46
+ custom_ids: SharedInfo<CustomId>;
47
+ }
48
+ interface HandshakeSerdesInfo {
49
+ includes_variants?: boolean;
50
+ bytespan?: number;
51
+ }
52
+
53
+ export interface HandshakeInfo {
54
+ components: Record<string, boolean>;
55
+ custom_ids: Record<string, boolean>;
56
+ serdes: Record<string, HandshakeSerdesInfo>;
25
57
  }
26
58
 
27
59
  export interface Components {
@@ -32,7 +64,6 @@ declare namespace Replecs {
32
64
  pair: Entity<MemberFilter>;
33
65
 
34
66
  serdes: Entity<SerdesTable>;
35
- bytespan: Entity<number>;
36
67
  custom: Entity;
37
68
  custom_handler: Entity<(value: any) => Entity>;
38
69
  global: Entity<number>;
@@ -44,7 +75,6 @@ declare namespace Replecs {
44
75
  Pair: Entity<MemberFilter>;
45
76
 
46
77
  Serdes: Entity<SerdesTable>;
47
- Bytespan: Entity<number>;
48
78
  Custom: Entity;
49
79
  CustomHandler: Entity<(value: any) => Entity>;
50
80
  Global: Entity<number>;
@@ -54,13 +84,25 @@ declare namespace Replecs {
54
84
  world: World;
55
85
  inited?: boolean;
56
86
 
87
+ is_relicating: boolean;
88
+ after_relication_callbacks: [() => void];
89
+
90
+ components: Components;
91
+
57
92
  init(world?: World): void;
58
93
  destroy(): void;
59
94
 
60
95
  handle_global(handler: (id: number) => Entity): void;
61
96
 
97
+ get_server_entity(client_entity: Entity): number | undefined;
98
+ get_client_entity(server_entity: number): Entity | undefined;
99
+
100
+ register_entity(entity: Entity, server_entity: number): void;
101
+ unregister_entity(entity: Entity): void;
102
+
62
103
  after_replication(callback: () => void): void;
63
104
  added(callback: (entity: Entity) => void): () => void;
105
+
64
106
  hook<T>(
65
107
  action: "changed",
66
108
  relation: Pair<MemberFilter, T>,
@@ -95,22 +137,67 @@ declare namespace Replecs {
95
137
 
96
138
  encode_component(component: Entity): number;
97
139
  decode_component(encoded: number): Entity;
98
-
99
- get_server_entity(client_entity: Entity): number | undefined;
100
- get_client_entity(server_entity: number): Entity | undefined;
140
+ register_custom_id(custom_id: CustomId): void;
101
141
 
102
142
  apply_updates(buf: buffer, all_variants?: unknown[][]): void;
103
143
  apply_unreliable(buf: buffer, all_variants?: unknown[][]): void;
104
144
  apply_full(buf: buffer, all_variants?: unknown[][]): void;
145
+
146
+ generate_handshake(): HandshakeInfo;
147
+ verify_handshake(
148
+ handshake: HandshakeInfo
149
+ ): LuaTuple<[true]> | LuaTuple<[false, string]>;
105
150
  }
106
151
 
107
- export interface Server {
152
+ export interface ServerImp {
153
+ set_networked(
154
+ server: Server,
155
+ entity: Entity,
156
+ filter?: MemberFilter
157
+ ): void;
158
+ stop_networked(server: Server, entity: Entity): void;
159
+
160
+ set_reliable(
161
+ server: Server,
162
+ entity: Entity,
163
+ component: Entity,
164
+ filter?: MemberFilter
165
+ ): void;
166
+ set_unreliable(
167
+ server: Server,
168
+ entity: Entity,
169
+ component: Entity,
170
+ filter?: MemberFilter
171
+ ): void;
172
+ set_pair(
173
+ server: Server,
174
+ entity: Entity,
175
+ relation: Entity,
176
+ filter?: MemberFilter
177
+ ): void;
178
+ set_custom(
179
+ server: Server,
180
+ entity: Entity,
181
+ handler: Entity | CustomId
182
+ ): void;
183
+
184
+ stop_reliable(server: Server, entity: Entity, component: Entity): void;
185
+ stop_unreliable(server: Server, entity: Entity, component: Entity): void;
186
+ stop_pair(server: Server, entity: Entity, relation: Entity): void;
187
+ remove_custom(server: Server, entity: Entity): void;
188
+ }
189
+
190
+ export interface Server extends ServerImp {
108
191
  world: World;
109
192
  inited?: boolean;
110
193
 
111
194
  init(world?: World): void;
112
195
  destroy(): void;
113
196
 
197
+ encode_component(component: Entity): number;
198
+ decode_component(encoded: number): Entity;
199
+ register_custom_id(custom_id: CustomId): void;
200
+
114
201
  get_full(player: Player): LuaTuple<[buffer, unknown[][]]>;
115
202
  collect_updates(): IterableFunction<
116
203
  LuaTuple<[Player, buffer, unknown[][]]>
@@ -119,16 +206,16 @@ declare namespace Replecs {
119
206
  LuaTuple<[Player, buffer, unknown[][]]>
120
207
  >;
121
208
 
122
- encode_component(component: Entity): number;
123
- decode_component(encoded: number): Entity;
124
-
125
209
  mark_player_ready(player: Player): void;
126
210
  is_player_ready(player: Player): boolean;
127
211
 
128
212
  add_player_alias(client: Player, alias: defined): void;
129
213
  remove_player_alias(alias: defined): void;
130
214
 
131
- masking: MaskingController;
215
+ generate_handshake(): HandshakeInfo;
216
+ verify_handshake(
217
+ handshake: HandshakeInfo
218
+ ): LuaTuple<[true]> | LuaTuple<[false, string]>;
132
219
  }
133
220
 
134
221
  export interface ReplecsLib {
@@ -136,12 +223,19 @@ declare namespace Replecs {
136
223
  server: Server;
137
224
 
138
225
  after_replication(callback: () => void): void;
226
+ register_custom_id(custom_id: CustomId): void;
139
227
  }
140
228
 
141
229
  export interface Replecs extends Components {
230
+ VERSION: string;
231
+
142
232
  create: (world?: World) => ReplecsLib;
143
233
  create_server: (world?: World) => Server;
144
234
  create_client: (world?: World) => Client;
235
+ create_custom_id: (
236
+ identifier: string,
237
+ handler?: (ctx: HandleContext) => Entity
238
+ ) => CustomId;
145
239
  }
146
240
  }
147
241
 
@@ -3,15 +3,32 @@ local common = require "@self/common"
3
3
 
4
4
  local client = require "@self/client"
5
5
  local server = require "@self/server"
6
+ local customid = require "@self/customid"
7
+ local VERSION = require "@self/ver"
6
8
 
7
9
  export type Server = server.Server
8
10
  export type Client = client.Client
9
11
 
12
+ export type HandleContext = customid.HandleContext
13
+ export type CustomId = customid.CustomId
14
+ export type HandshakeInfo = common.HandshakeInfo
15
+
16
+ type Entity = jecs.Entity
17
+
10
18
  export type ReplecsLib = {
11
19
  server: Server,
12
20
  client: Client,
13
21
 
14
22
  after_replication: (self: ReplecsLib, callback: () -> ()) -> (),
23
+ register_custom_id: (self: ReplecsLib, custom_id: CustomId) -> (),
24
+ }
25
+
26
+ type Replecs = common.Components & {
27
+ create: (world: jecs.World?) -> ReplecsLib,
28
+
29
+ create_server: (world: jecs.World?) -> Server,
30
+ create_client: (world: jecs.World?) -> Client,
31
+ create_custom_id: (identifier: string, handler: (ctx: HandleContext) -> Entity?) -> CustomId,
15
32
  }
16
33
 
17
34
  type MemberFilter = {
@@ -19,23 +36,22 @@ type MemberFilter = {
19
36
  }
20
37
 
21
38
  local replecs = {
39
+ VERSION = VERSION,
22
40
  shared = jecs.tag(),
23
- networked = jecs.component() :: jecs.Entity<(MemberFilter | Player)?>,
24
- reliable = jecs.component() :: jecs.Entity<(MemberFilter | Player)?>,
25
- unreliable = jecs.component() :: jecs.Entity<(MemberFilter | Player)?>,
26
- pair = jecs.component() :: jecs.Entity<(MemberFilter | Player)?>,
27
-
28
- serdes = jecs.component() :: jecs.Entity<common.Serdes>,
29
- bytespan = jecs.component() :: jecs.Entity<number>,
30
- custom = jecs.tag() :: jecs.Entity,
31
- custom_handler = jecs.component() :: jecs.Entity<(any) -> jecs.Entity>,
32
- global = jecs.component() :: jecs.Entity<number>,
41
+ networked = jecs.component(),
42
+ reliable = jecs.component(),
43
+ unreliable = jecs.component(),
44
+ pair = jecs.component(),
45
+
46
+ serdes = jecs.component(),
47
+ custom = jecs.tag(),
48
+ custom_handler = jecs.component(),
49
+ global = jecs.component(),
33
50
  __alive_tracking__ = jecs.tag(),
34
51
  }
35
52
 
36
53
  replecs.__index = replecs
37
54
  replecs.Serdes = replecs.serdes
38
- replecs.Bytespan = replecs.bytespan
39
55
  replecs.Custom = replecs.custom
40
56
  replecs.CustomHandler = replecs.custom_handler
41
57
  replecs.Networked = replecs.networked
@@ -46,7 +62,6 @@ replecs.Shared = replecs.shared
46
62
  replecs.Global = replecs.global
47
63
 
48
64
  jecs.meta(replecs.serdes, jecs.Name, "replecs.serdes")
49
- jecs.meta(replecs.bytespan, jecs.Name, "replecs.bytespan")
50
65
  jecs.meta(replecs.custom, jecs.Name, "replecs.custom")
51
66
  jecs.meta(replecs.custom_handler, jecs.Name, "replecs.custom_handler")
52
67
  jecs.meta(replecs.networked, jecs.Name, "replecs.networked")
@@ -62,11 +77,11 @@ jecs.meta(replecs.custom, jecs.Exclusive)
62
77
  jecs.meta(replecs.global, jecs.Exclusive)
63
78
 
64
79
  function replecs.create_server(world: jecs.World?): Server
65
- return server.create(world, replecs)
80
+ return server.create(world, replecs :: Replecs)
66
81
  end
67
82
 
68
83
  function replecs.create_client(world: jecs.World?): Client
69
- return client.create(world, replecs)
84
+ return client.create(world, replecs :: Replecs)
70
85
  end
71
86
 
72
87
  function replecs.create(world: jecs.World?): ReplecsLib
@@ -76,15 +91,19 @@ function replecs.create(world: jecs.World?): ReplecsLib
76
91
  local lib = {} :: ReplecsLib
77
92
 
78
93
  if RunService:IsServer() then
79
- lib.server = server.create(world, replecs)
94
+ lib.server = server.create(world, replecs :: Replecs)
80
95
  end
81
96
  if RunService:IsClient() then
82
- lib.client = client.create(world, replecs)
97
+ lib.client = client.create(world, replecs :: Replecs)
83
98
  end
84
99
 
85
100
  return setmetatable(lib, replecs) :: any
86
101
  end
87
102
 
103
+ function replecs.create_custom_id(identifier: string, handler: (ctx: HandleContext) -> Entity?)
104
+ return customid.create(identifier, handler)
105
+ end
106
+
88
107
  function replecs.after_replication(lib: ReplecsLib, callback: () -> ())
89
108
  local lib_client = lib.client
90
109
  if lib_client then
@@ -94,4 +113,13 @@ function replecs.after_replication(lib: ReplecsLib, callback: () -> ())
94
113
  end
95
114
  end
96
115
 
97
- return replecs
116
+ function replecs.register_custom_id(lib: ReplecsLib, custom_id: CustomId)
117
+ if lib.server then
118
+ lib.server:register_custom_id(custom_id)
119
+ end
120
+ if lib.client then
121
+ lib.client:register_custom_id(custom_id)
122
+ end
123
+ end
124
+
125
+ return replecs :: Replecs
@@ -163,8 +163,8 @@ export type MaskingController = {
163
163
 
164
164
  propagate_entity_addition: (self: MaskingController, entity: Entity) -> (),
165
165
 
166
- start_entity: (self: MaskingController, entity: Entity, filter: MemberFilter?) -> (),
167
- set_entity: (self: MaskingController, entity: Entity, filter: MemberFilter?) -> (),
166
+ start_entity: (self: MaskingController, entity: Entity, filter: GivenFilter?) -> (),
167
+ set_entity: (self: MaskingController, entity: Entity, filter: GivenFilter?) -> (),
168
168
  stop_entity: (self: MaskingController, entity: Entity) -> (),
169
169
  cleanup_entity: (self: MaskingController, entity: Entity) -> (),
170
170
 
@@ -173,14 +173,14 @@ export type MaskingController = {
173
173
  entity: Entity,
174
174
  component: Entity,
175
175
  component_type: number,
176
- filter: MemberFilter?
176
+ filter: GivenFilter?
177
177
  ) -> (),
178
178
  set_component: (
179
179
  self: MaskingController,
180
180
  entity: Entity,
181
181
  component: Entity,
182
182
  component_type: number,
183
- filter: MemberFilter?
183
+ filter: GivenFilter?
184
184
  ) -> (),
185
185
  stop_component: (self: MaskingController, entity: Entity, component: Entity, component_type: number) -> (),
186
186
 
@@ -235,7 +235,7 @@ end
235
235
  local function get_usable_filter(filter: (MemberFilter | any)?): MemberFilter?
236
236
  if filter then
237
237
  if type(filter) == "table" then
238
- return filter
238
+ return filter :: MemberFilter
239
239
  else
240
240
  return { [filter] = true }
241
241
  end
@@ -709,23 +709,24 @@ function masking_controller.move_component_storage(
709
709
  local component_added =
710
710
  get_component_index_entry(storage.changes.added_components, entity, component, component_type)
711
711
  if component_added then
712
+ remove_component_index_entry(target_storage.changes.added_components, entity, component, component_type)
712
713
  set_component_index_entry(target_storage.changes.added_components, entity, component, component_type, true)
713
714
  end
714
715
 
715
716
  local changes = storage.changes.changed[entity]
716
717
  if changes then
717
718
  local target_changes = get_or_set_changed(target_storage, entity)
718
- if component_type == COMPONENT_TYPES.component then
719
- target_changes.component[component] = changes.component[component]
719
+ if component_type == COMPONENT_TYPES.tag then
720
+ target_changes.tagged[component] = changes.tagged[component]
720
721
  target_changes.removed[component] = changes.removed[component]
721
722
 
722
- changes.component[component] = nil
723
+ changes.tagged[component] = nil
723
724
  changes.removed[component] = nil
724
- elseif component_type == COMPONENT_TYPES.tag then
725
- target_changes.tagged[component] = changes.tagged[component]
725
+ elseif component_type == COMPONENT_TYPES.component then
726
+ target_changes.component[component] = changes.component[component]
726
727
  target_changes.removed[component] = changes.removed[component]
727
728
 
728
- changes.tagged[component] = nil
729
+ changes.component[component] = nil
729
730
  changes.removed[component] = nil
730
731
  elseif component_type == COMPONENT_TYPES.pair then
731
732
  target_changes.pairs[component] = changes.pairs[component]
@@ -742,8 +743,6 @@ function masking_controller.move_component_storage(
742
743
  end
743
744
  end
744
745
 
745
- --todo: move changes
746
-
747
746
  return target_storage
748
747
  end
749
748
 
@@ -826,7 +825,6 @@ function masking_controller.register_stop_entity(masking: MaskingInternal, entit
826
825
  return
827
826
  end
828
827
  storage.deletions.entities[entity] = true
829
- storage.deletions_count += 1
830
828
  end
831
829
 
832
830
  function masking_controller.register_stop_component(
@@ -845,13 +843,11 @@ function masking_controller.register_stop_component(
845
843
  deletions = create_component_indexes() :: ComponentIndex<boolean>
846
844
  deletions[component_type][component] = true
847
845
  storage.deletions.components[entity] = deletions
848
- storage.deletions_count += 1
849
846
  else
850
847
  if deletions[component_type][component] then
851
848
  return
852
849
  end
853
850
  deletions[component_type][component] = true
854
- storage.deletions_count += 1
855
851
  end
856
852
  end
857
853
 
@@ -896,7 +892,6 @@ function masking_controller.unregister_stop_component(
896
892
  if deletions then
897
893
  if deletions[component_type][component] then
898
894
  deletions[component_type][component] = nil
899
- storage.deletions_count -= 1
900
895
  end
901
896
  end
902
897
  end
@@ -1017,6 +1012,7 @@ function masking_controller.stop_entity(masking: MaskingInternal, entity: Entity
1017
1012
  component_storage.shared_with[entity] = nil
1018
1013
  component_storage.changes.added[entity] = nil
1019
1014
  component_storage.changes.changed[entity] = nil
1015
+ component_storage.changes.added_components[entity] = nil
1020
1016
 
1021
1017
  if postponed == nil then
1022
1018
  postponed = create_component_indexes() :: PostponedList
@@ -1039,6 +1035,7 @@ function masking_controller.stop_entity(masking: MaskingInternal, entity: Entity
1039
1035
  remove_active(lookup.storage_group, entity)
1040
1036
  lookup.storage_group.changes.added[entity] = nil
1041
1037
  lookup.storage_group.changes.changed[entity] = nil
1038
+ lookup.storage_group.changes.added_components[entity] = nil
1042
1039
 
1043
1040
  masking.lookups.entities[entity] = nil
1044
1041
  end
@@ -1344,7 +1341,18 @@ end
1344
1341
  local function bitmask_from_set(masking: MaskingInternal, member_set: { [Member]: boolean }): utils.Bitmask
1345
1342
  local new_bitmask = utils.bitmask.create(masking.member_count)
1346
1343
  for member: Member in member_set do
1347
- local index = masking.member_indexes[member] or masking.member_indexes[masking.client_aliases[member]]
1344
+ local index = masking.member_indexes[member]
1345
+ if not index then
1346
+ local alias = masking.member_indexes[masking.client_aliases[member]]
1347
+ if alias then
1348
+ if utils.is_client_valid(alias) then
1349
+ index = alias
1350
+ end
1351
+ elseif utils.is_client_valid(member) then
1352
+ masking_controller.register_client(masking, member)
1353
+ index = masking.member_indexes[member]
1354
+ end
1355
+ end
1348
1356
  if index then
1349
1357
  new_bitmask:set(index)
1350
1358
  end
@@ -1496,13 +1504,13 @@ function masking_controller.create_exclude_generator(masking: MaskingInternal, e
1496
1504
  local bitmask = bitmask_from_set(masking, exclude)
1497
1505
  local active_members = masking.active_members_generator
1498
1506
 
1499
- local generator = mask_generator.create(bitmask, function(generator)
1500
- local bitmask = generator.bitmask :: utils.Bitmask
1501
- return active_members.result:band(bitmask:bnot())
1507
+ local new_generator = mask_generator.create(bitmask, function(generator)
1508
+ local current = generator.bitmask :: utils.Bitmask
1509
+ return active_members.result:band(current:bnot())
1502
1510
  end)
1503
- generator:track(active_members)
1511
+ new_generator:track(active_members)
1504
1512
 
1505
- return generator
1513
+ return new_generator
1506
1514
  end
1507
1515
 
1508
1516
  -- TODO: check for players existing and register them if they don't
@@ -1510,13 +1518,13 @@ function masking_controller.create_include_generator(masking: MaskingInternal, i
1510
1518
  local bitmask = bitmask_from_set(masking, include)
1511
1519
  local active_members = masking.active_members_generator
1512
1520
 
1513
- local generator = mask_generator.create(bitmask, function(generator)
1514
- local bitmask = generator.bitmask :: utils.Bitmask
1515
- return bitmask:band(active_members.result)
1521
+ local new_generator = mask_generator.create(bitmask, function(generator)
1522
+ local current = generator.bitmask :: utils.Bitmask
1523
+ return current:band(active_members.result)
1516
1524
  end)
1517
- generator:track(active_members)
1525
+ new_generator:track(active_members)
1518
1526
 
1519
- return generator
1527
+ return new_generator
1520
1528
  end
1521
1529
 
1522
1530
  function masking_controller.create_all_members_generator(masking: MaskingInternal)
@@ -1544,9 +1552,9 @@ function masking_controller.create_active_generator(masking: MaskingController):
1544
1552
  return new_generator
1545
1553
  end
1546
1554
 
1547
- function masking_controller.register_mask_group(masking: MaskingInternal, group: Member) end
1555
+ --function masking_controller.register_mask_group(masking: MaskingInternal, group: Member) end
1548
1556
 
1549
- function masking_controller.unregister_mask_group(masking: MaskingInternal, group: Member) end
1557
+ --function masking_controller.unregister_mask_group(masking: MaskingInternal, group: Member) end
1550
1558
 
1551
1559
  function masking_controller.register_client(masking: MaskingInternal, member: Member)
1552
1560
  if masking.member_indexes[member] then
@@ -1575,16 +1583,12 @@ function masking_controller.unregister_client(masking: MaskingInternal, member:
1575
1583
  end
1576
1584
  masking.client_indexes[member] = nil
1577
1585
  masking.member_indexes[member] = nil
1578
- masking.member_count -= 1
1579
1586
  masking.all_members_generator.bitmask:clear(index)
1580
1587
  masking.active_members_generator:compute()
1581
1588
  end
1582
1589
 
1583
1590
  function masking_controller.activate_client(masking: MaskingInternal, member: Member)
1584
1591
  local index = masking.client_indexes[member]
1585
- if index == nil then
1586
- index = masking.client_indexes[member]
1587
- end
1588
1592
 
1589
1593
  masking.unreplicated[member] = nil
1590
1594
  masking.unactive_members_generator.bitmask:clear(index)
@@ -63,7 +63,7 @@ end
63
63
 
64
64
  function mask_generator.compute(generator: GeneratorInternal)
65
65
  if generator.compute_callback then
66
- local result = generator.compute_callback(generator :: GeneratorInternal)
66
+ local result: utils.Bitmask = generator.compute_callback(generator :: any)
67
67
  generator.result = result
68
68
  end
69
69
  if generator.subscribed then