Players and characters

This page covers the Players service, each Player, and the Humanoid that gives a character health and movement.

The Players service

MemberDescription
Players.LocalPlayerThe player on this machine. Client only.
Players:List()Everyone currently in the game.
Players:FindByName(name)A player by name, or nil.
Players:FindById(id)A player by user id, or nil.
Players:FromCharacter(character)The player who owns a character model.
Players.PlayerAddedFires with the player when someone joins.
Players.PlayerRemovingFires with the player when someone leaves.
Players.CharacterAddedFires when any player's character spawns.
Players:ForEachPlayer(fn)Studz addition. Runs fn for everyone already in the game and everyone who joins later. Returns the PlayerAdded connection.
Players:SetStatsSaving(false)Turns off automatic leaderstats saving. See Saving data.

Why ForEachPlayer

PlayerAdded only fires for players who join after you connect. A script that starts after someone arrived would miss them. ForEachPlayer handles both groups:

Players:ForEachPlayer(function(player)
    print("hello", player.Name)
end)

The Player

Properties

PropertyDescription
Name, DisplayNameAccount name and display name.
UserIdThe account's numeric id.
CharacterThe current character model, or nil while respawning.
PlayerGuiThe player's interface container (client).
leaderstatsA folder of number values shown in the player list. See Saving data.

Events

EventDescription
player.CharacterAddedFires with the character on spawn and on each respawn.
player.ChattedFires with the message text when the player chats.
character.Humanoid.DiedFires when the character dies.
player:ForEachCharacter(fn)Studz addition. Runs fn for the current character and for every respawn.

Methods

MethodDescription
player:Kick([reason])Removes the player from the game.
player:Teleport(target)Moves the character to a Vector3, a CFrame or another player.
player:DistanceFromCharacter(point)Distance in studs from the character to a point.
player:Respawn()Respawns the character.
player:Kill()Sets health to zero.
player:Heal([amount])Restores health, optionally by a given amount.
player:SetSpeed(n)Sets walk speed.
player:SetJumpPower(n)Sets jump power.
player:GetMouse()The player's mouse. Client only.

Chat

MethodDescription
player:Tell(text)Sends a private system line to this player.
player:SendChat(text, [author])Sends a chat line as if author said it. The default author is "Server".

To message everyone, use the chat helper in Globals and services.

Outfits

These server-side methods change what everyone sees. They also work on the player's Character and Humanoid. Accessories are identified by their catalog id.

MethodDescription
:WearAccessory(id)Puts an item on.
:RemoveAccessory(id)Takes an item off.
:ReplaceAccessory(old, new)Swaps one item for another.
:SetOutfit({ids})Replaces the whole outfit with the listed items.
:ClearAccessories()Removes every item.
:ResetAppearance()Returns to the player's own avatar.
:GetAccessories()A list of what they are wearing.
:HasAccessory(id)Whether they wear an item.

Limbs

A character has six parts a script can pose: Head, Torso, LeftArm, RightArm, LeftLeg and RightLeg (the Roblox spellings such as character["Left Arm"] work too). Use them for emotes, poses and small animations. They work on a player's Character and on a rig, and everyone sees the result.

MemberTypeDescription
limb.TransformCFrameThe turn and shift of the limb about its joint: the shoulder, the hip, the neck, or the middle of the torso. CFrame.new() is no pose. Posed limbs are drawn on top of the built-in animation, so a raised arm still swings with the run cycle.
limb.ScaleVector3 or numberSize multiplier about the joint. 1 is normal. At most 16.
limb.SizeVector3The limb's size in studs. Assigning it sets Scale.
limb.Visiblebooleanfalse hides the limb.
limb.TransparencynumberBelow 0.5 shows the limb and from 0.5 up hides it. There is no half-transparent limb yet.
limb.ColorColor3Colours the limb over the avatar's own. nil until you set one.
limb.CFrame, limb.Position, limb.OrientationWhere the limb is in the world. Reading is exact: it follows the player and the pose. Assigning poses the limb so it ends up there (Torso and HumanoidRootPart move the whole character instead).
:ResetLimbs()Takes every pose away, so each limb follows the animation again. Works on a player, a character, a Humanoid, a rig or a limb. It leaves clips that are playing alone; :ResetAppearance() clears both.
-- Raise the right arm, make the head a little bigger, tint the left leg.
local character = player.Character
character.RightArm.Transform = CFrame.Angles(0, 0, math.rad(150))
character.Head.Scale = Vector3.new(1.3, 1.3, 1.3)
character.LeftLeg.Color = Color3.fromRGB(255, 80, 80)

Rotations turn the limb about its joint around the character's own axes, so the right arm raises with a turn about Z and swings forward and back with a turn about X. Tweens work on limbs: TweenService:Create(arm, TweenInfo.new(1), { Transform = CFrame.Angles(0, 0, math.rad(90)) }):Play(). For a loop of poses see the animation player in Examples.

