Declare and show
"activation": ["onWidget:counter.panel"], the plugin loads when the panel is first shown. Users move panels between docks, float them and close them; View › Panels lists them all.
The widget instance
The component getsinstance:
A tab that was shown once stays mounted while hidden. Do expensive work, and ask the running game
for data, only while
instance.visible is true.Svelte rules
- Plugins compile in runes mode (
$props,$state,$derived,$effect). - A value that changes outside Svelte must be an observable (read with
$), or state you update from a subscription. - A store that hands back the same array or object does not update the view: return a new one.
The component kit
Use the editor’s components so your panel looks and behaves like the rest:Button, IconButton, Input, NumberInput, Checkbox, Switch, Select, Combobox, Tabs, Tree, Menu, ContextMenu, Dialog, Tooltip, EmptyState, Icon, Splitter, PropertyGrid, ColorPicker, Vector2Input.
- Give every control an accessible name (
aria-labelwhen there is no visible label). - Write labels in sentence case, with a verb that says what the button does.
- Icons are Lucide names. A plugin adds its own with
registerIcons({ name: Component }). A dock panel shows only its icon, in a stripe on the edge of the window, before its plugin activates: until then, an icon the plugin registers shows as a box. Prefer anonStartupregistration, or an icon the editor already has.
Styles
Component<style> blocks are built into one CSS file (build.lib.cssFileName in vite.config.ts). Inject it when the plugin starts:
plugins.<name>), and removes it with the plugin.
Theme tokens
Use the editor’s CSS variables, never fixed colors: your panel then follows the theme.
A plugin adds a theme with
contributes.themes: see make a theme. Icons drawn with <Icon name="…"> follow the chosen icon theme.
Screens
A widget with"kind": "screen" is a main screen, next to Project, Scene, Script and Game. It is declared and given a view the same way.