Comments (10)
My overall take on this is that trying to control all possible points where your entity could be despawned is not feasible. If you're setting an OnRemove observer, you need to be prepared for the consequences that it could be triggered at any point in the frame.
If you add StateScoped
to an entity and then use OnExit
to perform cleanup, you are explicitly opting into a States-oriented data management model. The fact you can't clean up the side effects of StateScoped
within that framework is the fundamental problem.
And better docs are needed to make sure this is communicated.
Docs are great, but it doesn't solve the underlying ambiguity. This ambiguity makes it A) harder to use the States
API correctly, B) harder to compensate for problems caused by writing less-than-perfect code (such as OnRemove
side effects causing bugs).
from bevy.
Another thing, we can add an OnAdd
hook to StateScoped
that will check the state and remove the entity if it's incorrect.
This compliments the existing on-exit behavior by doing on-spawn validation.
from bevy.
Can you provide a more concrete example? What is the OnRemove
observer doing and what is it racing with? Not being able to despawn entities in OnExit(..)
seems problematic, if I'm reading this correctly.
from bevy.
Can you provide a more concrete example?
I hesitate to get too deep into an example, which often ends up with someone saying 'but don't do it that way'. OnRemove
observers can have a lot of side effects: sending events, mutating entities, mutating resources. The example I have in mind is something thrown together for a jam game - attackable entities can drop stuff on the ground when they die. I despawn entities when they die and use an OnRemove
observer to extract the info about what should be dropped. Since observers can't spawn anything, I use a normal bevy event to send that info into another system that spawns drops. Is it possible to redesign this to not use observers? Yes. But it's an intuitive pattern that many users will discover and implement in the future.
The 'recommended' pattern for games is to use states to transition between menu and gameplay (back and forth repeatedly). This means it's important for nothing to leak between sessions, including all OnRemove
side effects from StateScoped
entity cleanup (which I think unavoidably has the to be 'the way' to cleanup entities on state transition - no manual despawning in OnExit
unless you can guarantee no side effects).
It's certainly possible (and maybe even generally better) to perform cleanup in OnEnter
when re-entering a state as part of state initialization, and only use OnExit
to collect information that should be passed out of the state. However, the library can't enforce that and users may have good reasons to do cleanup in OnExit
.
from bevy.
I will say "don't do it that way" for this case because despawning != dying, and you ought to clear any lingering "spawn drops" events on exit as well (unless you can guarantee that the events will always be handled in the same frame after they're sent, which would be better practice anyways). This sounds to me like a logic issue similar to system ordering bugs that are difficult to track down but still the user's responsibility to fix.
That's not to say that there isn't a usability footgun here or maybe an actual scheduling issue, that a different example could elucidate, or again maybe I'm missing something.
It's certainly possible (and maybe even generally better) to perform cleanup in
OnEnter
when re-entering a state as part of state initialization, and only useOnExit
to collect information that should be passed out of the state.
All cleanup should go in OnExit
, so I wouldn't suggest otherwise. The primary purpose of the separate schedules is to guarantee that tearing down the previous state occurs before setting up the next state. As for whether e.g. setting a resource to its default value counts as "setup" or "teardown", that may not always be immediately obvious I guess.
from bevy.
My overall take on this is that trying to control all possible points where your entity could be despawned is not reasonable. If you're setting an OnRemove
observer, you need to be prepared for the consequences that it could be triggered at any point in the frame. And better docs are needed to make sure this is communicated.
from bevy.
I added a prototype of state scoped events here.
from bevy.
We didn't design states with observers in mind, they were still in development back then.
Something we can consider is moving the entire state architecture to observers, but this is quite a big change that I don't think is worth it until we unify all 3 state traits.
from bevy.
Something we can consider is moving the entire state architecture to observers, but this is quite a big change that I don't think is worth it until we unify all 3 state traits.
This seems pretty risky from a conceptual model standpoint and it's pretty unclear how it would even work. And also unclear what it would specifically do to help the StateScoped -> OnRemove
issue.
from bevy.
Another thing, we can add an
OnAdd
hook toStateScoped
that will check the state and remove the entity if it's incorrect. This compliments the existing on-exit behavior by doing on-spawn validation.
This is off-topic for the issue, but I don't believe that's the correct complementary behavior. The current behavior is "despawn on exit", so its complement would be "spawn on enter", which would be genuinely useful but is blocked on the better scenes work. As another example, "show on enter" + "hide on exit" is already possible.
from bevy.
Related Issues (20)
- Diagnose failure of crate-level #![expect()] in the project, then replace #![allow()] with #![expect()] HOT 4
- `create_handle_internal is too complex
- Fix doc link import style to avoid unused_imports
- Use `StableInterpolate` in the camera examples
- Replace `Trigger`'s default bundle filtering behavior from an OR to an AND HOT 2
- Many `elided lifetime has a name` warnings
- Allow filters to take a `Bundle` instead of a singular `Component`, and make the conjunction behavior configurable HOT 5
- Border vs TextureSlicer flickering HOT 1
- Fix `ObserverSystem` docs
- error: linking with `cc` failed: exit status: 1 HOT 4
- `OverflowAxis::Clip` allows UI node contents to spill over the border HOT 3
- add a no-std platform target to CI HOT 1
- Move ShortName to bevy_reflect
- Remove `bevy_utils::default`
- Bevy app with `pbr_transmission_textures` crashes on macOS/Metal after PCSS PR merge HOT 2
- Asset locking HOT 1
- Moving components out of an entity by ids HOT 1
- `ShortName` should work without depending on bevy_reflect HOT 1
- `DirectNestedLoader::load` sometimes uses asset type's default loader instead of inspecting path
- simple_picking.rs example has an observer on a 3d mesh but no picking backend HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bevy.