Enhance the OECS framework to support more robust component
deserialization during world serialization. This includes adding
boxed component support and a runtime fallback for component
discovery.
Additionally, introduces snapshot testing patterns for Blackjack
and TicTacToe to allow for manual verification of world state and
reactivity logs.
- Add xUnit test projects for both games
- Implement game flow tests for Blackjack
- Implement game flow tests for TicTacToe
- Rename namespaces and projects to follow `Game.*` convention
- Add documentation for testing games
- Move examples (Blackjack, TicTacToe) to the root directory
- Convert example projects from Console applications to Libraries
- Add Directory.Build.props for shared build settings
- Update solution file and project references to reflect new paths
Introduce an incremental source generator that automatically discovers
component types used with the World API. This allows the
WorldSerializer to perform serialization and deserialization without
relying on reflection, improving performance and stability.
Remove the mandatory Query property from the ISystem interface,
allowing systems to manage their own queries locally or via other
means. Update all implementing systems and tests to use local
query descriptors instead.
Add `where TSelf : struct where TTarget : struct` constraints to
the `Relationship` struct to ensure type safety and consistency with
the ECS architecture. Also remove unused `IterateThree` method in
`QueryExecutor`.
- Optimize `QueryExecutor` to use the smallest sparse set as a driver
for multi-component queries, reducing iteration overhead.
- Implement automatic cleanup of unused `Subject` instances in
`ChangeBuffer` using a subscriber count.
- Improve `ChangeSet` deduplication to correctly handle rapid
add/remove transitions for the same component.
- Add validation to ensure `IRelationship` components are added to
their declared `Source` entity.
- Update documentation to reflect correct `Entity` bit layout.
- Optimize Select2 and Select3 iterators to drive from the smallest
sparse set to minimize probes.
- Use a constrained generic in CommandQueue.Enqueue to avoid boxing
struct commands at the call site.
- Ensure singleton infrastructure is initialized during world
deserialization if the singleton entity is loaded.
- Change EnsureSingleton to internal.
Implement deferred structural mutations (AddComponent, RemoveComponent,
DestroyEntity) to allow safe modification of the world during
iteration.
Additionally, introduce a new `EntityIterator` API providing zero-
allocation `ref struct` iterators (`Select<T1>`, `Select<T1, T2>`, etc.)
to support manual iteration with early-exit capabilities.
As part of these changes, component access via `GetComponent<T>` during
iteration now automatically marks components as modified.
- Add serialization support to `World`, `EntityAllocator`, and
`SparseSet`
- Implement `SaveGame` and `LoadGame` functionality in the TicTacToe
example
- Add ability to resume a game from a saved state
- Implement auto-save after every move in the game loop
Implement a complete Tic-Tac-Toe game using OECS to demonstrate
ECS patterns, including:
- Command pattern for placing marks
- System groups for logical updates and rendering
- CSV loading for initial board state
- Reactivity logging for observing entity and component changes
fix: notify change buffer when removing components in World
docs: add caution about structural changes during ForEach
fix: prevent multiple disposals in World
- Implement `TryGetComponent<T>` in `World` and `SparseSet<T>`
- Add validation to ensure `ForEach` type parameters match the
`QueryDescriptor`
- Improve error handling in `SparseSet<T>.Get` to throw
`InvalidOperationException`
- Use `GUID` instead of `FullName` for `QueryDescriptor` hash stability
- Fix SparseSet resize logic to correctly initialize new slots
- Implement Equals and GetHashCode for QueryDescriptor
- Prevent collection modification exceptions in World.DestroyEntity
- Update CommandQueue to accumulate errors across drain cycles
- Add comprehensive edge case tests in EdgeCaseTests.cs
Introduces a mechanism to store and access singleton components on a
reserved entity. The singleton entity is automatically excluded from
all standard queries to prevent it from being processed like regular
entities.
- Added `SetSingleton`, `GetSingleton`, `HasSingleton`, and
`RemoveSingleton` to `World`.
- Added `RegisterSingleton` to `EntityAllocator` to support the
reserved entity.
- Updated `QueryExecutor` to skip the singleton entity during
iteration.
- Added unit tests for singleton functionality.
Introduces a relationship system to allow entities to point to other
entities. Includes a `Relationship<TSelf, TTarget>` component and a
`RelationshipIndex` to enable efficient reverse lookups (finding all
sources pointing to a specific target).
The `World.DestroyEntity` method now performs cascading removals:
- Relationships where the entity is the source are removed.
- Relationships where the entity is the target are removed from their
respective source entities.
Also adds MessagePack support to `Entity` and `Relationship`.
Introduces a complete query system for iterating over entities with
specific component combinations, including support for "with" and
"without" filters.
Also adds:
- `ISystem` and `ITickedSystem` interfaces for defining logic.
- `SystemGroup` for managing and running groups of systems.
- `QueryBuilder` for a fluent API to construct queries.
- `QueryExecutor` for high-performance iteration using ref parameters.
- `Tick` and `TickType` to support timed and logical updates.
- Update design.md with MessagePack component requirements
- Add ADR-012 to architecture.md regarding public type requirements
- Add MessagePackAnalyzer to OECS.csproj for compile-time validation
Initializes the OECS repository with the core foundation, including:
- Entity management with 24-bit IDs and 8-bit versioning
- Sparse set-based component storage
- Entity allocation and recycling logic
- Core World API for entity and component lifecycle
- Project scaffolding for source and unit tests
- Design documentation and architecture decision records (ADRs)