Builtin Library
README.md
substrate_batch
Unifies entity.batchWrite / entity.batchRead so they dispatch over
the typed substrate FFI primitives (ids/binding × values/buffer) by
argument shape. Pure Luau — a thin polymorphic wrapper around the
substrate bridge. The prelude grafts this onto the engine's entity
table at boot via M.installInto(entity). After install, callers use
the grafted methods on the entity global — they shouldn't require
this module directly.
Exports
M.installInto(entity: EntityNamespace)— graft the polymorphicbatchWrite/batchReadonto the supplied namespace. Errors if any of the five required FFI primitives is missing.
Types:
EntityNamespace = { batchWrite, batchWriteBound, batchWriteFromBuffer, batchRead, batchReadToBuffer, [string]: any }— the target namespace shape. The engine'sentityglobal satisfies it once the FFI bindings are installed.
Usage
-- The prelude installs the wrappers at boot:
require("@builtin::modules.substrate_batch").installInto(entity)
-- After install:
-- ids array + values table (per-call resolve):
entity.batchWrite(ids, "Transform", "x", { 1, 2, 3 })
-- binding + values table (bound fast path):
local b = world.bindEntities(ids)
entity.batchWrite(b, "Transform", "x", { 1, 2, 3 })
-- binding + typed buffer (memcpy fast path):
local buf = substrate.createBuffer({ type = "f32", len = #ids })
entity.batchWrite(b, "Transform", "x", buf)
-- read side mirrors the same dispatch shape.
local snapshot = entity.batchRead(ids, "Transform", "x")
entity.batchRead(b, "Transform", "x", buf)
Notes
- The five raw FFI primitives stay reachable under their original names AND under double-underscore aliases (
entity.__batchWriteIds,entity.__batchWriteBound, etc.) for power users / debug code that wants to skip dispatch overhead. The aliases are registered Rust-side, not by this module. - Buffer-source writes and buffer-sink reads require a binding handle — passing a buffer against a raw ids array errors loudly with the migration hint.
- The module owns no state. Reinstalling is idempotent: it just overwrites the two functions on the namespace.