
Fast, lightweight entity-component system library designed to improve performance and usability for game development. Simplifies API by eliminating redundant components and ensuring null-safety, achieving competitive benchmark results.
A fast, lightweight, entity component system library written in Kotlin.
When developing my hobby games using LibGDX, I always used Ashley as an Entity Component System since it comes out of the box with LibGDX and performance wise it was always good enough for me.
When using Kotlin and LibKTX you even get nice extension functions for it, but I was never fully happy with how it felt because:
Entity? passed in as default to
an IteratingSystem,
although it will never be null (or at least shouldn't 😉)Those are the reasons why I wanted to build my own ECS-library and of course out of interest to dig deep into the details of this topic and to learn something new!
If you need a lightweight and fast ECS in your Kotlin application then feel free to use Fleks.
If you are looking for a long time verified ECS that supports Java then use Artemis-odb or Ashley.
After about one year of the first release of Fleks, we are now at version 2.x. This version combines the KMP and JVM flavors into a single one. The history of the 1.6 version is kept in separate branches. Also, the wiki will contain a separate section for 1.6 for users who don't want to migrate to 2.x or prefer the other API:
I want to make a big shout-out to jobe-m who helped with the first Kotlin multiplatform version and who also helped throughout the development of 2.0. Thank you!
With version 2.0 I tried to simplify the API and usage of Fleks for new users. This means that
e.g. ComponentMapper are no longer necessary and also the API is more in style with typical
Kotlin libraries which means more concise and easier to read (imho).
And of course the big goal was to combine the JVM and KMP branch which was also achieved by
completely removing reflection usage. This hopefully also makes the code easier to understand
and debug.
To use Fleks add it as a dependency to your project:
<dependency>
<groupId>io.github.quillraven.fleks</groupId>
<artifactId>Fleks-jvm</artifactId>
<version>2.12</version>
</dependency>implementation 'io.github.quillraven.fleks:Fleks:2.12'implementation("io.github.quillraven.fleks:Fleks:2.12")dependencyMulti("io.github.quillraven.fleks:Fleks:2.12", registerPlugin = false)If you want to use the Snapshot version then you need to add the snapshot repository as well:
// Groovy DSL
maven { url 'https://central.sonatype.com/repository/maven-snapshots/' }
// Kotlin DSL
maven { url = uri("https://central.sonatype.com/repository/maven-snapshots/") }The API is documented in the wiki that also contains an example section for JVM and KMP projects.
One important topic for me throughout the development of Fleks was performance. For that I compared Fleks with Artemis-odb and Ashley in three scenarios which you can find in the jvmBenchmarks source set:
IteratingSystem for a single component that
gets a Float counter increased by one every tick.IteratingSystem and three components. It is a
time-consuming benchmark because all entities get added and removed from the first system each tick.
I used kotlinx-benchmark to create the benchmarks with a measurement that represents the number of executed operations within three seconds.
All Benchmarks are run within IntelliJ using the benchmarksBenchmark gradle task on my local computer. The hardware
is:
Here is the result (the higher the Score the better):
| Library | Benchmark | Mode | Cnt | Score | Error | Units |
|---|---|---|---|---|---|---|
| Ashley | AddRemove | thrpt | 3 | 207,007 | ± 39,121 | ops/s |
| Artemis | AddRemove | thrpt | 3 | 677,231 | ± 473,361 | ops/s |
| Fleks | AddRemove | thrpt | 3 | 841,916 | ± 75,492 | ops/s |
| Ashley | Simple | thrpt | 3 | 3,986 | ± 1,390 | ops/s |
| Artemis | Simple | thrpt | 3 | 32,830 | ± 2,965 | ops/s |
| Fleks | Simple | thrpt | 3 | 33,017 | ± 3,089 | ops/s |
| Ashley | Complex | thrpt | 3 | 0,056 | ± 0,117 | ops/s |
| Artemis | Complex | thrpt | 3 | 1,452 | ± 0,452 | ops/s |
| Fleks | Complex | thrpt | 3 | 1,326 | ± 0,269 | ops/s |
I am not an expert for performance measurement, that's why you should take those numbers with a grain of salt but as you can see in the table:
A fast, lightweight, entity component system library written in Kotlin.
When developing my hobby games using LibGDX, I always used Ashley as an Entity Component System since it comes out of the box with LibGDX and performance wise it was always good enough for me.
When using Kotlin and LibKTX you even get nice extension functions for it, but I was never fully happy with how it felt because:
Entity? passed in as default to
an IteratingSystem,
although it will never be null (or at least shouldn't 😉)Those are the reasons why I wanted to build my own ECS-library and of course out of interest to dig deep into the details of this topic and to learn something new!
If you need a lightweight and fast ECS in your Kotlin application then feel free to use Fleks.
If you are looking for a long time verified ECS that supports Java then use Artemis-odb or Ashley.
After about one year of the first release of Fleks, we are now at version 2.x. This version combines the KMP and JVM flavors into a single one. The history of the 1.6 version is kept in separate branches. Also, the wiki will contain a separate section for 1.6 for users who don't want to migrate to 2.x or prefer the other API:
I want to make a big shout-out to jobe-m who helped with the first Kotlin multiplatform version and who also helped throughout the development of 2.0. Thank you!
With version 2.0 I tried to simplify the API and usage of Fleks for new users. This means that
e.g. ComponentMapper are no longer necessary and also the API is more in style with typical
Kotlin libraries which means more concise and easier to read (imho).
And of course the big goal was to combine the JVM and KMP branch which was also achieved by
completely removing reflection usage. This hopefully also makes the code easier to understand
and debug.
To use Fleks add it as a dependency to your project:
<dependency>
<groupId>io.github.quillraven.fleks</groupId>
<artifactId>Fleks-jvm</artifactId>
<version>2.12</version>
</dependency>implementation 'io.github.quillraven.fleks:Fleks:2.12'implementation("io.github.quillraven.fleks:Fleks:2.12")dependencyMulti("io.github.quillraven.fleks:Fleks:2.12", registerPlugin = false)If you want to use the Snapshot version then you need to add the snapshot repository as well:
// Groovy DSL
maven { url 'https://central.sonatype.com/repository/maven-snapshots/' }
// Kotlin DSL
maven { url = uri("https://central.sonatype.com/repository/maven-snapshots/") }The API is documented in the wiki that also contains an example section for JVM and KMP projects.
One important topic for me throughout the development of Fleks was performance. For that I compared Fleks with Artemis-odb and Ashley in three scenarios which you can find in the jvmBenchmarks source set:
IteratingSystem for a single component that
gets a Float counter increased by one every tick.IteratingSystem and three components. It is a
time-consuming benchmark because all entities get added and removed from the first system each tick.
I used kotlinx-benchmark to create the benchmarks with a measurement that represents the number of executed operations within three seconds.
All Benchmarks are run within IntelliJ using the benchmarksBenchmark gradle task on my local computer. The hardware
is:
Here is the result (the higher the Score the better):
| Library | Benchmark | Mode | Cnt | Score | Error | Units |
|---|---|---|---|---|---|---|
| Ashley | AddRemove | thrpt | 3 | 207,007 | ± 39,121 | ops/s |
| Artemis | AddRemove | thrpt | 3 | 677,231 | ± 473,361 | ops/s |
| Fleks | AddRemove | thrpt | 3 | 841,916 | ± 75,492 | ops/s |
| Ashley | Simple | thrpt | 3 | 3,986 | ± 1,390 | ops/s |
| Artemis | Simple | thrpt | 3 | 32,830 | ± 2,965 | ops/s |
| Fleks | Simple | thrpt | 3 | 33,017 | ± 3,089 | ops/s |
| Ashley | Complex | thrpt | 3 | 0,056 | ± 0,117 | ops/s |
| Artemis | Complex | thrpt | 3 | 1,452 | ± 0,452 | ops/s |
| Fleks | Complex | thrpt | 3 | 1,326 | ± 0,269 | ops/s |
I am not an expert for performance measurement, that's why you should take those numbers with a grain of salt but as you can see in the table: