Tags

Tags are string labels you attach to any node - a way to group and query objects by role rather than by name, and the grouping stays live: reference a tag from a formula, and that formula tracks every node currently carrying it, automatically.

Adding tags

Select one or more nodes. In the properties panel header, click the tags area (it reads "tags" in gray when nothing's set yet) to open a small editor: type comma-separated names - brick, destructible, row1 - and press Enter to commit, or Escape to cancel. As you type, a live suggestion list shows up to eight matching existing tags, so reusing a tag across many nodes is a click, not retyping.

Multiple nodes can share the same tag, and one node can carry several tags at once. Selecting more than one node at a time shows only the tags they all have in common, so editing there sets that shared intersection.

Tag badges: hover and select

Once a node has tags, they render as small #tag badges right in the panel header.

Hover a badge and every node carrying that tag gets a real canvas highlight — a diagonal-stripe fill plus a blue outline — and the matching rows light up in the layers tree at the same time. Move your cursor away, and the highlight clears.

Shift+click a badge to select every node with that tag at once — the fast path for a bulk operation (recolor every brick, delete every enemy) without lassoing them by hand.

Using tags in formulas

Tag.<name> resolves to a live array of every node currently carrying that tag — plain array semantics, nothing special to learn beyond that:

Tag.brick              // → array of all nodes tagged "brick"
Tag.brick.length        // → count of brick nodes
Tag.brick[0]            // → the first brick node
Tag.brick[0].x          // → that node's x position

This is genuinely reactive: destroy a tagged node, or add/remove a tag from one, and every formula reading that tag recalculates on its own — nothing to manually refresh.

// Win condition — no bricks left
WinText.visible = Tag.brick.length === 0

// Enemy count display
Counter.text = Tag.enemy.length

Typing Tag. in a formula field brings up autocomplete listing every tag currently registered anywhere in the document; typing Tag.brick. after that autocompletes the usual node properties (x, y, width, rotation, and so on) on whichever node you index into.

Checking type and tag together: is()

Every node has an is() method that checks both its type and its tags in one call — useful in a collision handler where you want to know not just what hit you, but what kind of thing it was:

// Inside a collide event handler
if (event.target.is("brick")) {
  event.target.destroy()
}

Tagging objects from code

Tags aren't only set by hand in the panel, setTags() is a real method you can call from an event or method body, which is how a spawned object gets counted the instant it exists:

// Inside a method that spawns a new object
newBullet.setTags(["bullet"])
// Tag.bullet.length increases immediately — any formula reading it updates

Common patterns

// Win condition
WinText.visible = Tag.brick.length === 0

// Score tied to a tag count
ScoreBox.width = Tag.coin.length * 20

// Point toward the nearest tagged threat
Arrow.rotation = Math.atan2(Tag.enemy[0].y - this.y, Tag.enemy[0].x - this.x) * 180 / Math.PI

For the always-available globals tags sit alongside (mouse, keys, time, dt, frame), see Formula globals; for writing the event handlers and methods that actually call setTags() or destroy(), see Events and methods.

On this page

Formo

The browser studio where drawings become animations, toys, and games. Your files, open HTML export, nothing to install.