Things to know:

  • A limb you never touch keeps the built-in animation. A pose that goes back to nothing is dropped, so an untouched limb costs no network traffic.
  • Numbers are limited: a shift is at most 64 studs and a scale at most 16, and NaN counts as zero.
  • Poses are kept until you reset them. They are cleared when the character dies.
  • A LocalScript can pose its own character, shown on that player's screen only.
  • Anything can follow a limb: part:WeldTo(character.RightArm). See Welds.
  • A dead character's limbs fall apart and ignore poses.

Animations

A character plays one clip chosen by what it is doing: the run cycle while it moves, the jump clip in the air, and the rest pose otherwise. character.Animator (also rig.Animator and humanoid.Animator) lets a script play those clips itself and take over the automatic ones. Everyone sees the result.

The clips Studz ships are listed in animator.Clips: "Run" (it repeats; "Walk" is another name for it) and "Jump" (it plays once). They only move the arms and legs (Run) or the arms (Jump). Custom clips and an animation editor are not available yet.

MemberTypeDescription
animator:Play(clip, [options])trackStarts a clip and returns its track. See the options below.
animator:Stop([clip], [fade])Stops every track, or the ones playing clip. With fade (seconds) the clip fades out first.
animator:GetTrack(clip)track or nilThe track that is playing clip.
animator.TrackstableThe tracks that are playing now.
animator.ClipstableThe names of the clips: { "Run", "Jump" }.
animator.Locomotionbooleanfalse turns off the built-in run and jump animation, so the character shows only what you play. Back to true for a new character.
animator.LocomotionSpeednumberHow fast the built-in run cycle plays. 1 is normal, 0 freezes it. At most 7.9.

The options of Play, all optional:

OptionDefaultDescription
Speed1Playback speed, from -16 to 16. Negative plays backwards.
Weight10 to 1: how much of the clip shows over what is below it (the built-in animation, and tracks that started earlier).
Loopthe clip's owntrue starts the clip over when it ends. A clip that does not loop ends the track and goes back to what is below it.
Limbsall sixThe limbs the clip moves: a name ("RightArm"), a list ({ "LeftArm", "RightArm" }) or "Arms", "Legs", "All". The clip leaves the other limbs alone.
Fade0Seconds to fade the clip in.
Start0Seconds into the clip to start from.

An option that does not exist, or a value of the wrong type, is an error that says what is allowed.

Animation tracks

animator:Play returns a track.

MemberTypeDescription
track.ClipstringWhich clip it plays. Read-only.
track.LengthnumberThe clip's length in seconds. Read-only.
track.SpeednumberPlayback speed. You can change it while it plays.
track.Weightnumber0 to 1. Assigning it ends any fade.
track.LoopbooleanWhether it starts over at the end.
track.TimenumberSeconds into the clip. Assign it to jump to another moment.
track.LimbstableThe limbs it moves. Read-only.
track.Playingbooleantrue while it plays and is not paused.
track.Activebooleantrue until it ends or is stopped.
track:Pause(), track:Resume()Freeze the clip where it is, and carry on.
track:Stop([fade])Ends the track, after fading out over fade seconds if you give one.
track.Finishedsignal:On(function(reason) end). reason is "Ended" (a clip that does not loop reached its end), "Stopped" or "Interrupted" (something else took the clips away, such as a respawn, or a fifth clip made room).
track:Await()stringYields until the track finishes and gives the reason.
-- Make an NPC run on the spot for three seconds, then ease out.
local guard = workspace.Guard
guard.Animator.Locomotion = false
local run = guard.Animator:Play("Run", { Speed = 2, Fade = 0.3 })
task.wait(3)
run:Stop(0.3)
print(run:Await())   --> Stopped

-- Swing only the arms, with the legs standing still.
local animator = player.Character.Animator
animator.Locomotion = false
animator:Play("Run", { Limbs = "Arms" })

-- Slow motion for a power-up: the built-in run cycle at half speed.
animator.LocomotionSpeed = 0.5

-- A jump flourish, then carry on.
local flourish = animator:Play("Jump", { Speed = 0.6 })
flourish.Finished:On(function(reason) print("done:", reason) end)

Things to know:

  • A character plays at most four tracks at once. A fifth Play ends the one that has been playing longest (its Finished gives "Interrupted").
  • Tracks are layered in the order they started: each one is blended over everything below it, limb by limb, by its Weight. Poses (limbs) are applied on top of all of it.
  • A clip that does not loop ends by itself. Finished fires, and the limbs go back to what is below.
  • When the character dies and respawns, its tracks are interrupted and Locomotion is true again.
  • Only what is playing and how is sent to other players, not every frame. Each player's game keeps its own clock, so two screens can differ by a few frames.
  • The server does not draw the characters, so a part welded to a limb follows the player and the limb's pose, but not a clip that is playing.
  • A LocalScript can animate its own character, shown on that player's screen only.
  • ResetLimbs removes poses and leaves tracks playing. animator:Stop() stops the tracks and leaves poses alone.

