TraderX_Tools/docs/source-format.md
2026-09-06 22:47:27 +03:00

7.5 KiB
Raw Permalink Blame History

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 attachments list (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
  • @compat used without --compat
  • trader or category reference that doesn't exist
  • trader className with the wrong SurvivorM_/SurvivorF_ prefix for a known survivor name
  • duplicate explicit ids
  • with --strict: attachment/variant class not defined anywhere

Warnings:

  • coefficient set 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.