Skip to content

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.

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.girlsx and RandomGirls.rgirlsx must sit at the pack root. The loader doesn’t recurse looking for them, so per-character .girlsx files 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 inside Characters/<Name>/, and the folder name has to match the character’s Name attribute exactly.
  • Traits.traitsx and Items.itemsx also live at the pack root, and so does the lowercase scripts/ folder that item <on_use_script> files resolve against (character scripts live in Characters/<Name>/, next to triggers.xml). jobs/ is the one folder that does recurse: each subfolder under it is one data-driven job. The name must be lowercase jobs/; a capitalized Jobs/ folder loads on Windows and most Macs but silently does nothing on Linux. See the “Jobs in packs” section of jobs-reference for 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

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.

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 overrides

If 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.

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.

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.

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.

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.

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):

  1. Whatever packs is set to in your config.xml
  2. The canonical default resources/packages (so a stale config still picks up the new location)
  3. The historical resources/characters/Packages fallback

The legacy loader walks resources/characters/ once, picking up every loose .girlsx / .rgirlsx and matching character-name folder.

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.

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.