#Iterating a range of entities

1 messages · Page 1 of 1 (latest)

lone magnet
#

is there any smart way to iterate a range of entities in DOTS ECS? Forgetting one second the chunked datastructure and assuming that entities can be iterated linearly between 0 and N, is there a way to say: iterate between M..N range? (where M < N ofc)

worldly pecan
#

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.

lone magnet
#

yeah that wouldn't do.

vivid crescent
#

why not just GetEntityArray() on a query

#

Or world.getallentities

worldly pecan
vivid crescent
#

no, the non-async version doesn't schedule a job

lone magnet
#

@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

worldly pecan
#

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

lone magnet
#

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

worldly pecan
lone magnet
#

I am confused, did you say "that would be way slower than jobs"

#

did you mean if used outside jobs?

worldly pecan
#

either way. Lookups = random access

#

job iteration - nicely aligned arrays

lone magnet
#

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

worldly pecan
#

it's not actually dictionary

#

it's literally array[int]

#

where int is entity index

#

but the point of it is the same

lone magnet
#

ok so it's sort of a double indexing eventually

#

it may be not that bad

#

won't be simd, but still

worldly pecan
#

I assume your case is about some groups of entities (for ex: car wheels, soldiers squads or smth like that)?

lone magnet
#

it's about grouping in general

worldly pecan
#

then yeah, feel free to use lookups

lone magnet
#

shared component is the best way by far, but I need to change the range dynamically

worldly pecan
#

just precache your entity arrays

#

in buffers

#

Transform system is using lookups for example

#

and it's very efficient

#

and fast

lone magnet
#

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

worldly pecan
#

you can store entity list as DynamicBuffer

#

on other entity

#

in Transform they use DynamicBuffer<Child>

lone magnet
#

no I don't need that, I would need to get the list from a query anyway

worldly pecan
#

where Child can be casted to Entity

worldly pecan
lone magnet
#

it's the only way to be sure that the IDs are uptodate

#

i.e. : entities can be deleted

worldly pecan
#

what's the use case?

lone magnet
#

being able to group entities in a different way than just the archetype

worldly pecan
#

oh

lone magnet
#

so I cannot solve it with adding/removing components

worldly pecan
#

then yeah, shared comps

#

is a way

lone magnet
#

I know but since the groups change, I pay the prices of the structural change whe necessary

#

which is HUGE

worldly pecan
#

they are not that bad

lone magnet
#

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

worldly pecan
#

move as in?

lone magnet
#

as in changing shared component, so structural change

#

the components must move between chunks/arrays

worldly pecan
#

ah

lone magnet
#

so I was looking for a way to subset without paying this price

#

double indexing is the only way to go as alternative

worldly pecan
#

what would be the real case scenario for 500 entities suddenly changing their archetype though?

lone magnet
#

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

worldly pecan
#

well, there are batched EntityManager commands

#

that let you do structural changes in a very efficient way on whole queries (not specific entities)

lone magnet
#

would be faster than using ECB? I am using just ECBs

worldly pecan
#

everything is faster than ECB

lone magnet
#

the problem is their playback

#

really

#

wow

worldly pecan
#

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

lone magnet
#

sure

#

how can I use batched commands with ECB?

#

it's the first time I hear about that

worldly pecan
#

just use EntityManager

lone magnet
#

but I use ECB inside jobs

worldly pecan
#

EntityManager.DestroyEntity(query)

#

for example

lone magnet
#

is that jobifiable now?

worldly pecan
#

no

#

but you could create your own implementation of command buffer

#

if you really need something specific

#

that is not part of ECB

lone magnet
#

I got the query part, but I don't think I can specify a set of entiy IDs in a query can I?

worldly pecan
#

you can specify entity array

#

which also will be faster

#

than individual commands per entity

lone magnet
#

hmm interesting

#

I need to try that too

#

thank you 🙂

#

just to confirm @worldly pecan BatchedEM > ECB > EM

worldly pecan
#

no

lone magnet
#

because EM used to do single operations MUST be slower due to sync points

worldly pecan
#

ECB is always the worst

lone magnet
#

I can't believe that

#

EM used directly creates sync points

worldly pecan
#

Sir, all ECB does is just scheduling commands that later calls actual EM

lone magnet
#

imagine using it all over the places

worldly pecan
#

yes, it does cause sync point

#

thus can't be used in jobs

#

that's why it has to be smart

lone magnet
#

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

lone magnet
#

@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

worldly pecan
#

ECS requires some well thought architecture design

#

you can't just do it the same way as you do OOP projects

lone magnet
#

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

worldly pecan
#

that sounds like best be done batched

#

you instantiate 500 entities in one command

lone magnet
#

so there is something similar to that?

worldly pecan
#

and run a job that assigns all required components to them

#

EntityManager.CreateEntity(archetype, array);

lone magnet
#

nice one thank you!

#

I will try, btw my demo is very trivial

#

it's just about brute force tho