Roblox compatibility

Studz's API grew out of Roblox's so you can bring scripts and habits over. Where Roblox's spelling is clumsy Studz has its own, and the Roblox one is deprecated: it still works, gives the same result and warns once. This page lists what Studz adds, how the deprecated spellings map to the Studz ones, and the quirks you may run into.

What Studz adds

Everything below is official and PascalCase. The utility tables chat, server, ui and Sound are lowercase-named tables of their own.

AdditionThe problem it solves
part.PlayerTouched, PlayerTouchEnded (player, character, hit)Roblox Touched fires for every part that touches, so scripts check hit.Parent:FindFirstChild("Humanoid") and GetPlayerFromCharacter. These fire only for players.
part.Clicked (player)Forgetting the ClickDetector is the classic "my click does nothing". Clicked makes it.
Instance.Create(class, props)Setting properties after parenting replicates every intermediate state. This sets properties first and parent last, and leaves no half-made object if a property is wrong.
inst:GetChild(name)FindFirstChild returns nil and the script dies two lines later with "attempt to index nil". GetChild fails at the lookup and lists the children.
inst:TweenTo(...), tween:Await()Three objects and a Completed:Wait() for the most common animation.
inst:DestroyAfter(seconds)Debris:AddItem(inst, seconds) without the service.
Players:ForEachPlayer(fn), player:ForEachCharacter(fn)PlayerAdded misses players who joined before the script ran. CharacterAdded misses the current character.
remote:Listen(schema, fn)A validated FromClient: bad types, NaN and extra arguments never reach your code.
signal:Once(fn)A one-shot On without the disconnect-in-callback dance.
ChildAdded, ChildRemoved, DescendantAdded, Destroying, GetPropertyChangedSignalSee Events, signals and tasks.
task.after, task.every, task.debounceTimers and debouncing without hand-written loops and flags.
player:Tell(text), player:SendChat(text, author)Private chat lines.
part:Spin(degreesPerSecond, axis)Constant rotation.
part:WeldTo(other), part:BreakWelds()A weld takes an Instance.new, three assignments and a parent. WeldTo is one call, and it can follow a player's limb.
limb.Transform, Scale, Visible, Color, character:ResetLimbs()Posing a character in Roblox means Motor6D joints and animation assets. Here each limb can simply be posed from a script. See Limbs.
character.Animator, animator:Play(clip, options)Roblox plays animation assets through Humanoid:LoadAnimation. Here the clips the character model ships play from one call, on the limbs you choose, and tell you when they end. See Animations.
workspace:GetPartBoundsInRadius(position, radius)Objects near a point.
chat, server, ui, Sound tablesOne-line helpers. See Globals and services.
math.lerp, table.clone, table.clearSmall helpers from the Luau library.

What differs from Roblox

RobloxStudz
LuauLua 5.4. No +=, continue, types or string interpolation.
HttpService:GetAsync and friendsNot available. They raise an error.
Data stores hold any valueData stores hold numbers only. See Saving data.
WeldConstraint, WeldThey exist. Weld.C0 and C1 mean the same as in Roblox. A held part is anchored while a weld holds it. See Welds.
Motor6D, animation assets (LoadAnimation)Not available. Pose a character's limbs from a script (Limbs) or play the clips the character model ships with character.Animator (Animations). Your own clips and an animation editor come later.
Many services (MarketplaceService, TeleportService, Teams, ...)Inert objects that warn once.
Many properties (Archivable, Locked, Massless, CanTouch, Reflectance, ...)Accepted and ignored, with one warning.
Unknown class in Instance.newA plain Part, with a warning.
Misspelled memberAn error with a suggestion, instead of nil.
Instances exist before parentingInstance.new("Part") is in the workspace immediately.

Deprecated spellings

All of these still work. Each prints one warning that names the replacement, and each will be removed in a later release. Spellings are resolved before anything else, so part.pos = ... is exactly part.Position = ... and humanoid.WalkSpeed = ... is exactly humanoid.Speed = ....

The lowercase, camelCase and snake_case forms of a Roblox name (getChildren, find_first_child, walkSpeed) point at the Studz name too.

Roblox spellings

Names shared with Roblox that are not deprecated: Instance.new, Destroy, Clone, IsA, IsDescendantOf, Touched, TouchEnded, Changed, Died, Raycast, TweenService:Create, PlayerAdded and the value types (Vector3, CFrame, Color3, ...).

