@@ -33,7 +33,7 @@ extends RefCounted
3333## Generated by QueryCacheKey.build() from sorted component types
3434var signature : int = 0
3535
36- ## Sorted array of component resource paths (e.g., ["res://c_position.gd", "res ://c_velocity.gd"] )
36+ ## Array of component/relationship keys (ints for components, Strings for rel :// keys )
3737## Used for debugging and archetype matching logic
3838var component_types : Array = []
3939
@@ -54,15 +54,14 @@ var entity_to_index: Dictionary = {} # Entity -> int
5454var enabled_bitset : PackedInt64Array = []
5555
5656## OPTIMIZATION: Structure of Arrays (SoA) column storage for cache-friendly iteration
57- ## Maps component_path -> Array of component instances
57+ ## Maps script_instance_id (int) -> Array of component instances
5858## Enables Flecs-style direct array iteration without dictionary lookups
59- ## Example: columns["res://c_velocity.gd"] = [vel1, vel2, vel3, ...]
60- var columns : Dictionary = {} # String (component_path) -> Array of components
59+ var columns : Dictionary = {} # int (script_instance_id) -> Array of components
6160
62- ## Archetype edges for fast component add/remove (future optimization)
63- ## Maps: component_path -> Archetype (the archetype you get by adding/removing that component)
64- var add_edges : Dictionary = {} # String -> Archetype
65- var remove_edges : Dictionary = {} # String -> Archetype
61+ ## Archetype edges for fast component add/remove
62+ ## Maps: Variant (int for components, String for relationships) -> Archetype
63+ var add_edges : Dictionary = {} # Variant (int| String) -> Archetype
64+ var remove_edges : Dictionary = {} # Variant (int| String) -> Archetype
6665
6766## Reverse-edge tracking: which archetypes hold an add_edge or remove_edge pointing to this one.
6867## Keyed by source archetype instance_id for O(1) operations.
@@ -75,12 +74,12 @@ func _init(p_signature: int, p_component_types: Array):
7574 component_types = p_component_types .duplicate ()
7675 component_types .sort () # Ensure sorted for consistent matching
7776
78- # Separate relationship slot keys from component paths
77+ # Separate relationship slot keys (Strings) from component keys (ints)
7978 for comp_type in component_types :
80- if ( comp_type as String ) .begins_with ("rel://" ):
79+ if comp_type is String and comp_type .begins_with ("rel://" ):
8180 relationship_types .append (comp_type )
8281 else :
83- # Only create columns for component paths , NOT relationship slots
82+ # Only create columns for component keys , NOT relationship slots
8483 columns [comp_type ] = []
8584
8685
@@ -98,14 +97,14 @@ func add_entity(entity: Entity) -> void:
9897
9998 # OPTIMIZATION: Populate column arrays from entity.components
10099 # Iterate columns keys (skips rel:// keys which have no columns)
101- for comp_path in columns :
102- if entity .components .has (comp_path ):
103- (columns [comp_path ]
104- .append (entity .components [comp_path ]))
100+ for comp_key in columns :
101+ if entity .components .has (comp_key ):
102+ (columns [comp_key ]
103+ .append (entity .components [comp_key ]))
105104 else :
106105 # Entity doesn't have this component yet (might be mid-initialization)
107106 # Push null placeholder, will be fixed when component is added
108- columns [comp_path ].append (null )
107+ columns [comp_key ].append (null )
109108
110109
111110## Remove an entity from this archetype using swap-remove
@@ -125,8 +124,8 @@ func remove_entity(entity: Entity) -> bool:
125124 entity_to_index [last_entity ] = index
126125
127126 # OPTIMIZATION: Swap in column arrays too (maintain same ordering)
128- for comp_path in columns :
129- columns [comp_path ][index ] = columns [comp_path ][last_index ]
127+ for comp_key in columns :
128+ columns [comp_key ][index ] = columns [comp_key ][last_index ]
130129
131130 # OPTIMIZATION: Swap enabled bit
132131 var last_enabled = _get_enabled_bit (last_index )
@@ -137,8 +136,8 @@ func remove_entity(entity: Entity) -> bool:
137136 entity_to_index .erase (entity )
138137
139138 # OPTIMIZATION: Remove last element from all columns
140- for comp_path in columns :
141- columns [comp_path ].pop_back ()
139+ for comp_key in columns :
140+ columns [comp_key ].pop_back ()
142141
143142 # OPTIMIZATION: Update bitset size (no need to clear the bit, just reduce logical size)
144143 # The bit will be overwritten when a new entity is added
@@ -167,8 +166,8 @@ func clear() -> void:
167166 entity_to_index .clear ()
168167
169168 # OPTIMIZATION: Clear column arrays
170- for comp_path in columns :
171- columns [comp_path ].clear ()
169+ for comp_key in columns :
170+ columns [comp_key ].clear ()
172171
173172 # OPTIMIZATION: Clear bitset
174173 enabled_bitset .clear ()
@@ -234,10 +233,13 @@ func matches_relationship_query(required_rel_keys: Array, excluded_rel_keys: Arr
234233func _to_string () -> String :
235234 var comp_names = []
236235 for comp_type in component_types :
237- # Extract just the class name from the path
238- var parts = comp_type .split ("/" )
239- var filename = parts [parts .size () - 1 ].replace (".gd" , "" )
240- comp_names .append (filename )
236+ if comp_type is String :
237+ # Relationship slot key — extract readable name from path
238+ var parts = comp_type .split ("/" )
239+ var filename = parts [parts .size () - 1 ].replace (".gd" , "" )
240+ comp_names .append (filename )
241+ else :
242+ comp_names .append (str (comp_type ))
241243
242244 return "Archetype[sig=%d , comps=%s , entities=%d ]" % [
243245 signature ,
@@ -248,43 +250,43 @@ func _to_string() -> String:
248250
249251## Set up an edge to another archetype when a component is added
250252## Enables O(1) archetype transitions when components change
251- func set_add_edge (component_path : String , target_archetype : Archetype ) -> void :
252- add_edges [component_path ] = target_archetype
253+ func set_add_edge (comp_key : Variant , target_archetype : Archetype ) -> void :
254+ add_edges [comp_key ] = target_archetype
253255 target_archetype .neighbors [get_instance_id ()] = self
254256
255257
256258## Set up an edge to another archetype when a component is removed
257259## Enables O(1) archetype transitions when components change
258- func set_remove_edge (component_path : String , target_archetype : Archetype ) -> void :
259- remove_edges [component_path ] = target_archetype
260+ func set_remove_edge (comp_key : Variant , target_archetype : Archetype ) -> void :
261+ remove_edges [comp_key ] = target_archetype
260262 target_archetype .neighbors [get_instance_id ()] = self
261263
262264
263265## Get the target archetype when adding a component (if edge exists)
264- func get_add_edge (component_path : String ) -> Archetype :
265- return add_edges .get (component_path , null )
266+ func get_add_edge (comp_key : Variant ) -> Archetype :
267+ return add_edges .get (comp_key , null )
266268
267269
268270## Get the target archetype when removing a component (if edge exists)
269- func get_remove_edge (component_path : String ) -> Archetype :
270- return remove_edges .get (component_path , null )
271+ func get_remove_edge (comp_key : Variant ) -> Archetype :
272+ return remove_edges .get (comp_key , null )
271273
272274
273275## OPTIMIZATION: Get component column array for cache-friendly iteration
274276## Enables Flecs-style direct array access instead of dictionary lookups per entity
275- ## [param component_path ] The resource path of the component type (e.g., C_Velocity.resource_path )
277+ ## [param comp_key ] The component key (Script.get_instance_id()) or relationship slot key (String )
276278## [returns] Array of component instances in entity index order, or empty array if not found
277279##
278280## Example:
279281## [codeblock]
280- ## var velocities = archetype.get_column(C_Velocity.resource_path )
282+ ## var velocities = archetype.get_column(C_Velocity.get_instance_id() )
281283## for i in range(velocities.size()):
282284## var velocity = velocities[i]
283285## var entity = archetype.entities[i]
284286## # Process with cache-friendly sequential access
285287## [/codeblock]
286- func get_column (component_path : String ) -> Array :
287- return columns .get (component_path , [])
288+ func get_column (comp_key : Variant ) -> Array :
289+ return columns .get (comp_key , [])
288290
289291
290292## OPTIMIZATION: Get entities filtered by enabled state using bitset
0 commit comments