andriyDev / bevy_landmass

A crate for Bevy to use landmass.
Apache License 2.0
7 stars 1 forks source link

Alter component set on entity to add agent state reflecting components, when landmass Agent state changes #8

Closed tviel closed 12 months ago

tviel commented 1 year ago

Depends and follow up of Report the state of agents back to clients

With the exposed Agent state of the linked task, a (new) system could check the agent state and alter the set of components on the agents entity, by adding / removing state reflecting components:

e.g.

AgentReachedTarget
AgentAproachesTarget

in addition to the data keeping components like AgentTarget.

andriyDev commented 1 year ago

I like it! This idea actually made me realize we might want to implement #9.

I initially was thinking instead of having a single state enum that we just attach to the entity, but I do like the idea of being able to query for each state (especially the AgentReachedTarget one).

tviel commented 1 year ago

Only thing I'm unsure with altering the component set, due to my noobie state with bevy: in the other ECS based engine I've seen (Unity DOTS), changing the set of components on an entity results in rather heavy memory changes, as there chunks are used, which group unique component mixes. So changing the components there results in rearranging the entities to other chunks, which has a performance drawback, why they introduced EnablableComponents.

I haven't found any internals, if bevy organizes memory in the same manner. If it would be that way, altering an existing component would be better performance wise then changing the set of components.

andriyDev commented 1 year ago

Yes, Bevy uses the same kind of "chunk" stuff (called Archetypes). So you are correct that changing these states would be costly.

So we have three options: 1) use one state enum component. This could probably even be re-exported from landmass. This means fewer archetype changes, but it's harder to query. 2) use one component per state like you suggested. More archetype changes, but much faster to query. 3) one component per state, but use Sparse Set storage. This means no archetype changes, at the cost of slower querying, but at least users can still query for AgentReachedTarget directly which is convenient.

I think I'm leaning towards the first option. The other two options can be implemented by users if they want (depending on the trade-offs they want), but the reverse is not true.

What are your thoughts?

tviel commented 1 year ago

Sounds reasonable, to make it optimized for performance and let the client choose, if they add an additional layer of self-induced comfort for their cases, or use the stock. This would probably best align also with a high amount of agents. Me myself thinking about using for hundreds of agents simultanously.

andriyDev commented 12 months ago

I decided to just make this happen since Bevy 0.12.0 is already out and I'm still a ways away from getting islands to be fully operational. They are working enough to match the existing behaviour, but are not doing everything they need to yet.