msw-ui-system
msw-git/msw-ai-coding-plugins-official
Complete MSW UI system: design guide, component API, builder, and runtime patterns for `.ui` files.
What is msw-ui-system?
MSW UI System provides a unified reference for designing, building, and scripting game UIs in MSW. It covers layout fundamentals (anchor/pivot/RectTransform), component selection and API, builder invocation through msw_ui_builder.cjs, and Lua runtime patterns for interactive elements. Use this when creating or modifying any `.ui` file or connecting UI logic in `.mlua` scripts.
- Design guidance for anchor/pivot/RectTransform positioning and mobile-safe layouts
- Full component API reference (ButtonComponent, TextGUIRendererComponent, SpriteGUIRendererComponent, ScrollLayoutGroup, GridView, TextInput, Slider, Mask, AvatarGUIRenderer) with enum values
- UIBuilder invocation methods: add/replace/patch/remove nodes, 13 anchor presets, auto-lint on write
- Layout recipes for common patterns: HUD, popup, toast, menu, inventory grid, scroll list
- Runtime Lua patterns: popup open/close, toast fade, HP bar, GridView interaction, drag, tab, cooldown, world nametag
- Automatic `.ui` ↔ `.mlua` UUID binding injection for property defaults
How to install msw-ui-system
npx skills add https://github.com/msw-git/msw-ai-coding-plugins-official --skill msw-ui-system- MSW project with `.ui` file support
- Node.js (for msw_ui_builder.cjs invocation)
- Familiarity with anchor/pivot concepts or willingness to read ui-fundamentals.md
How to use msw-ui-system
- 1.Read the routing table in the skill to identify which reference document matches your task (e.g., 'anchor/pivot' → ui-fundamentals.md, 'popup placement' → layout-recipes.md)
- 2.Load the relevant reference document (ui-fundamentals, ui-hierarchy, component-api, layout-recipes, runtime-patterns, or ui-sound)
- 3.For any `.ui` creation or modification, read builder-protocol.md (core) and builder-protocol-ui.md §3 to understand the builder API
- 4.Match your layout to a recipe in layout-recipes.md; adapt rather than build from scratch
- 5.Invoke msw_ui_builder.cjs with the appropriate method (create, add, patch, remove) and anchor preset
- 6.Call b.write() to persist changes; auto-lint runs and validates the `.ui` file
- 7.For Lua integration, use b.injectBindings() or the bind parameter in b.write() to auto-populate property default UUIDs
- 8.Verify the layout visually with preview_ui_layout.cjs and test interaction in-engine
Use cases
- Build a HUD layout with health bar, mana bar, and inventory grid anchored to screen edges
- Create a popup dialog with buttons and text, then wire open/close and button-click handlers in Lua
- Design a toast notification system that fades in/out and auto-dismisses
- Implement a GridView inventory with drag-and-drop interaction patterns
- Set up a menu with tab navigation and cooldown timers on buttons
- Game UI designers building layouts in MSW
- Gameplay programmers wiring UI logic in Lua scripts
- Full-stack developers handling both `.ui` design and `.mlua` runtime code
- Mobile game developers needing safe-area and resolution-aware layouts
msw-ui-system FAQ
Check ui-fundamentals.md §1–§8 on anchor/pivot/RectTransform. Most issues stem from mixing anchoredPosition with OffsetMin/Max, or incorrect anchor/pivot alignment. Use the formula pos = ±(margin + size/2) for edge placement.
Build the button with msw_ui_builder.cjs, then use b.injectBindings() or the bind parameter in b.write() to auto-populate the button's UUID into your `.mlua` script. See builder-protocol-ui.md §3.6 Binding Injection and runtime-patterns.md for click handler patterns.
No. Direct JSON editing breaks UUID, ValueType, and @components consistency. Always use UIBuilder.read() to query and b.write() to mutate. The builder enforces auto-lint and maintains structural integrity.
UIGroup is the root container for a UI hierarchy; CanvasGroup is a child container that affects opacity and z-order of its children. See ui-hierarchy.md for z-order, displayOrder, and Enable vs Visible semantics.
Read ui-fundamentals.md §9 on mobile, safe area, and MobileOnly/ActivePlatform. Use anchor presets and the safe-area formula to position UI relative to screen edges, and set font/touch sizes conditionally by device.
Full instructions (SKILL.md)
Source of truth, from msw-git/msw-ai-coding-plugins-official.
name: msw-ui-system
description: "MSW .ui single entry point — design + component API + builder + runtime. Anchor/pivot/RectTransform, UIGroup/CanvasGroup hierarchy, layout recipes (HUD/popup/toast/menu/inventory/scroll-list), full API tables for ButtonComponent/TextGUIRendererComponent/SpriteGUIRendererComponent/ScrollLayoutGroup/GridView/TextInput/Slider/Mask/AvatarGUIRenderer + UI enums (AlignmentType/TextOverflowMode/ImageType/FillAmount), .mlua runtime patterns (popup open-close, toast, HP bar, GridView, drag, tab, cooldown, world nametag), UI-client-only caveats (nil on server, no RPC), .ui↔.mlua UUID auto-binding (write+injectBindings), resolution/safe-area/touch. UIBuilder (msw_ui_builder.cjs): all node types (empty/panel/text/sprite/button/slider/scrollLayout/textInput/group/mask/gridView/avatar/skeleton etc.), component add/replace/patch/remove, 13 anchor presets+stretch, auto-inject .mlua UUID bindings after write."
msw-ui-system
MSW .ui single entry point — design guide + component API + builder invocation + runtime patterns bundled into one skill.
Role division with existing skills:
| Skill | Responsibility |
|---|---|
msw-ui-system (this skill) | Everything .ui — design (which/when/why), component API/enum (what), builder invocation (how to mutate), runtime mlua patterns. .ui mutations must always go through this skill's builder |
references/templates/ | Pre-built style bundles — .ui + ruid-map + button handler packages |
0. Routing
Branch to sub-references based on request keywords.
| Trigger | Reference Document |
|---|---|
| "anchor/pivot/coordinates/why is the position wrong", "RectTransform", "stretch" | references/ui-fundamentals.md §1–§8 |
| "mobile", "safe area", "1920", "MobileOnly", "ActivePlatform", "touch size", "PC reserved zone", "font size by device" | references/ui-fundamentals.md §9 |
| "UIGroup", "above popup", "z-order", "displayOrder", "CanvasGroup", "opacity propagation", "Enable vs Visible" | references/ui-hierarchy.md; for runtime sibling reorder also read references/runtime-patterns.md §7 |
| "which component", "Sprite vs Text vs Button", "9-slice", "scroll list", "GridView vs ScrollLayoutGroup" | references/component-api.md §"Component Selection Guide" |
| "sprite pivot", "9-slice border", "slice boundary", "set sliced asset metadata", "resource storage properties" | Set asset-side metadata via msw-mcp asset_update_resource_storage_info directly; for the .ui side see references/component-api.md §"SpriteGUIRenderer — ImageType Selection" |
| "make a HUD", "popup placement", "toast", "menu", "inventory grid", "scroll list" | references/layout-recipes.md |
| "connect .mlua after building with .ui builder", "property default UUID", "binding without drag" | ../msw-general/references/builder-protocol-ui.md §3.6 Binding Injection (unified entry point — load with the builder-protocol.md core) |
Runtime UI component field read/write, component property name/type (ButtonComponent.Colors, TextGUIRendererComponent.Overflow, SpriteGUIRendererComponent.FillAmount…) | references/component-api.md required before every .mlua access to UI component fields |
Enum values (AlignmentType, TextOverflowMode, ImageType, UIBasicParticleType…) | references/component-api.md §Enums |
| Runtime mlua patterns (popup open/close, toast fade, HP bar, GridView, drag, tab, cooldown), Runtime UI Caveats (client-only, server-side nil, etc.) | references/runtime-patterns.md |
.ui builder invocation methods (UIBuilder API, anchor presets, write auto-lint, component add/patch/remove) | ../msw-general/references/builder-protocol-ui.md §3 UIBuilder (unified entry point — load with the builder-protocol.md core; .map MapBuilder / .model ModelBuilder live in sibling per-builder files) |
| "sound", "sfx", "click sound", "hover sound", "button audio", "PlaySound" | references/ui-sound.md |
1. Basic Workflow
(1) Clarify intent Layout sketch (ASCII or verbal) + which group to attach to
(2) Check design guide Match at least one of ui-fundamentals / ui-hierarchy / component-api §Component Selection Guide
(3) Builder Preflight Read ../msw-general/references/builder-protocol.md (core) + builder-protocol-ui.md §3 (unified call-protocol entry point)
(4) Match recipe Select the closest template from layout-recipes.md
(5) Invoke builder Create/patch via scripts/msw_ui_builder.cjs (protocol: builder-protocol-ui.md §3)
(6) Inject bindings Auto-inject .mlua property default UUIDs via b.write(path, { bind: {...} }) or b.injectBindings(...) (builder-protocol-ui.md §3.6 Binding Injection)
(7) Self-verify write() auto-runs scripts/ui_lint.cjs (strict ON by default)
(8) Preview Visual check via scripts/preview_ui_layout.cjs
(9) Sound pass For any interactive button, offer click/hover SFX wiring (references/ui-sound.md)
(10) Maker Refresh Apply to engine
2. Global Rules
NEVER
- Do not directly edit
.uiJSON —.uicreation/modification must go throughscripts/msw_ui_builder.cjs. Manual editing breaks UUID·ValueType·@componentsconsistency and causes silent drops. - Read existing
.uifiles through the builder too — Query viaUIBuilder.read(filepath)/.find()/.listEntities(). Do not directly grep/parse raw JSON..uidirectReadand shell commands such ascat/type/Get-Content/rg/grep/sed/awk/cp/mvare blocked by the registered guard. UseUIBuilder.read/load/snapshotfor reads andb.write()for writes. Deleting an entire.uifile has no builder API — delete it withnode -e "require('fs').unlinkSync('ui/<File>.ui')"thenrefresh(shellrm/catare guard-blocked; anode -ebuilder call is not).
- Set
Positiondirectly — Use onlyanchoredPosition(Position is engine-managed) - Express size via OffsetMin/Max on fixed anchors (AnchorsMin == AnchorsMax) while also using
anchoredPosition— Do not mix the two modes - Builder creates new UUIDs but
.mluaproperty defaults are not updated — Binding breaks
ALWAYS
- Builder Protocol Preflight —
../msw-general/references/builder-protocol.md(core) +../msw-general/references/builder-protocol-ui.md§3 must be in context before any.uimutation (read them only if never loaded this session or lost to compaction) (UIBuilder API, write auto-lint, pos / anchor rules, binding injection, coverage gaps). The core carries the shared contract and cross-builder flow;.mapMapBuilder /.modelModelBuilder live in sibling per-builder files — one unified entry point because the cross-flow is interlocked. - Check at least one design guide before invoking the builder (
ui-fundamentals/ui-hierarchy/component-api§Component Selection Guide) - Match a recipe first; build from scratch only as a last resort
- For edge placement use the formula:
pos = ±(margin + size/2) - Separate popups and toasts into their own
.uiroot UIGroup, standalone show/hide; useempty()/panel()for inner containers, never nestedgroup() - Verify text
Alignmentdefault isUpperLeft(0)— 95% of "I centered it but it sticks to the left" issues - Button touch target ≥ 88×88 (mobile support)
- After creating any interactive button — proactively suggest wiring click/hover SFX via
references/ui-sound.md(default UI SFX RUIDs available). Skip only if the user explicitly opts out or the button is purely decorative. - Build the tree nested, not flat. Controls of one unit (window + title/close, row + chip/value, slot + icon/count) must share a parent via
"Parent/Child"paths so they move / fade / toggle / bind as a block. Create each parent before its children; missing parents fail lint (L025ERROR). - Do not stack root-level text over a sibling box.
ui_lintreports this asL030WARN. Nest the text under the box, usebutton()for clickable labeled boxes, or put a direct label onpanel()/sprite()via theirtextoptions.
3. Sub-documents
references/ui-fundamentals.md— Coordinate system, RectTransform 3 elements, anchor mode determination (§1–§8) + Resolution·safe area·PC reserved zones·touch targets·font sizes·platform separation (§9)references/ui-hierarchy.md— UIGroup / displayOrder / CanvasGroup / Enable vs Visiblereferences/component-api.md— §"Component Selection Guide" (which/when/why) + full component property/method/event tables (what) + all UI-related enum values (§Enums)references/layout-recipes.md— Layout template collectionreferences/runtime-patterns.md—.mluaruntime patterns (popup/toast/HP/grid/drag…) + Runtime UI Caveatsreferences/ui-sound.md— UI sound integration (_SoundService:PlaySound, click/hover hook, default UI SFX RUIDs)../msw-general/references/builder-protocol-ui.md§3 —.uiCJS builder call protocol (unified entry point — load with thebuilder-protocol.mdcore) —.mapMapBuilder /.modelModelBuilder live in sibling per-builder files. panel / text / sprite / button / slider / scroll / script / group / mask / grid / avatar / touchReceive / skeleton / areaParticle / basicParticle, component CRUD, anchor presets, write auto-lint, and.mluaproperty UUID auto-binding all live in §3 + §3.6.references/templates/templates.md— Pre-built style bundle index (style-N-*.ui,ruid-map.md,Popupbutton.mlua)
4. Scripts
scripts/msw_ui_builder.cjs—.uibuilder core (UIBuilder class). Read../msw-general/references/builder-protocol.md(core) +../msw-general/references/builder-protocol-ui.md§3 (unified entry point) before use.scripts/preview_ui_layout.cjs—.uilayout visual check + touch target warningsscripts/ui_lint.cjs—.uifile self-verification (auto-called bywrite())scripts/ui_recipe.cjs— Recipe-based scaffolding
Out of Scope
.map/.model/.tilesetbuilders — Outside this skill's scope.uiJSON schema (raw field shapes,@type/@componentswrapping, AlignmentOption 0–15 mapping, etc.) — Handled internally by the builder. Users/AI do not need to know directly- Accessibility patterns (alt text, screen-reader hints, focus order) — Not covered
- Error-state UI patterns (disabled-button styling beyond
Transition.Disabled, validation messages, loading spinners) — Not covered; design ad-hoc per project - Automated UI testing / layout assertions beyond
ui_lint.cjsandpreview_ui_layout.cjs— Not provided - Custom shader materials (
MaterialId) — Field is exposed but authoring shaders is outside this skill's scope
Related skills
More from msw-git/msw-ai-coding-plugins-official and the wider catalog.

msw-avatar
Manage avatar costumes (17 equip slots) and animation state mapping for any entity.

msw-behaviourtree
End-to-end authoring for MSW `.behaviourtree` files with automatic spec generation and validation.

msw-combat-system
Complete MSW 2D combat system integration covering attack resolution, damage, hit reactions, game feel, and AI FSM.

msw-defaultplayer
Manage DefaultPlayer character model, components, movement, physics, HP, and camera settings.

karpathy-guidelines
Behavioral guidelines to reduce common LLM coding mistakes through explicit assumptions, simplicity, surgical changes, and verifiable success criteria.

context-engineering-collection
Comprehensive guidance for building production AI agent systems through context engineering, multi-agent coordination, and reliable operating loops.