Builtin Library
README.md
assetType.shared.inspector
Which inspector a type declares for its assets, and the declaration that file
returns. The editor's Inspector (edui.inspector) reads it to add, replace and
order the sections an asset shows.
The block
A type names its inspectors in type.yaml, with either key or both:
# the Inspector for every asset of the type, a file in the type's own folder
inspector: { type: "inspector.luau" }
# a file each asset may ship in its own folder, for what that asset declares
inspector: { instance: "inspector.luau" }
# both
inspector: { type: "inspector.luau", instance: "inspector.luau" }
type: is what selecting an asset of the type shows. instance: applies to
the things an asset declares, never to the asset's own view: a component
names instance: "inspector.luau", and a component that ships that file
shapes its card on every entity it is on. Each value is a .luau file name.
A block that is not a map, names another key, names neither key or names a
file that is not .luau is malformed; the assetType validator reports it as
assetType.inspector_block, and a type: file missing from the type folder
as assetType.inspector_file_missing.
The declaration
The file returns a table:
return {
-- sections this inspector adds (before Operations)
sections = {
{ id = "summary", title = "Summary", build = function(ctx)
return { ctx.widgets.text{ text = "mode is " .. tostring(ctx.settings.mode) } }
end },
},
-- a generic section id -> the section shown in its place
replace = { tags = { id = "tags", title = "Labels", build = function(ctx) return {} end } },
-- section ids, first to last; ids it does not name follow in default order
order = { "summary", "identity" },
}
A section is { id, title, icon?, open?, build(ctx) }; build returns the
section's body as a list of edui nodes. Any member of the declaration other
than sections, replace and order must be a function (a helper the file
exports). material.assetType/inspector.luau is a full example.
The Inspector rebuilds an asset's sections when the asset's files change. A
section that shows state held outside those files names it with a
signature(ref) member: text that moves when that state moves, read every
time the Inspector checks for a rebuild, so it has to be cheap.
renderFeature.assetType/inspector.luau folds in whether the feature runs
and its live settings, so a feature enabled or reconfigured from a script
shows in the Inspector as it happens.
API
local InspectorDecl = require("@builtin::assetTypes.assetType.shared.inspector")
InspectorDecl.blockFor("material") -- { type = "inspector.luau" }
InspectorDecl.blockProblem({ other = "x.luau" }) -- why a block is malformed, or nil
InspectorDecl.declaresTypeInspector("material") -- true: the asset view reads one
local decl, problem, file = InspectorDecl.declarationFor(matRef)
local cdecl = InspectorDecl.instanceDeclarationFor(compRef)
InspectorDecl.shapeProblem(decl) -- nil when well-formed
declarationFor(ref) (and typeDeclaration(typeName)) read the type: file:
(nil, nil, nil)when the type names notype:inspector;(nil, problem, file?)when the block is malformed, or the file is missing, raises while loading, or returns the wrong shape — the problem names the file and what is wrong with it;(declaration, nil, file)otherwise.
instanceDeclarationFor(declarerRef) reads the instance: file in the
declaring asset's own folder, and answers (nil, nil, file) when that asset
ships none.