Skip to content

Tags and attributes ​

Tags mark things as a kind - every part that is Lava, every Coin, every Door. Attributes are named values on a thing - a lava's Damage, a door's Speed. Set both in the Inspector, read them from one script for all of them: no script copied into every part.

In KHIM Engine ​

Select a part (or a Model, a folder, an object on a part); the Inspector's Tags and Attributes sections are at the bottom.

  • Tags: type a word in Add tag and press Enter. A tag is a button with an x to take it off. With a hundred coins selected, one tag goes on all of them.
  • Attributes: Add asks for a name and a kind - number, text, true/false, Vector3, Vector2 or colour - and adds it to every selected part. Then edit the value on its row.

Both are saved with the world and copied with a part.

One script for every tagged part ​

lua
-- Every part tagged Lava hurts by its own Damage attribute - now, and any cloned in later.
tags.each("Lava", function(lava)
    lava.touched:connect(function(hit)
        local player = players.fromPart(hit)
        if player then
            player:damage(lava.attributes.Damage or 10)
        end
    end)
end)

tags.each runs the function for every part with the tag now, and for every one that comes later (a clone parented, a part streamed in). Each runs in its own thread, so one that waits holds up none of the others.

The tags module ​

FunctionWhat it does
tags.get(tag)Every part and object in the game with the tag
tags.each(tag, fn)fn for each one now and each that comes later; returns the connection
tags.added(tag)An event: something got the tag, or came into the game with it
tags.removed(tag)An event: something lost it, or left the game with it
tags.all()Every tag in use

"In the game" means it has a parent all the way up: a clone not parented yet, or a destroyed part, isn't.

On a part or object ​

lua
part:addTag("Coin")
part:removeTag("Coin")
print(part:hasTag("Coin"))
print(part:getTags())        -- a sorted list

part:setAttribute("Speed", 12)
print(part:getAttribute("Speed"))   -- 12, or nil when it has none
part:setAttribute("Speed", nil)     -- takes it off

part.attributes.Damage = 25          -- the short way, to read and set
for name, value in part.attributes do print(name, value) end

An attribute's value is a number, text (up to 4,096 bytes), true/false, a vec3, a vec2 or a colour. Names are letters, digits and _.

Hearing changes ​

lua
local door = world.Door
door:getAttributeChangedSignal("Speed"):connect(function()
    print("speed is now", door:getAttribute("Speed"))
end)

door.attributeChanged:connect(function(name)
    print(name .. " changed")
end)

Who sees what ​

A part's tags and attributes are saved with the world and sent to every player. When a server Script changes them, players get the new set, and attributeChanged fires on their devices too - so the server can hand ClientScripts a value without a message:

lua
-- Script
world.Scoreboard:setAttribute("TimeLeft", 90)

-- ClientScript
local board = world:waitFor("Scoreboard")
board:getAttributeChangedSignal("TimeLeft"):connect(function()
    timerLabel.text = tostring(board:getAttribute("TimeLeft"))
end)

A ClientScript's changes stay on its player. Parts in ServerService and StorageService never leave the server.

Limits ​

  • A tag: 1 to 100 characters, no line breaks; 64 tags a part.
  • 128 attributes a part, and 60 KB of tags and attributes together.

Some tags KHIM knows ​

TagMeans
ClimbableCharacters climb it: a ladder, a vine, a truss
BuiltA block a player placed with building