# gaemstone.ECS .. is a medium-level managed wrapper library around the [flecs-cs] bindings for the amazing [Entity Component System (ECS)][ECS] framework [Flecs]. It is used as part of the [gæmstone] game engine, but may be used in other projects as well. To efficiently use this library, a thorough understanding of [Flecs] is required. [ECS]: https://en.wikipedia.org/wiki/Entity_component_system [Flecs]: https://github.com/SanderMertens/flecs [flecs-cs]: https://github.com/flecs-hub/flecs-cs [gæmstone]: https://git.mcft.net/copygirl/gaemstone ## Features These classes have only recently been split from the main **gæmstone** project. It is currently unclear what functionality belongs where, and structural changes are still very likely. In its current state, feel free to use **gæmstone.ECS** as a reference for building similar projects, or be aware that things are in flux, and in general nowhere near stable. - Simple wrapper structs such as [Entity] and [Identifier]. - Classes with convenience functions like [EntityRef] and [EntityType]. - Define your own [Components] as both value or reference types. - Query the ECS with [Iterators], [Filters], [Queries] and [Rules]. - Create [Systems] for game logic and [Observers] to act on changes. - [EntityPath] uses a unix-like path: `/Game/Players/copygirl` [Entity]: ./src/gaemstone.ECS/Entity.cs [Identifier]: ./src/gaemstone.ECS/Identifier.cs [EntityRef]: ./src/gaemstone.ECS/EntityRef.cs [EntityType]: ./src/gaemstone.ECS/EntityType.cs [Components]: ./src/gaemstone.ECS/Component.cs [Iterators]: ./src/gaemstone.ECS/Iterator.cs [Filters]: ./src/gaemstone.ECS/Filter.cs [Queries]: ./src/gaemstone.ECS/Query.cs [Rules]: ./src/gaemstone.ECS/Rule.cs [Systems]: ./src/gaemstone.ECS/System.cs [Observers]: ./src/gaemstone.ECS/Observer.cs [EntityPath]: ./src/gaemstone.ECS/EntityPath.cs ## Example ```cs var world = new World(); var position = world .New("Position") // Create a new EntityBuilder, and set its name. .Symbol("Position") // Set entity's symbol. (Used in query expression.) .Build() // Actually create the entity in-world. // Finally, create a component from this entity. // The "Position" struct is defined at the bottom of this example. .InitComponent(); world.New("One").Set(new Position( 0, 0)).Build(); world.New("Two").Set(new Position(10, 20)).Build(); var onUpdate = world.LookupOrThrow("/flecs/pipeline/OnUpdate"); // Create a system that will move all entities with // the "Position" component downwards by 2 every frame. world.New("FallSystem").Build() .InitSystem(onUpdate, new("Position"), iter => { var positionSpan = iter.Field(1); for (var i = 0; i < iter.Count; i++) { ref var position = ref positionSpan[i]; position = new(position.X, position.Y + 2); } }); // Create a system that will print out entities' positions. world.New("PrintPositionSystem").Build() .InitSystem(onUpdate, new("[in] Position"), iter => { var positionSpan = iter.Field(1); for (var i = 0; i < iter.Count; i++) { var entity = iter.Entity(i); var position = positionSpan[i]; Console.WriteLine($"{entity.Name} is at {position}"); } }); // Infinite loop that runs the "game" at 30 FPS. while (true) { var delta = TimeSpan.FromSeconds(1.0f / 30); // Progress returns false if quit was requested. if (!world.Progress(delta)) break; Thread.Sleep(delta); } record struct Position(int X, int Y); ``` ## Instructions ```sh # Clone the repository. Recurse into submodules to include flecs-cs and flecs. git clone --recurse-submodules https://git.mcft.net/copygirl/gaemstone.ECS.git # If you want to add it to your own repository as a submodule: git submodule add https://git.mcft.net/copygirl/gaemstone.ECS.git # To add a reference to this library to your .NET project: dotnet add reference gaemstone.ECS/gaemstone.ECS.csproj # To generate flecs-cs' bindings: ./gaemstone.ECS/src/flecs-cs/library.sh ```