- Notifications
You must be signed in to change notification settings - Fork12
... the little C# ECS that loves you back!
License
outfox/fennecs
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
We know... oh,we know. 😩 But in a nutshell,fennecs is... 🐾 zero codegen | |
Brand new? Try thecookbook for a quick & tasty intro, ordive into the docs!
Familiar with ECS architectures? Get anoverview of new & unique concepts!
At the basic level, all you need is a 🧩component type, a number ofsmall foxes 🦊entities, and a query to ⚙️iterate and modify components, occasionally passing in some uniform 💾data.
// Declare a component record. (we can also use most existing value & reference types)recordstructVelocity(Vector3Value);// Create a world. (fyi, World implements IDisposable)varworld=newfennecs.World();// Spawn an entity into the world with a choice of components. (or add/remove them later)varentity=world.Spawn().Add<Velocity>();// Queries are cached & we use ultra-lightweight Stream Views to feed data to our code!varstream=world.Query<Velocity>().Stream();// Run code on all entities in the query. (exchange 'For' with 'Job' for parallel processing)stream.For(uniform:DeltaTime*9.81f*Vector3.UnitZ,action:(Vector3uniform,refVelocityvelocity)=>{velocity.Value-=uniform;});
By any measure, we're talking just a couple of lines to get this gravity feature up and running. Creating the world and query is the only setup – the real slam dunk is how cleanly we built the full actor/gravity logic with barely any ceremonial code in sight.
And there's more: all that simplicity doesn't force any performance trade-offs! You get to have your cake and eat it too with zero confusion or fluff!
- Modern C# 12 codebase, targeting .NET 8.
- Full Unit Test coverage.
- Powerfully intuitive ways to access data...fast!
- Workloads can be easily parallelized acrossand within Archetypes
- Expressive, queryable relations among Entities themselves & between Entities and Objects
- No code generation and no reflection required.
📕 DOCUMENTATION:fennecs.tech (official website)
Grab a cup of coffee toget started, trythe Cookbook, viewthe Demos , and more!
Preliminary (WIP) benchmarks suggest you can expect to process over 2 million components per millisecond on a 2020 CPU without even customizing your logic.
Using Doraku's syntheticEcs.CSharp.Benchmark, fennecs scores among the faster ECS in the benchmark suite.
(link goes to PR #36 to reproduce)
Warning
These are synthetic benchmarks, using aBETA BUILD offennecs. Real-world performance will vary wildly.If you need a production-ready ECStoday, 9 out of 10 foxes endorseFriflo.Engine.ECS👍 andFlecs.NET👍
Another optimization pass forfennecs ison the Roadmap.
// Benchmark Process Environment Information:// BenchmarkDotNet v0.13.12// Runtime=.NET 8.0.5 (8.0.524.21615), X64 RyuJIT AVX2// GC=Concurrent Workstation// HardwareIntrinsics=AVX2,AES,BMI1,BMI2,FMA,LZCNT,PCLMUL,POPCNT VectorSize=256// Job: ShortRun(IterationCount=3, LaunchCount=1, WarmupCount=3)// [EntityCount=100_000]
ECS & Method | Duration (less=better) |
---|---|
🦊 fennecs | 1.458 ms |
FrifloEngineEcs | 1.926 ms |
LeopotamEcs | 4.991 ms |
LeopotamEcsLite | 4.994 ms |
Arch | 7.811 ms |
FlecsNet | 17.838 ms |
DefaultEcs | 19.818 ms |
TinyEcs | 24.458 ms |
HypEcs | 25.215 ms |
MonoGameExtended | 27.562 ms |
Myriad | 28.249 ms |
SveltoECS | 52.311 ms |
Morpeh_Stash | 64.930 ms |
RelEcs | 65.023 ms |
Morpeh_Direct | 131.363 ms |
// Benchmark Process Environment Information:// BenchmarkDotNet v0.13.12// Runtime=.NET 8.0.5 (8.0.524.21615), X64 RyuJIT AVX2// GC=Concurrent Workstation// HardwareIntrinsics=AVX2,AES,BMI1,BMI2,FMA,LZCNT,PCLMUL,POPCNT VectorSize=256// Job: ShortRun(IterationCount=3, LaunchCount=1, WarmupCount=3)// [EntityCount=100_000, EntityPadding=10]
ECS & Method | Duration (less=better) | Comment |
---|---|---|
🦊 fennecs(AVX2) | 10.43 µs | optimized Stream<>.Raw using AVX2 Intrinsics |
🦊 fennecs(SSE2) | 11.41 µs | optimized Stream<>.Raw using SSE2 Intrinsics |
FrifloEngineEcs_MultiThread | 13.45 µs | |
FrifloEngineEcs_SIMD_MonoThread | 16.92 µs | |
TinyEcs_EachJob | 20.51 µs | |
Myriad_MultiThreadChunk | 20.73 µs | |
TinyEcs_Each | 40.84 µs | |
FrifloEngineEcs_MonoThread | 43.41 µs | |
HypEcs_MonoThread | 43.86 µs | |
🦊 fennecs(Raw) | 46.36 µs | straightforward loop over Stream<>.Raw |
HypEcs_MultiThread | 46.80 µs | |
Myriad_SingleThreadChunk | 48.56 µs | |
Arch_MonoThread | 51.08 µs | |
Myriad_SingleThread | 55.65 µs | |
🦊 fennecs(For) | 56.32 µs | your typical bread & butterfennecs workload |
Arch_MultiThread | 59.84 µs | |
FlecsNet_Iter | 77.47 µs | |
🦊 fennecs(Job) | 97.70 µs | unoptimized in beta, ineffective <1M entities |
DefaultEcs_MultiThread | 102.37 µs | |
Myriad_Delegate | 109.31 µs | |
Arch_MonoThread_SourceGenerated | 134.12 µs | |
DefaultEcs_MonoThread | 142.35 µs | |
LeopotamEcs | 181.76 µs | |
FlecsNet_Each | 212.61 µs | |
LeopotamEcsLite | 230.50 µs | |
Myriad_Enumerable | 245.76 µs | |
RelEcs | 250.93 µs | |
SveltoECS | 322.30 µs | EntityPadding=0, skips benchmark with 10 |
MonoGameExtended | 387.12 µs | |
Morpeh_Stash | 992.62 µs | |
Myriad_MultiThread | 1115.44 µs | |
Morpeh_Direct | 2465.25 µs |
So how doesfennecs compare to other ECSs?
This library is a tiny, tiny ECS with a focus on good performance and great simplicity. But itcares enough to provide a few things you might not expect.
Important
The idea offennecs was to fill the gaps that the author felt working with various established Entity-Component Systems. This is why this matrix is clearly imbalanced, it's a shopping list of things thatfennecs does well and was made to dowell; and things it may aspire to do but compromised on in order to be able to achieve the others.
(TL;DR - Foxes are soft, choices are hard - Unity dumb, .NET 8 really sharp.)
🥇🥈🥉 (click to expand) ECS Comparison Matrix
Here are some of the key properties wherefennecs might be a better or worse choice than its peers. Our resident fennecs have worked with all of these ECSs, and we're happy to answer any questions you might have.
fennecs | HypEcs | Entitas | Unity DOTS | DefaultECS | |
---|---|---|---|---|---|
Boilerplate-to-Feature Ratio | 3-to-1 | 5-to-1 | 12-to-1 | 27-to-1 😱 | 7-to-1 |
Entity-Component Queries | ✅ | ✅ | ✅ | ✅ | ✅ |
Entity-Entity Relations | ✅ | ✅ | ❌ | ❌ | ✅ (Map/MultiMap) |
Entity-Object-Relations | ✅ | 🟨 (System.Type only) | ❌ | ❌ | ❌ |
Target Querying (find all targets of specific relations) | ✅ | ❌ | ❌ | ❌ | ✅ |
Wildcard Semantics (match multiple relations in 1 query) | ✅ | ❌ | ❌ | ❌ | ❌ |
Journaling | ❌ | ❌ | 🟨 | ✅ | ❌ |
Shared Components | ✅ (ref types only) | ❌ | ❌ | 🟨 (restrictive) | ✅ |
Mutable Shared Components | ✅ | ❌ | ❌ | ❌ | ✅ |
Reference Component Types | ✅ | ❌ | ❌ | ❌ | ❌ |
Arbitrary Component Types | ✅ | ✅ (value types only) | ❌ | ❌ | ✅ |
Structural Change Events | 🟨 (planned) | ❌ | ✅ | ☠️ (unreliable) | ❌ |
Workload Scheduling | ❌ | ❌ | ❌ | ✅ (highly static) | ✅ |
No Code Generation Required | ✅ | ✅ | ❌ | ❌ | 🟨 (roslyn addon) |
Enqueue Structural Changes at Any Time | ✅ | ✅ | ✅ | 🟨 (restrictive) | 🟨 |
Apply Structural Changes at Any Time | ❌ | ❌ | ✅ | ❌ | ❌ |
Parallel Processing | ⭐⭐ | ⭐ | ❌ | ⭐⭐⭐ | ⭐⭐ |
Singleton / Unique Components | 🟨 (ref types only) | ❌ | ✅ | 🟨 (per system) | ✅ |
Many thanks toByteron (Aaron Winter) for creatingHypEcs andRelEcs, the inspiring libraries thatfennecs evolved from.
Neofox was created byVolpeon and is in the Creative CommonsCC BY-NC-SA 4.0, the same license applies to all Neofox-derived works made for this documentation.
About
... the little C# ECS that loves you back!
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors7
Uh oh!
There was an error while loading.Please reload this page.