Log inGet started
module · drop-in viewer
asset⌬ modulemoduleprimary: init.luau·part ofmodule shared.module·originates fromworld 07158574-5…

onRegister

Drives the optional `onRegister(self)` assetType lifecycle hook — the surface that lets an asset instance run code exactly once when it first registers, operating on the per-instance ref (`self`). This is what makes "write an asset into the world → it takes effect live, no restar…

byzero-proxy @ DESKTOP-DB3UJOJ·posted 2mo ago
What it does

asset_on_register

Drives the optional onRegister(self) assetType lifecycle hook — the surface that lets an asset instance run code exactly once when it first registers, operating on the per-instance ref (self). This is what makes "write an asset into the world → it takes effect live, no restart" work for content that registers into a runtime registry (editor panels, and anything else that opts in).

A type opts in by exporting onRegister from its behavior.luau. The hook fires exactly once per instance:

  • On engine.onWorldLoaded — a batched sweep over every world instance of every type that implements onRegister, yielding every 32 instances so a large instance count never stalls a frame. The @builtin library (/zero/source/libs/) is excluded.
  • On live asset.create — the create path calls M.fireFor(ref) on the freshly-created instance.

A per-VM once-guard keyed by the instance's VFS path ensures the two triggers can't double-register the same instance.

Exports

  • M.fireFor(ref, onRegisterFn?) -> boolean — fire one instance's onRegister(self) hook exactly once. Resolves the type's hook from ref.type when onRegisterFn isn't supplied. Idempotent: a second call on the same instance is a no-op. Returns true if the hook fired this call.
  • M.sweep() — batched sweep: fire onRegister once for every world instance of every registered type that implements it. Yields, so it must run inside a task. Safe to call repeatedly.
  • M.install() — install the world-loaded sweep. Idempotent. Runs the sweep on a system task so it ticks through pause and never blocks the caller.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

AssetOnRegister Module Drives the optional `onRegister(self)` assetType lifecycle hook — the surface that lets an asset INSTANCE run code exactly once when it first registers, operating on the per-instance ref (`self`), not the type definition. This is what makes "write an asset into the world → it takes effect live, no restart" work for content that registers into a runtime registry (editor panels, and anything else that opts in). A type opts in by exporting `onRegister` from its `behavior.luau`: -- @builtin::assetTypes.editorPanel.assetType/behavior.luau local M = {} function M.onRegister(self) local editor = require("@builtin::modules.api.editor.registry") local spec = self:loadPanelSpec() -- read this instance's definition editor.addPanel(spec) end return M WHEN it fires (exactly once per instance, guarded by the interned ref's shared `runtime` table so a double trigger never double-registers): * On `engine.onWorldLoaded` — a BATCHED sweep of every world instance of every type that implements onRegister. Tied to world-loaded (not earlier) so an instance's backing files are present before its hook runs, avoiding the load-time race where the asset folder exists before its contents. * On live `asset.create` — the create path calls `M.fireFor(ref)` on the freshly-created instance, so a panel authored at runtime appears at once. GATING (all load-bearing): * Only types that IMPLEMENT onRegister are ever touched — a type without it costs nothing. * The @builtin LIBRARY is excluded from the sweep (`/zero/source/libs/`): builtin content is author-immutable and registered through its own fast path, so boot isn't an O(thousands) hook storm. * The sweep is BATCHED (yields every CHUNK instances) so a world with a large instance count never stalls a frame.

logWarn(msg: ?) → void

argtypedescription
msg?

firedSet( ) → void

keyOf(ref: ?) → string

argtypedescription
ref?

alreadyFired(ref: ?) → boolean

argtypedescription
ref?

markFired(ref: ?) → void

argtypedescription
ref?

fireFor(ref: any, onRegisterFn: any?) → boolean

Fire one instance's `onRegister(self)` hook exactly once. Resolves the type's hook from `ref.type` when `onRegisterFn` isn't supplied. Idempotent: a second call on the same instance is a no-op. re-loading the type module per instance). the type has no onRegister).

argtypedescription
refanyThe per-instance AssetRef (`self`).
onRegisterFnany?Optional pre-resolved hook fn (the sweep passes it to avoid

sweep( ) → void

Batched sweep: fire `onRegister` once for every WORLD instance of every registered type that implements it. Excludes the @builtin library and yields every CHUNK instances. Safe to call repeatedly — the per-instance once-guard makes a re-sweep cheap. Must run inside a task (it yields).

registerBuiltinType(typeName: string, primaryFile: string?) → void

Fire `onRegister` for every @builtin LIBRARY instance of `typeName`. `M.sweep()` deliberately EXCLUDES `/zero/source/libs/` so a world-load never pays an O(thousands) hook storm over author-immutable builtin content. A few builtin types, though, must register at boot: the default font and the egui symbol fallback have to be live before the first text render, offline included (no world-load sweep runs offline). This is the targeted fast path for those — it touches ONLY builtin instances of the one named type, so the set is tiny (a handful of fonts) and boot stays cheap. Idempotent via the shared once-guard. Synchronous, so it runs straight from the boot prelude. Safe to call more than once: an instance whose payload isn't available yet is left UNMARKED so a later call (a content-ready hook) can complete it. availability gates registration (a `.font`'s `"data.zfnt"`). A builtin binary leaf is fetched on first read; on WASM the bytes land asynchronously, so a read that returns nil means "not ready yet" — skip WITHOUT marking, and the read itself kicks that fetch so an early prelude call primes the later content-ready one. Omit to register unconditionally.

argtypedescription
typeNamestringAsset type whose builtin instances register now (e.g. "font").
primaryFilestring?Optional payload filename under each instance whose local

fireForPath(path: string) → boolean

Fire `onRegister` for the single instance whose FOLDER is at `path`. The entry for an asset that becomes present after the world-load sweep has already run: an install, a peer-synced write, anything that ARRIVES rather than being authored here. `asset.create` reaches the same hook through `fireFor` for the same reason — content that appears mid-session has no sweep to catch it, and a type that never learns an instance exists never registers what it owns.

argtypedescription
pathstringVFS path of the typed-asset folder.

examples

onReg.fireForPath("/zero/source/deps/w/pkg.package/api.module")

install( ) → void

Install the world-loaded sweep and the arrival entry. Idempotent. `engine.onWorldLoaded` is latched, so installing after the world already loaded still fires the sweep. The sweep runs on a system task so it ticks through pause and never blocks the caller.

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

2items
This part has no composite children. See the Files segment for its leaf payloads.
backing path · assetTypes/assetType.assetType/shared.module/onRegister.module

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported. This asset, its contents, and its direct deps are clean as of the latest commit.
ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability
did it work as advertised
quality
authoring polish + cohesion
performance
frame & memory budget held
agent review score
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.