Where packs go
Two folders under resources/ hold pack content. Both are loaded at game start; you can use either, or mix them.
| Folder | Purpose | Format |
|---|---|---|
resources/packages/ |
Structured packs (recommended) | One subfolder per pack, each with a package.xml |
resources/characters/ |
Loose character files (legacy, still supported) | .girlsx / .rgirlsx files plus per-character image folders, all at the top level |
Folder casing: engine versions from 1.17.1 use all-lowercase game folders (resources/packages/). Older versions spelled them Resources/Packages/. On Windows and macOS either spelling works; on Linux the case must match your engine version, so if your game folder still has a capitalized Resources/, that’s where packs go. The folders inside your pack (Characters/, image-type folders) are unchanged.
New format (recommended)
Section titled “New format (recommended)”Drop your pack as a subfolder of resources/packages/:
resources/packages/MyPack/ package.xml required: pack identity + dependencies Girls.girlsx optional: unique characters RandomGirls.rgirlsx optional: random-character definitions Traits.traitsx optional: custom traits Items.itemsx optional: custom items Characters/ Jane/ character-name folder, per-character content inside images.xml optional: per-character tag overrides triggers.xml optional: per-character event/trigger hooks MeetGirl.lua optional: meet script for this character Profile/ image category folders Sex/ ... scripts/ optional: scripts referenced by items (<on_use_script>) genie_grant.lua jobs/ optional: data-driven jobs (lowercase!) myjob/ job.xml ...The package.xml is what marks this as a pack. Without it, the folder is ignored. See the example packs in examples/packs/, next to resources/ in the game folder, for working examples of every pattern (from game 1.21; in 1.20 and older they are the Sample_* folders in resources/packages/).
A few rules about where files have to live:
Girls.girlsxandRandomGirls.rgirlsxmust sit at the pack root. The loader doesn’t recurse looking for them, so per-character.girlsxfiles in subfolders are silently ignored. One file per pack, every unique character as a<Girl>block inside.- Per-character content (
images.xml,triggers.xml,MeetGirl.lua, image folders) lives insideCharacters/<Name>/, and the folder name has to match the character’sNameattribute exactly.
Traits.traitsxandItems.itemsxalso live at the pack root, and so does the lowercasescripts/folder that item<on_use_script>files resolve against (character scripts live inCharacters/<Name>/, next totriggers.xml).jobs/is the one folder that does recurse: each subfolder under it is one data-driven job. The name must be lowercasejobs/; a capitalizedJobs/folder loads on Windows and most Macs but silently does nothing on Linux. See the “Jobs in packs” section ofjobs-referencefor pack-job ids and message overlays.
Use the new format if you want any of:
- Traits, items, jobs, Lua, or building definitions in the same drop
- Dependencies on another pack, or addons that extend one
- Pack-validator coverage
- Per-pack enable / disable through future tooling
Legacy format
Section titled “Legacy format”Drop loose files directly into resources/characters/:
resources/characters/ Jane.girlsx unique character XML Generic.rgirlsx random-character definitions Jane/ character-name folder, same layout as new format Profile/ Sex/ ...The engine collects everything at this top level and treats it as a single virtual pack named _Legacy. No package.xml is needed. Image folders use the same layout as the new format; nothing about per-character content changes.
Use the legacy format when:
- You’re loading existing legacy WM content that already matches this layout
- You inherited a
resources/characters/tree and don’t want to repackage it
For anything new, use the format above. The package wrapper is one file.
Default-image packs
Section titled “Default-image packs”A pack can ship art for a default image pool, the fallback set the game uses when a character’s own folder has nothing for the requested image type. This is the right shape for a bulk art pack that fleshes out the job-shift buckets (wait, cook, massage, dom, escort, etc.) without touching any individual character’s Characters/<Name>/ folder.
Drop the images into Characters/Default/ at the pack root:
resources/packages/MyDefaultsPack/ package.xml Characters/ Default/ Profile/ default profile portraits Wait/ default waitress images Cook/ default cook images Massage/ default masseuse images Dom/ default dominatrix images ... images.xml optional: per-file tag overridesIf those images are for your own characters, that is all you need, and the table below explains the rest.
If they are meant for everyone’s characters, the pack goes somewhere else and is laid out differently. See “Packs that share images with everybody” below.
Then decide who those images are for, by setting Type in package.xml:
Type |
Who sees the images |
|---|---|
Content (the default) |
only characters your own pack ships |
Addon |
characters of the pack named in Extends |
Defaults |
characters from every installed pack |
<Package Name="My Defaults Pack" Id="my_defaults_pack" Type="Defaults"/>A Type="Defaults" pack may hold nothing but default images, their images.xml, an optional pack-root image-fallback.xml, and ordinary metadata. No characters, traits, items, jobs, buildings or Lua. Ship those as a second pack and link them with <Requires>. The validator and the installer both refuse a Defaults pack that carries anything else, and name the file that broke the rule.
If you published a default-image pack before this change, add Type="Defaults" to it. Every pack’s Characters/Default/ used to be merged into one shared pool, so any pack could feed art to any character. It is now scoped by the type above, and the validator points at a pack that looks like it needs the line. Nothing else about your pack changes.
An addon’s layout depends on what it extends
Section titled “An addon’s layout depends on what it extends”An Addon’s shape is not decided by the role alone. It is decided by the pair: Addon, plus the role of the pack it extends.
| Extends a… | Put the art in | What is ignored |
|---|---|---|
Content pack |
Characters/Default/ at the addon root |
named pool directories are not read at all |
Defaults pack |
named pool directories at the addon root | nothing; they join the target’s pool |
Get this pair wrong and the files are simply never scanned. Nothing warns you at runtime, because an unread directory looks exactly like a directory you meant to leave empty.
What no pack can do
Section titled “What no pack can do”Engine 1.20 does not support named-character image overlays. A character’s own art comes from her own folder in the pack that owns her, and nothing reaches into it. That is the current engine, not a permanent rule.
Creating Characters/Sample Girl/ in your addon does not extend the target’s “Sample Girl”. It declares a character of that name owned by your pack, which is a different thing and almost never what you wanted. Fallback art is the supported way to contribute art to characters you do not own.
Known limitation: extending an empty provider
Section titled “Known limitation: extending an empty provider”An Addon that extends a Type="Defaults" pack which ships no images of its own contributes nothing at all. There is no pool to join, so its art is silently ignored even though the manifest is correct and the target is installed. Make sure the pack you extend provides at least one image of its own.
Packs that share images with everybody
Section titled “Packs that share images with everybody”A Type="Defaults" pack installs into its own folder and holds named image pools rather than a single Characters/Default:
resources/packages/defaults/catacombs_defaults/ package.xml Type="Defaults" image-fallback.xml optional, your substitution rules NOTICE the art's licence kobold/ images.xml combat/ death/ orc/ combat/ death/Every pool is loaded into one shared set, so a scene can be answered from any of them. Pool names keep two sets of art apart on disk and are recorded by the game, but they do not yet decide who gets which art. Restricting kobold/ to actual kobolds is planned; nothing you author now will need moving when it arrives.
Use lowercase names. The older Characters/Default/ layout still works and says so in the log, so you can move at your own pace.
The game ships one of these as a worked example, resources/packages/defaults/sfw_defaults. Open it to see the manifest, the pool layout and the NOTICE a redistributable pack needs.
The kit ships a converter that builds this layout and reports what is left to write by hand:
tools/defaults-pack/build-defaults-pack.sh [--dry-run] <source-art-dir> <out-pack-dir> <pool-name>It converts to WebP with fixed parameters so a rebuild produces the same bytes, never resizes anything, and refuses to finish if the pack’s media exceeds 12 MiB. --dry-run shows what it would write and the size it would land at.
Several Defaults packs can be installed at once. They are searched together: an exact match in any of them beats a substitute in any other, whichever loaded first. Substitution between types is governed by resources/data/ImageFallback.xml, or by an image-fallback.xml at your own pack root if you want different rules for your art. Only a handful of same-family affinities exist by default (for example spanking accepts bdsm art), and most types, formal included, show a dedicated image or the character’s profile. So tag your art with the types the game actually requests; a near-miss type will not be borrowed automatically.
Legacy filename aliases
Section titled “Legacy filename aliases”For art sourced from older WMR or WM7 trees, the loader recognises a few historical filename prefixes and maps them to the modern bucket names automatically:
| Filename prefix | Modern bucket |
|---|---|
Dominatrix (N).jpg |
dom |
Advertisement (N).jpg |
advertise |
Mast (N).jpg |
masturbate |
You can drop the original files in without renaming: they’ll be tagged for the right bucket at load.
Subfolder vs. filename prefix
Section titled “Subfolder vs. filename prefix”Either layout works for any tag in the image catalog. Characters/Default/Wait/portrait01.jpg and Characters/Default/wait_portrait01.jpg resolve to the same bucket. Pick whichever is easier for your art workflow. The multi-token filename inference rules from image-types apply unchanged, so preg_wait_03.jpg correctly tags both wait and pregnant.
Loader resolution
Section titled “Loader resolution”At startup the engine reads config.xml for two keys:
<resources> <packs>resources/packages</packs> <legacy>resources/characters</legacy></resources>Both default to the values shown. The structured-packs loader walks (in this order):
- Whatever
packsis set to in yourconfig.xml - The canonical default
resources/packages(so a stale config still picks up the new location) - The historical
resources/characters/Packagesfallback
The legacy loader walks resources/characters/ once, picking up every loose .girlsx / .rgirlsx and matching character-name folder.
Pointing the engine somewhere else
Section titled “Pointing the engine somewhere else”If you keep your packs outside the install (a shared library across versions, a Dropbox folder, a dev tree), set packs in config.xml to that absolute path:
<packs>D:/WM-Packs</packs>The Content Manager (the Rust authoring tool) reads the same key, so both tools agree on where your packs live.
Which one should I use?
Section titled “Which one should I use?”Use the new format. Always, for anything you’re authoring today, even a one-character drop. The cost is one extra file (package.xml), and in return you get the validator, the Content Manager, the dependency system, future per-pack enable / disable, and any feature that lands later. Picking legacy for a new pack means opting out of all of that to save thirty seconds.
The legacy format is for existing content. If you have a pile of loose .girlsx files from older WM or WMR versions and you just want them to load, drop them into resources/characters/ and they will. Don’t start a new pack there.
Legacy content is not deprecated and won’t be removed. It just isn’t the path to pick when you have a choice.