Workspace
The core job of Workspace is to hold objects that exist in the 3D world, effectively BaseParts and Attachments. While 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 that 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 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 3D world 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
Workspace can be accessed several ways, all of which are valid.
- workspace
- game.Workspace
- game:GetService("Workspace")
Notes
- Objects that require adornment, such as ParticleEmitters and BillboardGuis, will be at the 0, 0, 0 position when parented to Workspace without an adornee otherwise being set.
- The Model:MakeJoints() and Model:BreakJoints() methods inherited from the Model class are overridden by Workspace:MakeJoints() and Workspace:BreakJoints() which can only be used in plugins.
- It is impossible to delete Workspace.
- A client's current Camera object can be accessed using the Workspace.CurrentCamera property.
- The Terrain object can be accessed using the Workspace.Terrain property.
Summary
Properties
The air density at ground level, used in the aerodynamic force model.
Determines whether assets created by other users can be sold in the game.
Specifies the animation throttling mode for the local client.
The Camera object being used by the local player.
The amount of time, in seconds, that the game has been running.
Determines the height at which falling BaseParts and their ancestor Models are removed from Workspace.
Determines whether the physics engine computes aerodynamic forces on BaseParts whose EnableFluidForces property is true.
Specifies the global wind vector for animated terrain grass, dynamic clouds, and particles.
Determines the acceleration due to gravity applied to falling BaseParts.
Enables support for constraints for IKControls. If disabled, IKControls ignore physics constraints.
Sets whether character Heads and Accessories should be downloaded as MeshParts.
Controls the logic used to select the assembly root part when using any of the mover constraints.
Sets how the solver will advance the physics simulation forward in time.
Configures when the engine resumes event handlers.
Configures how the engine decides when to Stream content away from players.
Whether content streaming is enabled for the place.
Determines whether StreamingIntegrityMode is active.
Minimum distance that content will be streamed to players with high priority.
Maximum distance that content will be streamed to players.
A reference to the Terrain object parented to the Workspace.
Determines whether parts in different groups set to not collide will ignore collisions and touch events.
Sets the level of detail on the model for experiences with instance streaming enabled.
Controls the model streaming behavior on Models when instance streaming is enabled.
The primary part of the Model, or nil if not explicitly set.
Editor-only property used to scale the model around its pivot. Setting this property will move the scale as though Model/ScaleTo was called on it.
Determines where the pivot of a Model which does not have a set Model.PrimaryPart is located.
Methods
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's Unix time in seconds.
Creates joints between the specified Parts and any touching parts depending on the parts' surfaces and the specified joint creation mode.
Returns true if the game has the PGS Physics solver enabled.
Breaks all joints between the specified BaseParts and other BaseParts.
Positions and zooms the Workspace.CurrentCamera to show the extent of BaseParts currently in the Workspace.
Returns true if any of the given BasePart are touching any other parts.
Casts a block shape in a given direction and returns a RaycastResult if the shape hits a BasePart or Terrain cell.
Returns an array of parts whose bounding boxes overlap a given box.
Returns an array of parts whose bounding boxes overlap a given sphere.
Returns an array of parts whose occupied space is shared with the given part.
- IKMoveTo(part : BasePart,target : CFrame,translateStiffness : number,rotateStiffness : number,collisionsMode : Enum.IKCollisionsMode):void
Moves the specified part to the specified location via inverse kinematics rather than moving it there directly, to ensure any joints, constraints, or collisions that part is participating in remain physically satisfied.
Casts a ray using an origin, direction, and optional RaycastParams, then returns a RaycastResult if an eligible object or terrain intersects the ray.
- Spherecast(position : Vector3,radius : number,direction : Vector3,params : RaycastParams):RaycastResult?
Casts a spherical shape in a given direction and returns a RaycastResult if the shape hits a BasePart or Terrain cell.
Advances the simulation for parts in the world forward based on a specified time increment and an optional set of BaseParts.
Sets this model to be persistent for the specified player. Model.ModelStreamingMode must be set to PersistentPerPlayer for behavior to be changed as a result of addition.
Returns a description of a volume that contains all parts of a Model.
Returns the size of the smallest bounding box that contains all of the BaseParts in the Model, aligned with the Model.PrimaryPart if it is set.
Returns all the Player objects that this model object is persistent for. Behavior varies based on whether this method is called from a Script or a LocalScript.
Returns the canonical scale of the model, which defaults to 1 for newly created models and will change as it is scaled via Model/ScaleTo.
Moves the PrimaryPart to the given position. If a primary part has not been specified, the root part of the model will be used.
Makes this model no longer persistent for specified player. Model.ModelStreamingMode must be set to PersistentPerPlayer for behavior to be changed as a result of removal.
Sets the scale factor of the model, adjusting the sizing and location of all descendant Instances such that they have that scale factor relative to their initial sizes and locations when scale factor was 1.
Shifts a Model by the given Vector3 offset, preserving the model's orientation. If another BasePart or Terrain already exists at the new position then the Model will overlap said object.
Gets the pivot of a PVInstance.
Transforms the PVInstance along with all of its descendant PVInstances such that the pivot is now located at the specified CFrame.
Events
Fires when persistent models have been sent to the specified player.
Properties
AirDensity
The ground level (Y of 0) air density in RMU/stud³ units (see Roblox Units), used to calculate the aerodynamic force if Workspace.FluidForces is Experimental. The default corresponds to realistic sea level air density at standard temperature and pressure. Air density decays as the Y altitude increases, reaching 5% of its ground level value at 100,000 studs. Below Y of 0, the air density is fixed at the input value.
AllowThirdPartySales
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 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.
AvatarUnificationMode
CSGAsyncDynamicCollision
ClientAnimatorThrottling
Specifies the Enum.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:
- In-game FPS
- Number of active animations
CurrentCamera
The Camera object being used by the local player.
How to use CurrentCamera
When looking for a client's Camera object, use this property rather than looking for a child of Workspace named "Camera".
When you set this property, all other Camera objects in the Workspace are destroyed, including the previous CurrentCamera. If you set this property to nil or to a camera that is not a descendant of the Workspace (or the CurrentCamera is otherwise destroyed), a new Camera will be created and assigned. Avoid these scenarios, as destroying the camera can have unintended consequences.
For more information, see Scripting the Camera.
DistributedGameTime
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.
print(workspace.DistributedGameTime) --> Time the game started runningprint(os.time()) --> Time since epoch (1 January 1970, 00:00:00) UTCprint(tick()) --> Time since epoch (1 January 1970, 00:00:00) system timeprint(time()) --> Time the game started runningprint(elapsedTime()) --> Time since Roblox started running
FallenPartsDestroyHeight
This property determines the height at which the Roblox engine automatically removes falling BaseParts and their ancestor Models from Workspace by parenting them 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, that model will also be removed. This applies to all model ancestors of the part.
This property is clamped between -50,000 and 50,000 because BaseParts do not simulate or render properly at a great distance from the origin due to floating point inaccuracies.
This property can be read by scripts, but can only be set by plugins, the command bar, or the properties window in Studio.
FluidForces
With this property enabled, the physics engine computes aerodynamic forces on BaseParts whose EnableFluidForces property is true. The default, Default, disables aerodynamic forces. Note that this property cannot be set through scripting and instead must be toggled in Studio.
GlobalWind
This property specifies the direction and strength that wind blows through the experience, affecting terrain grass, dynamic clouds, and particles. See the Global Wind article for details.
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.
Code Samples
local MOON_GRAVITY_RATIO = 1.62 / 9.81
local DEFAULT_GRAVITY = 196.2
local MOON_GRAVITY = DEFAULT_GRAVITY * MOON_GRAVITY_RATIO
-- Create a touch pad
local pad = Instance.new("Part")
pad.Size = Vector3.new(5, 1, 5)
pad.Position = Vector3.new(0, 0.5, 0)
pad.Anchored = true
pad.BrickColor = BrickColor.new("Bright green")
pad.Parent = workspace
-- Listen for pad touch
local enabled = false
local debounce = false
local function onPadTouched(_hit)
if not debounce then
debounce = true
enabled = not enabled
workspace.Gravity = enabled and MOON_GRAVITY or DEFAULT_GRAVITY
pad.BrickColor = enabled and BrickColor.new("Bright red") or BrickColor.new("Bright green")
task.wait(1)
debounce = false
end
end
pad.Touched:Connect(onPadTouched)
IKControlConstraintSupport
Enables support for constraints for IKControls. The Default value is the same as Enabled. If disabled, IKControls ignore physics constraints. See IKControl for additional details.
InsertPoint
MeshPartHeadsAndAccessories
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.
ModelStreamingBehavior
MoverConstraintRootBehavior
Controls the logic used to select the assembly root part for mechanisms that use any of the following constraints:
When this property is set to Enum.MoverConstraintRootBehaviorMode.Enabled, these constraints will be ignored when selecting the assembly root part if the constraint does not transmit forces between two parts (some examples being AngularVelocity.ReactionTorqueEnabled set to false, AlignPosition.ReactionForceEnabled set to false, or AlignOrientation.Mode set to Enum.OrientationAlignmentMode.OneAttachment).
When this property is set to Enum.MoverConstraintRootBehaviorMode.Disabled, these constraints may be erroneously considered when selecting the assembly root part, leading to inconsistent network ownership and delays when adding these constraints to a mechanism.
PathfindingUseImprovedSearch
PhysicsSteppingMethod
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.
Option | Description |
---|---|
Adaptive | The 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. |
Fixed | All simulated assemblies inside the workspace will advance forward at 240 Hz. This option is best for optimal stability and simulation accuracy. |
Default | The 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.
PlayerCharacterDestroyBehavior
PrimalPhysicsSolver
RejectCharacterDeletions
RenderingCacheOptimizations
ReplicateInstanceDestroySetting
Retargeting
SandboxedInstanceMode
SignalBehavior
This property determines whether event handlers will be resumed immediately when the event fires, or deferred and then resumed at a later resumption point. Resumption points currently include:
- Input processing (resumes once per input to be processed, see UserInputService)
- Legacy waiting script resumption such as wait(), spawn(), and delay()
For more information, see Deferred Events.
StreamOutBehavior
The StreamOutBehavior controls where content will be unloaded from the ReplicationFocus based on device Memory Conditions, or based on Streaming Radius.
See also:
- Workspace.StreamingEnabled which controls whether content streaming is enabled
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
If instance streaming is enabled, 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.
StreamingMinRadius
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:
- Workspace.StreamingEnabled which controls whether content streaming is enabled
StreamingTargetRadius
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:
- Workspace.StreamingEnabled which controls whether content streaming is enabled
Terrain
This property is a reference to the Terrain object parented to the Workspace.
See Environmental Terrain for more information.
TouchEventsUseCollisionGroups
TouchesUseCollisionGroups
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.
Methods
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.
print(workspace:GetNumAwakeParts()) -- prints the number of 'awake' parts
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 doesn't apply to them. When a force is applied to a 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.
local i = 0while true doi += 1if i % 5 == 0 thentask.wait()endlocal part = Instance.new("Part", workspace)end
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
local Players = game:GetService("Players")
local player = Players.LocalPlayer
while task.wait(1) do
if workspace:GetRealPhysicsFPS() > 65 then
player:Kick()
end
end
GetServerTimeNow
GetServerTimeNow() returns the client's best approximation of the current time on the server. This is useful for creating synchronized experiences as every client will get about the same results regardless of their timezone or local clock.
This returns a Unix timestamp, similar to os.time(), that can be used with os.date() or with DateTime.fromUnixTimestamp().
The timestamp returned by this function is smoothed so that:
- It is monotonic; its value will never decrease.
- It moves at the same rate as the local clock to within 0.6%.
GetServerTimeNow() is expensive to call compared to DateTime.now(), and is less precise than os.clock(), so it should be used to make sure an event starts at the right real world time or to adjust things periodically to keep a series of events in sync.
This function relies on the server, so calling it from a client that isn't connected will throw an error. Also note that this function is not suitable for things like timed rewards as it is not secure compared to tracking such timers on the server.
See also:
- DistributedGameTime, a game-time clock
Returns
The estimated Unix timestamp on the server.
JoinToOutsiders
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.
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 Enum.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.
-- finished moving a selection, make joints
local function finishedMovingParts(parts)
local joinMode = Plugin:GetJoinMode()
workspace:JoinToOutsiders(parts, joinMode)
end
-- started moving a selection, break joints
local function startMovingParts(parts)
workspace:UnjoinFromOutsiders(parts)
end
Parameters
An array of BaseParts for whom joints are to be made.
The Enum.JointCreationMode to be used. Passing in Enum.JointCreationMode.All or Enum.JointCreationMode.Surface has the same behavior which equates to Join Always.
Returns
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.
print(workspace:PGSIsEnabled()) -- true = PGS solver enabledprint(workspace:PGSIsEnabled()) -- false = Legacy solver enabled
Returns
True if the PGS solver is enabled.
UnjoinFromOutsiders
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.
-- finished moving a selection, make joints
local function finishedMovingParts(parts)
local joinMode = Plugin:GetJoinMode()
workspace:JoinToOutsiders(parts, joinMode)
end
-- started moving a selection, break joints
local function startMovingParts(parts)
workspace:UnjoinFromOutsiders(parts)
end
Parameters
An array of BaseParts for whom joints are to be broken.
Returns
ZoomToExtents
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
Events
PersistentLoaded
This event fires every time a player has been sent all current persistent models and part-less atomic models. The player parameter indicates which player has received all applicable instances.
Note that experience loading happens before persistent loading, and firing of the DataModel.Loaded event does not indicate that all persistent models are present.