Finding things:

RobloxStudz
inst:FindFirstChild(name)inst:FindChild(name)
FindFirstChildOfClass, FindFirstChildWhichIsAinst:FindChildOfClass(class) (it matches subclasses too)
FindFirstAncestorinst:FindAncestor(name)
FindFirstAncestorOfClass, FindFirstAncestorWhichIsAinst:FindAncestorOfClass(class)
inst:GetChildren()inst:Children()
inst:GetDescendants()inst:Descendants()
inst:GetFullName()inst:FullName()
inst:WaitForChild(name, timeout)inst:AwaitChild(name, timeout)
game:GetService(name)game:Service(name)

Players and characters:

RobloxStudz
Players:GetPlayers()Players:List()
Players:GetPlayerByName(name)Players:FindByName(name)
Players:GetPlayerByUserId(id)Players:FindById(id)
Players:GetPlayerFromCharacter(character)Players:FromCharacter(character)
player:LoadCharacter(), humanoid:LoadCharacter():Respawn()
humanoid:TakeDamage(amount)humanoid:Damage(amount)
humanoid.WalkSpeedhumanoid.Speed
humanoid.JumpPowerhumanoid.JumpForce

Signals and timers:

RobloxStudz
signal:Connect(fn)signal:On(fn)
connection:Disconnect()connection:Off()
connection.Connectedconnection.Active
RunService.HeartbeatRunService.Frame
RunService.RenderSteppedRunService.Draw
button.MouseButton1Click, button.Activatedbutton.Clicked
task.delay(seconds, fn)task.after(seconds, fn)
Debris:AddItem(inst, seconds)inst:DestroyAfter(seconds)

Remotes (RemoteEvent and RemoteFunction):

RobloxStudz
remote:FireServer(...)remote:ToServer(...)
remote:FireClient(player, ...)remote:ToPlayer(player, ...)
remote:FireAllClients(...)remote:ToAll(...)
remote.OnServerEventremote.FromClient
remote.OnClientEventremote.FromServer
remote:InvokeServer(...)remote:CallServer(...)
remote.OnServerInvoke, OnClientInvokeremote.OnServerCall, OnClientCall

Properties:

RobloxStudz
sound.PlaybackSpeedsound.Speed
sound.Loopedsound.Loop
sound.RollOffMaxDistancesound.MaxDistance
part.AssemblyLinearVelocity, AssemblyAngularVelocitypart.LinearVelocity, part.AngularVelocity
part.Velocitypart.SurfaceVelocity. In Studz this has always been the surface (conveyor) velocity, not a push, so the name now says so.
Color3 on a part, decal or limbColor
TextColor3, BackgroundColor3, BorderColor3TextColor, BackgroundColor, BorderColor
BorderSizePixelBorderWidth
TextStrokeColor3, TextStrokeTransparencyShadowColor, ShadowTransparency

Older Studz spellings

Shorthand Studz had before its API was cleaned up. Same rules: they work, and warn once.

OldUse
The lowercase, camelCase or snake_case form of any method (getChildren, findFirstChild, applyImpulse, takeDamage, kick, kill, heal, ...)The PascalCase Studz name
findFindChild
Remove, removeDestroy
FindFirstPlayerPlayers:FindByName
OwnsGamePass, UserOwnsGamePassHasGamePass
OwnsBadgeHasBadge
IsInGroup, GetRankInGroup, GetRoleInGroupIsInClan, GetRankInClan, GetRoleInClan
AddAccessory, WearClothing, wearWearAccessory
RemoveClothing, unwearRemoveAccessory
ReplaceClothingReplaceAccessory
SetAccessoriesSetOutfit
on_touch(fn(hit, player)), onTouchpart.PlayerTouched
on_touch_end, onTouchEndpart.PlayerTouchEnded
on_click(fn), onClickpart.Clicked (parts) or button.Clicked (GUI)
on_chatplayer.Chatted
on_player_added, on_player_removingPlayers.PlayerAdded, Players.PlayerRemoving
send(text)Tell
tp(pos), teleport(pos)Teleport (players) or assign Position
tween(...), Tween, TweenPosition, TweenSize, TweenColor, TweenTransparencyTweenTo(goals, seconds, style, direction)
FadeIn(seconds), fade_inTweenTo({ Transparency = 0 }, seconds)
FadeOut(seconds), fade_outTweenTo({ Transparency = 1 }, seconds)
world:spawn({ name=, pos=, ... })Instance.Create("Part", { Name=, Position=, ... })
world:all(name)Descendants()
world:tagged(tag)CollectionService:GetTagged(tag)
world:near(pos, radius)GetPartBoundsInRadius(pos, radius)
Chat, Broadcast, Announce, PrivateBroadcast, SendMessage, SendNotification (on Players or a player)chat.broadcast, chat.announce, chat.whisper, player:Tell
CreateText, CreateFrame, CreateButton (on GuiService)Instance.new("TextLabel"), ("Frame"), ("TextButton")
ClearAllText, Clear, clearAllGuiService:ClearAll()
handle:cancel()Cancel
signal:wait, signal:onceWait, Once
The lowercase, camelCase or snake_case form of any property (part.position, part.canCollide, sound.sound_id)The PascalCase Studz name
pos, PosPosition
rot, RotOrientation
solid, SolidCanCollide
alpha, opacityTransparency. These are the inverse (alpha = 1 - Transparency) and keep that meaning.
PitchSpeed (sounds)
IsPlayingPlaying
FontSize, FontFamilyTextSize, Font
ImageTexture
ClickClicked
Assigning a table (part.Position = { 0, 5, 0 })Assign a Vector3, UDim2 or Color3

