`simTimeAuthority` - Simulation Time & Bullet Time Control
Central authority for simulation speed (bullet time / slow motion), pausing, and smooth time-scale transitions. All pause and speed changes should go through this module.
Central authority for simulation speed (bullet time / slow motion), pausing, and smooth time-scale transitions. All pause and speed changes should go through this module.
Exports
| Function | Signature | Description |
|---|---|---|
get | () → number | Get target simulation speed (0–1, may not be reached yet) |
getReal | () → number | Get current actual speed (with smoothing in progress) |
set | (val) | Set target speed with smooth transition + UI message |
setInstant | (val) | Set speed instantly (no smoothing) |
selectPreset | (val) | Select bullet time preset: "^" toggle, "v" instant slowmo, "<"/">" step |
pause | (paused, playPauseSound?) | Pause/unpause simulation |
pauseSmooth | (paused, rateLimit, startAccel, stopAccel, playPauseSound?) | Pause with smooth transition |
getPause | () → bool | Check if simulation is paused |
togglePause | () | Toggle pause state |
requestValue | () | Trigger BullettimeValueChanged GUI hook |
reportSpeed | (speed, simplified) | Show UI message about current speed |
getInitialTimeScale | () → number | Get the time scale before pause was applied |
pushPauseRequest | (id) | Push a named pause request (stacking) |
popPauseRequest | (id) | Pop a named pause request (unpauses when stack empty) |
Fields
| Field | Type | Description |
|---|---|---|
simulationSpeed | number | Target simulation speed (0–1) |
simulationSpeedReal | number | Current actual speed after smoothing |
selectionSlot | number | Current bullet time preset slot index |
Lifecycle Hooks
| Hook | Description |
|---|---|
onSerialize | Saves simulationSpeed and initialTimeScale |
onDeserialized | Restores speed and clears pause stack |
onUIInitialised | Clears pause stack on UI init |
How It Works
Speed Control
Speed values range from 0.001 to 1.0 (realtime). Changes are smoothed via TemporalSigmoidSmoothing to avoid jarring transitions:
-- Slow motion (half speed), smooth transition
simTimeAuthority.set(0.5)
-- Instant slow motion (no transition)
simTimeAuthority.setInstant(0.25)
-- Back to realtime
simTimeAuthority.set(1.0)
-- Check current speed
local target = simTimeAuthority.get() -- what we're aiming for
local actual = simTimeAuthority.getReal() -- what's currently in effectBullet Time Presets
12 preset slots from 1/1000x to 1x speed. Controlled via directional commands:
-- Toggle between realtime and last slowmo setting
simTimeAuthority.selectPreset("^")
-- Instant slowmo (slot 8 = 1/8x)
simTimeAuthority.selectPreset("v")
-- Step slower / faster through presets
simTimeAuthority.selectPreset("<")
simTimeAuthority.selectPreset(">")Preset slots: 1/1000, 1/500, 1/200, 1/100, 1/50, 1/32, 1/16, 1/8, 1/4, 1/2, 3/4, 1.0
Pausing
Basic pause/unpause with optional sound:
-- Pause
simTimeAuthority.pause(true)
-- Unpause (restores previous speed)
simTimeAuthority.pause(false)
-- Smooth pause with custom transition
simTimeAuthority.pauseSmooth(true, 5, 3, 2) -- rateLimit, startAccel, stopAccel
-- Toggle
simTimeAuthority.togglePause()Stacking Pause Requests
Multiple systems can request pause independently. Simulation only unpauses when ALL requests are popped:
-- System A needs pause
simTimeAuthority.pushPauseRequest("photoMode")
-- System B also needs pause
simTimeAuthority.pushPauseRequest("menuOpen")
-- System A done - still paused (B still active)
simTimeAuthority.popPauseRequest("photoMode")
-- System B done - NOW unpauses
simTimeAuthority.popPauseRequest("menuOpen")Duplicate push calls for the same ID are ignored. If the sim was already paused before the first push, it stays paused after all pops.
Internals
- Smoothing: Uses
TemporalSigmoidSmoothingwith default paramsrateLimit=20, startAccel=10, stopAccel=3 - Replay awareness:
getPause,pause,selectPreset, andtogglePauseall checkcore_replay.state.state == "playback"and delegate to replay controls when active - Engine bridge: Calls
be:setSimulationTimeScale(),be:setEnabled(), andphysicsStateChanged()to actually control the engine - UI feedback: Speed changes trigger
ui_messagewith localization keys like"vehicle.bullettime.changeSlow","vehicle.bullettime.realtime", etc. - Pause sound: Plays
'event:>UI>Main>Pause'viaEngine.Audio.playOncewhen pausing (can be disabled withplayPauseSound=false) - Update dispatch: The
updatefunction is a no-op wrapper that only runs the actual smoothing logic when a transition is in progress, avoiding unnecessary per-frame work
Common Patterns
-- Photo mode: pause while active
local function enterPhotoMode()
simTimeAuthority.pushPauseRequest("photoMode")
end
local function exitPhotoMode()
simTimeAuthority.popPauseRequest("photoMode")
end
-- Cinematic slowmo effect
simTimeAuthority.pauseSmooth(true, 2, 1, 1) -- slow fade to pause
-- ... show UI ...
simTimeAuthority.pauseSmooth(false, 2, 1, 1) -- slow fade backAdditional Exports
| Key | Signature | Description |
|---|---|---|
M.get | () | 1=realtime, 0.5=slowmo, 2=fastmotion (desired value, which may or may not have been reached yet) |
M.getInitialTimeScale | () | (No description available) |
M.getPause | () | (No description available) |
M.getReal | () | 1=realtime, 0.5=slowmo, 2=fastmotion (current value in effect, with smoothing in action) |
M.onDeserialized | (data) | (No description available) |
M.onSerialize | () | (No description available) |
M.onUIInitialised | () | (No description available) |
M.pause | (paused, playPauseSound) | (No description available) |
M.pauseSmooth | (paused, rateLimit, startAccel, stopAccel, playPauseSound) | (No description available) |
M.popPauseRequest | (id) | (No description available) |
M.pushPauseRequest | (id) | (No description available) |
M.reportSpeed | (speed, simplified) | (No description available) |
M.requestValue | () | (No description available) |
M.selectPreset | (val) | (No description available) |
M.set | (val) | 1=realtime, 0.5=slowmo, 2=fastmotion (change won't be instant: speed will slowly reach the desired value) |
M.setInstant | (val) | same as set, but instantaneous |
M.togglePause | () | (No description available) |
M.update | (...) | the extension system registers the function pointers, thus functions called back by it cannot be nop'ed. So we wrap it in another function. |
M.selectionSlot | variable | (No description available) |
M.simulationSpeed | variable | (No description available) |
M.simulationSpeedReal | variable | (No description available) |
`setSpawnpoint` - Default Spawn Point Persistence
Manages per-level default spawn point selection. Saves and loads the player's chosen spawn point to/from `settings/cloud/game-state.json`.
`spawn` - Vehicle Spawning & Safe Placement
Core vehicle spawning, safe teleportation, and collision-free placement system. Handles creating vehicles, finding non-intersecting positions, ground snapping, and trailer coupling.