RunService
RunService contains methods and events for time management as well as for managing the context in which an experience or script is running. Methods like IsClient(), IsServer(), and IsStudio() can help you determine under what context code is running. These methods are useful for ModuleScripts that may be required by both client and server scripts. Furthermore, IsStudio() can be used to add special behaviors for in‑Studio testing.
RunService also houses events that allow your code to adhere to Roblox's frame‑by‑frame loop, such as PreRender, PreAnimation, PreSimulation, PostSimulation, and Heartbeat. Selecting the proper event to use for any case is important, so you should read Task Scheduler to make an informed decision.
Context Test Results
Environment | IsStudio | IsClient | IsServer | IsEdit | IsRunning | IsRunMode |
---|---|---|---|---|---|---|
Live Player | false | true | false | |||
Live Server | false | false | true | |||
Edit Mode | true | true | true | true | false | false |
Collaborative Edit | true | true | false | true | false | false |
Run Mode | true | true | true | false | true | true |
Play Mode (Client) | true | true | false | false | true | false |
Play Mode (Server) | true | false | true | false | true | true |
Team Test (Player) | true | true | false | false | true | false |
Team Test (Server) | false | false | true | false | true | false |
Summary
Properties
Methods
Given a string name of a function and a priority, this method binds the function to RunService.PreRender.
Returns whether the current environment is running on the client.
Returns whether the current environment is in Edit mode.
Returns whether the Run button has been pressed to run the simulation in Studio.
Returns whether the experience is currently running.
Returns whether the current environment is running on the server.
Returns whether the current environment is running in Studio.
Pauses the experience's simulation if it is running, suspending physics and scripts.
Runs the game's simulation, running physics and scripts.
Stops the experience's simulation if it is running.
Unbinds a function that was bound to the render loop using RunService:BindToRenderStep().
Events
Fires every frame, after the physics simulation has completed.
Fires every frame, after the physics simulation has completed.
Fires every frame, prior to the physics simulation but after rendering.
Fires every frame, prior to the frame being rendered.
Fires every frame, prior to the physics simulation.
Fires every frame, prior to the frame being rendered.
Fires every frame, prior to the physics simulation.
Properties
ClientGitHash
RunState
Methods
BindToRenderStep
The BindToRenderStep() function binds a custom function to be called at a specific time during the render step. There are three main arguments: name, priority, and what function to call.
As it is linked to the client's rendering process, BindToRenderStep() can only be called on the client.
Name
The name parameter is a label for the binding and can be used with RunService:UnbindFromRenderStep() if the binding is no longer needed.
local RunService = game:GetService("RunService")
local function functionToBind() end
-- Bind the function above to the binding named "tempBinding"
RunService:BindToRenderStep("tempBinding", 1, functionToBind)
-- Unbind the function bound to "tempBinding"
RunService:UnbindFromRenderStep("tempBinding")
Priority
The priority of the binding is an integer; it determines when during the render step to call the custom function. The lower this number, the sooner the custom function will be called. If two bindings have the same priority, the Roblox engine will randomly pick one to run first. The default Roblox control scripts run with these specific priorities:
- Player Input: 100
- Camera Controls: 200 For convenience; the Enum.RenderPriority enum can be used to determine the integer value to set a binding. For example, to make a binding right before the default camera update, simply subtract 1 from the camera priority level.
When using Enum.RenderPriority, remember to use .Value at the end of the desired enum. RunService:BindToRenderStep() will not work if just the enum is used on its own.
local RunService = game:GetService("RunService")
local function beforeCamera(delta)
-- Code in here will run before the default Roblox camera script
end
RunService:BindToRenderStep("Before camera", Enum.RenderPriority.Camera.Value - 1, beforeCamera)
Custom Function and Delta Time
The last argument (function) is the custom function to call. This function will be passed one parameter called deltaTime which shows how much time passed between the beginning of the previous render step and the beginning of the current render step.
All rendering updates will wait until the code in the render step finishes. Make sure that any code called by BindToRenderStep() runs quickly and efficiently; if code takes too long, the experience visuals will be choppy.
Parameters
Priority of the binding as an integer; it determines when during the render step to call the custom function. The lower this number, the sooner the custom function will be called. If two bindings have the same priority the Roblox engine will randomly pick one to run first.
The custom function being bound.
Returns
Code Samples
local RunService = game:GetService("RunService")
-- How fast the frame ought to move
local SPEED = 2
local frame = script.Parent
frame.AnchorPoint = Vector2.new(0.5, 0.5)
-- A simple parametric equation of a circle
-- centered at (0.5, 0.5) with radius (0.5)
local function circle(t)
return 0.5 + math.cos(t) * 0.5, 0.5 + math.sin(t) * 0.5
end
-- Keep track of the current time
local currentTime = 0
local function onRenderStep(deltaTime)
-- Update the current time
currentTime = currentTime + deltaTime * SPEED
-- ...and the frame's position
local x, y = circle(currentTime)
frame.Position = UDim2.new(x, 0, y, 0)
end
-- This is just a visual effect, so use the "Last" priority
RunService:BindToRenderStep("FrameCircle", Enum.RenderPriority.Last.Value, onRenderStep)
--RunService.RenderStepped:Connect(onRenderStep) -- Also works, but not recommended
local RunService = game:GetService("RunService")
local function checkDelta(deltaTime)
print("Time since last render step:", deltaTime)
end
RunService:BindToRenderStep("Check delta", Enum.RenderPriority.First.Value, checkDelta)
local RunService = game:GetService("RunService")
-- Step 1: Declare the function and a name
local NAME = "Print Hello"
local function printHello()
print("Hello")
end
-- Step 2: Bind the function
RunService:BindToRenderStep(NAME, Enum.RenderPriority.First.Value, printHello)
-- Step 3: Unbind the function
RunService:UnbindFromRenderStep(NAME)
IsClient
If the code that invoked this method is running in a client context (in a LocalScript, in a ModuleScript required by a LocalScript, or in a Script with RunContext set to Enum.RunContext.Client), this method will return true. In all other cases, this method will return false.
If this method returns true, the current environment can access client‑only features like RunService.PreRender or Players.LocalPlayer.
Returns
Whether the current environment is running the client.
IsEdit
This method returns whether the current environment is in "edit" mode, for example in Studio when the experience is not running.
IsEdit() will return the inverse of IsRunning(), except when the simulation has been paused, in which case both methods will return false.
Returns
Whether the current environment is in "edit" mode.
IsRunMode
This method returns whether the Run button has been pressed to run the simulation in Studio. It will continue to return true if the simulation has been paused using the Pause button; however, once it has been stopped using the Stop button, it will revert to returning false.
Note that Studio only enters "run" mode when the Run button is pressed, not the Play button. Also note that this method will return false if the simulation was started using RunService:Run() rather than the Run button.
Returns
Whether the Run button has been pressed to run the simulation in Studio.
IsRunning
Returns whether the experience is currently running, meaning the simulation has been run using the Run or Play buttons.
IsRunning() will always return the inverse of IsEdit() except when the simulation has been paused, in which case both methods will return false.
Returns
Whether the experience is currently running.
IsServer
This method returns whether the current environment is running on the server. If the code that invoked this method is running in a server context (in a Script with RunContext set to Enum.RunContext.Server or Enum.RunContext.Legacy, or in a ModuleScript required by a Script), this method will return true. In all other cases, this method will return false.
If this function returns true, then the current environment can access server‑only features like ServerStorage or ServerScriptService.
Returns
Whether the current environment is running on the server.
IsStudio
This method returns whether the current environment is running in Studio. It can be used to wrap code that should only execute when testing in Studio.
Returns
Whether the current environment is running in Studio.
Pause
This method pauses the experience's simulation if it is running, suspending physics and scripts. The simulation can be started using Run() or the Run button in Studio; when the simulation is paused, IsRunning() will return false.
Returns
Run
This method runs the experience's simulation (physics and scripts). When the simulation is running, IsRunning() will return true. However, IsRunMode() will only return true if the simulation was started using the Run button in Studio.
Returns
Stop
This method stops the experience's simulation if it is running. When the simulation is stopped, IsRunning() will return false and IsEdit() will return true.
In contrast to the Stop button in Studio, calling this method will not restore the experience to the state it was in prior to the simulation being run. This means any changes made to the experience by the physics simulation and scripts will persist after the simulation has ended.
Returns
UnbindFromRenderStep
Given a name of a function sent to BindToRenderStep(), this method will unbind the function from being called during PreRender. This is used to unbind bound functions once they are no longer needed, or when they no longer need to fire every step.
If there is no bound function by the given name, this method takes no action and continues without raising an error.
Parameters
The name of the function being unbound.
Returns
Events
Heartbeat
The Heartbeat event fires every frame, after the physics simulation has completed. The deltaTime argument indicates the time that has elapsed since the previous frame.
This event is when most scripts run. It occurs at the end of each frame and it's also when any waiting scripts are executed, such as those scheduled with the task library. Heartbeat is commonly used for periodic tasks, such as updating core game systems like health regeneration.
Following this step, the engine sends property updates and events to the server or clients which are later received as part of the replication receive step.
Parameters
The time (in seconds) that has elapsed since the previous frame.
PostSimulation
The PostSimulation event fires every frame, after the physics simulation has completed. The deltaTimeSim argument indicates the time that has elapsed since the previous frame.
This event is useful for making final adjustments to the outcome of the simulation. Following this phase, the engine triggers the Heartbeat event.
Parameters
The time (in seconds) that has elapsed since the previous frame.
PreAnimation
The PreAnimation event fires every frame, prior to the physics simulation but after rendering. The deltaTimeSim argument indicates the time that has elapsed since the previous frame.
This event is useful for modifying animation objects, such as adjusting their speed or priority. Once the PreAnimation event is complete, the engine proceeds to run these animations, updating the joint transforms which will later be used to update objects during the physics simulation.
After animations are stepped, the engine triggers the PreSimulation event.
Parameters
The time (in seconds) that has elapsed since the previous frame.
PreRender
The PreRender event (equivalent to RenderStepped) fires every frame, prior to the frame being rendered. The deltaTimeRender argument indicates the time that has elapsed since the previous frame.
This event allows you to run code and update the world before it's drawn on a player's screen. This is useful for last‑minute adjustments such as changing object positions, updating animations, or preparing visual effects, but it should be used sparingly as the engine cannot start to render the frame until code running in this event has finished executing.
As PreRender is client-side, it can only be used in a LocalScript, in a ModuleScript required by a LocalScript, or in a Script with RunContext set to Enum.RunContext.Client.
Following the PreRender phase, the simulation phase begins with the PreAnimation event.
Parameters
The time (in seconds) that has elapsed since the previous frame.
PreSimulation
The PreSimulation event (equivalent to Stepped) fires every frame, prior to the physics simulation. The deltaTimeSim argument indicates the time that has elapsed since the previous frame.
This event is useful for adjusting properties like velocity or forces just before they're applied as part of the simulation. The simulation then runs, potentially multiple times, as the physics solver runs at a higher frequency than other engine systems. Once this is complete, the PostSimulation event is fired.
Parameters
The time (in seconds) that has elapsed since the previous frame.
RenderStepped
The RenderStepped event (equivalent to PreRender) fires every frame, prior to the frame being rendered. The deltaTime argument indicates the time that has elapsed since the previous frame.
This event allows you to run code and update the world before it's drawn on a player's screen. This is useful for last‑minute adjustments such as changing object positions, updating animations, or preparing visual effects, but it should be used sparingly as the engine cannot start to render the frame until code running in this event has finished executing.
As RenderStepped is client-side, it can only be used in a LocalScript, in a ModuleScript required by a LocalScript, or in a Script with RunContext set to Enum.RunContext.Client.
Following the RenderStepped phase, the simulation phase begins with the PreAnimation event.
Parameters
The time (in seconds) that has elapsed since the previous frame.
Stepped
The Stepped event (equivalent to PreSimulation) fires every frame, prior to the physics simulation. The deltaTime argument indicates the time that has elapsed since the previous frame.
This event is useful for adjusting properties like velocity or forces just before they're applied as part of the simulation. The simulation then runs, potentially multiple times, as the physics solver runs at a higher frequency than other engine systems. Once this is complete, the PostSimulation event is fired.
Parameters
The duration (in seconds) that RunService has been running for.
The time (in seconds) that has elapsed since the previous frame.