Quick answer: Frame-based time sources stop when the game pauses. For real-time timers, create the source with time_source_units_seconds and parent it to time_source_global.

A “respawn in 5 seconds” timer uses a frame-based time source. When the player opens a pause menu (and you stop stepping), the timer freezes too.

Frames vs Seconds

// frame-based: counts game frames; pauses when stepping stops
ts = time_source_create(time_source_game, 300, time_source_units_frames, on_done);

// real-time: counts wall-clock seconds; ignores game pause
ts = time_source_create(time_source_global, 5, time_source_units_seconds, on_done);

Pick the parent and units to match the behavior you want.

Parent Choice

Units Choice

Pause-Aware Gameplay Timers

For a gameplay timer that should pause (a power-up duration), keep it frame-based on time_source_game. The freeze-on-pause is correct there. The bug is only when you used that for something that shouldn’t pause.

Verifying

Start a real-time timer, open the pause menu. The timer keeps counting. Gameplay timers correctly freeze. Both resume as expected.

“Choose parent and units deliberately: game+frames pauses, global+seconds doesn’t.”

Wrap timer creation in helper functions named for intent — create_gameplay_timer() vs create_realtime_timer() — so call sites can’t pick the wrong combo.