🚀 Benchmarks 🚀
⚙️ Unity module ⚙️
❗️ Guide for migrating from version 1.0.x to 1.2.x ❗️
Static ECS - C# Binary Entity component system framework
- Lightweight
- Performance
- No allocations
- No Unsafe
- Based on statics and structures
- Type-safe
- Free abstractions
- Powerful query engine
- No boilerplate
- Compatibility with Unity with support for Il2Cpp and Burst
- Compatibility with other C# engines
- Compatible with Native AOT
Table of Contents
Contacts
Installation
The library has a dependency on StaticPack 1.0.6 for binary serialization, StaticPack must also be installed
-
As source code
From the release page or as an archive from the branch. In the
masterbranch there is a stable tested version -
Installation for Unity
- How to git module in Unity PackageManager
https://github.com/Felid-Force-Studios/StaticEcs.git
https://github.com/Felid-Force-Studios/StaticPack.git - Or adding to the manifest
Packages/manifest.json
"com.felid-force-studios.static-ecs": "https://github.com/Felid-Force-Studios/StaticEcs.git"
"com.felid-force-studios.static-pack": "https://github.com/Felid-Force-Studios/StaticPack.git"
- How to git module in Unity PackageManager
Concept
StaticEcs - a new ECS architecture based on an inverted hierarchical bitmap model. Unlike traditional ECS frameworks that rely on archetypes or sparse sets, this design introduces an inverted index structure where each component owns an entity bitmap instead of entities storing component masks. A hierarchical aggregation of these bitmaps provides logarithmic-space indexing of entity blocks, enabling O(1) block filtering and efficient parallel iteration through bitwise operations. This approach completely removes archetype migration and sparse-set indirection, offering direct SoA-style memory access across millions of entities with minimal cache misses. The model achieves up to 64× fewer memory lookups per block and scales linearly with the number of active component sets, making it ideal for large-scale simulations, reactive AI, and open-world environments.
- The main idea of this implementation is static, all data about the world and components are in static classes, which makes it possible to avoid expensive virtual calls and have a convenient API
- This framework is focused on maximum ease of use, speed and comfort of code writing without loss of performance
- Multi-world creation, strict typing, ~zero-cost abstractions
- Serialization system
- System of entity relations
- Multithreaded processing
- Low memory usage
- Based on Bitmap architecture, no archetypes, no sparse-sets
- The framework was created for the needs of a private project and put out in open-source.
Quick start
using FFS.Libraries.StaticEcs;
// Define the world type
public struct WT : IWorldType { }
public abstract class W : World<WT> { }
// Define the systems type
public struct SystemsType : ISystemsType { }
// Define type-alias for easy access to systems
public abstract class Systems : W.Systems<SystemsType> { }
// Define components
public struct Position : IComponent { public Vector3 Value; }
public struct Direction : IComponent { public Vector3 Value; }
public struct Velocity : IComponent { public float Value; }
// Define systems
public readonly struct VelocitySystem : IUpdateSystem {
public void Update() {
foreach (var entity in W.Query.Entities<All<Position, Velocity, Direction>>()) {
entity.Ref<Position>().Value += entity.Ref<Direction>().Value * entity.Ref<Velocity>().Value;
}
// Or
W.Query.For((ref Position pos, ref Velocity vel, ref Direction dir) => {
pos.Value += dir.Value * vel.Value;
});
}
}
public class Program {
public static void Main() {
// Creating world data
W.Create(WorldConfig.Default());
// Registering components
W.RegisterComponentType<Position>();
W.RegisterComponentType<Direction>();
W.RegisterComponentType<Velocity>();
// Initializing the world
W.Initialize();
// Creating systems
Systems.Create();
Systems.AddUpdate(new VelocitySystem());
// Initializing systems
Systems.Initialize();
// Creating entity
var entity = W.Entity.New(
new Velocity { Value = 1f },
new Position { Value = Vector3.Zero },
new Direction { Value = Vector3.UnitX }
);
// Update all systems - called in every frame
Systems.Update();
// Destroying systems
Systems.Destroy();
// Destroying the world and deleting all data
W.Destroy();
}
}