Girls.girlsx schema
Pack-author grammar for .girlsx (named girls) and .rgirlsx (random templates). One shape, one mental model — only the role-specific attributes differ. Identity stays on <Girl> as attributes; stats, skills, traits, gold, and inventory live as typed child elements.
Every legacy shape ever written for these files keeps loading silently — see Accepted variants at the bottom. New packs should use the canonical shape below.
Canonical named girl (.girlsx)
Section titled “Canonical named girl (.girlsx)”<?xml version="1.0" encoding="UTF-8"?><Girl Name="Azula" Desc="Princess of the Fire Nation." Status="Slave"> <Stat name="Age" value="22" /> <Stat name="Beauty" value="65" /> <Stat name="Charisma" value="85" /> <Skill name="Service" value="30" /> <Trait name="Pretty" /> <Trait name="Royal Blood" /> <Gold value="500" /> <Inventory> <Item Name="Lucky Charm" /> </Inventory></Girl>That’s enough for the game to load her. Everything else has defaults.
Canonical random template (.rgirlsx)
Section titled “Canonical random template (.rgirlsx)”<?xml version="1.0" encoding="UTF-8"?><Girl Name="Cute Girl"> <Stat name="Age" min="18" max="24" /> <Stat name="Beauty" min="40" max="70" /> <Stat name="Charisma" value="60" /> <!-- sugar: min = max = 60 --> <Stat name="Constitution" min="50" /> <!-- partial: only min set --> <Skill name="Service" min="10" max="30" /> <Trait name="Pretty" percent="40" /> <Trait name="Shy" /> <!-- no percent: uses the trait's RandomChance --> <Gold min="50" max="150" /></Girl>Random templates use min= / max= (or value= as min=max sugar) on stats, skills, and gold; named girls use value=. Trait percent= is only honoured for random templates — named girls always get the trait. On a random template, a trait listed without percent= falls back to the trait’s own RandomChance (from its .traitsx definition) rather than never rolling.
Identity attributes on <Girl>
Section titled “Identity attributes on <Girl>”| Attribute | Required | Purpose |
|---|---|---|
Name |
Yes | Display name. For named girls (and template-policy randoms), must match the Characters/<Name>/ folder exactly. |
Realname |
No | True name if Name is an alias. |
Desc |
No | Short description shown in girl details. |
Status |
No | Where she turns up: Slave (slave market) or Catacombs (found exploring). Absent or anything else: met in town. |
Virgin |
No | True / False — sets virgin status and overrides the age/skill-derived default (skipping that roll). Omit to derive from age + skill spread. Preferred over the legacy Virgin trait. |
UseAntiPreg |
No | True if she uses contraception by default. |
Comments |
No | Free-text notes; not shown in-game. |
Status is the entry channel, not a rarity. The game keeps one pool of named characters you have not met yet and draws from it by this flag: Slave characters are offered by the slave market caravan, Catacombs characters are found when workers or gangs explore the Catacombs (and arrive as captives), and everyone else is met walking the town or brought in by a gang kidnapping. A character is in exactly one channel.
Age is a stat, not an identity attribute. Use <Stat name="Age" value="22"/>. (The legacy <Girl Age="22"> form still works — see Accepted variants.)
<Stat> element
Section titled “<Stat> element”| Attribute | Named girls (.girlsx) |
Random templates (.rgirlsx) |
|---|---|---|
name |
Required. Stat name (see list). | Required. Stat name. |
value |
Required. Integer value. | Optional sugar — sets min = max = value. |
min |
Ignored. | Optional. Lower bound. If only min is set, max stays default. |
max |
Ignored. | Optional. Upper bound. Partial range tolerated. |
Recognised stat names (22 total):
Charisma, Happiness, Libido, Constitution, Intelligence, Confidence,Mana, Agility, Fame, Level, AskPrice, House, Exp, Age, Obedience,Spirit, Beauty, Tiredness, Health, PCFear, PCLove, PCHateLookup is case-insensitive. An unknown stat name is silently skipped.
<Skill> element
Section titled “<Skill> element”Same attribute shape as <Stat> (name + value for named, name + min/max + value-sugar for random). Skills default to 0 or a small starting value; only list the ones you want to set.
Recognised skill names (22 total):
Anal, Magic, BDSM, NormalSex, Beastiality, Group, Lesbian,Service, Strip, Combat, Performance, Farming, AnimalHandling, Crafting,Herbalism, Brewing, Cooking, Medicine, OralSex, TittySex, Handjob, FootjobEleven of these arrive with game 1.21, which is not released yet, and they are not all in the same state. OralSex, TittySex, Handjob and Footjob are already weighed by the Escort job, so setting them does change a shift. The seven occupational skills (Farming, AnimalHandling, Crafting, Herbalism, Brewing, Cooking, Medicine) are accepted everywhere but no job reads them yet, so setting one changes nothing in a shift until the Farm jobs are wired to them. A random template that does not give the eleven newer skills a range sets them to 0, while the original eleven keep their usual unranged default.
<Trait> element
Section titled “<Trait> element”| Attribute | Named girls | Random templates |
|---|---|---|
name |
Required. | Required. |
percent |
Ignored — always applied. | Optional. Chance (0-100) the trait is rolled. Omit to fall back to the trait’s RandomChance. |
Trait names match the Name attribute in .traitsx definitions exactly (case-sensitive — unlike stat / skill names). The core trait list is in resources/data/traits/. Pack-defined traits work too.
The legacy <Trait name="Virgin"/> is still accepted for back-compat, but it is migrated to the Virgin flag and dropped from the trait list — virginity is status data, not a descriptive trait. Use Virgin="true" on <Girl> instead (the validator warns about the trait form).
<Gold> element
Section titled “<Gold> element”| Attribute | Named girls | Random templates |
|---|---|---|
value |
Required. Starting gold. | Optional sugar — sets min = max = value. |
min |
Ignored. | Optional. Lower bound. |
max |
Ignored. | Optional. Upper bound. |
<Inventory> block (named girls only)
Section titled “<Inventory> block (named girls only)”Items she starts with. Item names match the Name attribute of an item in any loaded .itemsx file (including resources/data/Items.itemsx).
<Inventory> <Item Name="Simple Dress" /> <Item Name="Lucky Charm" /></Inventory>Each item is added to the girl’s inventory and equipped automatically when she loads. Items that cannot be worn — Food and Makeup — are added but left unequipped. Unknown item names are skipped, with a note in the game log. The inventory holds 40 slots; items past that are dropped.
The <Inventory> wrapper is optional: bare <Item> elements placed directly inside <Girl> are read the same way. Random templates don’t carry inventory.
Accepted variants
Section titled “Accepted variants”The loader silently accepts every legacy shape that ever worked. New packs should use the canonical shape above; existing packs do not need to migrate.
Optional wrappers around typed children. <Stats>, <Skills>, <Traits>, <Inventory> are equivalent to writing the children directly under <Girl>:
<Stats> <Stat name="Beauty" value="65" /></Stats><!-- same as --><Stat name="Beauty" value="65" />This is the shape some older kit copies documented. Both work.
Capital attribute names. <Stat Name="Beauty" Value="65"/> (capital N and V) parses the same as the canonical lowercase form. Same for Min=, Max=, Percent=. The canonical docs and snippet templates use lowercase; either works.
Legacy flat stat attributes (.girlsx). Pre-rethink named girls put every stat as a <Girl> attribute:
<Girl Name="LegacyAlice" Beauty="65" Charisma="80" Age="22" />Still works. Stats also set by a <Stat> child win; flat attributes only fill stats the structured walk didn’t touch.
Legacy bare-child <Stat> (.rgirlsx). Pre-rethink random templates wrote ranges as direct children with capital attributes:
<Stat Name="Beauty" Min="40" Max="70" />Still works. Equivalent to the canonical lowercase form.
Migration tool
Section titled “Migration tool”For authors who want to convert legacy files to the canonical shape:
python3 tools/pack-authoring-kit/tools/migrate-girlsx.py resources/packages/MyPack/Dry-run by default — prints what would change without touching files. Add --write to apply the rewrite (with .bak sidecars; --no-backup skips them). The tool refuses to rewrite files containing save-format <Stats> content (a safety check; pack authoring files should not have that shape).
VS Code authors get the same as palette tasks: Tasks: Run Task → Migrate girlsx (dry-run) or Migrate girlsx (write).
Image folder
Section titled “Image folder”The images for a girl go in Characters/<Name>/. The folder name must match the Name attribute of the <Girl> exactly (case-sensitive). If the folder is missing or empty, the Content Manager flags the girl as “Missing Images” and the game falls back to placeholder art.
Random girl naming (.rgirlsx)
Section titled “Random girl naming (.rgirlsx)”By default a random template’s Name is just a label; the engine assigns each spawned girl a fresh random name. Two attributes let a pack control this — set them on the <Girls> root of a .rgirlsx file (per-file) or in package.xml (pack-wide default):
| Attribute | Value | Effect |
|---|---|---|
RandomGirlNaming |
engine (default) |
Engine picks a random name from its built-in pool. |
RandomGirlNaming |
template |
Each spawned girl keeps the template’s Name. |
RandomGirlNaming |
pool |
Draw names from the file named by NamePool. |
NamePool |
a filename | Newline-delimited names file (beside the .rgirlsx or package). Blank lines and # comment lines are skipped. |
An invalid RandomGirlNaming value is ignored with a log warning and the engine default is used. Because the spawned name can differ from the template’s Name under engine / pool, those spawned girls draw images from the template’s folder, not from their assigned name.
Multiple girls per file
Section titled “Multiple girls per file”A .girlsx or .rgirlsx file can hold any number of <Girl> blocks under a <Girls> root. Split them across files however you like: one per girl, one per theme, or all in one. The loader doesn’t care.
See also
Section titled “See also”tools/pack-authoring-kit/snippets/Girls.girlsx: paste-and-edit named-girl skeleton.tools/pack-authoring-kit/snippets/RandomGirls.rgirlsx: random-template skeleton.examples/packs/Sample_Full/Girls.girlsx(game 1.21 on;resources/packages/Sample_Full/before): worked example with every block.