Builtin Library
README.md
assetType runtime
The machinery that reads a <typename>.assetType/behavior.luau and turns its
declarations into live behaviour.
A behavior.luau is a table of declarations — ref methods, modules shared
code, an events schema, a namePattern, refShapes, and the onCreate /
onRegister / onChange / onDelete / validate / settingsDefaults /
settingsCorrections hooks. None of it runs itself. This is the code that
runs it, and it lives here because reading a type's declarations is the
assetType type's own behaviour — the same way material.assetType owns
what a .material does.
Sub-modules
| Module | Reads | Responsibility |
|---|---|---|
ref.module | ref, modules | Builds every AssetRef envelope, attaches the shared metatable, and dispatches per-type methods and shared modules onto it. Also owns edit-mode write-behind persistence. |
create.module | onCreate, namePattern, validate | Backs asset.create: resolves the type, checks the name against its pattern, runs onCreate (or clones template/), and writes the instance. validate.module beside it checks a creation opts table against the type's createSchema. Before running onCreate, resolves the type's settings chain (below) and hands the result to the hook as opts.settings. |
settings.module | settings, settingsDefaults, settingsCorrections | A type's declared settings schema and where its values live (type.yaml's settings: block). Settings.resolveForCreate layers the schema's own defaults, the type's own settingsDefaults(name, opts, asked) hook (a DEFAULT the schema can't express — a name-derived convention, a fact read off a payload the caller handed it, a value following a field asked shows a higher layer naming; any later layer overrides it), the Preset Manager, an importer's settings, the caller's settings table, then the type's own settingsCorrections(values, name, opts) hook (a CROSS-FIELD CONSTRAINT the schema can't express, applied last over the fully merged values). A correction over a default/preset/importer value lands silently; a correction that would override what the caller's own settings table explicitly asked for refuses the creation instead, naming the field and why. Neither hook is ever handed a table to mutate; each returns what it wants changed (settingsCorrections may also return a { [field]: reason } table for that refusal message). Settings.cloneValues deep-copies a values table — create.module hands onCreate a copy, never the table it stamps. Settings.valuesOf / writeValues read and write an asset's own values file. |
typeYaml.module | type.yaml | The folder a type lives in and its parsed type.yaml, decoded once per content version of the file. settings.module and inspector.module read their blocks through it. about / aboutAt read a type's about.yaml (intent, function, usage), leaving out any key that is empty or still starts with [[describe]]; aboutRows and aboutMarkdown lay the texts out for the Inspector and the types/<name> guide. |
inspector.module | type.yaml's inspector: block | Which inspector a type declares for its assets (inspector: { type: ... } or { instance: ... }), and the declaration that file returns — the sections it adds, the generic ones it replaces, and their order — or the problem that kept it from loading. |
onRegister.module | onRegister | Fires an instance's once-only registration hook — on arrival, on world load, and for @builtin library instances. |
changeDispatch.module | onChange, onDelete, refShapes | Routes a VFS source write or a folder delete to the enclosing typed asset's type hooks. |
refShapes.module | refShapes, ref | Publishes what every AssetRef<category> answers to, so a member read on an asset-typed value is checked against that category's real surface. |
events.module | events | The per-asset event runtime behind ref.events. |
instantiable.module | ref.instantiate | The instantiation contract an asset type opts into: root stands the root entity, place applies the base placement opts to one the type adopted, and result shapes the (root, idMap) every instantiate returns. Also registers the sceneInstantiable field-constraint validator. |
declaration.module | type.yaml | The type's decoded declaration, read once and held until a write inside an .assetType folder; what every question about a type as a whole reads. |
previewRecipe.module | type.yaml preview: | How an instance's preview.png is produced: which of the four recipes (instantiate, image, surface, custom) the type declares, and what that recipe needs. |
Reaching it
local rt = require("@builtin::assetTypes.assetType.shared")
rt.ref.loadTypeBehavior("material")
Fields resolve lazily. The prelude requires the sub-modules directly, in
dependency order (ref, then changeDispatch, onRegister.install(),
refShapes.install()) — a table that required all six on load would take that
ordering away from it.