Game passes and badges

Server only. See Earning on Studz for how to create them.

MethodDescription
:HasGamePass(id)Whether the player owns the pass. Checked on the server. In the Polycarbonate playtest, the tester owns every pass.
:HasBadge(id)Whether the player has the badge.
:AwardBadge(id)Gives the badge. Returns false if they already had it.
local VIP_PASS = 12
Players:ForEachPlayer(function(player)
    if player:HasGamePass(VIP_PASS) then
        player:Tell("Welcome back, VIP!")
    end
end)

Clans

Server only.

MethodDescription
:IsInClan(id)Whether the player belongs to the clan.
:GetRankInClan(id)A number: Owner is 255, Admin is 200, Member is 1, or a custom rank. 0 when not a member.
:GetRoleInClan(id)The role name. "Guest" when not a member.
:GetClans()The clans the player belongs to.

The Humanoid

Every character has a Humanoid. Find it with character:FindChild("Humanoid") or character.Humanoid.

MemberTypeDescription
HealthnumberCurrent health. Clamped to 0 through MaxHealth.
MaxHealthnumberDefault 100.
SpeednumberWalk speed. Default 16. (WalkSpeed is the deprecated Roblox spelling.)
JumpForcenumberDefault 50. (JumpPower is deprecated.)
JumpbooleanWrite true to make the character jump.
DisplayNamestringThe name shown over the character.
:Damage(amount)Reduces health.
:Heal(amount)Restores health.
.DiedsignalFires when health reaches zero.

Health, speed and jump power are decided by the server. A LocalScript cannot change them. A player's Humanoid has no HealthChanged yet: poll Health, or use Died. (Rigs below do have it.)

-- A lava part
lava.PlayerTouched:On(function(player, character)
    character.Humanoid:Damage(25)
end)

Rigs (NPCs)

A Humanoid part placed in the workspace (Studio: Insert > Humanoid Dummy) is a rig: a character that no player controls. It is drawn as an avatar with a nametag, it is solid, and it has the same Humanoid a player does. A rig is its own character, so there is no model to dig through:

local guard = workspace.Guard        -- the rig part: Position, CFrame, Orientation, CanCollide ...
local humanoid = guard.Humanoid      -- its Humanoid (also FindChildOfClass("Humanoid"))
print(humanoid.Parent == guard, guard.HumanoidRootPart == guard)   --> true  true

Everything in the Humanoid table above works on a rig's Humanoid (Health, MaxHealth, Speed, JumpForce, DisplayName, :Damage, :Heal, .Died). The values are stored on the part, so they are saved with the place and set in the Studio Properties panel. DisplayName is the name shown over the rig; leave it empty to show the part's Name.

Rigs add these members:

MemberTypeDescription
:MoveTo(position)Walk in a straight line to position at Speed (the height stays the same). A new :MoveTo replaces the walk in progress. A dead rig ignores it.
:Stop()Cancel the walk.
:LookAt(position or part)Turn to face it (also on the rig part).
.MoveToFinishedsignal:On(function(reached) ... end). true on arrival, false if the walk was replaced, stopped, or the rig died.
.HealthChangedsignal:On(function(health) ... end) after every change of health.
.IsMovingbooleantrue while a :MoveTo walk is under way.
.RootPartPartThe rig part itself.
:Kill()Sets Health to 0.
:Respawn()Revives the rig at full health where it stands.

When a rig's health reaches zero it fires Died, disappears and stops blocking the way. Setting Health above zero (or :Respawn()) brings it back. Walking rigs animate by themselves. Everything runs on the server.

A rig has the same six limbs as a player: guard.Head, guard.RightArm and so on. The poses are stored on the part with the rest of the rig's settings, so they are replicated to everyone, and guard.Humanoid:ResetLimbs() clears them. A rig that a script poses is the quickest way to build a looping dance or an idle animation for an NPC.

local guard = workspace.Guard.Humanoid
guard.DisplayName = "Captain Brick"
local a = workspace.Guard.Position
local b = a + Vector3.new(20, 0, 0)

-- Patrol back and forth, resting a second at each end.
local toB = true
guard.MoveToFinished:On(function()
    task.wait(1)
    toB = not toB
    guard:MoveTo(toB and b or a)
end)
guard:MoveTo(b)

guard.Died:On(function()
    task.wait(5)
    guard:Respawn()
end)

A rig walks through walls and does not follow the ground: :MoveTo only changes its X and Z. Rigs do not hurt players on touch; use a Touched handler on the rig part and Damage for that.