Workspace

Show Deprecated
Not Creatable
Service

The Workspace is the service in which any objects that are to be rendered in the 3D world exist. Objects not descending from Workspace will not be rendered or physically interact with the world.

The core job of the Workspace is to hold objects that exist in the 3D world, BaseParts and Attachments. Whilst such objects are descendant of Workspace, they will be active. For BaseParts this means they will be rendered, and physically interact with other parts and the world. For Attachments this means objects adorned to them, such as ParticleEmitters, Beams and BillboardGuis will render.

Understanding this behavior is important, as it means objects can be removed from the Workspace when they are not needed. For example, map Models can be removed from the Workspace when a different map is being played on. Objects that are not immediately needed in the Workspace are generally stored in ReplicatedStorage or ServerStorage.

In its role as the holder of active 3D objects, Workspace includes a number of useful functions related to parts, their positions and joints between them.

Accessing the Workspace

The Workspace can be accessed several ways, all of which are valid.

  • workspace
  • game.Workspace
  • game:GetService("Workspace")

Note:

Summary

Properties

Determines whether assets created by other users can be sold in the game.

NOT REPLICATED

Determines whether a new, optimized animation runtime is used, which includes a bug fix to weighted blending of AnimationTracks.

NOT SCRIPTABLE

Specifies the animation throttling mode for the local client.

The Camera object being used by the local player.

NOT REPLICATED

The amount of time, in seconds, that the game has been running.

NOT REPLICATED

Determines the height at which falling BaseParts (and their ancestor Models) are removed from Workspace.

Determines the acceleration due to gravity applied to falling BaseParts.

Sets behavior for all Humanoids for setting part collisions.

NOT SCRIPTABLE

Sets whether character Heads and Accessories should be downloaded as MeshParts.

NOT SCRIPTABLE

Sets how the solver will advance the physics simulation forward in time.

NOT SCRIPTABLE

Configures how the engine decides when to Stream content away from players.

NOT SCRIPTABLE

Whether content streaming is enabled for the place.

Determines whether StreamingIntegrityMode is active.

NOT SCRIPTABLE

Minimum distance that content will be streamed to players with high priority.

NOT SCRIPTABLE

Maximum distance that content will be streamed to players.

NOT SCRIPTABLE

A reference to the Terrain object parented to the Workspace.

READ ONLY
NOT REPLICATED

Determines whether parts in different groups set to not collide will ignore collisions and touch events.

NOT SCRIPTABLE

Events

Methods

BreakJoints(objects: Objects): void  

Goes through all BaseParts given, breaking any joints connected to these parts.

CalculateJumpDistance(gravity: number, jumpPower: number, walkSpeed: number): number  


CalculateJumpHeight(gravity: number, jumpPower: number): number  


CalculateJumpPower(gravity: number, jumpHeight: number): number  



Returns true if the game has the PGS Physics solver enabled.


Returns the number of BaseParts that are deemed physically active, due to being recently under the influence of physics.


Returns an integer, between 0 and 100, representing the percentage of real-time that physics simulation is currently being throttled to.


Returns the number of frames per second that physics is currently being simulated at.


Returns the server epoch time in seconds.

JoinToOutsiders(objects: Objects, jointType: JointCreationMode): void  

Creates joints between the specified Parts and any touching parts depending on the parts' surfaces and the specified joint creation mode.

MakeJoints(objects: Objects): void  

Goes through all BaseParts given. If any part's side has a SurfaceType that can make a joint it will create a joint with any adjacent parts.


Returns true if the game has the PGS Physics solver enabled.


Determines whether physics throttling is enabled.

UnjoinFromOutsiders(objects: Objects): void  

Breaks all joints between the specified BaseParts and other BaseParts.

ZoomToExtents(): void  

Positions and zooms the Workspace.CurrentCamera to show the extent of BaseParts currently in the Workspace.

Properties

AllowThirdPartySales

Not Replicated

This Workspace property determines whether assets created by other uses can be sold in the game.

What are third party sales?

When this value is false, as it is by default, only assets created by the place creator (be it a player or a group) and Roblox can be sold using MarketplaceService.

In most cases, games do not need to sell third party assets. However, some games such as trade hangouts require this feature and therefore it exists as an opt-in option.

What third party products can I sell?

