Player
A Player object is a client that is currently connected. These objects are added to the Players service when a new player connects, then removed when they eventually disconnect from the server.
The Instance.Name property reflects the player's username. When saving information about a player, you should use their Player.UserId since it is possible that a player can change their username.
There are several similar methods in the Players service for working with Player objects. Use these over their respective Instance methods:
- You can get a table of current Player objects using Players:GetPlayers(); again, use this instead of Instance:GetChildren().
- To detect the addition of Player objects, it is recommended to use the Players.PlayerAdded event (instead of Instance.ChildAdded on the Players service).
- Similarly, you can detect the removal of Player objects using Players.PlayerRemoving, which fires just before the Player is removed (instead of Instance.ChildRemoved which fires after). This is important if you are saving information about the player that might be removed or cleaned up on-removal.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
-- Create a container for leaderstats
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
-- Create one leaderstat value
local vScore = Instance.new("IntValue")
vScore.Name = "Score"
vScore.Value = 0
vScore.Parent = leaderstats
-- Add to player (displaying it)
leaderstats.Parent = player
end
Players.PlayerAdded:Connect(onPlayerAdded)
Summary
Properties
Describes the player's account age in days.
Determines whether the character of a player using a mobile device will automatically jump upon hitting an obstacle.
The maximum distance the player's camera is allowed to zoom out.
The minimum distance the player's camera is allowed to zoom in.
Changes the camera's mode to either first or third person.
Determines whether the character's appearance will be loaded when the player spawns. If false, the player will spawn with a default appearance.
A Model controlled by the player that contains a Humanoid, body parts, scripts, and other objects.
Determines the user ID of the account whose character appearance is used for a player's character.
Sets how the default camera handles objects between the camera and the player.
Determines player's camera movement mode when using a desktop version of Roblox.
Determines player's character movement mode when using a desktop version of Roblox.
Determines if the player can toggle mouse lock.
Determines player's camera movement mode when using a touch device.
Determines player's character movement mode when using a touch device.
The DisplayName of the UserId associated with the Player.
Describes the user ID of the player who was followed into a game by a player.
Whether player client-side gameplay is currently paused.
Indicates if a player has a Verified Badge.
Sets the distance at which this player will see other Humanoid's health bars. If set to 0, the health bars will not be displayed.
This property shows the locale id that the local player has set for their Roblox account.
Describes the account's membership type.
Sets the distance at which this player will see other Humanoid's names. If set to 0, names are hidden.
Determines whether the player is on a specific team.
Sets the part to focus replication around.
If set, the player will respawn at the given SpawnLocation.
Determines the Team with which a Player is associated.
Determines the Team with which a Player is associated.
A unique identifying integer assigned to all user accounts.
Methods
Removes all accessories and other character appearance objects from a player's Character.
Returns the distance between the character's head and the given Vector3 point. Returns 0 if the player has no character.
Returns a dictionary containing information describing how the Player joins the experience.
Returns the mouse being used by the client.
Returns the isolated network latency in seconds.
Returns whether or not the appearance of the player's character has loaded.
Returns whether the player is verified with concrete, real-world signals.
Forcibly disconnect a player from the game, optionally providing a message.
Causes the player's character to walk in the given direction until stopped, or interrupted by the player (by using their controls).
Sets the AccountAge of the player.
Sets whether or not the player sees filtered chats, rather than normal chats.
Returns a dictionary of online friends.
Returns the player's rank in the group as an integer between 0 and 255, where 0 is a non-member and 255 is the group's owner.
Returns the player's role in the group as a string, or "Guest" if the player isn't part of the group.
Checks whether a player is a friend of the user with the given Player.UserId.
Checks whether a player is a member of a group with the given ID.
Creates a new character for the player, removing the old one. Also clears the player's Backpack and PlayerGui.
Spawns an avatar so it has everything equipped in the passed in HumanoidDescription.
Requests that the server stream to the player around the specified location.
Events
Fired when a player's character spawns or respawns.
Fires when the full appearance of a Player.Character has been inserted.
Fired right before a player's character is removed.
Fires when a player chats in-game using Roblox's provided chat bar.
This event fires approximately two minutes after the game engine classifies the player as idle. Time is the number of seconds that have elapsed since that point.
Fired when the TeleportState of a player changes.
Properties
AccountAge
The AccountAge is a Player property that describes how long ago a player's account was registered in days. It is set using the Player:SetAccountAge() function, which cannot be accessed by scripts.
This property is useful for conditionally showing new Roblox players content such as tutorials.
Code Samples
local Players = game:GetService("Players")
local MAX_AGE_NEW_PLAYER = 7 -- one week
local MIN_AGE_VETERAN = 365 -- one year
-- This function marks a part with text using a BillboardGui
local function mark(part, text)
local bbgui = Instance.new("BillboardGui")
bbgui.AlwaysOnTop = true
bbgui.StudsOffsetWorldSpace = Vector3.new(0, 2, 0)
bbgui.Size = UDim2.new(0, 200, 0, 50)
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(1, 0, 1, 0) -- Fill parent
textLabel.Text = text
textLabel.TextColor3 = Color3.new(1, 1, 1)
textLabel.TextStrokeTransparency = 0
textLabel.BackgroundTransparency = 1
textLabel.Parent = bbgui
-- Add to part
bbgui.Parent = part
bbgui.Adornee = part
end
local function onPlayerSpawned(player, character)
local head = character:WaitForChild("Head")
if player.AccountAge >= MIN_AGE_VETERAN then
mark(head, "Veteran Player")
elseif player.AccountAge <= MAX_AGE_NEW_PLAYER then
mark(head, "New Player")
else
mark(head, "Regular Player")
end
end
local function onPlayerAdded(player)
-- Listen for this player spawning
if player.Character then
onPlayerSpawned(player, player.Character)
end
player.CharacterAdded:Connect(function()
onPlayerSpawned(player, player.Character)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
AutoJumpEnabled
The AutoJumpEnabled property determines whether the Player.Character of a Player using a mobile device will automatically jump when they hit an obstacle. This can make levels more navigable while on a mobile device.
When the player joins the game, the StarterPlayer.AutoJumpEnabled value determines the initial state of this property. Then, this property determines the value of the Humanoid.AutoJumpEnabled property of the Player.Character on spawn. In other words, it is possible to set the auto-jump behavior on a per-character, per-player and per-game basis using these three properties.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local button = script.Parent
local function update()
-- Update button text
if player.AutoJumpEnabled then
button.Text = "Auto-Jump is ON"
else
button.Text = "Auto-Jump is OFF"
end
-- Reflect the property in the player's character, if they have one
if player.Character then
local human = player.Character:FindFirstChild("Humanoid")
if human then
human.AutoJumpEnabled = player.AutoJumpEnabled
end
end
end
local function onActivated()
-- Toggle auto-jump
player.AutoJumpEnabled = not player.AutoJumpEnabled
-- Update everything else
update()
end
button.Activated:Connect(onActivated)
update()
CameraMaxZoomDistance
The CameraMaxZoomDistance Player property sets the maximum distance in studs the camera can be from the character with the default cameras.
In other words, it controls the maximum distance the player's camera is allowed to zoom out.
The default value of this property is set by StarterPlayer.CameraMaxZoomDistance. If this value is set to a lower value than Player.CameraMinZoomDistance, it will be increased to CameraMinZoomDistance.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.CameraMaxZoomDistance = 50
player.CameraMinZoomDistance = 75
CameraMinZoomDistance
The CameraMinZoonDistance Player property sets the minimum distance in studs the camera can be from the character with the default cameras.
In other words, it controls the minimum distance the player's camera is allowed to zoom in.
The default value of this property is set by StarterPlayer.CameraMinZoomDistance. If this value is set to a higher value than Player.CameraMaxZoomDistance it will be decreased to CameraMaxZoomDistance.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.CameraMaxZoomDistance = 50
player.CameraMinZoomDistance = 75
CameraMode
The CameraMode property sets the player's camera mode, defaulting to third person.
Third Person
In the default third person mode (Enum.CameraMode.Classic), the character can be seen in the camera. While in this mode, the default behavior is:
- Players can right-click and drag (mouse), tap and drag (mobile), use the secondary thumbstick (gamepad), or press the left/right arrows (keyboard) to rotate the camera around their character.
- When a player moves their character, it faces in the corresponding movement direction.
- Players can zoom in and out freely, even to first person on full zoom in.
First Person
In first person mode (Enum.CameraMode.LockFirstPerson), the player's camera is zoomed all the way in. Unless there is a visible GUI present with the GuiButton.Modal property set to true, moving the mouse, tap-dragging on mobile, or using the secondary thumbstick on a gamepad will rotate the camera around the character.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.CameraMode = Enum.CameraMode.LockFirstPerson
CanLoadCharacterAppearance
The CanLoadCharacterAppearance Player property determines whether the character's appearance will be loaded when the player spawns. The default value of this property is set by StarterPlayer.LoadPlayerAppearance.
If true, the character will load the appearance of the player corresponding to the player's Player.CharacterAppearanceId.
If false, the player will spawn with a default appearance - a grey character model without any hats, shirts, pants, etc.
Attempting to set the property after the character has spawned will not change the character, you must call Player:LoadCharacter() to load the new appearance.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.CanLoadCharacterAppearance = false
Character
The Character property contains a reference to a Model containing a Humanoid, body parts, scripts, and other objects required for simulating the player's avatar in-experience. The model is parented to the Workspace but it may be moved. It is automatically loaded when Players.CharacterAutoLoads is true and it can be manually loaded otherwise using Player:LoadCharacter().
Initially this property is nil and it is set when the player's character first spawns. Use the Player.CharacterAdded event to detect when a player's character properly loads, and the Player.CharacterRemoving event to detect when the character is about to despawn. Avoid using Object:GetPropertyChangedSignal() on this property.
Note that LocalScripts that are cloned from StarterGui or StarterPack into a player's PlayerGui or Backpack respectively are often run before the old character model is replaced, so Player.Character may refer to the old model whose Parent property is nil. Therefore, in a LocalScript under StarterGui or StarterPack, it is advisable to make sure the parent of Character is not nil before using it, for example:
local Players = game:GetService("Players")local player = Players.LocalPlayerlocal character = player.Characterif not character or character.Parent == nil thencharacter = player.CharacterAdded:Wait()end
CharacterAppearanceId
This property determines the user ID of the account whose character appearance is used for a player's Player.Character. By default, this property is the Player.UserId, which uses the player's avatar as they have created it on the Roblox website.
Changing this property to the user ID of another account will cause the player to spawn with that account's appearance (hats, shirt, pants, etc).
Games can also toggle whether or not a player's character appearance is loaded in game by changing the StarterPlayer.LoadCharacterAppearance property.
Code Samples
local Players = game:GetService("Players")
local disguiseCommand = "/disguise "
local function onPlayerChatted(player, message)
if message:sub(1, disguiseCommand:len()):lower() == disguiseCommand:lower() then
local input = message:sub(disguiseCommand:len() + 1)
local id = tonumber(input)
if not id then -- Number failed to parse, maybe they typed a username instead
pcall(function() -- This call can fail sometimes!
id = Players:GetUserIdFromNameAsync(input) -- Fetch ID from name
end)
end
if id then
-- Set character appearance then respawn
player.CharacterAppearanceId = id
player:LoadCharacter()
else
-- We couldn't get an ID from their input
end
end
end
local function onPlayerAdded(player)
player.Chatted:Connect(function(...)
onPlayerChatted(player, ...)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
DevCameraOcclusionMode
Defines how the default camera scripts handle objects between the camera and the camera subject. Set by StarterPlayer.DevCameraOcclusionMode and can't be changed for individual players.
The default value is Zoom (0). See Enum.DevCameraOcclusionMode for a list of available modes.
DevComputerCameraMode
The DevComputerCameraMode property determines the manner in which a player moves their camera when using a device with a mouse and keyboard. See Enum.DevComputerCameraMovementMode for a description of each camera control mode available. This property cannot be set using a LocalScript (it must be set on the server using a Script).
The default value of this property is determined by StarterPlayer.DevComputerCameraMovementMode.
The word "Computer" in this property name refers to non-TouchEnabled, non-GamepadEnabled devices.
When set to UserChoice, a player can choose between any control mode (except Scriptable) in the Roblox game settings. In general, it's a good idea to allow players to choose their control mode to maximize accessibility.
It's possible to create a custom control scheme by setting this property to Scriptable.
This property doesn't affect players using a touch enabled device. See Player.DevTouchCameraMode instead.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- Set the player's camera movement mode on computers to classic
player.DevComputerCameraMode = Enum.DevComputerCameraMovementMode.Classic
DevComputerMovementMode
The DevComputerMovementMode property determines the manner in which a player moves their character when using a device with a mouse and keyboard. See Enum.DevComputerMovementMode for a description of each movement control mode available. This property cannot be set using a LocalScript (it must be set on the server using a Script).
The default value of this property is determined by StarterPlayer.DevComputerMovementMode.
The word "Computer" in this property name refers to non-TouchEnabled devices.
When set to UserChoice, a player can choose between any control mode (except Scriptable) in the Roblox game settings. In general, it is a good idea to allow players to choose their control mode to maximize accessibility.
It's possible to create a custom control scheme by setting this property to Scriptable.
This property doesn't affect players using a touch-enabled device. See Player.DevTouchMovementMode instead.
Code Samples
local Players = game:GetService("Players")
game.Players.PlayerAdded:Connect(function(player)
-- Set the player's movement mode on mobile devices to a dynamic thumbstick
player.DevComputerMovementMode = Enum.DevComputerMovementMode.DynamicThumbstick
end)
DevEnableMouseLock
This property determines if a player is able to toggle Mouse lock by pressing Shift. A player can disable the mouse lock switch in Roblox's game settings. By default, this property is set to the value of StarterPlayer.EnableMouseLockOption. This can be set server-side during run-time by using a Script. It can not be set client-side.
When mouse lock is enabled, the player's cursor is locked to the center of the screen. Moving the mouse will orbit the camera around the player's character, and the character will face the same direction as the camera. It also offsets the camera view just over the right shoulder of the player's character.
Note that shift-lock related APIs are in the process of being deprecated, so it's recommended to use UserInputService.MouseBehavior instead to lock the mouse.
Code Samples
local Players = game:GetService("Players")
local function toggleMouseLock(player)
player.DevEnableMouseLock = not player.DevEnableMouseLock
if player.DevEnableMouseLock then
print("Mouse lock is available")
else
print("Mouse lock is not available")
end
end
local function onPlayerChatted(player, message, _recipient)
if message == "mouselock" then
toggleMouseLock(player)
end
end
local function onPlayerAdded(player)
player.Chatted:Connect(function(...)
onPlayerChatted(player, ...)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
DevTouchCameraMode
The DevTouchCameraMode property determines the manner in which a player moves their camera when using a TouchEnabled device. See Enum.DevTouchCameraMovementMode for a description of each camera control mode available. This property cannot be set using a LocalScript (it must be set on the server using a Script).
The default value of this property is determined by StarterPlayer.DevTouchCameraMovementMode.
When set to UserChoice, a player can choose between any control mode (except Scriptable) in the Roblox game settings. In general, it is a good idea to allow players to choose their control mode to maximize accessibility.
It's possible to create a custom control scheme by setting this property to Scriptable.
This property doesn't affect players who aren't using a touch-enabled device. See Player.DevComputerCameraMovementMode instead.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- Set the player's camera movement mode on mobile devices to classic
player.DevTouchCameraMovementMode = Enum.DevTouchCameraMovementMode.Classic
DevTouchMovementMode
The DevTouchMovementMode property determines the manner in which a player moves their character when using a TouchEnabled device. See Enum.DevTouchMovementMode for a description of each movement control mode available. This property cannot be set using a LocalScript (it must be set on the server using a Script).
The default value of this property is determined by StarterPlayer.DevTouchMovementMode.
When set to UserChoice, a player can choose between any control mode (except Scriptable) in the Roblox game settings. In general, it's a good idea to allow players to choose their control mode to maximize accessibility.
It's possible to create a custom control scheme by setting this property to Scriptable.
This property doesn't affect players who aren't using a touch-enabled device. See Player.DevComputerMovementMode instead.
Code Samples
local Players = game:GetService("Players")
game.Players.PlayerAdded:Connect(function(player)
-- Set the player's movement mode on mobile devices to a dynamic thumbstick
player.DevTouchMovementMode = Enum.DevTouchMovementMode.DynamicThumbstick
end)
DisplayName
The DisplayName is a Player property that contains the display name of the authenticated user associated with the Player object. Unlike usernames, display names are non-unique names a player displays to others. If the Roblox user has not chosen one, the property will read the same as the Name property.
Note:
- Since display names are non-unique, it's possible for two players in a single instance to have identical names. If you need a globally unique identifier for a player, use Player.UserId (which is static) or Player.Name (which is the current Username) instead.
- Characters generated with Player.LoadCharacter or by the Roblox engine will have their Humanoid.DisplayName property assigned to the Player.DisplayName property.
- Display names may have unicode characters in the string. See UTF-8 for more information on how to work with strings with unicode characters.
FollowUserId
The FollowUserId is a Player property that contains the Player.UserId of the user that a player followed into the game. If the player did not follow anyone into the game, this property will be 0. This property is useful for alerting players who have been followed by another player into the game.
You can get the name of the player followed using this user ID and the Players:GetNameFromUserIdAsync() function.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local function onPlayerAdded(newPlayer)
if newPlayer.FollowUserId == player.UserId then
local hint = Instance.new("Hint")
hint.Parent = player:WaitForChild("PlayerGui")
hint.Text = "You were followed to this game by " .. newPlayer.Name .. "!"
task.delay(3, function()
if hint then
hint:Destroy()
end
end)
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
GameplayPaused
The GameplayPaused property indicates if the player is currently in a pause state in a place with StreamingEnabled activated. It is set on the client but replicated to the server. To determine the pause status, you can utilize this property.
See also:
- Workspace.StreamingEnabled which controls whether content streaming is enabled
- Workspace.StreamingIntegrityMode and Enum.StreamingIntegrityMode for more details on when gameplay is paused.
HealthDisplayDistance
The HealthDisplayDistance Player property sets the distance in studs at which this player will see other Humanoid health bars. If set to 0, the health bars will not be displayed. This property is set to StarterPlayer.HealthDisplayDistance by default.
If a Humanoid's health bar is visible, you can set the display type using Humanoid.DisplayDistanceType.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.HealthDisplayDistance = 0
player.NameDisplayDistance = 0
LocaleId
The LocaleId Player property shows the locale id that the local player has set for their Roblox account. It holds a string with the two letter code (for example, "en-us") for the locale.
This can be used to determine the geographic demographic of your game's player base, and is also the locale that will be used for automatic localization (see GuiBase2d.AutoLocalize) of in-experience content. This property allows access to the player's locale from the server.
See also LocalizationService.RobloxLocaleId, the locale ID used for localizing internal content. This will be a different value when Roblox does not yet internally support the local player's set locale.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
print(player.LocaleId)
MembershipType
This property can only be read from to determine membership (it cannot be set to another membership type). It holds a Enum.MembershipType enum of the account's membership type.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
if player.MembershipType == Enum.MembershipType.Premium then
-- Take some action specifically for Premium members
end
NameDisplayDistance
The NameDisplayDistance StarterPlayer property sets the distance in studs at which this player will see other Humanoid names. If the property is set to 0, names are hidden. This property is set to StarterPlayer.NameDisplayDistance by default.
If a Humanoid's health bar is visible, you can set the display type using Humanoid.DisplayDistanceType.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.HealthDisplayDistance = 0
player.NameDisplayDistance = 0
Neutral
The Neutral property determines whether the player is on a specific team.
- When true, the player is not on a specific team. This also means that the Player.Team property will be nil and the Player.TeamColor will be white.
- When false, the player is on a specific team. The Player.Team property will correspond to the Team that the player is on, as will the Player.TeamColor.
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
if player.Neutral then
print("Player is neutral!")
else
print("Player is not neutral!")
end
ReplicationFocus
The ReplicationFocus Player property sets the part to focus replication around a Player. Different Roblox systems that communicate over the network (such as physics, streaming, etc) replicate at different rates depending on how close objects are to the replication focus.
When this property is nil, it reverts to its default behavior which is to treat the local player's character's PrimaryPart as the replication focus.
This property should only be set on the server with a Script, not a LocalScript. Note that this property does not change or update network ownership of parts.
Code Samples
local Players = game:GetService("Players")
local PLAYER_NAME = "polarpanda16"
local player = Players:WaitForChild(PLAYER_NAME)
local part = Instance.new("Part")
part.Parent = workspace
part.Name = "ReplicationFocusPart"
part.Anchored = true
player.ReplicationFocus = part
RespawnLocation
If set, the player will respawn at the given SpawnLocation. This property can only be set through Lua and must contain a reference to a valid SpawnLocation, which must meet the following criteria:
- Descendant of Workspace
If RespawnLocation is not set to a valid SpawnLocation then the default spawning logic will apply. For more information on this see the page for SpawnLocation.
Alternatives to RespawnLocation
- A Player will spawn from SpawnLocations belonging to their team. In some cases it may be simpler to change the player's Player.Team instead.
- Implement your own custom spawn logic using PVInstance:PivotTo() to manually move the Player.Character.
Code Samples
local Players = game:GetService("Players")
local function addSpawn(spawnLocation)
-- listen for the spawn being touched
spawnLocation.Touched:Connect(function(hit)
local character = hit:FindFirstAncestorOfClass("Model")
if character then
local player = Players:GetPlayerFromCharacter(character)
if player and player.RespawnLocation ~= spawnLocation then
local humanoid = character:FindFirstChildOfClass("Humanoid")
-- make sure the character isn't dead
if humanoid and humanoid:GetState() ~= Enum.HumanoidStateType.Dead then
print("spawn set")
player.RespawnLocation = spawnLocation
end
end
end
end)
end
local firstSpawn
-- look through the workspace for spawns
for _, descendant in pairs(workspace:GetDescendants()) do
if descendant:IsA("SpawnLocation") then
if descendant.Name == "FirstSpawn" then
firstSpawn = descendant
end
addSpawn(descendant)
end
end
local function playerAdded(player)
player.RespawnLocation = firstSpawn
end
-- listen for new players
Players.PlayerAdded:Connect(playerAdded)
-- go through existing players
for _, player in pairs(Players:GetPlayers()) do
playerAdded(player)
end
Team
The Team property is a reference to a Team object within the Teams service. It determines the team the player is on; if the Player isn't on a team or has an invalid Player.TeamColor, this property is nil. When this property is set, the player has joined the Team and the Team.PlayerAdded event fires on the associated team. Similarly, Team.PlayerRemoved fires when the property is unset from a certain Team.
Code Samples
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
local teamPlaying = Teams.Playing
local teamSpectators = Teams.Spectating
local playCommand = "/play"
local function play(player)
player.Team = teamPlaying
player.TeamColor = teamPlaying.TeamColor
-- Respawn the player (moves them to spawn location)
player:LoadCharacter()
end
local function onPlayerDied(player, _character)
-- When someone dies, put them on the spectator team
player.Team = teamSpectators
end
local function onPlayerSpawned(player, character)
local human = character:WaitForChild("Humanoid")
human.Died:Connect(function()
onPlayerDied(player, character)
end)
end
local function onPlayerChatted(player, message)
if message:sub(1, playCommand:len()):lower() == playCommand then
play(player)
end
end
local function onPlayerAdded(player)
if player.Character then
onPlayerSpawned(player, player.Character)
end
player.CharacterAdded:Connect(function()
onPlayerSpawned(player, player.Character)
end)
player.Chatted:Connect(function(message, _recipient)
onPlayerChatted(player, message)
end)
end
for _, player in pairs(Players:GetPlayers()) do
onPlayerAdded(player)
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
-- Command to choose a team (note the trailing space)
local joinCommand = "/jointeam "
local function findTeamByName(name)
-- First, check for the exact name of a team
if Teams:FindFirstChild(name) then
return Teams[name]
end
-- Let's check for case-insensitive partial matches, like "red" for "Red Robins"
for _, team in pairs(Teams:GetChildren()) do
if team.Name:sub(1, name:len()):lower() == name:lower() then
return team
end
end
-- If we get to this point, no team matched the one we were looking for :(
end
local function onPlayerChatted(player, message, _recipient)
-- Note: string.sub(message, ...) is the same as message:sub(...)
if message:sub(1, joinCommand:len()):lower() == joinCommand:lower() then
-- Matched "/JOINTEAM xyz" to our join command prefix "/jointeam "
local teamName = message:sub(joinCommand:len() + 1) -- Cut out the "xyz" from "/jointeam xyz"
local team = findTeamByName(teamName)
if team then
-- Set the team!
player.Team = team
player.Neutral = false
else
-- Tell the player that team could not be found :(
player.Team = nil
player.Neutral = true
end
end
end
local function onPlayerAdded(player)
player.Chatted:Connect(function(...)
onPlayerChatted(player, ...)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
TeamColor
The TeamColor property determines which team a Player is associated with according to that Team's Team.TeamColor. Changing this property will change Player.Team according to whichever team has the same BrickColor for their Team.TeamColor. If no Team object has the associated TeamColor, the player will not be associated with a team.
It's often a better idea to set Player.Team to the respective Team instead of using this property. Setting this property often leads to repetition of the same BrickColor value for a certain team across many scripts; this is something you want to avoid when adhering to the "Don't Repeat Yourself" (DRY) principle.
Code Samples
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
local teamPlaying = Teams.Playing
local teamSpectators = Teams.Spectating
local playCommand = "/play"
local function play(player)
player.Team = teamPlaying
player.TeamColor = teamPlaying.TeamColor
-- Respawn the player (moves them to spawn location)
player:LoadCharacter()
end
local function onPlayerDied(player, _character)
-- When someone dies, put them on the spectator team
player.Team = teamSpectators
end
local function onPlayerSpawned(player, character)
local human = character:WaitForChild("Humanoid")
human.Died:Connect(function()
onPlayerDied(player, character)
end)
end
local function onPlayerChatted(player, message)
if message:sub(1, playCommand:len()):lower() == playCommand then
play(player)
end
end
local function onPlayerAdded(player)
if player.Character then
onPlayerSpawned(player, player.Character)
end
player.CharacterAdded:Connect(function()
onPlayerSpawned(player, player.Character)
end)
player.Chatted:Connect(function(message, _recipient)
onPlayerChatted(player, message)
end)
end
for _, player in pairs(Players:GetPlayers()) do
onPlayerAdded(player)
end
Players.PlayerAdded:Connect(onPlayerAdded)
UserId
The UserId is a Player property that contains a read-only integer that uniquely and consistently identifies every user account on Roblox. Unlike the Instance.Name of a Player, which may change according the user's present username, this value will never change for the same account.
This property is essential when saving/loading player data using GlobalDataStores. Use a player's UserId as the data store key so that each player has a unique key.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
print(player.UserId)
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local player = Players:GetPlayerByUserId(1)
if player then
print("Player with userId 1 is in this server! Their name is: " .. player.Name)
else
print("Player with userId 1 is not in this server!")
end
local BadgeService = game:GetService("BadgeService")
local Players = game:GetService("Players")
local OWNER_ID = 212423 -- can use game.CreatorId for published places
local BADGE_ID = 1
local ownerInGame = false
local function playerAdded(newPlayer)
if newPlayer.UserId == OWNER_ID then
-- if new player is the owner, set ownerInGame to true and give everyone the badge
ownerInGame = true
for _, player in pairs(Players:GetPlayers()) do
-- don't award the owner
if player ~= newPlayer then
BadgeService:AwardBadge(player.UserId, BADGE_ID)
end
end
elseif ownerInGame then
-- if the owner is in the game, award the badge
BadgeService:AwardBadge(newPlayer.UserId, BADGE_ID)
end
end
local function playerRemoving(oldPlayer)
if oldPlayer.UserId == OWNER_ID then
ownerInGame = false
end
end
Players.PlayerAdded:Connect(playerAdded)
Players.PlayerRemoving:Connect(playerRemoving)
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local goldDataStore = DataStoreService:GetDataStore("Gold")
local STARTING_GOLD = 100
local function onPlayerAdded(player)
local playerKey = "Player_" .. player.UserId
local leaderstats = Instance.new("IntValue")
leaderstats.Name = "leaderstats"
local gold = Instance.new("IntValue")
gold.Name = "Gold"
gold.Parent = leaderstats
local success, result = pcall(function()
return goldDataStore:GetAsync(playerKey) or STARTING_GOLD
end)
if success then
gold.Value = result
else
-- Failed to retrieve data
warn(result)
end
leaderstats.Parent = player
end
Players.PlayerAdded:Connect(onPlayerAdded)
Methods
ClearCharacterAppearance
The ClearCharacterAppearance function removes all Accessory, Shirt, Pants, CharacterMesh, and BodyColors from the given player's Player.Character. In addition, it also removes the T-Shirt Decal on the player's torso. The character's body part colors and face will remain unchanged. This method does nothing if the player does not have a Character.
It does not remove t-shirts, head meshes, or faces.
Returns
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local function onChildRemoved(child)
print(child.ClassName, "removed from character")
end
character.ChildRemoved:Connect(onChildRemoved)
player:ClearCharacterAppearance()
--> BodyColors removed from character
--> ShirtGraphic removed from character
--> Shirt removed from character
--> Pants removed from character
--> CharacterMesh removed from character
--> Hat removed from character
--> Shirt removed from character
DistanceFromCharacter
The DistanceFromCharacter Player function returns the distance between the character's head and the given Vector3 point. It returns 0 if the player has no Player.Character.
This is useful when determining the distance between a player and another object or location in game.
If you would like to determine the distance between two non-player instances or positions, you can use the following:
local distance = (position1 - position2).magnitude
Parameters
The location from which player's distance to is being measured.
Returns
The distance in studs between the player and the location.
Code Samples
local Players = game:GetService("Players")
for _, player in pairs(Players:GetPlayers()) do
print(player:DistanceFromCharacter(Vector3.new(0, 0, 0)))
end
GetJoinData
Returns a dictionary containing information describing how the Player joins the experience. The dictionary contains any of the following fields:
Key | Value Type | Description |
---|---|---|
SourceGameId | number | The DataModel.GameId of the experience the Player teleported from. Only present if the player teleports to the current experience and if a server calls the teleport function. |
SourcePlaceId | number | The DataModel.PlaceId of the place the Player teleported from. Only present if the player teleports to the current place and a server calls the teleport function. |
ReferredByPlayerId | number | The Player.UserId of the player who invited the current player to the experience. Use this data to identify the referrer and trigger reward logic. |
Members | array | An array containing the Player.UserId numbers of the users teleported alongside the Player. Only present if the player teleported as part of a group. |
TeleportData | variant | Reflects the teleportData specified in the original teleport. Useful for sharing information between servers the player teleports to. Only present if teleportData was specified and a server calls the teleport function. |
LaunchData | string | A plain or JSON encoded string that contains launch data specified in a deep link URL or ExperienceInviteOptions.LaunchData. |
GetJoinData and TeleportData
If a server initiates the Player's teleport, the dictionary that this method returns includes the player's teleport data. The Player:GetJoinData() method can only be used to fetch teleport data on the server. To fetch the data on the client, use TeleportService:GetLocalPlayerTeleportData().
Unlike TeleportService:GetLocalPlayerTeleportData(), Player:GetJoinData() only provides teleport data that meets the following security criteria:
- It's guaranteed to have been sent by a Roblox server in the past 48 hours.
- It's guaranteed to have been sent with this Player.
- The SourcePlaceId and SourceGameId are guaranteed to be the place and universe the data was sent from. This means you can verify the teleport data came from an approved place.
As this data is transmitted by the client, it can still potentially be abused by an exploiter. Sensitive data such as player currency should be transmitted via a secure solution like Memory Stores.
Returns
A dictionary containing PlaceId and UserId values (see table in description).
Code Samples
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local analyticsStore = DataStoreService:GetDataStore("Analytics")
local ALLOWED_SOURCES = {
"twitter";
"youtube";
"discord";
}
local function onPlayerAdded(player)
local source = player:GetJoinData().LaunchData
-- check if the provided source is valid
if source and table.find(ALLOWED_SOURCES, source) then
-- update the data store to track the source popularity
local success, result = pcall(analyticsStore.IncrementAsync, analyticsStore, source)
if success then
print(player.Name, "joined from", source, "- total:", result)
else
warn("Failed to record join source: " .. result)
end
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local DIRECT_JOIN_URL = "https://www.roblox.com/games/start?placeId=%d&launchData=%s"
local textBox = script.Parent
local function generateReferralURL(player)
return DIRECT_JOIN_URL:format(
game.PlaceId,
player.UserId
)
end
local function highlightAll()
if -- avoid recursive property updates
textBox:IsFocused()
and not (
textBox.SelectionStart == 1
and textBox.CursorPosition == #textBox.Text + 1
)
then
textBox.SelectionStart = 1
textBox.CursorPosition = #textBox.Text + 1
end
end
textBox.Focused:Connect(highlightAll)
textBox:GetPropertyChangedSignal("SelectionStart"):Connect(highlightAll)
textBox:GetPropertyChangedSignal("CursorPosition"):Connect(highlightAll)
textBox.TextEditable = false
textBox.ClearTextOnFocus = false
textBox.Text = generateReferralURL(player)
local HttpService = game:GetService("HttpService")
local DATA_CHARACTER_LIMIT = 200
local function encodeTableAsLaunchData(data)
-- convert the table to a string
local jsonEncodedData = HttpService:JSONEncode(data)
if #jsonEncodedData <= DATA_CHARACTER_LIMIT then
-- escape potentially invalid characters, such as spaces
local urlEncodedData = HttpService:UrlEncode(jsonEncodedData)
return true, urlEncodedData
else
-- report character limit error
return false, ("Encoded table exceeds %d character limit"):format(DATA_CHARACTER_LIMIT)
end
end
local sampleData = {
joinMessage = "Hello!";
urlCreationDate = os.time();
magicNumbers = {
534;
1337;
746733573;
};
}
local success, encodedData = encodeTableAsLaunchData(sampleData)
if success then
print(encodedData)
else
warn("failed to encode launch data: " .. encodedData)
end
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local function onPlayerAdded(player)
local launchData = player:GetJoinData().LaunchData
if launchData then
-- attempt to decode the data
local success, result = pcall(HttpService.JSONDecode, HttpService, launchData)
if success then
print(player.Name, "joined with data:", result)
else
-- this is probably due to the user messing with the URL
warn("Failed to parse launch data:" .. result)
end
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local approvedPlaceIds = { 1 } -- insert approved PlaceIds here
local function isPlaceIdApproved(placeId)
for _, id in pairs(approvedPlaceIds) do
if id == placeId then
return true
end
end
return false
end
local function onPlayerAdded(player)
local joinData = player:GetJoinData()
-- verify this data was sent by an approved place
if isPlaceIdApproved(joinData.SourcePlaceId) then
local teleportData = joinData.TeleportData
if teleportData then
local currentLevel = teleportData.currentLevel
print(player.Name .. " is on level " .. currentLevel)
end
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
GetMouse
The GetMouse Player function returns the Mouse being used by the client. The player's mouse instance can be used to track user mouse input including left and right mouse button clicks and movement and location.
The UserInputService service provides additional functions and events to track user input - especially for devices that do not use a mouse.
Note:
- This item must be used in a LocalScript to work as expected online.
- Following an update in July 2014, the mouse's icon can now be set with this method.
Returns
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local mouse = player:GetMouse()
local function onButton1Down()
print("Button 1 is down")
end
mouse.Button1Down:Connect(onButton1Down)
GetNetworkPing
GetNetworkPing returns the isolated network latency of the Player in seconds. "Ping" is a measurement of the time taken for data to be sent from the client to the server, then back again. It doesn't involve data deserialization or processing.
For client-side LocalScripts, this function can only be called on the Players.LocalPlayer. This function is useful in identifying and debugging issues that occur in high network latency scenarios. It's also useful for masking latency, such as adjusting the speed of throwing animations for projectiles.
Returns
HasAppearanceLoaded
The HasAppearanceLoaded Player function returns whether or not the appearance of the player's Player.Character has loaded.
A player's appearance includes items such as the player's Shirt, Pants, and Accessories.
This is useful when determining whether a player's appearance has loaded after they first join the game, which can be tracked using the Players.PlayerAdded event.
Returns
A boolean indicating whether or not the appearance of the player's character has loaded.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
local loaded = player:HasAppearanceLoaded()
print(loaded)
while not loaded do
loaded = player:HasAppearanceLoaded()
print(loaded)
task.wait()
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
IsVerified
Returns a boolean value indicating that player's verification status. When true, the player is verified. Verification includes, but isn't limited to, non-VOIP phone number or government ID verification.
When implementing IsVerified, exercise caution to ensure that the implementation does not inadvertently block all unverified users.
Note that the method can only be called on the backend server. Calling it client-side results in an error. Additionally, this method will always return false in Studio.
Returns
A boolean indicating whether the player is verified.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
print(player:IsVerified())
end
for _, player in pairs(Players:GetPlayers()) do
onPlayerAdded(player)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Kick
The Kick() method allows an experience to gracefully disconnect a client and optionally provide a message to the disconnected user. This is useful for moderating abusive users. You should only allow specific users whom you trust to trigger this method on other users.
Calling this method on a Player with no arguments disconnects the user from the server and provides a default notice message. Calling this method on a Player along with a string as the first argument replaces the default message with the provided string.
When using this method from a LocalScript, only the local user's client can be kicked.
Parameters
The message to show the user upon kicking.
Returns
Move
The Move Player function causes the player's character to walk in the given direction until stopped, or interrupted by the player (by using their controls).
This is useful when scripting NPC Humanoids that move around a map - but are not controlled by an actual player's input.
Note that the function's second argument indicates whether the provided Vector3 should move the player relative to world coordinates (false) or the player's Camera (true).
Parameters
The Vector3 direction that the player should move.
A boolean indicating whether the player should move relative to the player's camera.
Returns
Code Samples
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
-- Wait for the player's character and humanoid, which must exist before calling :Move()
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
character:WaitForChild("Humanoid")
-- The player will move until they are 50 studs away from the camera's position at the time of running
localPlayer:Move(Vector3.new(0, 0, -50), true)
SetAccountAge
The SetAccountAge function sets the Player.AccountAge of the player in days.
It is used to set the Player property that describes how long ago a player's account was registered in days.
This does not set the age of the player on the account, but the age of the account itself relative to when it was first created.
Parameters
The age of the account in days.
Returns
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player:SetAccountAge(100)
local Players = game:GetService("Players")
local MAX_AGE_NEW_PLAYER = 7 -- one week
local MIN_AGE_VETERAN = 365 -- one year
-- This function marks a part with text using a BillboardGui
local function mark(part, text)
local bbgui = Instance.new("BillboardGui")
bbgui.AlwaysOnTop = true
bbgui.StudsOffsetWorldSpace = Vector3.new(0, 2, 0)
bbgui.Size = UDim2.new(0, 200, 0, 50)
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(1, 0, 1, 0) -- Fill parent
textLabel.Text = text
textLabel.TextColor3 = Color3.new(1, 1, 1)
textLabel.TextStrokeTransparency = 0
textLabel.BackgroundTransparency = 1
textLabel.Parent = bbgui
-- Add to part
bbgui.Parent = part
bbgui.Adornee = part
end
local function onPlayerSpawned(player, character)
local head = character:WaitForChild("Head")
if player.AccountAge >= MIN_AGE_VETERAN then
mark(head, "Veteran Player")
elseif player.AccountAge <= MAX_AGE_NEW_PLAYER then
mark(head, "New Player")
else
mark(head, "Regular Player")
end
end
local function onPlayerAdded(player)
-- Listen for this player spawning
if player.Character then
onPlayerSpawned(player, player.Character)
end
player.CharacterAdded:Connect(function()
onPlayerSpawned(player, player.Character)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
SetSuperSafeChat
This method sets whether or not the player sees chat filtered by TextService:FilterStringAsync() rather than normal chats.
local Players = game:GetService("Players")local player = Players.LocalPlayerplayer:SetSuperSafeChat(true)
Regardless of whether a player has filtered chat enabled, all chat should be filtered by TextService when broadcast to other players or on the player's own screen. TextService:FilterStringAsync() returns a TextFilterResult object that can be filtered differently according to the message's intended use.
Parameters
A boolean indicating whether or not the player sees filtered chat.
Returns
GetFriendsOnline
This function returns a dictionary array of online friends, limited by the maxFriends value. The function uses a 30 second cache.
In the returned array, some fields are only present for certain location types. For example, PlaceId won't be present when LocationType is 0 (Mobile Website).
Name | Type | Description | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
VisitorId | number | The Player.UserId of the friend. | ||||||||||||||
UserName | string | The username of the friend. | ||||||||||||||
DisplayName | string | The Player.DisplayName of the friend. | ||||||||||||||
LastOnline | string | When the friend was last online. | ||||||||||||||
IsOnline | boolean | If the friend is currently online. | ||||||||||||||
LastLocation | string | The name of the friend's current location. | ||||||||||||||
PlaceId | number | The place ID of the friend's last location. | ||||||||||||||
GameId | string | The DataModel/JobId of the friend's last location. | ||||||||||||||
LocationType | number |
The location type of the friend's last location:
|
Parameters
The maximum number of online friends to return.
Returns
A dictionary of online friends (see the table above).
Code Samples
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local success, result = pcall(player.GetFriendsOnline, player, 10)
if success then
for _, friend in pairs(result) do
print(friend.UserName)
end
else
warn("Failed to get online players: " .. result)
end
GetRankInGroup
The GetRankInGroup Player function returns the player's rank in the group as an integer between 0 and 255, where 0 is a non-member and 255 is the group's owner.
Using this in a Script, as opposed to a LocalScript, will not get you the most up-to-date information. If a player leaves a group while they are in the game, GetRankInGroup will still think they're in that group until they leave. However, this does not happen when used with a LocalScript.
This is because the method caches results, so multiple calls of GetRankInGroup on the same player with the same group ID will yield the same result as when the method was first called with the given group ID. The caching behavior is on a per-peer basis: a server does not share the same cache as a client.
Parameters
The groupId of the specified group.
Returns
The player's rank in the group.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
if player:GetRankInGroup(2) == 255 then
print("Player is the owner of the group, 'LOL'!")
else
print("Player is NOT the owner of the group, 'LOL'!")
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
GetRoleInGroup
The GetRoleInGroup Player function returns the player's role in the group as a string, or Guest if the player isn't part of the group.
Using this in a Script, as opposed to a LocalScript, will not get you the most up-to-date information. If a player leaves a group while they are in the game, GetRoleInGroup will still think they're in that group until they leave. However, this does not happen when used with a LocalScript.
This is because the method caches results, so multiple calls of GetRoleInGroup on the same player with the same group ID will yield the same result as when the method was first called with the given group ID. The caching behavior is on a per-peer basis: a server does not share the same cache as a client.
Parameters
The groupId of the specified group.
Returns
The player's role in the specified group, or Guest if the player is not a member.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
print("Player is ranked as '", player:GetRoleInGroup(2), "' in group, 'LOL'!")
end
Players.PlayerAdded:Connect(onPlayerAdded)
IsFriendsWith
This function sends a request to the Roblox website asking whether a player is a friend of another user, given the Player.UserId of that user. This function caches results so multiple calls of the function on the same player with the same Player.UserId may not yield the most up-to-date result. This does not happen when used in a LocalScript.
Parameters
The Player.UserId of the specified player.
Returns
A boolean indicating whether a player is a friend of the specified user.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
if player:IsFriendsWith(146569) then
print(player.Name .. " is friends with gordonrox24!")
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
IsInGroup
The IsInGroup Player function sends a request to the Roblox website asking whether a player is a member of a group, given the ID of that group.
Using this in a Script, as opposed to a LocalScript, will not get you the most up-to-date information. If a player leaves a group while they are in the game, IsInGroup will still think they're in that group until they leave. However, this does not happen when used with a LocalScript.
This is because the method caches results, so multiple calls of IsInGroup on the same player with the same group ID will yield the same result as when the method was first called with the given group ID. The caching behavior is on a per-peer basis: a server does not share the same cache as a client.
Parameters
The groupId of the specified group.
Returns
A boolean indicating whether the player is in the specified group.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
if player:IsInGroup(7) then
print("Player is in the Roblox Fan club!")
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
LoadCharacter
The LoadCharacter Player function creates a new character for the player, removing the old one. It also clears the player's Backpack and PlayerGui.
This is useful in cases where you want to reload the character without killing the player, such as when you want to load a new character appearance after changing the player's Player.CharacterAppearance.
Note: The function is similar to Player:LoadCharacterBlocking(), but the request is processed asynchronously instead of synchronously. This means other tasks will be able to continue while the character is being loaded, including the rendering of the game and any other tasks. Also, this function can be used in a script, while LoadCharacterBlocking cannot.
After calling LoadCharacter for an individual player, it is not recommended to call it again for the same player until after that player's Player.CharacterAppearanceLoaded event has fired.
Character Loading Event order
Calling the Player:LoadCharacter() with an R15 Avatar fires events in the following order (Note: R6 ordering is different):
- Player.Character sets
- Player.CharacterAdded fires
- Player.Changed fires with a value of "Character"
- Character appearance initializes
- Player.CharacterAppearanceLoaded fires
- Character.Parent sets to the DataModel
- The Character rig builds, and the Character scales
- Character moves to the spawn location
- LoadCharacter returns
Returns
Code Samples
local Players = game:GetService("Players")
local RESPAWN_DELAY = 5
Players.CharacterAutoLoads = false
local function onPlayerAdded(player)
local function onCharacterAdded(character)
local humanoid = character:WaitForChild("Humanoid")
local function onDied()
task.wait(RESPAWN_DELAY)
player:LoadCharacter()
end
humanoid.Died:Connect(onDied)
end
player.CharacterAdded:Connect(onCharacterAdded)
player:LoadCharacter()
end
Players.PlayerAdded:Connect(onPlayerAdded)
LoadCharacterWithHumanoidDescription
This function spawns an avatar so it has everything equipped in the passed in HumanoidDescription.
After calling LoadCharacterWithHumanoidDescription for an individual player, it is not recommended to call the function again for the same player until after that player's Player.CharacterAppearanceLoaded event has fired.
See also:
- HumanoidDescription System, an article which explains the humanoid description system in greater detail and provides several scripting examples
Parameters
A HumanoidDescription containing traits like body parts/colors, body scaling, accessories, clothing, and animations that will be equipped to the loaded character.
Returns
Code Samples
local Players = game:GetService("Players")
Players.CharacterAutoLoads = false
local function onPlayerAdded(player)
local humanoidDescription = Instance.new("HumanoidDescription")
humanoidDescription.HatAccessory = "2551510151,2535600138"
humanoidDescription.BodyTypeScale = 0.1
humanoidDescription.ClimbAnimation = 619521311
humanoidDescription.Face = 86487700
humanoidDescription.GraphicTShirt = 1711661
humanoidDescription.HeadColor = Color3.new(0, 1, 0)
player:LoadCharacterWithHumanoidDescription(humanoidDescription)
end
Players.PlayerAdded:Connect(onPlayerAdded)
RequestStreamAroundAsync
For experiences where instance streaming is enabled, requests that the server stream to the player regions (parts and terrain) around the specified X, Y, Z location in the 3D world. It is useful if the experience knows that the player's CFrame will be set to the specified location in the near future. Without providing the location with this call, the player may not have streamed in content for the destination, resulting in a streaming pause or other undesirable behavior.
The effect of this call will be temporary and there are no guarantees of what will be streamed in around the specified location. Client memory limits and network conditions may impact what will be available on the client.
Usage Precaution
Requesting streaming around an area is not a guarantee that the content will be present when the request completes, as streaming is affected by the client's network bandwidth, memory limitations, and other factors.
Parameters
World location where streaming is requested.
Optional timeout for the request.
Returns
Events
CharacterAdded
The CharacterAdded event fires when a player's character spawns (or respawns). This event fires soon after setting Player.Character to a non-nil value or calling Player:LoadCharacter(), which is before the character is parented to the Workspace.
This can be used alongside the Player.CharacterRemoving event, which fires right before a player's character is about to be removed, typically after death. As such, both of these events can potentially fire many times as players die then respawn in a place. If you want to detect when a player joins or leaves the game, use the Players.PlayerAdded and Players.PlayerRemoving events instead.
Note that the Humanoid and its default body parts (head, torso, and limbs) will exist when this event fires, but clothing items like Hats, Shirts, and Pants may take a few seconds to be added to the character. Connect Instance.ChildAdded on the added character to detect these, or wait for the Player.CharacterAppearanceLoaded event to be sure the character has everything equipped.
Parameters
An instance of the character that spawned/respawned.
Code Samples
local Players = game:GetService("Players")
local function onCharacterAdded(character)
print(character.Name .. " has spawned")
end
local function onCharacterRemoving(character)
print(character.Name .. " is despawning")
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(onCharacterAdded)
player.CharacterRemoving:Connect(onCharacterRemoving)
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
-- This table maps "Player" objects to Vector3
local respawnLocations = {}
local function onCharacterAdded(character)
local player = Players:GetPlayerFromCharacter(character)
-- Check if we saved a respawn location for this player
if respawnLocations[player] then
-- Teleport the player there when their HumanoidRootPart is available
local hrp = character:WaitForChild("HumanoidRootPart")
-- Wait a brief moment before teleporting, as Roblox will teleport the
-- player to their designated SpawnLocation (which we will override)
RunService.Stepped:wait()
hrp.CFrame = CFrame.new(respawnLocations[player] + Vector3.new(0, 3.5, 0))
end
end
local function onCharacterRemoving(character)
-- Get the player and their HumanoidRootPart and save their death location
local player = Players:GetPlayerFromCharacter(character)
local hrp = character:FindFirstChild("HumanoidRootPart")
if hrp then
respawnLocations[player] = hrp.Position
end
end
local function onPlayerAdded(player)
-- Listen for spawns/despawns
player.CharacterAdded:Connect(onCharacterAdded)
player.CharacterRemoving:Connect(onCharacterRemoving)
end
local function onPlayerRemoved(player)
-- Forget the respawn location of any player who is leaving; this prevents
-- a memory leak if potentially many players visit
respawnLocations[player] = nil
end
-- Note that we're NOT using PlayerRemoving here, since CharacterRemoving fires
-- AFTER PlayerRemoving, we don't want to forget the respawn location then instantly
-- save another right after
Players.PlayerAdded:Connect(onPlayerAdded)
Players.ChildRemoved:Connect(onPlayerRemoved)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local function destroyAccessory(object)
if object:IsA("Hat") or object:IsA("Accessory") then
object:Destroy()
end
end
local function onCharacterAdded(character)
-- Wait a brief moment before removing accessories to avoid the
-- "Something unexpectedly set ___ parent to NULL" warning
RunService.Stepped:Wait()
-- Check for any existing accessories in the player's character
for _, child in pairs(character:GetChildren()) do
destroyAccessory(child)
end
-- Hats may be added to the character a moment after
-- CharacterAdded fires, so we listen for those using ChildAdded
character.ChildAdded:Connect(destroyAccessory)
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(onCharacterAdded)
end
Players.PlayerAdded:Connect(onPlayerAdded)
CharacterAppearanceLoaded
This event fires when the full appearance of a Player.Character has been inserted.
A Player.Character generally has a range of objects modifying its appearance, including Accoutrements, Shirts, Pants and CharacterMeshes. This event will fire when all such objects have been inserted into the Player.Character.
One use for this event is to ensure all accessories have loaded before destroying them. See below for an example of this.
Parameters
The Player.Character Model.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAddedAsync(player)
local connection = player.CharacterAppearanceLoaded:Connect(function(character)
-- All accessories have loaded at this point
local humanoid = character:FindFirstChildOfClass("Humanoid")
local numAccessories = #humanoid:GetAccessories()
print(("Destroying %d accessories for %s"):format(numAccessories, player.Name))
humanoid:RemoveAccessories()
end)
-- Make sure we disconnect our connection to the player after they leave
-- to allow the player to get garbage collected
player.AncestryChanged:Wait()
connection:Disconnect()
end
for _, player in Players:GetPlayers() do
task.spawn(onPlayerAddedAsync, player)
end
Players.PlayerAdded:Connect(onPlayerAddedAsync)
CharacterRemoving
The CharacterRemoving event fires right before a player's character is removed, such as when the player is respawning.
This event can be used alongside the Player.CharacterAdded event, which fires when a player's character spawns or respawns. For instance, if you would like to print a message every time a player spawns and dies:
local Players = game:GetService("Players")
local function onCharacterSpawned(player)
print(player.Name .. " is spawning")
end
local function onCharacterDespawned(player)
print(player.Name .. " is despawning")
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function()
onCharacterSpawned(player)
end)
player.CharacterRemoving:Connect(function()
onCharacterDespawned(player)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
This event is only concerned with the Character of a Player. If you instead need to track when a player joins/leaves the game, use the events Players.PlayerAdded and Players.PlayerRemoving.
Parameters
An instance of the character that is being removed.
Code Samples
game.Players.PlayerAdded:Connect(function(player)
player.CharacterRemoving:Connect(function(character)
print(character.Name .. " has died.")
end)
end)
Chatted
The Chatted event fires when a Player types a message and presses enter in Roblox's provided chat bar. This is done using some Lua bindings by the default chat script. You can prevent players from chatting by using StarterGui:SetCoreGuiEnabled() and disabling the Chat Enum.CoreGuiType.
Chat Commands
Using this event and some string manipulation functions like string.sub() and string.lower(), it is possible to create chat commands, even with arguments like player names. Usually, commands are prefixed such as heal PlayerName. To check for a prefix in a string, use string.sub() on the message to check a substring of the message: string.sub(message, 1, 6) == "/heal " (note the inclusion of the space). Then, extract the rest of the command using string.sub() again: string.sub(message, 7) will be equal to the player name. Check if that player exists, and if so, perform the command's action (in this example, healing them). Check the code samples for examples of chat commands.
Filtering
The message text fired with this event is unfiltered. If you are displaying player input like chat to other players in any form, it must be filtered using Chat:FilterStringAsync(). Keep this in mind when creating your own chat systems; if your game does not properly filter chat it may have moderation action taken against it.
Parameters
The content of the message the player typed in chat.
Deprecated. For whisper messages, this was the Player who was the intended target of the chat message.
Code Samples
local Players = game:GetService("Players")
local function onPlayerAdded(player)
local function onChatted(message)
-- do stuff with message and player
print(message)
end
player.Chatted:Connect(onChatted)
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
local teamPlaying = Teams.Playing
local teamSpectators = Teams.Spectating
local playCommand = "/play"
local function play(player)
player.Team = teamPlaying
player.TeamColor = teamPlaying.TeamColor
-- Respawn the player (moves them to spawn location)
player:LoadCharacter()
end
local function onPlayerDied(player, _character)
-- When someone dies, put them on the spectator team
player.Team = teamSpectators
end
local function onPlayerSpawned(player, character)
local human = character:WaitForChild("Humanoid")
human.Died:Connect(function()
onPlayerDied(player, character)
end)
end
local function onPlayerChatted(player, message)
if message:sub(1, playCommand:len()):lower() == playCommand then
play(player)
end
end
local function onPlayerAdded(player)
if player.Character then
onPlayerSpawned(player, player.Character)
end
player.CharacterAdded:Connect(function()
onPlayerSpawned(player, player.Character)
end)
player.Chatted:Connect(function(message, _recipient)
onPlayerChatted(player, message)
end)
end
for _, player in pairs(Players:GetPlayers()) do
onPlayerAdded(player)
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
-- Command to choose a team (note the trailing space)
local joinCommand = "/jointeam "
local function findTeamByName(name)
-- First, check for the exact name of a team
if Teams:FindFirstChild(name) then
return Teams[name]
end
-- Let's check for case-insensitive partial matches, like "red" for "Red Robins"
for _, team in pairs(Teams:GetChildren()) do
if team.Name:sub(1, name:len()):lower() == name:lower() then
return team
end
end
-- If we get to this point, no team matched the one we were looking for :(
end
local function onPlayerChatted(player, message, _recipient)
-- Note: string.sub(message, ...) is the same as message:sub(...)
if message:sub(1, joinCommand:len()):lower() == joinCommand:lower() then
-- Matched "/JOINTEAM xyz" to our join command prefix "/jointeam "
local teamName = message:sub(joinCommand:len() + 1) -- Cut out the "xyz" from "/jointeam xyz"
local team = findTeamByName(teamName)
if team then
-- Set the team!
player.Team = team
player.Neutral = false
else
-- Tell the player that team could not be found :(
player.Team = nil
player.Neutral = true
end
end
end
local function onPlayerAdded(player)
player.Chatted:Connect(function(...)
onPlayerChatted(player, ...)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Idled
This event fires approximately two minutes after the game engine classifies the player as idle. Time is the number of seconds that have elapsed since that point. The event continues to fire every 30 seconds for as long as the player remains idle.
This event only fires in client scripts, not server scripts; use a RemoteEvent to notify the server of idle players.
Roblox automatically disconnects players that have been idle for at least 20 minutes, so this event is useful for warning players that they will be disconnected soon, disconnecting players prior to those 20 minutes, or other away from keyboard (AFK) features.
To track how often automatic disconnects occur, try correlating this event with occurrences of Players.PlayerRemoving.
Parameters
The time in seconds the player has been idle.
Code Samples
local Players = game:GetService("Players")
local function onIdled(idleTime)
print(`Player has been idle for {idleTime} seconds`)
if idleTime > 900 then
-- warn player that they've been idle for 15 minutes
-- and will be disconnected in another 5
end
end
Players.LocalPlayer.Idled:Connect(onIdled)
OnTeleport
Fired when the TeleportState of a player changes. This event is useful for detecting whether a teleportation was successful.
What is the TeleportState?
When a teleportation request is made using TeleportService, there are a series of stages before the Player is teleported. The current stage is represented by the Enum.TeleportState value which is given by OnTeleport. See below for a practical example of this.
Parameters
The new Enum.TeleportState of the Player.
The name of the spawn to teleport to, if TeleportService:TeleportToSpawnByName() has been used.
Code Samples
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
local playerOnTeleport = player
player.OnTeleport:Connect(function(teleportState, _placeId, _spawnName)
if teleportState == Enum.TeleportState.Started then
print("Teleport started (" .. playerOnTeleport.Name .. ")")
elseif teleportState == Enum.TeleportState.WaitingForServer then
print("Teleport waiting for server (" .. playerOnTeleport.Name .. ")")
elseif teleportState == Enum.TeleportState.InProgress then
print("Teleport in progress (" .. playerOnTeleport.Name .. ")")
elseif teleportState == Enum.TeleportState.Failed then
print("Teleport failed! (" .. playerOnTeleport.Name .. ")")
end
end)
end)