Log inGet started

values

Updated October 26, 2026

Named values an entity holds: typed numbers, vectors and booleans (throttle, rpm, gear, headlights, doorOpen) that scripts and engine systems write and read cheaply, and that materials, audio voices, the UI and replication follow without a script copying them every frame. A value stays on this engine unless it is declared to replicate, at a rate in Hz.

require("@builtin::modules.api.engine.values") -- values (also available as global 'values')

The values namespace: 47 functions.

entity/proxy/values/clear

entity(id).values.clear() -> number

Drop every named value this entity holds; answers how many it held.

Returns number

entity/proxy/values/declare

entity(id).values.declare(name: string, declaration: { type: string?, default: (number | vector | boolean)?, replicate: number? }?) -> ()

State a named value's type, the default it starts at, and the rate in Hz it replicates at; a value with no replicate rate stays on this engine.

Parameters

  • name string
  • declaration { type: string?, default: (number | vector | boolean)?, replicate: number? } (optional)

Returns ()

car.values.declare("throttle", { type = "number", replicate = 10 })

entity/proxy/values/describe

entity(id).values.describe() -> { { name: string, type: string, value: number | vector | boolean, writer: string, revision: number, replicate: number?, declared: boolean } }

Every named value this entity holds with its type, last writer, revision and replication rate, sorted by name.

Returns { { name: string, type: string, value: number | vector | boolean, writer: string, revision: number, replicate: number?, declared: boolean } }

entity/proxy/values/get

entity(id).values.get(name: string) -> (number | vector | boolean)?

The named value this entity holds, or nil.

Parameters

  • name string

Returns (number | vector | boolean)?

local rpm = car.values.get("rpm") or 0

entity/proxy/values/list

entity(id).values.list() -> { [string]: number | vector | boolean }

Every named value this entity holds, by name.

Returns { [string]: number | vector | boolean }

entity/proxy/values/remove

entity(id).values.remove(name: string) -> boolean

Drop a named value; answers whether this entity held it.

Parameters

  • name string

Returns boolean

entity/proxy/values/set

entity(id).values.set(name: string, value: (number | vector | boolean)?) -> ()

Write a named value: a number, a vector or a boolean; nil removes it. A name keeps the kind of its first value. Nothing is replicated unless the name is declared to replicate.

Parameters

  • name string
  • value (number | vector | boolean) (optional)

Returns ()

car.values.set("rpm", 3200)

entity/proxy/values/subscribe

entity(id).values.subscribe(name: string?, callback: ((number | vector | boolean)?, string, string) -> ()) -> { Connected: boolean, Disconnect: (any) -> () }

Call callback(value, name, entityId) once per frame in which a named value changed, whoever changed it; nil name follows every value of this entity.

Parameters

  • name string (optional)
  • callback ((number | vector | boolean)?, string, string) -> ()

Returns { Connected: boolean, Disconnect: (any) -> () }

car.values.subscribe("gear", function(gear) print(gear) end)

globals/values/bind

values.bind(target: string | entityRef, name: string, opts: { format: string?, scale: number?, offset: number?, fallback: any? }?) -> ValueBinding

A UI prop that follows a named value, with no script updating the screen: put it where a widget takes text, value, visible, checked or enabled, and the widget reads the value every frame. format is a string.format pattern for text ("%d rpm"; the value as it reads when absent); scale and offset map a number (value * scale + offset) before it is shown. A value the entity does not hold shows fallback (empty text, 0 or false when absent).

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
  • opts { format: string?, scale: number?, offset: number?, fallback: any? } (optional) — { format?, scale?, offset?, fallback? }.

Returns ValueBinding — A binding to place in a widget's props.

ui.registerScreen("dash", { type = "vertical", children = {
{ type = "label", props = { text = values.bind(car, "rpm", { format = "%.0f rpm" }) } },
{ type = "slider", props = { min = 0, max = 1, value = values.bind(car, "throttle") } },
} })

globals/values/clear

values.clear(target: string | entityRef) -> number

Drop every named value an entity holds. An entity's values also go when the entity leaves the world.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.

Returns number — How many values it held.

values.clear(car)

globals/values/declare

