Search Unity

  1. Unity 2019.1 beta is now available.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We're looking for insight from anyone who has experience with game testing to help us better Unity. Take our survey here. If chosen to participate you'll be entered into a sweepstake to win an Amazon gift card.
    Dismiss Notice
  4. On February 28th the Feedback website will shut down and be redirected to the Unity forums. See the full post for more information.
    Dismiss Notice
  5. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  6. Unity 2018.3 is now released.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

[Tutorial] Starting a new tutorial series to cover making "jobified" systems

Discussion in 'Entity Component System and C# Job system' started by skhamis, Jan 13, 2019.

  1. skhamis

    skhamis

    Joined:
    Mar 3, 2017
    Posts:
    10
    Hey all!

    I am starting a new tutorial series that ill try cover the most "updated" way to make a game with ECS. I felt like there might not have been enough examples for making easy-to-understand systems. I'm going to target RTS as I feel it suits very well to something like this (alot of units, various types and things happening, etc). I have the full code on GitHub and will probably try to keep it updated as much as possible. Looking for feedback and if any of the code looks wrong!


    Link to final code: https://github.com/skhamis/pure-ecs-rts

    Link to (my) first video on the series:
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,059
    Didn't watch video (I'm personally just not a fan of video tutorials) but I had a read of your code and it looks solid.

    I look forward to watching it progress.
     
    Last edited: Jan 13, 2019
  3. skhamis

    skhamis

    Joined:
    Mar 3, 2017
    Posts:
    10
    I appreciate reading the code! I definitely know there are some people who like to see everything piece-by-piece and some people who prefer to just be given code and decipher what they need from there. Hopefully I can help people from both groups!
     
    Antypodish and Ylly like this.
  4. NoDumbQuestion

    NoDumbQuestion

    Joined:
    Nov 10, 2017
    Posts:
    99
    I read the code
    I wonder do we need to remove and add component to Entity. Just to tag it as selected.

    As far as I understand how ECS work, add/remove component from entity move it to different chunk since it is a new archetypes. And Command Buffer is not consider cheap.

    Would it be better if Selected Component have bool type or using SharedComponentData.
     
  5. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,059
    It's actually unlikely to move it to a new chunk in this situation as there will likely only be a single 'input' entity so the chunk will just be redefined. (And when the next build drops with singletons it'll probably made into that.)

    It's definitely a valid point though. Better off setting than adding/removing, I do not agree with the SharedComponentData suggestion though.
     
  6. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    867
    This right
    This not right :) Using SCD do same things, because it's per chunk basis based on SCD value, it's similar as add tag - it's moving entities in different chunks.
     
    Last edited: Jan 15, 2019
  7. skhamis

    skhamis

    Joined:
    Mar 3, 2017
    Posts:
    10
    Agree with the commenters that ShareComponentData shouldn't be used for anything that's changing often (like selecting units). From the docs:
    As for SelectedComponent being a component on all PlayerUnits and then just set the value to true/false. I felt like other systems that need to do anything with the selected units (move, attack, see available stats, etc) can filter easier rather than having to check component.isTrue. Though the more I think about it, it definitely might be more performant -- will have to run some tests!
     
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    3,495
    Surely we don't want every system running through thousands of entities, to check true false, if we dont change state often. Hence component taging can be useful.
    Probably wont be changing state of all units per same frame anyway. So taging can be naturally distributed over the time. This way, reducing number of unnecessary entities iterations on other systems.
     
  9. NoDumbQuestion

    NoDumbQuestion

    Joined:
    Nov 10, 2017
    Posts:
    99
    On contrary, I think iterate over 100000 every entities to check if-else is much cheaper than component tag different kind of archetype.
    Like if we pick different kind of minions with different components then each of them will become new archetype type and each in seperate chunks or redefine like tertle say.
     
  10. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    3,495
    For one system may be.
    Likely project specific, what requires.

    But if you have few system, which checks bool value, instead filtered entities by components?
    So lets say having 5 systems, which iterates through 100k each.
    Instead of having maybe 10k per system, per frame.
    And if you don't change status every frame, as I said earlier, that massive performance saving.

    Some nice comparison benchmark would be welcome.
     
  11. NoDumbQuestion

    NoDumbQuestion

    Joined:
    Nov 10, 2017
    Posts:
    99
    Then what would you think of the hierarchy tree sub-system design? Main system pass interest data over to sub-system.

    Starting with a tag system process 100k check if-else tag entities and pass 10k tag entities to sub-tag-system and 90k to sub-notag-system. This way we can handle different type of tag to different system in one go (may not optimal when made new data to each system)

    I think if design this way, more control over tag-system specific. Would it better than make system query for different component tag?

    Edit: this is for game that need lots of tag like minion type need different solution. Not simple isclick tag like above
     
  12. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    3,495
    You need weight, where you would use tag, and where bool of course.

    IsAlive tag, is a good example of use tags, to reduce count of entities for system (s).
    ReadyToAttack can be another use.
    Or retreat tag.

    But in case of fire now, if firing / attack is rapid and often bool iteration can be suitable.
    However, my system probably will be already filtered, by some form tag, as CanAttack / CanFight etc, since these are not need be toggled every single frame.

    Again, last thing I want, is having multiple system iterating through all entities, when not needed.
     
  13. jooleanlogic

    jooleanlogic

    Joined:
    Mar 1, 2018
    Posts:
    164
    They both have a place as Anytpodish showed good examples but polling the many for the few isn't a good strategy to use by default. It could take a toll over time as your game grows and would be harder to identify and fix later on as a performance issue.

    Tagging has it's downsides too though and polling has increased benefits vs tags within the job system.

    There is a thirdly option which is reference entities where you spawn a new entity and leave the target unaffected.
    Code (CSharp):
    1. Selected : IComponentData { Entity target; }
    You spawn a new Entity with Selected component and then the processing system just updates the target Entity position via ComponentDataFromEntity.
    This could be useful if you have ordered entities which can't move or heavy entities (dozens of components) which could be overkill to move for the sake of small operations.
     
  14. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    720
    And not to forget, that you would also only need to iterate through changed chunks. I would also love to see some benchmarks around this, to derive at some guiding design principles
     
  15. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    58
    The most important aapect of tagging to remember is in how often the tag is added/removed. Richard Fabian's book on Data-Oriented Design talks of the concept as existence based processing.

    His example is that a health recharge system that only does processing when some entity is damaged meaning that if the entity is at full health it's health component is removed and the same for when the entity is dead. This removes the need to check if the entity is at max health thus allowing the CPU to only focus on processing what data actually exists.

    It does depend on your use case though so it's most important to understand what your data is doing.
     
  16. skhamis

    skhamis

    Joined:
    Mar 3, 2017
    Posts:
    10
    Instead of making a new post I will just bump this one with my part 2! I also show how to update to 0.0.21 package (and update MeshInstanceRenderer to use a ISharedComponent)

     
    Rewaken and Antypodish like this.
  17. Garmbrael

    Garmbrael

    Joined:
    Jan 12, 2018
    Posts:
    1
    Another great tutorial video! Thank you very much for creating these and helping to educate us poor souls who are still struggling with the concept of how to use ECS. I did notice 2 things though. First, your github link https://github.com/skhamis/pure-ecs-rts is out of date and not actually representative of your current code in the video (namely the "Unit Spawn" component and system are missing). Second, I think you missed a few areas that should have had [BurstCompile] on the Jobs. ;)
     
  18. skhamis

    skhamis

    Joined:
    Mar 3, 2017
    Posts:
    10
    Hey Garmbrael,

    Thanks for watching! Also thanks for the feedback!

    1. GitHub updated, I hope sometime this weekend to start having branches per-video as opposed to just a dump on master once the "core" mechanics are done.

    2. I am actually saving the [BurstCompile] decorator, and burst compiling as a topic in general, for an entirely separate video where I can deep dive into the why and when to use it! Though thanks for keeping me on my toes ;P
     
  19. skhamis

    skhamis

    Joined:
    Mar 3, 2017
    Posts:
    10
    Part 3 released! I try to switch it up and use IJobProcessComponentDataWithEntity to get selecting working and we start creating a custom NavAgent to process smoothly moving from position to final position!

    updated github: https://github.com/skhamis/pure-ecs-rts

     
    Kiupe likes this.
  20. NoDumbQuestion

    NoDumbQuestion

    Joined:
    Nov 10, 2017
    Posts:
    99
    Your navagent not use Navmesh is kind of misleading. But anyway, great start up sample.
     
  21. Micz84

    Micz84

    Joined:
    Jul 21, 2012
    Posts:
    194
    I would pull out an if from select job and put it to execute method of the system so you do not start a job for no work at all.
     
  22. skhamis

    skhamis

    Joined:
    Mar 3, 2017
    Posts:
    10
    Continuing the series! Some people asked how to use the Attach component and attaching new entities to existing one so I cover that in part 4 of the series!

    Link to Github: https://github.com/skhamis/Unity-ECS-RTS

     
    FROS7 and MostHated like this.