Msw UI System
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.
- Skill ID
- msw-git/msw-ai-coding-plugins-official/msw-ui-system
- Publisher
- msw-git
- Repository
- msw-ai-coding-plugins-official
- Installs
- 0
- Files
- 46
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
msw-git/msw-ai-coding-plugins-official/msw-ui-systemInstalls these files- SKILL.md
- references/component-api.md
- references/layout-recipes.md
- references/runtime-patterns.md
- references/templates/scripts/ruid-lookup.cjs
- references/templates/scripts/ui-structure.cjs
- references/templates/style-1-black/ButtonGroup.ui
- references/templates/style-1-black/DefaultGroup.ui
- references/templates/style-1-black/HUDGroup.ui
- references/templates/style-1-black/PopupGroup.ui
- references/templates/style-1-black/Popupbutton.mlua
- references/templates/style-1-black/ToastGroup.ui
- references/templates/style-1-black/ruid-map.md
- references/templates/style-1-black/structure.md
- references/templates/style-2-diary/HUDGroup.ui
- references/templates/style-2-diary/PopupGroup.ui
- references/templates/style-2-diary/Popupbutton.mlua
- references/templates/style-2-diary/Popupbutton.ui
- references/templates/style-2-diary/ToastGroup.ui
- references/templates/style-2-diary/TrashBin.ui
- references/templates/style-2-diary/ruid-map.md
- references/templates/style-2-diary/structure.md
- references/templates/style-3-wood/ButtonGroup.ui
- references/templates/style-3-wood/DefaultGroup.ui
- references/templates/style-3-wood/HUDGroup.ui
- references/templates/style-3-wood/PopupGroup.ui
- references/templates/style-3-wood/Popupbutton.mlua
- references/templates/style-3-wood/ToastGroup.ui
- references/templates/style-3-wood/ruid-map.md
- references/templates/style-3-wood/structure.md
- references/templates/style-4-blue/ButtonGroup.ui
- references/templates/style-4-blue/DefaultGroup.ui
- references/templates/style-4-blue/HUDGroup.ui
- references/templates/style-4-blue/PopupGroup.ui
- references/templates/style-4-blue/Popupbutton.mlua
- references/templates/style-4-blue/ToastGroup.ui
- references/templates/style-4-blue/ruid-map.md
- references/templates/style-4-blue/structure.md
- references/templates/templates.md
- references/ui-fundamentals.md
- references/ui-hierarchy.md
- references/ui-sound.md
- scripts/msw_ui_builder.cjs
- scripts/preview_ui_layout.cjs
- scripts/ui_lint.cjs
- scripts/ui_recipe.cjs
What this skill tells the agent
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 engine2. Global Rules
NEVER
- Do not directly edit `.ui` JSON —
.uicreation/modification must go throughscripts/msw_ui_builder.cjs. Manual editing breaks UUID·ValueType·@componentsconsistency and causes silent drops. - Read existing `.ui` files through the builder too — Query via
UIBuilder.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`](../msw-general/references/builder-protocol.md) (core) + [`../msw-general/references/builder-protocol-ui.md`](../msw-general/references/builder-protocol-ui.md) §3 must be in context before any `.ui` mutation (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 `.ui` root UIGroup, standalone show/hide; use
empty()/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
More from msw-git
Use this skill in a project
Open any RiverX project, search the Skills panel for msw-git/msw-ai-coding-plugins-official/msw-ui-system, and install it in one click.