values.declare(target: string | entityRef, name: string, declaration: ValueDeclaration?)

State what a named value is: its type ("number", "vector" or "boolean"), the default it starts at, and whether it replicates. A name the entity already holds keeps its value. replicate is a rate in Hz (up to 60): the owner of the entity sends the value to every other peer at most that often while it changes, and always sends the latest one, and the other peers read it like any value. A value with no replicate is never sent anywhere.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
  • declaration ValueDeclaration (optional) — { type?, default?, replicate? }; give type or default for a name the entity does not hold yet.
values.declare(car, "throttle", { type = "number", default = 0, replicate = 10 })
values.declare(car, "brake", { default = false, replicate = 20 })

globals/values/describe

values.describe(target: string | entityRef) -> { ValueRow }

Every named value an entity holds, sorted by name, each with its type, its value, who wrote it last (writer: "script", "engine" or "remote"), the store revision of its last change, its replicate rate (absent for a value kept on this engine) and whether a declaration states it. The same rows /zero/runtime/values/<entityId> and the values toolbox list.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.

Returns { ValueRow } — The rows.

for _, row in values.describe(car) do print(row.name, row.type, row.value, row.writer) end

globals/values/entities

values.entities() -> { string }

Every entity holding at least one named value, sorted by id.

Returns { string } — Entity ids.

for _, id in values.entities() do print(id, #values.describe(id)) end

globals/values/get

values.get(target: string | entityRef, name: string) -> Value?

Read a named value an entity holds, or nil when it holds none under that name. Engine systems write values too: a WheelCollider writes its own state (wheel.slipRatio, wheel.angularVelocity, ...), so a script reads it here the way it reads a value a script wrote.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.

Returns Value? — The value, or nil.

local rpm = values.get(car, "rpm") or 0

globals/values/list

values.list(target: string | entityRef) -> { [string]: Value }

Every named value an entity holds, by name.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.

Returns { [string]: Value } — { [name] = value }.

for name, v in values.list(car) do print(name, v) end

globals/values/onAnyChange

values.onAnyChange(callback: (Value?, string, string) -> ()) -> ValueConnection

Call callback(value, name, entityId) for every change of every named value on every entity, once per frame in which it changed: what a debug view or a recorder of a session's values follows.

Parameters

  • callback (Value?, string, string) -> () — function(value, name, entityId).

Returns ValueConnection — A connection; :Disconnect() ends it.

local conn = values.onAnyChange(function(v, name, id) print(id, name, v) end)

globals/values/remove

values.remove(target: string | entityRef, name: string) -> boolean

Drop a named value from an entity.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.

Returns boolean — Whether the entity held it.

values.remove(car, "rpm")

globals/values/set

values.set(target: string | entityRef, name: string, value: Value?)

Write a named value on an entity: a number, a vector or a boolean; nil removes it. A name takes the kind of its first value and keeps it: writing another kind raises (remove the value first to change its kind). The write is a store, with nothing replicated and nothing copied, and every reader sees it from the next read: values.get, a material property bound to the name, an Audio voice following it, a UI prop values.bind made. Only a value values.declare gives a replicate rate is ever sent to other peers.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
  • value Value (optional) — A number, a vector or a boolean; nil removes the value.
values.set(car, "rpm", 3200)
values.set(car, "headlights", true)
values.set(car, "wheelSpin", vector.create(0, 12.5, 0))

globals/values/stats

values.stats() -> { entities: number, values: number, revision: number, replication: ValueReplicationStats }

How many entities hold values, how many values there are, the store's revision (which advances on every change), and what replication has carried: a value with no replicate rate adds nothing to it.

Returns { entities: number, values: number, revision: number, replication: ValueReplicationStats } — { entities, values, revision, replication }.

print(values.stats().values, values.stats().replication.sentBytes)

globals/values/subscribe

values.subscribe(target: string | entityRef, name: string?, callback: (Value?, string, string) -> ()) -> ValueConnection

Call callback(value, name, entityId) when a named value of an entity changes, whoever changed it: a script, an engine system or another peer. Give name to follow one value, or nil to follow every value of the entity. The callback runs once for the writes a frame made, on the engine's next pass over its tasks, with the value as it stands then: three writes in one frame are one call with the last of them. A value that went (values.remove, its entity left the world) arrives as nil. A subscription made by a component ends with the component.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string (optional) — The value's name, or nil for every value of the entity.
  • callback (Value?, string, string) -> () — function(value, name, entityId).

Returns ValueConnection — A connection; :Disconnect() ends it.

local conn = values.subscribe(car, "gear", function(gear) print("now in gear", gear) end)
conn:Disconnect()

modules/values/bind

bind(

A UI prop that follows a named value, with no script updating the screen: put it where a widget takes text, value, visible, checked or enabled, and the widget reads the value every frame. format is a string.format pattern for text ("%d rpm"; the value as it reads when absent); scale and offset map a number (value * scale + offset) before it is shown. A value the entity does not hold shows fallback (empty text, 0 or false when absent).

ui.registerScreen("dash", { type = "vertical", children = {
{ type = "label", props = { text = values.bind(car, "rpm", { format = "%.0f rpm" }) } },
{ type = "slider", props = { min = 0, max = 1, value = values.bind(car, "throttle") } },
} })

modules/values/clear

clear(target: string | entityRef): number

Drop every named value an entity holds. An entity's values also go when the entity leaves the world.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
values.clear(car)

modules/values/declare

declare(target: string | entityRef, name: string, declaration: ValueDeclaration?)

State what a named value is: its type ("number", "vector" or "boolean"), the default it starts at, and whether it replicates. A name the entity already holds keeps its value. replicate is a rate in Hz (up to 60): the owner of the entity sends the value to every other peer at most that often while it changes, and always sends the latest one, and the other peers read it like any value. A value with no replicate is never sent anywhere.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
  • declaration ValueDeclaration? (optional) — { type?, default?, replicate? }; give type or default for a name the entity does not hold yet.
values.declare(car, "throttle", { type = "number", default = 0, replicate = 10 })
values.declare(car, "brake", { default = false, replicate = 20 })

modules/values/describe

describe(target: string | entityRef): { ValueRow }

Every named value an entity holds, sorted by name, each with its type, its value, who wrote it last (writer: "script", "engine" or "remote"), the store revision of its last change, its replicate rate (absent for a value kept on this engine) and whether a declaration states it. The same rows /zero/runtime/values/<entityId> and the values toolbox list.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
for _, row in values.describe(car) do print(row.name, row.type, row.value, row.writer) end

modules/values/entities

entities(): { string }

Every entity holding at least one named value, sorted by id.

for _, id in values.entities() do print(id, #values.describe(id)) end

modules/values/get

get(target: string | entityRef, name: string): Value?

Read a named value an entity holds, or nil when it holds none under that name. Engine systems write values too: a WheelCollider writes its own state (wheel.slipRatio, wheel.angularVelocity, ...), so a script reads it here the way it reads a value a script wrote.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
local rpm = values.get(car, "rpm") or 0

modules/values/list

list(target: string | entityRef): { [string]: Value }

Every named value an entity holds, by name.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
for name, v in values.list(car) do print(name, v) end

modules/values/onAnyChange

onAnyChange(callback: (Value?, string, string) -> ()): ValueConnection

Call callback(value, name, entityId) for every change of every named value on every entity, once per frame in which it changed: what a debug view or a recorder of a session's values follows.

Parameters

  • callback (Value?, string, string) -> () — function(value, name, entityId).
local conn = values.onAnyChange(function(v, name, id) print(id, name, v) end)

modules/values/remove

remove(target: string | entityRef, name: string): boolean

Drop a named value from an entity.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
values.remove(car, "rpm")

modules/values/set

set(target: string | entityRef, name: string, value: Value?)

Write a named value on an entity: a number, a vector or a boolean; nil removes it. A name takes the kind of its first value and keeps it: writing another kind raises (remove the value first to change its kind). The write is a store, with nothing replicated and nothing copied, and every reader sees it from the next read: values.get, a material property bound to the name, an Audio voice following it, a UI prop values.bind made. Only a value values.declare gives a replicate rate is ever sent to other peers.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
  • value Value? (optional) — A number, a vector or a boolean; nil removes the value.
values.set(car, "rpm", 3200)
values.set(car, "headlights", true)
values.set(car, "wheelSpin", vector.create(0, 12.5, 0))

modules/values/stats

stats(): { entities: number, values: number, revision: number, replication: ValueReplicationStats }

How many entities hold values, how many values there are, the store's revision (which advances on every change), and what replication has carried: a value with no replicate rate adds nothing to it.

print(values.stats().values, values.stats().replication.sentBytes)

modules/values/subscribe

subscribe(

Call callback(value, name, entityId) when a named value of an entity changes, whoever changed it: a script, an engine system or another peer. Give name to follow one value, or nil to follow every value of the entity. The callback runs once for the writes a frame made, on the engine's next pass over its tasks, with the value as it stands then: three writes in one frame are one call with the last of them. A value that went (values.remove, its entity left the world) arrives as nil. A subscription made by a component ends with the component.

local conn = values.subscribe(car, "gear", function(gear) print("now in gear", gear) end)
conn:Disconnect()

tools/values/describe

values.describe(target: string) -> ValueDescription

One entity's named values as they stand now, sorted by name: each with its type, value (a vector as [x, y, z]), last writer ("script", "engine" or "remote"), the store revision of its last change, its replication rate when it replicates, and whether a declaration states it.

Parameters

  • target string

Returns ValueDescription

"car"

tools/values/list

values.list() -> ValueListing

Every entity holding at least one named value, sorted by id, each with its name and how many values it holds; and the total values and the store's revision, which advances on every change.

Returns ValueListing

tools/values/set

values.set(target: string, name: string, value: any) -> SetResult

Write one named value on an entity: a number, a boolean, or a list of three numbers for a vector; nil removes it. Answers the value the entity holds after the write, a vector as [x, y, z].

Parameters

  • target string
  • name string
  • value any (optional)

Returns SetResult

"car", "brake", true

typed/builtin//modules/api/engine/values/values/bind

values.bind(target: string | entityRef, name: string, opts: { format: string?, scale: number?, offset: number?, fallback: any? }?) -> ValueBinding

A UI prop that follows a named value, with no script updating the screen: put it where a widget takes text, value, visible, checked or enabled, and the widget reads the value every frame. format is a string.format pattern for text ("%d rpm"; the value as it reads when absent); scale and offset map a number (value * scale + offset) before it is shown. A value the entity does not hold shows fallback (empty text, 0 or false when absent).

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
  • opts { format: string?, scale: number?, offset: number?, fallback: any? } (optional) — { format?, scale?, offset?, fallback? }.

Returns ValueBinding — A binding to place in a widget's props.

ui.registerScreen("dash", { type = "vertical", children = {
{ type = "label", props = { text = values.bind(car, "rpm", { format = "%.0f rpm" }) } },
{ type = "slider", props = { min = 0, max = 1, value = values.bind(car, "throttle") } },
} })

typed/builtin//modules/api/engine/values/values/clear

values.clear(target: string | entityRef) -> number

Drop every named value an entity holds. An entity's values also go when the entity leaves the world.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.

Returns number — How many values it held.

values.clear(car)

typed/builtin//modules/api/engine/values/values/declare

values.declare(target: string | entityRef, name: string, declaration: ValueDeclaration?)

State what a named value is: its type ("number", "vector" or "boolean"), the default it starts at, and whether it replicates. A name the entity already holds keeps its value. replicate is a rate in Hz (up to 60): the owner of the entity sends the value to every other peer at most that often while it changes, and always sends the latest one, and the other peers read it like any value. A value with no replicate is never sent anywhere.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
  • declaration ValueDeclaration (optional) — { type?, default?, replicate? }; give type or default for a name the entity does not hold yet.
values.declare(car, "throttle", { type = "number", default = 0, replicate = 10 })
values.declare(car, "brake", { default = false, replicate = 20 })

typed/builtin//modules/api/engine/values/values/describe

values.describe(target: string | entityRef) -> { ValueRow }

Every named value an entity holds, sorted by name, each with its type, its value, who wrote it last (writer: "script", "engine" or "remote"), the store revision of its last change, its replicate rate (absent for a value kept on this engine) and whether a declaration states it. The same rows /zero/runtime/values/<entityId> and the values toolbox list.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.

Returns { ValueRow } — The rows.

for _, row in values.describe(car) do print(row.name, row.type, row.value, row.writer) end

typed/builtin//modules/api/engine/values/values/entities

values.entities() -> { string }

Every entity holding at least one named value, sorted by id.

Returns { string } — Entity ids.

for _, id in values.entities() do print(id, #values.describe(id)) end

typed/builtin//modules/api/engine/values/values/get

values.get(target: string | entityRef, name: string) -> Value?

Read a named value an entity holds, or nil when it holds none under that name. Engine systems write values too: a WheelCollider writes its own state (wheel.slipRatio, wheel.angularVelocity, ...), so a script reads it here the way it reads a value a script wrote.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.

Returns Value? — The value, or nil.

local rpm = values.get(car, "rpm") or 0

typed/builtin//modules/api/engine/values/values/list

values.list(target: string | entityRef) -> { [string]: Value }

Every named value an entity holds, by name.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.

Returns { [string]: Value } — { [name] = value }.

for name, v in values.list(car) do print(name, v) end

typed/builtin//modules/api/engine/values/values/onAnyChange

values.onAnyChange(callback: (Value?, string, string) -> ()) -> ValueConnection

Call callback(value, name, entityId) for every change of every named value on every entity, once per frame in which it changed: what a debug view or a recorder of a session's values follows.

Parameters

  • callback (Value?, string, string) -> () — function(value, name, entityId).

Returns ValueConnection — A connection; :Disconnect() ends it.

local conn = values.onAnyChange(function(v, name, id) print(id, name, v) end)

typed/builtin//modules/api/engine/values/values/remove

values.remove(target: string | entityRef, name: string) -> boolean

Drop a named value from an entity.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.

Returns boolean — Whether the entity held it.

values.remove(car, "rpm")

typed/builtin//modules/api/engine/values/values/set

values.set(target: string | entityRef, name: string, value: Value?)

Write a named value on an entity: a number, a vector or a boolean; nil removes it. A name takes the kind of its first value and keeps it: writing another kind raises (remove the value first to change its kind). The write is a store, with nothing replicated and nothing copied, and every reader sees it from the next read: values.get, a material property bound to the name, an Audio voice following it, a UI prop values.bind made. Only a value values.declare gives a replicate rate is ever sent to other peers.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string — The value's name.
  • value Value (optional) — A number, a vector or a boolean; nil removes the value.
values.set(car, "rpm", 3200)
values.set(car, "headlights", true)
values.set(car, "wheelSpin", vector.create(0, 12.5, 0))

typed/builtin//modules/api/engine/values/values/stats

values.stats() -> { entities: number, values: number, revision: number, replication: ValueReplicationStats }

How many entities hold values, how many values there are, the store's revision (which advances on every change), and what replication has carried: a value with no replicate rate adds nothing to it.

Returns { entities: number, values: number, revision: number, replication: ValueReplicationStats } — { entities, values, revision, replication }.

print(values.stats().values, values.stats().replication.sentBytes)

typed/builtin//modules/api/engine/values/values/subscribe

values.subscribe(target: string | entityRef, name: string?, callback: (Value?, string, string) -> ()) -> ValueConnection

Call callback(value, name, entityId) when a named value of an entity changes, whoever changed it: a script, an engine system or another peer. Give name to follow one value, or nil to follow every value of the entity. The callback runs once for the writes a frame made, on the engine's next pass over its tasks, with the value as it stands then: three writes in one frame are one call with the last of them. A value that went (values.remove, its entity left the world) arrives as nil. A subscription made by a component ends with the component.

Parameters

  • target string | entityRef — The entity: a proxy from entity(...), or its id.
  • name string (optional) — The value's name, or nil for every value of the entity.
  • callback (Value?, string, string) -> () — function(value, name, entityId).

Returns ValueConnection — A connection; :Disconnect() ends it.

local conn = values.subscribe(car, "gear", function(gear) print("now in gear", gear) end)
conn:Disconnect()
  • api
  • reference