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 | Slave, Free, or Normal. Controls who can buy/hire her. |
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="Slave" matters for the slave market. The caravan only shows girls flagged as slaves. Default is Normal, which means she won’t show up.
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 (11 total):
Anal, Magic, BDSM, NormalSex, Beastiality, Group, Lesbian,Service, Strip, Combat, Performance<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.resources/packages/Sample_Full/Girls.girlsx— worked example with every block.