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

Add a standardized way to track simulation time for interoperability #13306

Open
NiseVoid opened this issue May 9, 2024 · 3 comments
Open

Add a standardized way to track simulation time for interoperability #13306

NiseVoid opened this issue May 9, 2024 · 3 comments
Labels
A-Networking Sending data between clients, servers and machines A-Time Involves time keeping and reporting C-Enhancement A new feature X-Contentious There are nontrivial implications that should be thought through

Comments

@NiseVoid
Copy link
Contributor

NiseVoid commented May 9, 2024

What problem does this solve or what need does it fill?

There is currently no universal way to track the time of a running simulation. If it's just needed in user code it's simple enough to create a resource that tracks the number of ticks since the simulation started and use some constant for timesteps. However, when third-party plugins get involved there is no good interoperable solution. Some crates provide their own type, resulting in some vendor lock-in. Other crates can be configured for where to source their time, making them harder to set up.

These types are further complicated by conflicting needs of different crates. A networking crate most likely has a counter it only needs to go up, but a rollback crate depending on that networking crate would need it to also go backwards.

What solution would you like?

A centralized way to track the time in a simulation. It could be a fairly simple type like:

type SimulationClock {
    tick: u64,
    timestep: Duration,
}

It could either be it's own thing or a variant for Time, as Time<Simulation>. Incrementing it could either be left up to the user, or configured in a more out-of-the-box way like deciding between FixedUpdate and the main loop depending on the app's runner.

The tick value could also be a newtype on u64 (or u32) so it's clear what these values mean if they are requested in function signatures or stored in other types (for example storing the tick on which an event happened).

What alternative(s) have you considered?

  • Add the counter to an existing resource, like Time<Fixed>, but this wouldn't be ideal for apps that run at a fixed rate without FixedUpdate.
  • Don't add an official way to do this and keep the fragmented approach without interoperability.
  • Create a third-party plugin that provides a type like this, and convince everyone to use it

Additional context

Here's a few crates that deal with some sort of simulation tick:

ggrs
bevy_replicon
lightyear
bevy_bundlication (disclaimer: I wrote this crate, the next version will likely also no longer have this type since it has been rewritten as a layer on top of bevy_replcion)

@NiseVoid NiseVoid added C-Enhancement A new feature S-Needs-Triage This issue needs to be labelled labels May 9, 2024
Shatur added a commit to projectharmonia/bevy_replicon that referenced this issue May 9, 2024
Third-party rollback crates need decrement operations. This is why they
using their own ticks and convert them back and forth. It's not
convenient.

Just providing decrement operations to resource would be weird since
user should never decrement it. This is why I made `RepliconTick` into a
simple struct and use a dedicated resource called `ServerTick` for
tracking current simulation tick.

See also bevyengine/bevy#13306
Shatur added a commit to projectharmonia/bevy_replicon that referenced this issue May 11, 2024
Third-party rollback crates need decrement operations. This is why they
using their own ticks and convert them back and forth. It's not
convenient.

Just providing decrement operations to resource would be weird since
user should never decrement it. This is why I made `RepliconTick` into a
simple struct and use a dedicated resource called `ServerTick` for
tracking current simulation tick.

See also bevyengine/bevy#13306
@alice-i-cecile alice-i-cecile added A-Time Involves time keeping and reporting A-Networking Sending data between clients, servers and machines X-Contentious There are nontrivial implications that should be thought through and removed S-Needs-Triage This issue needs to be labelled labels May 13, 2024
@alice-i-cecile
Copy link
Member

Can you explain why Time<()> doesn't meet the needs of networking crates here? This was intended to be a standard "in-game-time", which worked correctly both inside and outside of the fixed update loop.

@NiseVoid
Copy link
Contributor Author

There's a few issues, but the main ones would be:

  • You might be writing logic for an app that runs in either the FixedUpdate of a client or the Update of a server. But Time<Virtual> is not suitable to run a deterministic simulation.
  • None of the clocks is supposed to be turned back, but this is necessary when synchronizing the clocks as well as for things like rollback.
  • The units used for time are very unpractical for networked simulations, Duration is huge and difficult to deal with compared to a simple tick counter.

Even if someone decided to internally use Time<()> for their simulation tick, they would need to make a SystemParam containing a few other resources to work around these issues, this would in turn become yet another type lacking interoperability.

Adding this functionality to Time<()> would be another potential solution, but I'd imagine this would lead to confusing behavior with Time<Virtual> having ticks with a variable delta. It would also add one field that doesn't match with this line in the docs: The clock does not support time moving backwards, but I guess a Time<Simulation> would have the same problem.

@NiseVoid
Copy link
Contributor Author

If there's interest in this I could pick this up once we have an idea of what it should look like (eg. part of Time, a separate Time<Simulation>, or a simple stand alone resource + plugin similar to FrameCount). I'd imagine @maniwani also has some opinions on this, since it relates to fixed timestep simulations and networking stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Networking Sending data between clients, servers and machines A-Time Involves time keeping and reporting C-Enhancement A new feature X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
Development

No branches or pull requests

2 participants