Log inGet started

Field

Updated 5 September 2026

The Field namespace — 42 functions.

globals/Field/alias

Field.alias(target: string | { string }, description: string?) -> FieldDesc<any>

Alias for one or more existing fields. An alias is an ACCEPTED key that is not stored itself — it routes the written value to the real field(s) it points at, so a component answers to a caller's natural key without hand-rolling translation code, and both the runtime and the LSP recognise the key.

The key works everywhere the fields it targets do: as a component.add init key, and as a read and a write on the live component. Reading it returns what the target(s) hold right now.

Two forms:

  • Field.alias("radius") — rename. The value is written verbatim to the single target field (running that field's normal coercion, so an alias onto an assetRef field resolves the ref), and reads back as that field's value.
  • Field.alias({ "colorR", "colorG", "colorB" }) — fan-out. The value is destructured across the targets: an array {a, b, c} positionally, or a named {r=, g=, b=} / {x=, y=, z=} table by the target's position (r/x, g/y, b/z, a/w). It reads back as an array in target order, so c.color = c.color round-trips.

An alias never replicates and is never persisted — the fields it targets own their own Sync/NoSync, so no mode argument is taken.

Parameters

  • target string | { string } — A single target field name, or an array of target field names.
  • description string (optional) — Documents the alias for the LSP; nil to leave it undocumented.

Returns FieldDesc<any> — FieldDesc descriptor with kind = "alias".

type  = Field.alias("kind")
color = Field.alias({ "colorR", "colorG", "colorB" })

globals/Field/assetRef

Field.assetRef(category: C & string, default: AssetRef<C> | I | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<C, I>>

Typed asset reference field. C is the asset category — a singleton string type inferred from the category argument ("material", "mesh", "@user/customCategory", etc.). One constructor handles every category, including user-registered ones.

Default accepts a resolved AssetRef<C> handle, an identity string (full @library::path form OR a bare leaf name resolved category-locally via asset.resolve(identity, category)), or nil.

At registration the engine resolves any string default through the same category-aware resolver public_newindex uses for runtime writes, so the first read of public.<field> already returns a resolved envelope — not a raw string.

Parameters

  • category C & string — Asset category as a string literal ("material", "mesh", etc.). Inferred into C.
  • default AssetRef<C> | I | nil (optional) — AssetRef envelope, identity string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef<C, I>> descriptor.

material = Field.assetRef("material", "@my-library::materials.gold", Sync)
source = Field.assetRef("bundle", nil, Sync)

globals/Field/bitmask

Field.bitmask(bits: number, default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>

Bit-mask number field. bits declares the width the consumer can address; a default or a write that is not a whole number in 0 .. 2^bits - 1 is rejected, naming the width. Use it wherever a numeric field is read as a set of bits rather than as a quantity — what the field reads back is then a mask, so a read-back is evidence the value took.

Parameters

  • bits number — How many bits wide the mask is, 1..53.
  • default number (optional) — Numeric default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor carrying a bitmask constraint.

lightChannels = Field.bitmask(32, 0, Sync)

globals/Field/bool

Field.bool(default: boolean?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<boolean>

Boolean field. nil leaves the field unset.

Parameters

  • default boolean (optional) — Boolean default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

enabled = Field.bool(true, Sync)

globals/Field/color

Field.color(default: color?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<color>

Color field. Default is a color — either {r = .., g = .., b = .., a = ..?} or {r, g, b, a?}.

Parameters

  • default color (optional) — color default for public.<field>.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

tint = Field.color({ 1, 1, 1, 1 }, Sync)

globals/Field/componentRef

Field.componentRef(componentType: T & string, default: ComponentRef<T> | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<ComponentRef<T>>

Typed component reference field. T is the component-type name — a singleton string type inferred from the componentType argument ("Camera", "Transform", "@user/Inventory"). The engine validates the referent exists and is of the declared type at every write.

Parameters

  • componentType T & string — Component type name as a string literal. Inferred into T.
  • default ComponentRef<T> | nil (optional) — ComponentRef envelope or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<ComponentRef> descriptor.

aimCam = Field.componentRef("Camera", nil, NoSync)

globals/Field/dataRef

Field.dataRef(contract: C & string, default: AssetRef<"data"> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<"data">>

Contract-constrained typed-data reference field. Accepts only .data assets whose dataType contract chain includes contract. Rides the assetRef machinery (category "data") — dependency graph, sync, and rehydration behave exactly like Field.assetRef — with the contract gate enforced through the generic field-constraint hook on every write and on the registration-time default.

Parameters

  • contract C & string — The required dataType contract identity. Inferred into C.
  • default AssetRef<"data"> | string | nil (optional) — AssetRef envelope, identity string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef<"data">> descriptor.

weapon = Field.dataRef("weapon", nil, Sync)

globals/Field/entityRef

Field.entityRef(default: EntityRef | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<EntityRef>

Entity reference field. Accepts a live entity proxy (EntityRef), a raw entity-id string, or nil (no target). Writes are normalised to the plain id string for storage/replication; reads return a live EntityRef proxy (or nil), so public.<field>:method() and public.<field>.id work directly without re-resolving.

Parameters

  • default EntityRef | string | nil (optional) — Live entity proxy, entity-id string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

target = Field.entityRef(nil, Sync)

globals/Field/enum

Field.enum(values: { string }, default: string?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<string>

Closed-set string field. values declares every member; a default or a write outside the set is rejected with the whole set named. The editor renders the members as a choice and the LSP completes them.

Parameters

  • values { string } — The members, as an array of non-empty, distinct strings.
  • default string (optional) — The default member, or nil to leave the field unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor carrying an enum constraint.

fit = Field.enum({ "exact", "hull" }, "hull", Sync)

globals/Field/instantiableRef

Field.instantiableRef(default: AssetRef<any> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<any>>

Scene-instantiable asset reference field — accepts ANY asset whose type can be instantiated into a scene, gated by CAPABILITY rather than a hardcoded type list. Rides the assetRef machinery with no category filter (any asset type resolves), and the generic field-constraint hook rejects, on every write and on the registration-time default, any asset whose type defines no instantiate method (ref:canInstantiate() is false). A new scene-instantiable asset type is accepted here the moment it defines the hook — no edit to this field or its consumers. The uniform ref:instantiate(target?, opts?) is how a consumer then instantiates the assigned asset (Asset.component, a viewport drop, a tool argument).

Parameters

  • default AssetRef<any> | string | nil (optional) — AssetRef envelope, identity string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef> descriptor.

source = Field.instantiableRef(nil, Sync)

globals/Field/list

Field.list(element: FieldDesc<any>, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<ListValue>

List field — an array of one repeated element type. The element is the Field constructor descriptor every item conforms to, often a Field.struct for a list of records. The list value is an array of the element's value type. Like Field.struct, the engine descends the element schema to resolve nested asset refs into envelopes, so a stack of structs each holding an asset ref has every ref appear in the asset dependency graph, validates each item, and the LSP type-checks the array. The default value is an empty list. The element declares its own Sync or NoSync for typing; the list's own mode governs replication of the whole array as a unit.

Parameters

  • element FieldDesc<any> — The Field constructor descriptor each item conforms to.
  • mode SyncMode — Sync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<ListValue> — FieldDesc whose value is an array of the element's values.

globals/Field/number

Field.number(default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>

Number field. nil leaves the field unset, so a component can treat an absent value as "derive this from somewhere else" without a second field recording whether the first one was authored.

Parameters

  • default number (optional) — Numeric default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor consumed by component registration.

positionX = Field.number(0, Sync)

globals/Field/quat

Field.quat(default: quat?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<quat>

Quaternion field. Default is a quat — either {x = .., y = .., z = .., w = ..} or {x, y, z, w}.

Parameters

  • default quat (optional) — quat default for public.<field>.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

rotation = Field.quat({ 0, 0, 0, 1 }, Sync)

globals/Field/range

Field.range(min: number?, max: number?, default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>

Bounded number field. min and max declare the interval the value means something in; a default or a write outside it is rejected with the interval named. Either bound may be nil, leaving that side open. The value the field reads back is one the system consuming it can use, and a number that lands outside is reported where it was written.

Parameters

  • min number (optional) — Lowest accepted value, or nil to leave the low side open.
  • max number (optional) — Highest accepted value, or nil to leave the high side open.
  • default number (optional) — Numeric default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor carrying a range constraint.

volume = Field.range(0, 1, 1, Sync)

globals/Field/resource

Field.resource(category: C & string, default: AssetRef<C> | Handle<C> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<C> | Handle<C>>

Category-gated RESOURCE field — accepts EITHER a persistent AssetRef<C> OR a live GPU Handle<C>, gated by category. This is the renderer-facing field type (e.g. Model.model, Model.material, material texture slots): content can author a persistent asset OR pass a runtime handle (renderer.<resource>.create(...)); the component bridges either to the GPU resource. The category gate still holds — an AssetRef<audio> or a wrong-category handle (a TextureHandle on a "mesh" slot) is a type error AND a runtime rejection. Use Field.assetRef instead when the field MUST be a persistent asset (handles rejected). With Sync, persistent-asset values replicate to peers; a live GPU handle value is local by construction and stays local — peers keep the last replicated asset value.

Parameters

  • category C & string — Resource category string literal ("mesh", "texture", "material", ...). Inferred into C.
  • default AssetRef<C> | Handle<C> | string | nil (optional)AssetRef<C> / Handle<C> / identity string / nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef | Handle> descriptor.

model = Field.resource("mesh", nil, Sync)

globals/Field/string

Field.string(default: string?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<string>

String field. nil leaves the field unset.

Parameters

  • default string (optional) — String default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

label = Field.string("hello", Sync)

globals/Field/struct

Field.struct(schema: FieldSchema, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<StructValue>

Struct field — a table whose keys are themselves typed fields. The schema maps each subfield name to its Field constructor descriptor; the struct value is a table holding one value per subfield. Use this instead of Field.table when the table carries asset references or other typed data: the engine descends the schema to resolve nested asset refs into envelopes at registration and at write time, so they appear in the asset dependency graph, validates writes per subfield, and the LSP type-checks the shape. Each subfield declares its own Sync or NoSync for typing; the struct's own mode governs replication of the whole value as a unit.

Parameters

  • schema FieldSchema — Map of subfield name to a Field constructor descriptor.
  • mode SyncMode — Sync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<StructValue> — FieldDesc whose value is a table of the subfields' values.

globals/Field/table

Field.table(default: T, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<T>

Generic table field. T is the table's shape — usually inferred from the default value, or supplied explicitly via an explicit ascription Field.table({} :: MyShape, mode) when the default doesn't cover every key the runtime will write. The engine accepts any Luau table as a value at write time; per-shape enforcement is opt-in static typing only.

Parameters

  • default T — Table value to use as the default for public.<field>.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

idMap = Field.table({} :: { [string]: string }, NoSync)

globals/Field/taggedRef

Field.taggedRef(tag: string, default: AssetRef<any> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<any>>

Tag-constrained asset reference field — accepts any asset carrying tag in its .metadata.tags, whatever its type. This is how a slot states the KIND of asset it takes (a camera behavior, a player visual) without naming the assets themselves: a new asset becomes assignable the moment it is tagged, with no edit here or in the consumer. Rides the assetRef machinery with no category filter — dependency graph, sync and rehydration behave exactly like Field.assetRef — and the generic field-constraint hook rejects an untagged asset on every write and on the registration-time default. asset.list({ fields = { tags = tag } }) enumerates what fits the slot.

Parameters

  • tag string — The tag an assigned asset must carry.
  • default AssetRef<any> | string | nil (optional) — AssetRef envelope, identity string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef> descriptor.

behavior = Field.taggedRef("cameraBehavior", nil, Sync)

globals/Field/vec2

Field.vec2(default: vec2?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<vec2>

Parameters

  • default vec2 (optional)
  • mode SyncMode
  • marker (SerializedMode | string | FieldOptions) (optional)

Returns FieldDesc<vec2>

globals/Field/vec3

Field.vec3(default: vec3?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<vec3>

Vec3 field. Default is a vec3 — either {x = .., y = .., z = ..} or the 3-element array form {x, y, z}.

Parameters

  • default vec3 (optional) — vec3 default for public.<field>.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

offset = Field.vec3({ 0, 0, 0 }, Sync)

typed/builtin//modules/field/Field/alias

Field.alias(target: string | { string }, description: string?) -> FieldDesc<any>

Alias for one or more existing fields. An alias is an ACCEPTED key that is not stored itself — it routes the written value to the real field(s) it points at, so a component answers to a caller's natural key without hand-rolling translation code, and both the runtime and the LSP recognise the key.

The key works everywhere the fields it targets do: as a component.add init key, and as a read and a write on the live component. Reading it returns what the target(s) hold right now.

Two forms:

  • Field.alias("radius") — rename. The value is written verbatim to the single target field (running that field's normal coercion, so an alias onto an assetRef field resolves the ref), and reads back as that field's value.
  • Field.alias({ "colorR", "colorG", "colorB" }) — fan-out. The value is destructured across the targets: an array {a, b, c} positionally, or a named {r=, g=, b=} / {x=, y=, z=} table by the target's position (r/x, g/y, b/z, a/w). It reads back as an array in target order, so c.color = c.color round-trips.

An alias never replicates and is never persisted — the fields it targets own their own Sync/NoSync, so no mode argument is taken.

Parameters

  • target string | { string } — A single target field name, or an array of target field names.
  • description string (optional) — Documents the alias for the LSP; nil to leave it undocumented.

Returns FieldDesc<any> — FieldDesc descriptor with kind = "alias".

type  = Field.alias("kind")
color = Field.alias({ "colorR", "colorG", "colorB" })

typed/builtin//modules/field/Field/assetRef

Field.assetRef(category: C & string, default: AssetRef<C> | I | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<C, I>>

Typed asset reference field. C is the asset category — a singleton string type inferred from the category argument ("material", "mesh", "@user/customCategory", etc.). One constructor handles every category, including user-registered ones.

Default accepts a resolved AssetRef<C> handle, an identity string (full @library::path form OR a bare leaf name resolved category-locally via asset.resolve(identity, category)), or nil.

At registration the engine resolves any string default through the same category-aware resolver public_newindex uses for runtime writes, so the first read of public.<field> already returns a resolved envelope — not a raw string.

Parameters

  • category C & string — Asset category as a string literal ("material", "mesh", etc.). Inferred into C.
  • default AssetRef<C> | I | nil (optional) — AssetRef envelope, identity string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef<C, I>> descriptor.

material = Field.assetRef("material", "@my-library::materials.gold", Sync)
source = Field.assetRef("bundle", nil, Sync)

typed/builtin//modules/field/Field/bitmask

Field.bitmask(bits: number, default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>

Bit-mask number field. bits declares the width the consumer can address; a default or a write that is not a whole number in 0 .. 2^bits - 1 is rejected, naming the width. Use it wherever a numeric field is read as a set of bits rather than as a quantity — what the field reads back is then a mask, so a read-back is evidence the value took.

Parameters

  • bits number — How many bits wide the mask is, 1..53.
  • default number (optional) — Numeric default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor carrying a bitmask constraint.

lightChannels = Field.bitmask(32, 0, Sync)

typed/builtin//modules/field/Field/bool

Field.bool(default: boolean?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<boolean>

Boolean field. nil leaves the field unset.

Parameters

  • default boolean (optional) — Boolean default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

enabled = Field.bool(true, Sync)

typed/builtin//modules/field/Field/color

Field.color(default: color?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<color>

Color field. Default is a color — either {r = .., g = .., b = .., a = ..?} or {r, g, b, a?}.

Parameters

  • default color (optional) — color default for public.<field>.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

tint = Field.color({ 1, 1, 1, 1 }, Sync)

typed/builtin//modules/field/Field/componentRef

Field.componentRef(componentType: T & string, default: ComponentRef<T> | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<ComponentRef<T>>

Typed component reference field. T is the component-type name — a singleton string type inferred from the componentType argument ("Camera", "Transform", "@user/Inventory"). The engine validates the referent exists and is of the declared type at every write.

Parameters

  • componentType T & string — Component type name as a string literal. Inferred into T.
  • default ComponentRef<T> | nil (optional) — ComponentRef envelope or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<ComponentRef> descriptor.

aimCam = Field.componentRef("Camera", nil, NoSync)

typed/builtin//modules/field/Field/dataRef

Field.dataRef(contract: C & string, default: AssetRef<"data"> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<"data">>

Contract-constrained typed-data reference field. Accepts only .data assets whose dataType contract chain includes contract. Rides the assetRef machinery (category "data") — dependency graph, sync, and rehydration behave exactly like Field.assetRef — with the contract gate enforced through the generic field-constraint hook on every write and on the registration-time default.

Parameters

  • contract C & string — The required dataType contract identity. Inferred into C.
  • default AssetRef<"data"> | string | nil (optional) — AssetRef envelope, identity string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef<"data">> descriptor.

weapon = Field.dataRef("weapon", nil, Sync)

typed/builtin//modules/field/Field/entityRef

Field.entityRef(default: EntityRef | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<EntityRef>

Entity reference field. Accepts a live entity proxy (EntityRef), a raw entity-id string, or nil (no target). Writes are normalised to the plain id string for storage/replication; reads return a live EntityRef proxy (or nil), so public.<field>:method() and public.<field>.id work directly without re-resolving.

Parameters

  • default EntityRef | string | nil (optional) — Live entity proxy, entity-id string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

target = Field.entityRef(nil, Sync)

typed/builtin//modules/field/Field/enum

Field.enum(values: { string }, default: string?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<string>

Closed-set string field. values declares every member; a default or a write outside the set is rejected with the whole set named. The editor renders the members as a choice and the LSP completes them.

Parameters

  • values { string } — The members, as an array of non-empty, distinct strings.
  • default string (optional) — The default member, or nil to leave the field unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor carrying an enum constraint.

fit = Field.enum({ "exact", "hull" }, "hull", Sync)

typed/builtin//modules/field/Field/instantiableRef

Field.instantiableRef(default: AssetRef<any> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<any>>

Scene-instantiable asset reference field — accepts ANY asset whose type can be instantiated into a scene, gated by CAPABILITY rather than a hardcoded type list. Rides the assetRef machinery with no category filter (any asset type resolves), and the generic field-constraint hook rejects, on every write and on the registration-time default, any asset whose type defines no instantiate method (ref:canInstantiate() is false). A new scene-instantiable asset type is accepted here the moment it defines the hook — no edit to this field or its consumers. The uniform ref:instantiate(target?, opts?) is how a consumer then instantiates the assigned asset (Asset.component, a viewport drop, a tool argument).

Parameters

  • default AssetRef<any> | string | nil (optional) — AssetRef envelope, identity string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef> descriptor.

source = Field.instantiableRef(nil, Sync)

typed/builtin//modules/field/Field/list

Field.list(element: FieldDesc<any>, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<ListValue>

List field — an array of one repeated element type. The element is the Field constructor descriptor every item conforms to, often a Field.struct for a list of records. The list value is an array of the element's value type. Like Field.struct, the engine descends the element schema to resolve nested asset refs into envelopes, so a stack of structs each holding an asset ref has every ref appear in the asset dependency graph, validates each item, and the LSP type-checks the array. The default value is an empty list. The element declares its own Sync or NoSync for typing; the list's own mode governs replication of the whole array as a unit.

typed/builtin//modules/field/Field/number

Field.number(default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>

Number field. nil leaves the field unset, so a component can treat an absent value as "derive this from somewhere else" without a second field recording whether the first one was authored.

Parameters

  • default number (optional) — Numeric default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor consumed by component registration.

positionX = Field.number(0, Sync)

typed/builtin//modules/field/Field/quat

Field.quat(default: quat?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<quat>

Quaternion field. Default is a quat — either {x = .., y = .., z = .., w = ..} or {x, y, z, w}.

Parameters

  • default quat (optional) — quat default for public.<field>.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

rotation = Field.quat({ 0, 0, 0, 1 }, Sync)

typed/builtin//modules/field/Field/range

Field.range(min: number?, max: number?, default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>

Bounded number field. min and max declare the interval the value means something in; a default or a write outside it is rejected with the interval named. Either bound may be nil, leaving that side open. The value the field reads back is one the system consuming it can use, and a number that lands outside is reported where it was written.

Parameters

  • min number (optional) — Lowest accepted value, or nil to leave the low side open.
  • max number (optional) — Highest accepted value, or nil to leave the high side open.
  • default number (optional) — Numeric default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor carrying a range constraint.

volume = Field.range(0, 1, 1, Sync)

typed/builtin//modules/field/Field/resource

Field.resource(category: C & string, default: AssetRef<C> | Handle<C> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<C> | Handle<C>>

Category-gated RESOURCE field — accepts EITHER a persistent AssetRef<C> OR a live GPU Handle<C>, gated by category. This is the renderer-facing field type (e.g. Model.model, Model.material, material texture slots): content can author a persistent asset OR pass a runtime handle (renderer.<resource>.create(...)); the component bridges either to the GPU resource. The category gate still holds — an AssetRef<audio> or a wrong-category handle (a TextureHandle on a "mesh" slot) is a type error AND a runtime rejection. Use Field.assetRef instead when the field MUST be a persistent asset (handles rejected). With Sync, persistent-asset values replicate to peers; a live GPU handle value is local by construction and stays local — peers keep the last replicated asset value.

Parameters

  • category C & string — Resource category string literal ("mesh", "texture", "material", ...). Inferred into C.
  • default AssetRef<C> | Handle<C> | string | nil (optional)AssetRef<C> / Handle<C> / identity string / nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef | Handle> descriptor.

model = Field.resource("mesh", nil, Sync)

typed/builtin//modules/field/Field/string

Field.string(default: string?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<string>

String field. nil leaves the field unset.

Parameters

  • default string (optional) — String default for public.<field>, or nil to leave it unset.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

label = Field.string("hello", Sync)

typed/builtin//modules/field/Field/struct

Field.struct(schema: FieldSchema, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<StructValue>

Struct field — a table whose keys are themselves typed fields. The schema maps each subfield name to its Field constructor descriptor; the struct value is a table holding one value per subfield. Use this instead of Field.table when the table carries asset references or other typed data: the engine descends the schema to resolve nested asset refs into envelopes at registration and at write time, so they appear in the asset dependency graph, validates writes per subfield, and the LSP type-checks the shape. Each subfield declares its own Sync or NoSync for typing; the struct's own mode governs replication of the whole value as a unit.

Parameters

  • schema FieldSchema — Map of subfield name to a Field constructor descriptor.
  • mode SyncMode — Sync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<StructValue> — FieldDesc whose value is a table of the subfields' values.

typed/builtin//modules/field/Field/table

Field.table(default: T, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<T>

Generic table field. T is the table's shape — usually inferred from the default value, or supplied explicitly via an explicit ascription Field.table({} :: MyShape, mode) when the default doesn't cover every key the runtime will write. The engine accepts any Luau table as a value at write time; per-shape enforcement is opt-in static typing only.

Parameters

  • default T — Table value to use as the default for public.<field>.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

idMap = Field.table({} :: { [string]: string }, NoSync)

typed/builtin//modules/field/Field/taggedRef

Field.taggedRef(tag: string, default: AssetRef<any> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<any>>

Tag-constrained asset reference field — accepts any asset carrying tag in its .metadata.tags, whatever its type. This is how a slot states the KIND of asset it takes (a camera behavior, a player visual) without naming the assets themselves: a new asset becomes assignable the moment it is tagged, with no edit here or in the consumer. Rides the assetRef machinery with no category filter — dependency graph, sync and rehydration behave exactly like Field.assetRef — and the generic field-constraint hook rejects an untagged asset on every write and on the registration-time default. asset.list({ fields = { tags = tag } }) enumerates what fits the slot.

Parameters

  • tag string — The tag an assigned asset must carry.
  • default AssetRef<any> | string | nil (optional) — AssetRef envelope, identity string, or nil.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc<AssetRef> descriptor.

behavior = Field.taggedRef("cameraBehavior", nil, Sync)

typed/builtin//modules/field/Field/vec2

Field.vec2(default: vec2?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<vec2>

Parameters

  • default vec2 (optional)
  • mode SyncMode
  • marker (SerializedMode | string | FieldOptions) (optional)

Returns FieldDesc<vec2>

typed/builtin//modules/field/Field/vec3

Field.vec3(default: vec3?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<vec3>

Vec3 field. Default is a vec3 — either {x = .., y = .., z = ..} or the 3-element array form {x, y, z}.

Parameters

  • default vec3 (optional) — vec3 default for public.<field>.
  • mode SyncModeSync or NoSync — required.
  • marker (SerializedMode | string | FieldOptions) (optional)Serialized, a description string, or a { serialized, description } options table; omit for neither.

Returns FieldDesc descriptor.

offset = Field.vec3({ 0, 0, 0 }, Sync)
  • api
  • reference