Globals

Deprecated globals cannot be intercepted, so they give no warning. Switch anyway.

OldUse
world, World, scene, Sceneworkspace
players, plrsPlayers
lightingLighting
camera, mouseworkspace.CurrentCamera, player:GetMouse()
spawn, after, every, defertask.spawn, task.after, task.every, task.defer
vec3, v3, rgb, hex, colorVector3.new, Color3.fromRGB and friends
tween, fade_in, fade_out, spinTweenTo, part:Spin

Known quirks

Current behaviours worth knowing. Several are planned to change.

  • Containers are open ended. workspace.Foo, model.Foo and Players.Foo are nil when nothing is called Foo. Only parts, lights, values, sounds, GUI elements and humanoids check their members.
  • Models and containers are identified by name. Two models with the same name are treated as one container, and workspace.Foo scans the scene linearly.
  • Instance.new("Part") is in the workspace immediately. Instance.Create and "parent last" avoid showing a half-built object. part.Parent = nil destroys.
  • FindChildOfClass behaves like Roblox's FindFirstChildWhichIsA, and some ancestor and child name searches are case-insensitive.
  • workspace.Player and workspace.Character resolve to the local player's character. This is a Studz convenience. Do not rely on it in server scripts.
  • GUI ids are unique per process. Elements created by a server script and by a client's LocalScript live in separate tables.
  • Changed and GetPropertyChangedSignal only see assignments made by scripts, not changes made by the engine (physics, the character controller).
  • workspace:GetPartBoundsInRadius returns objects by position only, with no size, and includes non-physical objects.
  • A limb's Transparency is all or nothing. Below 0.5 shows it and from 0.5 up hides it. A limb can be scaled, coloured and hidden, but not drawn half see-through yet.
  • Limb poses are drawn on top of the animation. Turn the built-in run and jump animation off with animator.Locomotion = false. A part welded to a limb follows the poses a script gave, not the animation or the clips a script plays.
  • The Animator plays only the clips the character model ships (Run and Jump), at most four at once. Your own clips and an editor are planned.
  • Welds are made while the game runs. A weld a script makes is not saved with the place, and a weld only holds on the server. Use the Weld tool in Polycarbonate for welds that belong to the place.
  • Humanoid.HealthChanged exists on rigs (NPCs) only. A player's Humanoid has no such signal yet: poll Health, or use Died.

Roadmap

Planned, in rough order:

  1. Identify models and containers by id instead of name, and check container lookups (workspace.Foo) the way parts are checked.
  2. HealthChanged on players' humanoids, Changed for engine-driven changes, and DescendantRemoving.
  3. Body movers and more constraints: LinearVelocity, AlignPosition, AlignOrientation, SpringConstraint, and hinges. (Welds exist. A LinearVelocity mover would clash with the part.LinearVelocity property, so movers will get names of their own.)
  4. Animation clips of your own and an animation editor, to replace hand-written limb poses. The Animator already plays and blends the clips that ship with the character model.
  5. Remove the deprecated spellings (the Roblox ones and the older Studz ones), after the warnings have been out for a few releases.
  6. Luau as the runtime (+=, continue, types, string interpolation). Deliberately postponed.