Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API for dynamic management of systems (adding and removing at runtime) #279

Open
inodentry opened this issue Aug 21, 2020 · 10 comments
Open
Labels
A-ECS Entities, components, systems, and events C-Enhancement A new feature

Comments

@inodentry
Copy link
Contributor

It would be great to have a way to remove and add systems to the ECS as the game is running.

@MNTRA
Copy link

MNTRA commented Aug 22, 2020

Agreed, maybe a version of add_system(...) that also takes a predicate that only runs the system if the predicate returns true?
Something along the lines of this.

    app.add_system_with_pred(my_system.system(), |my_resource| {
           /* code that returns bool */
    });

@TehPers
Copy link
Contributor

TehPers commented Aug 22, 2020

I know there's been discussion of the possibility of multiple schedulers, or having systems run based on some kind of condition. Related: #128

@karroffel karroffel added A-ECS Entities, components, systems, and events C-Enhancement A new feature labels Aug 22, 2020
@Ratysz Ratysz mentioned this issue Aug 22, 2020
@alice-i-cecile alice-i-cecile added the S-Needs-Design-Doc This issue or PR is particularly complex, and needs an approved design doc before it can be merged label Dec 12, 2021
@alice-i-cecile
Copy link
Member

Agreed, maybe a version of add_system(...) that also takes a predicate that only runs the system if the predicate returns true?

"Run criteria" is the name for the tool that we ended up using for this.

#2507 is an initial attempt to add support for true dynamic schedule modifications.

@inodentry
Copy link
Contributor Author

Well, "true dynamic schedule modifications" would be infinitely more flexible than run criteria. Makes sense to keep this issue open for that.

@alice-i-cecile
Copy link
Member

From #2192 by @cart:

To add to this: I think we should have a way to queue runs of systems (in the same stage as the queuing system or some future stage) via their labels. This is slightly different than disabling and enabling at runtime, because queuing twice should result in two runs of the system.

(I agree with this position, I'm cross-posting it here so we can track the feature requirements a bit better) for #2801.

@alice-i-cecile
Copy link
Member

Closing as duplicate of #2192 + #142.

@alice-i-cecile
Copy link
Member

That was a mistake; this is much better scoped than #142...

@Escapingbug
Copy link

It seems we still lack the dynamic removing systems ability. Is that planned to be implemented?

@alice-i-cecile
Copy link
Member

It's controversial, but we're leaning towards including it with warnings on the performance cost of doing so.

@alice-i-cecile alice-i-cecile added this to the 0.11 milestone Feb 16, 2023
@alice-i-cecile alice-i-cecile modified the milestones: 0.11, 0.12 Jun 19, 2023
github-merge-queue bot pushed a commit that referenced this issue Sep 19, 2023
I'm adopting this ~~child~~ PR.

# Objective

- Working with exclusive world access is not always easy: in many cases,
a standard system or three is more ergonomic to write, and more
modularly maintainable.
- For small, one-off tasks (commonly handled with scripting), running an
event-reader system incurs a small but flat overhead cost and muddies
the schedule.
- Certain forms of logic (e.g. turn-based games) want very fine-grained
linear and/or branching control over logic.
- SystemState is not automatically cached, and so performance can suffer
and change detection breaks.
- Fixes #2192.
- Partial workaround for #279.

## Solution

- Adds a SystemRegistry resource to the World, which stores initialized
systems keyed by their SystemSet.
- Allows users to call world.run_system(my_system) and
commands.run_system(my_system), without re-initializing or losing state
(essential for change detection).
- Add a Callback type to enable convenient use of dynamic one shot
systems and reduce the mental overhead of working with Box<dyn
SystemSet>.
- Allow users to run systems based on their SystemSet, enabling more
complex user-made abstractions.

## Future work

- Parameterized one-shot systems would improve reusability and bring
them closer to events and commands. The API could be something like
run_system_with_input(my_system, my_input) and use the In SystemParam.
- We should evaluate the unification of commands and one-shot systems
since they are two different ways to run logic on demand over a World.

### Prior attempts

- #2234
- #2417
- #4090
- #7999

This PR continues the work done in
#7999.

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Federico Rinaldi <[email protected]>
Co-authored-by: MinerSebas <[email protected]>
Co-authored-by: Aevyrie <[email protected]>
Co-authored-by: Alejandro Pascual Pozo <[email protected]>
Co-authored-by: Rob Parrett <[email protected]>
Co-authored-by: François <[email protected]>
Co-authored-by: Dmytro Banin <[email protected]>
Co-authored-by: James Liu <[email protected]>
@alice-i-cecile alice-i-cecile removed this from the 0.12 milestone Sep 20, 2023
@alice-i-cecile alice-i-cecile removed the S-Needs-Design-Doc This issue or PR is particularly complex, and needs an approved design doc before it can be merged label Sep 20, 2023
rdrpenguin04 pushed a commit to rdrpenguin04/bevy that referenced this issue Jan 9, 2024
I'm adopting this ~~child~~ PR.

# Objective

- Working with exclusive world access is not always easy: in many cases,
a standard system or three is more ergonomic to write, and more
modularly maintainable.
- For small, one-off tasks (commonly handled with scripting), running an
event-reader system incurs a small but flat overhead cost and muddies
the schedule.
- Certain forms of logic (e.g. turn-based games) want very fine-grained
linear and/or branching control over logic.
- SystemState is not automatically cached, and so performance can suffer
and change detection breaks.
- Fixes bevyengine#2192.
- Partial workaround for bevyengine#279.

## Solution

- Adds a SystemRegistry resource to the World, which stores initialized
systems keyed by their SystemSet.
- Allows users to call world.run_system(my_system) and
commands.run_system(my_system), without re-initializing or losing state
(essential for change detection).
- Add a Callback type to enable convenient use of dynamic one shot
systems and reduce the mental overhead of working with Box<dyn
SystemSet>.
- Allow users to run systems based on their SystemSet, enabling more
complex user-made abstractions.

## Future work

- Parameterized one-shot systems would improve reusability and bring
them closer to events and commands. The API could be something like
run_system_with_input(my_system, my_input) and use the In SystemParam.
- We should evaluate the unification of commands and one-shot systems
since they are two different ways to run logic on demand over a World.

### Prior attempts

- bevyengine#2234
- bevyengine#2417
- bevyengine#4090
- bevyengine#7999

This PR continues the work done in
bevyengine#7999.

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Federico Rinaldi <[email protected]>
Co-authored-by: MinerSebas <[email protected]>
Co-authored-by: Aevyrie <[email protected]>
Co-authored-by: Alejandro Pascual Pozo <[email protected]>
Co-authored-by: Rob Parrett <[email protected]>
Co-authored-by: François <[email protected]>
Co-authored-by: Dmytro Banin <[email protected]>
Co-authored-by: James Liu <[email protected]>
@hymm
Copy link
Contributor

hymm commented Jan 23, 2024

I think a fairly uncontroversial first step towards this is to add a method to Schedule to get a Vec's using a SystemSet label. The next step after that would be to try and use that method to remove those systems. The tricky bit here is what to do it that set is connected to other systems. I suspect we'll want some configuration here to by default return an error, but let people ignore the error and remove the dangling edges when wanted. Probably some complexity here around plugins that we'll need to iterate on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Enhancement A new feature
Projects
Status: Needs Implementation
Development

No branches or pull requests

7 participants