Skip to content

Resources reference

A resource is a counted thing the player holds: beasts in a cage, potions on a shelf, towels in a bathhouse. Your pack declares its own with one file, and from then on jobs can gate on how many there are, scripts can read and change the count, and (from game 1.21) a building can produce or consume it every week.

Declaring resources has worked since game 1.17.2. The per-field notes below say where a newer version is needed.

Any number of *.resourcesx files at your pack’s root, beside package.xml:

MyPack/
package.xml
towels.resourcesx
jobs/

Subfolders are not searched. Files load in sorted filename order, which only matters for duplicates (see below).

<?xml version="1.0" encoding="UTF-8"?>
<Resources>
<Resource Id="clean_towels" Name="Clean Towels" StorageScope="building"
Description="Laundered and folded, ready for the baths."/>
<Resource Id="soap" Name="Soap"/>
</Resources>

The root element must be <Resources>. A file with a different root, or one that fails to parse, is dropped whole: every resource in it disappears, with a line in gamelog.txt. Elements other than <Resource> inside the root are ignored without comment.

Attribute Needs Notes
Id 1.17.2 Required. The local id: no slash, not empty. The game puts your pack in front of it, so Id="soap" in MyPack is MyPack/soap everywhere anything refers to it. A missing id, or one containing a slash, skips that one <Resource> and logs an error; the rest of the file still loads.
Name 1.17.2 What a player reads, wherever the resource is named. Leave it out and the game shows the local id instead, so Id="clean_towels" with no Name reaches the player as clean_towels, underscore and all.
Description 1.17.2 Free text. The game stores it and no screen shows it yet.
StorageScope 1.20.3 estate (the default) or building. estate is one shared pool across the whole game; building gives every venue its own shelf. Any other value skips the definition entirely rather than falling back, and that is deliberate: a typo that quietly became estate would build a pool that fills, saves and reads back perfectly while being the wrong one, and nothing downstream could tell.
Marketable 1.17.2 true or false, default false. Marks the resource as something that may one day be bought and sold for gold. No shipped screen trades resources, so today this only affects a design warning in the game’s own job audit. Opt-in, so a pack resource can never quietly become an income tap.
EngineProduced, EngineConsumed 1.17.2 true or false, default false. Records that the engine itself makes or spends the resource. They describe the game’s own resources; there is nothing for a pack author to set here.

A boolean the game cannot read is ignored and the flag stays false.

LegacyBacked exists in the format and is engine-only: declared by any pack other than the game’s own core, it is stripped with a warning. It is listed here so you know what it is when you meet it, not as something to write.

First one wins, with a warning naming the loser. Files load in sorted filename order, so a-first.resourcesx beats b-second.resourcesx and the outcome is the same on every machine and every run.

Gate a job on it with a <Stock> condition, addressed by the qualified id (game 1.17.2 and later):

<Eligibility>
<Stock resource="MyPack/soap" ge="1"/>
</Eligibility>

See <Stock> in the conditions reference for the comparison shape and when it is re-checked.

Read or change the count from Lua with wm.resource_get(id) and wm.resource_adjust(id, delta), both qualified-id only (game 1.17.2 and later). A positive delta produces, a negative one consumes, and consuming more than the player holds fails as a whole rather than going negative. Types and the full signatures are in resources/scripts/definitions/wm.lua.

Produce or consume it weekly from a building’s <Flow> entries, which needs game 1.21: see the buildings reference.

Stock belonging to a pack that is no longer installed is kept in the save and comes back untouched when the pack returns, but while the pack is gone the count is invisible to conditions and to scripts. That is on purpose: a save should not lose a player’s things because a pack was moved out of the folder for an evening, and a condition should not answer questions about a resource nothing can define.