Open jrmoserbaltimore opened 4 months ago
Okay, from reading the docs, I thought timers just ran on their own.
I looked through the source code to see if it'd be easy enough to just implement this myself and PR it; it turns out timers have to be manually ticked.
…I don't see how timers are anything other than an overcomplicated float. How are Timer
and Stopwatch
even useful at all in their current state? You could just check the clock and update a variable instead; the only difference right now seems to be updating your own variable requires an assignment operator to add the duration of time elapsed, while updating a Timer
requires calling tick()
with the duration of time elapsed.
There are some invariants involved in keeping track of time, and you want to use a Duration
, not a float.
But overall I agree with your analysis: it's frustrating and unintuitive that timers don't advance on their own. IMO the best way to resolve that would be to use trait queries (generalized to resources) and advance all objects that implement a derivable trait.
These aren't yet upstreamed (see https://github.com/bevyengine/rfcs/pull/39), but this is an interesting potential first-party use case.
This issue needs clarification.
Is the goal to provide a simple way of making Time<CustomVirtual>
from Time<Virtual>
or is the goal to auto-tick timers like discussed in the comments?
What problem does this solve or what need does it fill?
The docs for Bevy 0.13 indicate
Time<Virtual>
provides a timer running at a multiple of the system clock.Res<Time<Virtual>>
can be sped up, slowed down, or paused to control game time, so long as the game's objects are tied toRes<Time<Virtual>>
for their time. The docs don't indicate a way to produce aTime<Virtual>
based onRes<Time<Virtual>>
or anotherTime<Virtual>
.Further, the docs for
Timer
don't indicate whetherTimer
followsRes<Time<Real>>
orRes<Time<Virtual>>
, and there is nothing in the docs indicating any way to control this.For events with cooldown, it would make sense to be able to somehow time the cooldown relative to a virtual timer tied to game time. For example, Final Fantasy's active time battle system uses a character's speed to slowly fill a time gauge before the character's turn begins; while several games have cooldown times for using special moves. These times can be made faster or slower by status effects to increase or decrease a character's speed. A good approach to do so is not obvious.
There are also speedup and slowdown mechanics such as dialog box speed or battle speed in RPGs separate from the rest of game time. These somehow require timing against a clock relative to the main game clock.
What solution would you like?
A way to time events based on a given time source. One approach is to allow creation of a
Time<Virtual>
based on some otherTime
object specified by the programmer, and adjust theTime<Virtual>
speed to compound with its base clock. For example,my_time
can be set to 0.5 speed and based onRes<Time<Virtual>>
; settingRes<Time<Virtual>>
to 0.5 speed would havemy_time
run at 0.25 system speed.A way to create a timer based on a
Time
object to go with this.my_timer
could then be aTimer
based onmy_time
, and speeding up or slowing downmy_time
would affect the length of real-time required formy_timer
to finish.What alternative(s) have you considered?
Writing a custom timer by simply reading
Res<Time<Virtual>>
and looking at the current virtual time versus a recorded virtual time at which the timer started. This offloads the entire function ofTimer
onto a custom implementation, which means every programmer needs to implement their own type ofTimer
.