Search Unity

Iterating over specific entities in a NativeList/NativeArray?

Discussion in 'Entity Component System' started by NanushTol, Sep 19, 2019.

  1. NanushTol

    NanushTol

    Joined:
    Jan 9, 2018
    Posts:
    131
    I'm designing my own ai system for the creatures in my game, and i'm currently working on a Ai planner, similar to goap.
    in the traditional way(none ECS) it should have 2 or 3 states.
    there are 3 options as I see it now:
    1. using a tag component, I don't want to add and remove tag components for each state, because it is costly in performance & It means ill have big sync points in my code because of the CommandBuffer
    2. using in-component flags, I would want to avoid having flags to avoid redundant checking of these flags in entities that doesn't need anything at the moment.
    3. having 3 Native Lists of entities, 1 for each state, GoTo list, PerformAction List, and IdleList, in this way I would avoid having command buffer syncpoint and wouldn't need to do redundant flag checking
    so the problem is that i don't know how or even if it's possible to iterate over a specific entity list in a parallel job.
    is there a way of doing that or another way to fake states?

    there are going to be a lot of creatures, aiming at around 5000 +, and would love to have 10K creature running at the same time. thats why im trying to avoid the 2 first options.
     
  2. tarahugger

    tarahugger

    Joined:
    Jul 18, 2014
    Posts:
    129
    I'd love to see some performance comparisons of each approach. With Option2 even though you would be wasting time checking the flags for every entity, it might end up faster because of how efficiently you can loop through them all. If you keep a list of entities in each state somewhere (and it's potentially out of order) then data access would jump around unpredictably and therefore be slower. So how many in each state you expect, how often the state changes and what extra components you need to get from entities in the various states come into play.

    This comment is not too helpful I know but if I have some time next month ill put together some test projects because I'm genuinely interested in where these thresholds lie. It's also worth considering that they're actively working on CommandBuffer and being able to make structural changes within burst in the future (according to the comments in Entities source code). Which would close the performance gap on the tagging (add/remove/query) approaches. It might come down to doing what is easier/cleaner for right now, see how performant it actually is and then re-evaluate as things change.
     
    JesOb and NanushTol like this.
  3. NanushTol

    NanushTol

    Joined:
    Jan 9, 2018
    Posts:
    131
    Thanks!
    I actually haven't thought about the problem of a random ordered list, that's a very good point!
    my assumption about performance didn't take that into account.
    It does raises another question, is it possible to order those lists according to chunks order?
    but I guess maybe i should start by using flags and change that if it doesn't work and perform well enough
     
  4. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    The question is how often you iterate over an entity without changing it's state. If you do: iteration -> state change -> iteration, option 2 would probably win. But your case sounds like there are a lot of iterations per state change. Meaning option 1 will waste no memory bandwidth as all data is used and no per entity branching is required.

    You should make sure to execute your command buffer at an existing sync point when possible.
     
    JesOb and NanushTol like this.
  5. NanushTol

    NanushTol

    Joined:
    Jan 9, 2018
    Posts:
    131
    the plan is to check if any entity needs a new plan every frame (checking for idle state) and then most likely queue them, so I would iterate over all creature entities every frame and make a flag check, thats alot of redundant checks per frames, the amount of state changes will be limited to the amount the planning system can take without causing frame drops.
    adding to that, the different "actions" that the creature can execute will also have a similar problem.
    I don't have actual amounts & performance data yet because i'm in the research & design phase now.

    what come to mind now is this:
    1. create a set of jobs, each job for a different plan action & state, which will use components as tags for the actions & states
    2. in addition to that having a component that holds flags for the different states & actions, so the system checks only once per frame what components needs to be added or removed.
    3. at the end of each frame\cycle checking those flags and add/remove components via command buffer only once
     
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,759
  7. NanushTol

    NanushTol

    Joined:
    Jan 9, 2018
    Posts:
    131
    I have checked the ai planner,
    Its still to early for me to adopt it as it seams that it is in a very early expirimental phase, couldn find a documentation that i can understand and use it in my level of programming,
    Looking at the source is a good idea!
    In the game im creating there is a need for some ai system that can have more flexebility then the regular fsm, so im looking at alternatives, do u have other recommendation then goap?
     
  8. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,759
    I'm quite a fan of the simplicity of Utility AI, however once you get hundreds of actions can be a bit of a pain to maintain.

    So I think the best approach (especially if you're going to write it from scratch anyway) is going to be some type of hybrid that fits your game. Take bits of GOAP, Utility AI etc and build them into a solution that works for what you need it to do.

    I think this is a decent explanation of a few approaches (and how he combined them for his own game)

     
    NanushTol and Deleted User like this.