Note, [developer products](/production/monetization/developer-products can only be sold in the game they are associated with, regardless of what AllowThirdPartySales is set to. This property affects Game Passes and clothing.

AnimationWeightedBlendFix

Not Scriptable

Enabling this property opts your experience into using a new, optimized animation runtime. This runtime contains a fix to a longstanding bug that
AnimationTrackswith the same priority would not always blend based on their relative track weights, but might instead override each other based on the play order, or the replication order. Enabling this property requires you to make changes to the priority levels of the AnimationTracks in your experience if
you relied on the behavior of this bug to have AnimationTracks with the same priority overriding each other. Always use AnimationTrack.Priority to force one animation to override another already-playing animation on the same Animator.

ClientAnimatorThrottling

Specifies the ClientAnimatorThrottlingMode to use for the local client.

When enabled, animations on remotely-simulated Model instances will begin to throttle. The throttler calculates throttling intensity using:

  • Visibility of a Model in relation to the Camera
  • In-game FPS
  • Number of active animations

CurrentCamera

Not Replicated

The Camera object being used by the local player.

How to use CurrentCamera

This property can be set. When it is set, all other Camera objects in the Workspace are destroyed, including the previous CurrentCamera. If this property is set to nil, or the CurrentCamera is otherwise destroyed, a new Camera will be created and assigned. Developers should avoid setting this property to nil or destroying the CurrentCamera however as it can have unintended consequences.

When looking for a client's Camera object, developers should use this property rather than looking for a child of Workspace named 'Camera'.

What can be done with CurrentCamera

Accessing a client's current Camera object brings a range of uses.

Below is an example of how this property can be used to access the Camera object and increase its Camera.FieldOfView.


1workspace.CurrentCamera.FieldOfView = 100
2

DistributedGameTime

Not Replicated

The amount of time, in seconds, that the game has been running.

Despite the title, this value is currently not 'Distributed' across the client and the server. Instead, on the server it represents how long the server has been running. On the client, it represents how long the client has been connected to the server.

Developers should not rely on the above behavior, and it is possible this property will be synchronized across clients and the server in the future.

Those looking for the time since the program started running should use the 'time' function instead. See below for a comparison between DistributedGameTime and its alternatives.


1print(workspace.DistributedGameTime) --> Time the game started running
2print(os.time()) --> Time since epoch (1 January 1970, 00:00:00) UTC
3print(tick()) --> Time since epoch (1 January 1970, 00:00:00) system time
4print(time()) --> Time the game started running
5print(elapsedTime()) --> Time since Roblox started running
6

FallenPartsDestroyHeight

This property determines the height at which falling BaseParts (and their ancestor Models) are removed from Workspace.

Parts being removed at the FallenPartsDestroyHeight

What happens to falling parts?

For performance reasons, Roblox automatically parents parts that fall below this value to nil. This is to prevent parts that have fallen off the map from continuing to fall forever.

If a part removed due to this behavior is the last part in a Model, then that model will also be removed. This applies to all model ancestors of the part.

This property can be read by scripts, but can only be set by plugins, the command bar, or the properties window in Studio.

This property is clamped between -50,000 and 50,000. This is because BaseParts do not simulate or render properly at a great distance from the origin due to floating point inaccuracies.

Gravity

Determines the acceleration due to gravity applied to falling BaseParts. This value is measured in studs per second squared and by default is set to 196.2 studs/second2. By changing this value, developers can simulate the effects of lower or higher gravity in game.

HumanoidOnlySetCollisionsOnStateChange

Not Scriptable

Sets the behavior of all Humanoids for setting part collisions. See Enum.HumanoidOnlySetCollisionOnStateChange for description of each option.

MeshPartHeadsAndAccessories

Not Scriptable

Sets whether character Heads and Accessories should be downloaded as MeshParts. The "Default" value is the same as "Enabled". If this feature is enabled, built-in avatars will use MeshParts for the character's Head and Accessories.

PhysicsSteppingMethod

Not Scriptable

Sets how the solver will advance the physics simulation forward in time. This option is not scriptable and must be set from the PhysicsSteppingMethod property of Workspace within Studio. See Adaptive Timestepping for details.

OptionDescription
AdaptiveThe engine attempts to assign optimal simulation rates for individual assemblies of either 240 Hz, 120 Hz, or 60 Hz. This setting is optimized for performance.
FixedAll simulated assemblies inside the workspace will advance forward at 240 Hz. This option is best for optimal stability and simulation accuracy.
DefaultThe current default is Fixed.

Note that when assemblies of different simulation rates become connected via Constraints or collisions, the combined mechanism will default to the highest simulation rate for stability.

ReplicateInstanceDestroySetting

Not Scriptable

SignalBehavior

Not Scriptable

StreamOutBehavior

Not Scriptable

The StreamOutBehavior controls where content will be unloaded from the ReplicationFocus based on device Memory Conditions, or based on Streaming Radius.

See also:

StreamingEnabled

The StreamingEnabled property determines whether game content streaming is enabled for the place. This property is not scriptable and therefore must be set on the Workspace object in Studio.

See also:

StreamingIntegrityMode

Not Scriptable

If Workspace.StreamingEnabled is activated, an experience may behave in unintended ways if a player's character moves into a region of the world that has not been streamed to their client. The Streaming Integrity feature offers a way to avoid those potentially problematic situations. Please see the StreamingIntegrityMode documentation and the Content Streaming article for more details.

StreamingMinRadius

Not Scriptable

The StreamingMinRadius property indicates the radius around the player's character or the current ReplicationFocus in which content will be streamed in at the highest priority. Defaults to 64 studs.

Care should be taken when increasing the default minimum radius since doing so will require more memory and more server bandwidth at the expense of other components.

See also:

StreamingTargetRadius

Not Scriptable

The StreamingTargetRadius property controls the maximum distance away from the player's character or the current ReplicationFocus in which content will be streamed in. Defaults to 1024 studs.

Note that the engine is allowed to retain previously loaded content beyond the target radius, memory permitting.

See also:

Terrain

Read Only
Not Replicated

This property is a reference to the Terrain object parented to the Workspace.

An example of Roblox terrain

This property, like Workspace.CurrentCamera, ensures that developers to not inadvertently index a descendant of Workspace named 'Terrain' when looking for a game's Terrain object. Without this property, developers would need to use the Instance:FindFirstChildOfClass() function.


1workspace.Terrain.WaterColor = Color3.new(0, 1, 0) -- make the water green
2

TouchesUseCollisionGroups

Not Scriptable

This property determines whether parts in different groups set to not collide will ignore collisions and touch events. By default, the value of this property is set to false.

When this property is enabled, parts in different groups set to not collide will also ignore the CanTouch property, similar to how BasePart.CanCollide is ignored. For more information on the behavior of CanTouch, please visit its property page.

UnionsScaleNonuniformly

Not Scriptable

Events

PersistentLoaded

Parameters

player: Player

Methods

BreakJoints

void
Plugin Security

Goes through all BaseParts given, breaking any joints connected to these parts.

This function will break any of the following types of joints:

Unlike Model.MakeJoints, this function requires an array of BaseParts as a parameter. This array is given as follows:


1workspace:BreakJoints({part1, part2, part3})
2

Note, this function cannot be used by scripts and will only function in plugins.

Parameters

objects: Objects

An array of BaseParts for whom joints are to be broken.


Returns

void

CalculateJumpDistance

Roblox Script Security

Parameters

gravity: number
jumpPower: number
walkSpeed: number

Returns

CalculateJumpHeight

Roblox Script Security

Parameters

gravity: number
jumpPower: number

Returns

CalculateJumpPower

Roblox Script Security

Parameters

gravity: number
jumpHeight: number

Returns

ExperimentalSolverIsEnabled

Local User Security

Returns true if the game has the PGS Physics solver enabled.

The PGS Physics solver was previously called the 'Experimental' solver, before becoming Roblox's default server. This function returns the same result as Workspace:PGSIsEnabled().


1print(workspace:PGSIsEnabled() == workspace:ExperimentalSolverIsEnabled()) -- true
2

This function can only be used by plugins and the command bar.


Returns

True if the experimental solver is to be enabled.

GetNumAwakeParts

Returns the number of BaseParts that are deemed physically active, due to being recently under the influence of physics.

This function provides a measure of how many BaseParts are being influenced by, or recently under the influence of, physical forces.


1print(workspace:GetNumAwakeParts()) -- prints the number of 'awake' parts
2

Sleeping vs Awake Parts

In order to ensure good performance, Roblox sets BaseParts in which physics are not being applied to a 'sleeping' state. BaseParts with BasePart.Anchored set to true, for example, will always be sleeping as physics does not apply to them. When a force is applied to an non anchored BasePart, an 'awake' state will be applied. Whilst a BasePart is awake the Roblox physics engine will perform continuous calculations to ensure physical forces interact correctly with the part. Once the BasePart is no longer subject to physical forces, it will revert to a 'sleeping' state.


Returns

The number of awake parts.

GetPhysicsThrottling

Returns an integer, between 0 and 100, representing the percentage of real-time that physics simulation is currently being throttled to.

This function can be used to determine whether, and to what degree, physics throttling is occurring.

What is physics throttling?

Physics throttling occurs when the physics engine detects it cannot keep up with the game in realtime. When physics is being throttled, it will update less frequently causing BaseParts to appear to move slower.

Without throttling, the physics simulation would fall further behind out of sync with the game. This can lead to lower frame rates and other undesirable behavior.

Objects associated with Humanoids are exempt from physics throttling.

See also Workspace:SetPhysicsThrottleEnabled().

Demonstrating physics throttling

Developers should always avoid creating places that overload the physics engine, as it leads to sub-par experience for players. Those wishing to simulate physics throttling for research purposes however, need only create a lot of Parts very quickly.


1local i = 0
2while true do
3 i = i + 1
4 if i % 5 == 0 then
5 wait()
6 end
7 local part = Instance.new("Part", workspace)
8end
9

Returns

The percentage of real-time that physics simulation is currently being throttled to.

GetRealPhysicsFPS

Returns the number of frames per second that physics is currently being simulated at.

Using GetRealPhysicsFPS to combat exploiters

A common use of this function is to detect if exploiters are increasing their local physics frame rate to move faster. This is generally done by comparing the result returned by a client's GetRealPhysicsFPS to a maximum that will not be breached in normal circumstances (usually 65 or 70). If this limit is breached, developers can use the Player:Kick() function to remove that Player from the game. It is important to remember that, although this practice may be effective sometimes, client-side anti-exploiter measures are never 100% reliable.


Returns

Returns the number of frames per second that physics is currently being simulated at.

Code Samples

Workspace:GetRealPhysicsFPS

1local Players = game:GetService("Players")
2
3local player = Players.LocalPlayer
4
5while task.wait(1) do
6 if workspace:GetRealPhysicsFPS() > 65 then
7 player:Kick()
8 end
9end

GetServerTimeNow

GetServerTimeNow returns the epoch time on the server with microsecond precision. The time is adjusted for drift and smoothed monotonically (it is guaranteed to be non-decreasing). The server clock progresses no faster than 1.006× speed and no slower than 0.994× speed.

This function is useful for creating synchronized experiences, as it has three properties necessary for doing so: it's a real-world time clock, it's monotonic, and it has decent precision.

This function relies on the server, so calling it from a client that isn't connected will throw an error.

See also:


Returns

The estimated epoch time on the server.

JoinToOutsiders

void

This function creates joints between the specified Parts and any touching parts depending on the parts' surfaces and the specified joint creation mode.

This function creates joints between the specified Parts and any planar touching surfaces, depending on the parts' surfaces and the specified joint creation mode.

  • Glue, Studs, Inlets, Universal, Weld, and Smooth surfaces will all create Weld instances.
  • Spheres will not surface-weld to anything. The rounded sides of cylinders will not surface-weld, but the flat end sides will.
  • Hinge and Motor surfaces will still create Rotate and RotateP joint instances, regardless of part shape.

The first parameter is an array of BaseParts. Joints will only be created between the parts in the array and not in the array. Joints will not be created between the parts in the array.

The second parameter is a JointCreationMode that determines how joints will be created. Passing in either enum value, Enum.JointCreationMode.All or Enum.JointCreationMode.Surface, has the same behavior which equates to Join Always

This function is used by the Roblox Studio Move tool when the user finishes moving a selection. In conjunction with Plugin:GetJoinMode() and Workspace:UnjoinFromOutsiders() it can be used to retain join functionality when developing custom studio build tools. See the snippets below for an example.


1-- finished moving a selection, make joints
2local function finishedMovingParts(parts)
3 local joinMode = Plugin:GetJoinMode()
4 workspace:JoinToOutsiders(parts, joinMode)
5end
6

1-- started moving a selection, break joints
2local function startMovingParts(parts)
3 workspace:UnjoinFromOutsiders(parts)
4end
5

Parameters

objects: Objects

An array of BaseParts for whom joints are to be made.

The JointCreationMode to be used. Passing in Enum.JointCreationMode.All or Enum.JointCreationMode.Surface has the same behavior which equates to Join Always.


Returns

void

MakeJoints

void
Plugin Security

Deprecated

SurfaceType based joining is deprecated, do not use MakeJoints for new projects. WeldConstraints and HingeConstraints should be used instead.

Goes through all Parts given. If any part's side has a SurfaceType that can make a joint it will create a joint with any adjacent parts.

Joints will be created between the specified Parts and any planar touching surfaces, depending on the parts' surfaces.

  • Smooth surfaces will not create joints
  • Glue surfaces will create a Glue joint
  • Weld will create a Weld joint with any surface except for Unjoinable
  • Studs, Inlet, or Universal will each create a Snap joint with either of other the other two surfaces (e.g. Studs with Inlet and Universal)
  • Hinge and Motor surfaces create Rotate and RotateV joint instances

Unlike Model:MakeJoints(), this function requires an array of parts as a parameter. This array is given as follows:


1workspace:MakeJoints({part1, part2, part3})
2

Joints are broken if enough force is applied to them due to an Explosion, unless a ForceField object is parented to the BasePart or ancestor Model. For this reason, they are often used to make simple destructible buildings and other models.

Parameters

objects: Objects

An array of parts for whom joints are to be made.


Returns

void

No return.

PGSIsEnabled

Returns true if the game has the PGS Physics solver enabled.

As Workspace.PGSPhysicsSolverEnabled cannot be accessed by scripts, the PGSIsEnabled function allows developers to tell which physics solver the game is using.


1print(workspace:PGSIsEnabled()) -- true = PGS solver enabled
2print(workspace:PGSIsEnabled()) -- false = Legacy solver enabled
3

Returns

True if the PGS solver is enabled.

SetMeshPartHeadsAndAccessories

void
Roblox Script Security

Returns

void

SetPhysicsThrottleEnabled

void
Local User Security

This property determines whether physics throttling is enabled.

Historically this function could be used by plugins. However, for security reasons this has been changed and now it can only be used by developers in the command bar.

Note, currently physics throttling will always stay enabled regardless if this function is used or not.

What is physics throttling?

Physics throttling occurs when the physics engine detects it cannot keep up with the game in realtime. When physics is being throttled, it will update less frequently causing BaseParts to appear to move slower.

Without throttling, the physics simulation would fall further behind out of sync with the game. Without physics throttling, users experience lower frame rates.

Objects associated with Humanoids are exempt from physics throttling.

Developers can use Workspace:GetPhysicsThrottling() to determine the degree to which physics are being throttled.

Demonstrating physics throttling

Developers should always avoid creating places that overload the physics engine, as it leads to sub-par experience for players. Those wishing to simulate physics throttling for research purposes however, need only create a lot of Parts very quickly.


1local i = 0
2while true do
3 i = i + 1
4 if i % 5 == 0 then
5 wait()
6 end
7 local part = Instance.new("Part", workspace)
8end
9

Parameters

value: boolean

Whether or not physics throttling is enabled.


Returns

void

UnjoinFromOutsiders

void

Breaks all joints between the specified BaseParts and other BaseParts.

This function requires an array of BaseParts. Note, joints will not be broken between these BaseParts (each other), only between these BaseParts and other BaseParts not in the array.

This function is used by the Roblox Studio Move tool when the user starts moving a selection. In conjunction with Plugin:GetJoinMode() and Workspace:JoinToOutsiders() it can be used to retain join functionality when developing custom studio build tools. See the snippets below for an example.


1-- finished moving a selection, make joints
2local function finishedMovingParts(parts)
3 local joinMode = Plugin:GetJoinMode()
4 workspace:JoinToOutsiders(parts, joinMode)
5end
6

1-- started moving a selection, break joints
2local function startMovingParts(parts)
3 workspace:UnjoinFromOutsiders(parts)
4end
5

Parameters

objects: Objects

An array of BaseParts for whom joints are to be broken.


Returns

void

ZoomToExtents

void
Plugin Security

Positions and zooms the Workspace.CurrentCamera to show the extent of BaseParts currently in the Workspace.

This function was used in the, now removed, 'Zoom To Extents' button in Roblox Studio. It exhibits similar behavior to the 'Zoom To' (F shortcut) feature, however it shows the extents of the Workspace rather than the currently selected object.

This function cannot be used in scripts but will function in the command bar or plugins.


Returns

void