RunService

Show Deprecated
Not Creatable
Service
Not Replicated

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
EnvironmentIsStudioIsClientIsServerIsEditIsRunningIsRunMode
Live Playerfalsetruefalse
Live Serverfalsefalsetrue
Edit Modetruetruetruetruefalsefalse
Collaborative Edittruetruefalsetruefalsefalse
Run Modetruetruetruefalsetruetrue
Play Mode (Client)truetruefalsefalsetruefalse
Play Mode (Server)truefalsetruefalsetruetrue
Team Test (Player)truetruefalsefalsetruefalse
Team Test (Server)falsefalsetruefalsetruefalse

Summary

Properties

Methods

  • BindToRenderStep(name : string,priority : number,function : function):void

    Given a string name of a function and a priority, this method binds the function to RunService.PreRender.

  • Write Parallel

    Returns whether the current environment is running on the client.

  • Plugin Security
    Write Parallel

    Returns whether the current environment is in Edit mode.

  • Write Parallel

    Returns whether the Run button has been pressed to run the simulation in Studio.

  • Returns whether the experience is currently running.

  • Write Parallel

    Returns whether the current environment is running on the server.

  • Write Parallel

    Returns whether the current environment is running in Studio.

  • Pause():void
    Plugin Security

    Pauses the experience's simulation if it is running, suspending physics and scripts.

  • Run():void
    Plugin Security

    Runs the game's simulation, running physics and scripts.

  • Stop():void
    Plugin Security

    Stops the experience's simulation if it is running.

  • Unbinds a function that was bound to the render loop using RunService:BindToRenderStep().

Events

Properties

ClientGitHash

Read Only
Not Replicated
Roblox Script Security
Read Parallel
Not Replicated
Plugin Security
Read Parallel

Methods

BindToRenderStep

void

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

name: string

Label for the binding which can be used with Unbind if the binding is no longer needed.

priority: number

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.

function: function

The custom function being bound.


Returns

void

Code Samples

Frame Moving in Circle

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
RunService Custom Function

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)
Bind and Unbind a Function

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

Write Parallel

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

Plugin Security
Write Parallel

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

Write Parallel

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

Write Parallel

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

Write Parallel

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

void
Plugin Security

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

void

Run

void
Plugin Security

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

void

Stop

void
Plugin Security

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

void

UnbindFromRenderStep

void

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

name: string

The name of the function being unbound.


Returns

void

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

deltaTime: number

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

deltaTimeSim: number

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

deltaTimeSim: number

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

deltaTimeRender: number

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

deltaTimeSim: number

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

deltaTime: number

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

time: number

The duration (in seconds) that RunService has been running for.

deltaTime: number

The time (in seconds) that has elapsed since the previous frame.