1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//! Core ECS Types, Identifiers, and Bit-Level Layouts
//!
//! This module defines the **fundamental types, identifiers, and bit layouts
//! used throughout the ECS engine. These definitions form the
//! *semantic backbone* of the system and are shared across all subsystems,
//! including entity management, archetypes, queries, scheduling, and systems.
//!
//! ## Design Philosophy
//!
//! The ECS is designed around **Dense storage**
//!
//! To support this goal efficiently, this module:
//!
//! - Encodes entities into a single 64-bit value,
//! - Represents component sets as fixed-size bit arrays,
//! - Uses small, copyable numeric IDs for all ECS concepts.
//!
//! ## Entity Representation
//!
//! Entities are encoded as a packed 64-bit integer with the following layout:
//!
//! ```text
//! | version | shard | index |
//! ```
//!
//! - **Index** identifies the slot within a shard.
//! - **Shard** allows scalable partitioning for allocation and concurrency.
//! - **Version** enables stale-entity detection after despawning.
//!
//! The exact bit widths are controlled by compile-time constants and validated
//! using static assertions.
//!
//! ## Archetypes and Components
//!
//! Components are identified by compact [`ComponentID`] values. Archetypes are
//! described by [`Signature`] bitsets indicating which components they contain.
//!
//! Component signatures:
//!
//! - are fixed-size arrays of `u64`,
//! - support fast bitwise comparison,
//! - allow efficient iteration over set bits,
//! - are used for both archetype identity and query matching.
//!
//! ## Safety and Performance
//!
//! This module contains **no unsafe code**, but many of its types are used at
//! unsafe boundaries elsewhere in the engine.
//!
//! All constants, bit widths, and capacities are chosen to:
//!
//! - fit within cache-friendly data structures,
//! - allow fast bitwise operations,
//! - minimise memory overhead,
//! - support large-scale simulations.
/// Bit-width type used for compile-time layout calculations.
pub type Bits = u8;
/// Globally unique entity identifier encoded as a packed 64-bit value.
pub type EntityID = u64;
/// Identifier for an entity allocation shard.
pub type ShardID = u16;
/// Index within a shard.
pub type IndexID = u32;
/// Generation counter used to detect stale entities.
pub type VersionID = u32;
/// Count of live entities.
pub type EntityCount = u32;
/// Unique identifier for a system.
pub type SystemID = u16;
/// Total number of bits in an [`EntityID`].
pub const ENTITY_BITS: Bits = 64;
/// Number of bits reserved for shard identification.
pub const SHARD_BITS: Bits = 10;
/// Number of bits reserved for entity versioning.
pub const VERSION_BITS: Bits = 32;
/// Number of bits reserved for entity index within a shard.
pub const INDEX_BITS: Bits = ENTITY_BITS - SHARD_BITS - VERSION_BITS;
const _: = ;
const _: = ;
const _: = ;
const _: = ;
const
/// Mask selecting the index portion of an [`EntityID`].
pub const INDEX_MASK: EntityID = mask;
/// Mask selecting the shard portion of an [`EntityID`].
pub const SHARD_MASK: EntityID = mask;
/// Maximum number of indices per shard.
pub const INDEX_CAP: IndexID = INDEX_MASK as IndexID;
/// Unique identifier for an archetype.
pub type ArchetypeID = u16;
/// Row index within a chunk.
pub type RowID = u32;
/// Chunk index within an archetype.
pub type ChunkID = u16;
/// Maximum number of rows per chunk.
///
/// Chunks are sized in **rows, not bytes**: a chunk of a 4-byte component
/// occupies 64 KiB while a chunk of a 64-byte component occupies 1 MiB. This
/// keeps every column of an archetype row-aligned at the same `(chunk, row)`
/// coordinates, at the cost of per-chunk memory footprint scaling with
/// component size. Byte-targeted chunk sizing was considered and rejected:
/// row-splitting during parallel iteration already decouples task granularity
/// from chunk size, which was the main argument for byte-sized chunks.
pub const CHUNK_CAP: usize = 16_384;
/// Unique identifier for a component type.
pub type ComponentID = u16;
/// Compact identifier for an agent template registered in an agent registry.
;
/// Maximum number of registered component types.
///
/// This value controls the size of [`Signature`] bitsets: each 256-component
/// capacity requires 4 `u64` words (32 bytes) per signature. If a simulation
/// requires more than 256 distinct component types, this constant can be
/// increased in multiples of 64. Each additional 64 components adds one `u64`
/// word (8 bytes) to every signature, so increases should be made deliberately.
pub const COMPONENT_CAP: usize = 256;
/// Number of `u64` words required to represent a full component signature.
pub const SIGNATURE_SIZE: usize = COMPONENT_CAP.div_ceil;
/// Opaque identifier for a non-component scheduling channel.
///
/// Channels are allocated by extension modules (messaging, environment) and
/// recorded in `AccessSets::produces` / `AccessSets::consumes`. The engine
/// treats them as opaque bitset indices; it does not interpret their meaning.
///
/// Assigned by [`ChannelAllocator`](crate::engine::channel_allocator::ChannelAllocator).
/// One allocator exists per `Model`, shared by messaging and environment so
/// both live in the same `u32` ID space and the scheduler can reason about
/// them uniformly.
pub type ChannelID = u32;
/// Opaque identifier for a boundary resource registered on
/// [`ECSManager`](crate::engine::manager::ECSManager).
///
/// Returned by `ECSManager::register_boundary` and used by systems to retrieve
/// a typed reference to the resource via `ECSReference::boundary::<R>(id)`.
pub type BoundaryID = u32;
/// Unique identifier for a GPU resource.
pub type GPUResourceID = u16;
/// Declares how a component buffer is accessed during GPU execution.