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 global time scale for all effects #267

Merged
merged 13 commits into from
Mar 5, 2024
Merged

Add a global time scale for all effects #267

merged 13 commits into from
Mar 5, 2024

Conversation

jannik4
Copy link
Contributor

@jannik4 jannik4 commented Jan 14, 2024

Add a global time scale for all effects. Currently very WIP. Probably needs:

  • Some tests/examples
  • More docs

Now reimplemented (and documented) using the Time<T> resource from bevy.

(Could still need some examples/tests when we have settled on the design)

Closes #239. Pausing should be possible by setting EffectTimeScale to zero.

Comment on lines 1346 to 1347
sim_params.time += ***time_scale * time.delta_seconds_f64();
sim_params.delta_time = (***time_scale * time.delta_seconds_f64()) as f32;
Copy link
Owner

@djeedai djeedai Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this essentially re-implementing partially Time<T>? Could we instead simply use Time<EffectSimulation>? See my comment on #239 for details.

Copy link
Contributor Author

@jannik4 jannik4 Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like yes, just had a proper look at Time<T> for the first time. Something like Time<EffectSimulation> seems like a good idea then.

I would be happy to try to implement this. I can then imagine a total of three "Time/Delta Time" values:

  • sim_params.real_time: From Time<Real>
  • sim_params.virtual_time: From Time<Virtual>
  • sim_params.time: From Time<EffectSimulation>

Where Time<EffectSimulation> is then a scaled version of Time<Virtual>. This would allow pausing/scaling time by both bevy's Time<Virtual> and by hanabi's Time<EffectSimulation>. All built in shader code would then use sim_params.time, but users can also use the other two versions.

This should be quite flexible. (But also adds a bit complexity)

Alternatively, you could of course leave out sim_params.real_time and sim_params.virtual_time for now and only add them if someone really needs them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation wise this seems pretty straight forward:

  • bevy provides virtual_time_system
  • So we can then just update Time<EffectSimulation> after that by Time<Virtual>::delta()

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds all good to me. SimParams is small and uploaded once per frame, not per effect, so I'm totally fine adding more stuffs to it (including real/virtual times). Chances are, with DMA copy alignment (256 bytes?) we're already copying zeros instead at the minute, so it will make no difference.

@jannik4 jannik4 marked this pull request as ready for review January 16, 2024 23:01
@jannik4 jannik4 requested a review from djeedai January 17, 2024 00:58
Copy link
Owner

@djeedai djeedai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good overall but there's a number of small issues I think. Maybe some test would help validate the behavior here? Thanks!

src/time.rs Outdated
// avoid rounding when at normal speed
virt_delta
};
effect_simulation.context_mut().effective_speed = effective_speed;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand, effective_speed was read directly from the simulation clock, and is re-written back into it, but doesn't seem to be affected in any way by the virtual clock. Is this missing some * virtual_speed somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

effective_speed is a local variable a few lines above and is set depending on paused and relative_speed.

effective_speed is just zero when paused and relative_speed when running. It is and should be independent of the virtual time.

The only thing that is dependent on the virtual time is the resulting delta for that frame.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but Virtual is a self-contained clock whereas this one is based on Virtual. What is strange to me is that we document "the final speed is the product of the two clock speeds" but then when we calculate we only store this clock speed in effective_speed, not the product. So it's "effective" because it takes into account pausing, but it's still not "effective" as in being the final value used in practice.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't compare with Bevy code, there's no clock in Bevy which is relative to another clock as far as I know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the time code is literally copy-pasted from Time<Virtual> and adapted (e.g. remove clamping).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I think I see your point: Because Time<Virtual> already has time scaling.

Copy link
Contributor Author

@jannik4 jannik4 Feb 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should fix it: 1f9a23e

Edit: Also updated the docs now.

@@ -800,7 +800,7 @@ mod test {
// app.add_plugins(DefaultPlugins);
app.init_asset::<Mesh>();
app.add_plugins(VisibilityPlugin);
app.init_resource::<Time>();
app.init_resource::<Time<EffectSimulation>>();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd assume this also needs init_resource::<Time>() since we need the base Virtual time. This is an emty app for testing, so won't have Time by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Time is not need as the time is advanced manually in the tests. (It was the same before, I didn't change anything there)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok and we don't insert the effect_simulation_time_system system so we don't need to read Time<Virtual>.

@jannik4
Copy link
Contributor Author

jannik4 commented Feb 26, 2024

Rebased on main and added a test for the effect simulation time. Could you take another look at this, @djeedai?

@jannik4 jannik4 requested a review from djeedai February 27, 2024 19:39
Copy link
Owner

@djeedai djeedai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks all good, thanks for the update!

@@ -800,7 +800,7 @@ mod test {
// app.add_plugins(DefaultPlugins);
app.init_asset::<Mesh>();
app.add_plugins(VisibilityPlugin);
app.init_resource::<Time>();
app.init_resource::<Time<EffectSimulation>>();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok and we don't insert the effect_simulation_time_system system so we don't need to read Time<Virtual>.

@djeedai djeedai added C - enhancement New feature or request C - breaking change A breaking API or behavior change labels Mar 5, 2024
@djeedai djeedai merged commit 4933a35 into djeedai:main Mar 5, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C - breaking change A breaking API or behavior change C - enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ability to pause / unpause effects independently from Bevy Time
2 participants