Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

README.md

entityRef members

One table describing every member of the entityRef — the value entity(id) returns.

--!members entityRef entity/proxy
local M: { [string]: Member } = {
    id      = { kind = "property", type = "string", doc = "This entity's id string." },
    despawn = { kind = "method",   type = "(self) -> ()", doc = "Remove this entity from the scene." },
    component = { kind = "namespace", type = "{ [string]: any }", doc = "Script components attached to this entity." },
}

Why one table

Three things need to agree about what an entityRef has, and they used to be written separately:

ConsumerWhat it takes from here
ref.moduleThe accepted-member set — a member not named here is refused, and the refusal lists these names.
The LSPThe entityRef type, generated from every entry's type.
man / lsp.describeEach member's description and rendered signature.

The --!members entityRef directive publishes the last two. Because all three read this table, a member cannot be documented but unimplemented, or accepted but undescribed.

Declaring a member

kind says what the member IS, which is what a reader needs and what decides how it renders:

  • property — read as a value. Renders entityRef.id -> string.
  • method — called. type is the whole signature, self first. Renders entityRef.rename(self, newName: string) -> ().
  • namespace — carries its own members (component, attribute).

type is a Luau type expression. A type that does not parse degrades to any, which answers every member access and quietly reverses the checking this exists for — so prefer a shape that is true over one that is precise. Several transform members are { [string]: any } because the value really is a live proxy answering .x, [1], and set/get/add.

doc is one sentence, and deprecated names the path that supersedes it.

example is the line a reader copies, published on the member's page under Examples:. A signature says what the call answers with; an example says what to write with the answer, which is what a member answering a shape (an array of identity strings, an array of records) needs beside its type.

Where the members publish

The directive's second token is the doc path the surface is reached at, and every member publishes there as well as under the subject's own name:

DirectiveA member lands at
--!members entityRef entity/proxyentityRef/<member> and entity/proxy/<member>
--!members entityComponents entity/proxy/componententityComponents/<member> and entity/proxy/component/<member>
--!members entityHierarchy globals/entity/hierarchyentityHierarchy/<member> and globals/entity/hierarchy/<member>

The subject is a TYPE name, which is the spelling the checker and lsp.methods use. The root is the spelling a reader who knows the CALL writes. entity(id).component.list() reads at entity/proxy/component/list, which is the page man component.list answers with and the entry /zero/docs/api/entity/ lists. A subject that declares no root publishes under its own name alone.

Adding one

Declare it here and implement it in ref.module. The member is then accepted at runtime, typed by the checker, and documented — from this one edit.