bevyengine / bevyengine/bevy

Allow use of systems for custom time handling

Open
#15,455 1 comment 2 reactions 0 assignees View on GitHub
A-Time C-Feature D-Modest S-Ready-For-Implementation
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.