Fast ECS and duplication of data

Hello. I’m currently using edge ECS, however when reaching 1k components, I get sharp FPS drop (lots of bullets, using TileMap) even with only 2 systems. BunnyMark works without a hiccup up to 8k bunnies across all platforms for me. So, the question is: which ECS written in haxe is fastest? Did anybody make a benchmark?

ECS’s I’m aware of, but haven’t tried yet:
Ash-Haxe - additional upsides: entity state machines. Downsides: manual writing of nodes, probably no more updates
eskimo - as author written himself: functionality over performance

I’ve asked earlier for a review, because maybe the problem doesn’t lie with ECS, but with my code.

Now the second question about integrating OpenFL data with components. At the moment I have clean distinction of component Position and Render. Not every object is visible, so why render it at all? The problem with this approach however, is that I must keep my own object hierarchy within Position, parent-child relations, matrixes, all that jazz. Anybody had similar experience, or the best way is just to always render objects and use default openfl implementation?

Unrelated: How on earth is html5 target more performant than CPP? Is it because of cairo?

Doesnt look like you are recycling your bullet objects, I’ve seen many projects that simply set the bullet to “inactive” when it expires.
Khashmup does it this way:

As far as CPP being slower than HTML5, that makes no sense to me. Mine is much faster when I run my game with:
haxelib run openfl test linux

1 Like

Hello,

you can try seagal (branch seagal2), the author made an improvement on performance. But sadly you are limited to 32 components right now.

Also you can try ECX, according to the author (see benchmark) it’s the fastest ECS alive.

1 Like

@loudo For a second when looking on benchmarks I didn’t see much improvement, until I realized the scale on X axis is different. Just by looking on CPP: Edge’s 3K iterations/s vs ECX 225K iterations/s - now that’s a boost I won’t pass on!

@meowman9000 That’s something I didn’t consider, thank you as well

However, I don’t know the value of the benchmark. Also be careful, the most natural way to handle components is labeled as ecx_view in the benchmark which is less performant than ecx. The other, labeled ecx, is different, the way you get a component is like inverted (from component to entity instead of from entity to component). Also, it doesn’t seem that ecx allow family or node matching (group of components), it seems to only handle component matching. So if the world get bigger, you will always (I think) iterate on every entities and not only the family. I would love to know more about this framework.

EDIT: it seems that ECX has a family class but the benchmark doesn’t use it.

Well, ECX’s Family uses EntityVector as the underlying implementation for iteration.

The getIterator() will return a single instance of new EntityVectorIterator() per system process. Beyond that, each instance being returned per iteration is simply new Entity(), but since Entity is merely an abstract int, ie. it’s simply returns an integer per iteration. The int is retrieved from the ds CInt32ArrayData, which the native JS platform also takes advantage of as well.

Overall, the additional overhead with iterating though Family (if any) is bound to be less (i think) compared to other framework equilavents. But generally, it may be unfair to compare ECS( Packed Component Services with Abstract Entity Integers) vs. ECS(Entity Bag of Components) frameworks. Another Similar Packed component ECS framework is awe (not on haxelib, but on github), but i couldn’t ge tit to work as i think it’s pretty old. Furthermore, I don’t see much potential benefit with AWE framework using haxe.io.Bytes for packing since ByteArray access in Flash is slow (you need to use Domain memory for that).

Overall, I think you must use the development version of ECX on git though, as the one on Haxelib is the legacy version that has a lot of key limitations (much older API). My main beef with ECX compared to other frameworks is that you still need to implement a boiler-plate class declaration adaptors that extends AutoComp<Untouched> for each component (you might want to create a macro to automate this for any of your component classes.), but at least your components can be left “untouched” and this is a significant improvement over other Packed-Component-service-oriented ECS frameworks (eg. awe requires extending Component directly) (all of which i see do require actual dirtying of any classes you intend to use as components.). In ECX, this is avoided at the cost of slightly more boilerplate/user-land macroing.


In terms of syntactic sugar and ease of use, Edge is a good framework to consider instead of Ash, especially for Javascript environment where it seems that Ash’s use of linked list doesn’t really perform well in Javascript environments anyway (only in static-typed environments) .Otherwise, looking for something most mature and established, still stick to Ash, as long as you don’t mind the boilerplate of constructing your Node classes. But if need a potential future data-driven packing/serialization/parellization approach with potential use of domain memory integration (or maybe integrate your own DS pipeline), I think ECX seems like the choice, but be prepare to have to fork it and make changes as it’s not as mature compared to Edge or Ash.

Eg. I encountered a minor macro-related type-completion issue with the ECX components when using it with Haxe 3.3 (working) versus HAxe 3.4 (vomitted out all compile-time metadata fields), which was exactly what I encountered with one of my own frameworks as well ( namely, HaxeVx ) …and i’d probably have to look into forking/fixing that, as I can’t remember how I went about fixing it…lol)

So, my top 3 choices boil down to:

  1. Ash (Entity Bag) - >= 1.5.4 (use on haxelib)
  2. Edge (Entity Bag) - >= 0.7.0 (use on haxelib)
  3. ECX (Packed Components and Abstract Entity Ints) - >= 0.1.0 (fork your own)

NOTE: Edge uses Tink though, and I had to upgrade HaxeDevelop to a latest version in order to avoid crashes with Tink under HaxeDevelop IDE.

Other frameworks i’ve looked into briefly and considered (both Entity-bag based):

  1. Cosmos: https://github.com/wighawag/cosmos - >= 0.5.0
  2. Eskimo: https://github.com/PDeveloper/eskimo - >= 0.1.0

When it comes to ECS, the key lies in how it goes about retrieving component data.

Cosmos is null-safe with a similar implementation to Edge’s View<{...componentFields}> de construction (cosmos’ Entities<T>), and uses macro to be able to resolve dependencies and even hook up event handlers via annotations. However, T doesn’t appear to work with regular classes from my tests, and he macro needs to be better improved with better checkings in case I’m using it wrongly…(again, not too sure…). May stick to Edge for more predictability since Edge is more mature and more documented over standard usage.

Eskimo requires retrieving components via entity.get(ComponentClass) as the only option, and is likely to be not null-safe (i think, not too sure). Because of this, I don’t see how this is an “improvement”, though this was a design decision made according to the readme. It does appear to have some good (pure-entity) filtering capabilities via the IFilter/Filter api though. Eskimo as an ECS framework seems to emphasise more on the “E” as the main driver to retrieve components, and nothing else.

2 Likes

There is a new challenger : https://github.com/kevinresol/exp-ecs
Have you tried it?

It seems that it’s like Ash with less boilerplate (no need to create nodes class).