Parts and objects
A part's properties
| Member | Type | What it is |
|---|---|---|
position | vec3 | Where its middle is |
rotation | vec3 | Its turn in degrees (X, Y, Z) |
transform | transform | Position and turn together |
size | vec3 | Units along its own X, Y, Z |
color | colour | rgb(...) or hsv(...) |
transparency | number | 0 solid to 1 invisible |
anchored | boolean | Stays where it is; unanchored parts fall and can be pushed |
canCollide | boolean | Off: characters and parts go through it |
shape | string | "Block", "Ball", "Cylinder", "Wedge" |
material | string | "Plastic", "Smooth", "Neon", "Glass", "Metal", "Wood", "Grass", "Brick", "Concrete", "Sand", "Rock", "Water", "Leaves"... |
velocity | vec3 | Units a second |
group | string | Its collision group ("Default") - see Physics and joints |
mesh | string | The model a MeshPart shows |
touched, touchEnded | event | Something started / stopped touching it |
local part = world.Platform
part.position = vec3(0, 10, 0)
part.rotation = vec3(0, 45, 0)
part.color = rgb(80, 160, 255)
part.material = "Neon"
part.transparency = 0.3A material changes a part's weight, grip and bounce too, not only its look: Metal is heavy, Wood light, Smooth slippery.
Every object
Parts, Models, Folders, objects on parts, UI - everything shares these:
| Member | What it does |
|---|---|
name, className, parent | Its name, its class, what it is inside |
find(name) | A child by name, or nil |
waitFor(name, timeout?) | A child by name, waiting until it exists (nil after timeout) |
findByClass(className) | The first child of a class |
children() | A list of its children |
isA(className) | Whether it is of that class |
clone() | A copy, with everything inside it (scripts inside are not copied) |
destroy(), destroyAfter(seconds) | Removes it and everything inside |
tween(goals, time or options) | Moves its properties smoothly |
And children by name, as members: world.House.Door.
for _, child in world.Coins:children() do
if child:isA("Part") then child.color = rgb(255, 215, 0) end
endMaking and removing
local crate = new("Part", world) -- the parent as the second argument
crate.name = "Crate"
crate.size = vec3(3, 3, 3)
crate.material = "Wood"
crate.anchored = false
crate.position = vec3(0, 30, 0)
local tree = shared.Tree:clone() -- a copy of a Model kept in ReplicationService
tree.parent = world
crate:destroyAfter(10)A Model groups parts that move and copy as one. new("Model") makes one; put parts inside with part.parent = model.
Keep templates out of the world
Models you clone - enemies, coins, projectiles - are best kept in ReplicationService (shared) or StorageService (server only), so they aren't in the world until you clone them.
Server and client changes
A server Script's change to a part reaches every player. A ClientScript's change stays on that player's screen. Moving a door from a ClientScript moves it for one player only - and the server, which owns collisions, still has it closed. See Server and client.
Tweens
local lift = world.Lift
local bottom = lift.position
local tween = lift:tween({position = bottom + vec3(0, 20, 0)}, {
time = 3,
style = "Sine",
direction = "InOut",
repeats = -1, -- forever
reverses = true, -- there and back
})
-- tween:cancel() stops it; tween.completed fires when it endsAnything numeric or a value type tweens: position, size, color, transparency, rotation, transform...
Raycasts
world:raycast(origin, direction) finds the first part along a line:
local hit = world:raycast(vec3(0, 50, 0), vec3(0, -100, 0)) -- straight down, 100 units
if hit then
print(hit.part.name, hit.position, hit.normal, hit.distance)
endObjects on parts
Many objects work by being put inside a part:
| Object | What it adds |
|---|---|
Clickable | Players can click the part |
Prompt | "[E] Open" near the part |
Billboard | Text floating over the part |
Sign | Writing on one face of the part |
Sound | A sound heard around the part |
Light | The part gives off light |
ParticleEmitter | Sparks, smoke, fire... |
Decal, Texture | A picture on a face |
Highlight | An outline, even through walls |
Trail, Beam | A streak behind it, a band to another part |
Zone | The part is an area that knows who is inside |
Hinge, Slider, BallJoint, Spring, Rope | Joins it to another part |
Mover, Spinner, Thruster | Push a loose part |
Teleporter, Hazard, Checkpoint, Pickup, Boost, Motion, Spawner, Seat | Gameplay with no code |
Put them in in KHIM Engine, or from a script: new("Light", part). A script reaches one by its name: script.parent.Light.brightness = 3.
See Touch, prompts and zones, Sounds, lights and effects and Classes.
Values
IntValue, NumberValue, StringValue, BoolValue, ObjectValue, Vector3Value, Color3Value hold one value for scripts to read - a price on a shop item, a door's speed - set in the Inspector:
local price = script.parent.Price.value
script.parent.Price.changed:connect(function(new) print("now", new) end)Attributes do the same job without an extra object.
Between scripts on the same side
A BindableEvent lets scripts tell each other something happened; a BindableFunction lets one ask another a question:
-- one Script
local roundOver = shared.RoundOver -- a BindableEvent
roundOver:fire("Red")
-- another Script
shared.RoundOver.event:connect(function(winner) print(winner .. " won") end)local getScore = shared.GetScore -- a BindableFunction
getScore.onInvoke = function(player) return player.stats.Coins end
print(getScore:invoke(somePlayer))To cross between the server and players, use net instead.