Replies: 6 comments 19 replies
-
Might be interesting to look at this issue and particularly this specific comment by AlphaModder (don't forget to unfold the folded code at the bottom of the comment) for how Commands might fit into the scheduling part of this. Edit: It seems you're already doing something like it. One comment I have on the code example is that the ergonomics as written are not good. The extra type parameters such as |
Beta Was this translation helpful? Give feedback.
-
Hmm, this looks very promising but right now, the boilerplate looks just too much :( The added control of systems being piped in handles is also a double-edged sword. On one hand, it helps in managing side effects and understandably, but on the other hand I feel like it could quickly lead to plumbing mess, as when a system decides it needs a component / resource and suddenly it needs to be piped through 3 modules to get it there. |
Beta Was this translation helpful? Give feedback.
-
First: this is very cool! Buuut this appears to be a pretty major digression from the bevy app model, in that it aims to undo "inversion of control" from the public api while still using it in the internal schedule execution. There are definitely benefits, especially for single-plugin use cases, but in a "modular" context I think this starts to create problems. When a system needs an AssetServer reference, instead of just saying "give me the AssetServer" using |
Beta Was this translation helpful? Give feedback.
-
I've spent some time poking around and trying to figure this out, but I still can't definitively answer this question: what problem does this solve? In the "Why is this useful?" section of the docs:
What does this mean, exactly? What is different in
This seems to be contrasted with current "order is not defined unless you explicitly define it" approach, and advocating a regression to the previous overly-restrictive and rigid model that implicitly preserved the order of insertion of systems in their order of execution. In fact, the whole endeavor feels like a way to build that again on top of the new model. |
Beta Was this translation helpful? Give feedback.
-
So, I finally have time to give this a proper look. I share the concerns about weak / unclear motivation and boilerplate, but I'm open to being convinced :)
My intuition is that this is true for very small programs, and actively false for large ones. Unfortunately, it's impossible to achieve perfect modularity. As a result, your high-level units of code (plugins, in Bevy's case) end up having subtle cross-dependencies. By encoding these dependencies into the order in which these high-level dependencies are composed you a) reduce flexibility to solve issues (what if some of A needs to run before competitors in B, but the opposite is also true) and b) increase implicit mental overhead (oh wait this only works because x <: X and y :< Y and X > Y) and c) increase fragility (good luck refactoring safely when there are huge implicit dependencies cutting across your code base). For quite a few use cases (e.g. scientific simulation, rollback networking, ironing out tricky bugs), I am convinced that full schedule determinism is a critical goal. However, the three obvious ways to do this are all woefully inadequate at scale. The first, to implicitly resolve ambiguities based on system ordering, has been tried with poor success, as outlined above. The second is to just run everything in sequence. This again struggles due to overspecification issues, creating boilerplate and causing fragility, as it doesn't map cleanly onto the reasons why you need that particular order. Of course, this also comes with a huge performance hit. The final obvious option is to just run the ambiguity checker and arbitrarily insert dependencies between pairs of systems (and explicit ambiguities for where you know it "should be impossible for them to conflict"). The problems with this approach though are:
Pulling this together, I think scheduler determinism is a worthy goal (for some users), but the core challenge is ensuring that your model that describes the data flow dependency graph corresponds tightly with why it must be that way. Mess that up, and your code base becomes opaque, implicit and fragile. |
Beta Was this translation helpful? Give feedback.
-
CommandsI agree, the current "commands can do anything!" model poses serious issues for both ergonomics (due to the necessarily delayed effects) and code readability (well this system takes in Commands so who knows what it might do...). I think this is important to improve. Derived dataThis is a promising angle: I'd very much like this for a number of features (namely indexing). I worry about the scheduler costs in terms of overhead and complexity, but I think this could be killer. TablesI am very nervous that this isn't a great model for many games, and will result in a lot of gnashing of the teeth well into the development cycle. I can certainly see the value (see #1481 after all!), but I'm not convinced by the model.
To me, this is throwing away one of the most powerful advantages of the ECS: the ability to dynamically compose behavior across wildly disparate types of game objects in a trait-like way. Either you make this extremely broad (in which case it has very minimal safety benefits) or narrow enough to enforce invariants appropriately, at the risk of code duplication. I worry that this ends up in the same place OOP game object models do: with a handful of unopinionated Mega Classes, into which all behavior is shoehorned. Like with the scheduling API, this feels like a leaky abstraction: appealingly simple, and then endlessly frustrating when you get into the messy details because it doesn't track the reasons why things must be that way as tightly as it should. |
Beta Was this translation helpful? Give feedback.
-
Hi all,
Recently, I've been collecting ideas and notes on aspects of the Bevy ECS API related to scheduling and ordering of systems. I'd like to convert these into a series of RFCs, but first, I created a proof of concept implementation, in order to convince myself that the whole set of ideas together was cohesive and implementable. I hope it will also be interesting to others.
You can find the code here. Docs can be built with
rustdoc
or found in the repository.The most important principles behind the design are:
Resource
andComponent
has a single owner that takes responsibility for managing it. Other code must be passed a handle to the data.An important point about the implementation is that it's a layer on top of
bevy_ecs
. I think this is a solid technical direction, because it allows some decoupling between the two crates:bevy_ecs
can focus on organizing data for efficiency and high performance, whilebevy_flow
provides a nice high-level API. Once scheduling is complete, there should be virtually no overhead frombevy_flow
.As a bonus,
bevy_flow
also contains proof of concept implementations of entity tables and derived data (aka indexing), built on the foundations above (@alice-i-cecile, I know you are interested in derived data).I'd be interested to hear what others think about this direction, and particularly interested to hear feedback if anyone experiments with the API. I'm especially interested in the overall structure and organization -- I expect that names and function signatures will change in the RFC process.
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions