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 a game or script is running. Methods like IsClient, IsServer, 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 PreAnimation, PreSimulation, Heartbeat and PreRender. Selecting the proper event to use for any case is important, so you should read Task Scheduler to make an informed decision.

Code Samples

RunService Stepped

local RunService = game:GetService("RunService")
local PART_START_POS = Vector3.new(0, 10, 0)
local PART_SPEED = Vector3.new(10, 0, 0)
-- Create a Part with a BodyPosition
local part = Instance.new("Part")
part.CFrame = CFrame.new(PART_START_POS)
local bp = Instance.new("BodyPosition")
bp.Parent = part
bp.Position = PART_START_POS
part.Parent = workspace
local function onStep(_currentTime, deltaTime)
-- Move the part the distance it is meant to move
-- in the last `deltaTime` seconds
bp.Position = bp.Position + PART_SPEED * deltaTime
-- Here's the math behind this:
-- speed = displacement / time
-- displacement = speed * time
end
RunService.Stepped:Connect(onStep)

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.

  • 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 Roblox Studio.

  • Returns whether the game 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 Roblox Studio.

  • Pause():void

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

  • Run():void

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

  • Stop():void

    Ends the game'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
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 for BindToRenderStep: 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, and 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 InlineCode.Value at the end of the desired enum. BindToRenderStep will not work if just the enum on its own is used.


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 of BindToRenderStep is the custom function to call. This function will be passed one parameter called deltaTime. DeltaTime 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 in BindToRenderStep takes too long, then the game visuals will be choppy.

Parameters

name: string

The name parameter is a label for the binding, and can be used with RunService.Unbind if the binding is no longer needed.

priority: number

The priority of the binding is an integer, and 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.

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
local success, message = pcall(function()
RunService:UnbindFromRenderStep(name)
end)
if success then
print("Success: Function unbound!")
else
print("An error occurred: " .. message)
end

IsClient

write parallel

This function returns whether the current environment is running on the client.

If the code that invoked this method is running in a client context (in a LocalScript or a ModuleScript required by a LocalScript) then this method will return true. In all other cases, this function will return false.

If this function returns true, then the current environment can access client-only features like RunService.PreRender or Players.LocalPlayer.

RunService test function results

EnvironmentIsStudioIsClientIsServerIsEditIsRunningIsRunMode
Live Playerfalsetruefalse
Live Serverfalsefalsetrue
Edit Modetruetruetruetruefalsefalse
Edit Mode (Team Create)truetruefalsetruefalsefalse
Run Modetruetruetruefalsetruetrue
Play Mode (Client)truetruefalsefalsetruefalse
Play Mode (Server)truefalsetruefalsetruetrue
Team Test Playertruetruefalsefalsetruefalse
Team Test Serverfalsefalsetruefalsetruefalse
Legacy Play Mode †truetruetruefalsetruefalse
† 'Legacy Play Mode' refers to Play Mode with Accurate Play Solo disabled

See also:


Returns

Whether the current environment is running the client.

Code Samples

Run Context

local RunService = game:GetService("RunService")
if RunService:IsStudio() then
print("I am in Roblox Studio")
else
print("I am in an online Roblox Server")
end
if RunService:IsRunMode() then
print("Running in Studio")
end
if RunService:IsClient() then
print("I am a client")
else
print("I am not a client")
end
if RunService:IsServer() then
print("I am a server")
else
print("I am not a server")
end
if RunService:IsRunning() then
print("The game is running")
else
print("The game is stopped or paused")
end

IsEdit

write parallel

This function returns whether the current environment is in 'Edit' mode. For example, Roblox Studio is in 'Edit Mode' when the game is not running.

IsEdit will return the inverse of RunService:IsRunning() with one exception, if the simulation has been 'paused' then both IsEdit and RunService:IsRunning() will return false.

See also:


Returns

Whether the current environment is in Edit mode.

IsRunMode

write parallel

This function returns whether the 'Run' button has been pressed to run the simulation in Roblox Studio.

If the user has pressed 'Run', then this function will return true. This function 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.

Roblox Studio only enters run mode when the 'Run' button is pressed, not the 'Play' button. This function will also return false if the simulation was started using RunService:Run() rather than the 'Run' button.

