Nuget Packages
Flecs.NET (Wrapper + Bindings + Native Libraries): Release | Debug
Flecs.NET.Bindings (Bindings + Native Libraries): Release | Debug
Flecs.NET.Native (Native Libraries): Release | Debug
New GitHub Package registry
For immediate access to the latest changes, NuGet packages are now pushed to the GitHub Package registry on every commit to the main branch. See the following link for more information. https://github.com/BeanCheeseBurrito/Flecs.NET?tab=readme-ov-file#github-package-registry
Static linking
Flecs can now be statically linked with Native AOT apps using the $(FlecsStaticLink)
property when consuming the Flecs.NET NuGet package.
To enable static linking, add <FlecsStaticLink>true</FlecsStaticLink>
to a property group. To prevent shared libraries from being copied to the output directory, add ExcludeAssets="native"
to your package reference.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PublishAot>true</PublishAot>
<FlecsStaticLink>true</FlecsStaticLink>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Flecs.NET.Debug" Version="*-*" ExcludeAssets="native"/>
</ItemGroup>
</Project>
Entity and Id extensions
All entity and id methods can now be called directly on Alert
, Component
, Observer
, Pipeline
, System
, TimerEntity
, and UntypedComponent
. Previously, accessing entity and id methods had to be done through the .Entity
and .Id
properties.
Old:
world.Component<Phases.Render>().Entity
.Add(Ecs.Phase)
.DependsOn(Ecs.OnUpdate);
New:
world.Component<Phases.Render>()
.Add(Ecs.Phase)
.DependsOn(Ecs.OnUpdate);
Managed type support for user contexts
The .Ctx()
APIs have been changed to support storing managed types as user context for queries, systems, and observers.
Old:
int value = 10;
world.System()
.Ctx(&value) // Pointer has to be passed.
.Each(static (Iter it, int _) =>
{
ref int ctx = ref it.Ctx<int>();
Console.WriteLine(ctx); // Prints 10
});
New:
world.System()
.Ctx("Context") // Context is passed by value
.Each(static (Iter it, int _) =>
{
ref string ctx = ref it.Ctx<string>();
Console.WriteLine(ctx); // Prints "String"
});
A callback can be provided to run clean-up logic before the context object is freed.
world.System()
.Ctx("Context", static (ref string ctx) =>
{
Console.WriteLine("Context is being freed");
})
.Each(...);
Managed types can now also be used for user data associated with groups.
using Query<Position> q = world.QueryBuilder<Position>()
.GroupBy<Group>()
// Callback invoked when a new group is created. Including the third "out T" parameter
// allows you to provide a user context.
.OnGroupCreate((World world, ulong id, out GroupCtx ctx) =>
{
Console.WriteLine($"Group {world.Entity(id)} created");
// Set data that will be associated with the group
ctx = new GroupCtx(groupCounter++);
})
// Callback invoked when a group is deleted. Including the third "ref T" parameter
// provides access to the user context object.
.OnGroupDelete((World world, ulong id, ref GroupCtx ctx) =>
{
Console.WriteLine($"Group {world.Entity(id)} deleted");
})
.Build();
Type-checked QueryBuilder.TermAt()
New type-checked versions of QueryBuilder.TermAt()
have been added to help ensure the intended field matches the correct type.
world.QueryBuilder<Position, Velocity, Mass>()
.TermAt<Position>(0).Singleton()
.TermAt<Velocity>(1).Singleton()
.TermAt<Velocity>(2).Singleton() // Assertion fails due to mismatched type
.Each(...);
For simple queries, the field index can be omitted, in which case the first field that matches the type argument is retrieved.
world.QueryBuilder<Position, Velocity, Mass>()
.TermAt<Velocity>().Singleton() // Matches field index 1
.Each();
World.AtFini/World.RunPostFrame/AppBuilder.Init
World.AtFini()
and World.RunPostFrame()
have been updated to only take a World
argument. You can no longer pass a user context alongside the callbacks. User data can instead be stored in a static field if needed.
Old:
world.RunPostFrame(static (ecs_world_t*, void*) =>
{
Console.WriteLine("Frame finished.")
}, null);
world.AtFini(static (ecs_world_t*, void*) =>
{
Console.WriteLine("World finish.")
}, null);
New:
world.RunPostFrame(static (World world) =>
{
Console.WriteLine("Frame finished.")
});
world.AtFini(static (World world) =>
{
Console.WriteLine("World finish.")
});
AppBuilder.Init()
now takes a World
instead of an ecs_world_t*
Old:
using World world = World.Create();
world.App()
.Init(Setup)
.Run();
static void Setup(ecs_world_t* worldPtr)
{
World world = World.Create(worldPtr);
world.Import<Module1>();
world.Import<Module2>();
world.Import<Module3>();
}
New:
using World world = World.Create();
world.App()
.Init(Setup)
.Run();
static void Setup(World world)
{
world.Import<Module1>();
world.Import<Module2>();
world.Import<Module3>();
}
Other
- Native build script can now output WASM static libraries
- Longstanding issue with multi-threaded system crashes has been fixed
- Using Flecs.NET in Native AOT applications works again
What's Changed
- Switch to GetEnumValuesAsUnderlyingType to resolve AOT warning by @deathbeam in #53
- Add support for QueryBuilder#TermAt and QueryBuilder#TermAt(int) by @deathbeam in #52
- Fix "address not mapped to object" crash by @BeanCheeseBurrito in #54
- Rewrite Flecs.NET.Codegen as console application by @BeanCheeseBurrito in #56
- Update CI script to upload to GitHub package registry on push by @BeanCheeseBurrito in #57
- Follow semver 2.0 for dev builds by @deathbeam in #59
- Rework how natives are built and add emscripten support by @deathbeam in #58
- Disable automatic NativeAOT linking by @deathbeam in #60
- Fix spacing issue when enabling SoftAssert by @deathbeam in #62
- Move duplicate properties to Directory.Build by @deathbeam in #61
- Pass zig include headers to binding generator by @BeanCheeseBurrito in #63
- Generate native getter functions for extern variables by @BeanCheeseBurrito in #68
- Compile flecs using src directory, build static and shared libraries separately by @BeanCheeseBurrito in #69
- Disable stack protection when compiling flecs by @BeanCheeseBurrito in #70
- Bundle zig's compiler rt when compiling flecs native libraries by @BeanCheeseBurrito in #71
- Update to flecs 4.0.3 by @BeanCheeseBurrito in #73
- Id and Entity extension generator by @BeanCheeseBurrito in #74
- Fix leak when disposing query builder, move free logic to context structs by @BeanCheeseBurrito in #75
- Allow managed types with .Ctx() for systems/observers, and update AppBuilder.Init() callback signature by @BeanCheeseBurrito in #76
- Make static linking optional by @BeanCheeseBurrito in #77
New Contributors
- @deathbeam made their first contribution in #53
Full Changelog: v4.0.2...v4.0.3