s&box docs
GuidesCodeCode Basics

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

TypeResets withReads asUse for
TimeSince= 0seconds elapsedcooldowns, durations
TimeUntil= secondsseconds remaining (bool when done)countdowns, delays
RealTimeSince= 0seconds elapsed (wall clock)UI, network, pause-immune timers
RealTimeUntil= secondsseconds remaining (wall clock)pause-immune countdowns
Time.Deltan/aseconds since last frameframe-rate independent movement
Time.Nown/atotal seconds since scene startraw time reference

Referenced API

Canonical API pages mentioned in this guide.

Created at:
Updated at:

On this page