RunService test function results

See also:


Returns

Whether the 'Run' button has been pressed to run the simulation in Roblox Studio.

Code Samples

Run Context

local RunService = game:GetService("RunService")
if RunService:IsStudio() then
print("I am in Roblox Studio")
else
print("I am in an online Roblox Server")
end
if RunService:IsRunMode() then
print("Running in Studio")
end
if RunService:IsClient() then
print("I am a client")
else
print("I am not a client")
end
if RunService:IsServer() then
print("I am a server")
else
print("I am not a server")
end
if RunService:IsRunning() then
print("The game is running")
else
print("The game is stopped or paused")
end

IsRunning

Returns whether the game is currently running

The game is considered running when it is not in edit mode in Roblox Studio. This means, if the simulation has been run using the 'Run' or 'Play' buttons the game is running.

IsRunning will always return the inverse of RunService:IsEdit() with one exception, if the simulation has been 'paused' then both RunService:IsEdit() and IsRunning will return false.

RunService test function results

See also:


Returns

Whether the game is currently running.

Code Samples

Run Context

local RunService = game:GetService("RunService")
if RunService:IsStudio() then
print("I am in Roblox Studio")
else
print("I am in an online Roblox Server")
end
if RunService:IsRunMode() then
print("Running in Studio")
end
if RunService:IsClient() then
print("I am a client")
else
print("I am not a client")
end
if RunService:IsServer() then
print("I am a server")
else
print("I am not a server")
end
if RunService:IsRunning() then
print("The game is running")
else
print("The game is stopped or paused")
end

IsServer

write parallel

This function 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 or a ModuleScript required by a Script) then this method will return true. In all other cases, this function will return false.

If this function returns true, then the current environment can access server-only features like ServerStorage or ServerScriptService.

See also:


Returns

Whether the current environment is running on the server.

Code Samples

Run Context

local RunService = game:GetService("RunService")
if RunService:IsStudio() then
print("I am in Roblox Studio")
else
print("I am in an online Roblox Server")
end
if RunService:IsRunMode() then
print("Running in Studio")
end
if RunService:IsClient() then
print("I am a client")
else
print("I am not a client")
end
if RunService:IsServer() then
print("I am a server")
else
print("I am not a server")
end
if RunService:IsRunning() then
print("The game is running")
else
print("The game is stopped or paused")
end

IsStudio

write parallel

This function returns whether the current environment is running in Roblox Studio.

This function will only return true when using Roblox Studio and can be used to add code to test your game within Studio.

See also:


Returns

Whether the current environment is running in Roblox Studio.

Code Samples

Run Context

local RunService = game:GetService("RunService")
if RunService:IsStudio() then
print("I am in Roblox Studio")
else
print("I am in an online Roblox Server")
end
if RunService:IsRunMode() then
print("Running in Studio")
end
if RunService:IsClient() then
print("I am a client")
else
print("I am not a client")
end
if RunService:IsServer() then
print("I am a server")
else
print("I am not a server")
end
if RunService:IsRunning() then
print("The game is running")
else
print("The game is stopped or paused")
end

Pause

void

This function pauses the games' simulation if it is running, suspending physics and scripts.

The simulation can be started using RunService:Run() or the 'Run' button in Roblox Studio. When the simulation is paused, RunService:IsRunning() will return false.

Pausing the simulation can be used to assist with debugging in Roblox Studio, it cannot be used in real game sessions.

See also:


Returns

void

Run

void

This function runs the game's simulation, running physics and scripts.

When the simulation is running, RunService:IsRunning() will return true. However, RunService:IsRunMode() will only return true if the simulation was started using the 'Run' button in Roblox Studio. This means when this function is used to start the simulation, IsRunMode will return false even though the simulation is running.

The simulation can be paused using RunService:Pause() or the 'Pause' button in Roblox Studio. It can also be ended using RunService:Stop().

Running the simulation can be used to assist with debugging in Roblox Studio. Currently it is not possible to restore the game to the state it was in prior to running the simulation if the simulation was started using this function. If this is a problem, instead use the 'Run' button in Roblox Studio.

See also:


Returns

void

Stop

void

This function ends the game's simulation if it is running.

