Time
s&box provides a set of utilities for working with time in your game. These let you write things like cooldowns, countdowns, and frame-rate independent movement cleanly and without manual bookkeeping.
s&box provides a set of utilities for working with time in your game. These let you write things like cooldowns, countdowns, and frame-rate independent movement cleanly and without manual bookkeeping.
Time.Delta
Time.Delta is the number of seconds that have elapsed since the last frame. You should multiply any per-frame movement or change by this to make it frame-rate independent - so it behaves the same whether your game is running at 30fps or 300fps.
protected override void OnUpdate()
{
// Move 100 units per second, regardless of frame rate
WorldPosition += Vector3.Forward * 100f * Time.Delta;
}
Time.Now
Time.Now is the total time in seconds since the scene started. You can use it to schedule things or measure durations. Time.Now is synchronized across the network.
float startTime = Time.Now;
// later...
float elapsed = Time.Now - startTime;
Log.Info( $"It has been {elapsed} seconds" );
This works, but s&box has cleaner helpers for this pattern - TimeSince and TimeUntil.
TimeSince
TimeSince is a struct that automatically tracks how long ago it was set. Assigning 0 resets the timer to now. Reading it as a float gives you the number of seconds elapsed.
TimeSince lastShot = 0;
protected override void OnUpdate()
{
if ( Input.Pressed( "attack1" ) && lastShot > 0.5f )
{
Shoot();
lastShot = 0; // reset the timer
}
}
This is much simpler than storing float lastShotTime = Time.Now and writing Time.Now - lastShotTime > 0.5f everywhere.
You can also compare with <, <=, >=, >:
TimeSince timeSinceGrounded;
// check if the player has been airborne for more than 0.2 seconds
if ( timeSinceGrounded > 0.2f )
{
// play coyote time logic
}
TimeUntil
TimeUntil counts down to a moment in the future. Assigning a number of seconds sets the countdown. It implicitly converts to a true bool when the time has expired.
TimeUntil respawnAt;
void OnDeath()
{
respawnAt = 5f; // respawn in 5 seconds
}
protected override void OnUpdate()
{
if ( respawnAt )
{
Respawn();
}
}
You can also read it as a float to get the remaining seconds:
float secondsLeft = respawnAt;
Log.Info( $"Respawning in {secondsLeft:F1}s" );
Fraction
TimeUntil.Fraction returns a value from 0 (just started) to 1 (expired), which is great for progress bars or lerping effects:
TimeUntil reloadDone;
void StartReload()
{
reloadDone = 2.0f; // 2 second reload
}
protected override void OnUpdate()
{
float progress = reloadDone.Fraction; // 0 โ 1 as time passes
ReloadBar.SetProgress( progress );
}
RealTimeSince and RealTimeUntil
These work exactly like TimeSince and TimeUntil, but they use wall-clock time (RealTime.Now) instead of game time (Time.Now).
Use RealTimeSince / RealTimeUntil when you want the timer to keep ticking even if the game is paused or the time scale is changed (e.g., for UI animations, network timeouts, or cooldowns that should be unaffected by slow motion).
RealTimeSince lastHeartbeat = 0;
protected override void OnUpdate()
{
if ( lastHeartbeat > 30f )
{
SendHeartbeat();
lastHeartbeat = 0;
}
}
Quick Reference
| Type | Resets with | Reads as | Use for |
|---|---|---|---|
TimeSince | = 0 | seconds elapsed | cooldowns, durations |
TimeUntil | = seconds | seconds remaining (bool when done) | countdowns, delays |
RealTimeSince | = 0 | seconds elapsed (wall clock) | UI, network, pause-immune timers |
RealTimeUntil | = seconds | seconds remaining (wall clock) | pause-immune countdowns |
Time.Delta | n/a | seconds since last frame | frame-rate independent movement |
Time.Now | n/a | total seconds since scene start | raw time reference |
Referenced API
Canonical API pages mentioned in this guide.
Like a widget - but is drawn
No summary available.
Keyframes times and values should range between 0 and 1
No summary available.
Access to time.
A convenience struct to easily measure time since an event last happened, based on `Sandbox.RealTime.GlobalNow`. Typical usage would see you assigning 0 to a variable of this type to reset the timer. Then the struct would return time since the last reset. i.e.: RealTimeSince lastUsed = 0; if ( lastUsed > 10 ) { /*Do something*/ }
A convenience struct to easily manage a time countdown, based on `Sandbox.RealTime.GlobalNow`. Typical usage would see you assigning to a variable of this type a necessary amount of seconds. Then the struct would return the time countdown, or can be used as a bool i.e.: RealTimeUntil nextAttack = 10; if ( nextAttack ) { /*Do something*/ }
Describes a single animation frame