Characters & assets

Clothing

Add garments as loose FBX files with a small text file each, textures by naming convention, and catalog thumbnails.

Every garment in the game, all 960 of them, is a mod file: a .ulcloth description plus a mesh. There is no clothing database in the engine. Yours sit next to them with the same powers.

A garment

textMods/yourname_streetwear/
├── Clothes/
│   └── Tops/
│       ├── Neon-Hoodie_1_F.ulcloth
│       └── Thumbs/
│           └── Neon-Hoodie_1_F.png
└── Meshes/
    └── Clothes/
        └── Tops/
            ├── Neon-Hoodie_1_F.fbx
            └── Textures/
                └── Neon-Hoodie_1_F/
                    ├── Default_BC.png
                    ├── Default_N.png
                    └── Default_M.png
ini# Clothes/Tops/Neon-Hoodie_1_F.ulcloth
DisplayName: Neon Hoodie
Gender: Female
Slots: Outerwear
MeshId: Clothes/Tops/Neon-Hoodie_1_F.fbx
Color: 1, 1, 1, 1
Rarity: rare
Stats: attractiveness +2, interpersonal +1
Key Meaning
(file name) The garment's id, used by shops and outfits. Must be unique across all mods.
DisplayName Name in the wardrobe and shops
Gender Female, Male or Unisex: which body it is fitted to
Slots Comma-separated body slots it occupies (below)
MeshId The mesh, relative to a Meshes/ folder in any enabled mod
Textures Optional texture set: a folder name beside the mesh's own (Meshes/.../Textures/<name>/), or a path with / relative to any mod's Meshes/. Without it the garment reads Textures/<mesh file name>/. Several .ulcloth can share one MeshId and differ only here: one FBX, any number of painted looks (a _M.png in the set can also shorten it, see Texture sets)
VariantOf, Variant A painted look of another garment: VariantOf: <base id> hides this item from the catalogue and lists it as a button in the creator's LOOK row of the base garment, Variant: Striped is the button's text. Colour, pattern, cuts and wear carry over when the player switches looks. The base garment's own Color is a swatch: the game shows a painted texture as painted and only recolours when the player picks a colour
Color r, g, b, a tint, 0–1
IconId Optional picture for lists, under Images/
HandPose For something held (a pistol, a purse): a Daz pose preset (.duf) for the hand that holds it, relative to the .ulcloth. While the item is worn the pose is laid over whatever animation plays, on the bones it names only. See Held items
Stats Stat bonuses while worn: stat +n, stat -n (also stat=n). Taken off with the garment, never written into the stat (see Stats)
Rarity A tier of Items/*.ulrarity (common, uncommon, rare, epic, legendary in ul_Base): the wardrobe colours the garment's name and shows its bonuses in the tooltip, the shop shows it before the category
Price What a clothes shop asks, in dollars. Without it, the shop's ClothingPrice for the category (see Shops)
StatName, StatChange The legacy single bonus; same as one entry of Stats
Type The garment's kind inside its category (tank, skirt, heel…): the wardrobe shows a tab per type present. Ids and their names are Clothes/types.txt (<id> | <Name> per line, in tab order; a later mod renames an id or adds new ones). A third column puts the type under another wardrobe tab; a fourth holds flags, space separated: Hides=Bottom_Under (underwear a garment of that type always hides, even with Always Show Underwear on: jeans | Jeans | Bottom | Hides=Bottom_Under, no panty shows through skin-tight trousers) and Multiple (several garments of the type worn at once, as rings or bags; any other type is one at a time, a second top replaces the first whatever slots each names). A garment with no Type, or one no file knows, takes the type Clothes/slot_types.txt gives its slots (<slot, slot…> | <type>; the exact slot set first, else its first slot)
Sexiness How revealing it is, 1 (ordinary) to 5. Someone under 18 is never shown or dressed in anything above 2; a file without the line counts as adult-only. A cut option can add to it (below)
HidesHair true: the wearer's hair is not drawn while this is worn. For hoods, sacks and anything else that goes over the head; without it the hair comes through the hood
Cut A group of cut variants the player can pick (repeatable). See Cuts
Pattern Optional: the pattern the garment wears until the player picks another, as <id> <RRGGBB> <RRGGBB> [size]. Pattern: Fishnet 0A0A0A 0A0A0A 1 on a plain catsuit mesh is how the base game's body stockings are made. See Patterns
StateOf Optional: <item id> <state> -- this garment is another garment in a worn state (the base game's panties down at the thigh, knee or ankle, on both legs or -one leg, in Couture/G8F/PantyStates). Never listed in the wardrobe or shops; scenes reach it with Actor:setClothingState(slot, state). States a shape can express (aside, lowered, lifted for a skirt hiked up) are keys of the base garment's Worn cut group instead; a skirt or dress with no Lifted key is lifted with its shortest Length cut. The sex scene's Clothes petals offer every state a garment has
Finish Optional: how the fabric takes the light, a ClothFinishes id. Finish: Leather for the whole garment, Finish: Buckle=Metal for one material (repeatable). Without it the finishes' own rules choose. See Finishes

.ulcloth files are found anywhere under Clothes/; subfolders are only for your own organisation.

A scene asks what someone wears with Actor:getEquippedItem("Top"): { id, name, rarity, stats } or nil.

Rarity tiers: Items/*.ulrarity

json{ "rarities": [
	{ "id": "common", "name": "Common", "color": "#A7ADB4" },
	{ "id": "cursed", "name": "Cursed", "color": "#B3261E" }
] }

Tiers rank in file order, lowest first. A later mod's tier with an existing id renames or recolours it in place; a new id is added after the others. .ulitem takes Rarity: too.

Slots

Top, Top_Under, Bottom, Bottom_Under, Foot, Foot_Under, Outerwear, Torso, Neck, Head, Hood, Mask, Eyewear, Ear, Wrist, Finger, Waist, Collar, Chastity, Blindfold, Gag, GagOpen, Handcuffs, Thighcuffs, Shincuffs, Accessory.

  • Two garments that share a slot cannot be worn together.
  • The first slot decides the wardrobe category (Top, Bottom, Outerwear, Underwear, Shoes, Socks, Headwear, Accessory). A garment covering both Top and Bottom is listed as a Dress.
  • An unknown slot name is dropped with a warning in the log.

Cuts

One mesh can be worn several ways: sleeves long or short, a top full-length or cropped, a skirt at the knee or a mini. Each way is a shape key in the FBX (an ordinary morph target) that moves the part being cut away. The .ulcloth names them in groups:

iniCut: Sleeve | Long | CutSleeve=Short
Cut: Hem | Full | CutHem=Underbust | CutHemMid=Midbust

Cut: <group> | <label for the mesh as made> | <shape key>=<label> | …

  • The wardrobe shows one row per group, in file order: the first button is the garment as made, then one button per shape key.
  • The options of a group exclude each other; groups combine freely (short sleeves and cropped).
  • A picked shape key is set to 1, the others of the item to 0. There is no slider: half a cut never looks right.
  • A label ending in +N (CutHem=Cropped +1) raises the garment's Sexiness by N while that cut is worn; the +N is not shown.
  • The choice is kept per garment, in the wardrobe, saves and character presets (CLOTHING Cut: 100% <id> CutSleeve,CutHem).

Making the shape keys: the part cut away must disappear in every pose, not only in the rest pose. A sleeve piled up at the shoulder is still skinned to the forearm and swings out when the elbow bends; tuck it inside the limb where it is instead, and keep only the first centimetre or two to form the new edge. A hem raised on a top can be collapsed onto the cut line. For a skirt with a decorated hem, remove a band above the hem and lift the hem up, so the ruffles stay whole.

Patterns

Any garment can wear a pattern over its own texture: stripes, leopard, a monogram canvas, fishnet. The player picks one on the wardrobe's Pattern page, with its two colours and a size; some passers-by wear one too. Patterns are mod files, so yours sit beside the base game's:

textMods/yourname_prints/
└── Patterns/
    ├── Signature-Canvas.png
    ├── Signature-Canvas.ulpattern
    ├── npc.txt
    └── Thumbs/
        └── Signature-Canvas.png
ini# Patterns/Signature-Canvas.ulpattern
Name: Signature Canvas
Kind: color
Scale: 30
Colors: #FFFFFF, #FFFFFF
Group: Luxury
Npc: 1
Key Meaning
(file name) The pattern's id, as saves and scripts name it. A later mod's file with the same id replaces it
Name Shown under its tile
Kind How the picture is read (below). Default duotone
Scale How many centimetres one repeat of the picture covers on the body. The player's size multiplies it
Colors The two colours it comes in, #RRGGBB, #RRGGBB, before the player changes them
Group The tab it is listed under (Classic, Animal, Luxury…). Any name makes a tab
Image Optional: another picture than <id>.png
Npc How often someone dressed by the game picks this one among all patterns, 0 never. Default 1

Kinds

  • duotone: a greyscale picture. Black takes colour 1, white colour 2, greys a mix: one picture of a leopard is every colour of leopard. The player chooses both colours.
  • color: a full-colour picture, drawn as it is (tie-dye, a printed canvas). Colour 1 tints it; white leaves it alone.
  • cutout: white is cloth in colour 1, black is a hole (fishnet, lace, slashes). A cutout adds 1 to the garment's Sexiness, and nobody under 18 can wear one.

The picture: square, seamless (its left edge continues its right one, its top its bottom), a power of two (512, 1024, 2048). It is wrapped around the garment from the front, the sides and above rather than through the garment's UVs, so a stripe stays a stripe across every seam and every garment at the same scale. The garment's folds still shade it. Thumbs/<id>.png is the wardrobe tile, about 128 px; without it the picture itself is shown.

Patterns/npc.txt: chance = 0.2, the share of tops and trousers the game puts a pattern on when it dresses someone (in the pattern's own colours). A later mod's line wins; 0 turns it off.

Scripts set one with Actor:setClothingPattern(slot, id, color1, color2, size) and read it with getClothingPattern(slot) (Actor API). The choice is kept per garment, in the wardrobe, saves and character presets (CLOTHING Pattern: 100% <id> <pattern> <RRGGBB> <RRGGBB> <size>).

Finishes

A finish is how a fabric takes the light: matte cotton, the sheen of satin, the shine of latex, the grain of denim or leather, metal buttons. It sets the material's roughness, specular and metal, and lays a fine weave over the garment's own normal map. Finishes are mod files:

textMods/yourname_fabrics/
└── ClothFinishes/
    ├── Brocade.ulfinish
    └── Brocade_N.png
ini# ClothFinishes/Brocade.ulfinish
Name: Brocade
Roughness: 0.55
Specular: 0.55
Metallic: 0
Weave: Brocade
WeaveCm: 3
WeaveStrength: 0.6
Materials: brocade, damask
Names: brocade, damask, cheongsam
Types: dress
Priority: 60
Key Meaning
(file name) The finish's id, as Finish: lines name it. A later mod's file with the same id replaces it (change the base game's Leather by shipping your own Leather.ulfinish)
Name A readable name
Roughness 0 mirror-smooth to 1 fully matte. Cotton is about 0.8, satin 0.3, latex 0.1
Specular Strength of the reflection on a non-metal, 0–1. 0.5 is ordinary
Metallic 1 for metal (zips, buckles, jewellery), 0 for everything else
Sheen Velvet, wool and knit pile: light gathers along the silhouette instead of shining in the middle. 0 none (most fabrics) to 1 (velvet)
Weave Optional: the weave picture, <Weave>_N.png beside the file
WeaveCm How many centimetres one repeat of the weave picture covers on the body
WeaveStrength How deep the weave looks, 0 none to about 1.5
Materials Words in a material's name that call for this finish (sole, buttons, lace)
Names Words in the garment's file or display name (denim, satin, biker)
Types Garment Types it is the usual fabric of (boot, stocking)
Priority When two finishes match at the same step, the higher wins
Default 1 on the one finish used when nothing matches (Cotton in the base game)

How a finish is chosen, for each material of a garment, first match wins:

  1. the garment's Finish: <material>=<id> line;
  2. a finish whose Materials word is in the material's name (a shirt's Buttons are plastic even on cotton);
  3. the garment's Finish: <id> line;
  4. a finish whose Names word is in the garment's file name or DisplayName;
  5. a finish listing the garment's Type;
  6. the Default finish.

Words are whole words, compared in lower case, with any non-letter as a separator: City-Limits-Jeans_1_F is city limits jeans f. Name your materials and files for what they are made of and they are covered without a Finish: line.

The weave picture is a normal map (DirectX convention, like UE's), square, seamless and a power of two. It is wrapped around the garment like a pattern, from the front, the sides and above, so it keeps one scale on every garment. Keep it fine and regular (threads, knit loops, grain), a few millimetres a repeat: the garment's own normal map already carries the folds and seams.

Held items

A prop in the hand is a garment like any other: an FBX skinned to the hand bone (lHand or rHand), usually in the Accessory slot. What makes it held is HandPose:

ini# Clothes/Props/Pistol.ulcloth
DisplayName: Pistol
Gender: Female
Slots: Accessory
MeshId: Clothes/Props/Pistol.fbx
HandPose: Poses/Pistol.duf

Poses/Pistol.duf is an ordinary Daz pose preset. Save one from Daz Studio with only the fingers of the holding hand selected (File > Save As > Pose Preset), or write the channels by hand:

json{ "scene": { "animations": [
	{ "url": "name://@selection/lIndex2:?rotation/z/value", "keys": [[0, -62.5]] }
] } }
  • Only the bones the file drives are posed; list every finger of that hand, the straight ones at 0, or a finger you want straight keeps the curl of the animation.
  • Both hands can be in one file (a baton in each hand).
  • The catalogue picture is rendered with the pose applied.

Texture sets

A garment's pictures live in Meshes/.../Textures/<mesh file name>/, one <Material>_BC.png (colour), _N.png (normal map, DirectX) and optional _M.png (white = fabric, black = hole) per material of the FBX. A second look of the same mesh is another folder beside it and a second .ulcloth naming it:

ini# Clothes/Tops/RubyHenley_Breton.ulcloth
DisplayName: Garnet Henley (Striped)
Gender: Female
Slots: Top
Type: tank
MeshId: Clothes/Tops/RubyHenley.fbx
Textures: RubyHenley_Breton

Meshes/Clothes/Tops/Textures/RubyHenley_Breton/Default_BC.png is then its colour. Add VariantOf: RubyHenley and Variant: Striped and the look is offered on the Henley itself instead of filling the list with near-duplicates. The mesh is loaded once whatever the number of sets. A set's _M.png is how a texture alone makes a cropped top or shorts out of a long piece: black below the new hem removes the fabric, the layer underneath shows through. Underlives's own tools paint such sets from the mesh's position map (Tools/Couture/texturing/paint_variants.py), so a stripe, a hem band or a chest print lands where it is on the body, not where it falls in UV space.

Two-point restraints

Handcuffs, an ankle chain, a rope round the wrists, a spreader bar: two anchors on two bones and a link between them. The game draws a cuff on each bone and the link (a chain or rope that sags and swings, or a straight bar), and holds the body to it whatever animation plays: when the clip spreads the wrists further than the chain allows, the arms are drawn back together; a bar also keeps the ankles apart. The item needs no MeshId.

ini# Clothes/Restraints/Bdg_Tether_Handcuffs.ulcloth
DisplayName: Steel handcuffs
Gender: Unisex
Slots: Handcuffs
Tether: lHand, rHand, 7
TetherAnchor: Sets/GenCore/Pieces/GenCore/Wear_Cuff_Steel_Handcuff.glb#Wear_Cuff_Steel_Handcuff
TetherOffset: -2 0 0
TetherEye: 0 0 -3.8
TetherLink: chain 0.6 0.62,0.63,0.66
Key Meaning
Tether Bone A, bone B, the longest the link lets them part, in cm. Hands (lHand, rHand) and feet (lFoot, rFoot) are moved; any other bone (neckLower for a collar) stays put and the other end comes to it
TetherRigid true: exactly that far apart (a bar)
TetherFit morph: the piece is scaled and shifted by what the wearer's shape morphs did to the skin under the bone and its children, so head gear modelled on the base head (hoods, gags, blindfolds) follows a bigger or smaller head. Cuffs use TetherInner instead
TetherAnchor, TetherAnchorB The cuff mesh (.glb#Node, under a mod's Rooms/ folder), B defaulting to A. Modelled with the limb passing through along Blender X, the eye at Blender −Z
TetherOffset Where the cuff sits: x along the limb (negative = up the forearm or shin), y sideways, z away from the eye, in cm. A fourth to sixth number rolls it round the limb (degrees, in the sixth place)
TetherEye Where the link hooks onto the cuff mesh, in cm, mesh space
TetherLink chain, rope or bar, its width in cm and colour (r,g,b, 0–1)

The cuff is turned along the limb and its eye toward the other bone automatically, so one anchor mesh fits both wrists. Put it on like any restraint: Actor:dressBondage("Bdg_Tether_Handcuffs"), the sex menu, an outfit. The old one-piece cuffs (Bdg_Handcuffs) still freeze the arms in their pose clip; a two-point item replaces that pose.

Single-bone gear (collars, gags, hoods, clamps)

A Tether line with one bone and no second one is a rigid piece worn on that bone, with no link: a collar, a gag, a blindfold, a hood, a box over the head, nipple clamps. It follows the bone through every animation.

ini# Clothes/Restraints/Bdg_Wear_Gag_Ball_Red.ulcloth
DisplayName: Ball gag, red
Gender: Unisex
Slots: Gag, GagOpen
Type: acc_head
Tether: head
TetherAnchor: Sets/GenCore/Pieces/GenCore/Wear_Gag_Ball_Red.glb#Wear_Gag_Ball_Red

The mesh is placed in the bone's own frame: Blender +X runs along the bone (from its parent to it, in the rest pose), Blender −Z faces the front of the body, Blender +Y is the person's left, and the origin is the bone. In practice: model the piece on the G8 body where it belongs, then move it into that frame. The shipped head gear sits on head, the chest pieces (clamps, a sign on a string) on chestUpper, collars on neckLower. TetherOffset (cm) still shifts it.

Key Meaning
TetherInner Optional. The opening across Blender Y and Z, in cm (12 11 for a collar). With it, the band is recentred on the skin round the bone and opened until it clears it, so it never sinks into a thick neck. Leave it out for anything that is not a band round the bone itself (gags, hoods, a bucket): the fit reads only that bone's skin, and the face belongs to the face bones
TetherEye Where a link or leash would hook on, in cm, mesh space

A gear piece with a printed face (the word on a cardboard sign, a face drawn on a paper bag) uses a Canvas zone like any prop.

Torn clothes

Actor:damageClothing(slot, holes, rips) punches holes and rips through a worn garment (0..1 each); repairClothing(slot) mends it. The holes are stamped at random places of the garment's UV through its opacity, the same places every time for the same garment, and saved with the wardrobe.

The shapes are images any mod adds: ClothingDamage/Holes/*.png and ClothingDamage/Rips/*.png, greyscale, white for cloth and black for the hole, one shape centred on white (not a tiling pattern), up to 256 px.

Ripped: holes placed on the body

Worn Ripped, a garment is not scattered with stamps: a file per category places each hole where it belongs on the body, the same on every garment of the category whatever its UV. ClothingDamage/Ripped/Bottom.ulripped (trousers, leggings, jeans) has one line per hole:

Placement: Stamp=UL_Ripped_01 Side=Back X=0 Z=87 Width=42
Placement: Stamp=UL_Ripped_02 Side=Front X=0 Z=91 Width=20

Stamp is a picture beside the file (Ripped/<Stamp>.png, white for cloth and black for the hole, any square size), Side is Front or Back, X the centimetres toward the wearer's right, Z the height above the floor in centimetres, Width the picture's width in centimetres. The hole is projected from that side onto the garment, so a pair of shorts and a long legging both get it at the same spot of the body. A later mod's file for the same category replaces an earlier one's. A category without a file keeps the random stamps of ClothingDamage/Ripped/*.png. Never applied to a minor.

The mesh

  • A skinned FBX exported from Daz Studio, fitted to the Genesis 8 Female or Male figure, with the Genesis 8 bone names. The garment follows the wearer's skeleton; it does not bring its own.
  • Loaded at runtime: no import, no engine.

Following the body's shape

A garment follows the wearer's body shape (weight, muscle, bust, hips, a pregnancy) through morph targets with the same names as the body's, exactly as in Daz. You do not have to export them all: for every body morph a person actually has set, a garment that lacks it gets one copied from the nearest body vertices, like Daz's auto-follow, and the breast and glute jiggle weights are copied the same way. A morph or a weight you exported is kept as you made it, so export your own where the copy looks wrong (a stiff belt, a corset that should not take the belly's shape, a loose skirt that should hang rather than cling).

The copy only works for a garment fitted on the figure in its default shape (Base Female or Base Male, no morph dialled in when you export). Fitted to a reshaped figure, every copied morph is measured from the wrong surface and the garment floats or sinks into the skin. A garment for a figure other than Genesis 8 does not follow the shape at all.

Textures

Textures are found by name next to the mesh, in Textures/<mesh name>/:

File Is
<Material>_BC.png Base colour
<Material>_N.png Normal map
<Material>_M.png Opacity mask (lace, mesh fabric); its presence makes the garment alpha-masked

<Material> is the material name in the FBX.

Lookup order per material: <Material>_BC.png, the name without a trailing _1/_2, Default_BC.png, then the folder's only *_BC.png if it holds exactly one. A garment with no texture at all is plain white cloth. Every garment takes the creator's COLOR row: with no colour chosen the texture shows as painted; a chosen colour keeps only the texture's shading (folds, seams, a printed heart in relief) and replaces its colours, so a yellow top turns exactly the blue the player picked.

The base game's own generated garments (the Couture folders of the ClothingExtended mod, formerly the ul_Couture mod) are generated, not sculpted, and ship with a UV_Layout.png beside their textures: the mesh unrolled as one flat tube at real scale, front centre in the middle, the seam down the back, hem at the bottom, one island per part (bodice, skirt, sleeves). Paint over it, or hand it to an image model with a description of the fabric, save the result as Default_BC.png in your own mod's copy of the garment, and the piece wears it. Patterns (below) need no texture at all: they are projected onto any garment, including a fishnet or lace cutout. Default_… answers for any material without its own files, which is enough for most garments (822 of the 940 base garments use a single texture set).

Keep textures to what the garment needs: a PNG is decoded to 4 bytes a pixel, so one 2048 image is 16 MiB in memory whatever it weighs on disk. 1024 for a top or trousers, 512 for shoes and hats, 256 for jewellery; normal maps half that. Optionally ship a block-compressed <name>.dds (BC1, or BC3 when the image has any transparency, with its mips) beside each PNG: the game loads it instead as long as it is not older than the PNG, at an eighth to a quarter of the memory. Tools/GlbTextures/shrink_cloth_textures.py in the game repository does both.

Thumbnails

The wardrobe and shops show Thumbs/<id>.png, in a Thumbs/ folder next to the .ulcloth. The base game's thumbnails are renders of the garment worn on the Genesis 8 body of its gender, on a neutral background: match that for a consistent catalog.

Selling it

Shops stock garments by id: Item: Neon-Hoodie_1_F, 60, -1 in a .ulshop (Shops and items).

Wardrobes and occasions

Everyone the game remembers (the player and every known person) has a wardrobe: the garments they own, what they wear, and an outfit per occasion. It is kept across rooms and saves. Scripts reach it through getClothes, giveClothing, setOutfit, wearOutfit and Game:showWardrobe (People → Clothes).

Occasions are defined in Clothes/Outfits/occasions.txt, one per line:

# id | Name | outfit list | place words
work   | Work   | work   | work, office, company, bank
sports | Sports | sports | sport, gym, fitness, stadium
  • outfit list: the outfits_<F|M>_<list>.txt to draw from when someone has no outfit of their own for it (empty means everyday clothes).
  • place words: parts of location tags where people dress for this occasion. They are matched against whole parts of the tag (gym matches city_gym; bar does not match barber).
  • A later mod adds occasions, redefines one by repeating its id, or removes one with id | -. everyday must exist: it is what anywhere unclaimed means.

When someone dresses for a place (Actor:dress(), dressUniform with no uniform), their own outfit for that occasion comes first, before the outfit lists.

The base game's interactions Give clothes and Suggest an outfit (ul_Base/Interactions/wardrobe/) show how a scene uses the wardrobe; the acceptance roll of a suggestion lives in that scene, so a mod can change it.

The outfit-change spin

When someone changes outfit in front of the player (Actor:wearOutfit, Actor:changeInto, the wardrobe's Wear outfit), they spin inside a swirl of light and the clothes change at its peak. Its look is Clothes/outfit_change.txt, key = value lines that a later mod overrides one by one:

Key Is
spin_up, spin_down Seconds to the peak, and back to still
turns Whole turns of the body
color_a, color_b r, g, b at the feet and at the head
ribbons, sparkles How many bands of light and sparkles
intensity Glow strength
flash Light thrown on the room at the peak