Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Feedback [1.0.14] Full ECS Review

Discussion in 'Entity Component System' started by DreamingImLatios, Aug 18, 2023.

  1. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    [1.0.14] Full ECS Stack Review
    Hi everyone,

    Entities has been out of preview for a little while now, and it is about time for another one of these reviews. As a reminder:

    This feedback is addressed specifically at all of you at Unity. I don’t expect each of you to read all of this. But I hope you at least read the stuff relevant to each of your individual teams.

    If you are just looking for a list of things to fix that would make me happy, look here. That’s my wishlist of features, some being very low-hanging fruits. I will try to avoid repeating myself in this review, so be sure to check those out if you want actionables.

    In addition, I’m going to avoid discussing design choices for things I decided to re-implement in my framework. If you want some fresh perspectives on workflows and some ideas for alternate ways of doing things, reach out to me. I don’t charge.

    General Feeling
    Entities 1.0 continues the Unity tradition of releasing a 1.0 that is still a little rough, missing features, and has a few design shortcomings that all make it feel unfinished. When you dig into the internals, there’s a lot of really good machinery. But on the surface, it is very rough and difficult to accomplish things. This is why many projects that are having success with ECS either have asmrefs or are using a package that uses asmrefs. There’s a lot of really good tech, but the out-of-the-box experience is not that great. With that said, the current state of things are much better since my last review, and I find myself mostly unblocked and working with exceptional velocity.

    My Biggest Pain Point
    AudioClip.GetData() inside a baker crashes subscene imports, which then drags down the entirety of Unity. It doesn’t happen on every computer, but it happens on mine, and it happens on others’ as well. This can be reproduced with just the Entities package and a single baker script. No DSP Graph. No trying to even play sound.

    I’ve had and reported variants of this crash ever since subscenes were introduced. At this point, I don’t even know who I’m supposed talk to. QA hasn’t made any real effort to try and reproduce the issue. And the ECS community is still too small for them to see any pattern in things breaking. Everyone is afraid to even try the tech I share because they don’t want the crashes, so very few others are even reporting the issue.

    Honestly, if this is the only thing you take action on in this entire post, I’ll be ecstatic.

    Mathematics
    No math library is perfect. But this one works well enough for me. I don’t really have anything else to say about it.

    Burst
    I know your team has really thinned out a lot, and consequently releases are a lot slower than they used to be. I can imagine it is hard to find people with the level of excellence your team strives for. As a consequence, I imagine it must be tough keeping up with engine changes and fixing all the regressions with caching jobs and preserving iteration times. And for some people, that’s degraded to a point of frustration. I’ve been very fortunate for the most part.

    What I really appreciate from the team is every time I want a performance feature, I end up getting it. I’ve asked for branch hints. I’ve asked for runtime-determined shuffle patterns. By the time I asked for atomic bitwise AND and OR operations, it was already there behind a scripting define. And by the time I asked for default interface method support, it was already being worked on.

    I must say, the release notes for 1.8.8 are absolute fire! Default interface methods, improved domain reloads, and string interpolation in exceptions are all absolutely amazing!

    There are still a couple areas for further improvement if you need new feature ideas. The first is that for a large job, it can be difficult to navigate. A job of this size is broken up into a bunch of different functions. I wish I had a side-panel on the right that showed a list of all these functions and allowed me to jump to each of them.

    Second, can we get a Hint.AssertAssume()? The big difference being that when safety checks are enabled, it asserts, otherwise it assumes? I’m always paranoid about the Assume() causing Burst to optimize out the assertion.

    And lastly, while I’ve provided my wishlist, I also want to ask for the reverse. I’d like to know Burst’s wishlist. I’d imagine that as it is compiling code, there are certain pointers or integer values where it wants to optimize something but can’t because it doesn’t know enough about the data. I’d love to be able to click a button and have it calculate a full report of all these things so that I can insert Assume() statements. Often times I find myself writing Assume() statements that don’t change the Burst output at all.

    Regardless, thanks for all the hard work you put into this amazing piece of tech, and please keep doing awesome things!

    Collections
    These have gotten very good and comprehensive. Seriously, great job!

    There are still a few points of friction, such as trying to set 0 bits in a BitField64 or the inability to bulk-write in NativeStream without messing up the element count.

    But at this point, I think my biggest desire is for per-thread rewindable allocators that can be rewound in the job. Both bump and stack allocators would be awesome. The use case is for heavy jobs that require lots of allocations that would balloon the Temp allocator when a lot of those allocations could be reused, reducing memory usage and L2 pollution.

    I have a couple of other entries in my wishlist. But overall, this is another package done well and leaves little to be desired.

    A couple of questions where the documentation failed me:

    Is there any rhyme or reason to the return value of UnsafeUtility.MemCmp when the byte arrays are not equal? Could they be used for sorting to speed up matching algorithms?

    How expensive is JobsUtility.ThreadIndex when called from Burst? Is it something we should aggressively cache? Or is it fairly lightweight? I suppose I could profile, but I think there should be something in the documentation as to why we might prefer [NativeSetThreadIndex] instead.

    Entities Baking
    Baking is where the most dragons of the Entities package live. Baking systems are extremely difficult to get right. I cringe every time I see their use in an example because the example is nearly always very easy to break with Ctrl+Z.

    Hybrid is still a disaster that requires some sort of hack one way or another, and I really want a supported hook for overriding the bakers and baking systems rather than rely on reflection hacks or disable an entire assembly. Also, Burst?

    I have lots of things on the wishlist with regards to baking, so if you want to make things better, go through that and don’t hesitate to ask questions.

    With all that said, I’m continuing to find ways around the limitations of baking to build robust baking solutions.

    Aside from that stupid evil audio crash, baking is very stable for me now. If anything goes wrong, I can usually just reimport a subscene to get everything back on track.

    Entities Editor
    Exceptions. Exceptions everywhere. Most of the time, the exceptions are harmless. But sometimes the EntityManager gets lost and the entire Editor becomes an unusable mess.

    I personally don’t find journaling useful most of the time. It is inconsistent as to what gets journaled and what doesn’t. Also, sometimes the live mode setting for the Entities hierarchy sticks, and sometimes it doesn’t. I don’t know why.

    Most of the windows are helpful. Though there is a lot of having to click on things just to see what it is, whereas little balloons with some essential identification details would make navigation a lot faster. This is especially true for queries in systems, though there are lots of instances of this sort of thing.

    There are two things I would like to be able to do. First, I want to be able to create custom inspectors for components, blob assets, and aspects without asmref hacks. Second, I would like to be able to generate a custom tree-view for entities, via a Burst job, and then be able to select different tree-views in the Entities Hierarchy window.

    I guess I should also mention I have a hack to replace the editor world with one provided by an ICustomBootstrap-like interface. Why is this not an official thing?

    Overall, I’m glad what exists exists. But I still feel like this is one of the weaker links.

    Entities Runtime
    The Entities runtime is actually pretty amazing in all but two cases:

    · When there’s a hack

    · When it thinks it is smarter than you

    When neither of those are at play, the power and control and the layers of scaffolding are honestly a joy to work with. I accomplish precisely what I want without fail. Projects stay organized, performance stays spectacular, I’m very very happy!

    However, there’s some rough spots that totally sour the experience. A good amount of my framework tech addresses these issues. But you should really read the wishlist if you want a detailed list of problems. A good number of items there pertain to Entities runtime.

    The two newest features introduced with 1.0 are powerful, but the most incomplete. Those being IAspect and IEnableableComponent. IEnableableComponent completely made a mess of queries. IAspect is missing SystemAPI helpers for Lookup and TypeHandle (nevermind the fact that most people don’t even know these exist). And Lookup is missing the Exists(), TryGet(), and other such APIs.

    There’s also some other small missing APIs which you can find in the wishlist.

    I can safely say I understand singletons now, and why they behave the way they do with collections. You realized that singletons were a hack that you didn’t believe you could fix, and then you needed collections on components which you didn’t have time to design properly since by that point you were rushing out 1.0, so you put a hack on top of a hack because it was already a hack. Touché.

    Scenes
    The SceneSystem static API is very much a black-box API. While comprehensive, it does a lot of hidden structural changes and other manipulations that can make it tricky for a new user to know what is going on. It is unclear which components should be messed with directly, versus which should be managed by the static APIs. Also the fact that you put all the static APIs in a system is confusing, and conflicting with any messaging about preferring to avoid accessing other systems directly.

    I don’t have an issue with its supported functionality, but I think there is much to be improved with the API.

    Transforms
    Transforms have had a rocky history with Unity. It has gotten so bad, that now the Physics and NetCode teams are screaming “Transform hierarchies are evil!”

    Here’s an idea, instead of spreading propaganda, maybe make transforms good.

    Good transforms mean flexible update mechanisms, race-free swapping of parents and updating change versions, fast update performance by taking advantage of ECS strengths, and designing the data so that Physics and NetCode can work with it better, being efficient with chunk data usage (80 bytes Child?).

    This is possible. You don’t have to be afraid of transform hierarchies. They can be good and powerful in an ECS. Stop the propaganda and put in the effort to really make them good and useful for gameplay.

    With that criticism said, the existing version of Transforms is better than all of the previous iterations now. It is good enough that I can at least make a functional mode in my framework to support it (with caveats). Thank you for at least fixing rotation extraction from LocalToWorld.

    Graphics
    It is difficult for me to discuss Entities Graphics. On one hand, I learned a lot about how to do advanced ECS things from this package. On the other hand, my heavily-modified version is significantly faster and has dozens more features, so there’s clearly room for improvement.

    My wishlist has a few items, mostly engine side. But honestly, I’m pretty content with what I have. If you ever want to chat to see what I did or discuss possible engine-side changes, feel free to ping me!

    At this point, it is hard for me to give any sort of rating on the current state of Entities Graphics, because I did fix a lot of stuff. But what I do know is that the fundamental concepts are rock solid, because I built on top of them to make something absolutely killer.

    Also, am I the only one who thinks it is weird how skinned mesh rendering is “experimental” in a 1.0 release without being guarded by an experimental namespace or scripting define?

    Physics
    Here’s the thing with Unity Physics. If it solves your problem, it works great. But as soon as it doesn’t, it becomes a brick wall of a dead end that you have to throw some heavy-duty hacks at to smash through. I think you converged too fast on a solution that is too rigid.

    The four common complaints I hear about Unity Physics are as follows:

    · Need a Pro License for stable stacking with Havok

    · Editor breaks frequently

    · Transform hierarchies don’t work

    · Performance sucks because it does calculations that aren’t actually necessary but can’t be turned off because the controls are baked into blob assets or other reasons

    However, I’ve been told that what I am doing is “unlike any other physics engine”, so we’ll see where we end up. I will say that Unity Physics development seems stagnant as of late.

    Overall, mileage varies wildly.

    Character Controller
    I think my biggest complaint with this is that it uses Unity Physics. Otherwise, there’s bits and pieces that are a little clunky, but overall it is very extendible and modular. I can’t identify limitations on the surface. I’d probably have to be deeply invested to identify anything. I wish more Unity features were this flexible.

    I have heard concerns that the character controller is a bit heavy, and I definitely have seen it in profile captures. But I don’t know if that’s a fundamental issue or a user error. I think this package would benefit from a guide that walked through step by step of building a character controller, incrementally adding features and explaining where such features go and why.

    A lot of people ask me how to make my tech work with this character controller package. They hardly care about Unity Physics simulation, but this package is just that good. Nice job!

    NetCode
    Admittedly, I still haven’t gotten around to deep-diving with NetCode, but I do get rants about it on a weekly basis.

    I think I can safely give one major criticism based on the rants, discussions, and the little investigation I have done. NetCode is very invasive! It completely dominates everything about your game, and if your game functions with it, then it won’t function without it. That makes spawning and despawning and managing presentation effects very difficult, because NetCode lives inside the simulation that is trying to drive these things, and puts extreme restrictions on these things as well.

    I think when I really try to use it (my plans got delayed), I’m going to try to isolate it from the actual simulation. It will be a good test of the flexibility of interpolation control. I’ll probably have lots of questions on the forums, because I’ve been told I won’t find answers in the documentation.

    Hopefully I won’t run into build issues. I’m pretty cursed when it comes to dev ops, and I’ve heard horror stories about builds not working.

    But all of this is through a very biased lens. Let’s hope reality is actually very flexible for someone detail-oriented.

    DSPGraph
    This experimental package hasn’t been touched for a while. But you know what? It works. Nevermind the audio issues I mentioned earlier, this one isn’t the cause. I know this because one of my projects doesn’t use AudioClip at all and instead does everything procedurally, and DSPGraph just works!

    The API is a bit rough, and I am converging on a single mega-kernel design. But it provides the performance-friendly hooks I need to get things done, and that’s good enough for me!

    There is one issue I found where if I create a graph, and then never pipe actual audio through it before tearing it down again, sometimes domain reload gets permanently stuck. It gets stuck somewhere deep in the C++ according to VTune.

    There’s also a buffer underflow race condition somewhere on shutdown. That one is in the package somewhere, so if it becomes a major problem I’m willing to fix it myself.

    Overall, I don’t really understand what Unity audio is doing, because this tech is cool and promising and way more practical than whatever they are doing now.

    Final Thoughts
    I’m a bit scarred from the 1.0 experimental saga. But I am enjoying the API stability and am able to move very fast now. I think vanilla ECS is far from production-ready and probably needed one more year to mature. But with third parties in the picture, it is definitely usable today.

    I want to thank all the developers who pay attention to my concerns as well as others on these forums and other channels. I know you all have your own opinions, and I know I’m not always pleasant when I am frustrated and some of the things I do are probably frustrating to you too. But this is still the shortest road to the tech I dream of, and I have you to thank for getting me that much closer! Any of you are welcome to reach out to me at any time via forums or Discord! Though I do typically sleep when a lot of you work.

    And as always, thanks for making it to the bottom of this wall of text! If you have thoughts, feel free to reply and share them!
     
  2. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    228
    @DreamingImLatios do you have an IN-***** bug number I could brandish internally about the audioclip business? Doesn't matter if they failed to repro it or rejected it or whatever.
     
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    IN-18952

    If you need a much more simplified repro with just the Entities package and a single Baker like I did for IN-8080 with conversion, let me know!
     
    layker90524 and elliotc-unity like this.