Shop mannequins
Live display figures dressed in what the shop sells, from .ulmannequin files: forms, skins, poses, outfits and the display pieces they replace.
The mannequins in a clothes shop wear what the shop actually sells. A shop grammar places its display pieces as usual (a figure on its feet, a torso on legs, a lingerie window, a dress form, a counter bust); the room's dressing then puts a live figure on each of them, dressed in a coordinated outfit drawn from the venue's clothes stock. Click one to buy the whole outfit or try it on.
Your mod's garments show up on the mannequins of every shop that sells them: nothing to add. A mod can also add its own figures (a dress form, a torso, a hand), skins, poses and outfit recipes in a .ulmannequin file.
How it works
- The dressing file
Rooms/Dressing/mannequins.uldressinghas a rule with aMANNEQUINtable (see Room dressing). ItsONnames the display pieces it may replace. - For each such piece, the first
piecesentry (below) whosematchfits the piece's name says which forms may stand there, which of the piece's materials to hide, and where the figure stands. - The game draws, seeded by the building (the same figures on every visit): a form (of the sex the piece shows:
_Malein its name), an outfit recipe, garments for it from the venue's stock, a skin and a pose. - The figure is put up, dressed, posed once, and then never updated again until its outfit changes.
The baked figure stays when the venue sells no clothes (no .ulshop with a Clothing: line at its tag), when no pieces entry matches, when no complete outfit can be found, or when the room already has MAX live figures.
Garments go on the figures exactly as on people (same skeleton, same leader-posed garment meshes), at their base fit: the forms are the morphless figure the garments were made on.
A mannequin file
<mod>/Mannequins/*.ulmannequin, JSON. Every mod's files are read in load order; an entry whose id comes again replaces the earlier one (a pieces entry: its match).
json{
"forms": [
{ "id": "female", "gender": "Female", "mesh": "Mannequins/mannequin_f.glb" },
{ "id": "female_bust", "gender": "Female", "mesh": "Mannequins/mannequin_f_bust.glb",
"slots": ["Neck", "Collar"], "outfits": ["necklace"], "poses": ["still"], "skins": ["velvet_black"] }
],
"skins": [
{ "id": "chrome", "color": [0.85, 0.86, 0.88], "roughness": 0.14, "specular": 0.5, "metallic": 1.0 }
],
"skin_by_piece": [ { "match": "*_Chrome*", "skin": "chrome" } ],
"poses": [
{ "id": "arms_down", "weight": 2,
"bones": { "lShldrBend": [0, 42, 0], "rShldrBend": [0, -42, 0] } }
],
"outfits": [
{ "id": "casual", "weight": 3, "pieces": [
{ "category": "Top", "types": ["tee", "tank", "shirt"] },
{ "category": "Bottom", "types": ["pants", "shorts", "skirt"] },
{ "category": "Shoes", "types": ["sneaker", "flat"] },
{ "category": "Outerwear", "chance": 0.3 } ] }
],
"pieces": [
{ "match": "Display_Mannequin_Figure_*", "forms": ["female", "male"] },
{ "match": "Display_Bust_Black", "forms": ["female_bust"], "hide": ["Body"], "anchor": "neckLower", "offset": [0, 0, 27], "scale": 0.75 }
]
}
Forms
| Field | Meaning |
|---|---|
id |
The form's name. |
gender |
Female or Male: which garments it wears and which people's skeleton it uses. |
mesh |
The body, a .glb (or .fbx) under a mod's Meshes/. It must be skinned to the Genesis 8 skeleton of that sex, with the exact G8 bone names, in the base shape (no morphs): garments go on it without any fitting. |
slots |
The clothing slots it can show (Top, TopUnder, Bottom, BottomUnder, Foot, FootUnder, Outerwear, Torso, Neck, Ear, Wrist, Finger, Waist, Collar...). A garment with any other slot is never drawn for it: no trousers under a torso cut at the thighs. Empty: every slot. |
outfits |
The outfit recipes it uses. Empty: every recipe with a weight above 0. |
poses |
The poses it takes. Empty: every pose that names no forms. |
skins |
The skins it may be rolled. Empty: any. |
Shipped forms (ul_Base/Meshes/Mannequins/, made by Tools/Mannequin/export_mannequin.py):
| Form | |
|---|---|
female, male |
The whole figure, headless (a closed neck cap) |
female_head, male_head |
The whole figure with a smooth featureless head |
female_armless, male_armless |
The whole figure without arms (the torso-on-legs and lingerie figures) |
female_torso, male_torso |
A lingerie torso form: neck to just below the crotch, arms cut at the upper arm |
female_bra |
A bra form: neck to under the bust |
female_legs, male_legs |
Hips and legs: panties, tights, stockings, socks |
female_bust, female_bust_head, male_bust |
Jewellery busts: neck, shoulders, upper chest (with a head for earrings) |
female_hand, male_hand |
A display hand, upright: rings, bracelets, watches |
Jewellery is worn the same way as clothes (.ulcloth garments in the Neck, Ear, Wrist and Finger slots), so busts and hands are dressed like the full figures.
Skins
A skin is a material, not pictures: color (linear RGB), roughness, specular, metallic, sheen (velvet). Shipped: white, grey, black, chrome, velvet_black, velvet_cream. skin_by_piece keeps a figure the colour its piece was made in (*_Black* stays black); a pieces entry's skin fixes it outright. Otherwise the skin is rolled among the form's skins.
Poses
bones turns bones from the figure's rest pose: [x, y, z] degrees about the figure's own axes, x pointing to the figure's left, y to its back, z up, applied x first, then y, then z; each bone about its own joint, parents before children, so a turned upper arm carries the forearm with it. After the turn the figure is lowered or raised so its lowest foot stands where it stood ("ground": false to keep it where the bones put it: a hand, a bust). forms limits a pose to those forms. weight is how often it is drawn.
These are the axes of Blender's world with the figure facing -Y, so a pose can be tried on the body in Blender first: blender -b -P Tools/Mannequin/preview_poses.py -- <body.glb> <file.ulmannequin> <out.png> [pose ids] renders each pose front and side, exactly as the game applies it.
Shipped: arms_down, hand_on_hip, three_quarter, walking_stride, contrapposto; still (the partial forms) and hand_upright.
Outfits
A recipe is a list of pieces, each drawn from the stock that the form can show:
| Field | Meaning |
|---|---|
category |
The garment's category (Top, Bottom, Dress, Outerwear, Underwear, Shoes, Socks, Headwear, Accessory). |
types |
Optional: the garment's Type: (tee, skirt, heel, bra, panty, stocking...). |
slots |
Optional: a slot the garment must occupy (["Neck"] for a necklace). |
chance |
Below 1: the piece is optional and only drawn that often. A required piece that the stock cannot supply makes the game try another recipe. |
A recipe may also say max_sexiness (no piece scored above it: a full figure in a clothes shop wears clothes, not a bra and hot pants) and spread (default 1). The pieces of one outfit never share a slot, and stay within spread of the first piece's Sexiness: so a figure reads as one look. Shipped recipes: dress, casual, smart, coat (the full figures; an outer layer only over nothing, since a shirt under a jacket pokes through it on a figure that never moves), lingerie (the lingerie figures and window), and torso_top, lingerie_set, bra, legwear, necklace, earrings, hand_jewellery for the partial forms (weight 0: only where a form or piece names them).
Pieces
| Field | Meaning |
|---|---|
match |
The catalogue piece's name, wildcards allowed, | between alternatives ("Display_DressForm_Linen|Display_DressForm_Red"). Later files win. |
forms |
The forms that may stand there. |
hide |
The piece's materials to hide (its baked figure), keeping the rest (a window's glass, a dress form's stand). Omitted: the whole piece is hidden. |
offset |
[x, y, z] cm in the piece's frame (x towards its back, the figure faces -x; z up) where the figure's feet, or its anchor, stand. |
anchor |
A bone placed at offset instead of the feet (neckLower for a bust on a stem, lHand for a hand). |
scale |
The figure's size (a counter bust is 0.6 to 0.75). |
yaw |
Degrees added to the figure's turn. |
skin, outfits, poses |
Narrow the form's own for this piece ("outfits": ["lingerie"] in the lingerie window). |
The dressing rule
lua-- Rooms/Dressing/mannequins.uldressing
return {
NAME = "mannequins",
GRAMMARS = { "shop_clothes", "shop_fashion", "shop_luxury", "shop_department", "shop_sports", "shop_outdoor", "sex_shop" },
RULES = {
{ ID = "mannequin_live", ON = { "Display/Mannequin", "Display/Showcase", "Display/DressForm", "Display/Bust" },
MANNEQUIN = { STOCK = "shop", MAX = 6, FREEZE = "static" } },
},
}
MANNEQUIN field |
Meaning |
|---|---|
STOCK |
"shop": the venue's own clothes .ulshop files (the only source for now). |
MAX |
Live figures per room at most (default 6); the others keep their baked figure. |
FREEZE |
"static" (default): posed once, then the body and each garment are baked into static meshes (one per garment, so a sold-out piece can still come off). true: posed once and left as skinned meshes that are never updated. false keeps it evaluating every frame, only useful to measure the difference. |
FORMS, SKINS, POSES, OUTFITS |
Optional lists of ids that narrow the .ulmannequin choices for this rule. |
In the game
Clicking a mannequin opens its menu: Buy this outfit (the price of every piece together) buys each garment through the till like a shelf item, and Try it on opens the shop's fitting rails with the outfit already on the player (offered when the figure is of the player's sex). When a limited garment's last one is sold, the mannequins of that building take it off, as the shelves lose their last box; it is back when the shop restocks.