Allow use of systems for custom time handling
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## What problem does this solve or what need does it fill?
Bevy is pretty great at handling time (`time.delta_seconds()` just working in both variable/fixed timestep is some nice UX that other engines don't really have) , but it'd be even better if users could simply take complete control of time for advanced usecases.
Time handling (especially fixed update) is still a bit clunky in a few noticeable ways.
- External events like input don't carry any timing information, so there's some aliasing happening.
- There is no automatic or built-in tool (such as interpolation) to smoothly render state that updates in `FixedMain`.
- Some users (e.g. networking plugins) would like to control when `FixedMain` runs but are unable to do so.
- Some users would like to disable `FixedMain` entirely but are unable to do so.
## What solution would you like?
Instead of going down the path of adding more parameters and preset[^1] behaviors to address these issues, Bevy could address the root problem of "time isn't configurable enough" by reworking `time_system` and `run_fixed_main_schedule` to call *other* systems that implement the actual behavior, e.g. based on "call this `Entity`" values stored in a publicly visible resource.
```rust
pub fn time_system(world: &mut World) {
let res = world.resource::();
let system_id = res.system_id();
world.run_system(system_id);
}
```
By turning `time_system` and `run_fixed_main_schedule` into dispatchers, a user could control how time is handled by creating their own "one-shot" systems and setting them as the systems that get called instead of the default ones.
[^1]: That being said, I do *strongly* recommend adding the behavior described in [#12465](https://github.com/bevyengine/bevy/issues/12465) as a preset for `Time`.
## What alternative(s) have you considered?
- The time plugin could keep packing more and more configurable parameters into "official" components/resources.
- I wouldn't like this solution because it puts the onus on Bevy to keep adding and documenting them.
- The time plugin could let users provide `time_system` and `run_fixed_main_schedule` as configuration.
- I wouldn't like this because it's important to be able to control the behavior at runtime. Other plugins or the editor might want to take control, not just the end user.
I think my proposed solution is more idiomatic and "ECS-y" (systems define behavior) and would let Bevy draw a clear line between "simple" and "advanced" configuration. Any behavior that isn't baked into one of the `Time` structs would become "advanced use" that users can achieve by overriding the default targets.
## Additional context
IMO this is sort of a logical continuation of #8964. That one made whoever's calling (`Main` or `FixedMain`) transparent to the systems that are called. This would makes whoever's advancing `Time` and calling `FixedMain` transparent.
Contributor guide
Research direction
Start by reading the existing time_system and run_fixed_main_schedule entry points, then review the related discussions in #8964 and #12465. Determine how the default behavior could be dispatched through publicly configurable systems while preserving normal time handling. Done means users can replace the time advancement and fixed-schedule behavior at runtime without losing the defaults.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100