The simulation can be started using RunService:Run() or the 'Run' button in Roblox Studio. When the simulation is stopped, RunService:IsRunning() will return false and RunService:IsEdit() will return true.

In contrast to the 'Stop' button in Roblox Studio, calling this function will not restore the game to the state it was in prior to the simulation being run. This means any changes made to the game by the physics simulation and scripts will persist after the simulation has ended.

See also:


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 step argument indicates the time that has elapsed since the previous frame.

As Heartbeat fires every frame, it runs on a variable frequency. This means the rate will vary depending on the performance of the machine. If the game is running at 40 FPS, then Heartbeat will fire 40 times per second and the step argument will be roughly 1/40th of a second.

The step argument can be used to account for the variable frequency of this event, for example:


local RunService = game:GetService("RunService")
local RATE_PER_SECOND = 2
RunService.Heartbeat:Connect(function(step)
local increment = RATE_PER_SECOND * step
end)

There is no guarantee that functions connected to this event will fire at the exact same time, or in any specific order. For an alternative where the priority can be specified, see RunService:BindToRenderStep().

Parameters

deltaTime: number

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


Code Samples

Printing Heartbeat Frequency

local RunService = game:GetService("RunService")
local LOOP_COUNT = 5
local count = 0
local connection
function onHeartbeat(step)
if count < LOOP_COUNT then
count = count + 1
print("Time between each loop: " .. step)
else
connection:Disconnect()
end
end
connection = RunService.Heartbeat:Connect(onHeartbeat)

PostSimulation

Parameters

deltaTimeSim: number

PreAnimation

Parameters

deltaTimeSim: number

PreRender

Parameters

deltaTimeRender: number

PreSimulation

Parameters

deltaTimeSim: number

RenderStepped

The RenderStepped event fires every frame, prior to the frame being rendered. The step argument indicates the time that has elapsed since the previous frame.

RenderStepped does not run in parallel to Roblox's rendering tasks and code connected to RenderStepped must be executed prior to the frame being rendered. This can lead to significant performance issues if RenderStepped is used inappropriately. To avoid this, only use RenderStepped for code that works with the camera or character. Otherwise, RunService.Heartbeat should be used.

As RenderStepped fires every frame, it runs on a variable frequency. This means the rate will vary depending on the performance of the machine. If the game is running at 40 FPS, then RenderStepped will fire 40 times per second and the step argument will be roughly 1/40th of a second.

The step argument can be used to account for the variable frequency of this event, for example:


local RunService = game:GetService("RunService")
local RATE_PER_SECOND = 2
RunService.RenderStepped:Connect(function(step)
local increment = RATE_PER_SECOND * step
end)

There is no guarantee that functions connected to this event will fire at the exact same time, or in any specific order. For an alternative where the priority can be specified, see RunService:BindToRenderStep().

As RenderStepped is client-side only, it can be used in a LocalScript or a ModuleScript required by a LocalScript.

Parameters

deltaTime: number

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


Code Samples

Spin GuiObject

local RunService = game:GetService("RunService")
local guiObject = script.Parent
local degreesPerSecond = 180
local function onRenderStep(deltaTime)
local deltaRotation = deltaTime * degreesPerSecond
guiObject.Rotation = guiObject.Rotation + deltaRotation
end
RunService.RenderStepped:Connect(onRenderStep)

Stepped

The Stepped event fires every frame prior to the physics simulation. The step argument indicates the time that has elapsed since the previous frame.

As Stepped fires every frame, it runs on a variable frequency. This means the rate will vary depending on the performance of the machine. If the game is running at 40 FPS, then Stepped will fire 40 times per second and the step argument will be roughly 1/40th of a second.

The step argument can be used to account for the variable frequency of this event, for example:


local RunService = game:GetService("RunService")
local RATE_PER_SECOND = 2
RunService.Stepped:Connect(function(time, step)
local increment = RATE_PER_SECOND * step
end)

There is no guarantee that functions connected to this event will fire at the exact same time, or in any specific order. For an alternative where the priority can be specified, see RunService:BindToRenderStep().

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.


Code Samples

Using the Stepped Event

local RunService = game:GetService("RunService")
local function onStepped()
print("Stepped")
end
RunService.Stepped:Connect(onStepped)