7.5 KiB
Source file format (traderx_build.py)
The source is a single YAML (or JSON – identical keys) file with four top-level sections.
Everything is optional except categories.
defaults: # global defaults
groups: # named, reusable lists of class names
items: # products that are NOT shown in any category (attachments, variants…)
categories: # what the traders sell
Class names are matched case-insensitively. Product and category ids are derived from
names automatically (AKM → prod_akm_001, Assault Rifles → cat_assault_rifles_001)
and are stable across builds as long as the name doesn't change. Set id: explicitly
to keep an id from an existing config (the reverse-importer does this for you).
defaults
| Key | Default | Meaning |
|---|---|---|
stock |
unlimited |
unlimited or an integer max stock |
coefficient |
1.0 |
Dynamic price factor; only has an effect with a finite stock |
sell_percent |
25 |
Sell price as % of buy price when sell isn't given |
buy |
full |
Item quantity on purchase – see Quantity words |
sell |
full |
Required quantity on sale |
restart |
keep |
Stock behaviour at server restart: keep / reset / random |
destock |
0 |
Fraction (0–1) of stock removed at every restart |
attachment_price |
50 |
Buy price for attachments/variants that are not defined anywhere else (auto-created hidden products) |
attachment_sell_percent |
25 |
Sell % for those auto-created products |
Every key except the two attachment_* ones can be overridden per category and per item.
Resolution order is item → category → defaults.
groups
groups:
ak_optics: [PSO1Optic, KobraOptic, SNAFU_AKKahles]
ak_muzzle: [AK_Suppressor, SNAFU_AK19Muzzel]
ak_full_kit: [ak_optics, ak_muzzle, Mag_AKM_30Rnd] # groups can contain groups
A group name can be used anywhere a list of class names is expected: attachments,
variants, preset contents. Duplicates are removed; recursion is detected.
items
Products that exist but are not listed in any category. Typical use: attachments and
variants that you price explicitly rather than relying on attachment_price.
items:
- SNAFU_AKKahles: {price: 800}
- PSO1Optic: {price: 300, sell: 60}
- AKM_Tan # all defaults, price -1 (unbuyable) – only useful as variant
categories
categories:
- name: Assault Rifles # required, shown in the trader UI
id: cat_assault_rifles_001 # optional, otherwise derived from name
traders: [Boris, 3] # givenName or npcId from TraderXGeneralSettings.json
licenses: [Weapons License] # license *names*; created if missing
visible: true # false hides the category (products still work as attachments)
icon: "" # image path for the category card
price: 1200 # default buy price for items below
stock / coefficient / sell_percent / buy / sell / restart / destock # category defaults
items: [...]
traders controls categoriesId in TraderXGeneralSettings.json. Every trader that is
named by at least one category gets its list rebuilt in source order; traders not named
anywhere are left untouched (with a warning).
Items
Three spellings are accepted:
items:
- AKM # bare class, all defaults
- AKM: {price: 1000, stock: 5} # class as key
- {class: AKM, price: 1000} # explicit key
Item options:
| Key | Meaning |
|---|---|
id |
Keep a specific product id (prod_…_NNN). |
price |
Buy price. -1 = cannot be bought. Required somewhere (item, category or price in defaults is not a thing – an item without a resolvable price is an error). |
sell |
Sell price (integer). -1 = cannot be sold. If omitted, derived from sell_percent. |
sell_percent |
Override the percentage for this item. |
stock |
unlimited or integer. |
coefficient |
Dynamic price factor (see the configuration guide, §4.2). |
buy |
Purchase quantity word. |
sell_mode |
Sale quantity word (named sell_mode because sell is the price). At category/defaults level the key is sell. |
restart, destock |
Stock behaviour at restart. |
attachments |
List of class names / group names / @compat refs. |
variants |
List of class names / groups. Variants that don't define their own attachments inherit the base item's. |
presets |
Map of preset name → attachment list (see below). |
An item may appear in several categories; the first occurrence with options defines it, later occurrences just add it to that category (a warning is printed if they carry conflicting options).
Quantity words
Used for buy (item state when purchased) and sell / sell_mode (state required when sold):
| Word | Buy | Sell |
|---|---|---|
full |
item spawns full | must be full |
empty |
spawns empty | must be empty |
any |
– | any amount accepted, paid pro-rata |
static N |
exactly N units | exactly N units |
coef 50% (or coef 0.5) |
50 % of max | 50 % of max |
The build packs these into the mod's tradeQuantity bitfield using the layout the mod's
runtime actually reads (TraderXTradeQuantity), not the one in its CSV packer, which is
inconsistent.
Presets
- AKM:
attachments: [ak_optics, ak_muzzle, Mag_AKM_30Rnd]
presets:
"CQB*": [KobraOptic, AK_Suppressor, Mag_AKM_30Rnd] # * marks the default preset
"DMR": [PSO1Optic, Mag_AKM_30Rnd]
Each item with presets produces TraderXPresets/presets_<productId>.json. Rules enforced
at build time:
- every preset attachment must be in the item's own
attachmentslist (the mod won't let players select it otherwise) – error; - exactly one preset can carry
*; if none does, the first one becomes the default; - preset ids are derived (
preset_akm_cqb_001) and stable.
Player-saved presets live in the same folder and are not touched.
@compat references
Require build --compat FILE. See compat.md.
| Ref | Expands to |
|---|---|
@compat |
every attachment the compat file lists for this weapon that is defined as a product somewhere in the source |
@compat_mags |
same, for magazines |
@compat_all |
everything compatible, auto-creating products that don't exist (rarely what you want) |
What the build checks
Errors (nothing is written):
- item without a resolvable price
- unknown quantity/restart word, out-of-range values
- preset using a class not in the weapon's attachments, or not defined at all
@compatused without--compat- trader or category reference that doesn't exist
- trader
classNamewith the wrongSurvivorM_/SurvivorF_prefix for a known survivor name - duplicate explicit ids
- with
--strict: attachment/variant class not defined anywhere
Warnings:
coefficientset while stock is unlimited (the mod ignores it)- sell price higher than buy price
- attachment not attachable according to the compat file
- item listed twice in a category; item defined twice with options
- category with no items; trader not referenced by any category
- auto-created hidden products (as notes)
Minimal complete example
defaults:
sell_percent: 30
categories:
- name: Food
traders: [Eve]
price: 50
items: [Apple, Pear, BakedBeansCan]
builds three product files, one category file and sets Eve's categoriesId.