Overlook.Pool
1.0.0
dotnet add package Overlook.Pool --version 1.0.0
NuGet\Install-Package Overlook.Pool -Version 1.0.0
<PackageReference Include="Overlook.Pool" Version="1.0.0" />
<PackageVersion Include="Overlook.Pool" Version="1.0.0" />
<PackageReference Include="Overlook.Pool" />
paket add Overlook.Pool --version 1.0.0
#r "nuget: Overlook.Pool, 1.0.0"
#:package Overlook.Pool@1.0.0
#addin nuget:?package=Overlook.Pool&version=1.0.0
#tool nuget:?package=Overlook.Pool&version=1.0.0
Overlook ECS
Overlook ECS is a high-performance Entity Component System (ECS) designed for the Overlook Game Framework, built with C# and optimized for Unity development workflows.
Overview
Entity Component System (ECS) is an architectural pattern that emphasizes data-oriented design by separating data (Components) from identity (Entities) and behavior (Systems). This approach promotes:
- Improved Performance: By organizing data in a way that's cache-friendly (often through archetypes).
- Enhanced Code Reusability: Components and systems can be more modular and independent.
- Better Data Organization: Clear separation of concerns makes complex game states easier to manage.
Overlook.Ecs provides a robust implementation of these core principles.
Core Concepts in Overlook.Ecs
World: The central container and manager for all ECS data. It holds entities, archetypes, and provides the primary API for interacting with the ECS (e.g., spawning entities, creating queries).- Each
Worldis an isolated ECS environment.
- Each
Entity: A lightweightstructthat uniquely identifies a game object or logical element. It's essentially an ID (Identity) that groups a set of components.Entity.NoneandEntity.Anyare special static values.
- Component: Data structures (primarily
structfor unmanaged components, butclassfor object components) that define the attributes or state of an entity. Examples:Position,Velocity,Health.- Unmanaged Components:
structcomponents offer high performance due to direct memory layout within archetypes. - Object Components:
classcomponents allow for reference types and more complex behaviors, managed separately but still associated with entities. - Tagged Components (
ITaggedComponent): A specialized mechanism for associating components with a "tag" type, allowing for more nuanced component relationships and querying (e.g., anEquipmentcomponent tagged with anEquippedByPlayertag).
- Unmanaged Components:
Archetypes: An internal system that manages the unique combinations of component types. Entities with the exact same set of components belong to the same archetype. This is crucial for:- Efficient Storage: Components of the same type within an archetype are often stored contiguously in memory (
Table,TableStorage). - Fast Querying: Queries can quickly identify matching archetypes and then iterate over their entities.
- Efficient Storage: Components of the same type within an archetype are often stored contiguously in memory (
StorageType: Represents the type of a component, used internally for managing storage and type information.
Key Features
- High-Performance Design:
- Archetype-based component storage for cache efficiency.
- Focus on
unmanaged(struct) components for performance-critical data. - Object pooling (
Overlook.Pool) is used internally (e.g., inEntityBuilderandArchetypes) to reduce allocations. - Uses
Mask(orNativeBitArrayMaskifOVERLOOK_ECS_USE_UNITY_COLLECTIONis defined) for efficient component type matching in queries.
- Flexible Entity Management:
world.Spawn(): Creates a new entity.world.Despawn(entity): Destroys an entity and its components.- Component Addition:
world.AddComponent<T>(entity, data)for unmanaged,world.AddObjectComponent<T>(entity, data)for managed. - Component Removal:
world.RemoveComponent<T>(entity),world.RemoveObjectComponent<T>(entity). - Component Access:
world.GetComponent<T>(entity)(ref return for unmanaged),world.GetObjectComponent<T>(entity). - Checking for components:
world.HasComponent<T>(entity).
- Powerful Querying System:
QueryBuilder: Fluent API to define which components an entity must have (Has<T>), must not have (Not<T>), or could have (Any<T>).query.Build(world): Constructs aQueryobject.- Iterate over query results:
foreach (var queryEntity in query) { ... }. QueryEntity: Provides access to theEntityand its components within a query loop (e.g.,queryEntity.Get<Position>()).WhereQuery: Allows for additional filtering on query results using predicates.
- Entity Construction with
EntityBuilder:- While
Worldprovides direct methods,EntityBuilder(and its extensionsValueComponentBuilder,ObjectComponentBuilder) offers a composable, fluent way to define an entity's components before instantiation. EntityBuilder.Create().Add(new Position { ... }).Add(new Velocity { ... }).Build(world);
- While
- Component Grouping (
ComponentGroupAttribute):- An assembly-level attribute to define logical groupings of component types. This can be used for editor tooling or framework-level conventions.
- Tagged Components (
TaggedComponentextensions):- Provides a way to create and query components that are "tagged" by another type, offering a form of component relationship or categorization.
- Example:
world.AddTaggedComponent(entity, myRenderer, typeof(PlayerViewTag));
Basic Usage Examples
using Overlook.Ecs;
// Define your components
public struct Position // Assuming IComponentData or similar if you have one
{
public float X, Y, Z;
}
public struct Velocity
{
public float DX, DY, DZ;
}
public class EnemyAI // Example of a class component
{
public float AggroRadius;
}
public struct IsPlayerTag { } // A simple unmanaged tag component
public class GameController
{
private World _world;
public void Initialize()
{
_world = new World();
// === Entity Creation ===
// Method 1: Direct with World API
Entity playerEntity = _world.Spawn();
_world.AddComponent(playerEntity, new Position { X = 0, Y = 1, Z = 0 });
_world.AddComponent(playerEntity, new Velocity { DX = 1, DY = 0, DZ = 0 });
_world.AddComponent<IsPlayerTag>(playerEntity); // Adding a tag
Entity enemyEntity = _world.Spawn();
_world.AddComponent(enemyEntity, new Position { X = 10, Y = 1, Z = 5 });
_world.AddObjectComponent(enemyEntity, new EnemyAI { AggroRadius = 15f });
// Method 2: Using EntityBuilder (conceptual, actual API from EntityBuilderExtensions)
// Note: The direct EntityBuilder methods like Add<T>() are part of extensions.
// The following is a more realistic use of how builders are chained.
var builder = Overlook.Ecs.EntityBuilder.Create()
.Add(new Position { X = 5, Y = 0, Z = 5 })
.Add(new Velocity { DX = 0, DY = 0, DZ = -1 });
Entity anotherEntity = builder.Build(_world);
// === Querying Entities ===
// Query for all entities with Position and Velocity
var moveableEntitiesQuery = QueryBuilder.Create()
.Has<Position>()
.Has<Velocity>()
.Build(_world);
Console.WriteLine("Moveable Entities:");
foreach (var queryEntity in moveableEntitiesQuery) // queryEntity is of type QueryEntity
{
ref var pos = ref queryEntity.Get<Position>(); // Get by ref for structs
ref readonly var vel = ref queryEntity.Get<Velocity>(); // Can also get as readonly ref
Console.WriteLine($" Entity {queryEntity.Entity.Identity} at ({pos.X}, {pos.Y}, {pos.Z}) moving at ({vel.DX}, {vel.DY}, {vel.DZ})");
// Modify component data directly
pos.X += vel.DX * 0.1f; // Example: simple movement update
}
// Query for entities with the IsPlayerTag
var playerQuery = QueryBuilder.Create().Has<IsPlayerTag>().Build(_world);
foreach (var queryEntity in playerQuery)
{
if (_world.HasComponent<Position>(queryEntity.Entity)) // Check for other components
{
ref var playerPos = ref _world.GetComponent<Position>(queryEntity.Entity);
Console.WriteLine($"Player {queryEntity.Entity.Identity} is at: ({playerPos.X}, {playerPos.Y}, {playerPos.Z})");
}
}
// === Accessing/Modifying Components ===
if (_world.IsAlive(playerEntity) && _world.HasComponent<Velocity>(playerEntity))
{
ref var playerVel = ref _world.GetComponent<Velocity>(playerEntity);
playerVel.DX = 5f; // Change player velocity
Console.WriteLine($"Updated player velocity X to {playerVel.DX}");
}
// === Despawning ===
_world.Despawn(enemyEntity);
Console.WriteLine($"Enemy {enemyEntity.Identity} despawned. IsAlive: {_world.IsAlive(enemyEntity)}");
}
public void Shutdown()
{
_world?.Dispose(); // Important to dispose the world to clean up resources
}
}
Systems (Behavior)
Overlook.Ecs primarily provides the data container and manipulation APIs. The actual game logic (behavior) is typically implemented in Systems. Systems are classes or methods that:
- Query the
Worldfor entities with specific combinations of components. - Iterate over these entities and update their components or perform other game logic.
This package focuses on the ECS core; you would build your systems on top of it.
Further Considerations
- Integration with Unity: While a general-purpose C# ECS, its design choices (like
NativeBitArrayMaskoption) suggest an orientation towards Unity's performance-sensitive environment. Consider how this integrates with Unity's Job System and Burst Compiler for maximal performance if applicable. - Error Handling and Debugging: The codebase includes
Debug.Assertand conditional debug messages (OVERLOOK_ECS_DEBUG), which are helpful during development.
This README provides a foundational understanding of Overlook.Ecs. For more in-depth knowledge, refer to the source code and specific API documentation within the package.
Acknowledgments
- modified from RelEcs
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- JetBrains.Annotations (>= 2024.3.0)
- Overlook.Core (>= 1.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Overlook.Pool:
| Package | Downloads |
|---|---|
|
Overlook.Ecs
Overlook ECS |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 261 | 5/9/2025 |