Building a fast ECS on top of a slow ECS

preview_player
Показать описание
This is a quick introduction to Entity Component System Framework design. Specifically focused on how I built and implemented mine. There's a few interesting challenges with cache coherency, entity management, and entity filtering to tackle; so let's take a look!

Articles about building ECS frameworks

Other links
Рекомендации по теме
Комментарии
Автор

This might just be the best video covering ECS I've seen. Just this week I began attempting to implement this on the GBA as the data driven nature of it really aligns well with that sort of limited environment

graydhd
Автор

Great video, I was reading several articles and could NOT wrap my head around what the archetype is supposed to be. Your video was very easy to understand and much appreciated!

aghayejalebian
Автор

I'd been saying for years that Go wouldn't be viable for a working ECS until it had generics. And here we are.

tsalVlog
Автор

nice. I tried writing an ecs in typescript a year ago but gave up after being stuck in the weeds debugging type issues. Now I'm redoing the project in python and this video has been very helpful as you're extremely concise compared to other resources

bobsmithy
Автор

Very nice explanation of what goes into an ECS. Thanks for the Flecs shoutout!

sandermertens
Автор

Great content! Thank you for your time assembling such a great summary in such a consumable way! :D

panagiotisgeorgiadis
Автор

Great video as always. Curious to see the next video. My current ECS imlementation uses a similar approach.

jomy-games
Автор

Underrated channel; also a nice listen. thank you

mattshu
Автор

This is really cool, I don't know anything about Go, but the background knowledge of ECSs is really nice!

Zaniahiononzenbei
Автор

4:25 Why cant we just loop over the health array directly and add a variable inside the Health component to check if it is used by the entity

TheCommunistRabbit
Автор

I tried a lot of different ecs systems. What worked for me and is good enough for <20000 entities is just having an array of entities each containing a set array of components containing pointers to component data. It's far from optimal, but very easy to work with and fast enough. If an entity doesn't use a component it's just set as nullptr (C++).

basboerboom
Автор

My custom ECS in Rust uses sparse arrays instead, and I keep them sorted (by entity index). This means running the ECS system is as fast as it can be (you're literally going over a flat array that stores all data densely). The trade off is that getting a component by entity index needs to use binary search to get to the location.

Archetypes incur the cost at adding/deleting components instead of fetching them. It really depends on the use case whether one or the other is better. I really like to just add and delete components a bunch for a dynamic gameplay loop where you can alter state by adding or removing components. For the archetype pattern that's horrible. Yet if you like to fetch components by entity index a lot in your code the binary search my implementation has to do can become a bottleneck.

It's really fun to create an ECS but it's also full of very benign seeming nuances that can have a huge impact for hot loops.

stysner
Автор

honestly that chart at 1:15 instantly made it make sense to me holy crap

stefan
Автор

Very cool! The Archetype pattern loosely reminds me of how the v8 Javascript engine stores Prototypes, the internal object schema for all objects in a Javascript runtime.

helsontaveras
Автор

dude that thumbnail had me puzzled for a minute

awlam
Автор

what does the := operator in 1:40 mean ?

sitter
Автор

In your first little example, it would make more sense to have position but not velocity. I dont see why something would have velocity and no position.

mworld
Автор

Instead of searching for entities in an archetype, I just constantly update each archetype's list of entities each time a change in components happen on an event model, which is much faster.
So each archetype knows about all the eligible entities at any given moment.

Nidere
Автор

Since you are working on Golang, I wonder if channels help in this case for concurrency/parallelism?

cwhy
Автор

Interesting idea. But man that's a lot of overhead just for a few doubles and so many iterations to get to the actual data.
I'd just make an array of doubles, keep track of each entity/component start index and length in the array and then for integration send that entire array to the integrator (s += dt*ds). And if there are colliding objects I'd not give each object access to each other object in the world, I'd pre-cluster them so that each one checks a handful but not millions of entities.

Jet-Pack