Alternative managed wrapper around flecs-cs bindings for using the ECS framework Flecs in modern .NET.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
3.9 KiB

# 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<Position>();
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<Position>(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<Position>(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
```