#Iterating a range of entities
1 messages · Page 1 of 1 (latest)
not really. Jobs iterate chunks, not single entities.
To do this you'd need to allocate entity list obtained from chunks (this will be a job) and then whatever calculation you'd do will probably require slow random access lokups.
yeah that wouldn't do.
Isn't it just a GetEntityListAsync with Complete()?
no, the non-async version doesn't schedule a job
@vivid crescent I can surely try that, but I need to write back to the entities, I need to see if I can do that
is the pattern DOTS 1.0 compliant?
if I remember correctly this would copy data though, while I would need a reference
ComponentLookup + ToEntityArray may be a solution, but I am not sure how slow that would be either
that would be way slower than jobs
think of it this way, when you iterate over components in job - you work with pointers of actual data aligned in nice 16kb (could be wrong on exact size) chunks
but when you use lookup
first you go over huge dictionary to figure what chunk this entity belongs to
Then you obtain resolve pointer of that entity to actual data in chunk
ok so the implementation of the look up is slow. In the latest examples look up are used (inside jobS), while EntityArray not that much
in any case I need to write back into the entities components
for what I have to do, I had already a solution in reality, which was to use ISharedComponent as range ID
unfortunately DOTS is VERY VERY wary of structural changes, but still it seems to be the best way to go
I think DOTS misses a more flexible filtering system, but I am sure it's all due to the limitation due to the chunked architecture
it's totally fine to use lookups, just use jobs whenever you can
I am confused, did you say "that would be way slower than jobs"
did you mean if used outside jobs?
yes if it uses a dictionary yes, I was hoping it would use a sparse set and double indexing
still randomish, but a bit better
it's not actually dictionary
it's literally array[int]
where int is entity index
but the point of it is the same
ok so it's sort of a double indexing eventually
it may be not that bad
won't be simd, but still
I assume your case is about some groups of entities (for ex: car wheels, soldiers squads or smth like that)?
it's about grouping in general
then yeah, feel free to use lookups
shared component is the best way by far, but I need to change the range dynamically
just precache your entity arrays
in buffers
Transform system is using lookups for example
and it's very efficient
and fast
nice, I will need to check that then
so what I can do is to create slices of the EntitiesID and run a job for each slice with the lookup
defo something to try
you can store entity list as DynamicBuffer
on other entity
in Transform they use DynamicBuffer<Child>
no I don't need that, I would need to get the list from a query anyway
where Child can be casted to Entity
that does not sound too good
it's the only way to be sure that the IDs are uptodate
i.e. : entities can be deleted
what's the use case?
being able to group entities in a different way than just the archetype
oh
so I cannot solve it with adding/removing components
I know but since the groups change, I pay the prices of the structural change whe necessary
which is HUGE
they are not that bad
on my I9, when I move hundreds of entities (let's say up to 500), using the default entities wihout any custom component, it can get up to 4ms
it spikes randomly
move as in?
as in changing shared component, so structural change
the components must move between chunks/arrays
ah
so I was looking for a way to subset without paying this price
double indexing is the only way to go as alternative
what would be the real case scenario for 500 entities suddenly changing their archetype though?
well without going in to specific, I use sets to define states. so in a frame is possible that for some reason 500 entitie schange state at the same time
these are extreme scenario, in reality it's a simple demo to test use cases
but the concept is that: modelling states
and not using if
well, there are batched EntityManager commands
that let you do structural changes in a very efficient way on whole queries (not specific entities)
would be faster than using ECB? I am using just ECBs
everything is faster than ECB
ECB is just a buffer to store commands
all you do using it - allow yourself to delay some structural changes in jobs
where they can't happen
sure
how can I use batched commands with ECB?
it's the first time I hear about that
just use EntityManager
but I use ECB inside jobs
is that jobifiable now?
no
but you could create your own implementation of command buffer
if you really need something specific
that is not part of ECB
I got the query part, but I don't think I can specify a set of entiy IDs in a query can I?
you can specify entity array
which also will be faster
than individual commands per entity
hmm interesting
I need to try that too
thank you 🙂
just to confirm @worldly pecan BatchedEM > ECB > EM
no
because EM used to do single operations MUST be slower due to sync points
ECB is always the worst
Sir, all ECB does is just scheduling commands that later calls actual EM
imagine using it all over the places
yes, it does cause sync point
thus can't be used in jobs
that's why it has to be smart
so that's it
ofc most of the code is jobified
however I do believe that using batchedEM in already existing sync points may be a good move
I need to test that
@worldly pecan I did several tests, not sreally sure about how it looks like yet, because it made me find out that a massive part of the problem is due to creation of entities
that I am still doing through ECB
ECS requires some well thought architecture design
you can't just do it the same way as you do OOP projects
I am the creator of Svelto.ECS, doing it since 2015. I usually teach about ECS 🙂
that's not the problem
it's the real sheer amount of entities I am creating
500 each frame
so there is something similar to that?