UIDoc Game UI Kit
Skin finished UIDoc screens with the engine's hand-drawn Game UI kit: the @import mechanism, class reference, assembly rules, and worked examples.
The Game UI kit is the art team's hand-drawn UI set ($AO/ui/kit/Game UI/**): modals, buttons, tabs, progress bars, banners, portholes, item slots, checkboxes, and toggles. The engine ships a matching stylesheet so any UIDoc asset can adopt the kit look without copying CSS.
Apply the kit as a final styling pass. Build the screen first — layout, bindings, events, viewport behavior — verify it works, then skin it. Kit styling is paint and padding; it must never be the tool used to fix layout.
Enabling the kit
Add one line to the asset's index.css:
@import "game-ui-kit";At bake time the engine splices res/ui/kit/kit.css in place of the import, so put the import first and your own rules below it — your rules win cascade ties. The import composes with Tailwind utilities. Editing the engine stylesheet re-bakes importing assets on the next build; UIDoc still does not hot reload in a running game.
The one pattern to know
UIDoc has no bitmap CSS backgrounds, so kit art enters through ordinary img elements. Every kit container is a positioned element whose first child is a .kit-bg image; the div owns shape and layout, the image just paints, nine-slicing via asset settings that ship with the kit:
<div class="kit-modal">
<img class="kit-bg kit-bg--shadow" src="$AO/ui/kit/Game UI/Modals/Basic Modals/modal_simple_grey1.png">
<!-- content -->
</div>.kit-bg is object-fit: fill for nine-sliced art (modals, buttons, tabs, bars, banners). Fixed-aspect art (checkboxes, toggles, portholes, slot icons) uses .kit-bg--contain and the container's own width/height.
Use .kit-bg--shadow on the actual backing img when the art should cast a shadow. It uses an alpha-aware drop-shadow(...), so transparent corners and the painted result of nine-slicing define the silhouette. A box-shadow follows the container's rectangular border box instead, while putting drop-shadow(...) on the container would also include its text and other descendants.
Put visible button/tab copy in a foreground label element after the art. Raw text owned by the container can paint below its child image:
The kit optically lowers direct button labels by 5px to match the art. For a compound foreground such as an icon plus a price, wrap the whole foreground in .kit-btn-content so the icon and copy move together:
Class reference
.kit-bg, .kit-bg--contain, .kit-bg--shadow
Art backing image, fixed-aspect fit, and alpha-aware image shadow
.kit-fg
Generic foreground layer above .kit-bg
.kit-modal
Positioned flex-column panel with kit padding
.kit-modal-header
Centered title safe area with 72px reserved on both sides
.kit-modal-title
Centered title row; combine with .kit-text-header
.kit-title-banner
pointy_banner_* backing behind a modal title, fully inside the modal
.kit-header-band
modal_header_* band across the modal's painted top edge
.kit-dim
Full-screen dim behind a modal
.kit-btn, .kit-btn-label, .kit-btn-content, .kit-btn--<colour>
Button art plus an optically lowered foreground label/group with a colour-matched outline
.kit-tab-row, .kit-tab, .kit-tab-label, .kit-tab--active
Pill-tab navigation row with foreground labels
.kit-progress, .kit-progress-fill, .kit-progress--N, .kit-progress--compact
Track plus bound fill; family modifier aligns the fill and compact selects the 30px scale
.kit-card, .kit-list-row
Structural containers for art-backed cards and rows
.kit-close
Foreground close control absolutely rooted at the modal's top-right
.kit-slot, .kit-slot-icon, .kit-slot-qty
Inventory/shop square with icon and count
.kit-porthole
Circular frame; stack *_back.png under *_ring.png
.kit-checkbox, .kit-toggle
Fixed-aspect state controls
.kit-text-header/body/body-dark/info
The art doc's four approved text styles
Text sizes follow the art doc (65/55/45/40) at the standard logical viewport; override in the asset when a screen needs a different scale.
Assembly rules
These come from the art team's Game UI documentation and established practice; the classes encode most of them, the markup patterns cover the rest.
Titles: white, Heavy, black outline, drop shadow (
.kit-text-header), set either straight on the modal, on a.kit-title-banner(dark banner backing, fully inside the modal — avoid the brown "yellow" pointy banner), or on a.kit-header-bandwhen the colour pairing works: a saturated band on a light modal (red on white) reads well; muted-on-muted (gold on grey) does not. When unsure, plain title text is always safe.Closable modal headers: keep
.kit-closeas a direct child of.kit-modal, where it remains absolutely rooted at the top-right. Put the title or title banner inside.kit-modal-header; its symmetric 72px side reserves keep the title visually centered and clear of the close control. Budget modal width as the desired title/banner width plus both 72px reserves plus the panel's left and right padding. This deliberately makes closable modals a little wider than tightly fitted body content.Art shadows:
box-shadowfollows a rectangular border box. For irregular or nine-sliced kit art, put.kit-bg--shadowon the actual backingimgso the shadow follows its painted alpha. Do not put the filter on.kit-modal, because that would include the modal's text and child art in the shadow silhouette.Buttons: text is white with a colour outline complementing the button art — never black. Put a plain label directly in
.kit-btn-labelso it paints above the art and receives the kit's 5px optical baseline offset. For icon-plus-text content, put both inside a direct.kit-btn-contentchild so the pair receives that offset together. Useshiny_buttonsfor purchases and special interactions,basic_buttonsfor everything else, and give text generous padding. The grey button is the disabled look.Body text: subtle 20%-opacity outline (
.kit-text-body) on colour modals; plain dark text (.kit-text-body-dark) on white/grey modals.Tabs: a pill row inside the modal body, not attached to the top edge. Put copy in
.kit-tab-label. Active tab uses a colour art variant (e.g.tabs_blue) with a matching text outline; inactive tabs usetabs_black. Usetab_med.pngortab_large.pngfor dynamic labels. Thetab_small.pngsource files are inconsistent and some contain baked labels, so they are intentionally not nine-sliced.Progress bars: each
progress_bar_Nfolder pairs abacking.pngwith a purpose-builtfill_*.png, but the interior offsets differ by family and are often asymmetric because of the lower rim/drop shadow. Track art goes in.kit-bg; the matching family fill goes in.kit-progress-fill, which usesobject-fit: fill; add the matching.kit-progress--Nmodifier to the container and binddata-style-image-fill-amount. Do not substitute a tinted icon or decorative transparent image: tint preserves source alpha, andcovercan crop square art into gaps or diagonal wedges on a thin track. Preview the bar at0,0.25,0.5, and1; current diagnostics do not detect unsuitable texture alpha. The default component is 40px thick; add.kit-progress--compactfor the proportionally scaled 30px form. For a custom thickness, set equalfont-sizeandheightvalues on the container so its em-based family insets scale with it. Kit tracks useflex-shrink: 0; choose the thickness explicitly instead of relying on a flex parent to compress the track, which can make the track and its fill resolve at different sizes.Item slots: colour squares (
inv_square_<colour>1.png) for filled slots;inv_square_empty2.pngis the designed EMPTY state.Modal family art shares one scale (37px corners, 6px outline in source pixels — the shipped slice insets already account for this). Pieces meant to composite, like a header band over a modal, align because they are drawn at the same scale; do not hand-edit individual slice values.
Example: settings modal
Stripe modals (modal_stripe_*) carry a darker footer band — seat the action row on it by keeping it the last flow child.
Example: confirm dialog (battle request)
A saturated header band on a light modal, dark body text, and a yellow/red accept/decline pair.
Example: daily reward
A banner-backed title on a grey modal, reward slots, a streak bar, and a shiny claim button.
Filled slots bind reward.back to $AO/ui/kit/Game UI/Item Backs/inventory_squares_1/inv_square_blue1.png (or another colour); empty slots use inv_square_empty2.png with no icon.
Art coverage
Nine-slice insets ship in res/ui/kit/Game UI/.asset_settings for: Basic Modals (simple, stripe, headers), basic and shiny buttons, medium/large modal tab pills and trapezoids, horizontal progress-bar backings/fills (excluding segment sprites and fixed-aspect bar 12), horizontal pointy banners, and horizontal interior panels. Fixed-aspect pieces — including inventory squares, checkboxes, sliders and toggles, portholes, helper masks, and highlights — need no slices. Other families (cards, speech bubbles, fancy banners, ranking backings) exist in the kit but have no tuned insets yet — measure before slicing them, and keep composited pieces at one shared scale.
Last updated