Search Unity

Discussion Verbosity in the Entities 1.0

Discussion in 'Entity Component System' started by vectorized-runner, Jun 4, 2023.

  1. vectorized-runner

    vectorized-runner

    Joined:
    Jan 22, 2018
    Posts:
    398
    Am I the only one frustrated with the amount of Verbosity in the Entities 1.0? Did we have to sacrifice so much for performance?

    Examples:
    • Can't have GetSingletonEntity (and friends) in SystemBase now, it needs to called through SystemAPI. SystemAPI has weird naming anyway (I've never seen any class called API before, lol) and I'm not sure why a such class needs to exists when we have EntityManager (that's a conversation for later)
    • New EntityQueryBuilder, can't use GetEntityQuery.
    • Entities.ForEach, Job.WithCode, all were really productive, it looks like they're going to be deprecated. (Do we really care all that much about Burst compiling the System update)
    • GenerateAuthoringComponent deprecated.
    • New IJobChunk syntax (are you even serious with this?)
    It feels like everything has to be explicitly handled. The abstractions are leaked.

    I'm not quite sure if I'll get used to this, as I'm not using ECS in my daily job anyway, just for side projects.

    It might be natural for people here who are ECS enthusiasts for many years, but I'm not sure if the average coder will like it, the current way of doing things look intimidating.

    Up until Entities 0.50 ECS was increasing in productivity, such as JobComponentSystem to SystemBase. I'm not sure where it goes from here.
     
    Last edited: Jun 4, 2023
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    I've deleted at least 3,000 lines of code since upgrading to 1.0 from 0.51

    As someone who still works with 0.51 at work, 1.0 is so much less verbose... :confused:

    Also disagree with this. They cause really slow iteration times, our work project got up to 45-70+ second iteration times for 1k EFE/JWC (they're something like 4x slower than IJobEntity) and produce some of the least manageable code I've ever seen.
     
    Last edited: Jun 4, 2023
    Krajca, toomasio, Tony_Max and 6 others like this.
  3. gencontain

    gencontain

    Joined:
    Nov 15, 2012
    Posts:
    15
    If you statically import SystemAPI it really isn't that verbose. Idiomatic foreach is also very easy to use to get things up and running quickly if you want to avoid writing job structs. I think it's in a decent place now, you don't have to write a single explicit job until you want to so you're not confronted with the complexity.
     
  4. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    628
    A fair number of stuff would best be in jobs though, idiomatic foreach doesn’t introduce any parallelism or threading support unlike jobs/E.FE/J.WC. It’s pretty much a given that any serious project that at least attempts to make full use of Entities will need a smattering of IJobEntity & co.
     
  5. gencontain

    gencontain

    Joined:
    Nov 15, 2012
    Posts:
    15
    Yes of course, but I feel that the discussion here is more about what it's like getting into ECS to begin with. If you're coming from a more OOP place it'll be enough of a challenge to figure out how to lay out your data in structs and process them in systems, never mind parallelism. This is where idiomatic foreach is very nice since it's just a foreach loop, not a construct like Entities.ForEach where your past experience isn't as much help.

    It ties into whether it's too verbose or not in that you can get to a pretty good place with little verbosity, and once you're more comfortable with how Entities works and have identified bottlenecks that can take advantage of parallelism you can then start writing more code to get the performance gains you need.
     
  6. vectorized-runner

    vectorized-runner

    Joined:
    Jan 22, 2018
    Posts:
    398
    I guess I should give it a longer go, if you all think that way
     
  7. gencontain

    gencontain

    Joined:
    Nov 15, 2012
    Posts:
    15
    Do give it another go, it's not really that bad! Just to elaborate a bit more, the amount of code needed to get a burst compiled system up and running that does useful work is quite small now:

    Code (CSharp):
    1.  
    2. using Unity.Burst;
    3. using Unity.Entities;
    4. using static Unity.Entities.SystemAPI;
    5.  
    6. public struct Foo : IComponentData { }
    7. public struct Baz : IComponentData { }
    8.  
    9. public partial struct MySystem : ISystem {
    10.     [BurstCompile]
    11.     public void OnUpdate(ref SystemState state) {
    12.         foreach (var (foo, baz) in Query<Foo, Baz>()) {
    13.             // Do things with foo & baz data here
    14.         }
    15.     }
    16. }
    17.  
     
  8. inSight01

    inSight01

    Joined:
    Apr 18, 2017
    Posts:
    90
    This one annoys me if I'm being honest. I'm currently using 0.51 in my current project and I quite like being able to easily add and remove authoring components. I haven't played with 1.0 much but it seems you're locked into using the baking system which limits this ability. It seems you need to create a new baker any time you want to make a change to what components an entity has. What I mean by this is you could have two entities with the same components, but if you want to change one entity then you need a new baker. Whereas before you'd just add/remove an authoring component.

    What also annoys me is that you can only create entities in a subscene. If you're using Unity.Entities, as I am, and not using the hybrid renderer or Unity.Graphics then any MeshRenderer you add to a subscene disappears. This is incredibly annoying. What if I want to create an entity from a GameObject and still keep the GameObject. Or what if I want to create an entity from a GameObject but want to render it at runtime using something like Graphics.DrawMeshInstanced and only use the GameObject to see the object whilst in the editor. This is easily accomplished with 0.51.

    Another thing, and this is most likely because I don't adapt well to change because I'm a simpleton, is the whole RefRO<T> RefRW<T> etc. For example RefRW<Spawner> spawner and then to change a value it will look like spawner.ValueRO.Time etc. If I'm already calling the spawner as ReadWrite then what's the point in getting a value as Read Only? (this was one of Unity's examples). Does it offer some kind of performance benefit? If not then it seems kind of pointless.