Skip to content

Ware

A Ware is a tradable / produceable / carryable thing — the unit of cargo, inventory, production, and trade. Every Cargo entry, Trade offer, production recipe input/output, mission reward, NPC inventory item, deployable item — all of them are wares.

A ware is a dbdata type, defined in libraries/wares.xml. A ware reference is acquired by:

  • Lookup by id: ware.energycells, ware.ore, ware.inv_spaceflycaviar
  • Via a macro: $macro.ware (every macro that represents a buildable/equippable item has a back-reference)
  • Via container properties: $station.products (warelist), $ship.cargo.list (warelist)
  • Via ware lists: $container.resources.{$ware}.primary

Categories (driven by tags + boolean accessors):

  • Cargo wares (.iscargo) — products and intermediate resources. Have a .waretransport type (container / liquid / solid / condensate / passenger).
  • Inventory (.isinventory) — NPC inventory, mission deliverables. Carried by entities, not ships’ cargo.
  • Ammo (.isammo) — missiles, mines, drones for reload. Stored in ammostorage, not cargo.
  • Crafting (.iscrafting) — used in crafting recipes.
  • Deployable (.isdeployable) — satellites, nav beacons, lasertowers etc. Have an objectmacro.
  • Mods (.isweaponmod, .isshieldmod, .isenginemod, .isshipmod, .isequipmentmod, .ispaintmod, .isclothingmod) — equipment upgrades.
  • Software (.issoftware) — pilot software (scanner, dock, longrange, police).
  • Research (.isresearchable) — researchable techs.
  • Gift / Rare / Volatile — special flags.

The most-used accessors. Full list (~70) at vanilla libraries/scriptproperties.xml:1897.

PropertyTypeDescription
.idstringWare id (e.g. "energycells", "ore")
.namestringDisplay name (respects unknown-status)
.rawnamestringRaw t/0001-l044.xml text entry key
.descriptionstringDescription
.iconstringUI icon id
.tagslistWare tags (tag.economy, tag.silicon, …)
.hastag.{tag}boolHas tag
PropertyTypeDescription
.minpricemoneyMinimum allowed price
.averagepricemoneyReference price (used for value calculations)
.maxpricemoneyMaximum allowed price
.pricerangemoneyMax − Min
.volumeintVolume per unit (cargo space cost)
.waretransportwaretransportcontainer / liquid / solid / condensate / passenger
.transporttagtagTransport-type tag (used by find_station hastransport=)
PropertyTypeDescription
.resourceswareamountlistDefault recipe inputs (ware → required amount)
.raceresources.{race}wareamountlistRace-specific recipe (Argon vs Boron vs Teladi may differ)
.productswarelistWares this ware is a resource for (reverse lookup)
.group.factory.namestringDisplay name of the factory module that produces this
.group.isbuildableboolCan this group be built
PropertyTypeDescription
.containermacroContainer macro this ware uses (e.g. liquid_storage_macro)
.objectmacromacroObject macro for deployable wares (e.g. satellite’s eq_arg_satellite_02_macro)
.objectcountintHow many objects per “1 ware” (usually 1)
.videomacromacroVideo preview macro
PropertyTypeDescription
.illegalboolIllegal to some faction
.illegalto.{faction}.{null}boolIllegal to specified faction
.illegalto.{faction}.{faction}boolIllegal to faction 1, given licences held by faction 2
.buyrestriction.{faction}floatNotoriety threshold needed to buy from faction
.sellrestriction.{faction}floatNotoriety threshold needed to sell to faction
.isvolatileboolSpecial handling (hazardous)
.isdropallowedboolCan be dropped from inventory
PropertyTypeDescription
.isresearchableboolCan be researched
.research.unlockedboolPlayer has researched this
.research.precursorswarelistTech tree precursors
.research.resourceswareamountlistResources needed to research
PropertyTypeDescription
.isweaponmod / .isshieldmod / .isenginemod / .isshipmodboolPrimary ware for a mod type
.isequipmentmodboolAny of the above
.equipmentmodqualityintQuality tier
.softwareversion.base / .max / .next / .previouswareSoftware version graph
<add_inventory ware="ware.inv_spaceflycaviar" exact="99"/>

Adds to player.entity by default. To target an NPC:

<add_inventory ware="ware.inv_securitybypasssystem" exact="99"
entity="player.headquarters.defencenpc"/>

Critical: ware= must be a wareref — ware.X literal or a variable holding a wareref. A string like "$wareName" silently no-ops; money is charged but nothing is delivered.

When using a variable, the variable itself must already be a wareref:

<set_value name="$drop" exact="ware.energycells"/>
<add_inventory ware="$drop" exact="50"/> <!-- OK -->
<add_inventory ware="'energycells'" exact="50"/> <!-- BROKEN — string, not ware -->

Add ware to cargo (ship/station container)

Section titled “Add ware to cargo (ship/station container)”
<add_cargo object="$Station" ware="ware.advancedcomposites" exact="200"/>
<add_cargo object="$Station" ware="ware.advancedelectronics" exact="1300"/>

add_cargo is for container cargo, add_inventory is for NPC inventory. Different storage.

Add ware as ammo / deployables (ammostorage)

Section titled “Add ware as ammo / deployables (ammostorage)”
<add_ammo object="player.ship"
macro="macro.eq_arg_satellite_02_macro"
amount="1"/>

For deployables, missiles, mines, drones, lasertowers — these go in ammostorage.{macro}, not in cargo or inventory. add_inventory ware= will silently fail.

Use $ware.objectmacro to bridge ware → ammomacro:

<add_ammo object="$Ship"
macro="$ware.objectmacro"
amount="$Amount"/>
<remove_inventory ware="ware.inv_spaceflycaviar" exact="50"/>
<transfer_inventory from="$Source" to="$Target"
ware="ware.inv_securityslicer" exact="10"/>

Add ware to a station’s production / build list (less common)

Section titled “Add ware to a station’s production / build list (less common)”
<set_ship_wares_included container="$Wharf"
wares="[ware.ship_arg_m_corvette_01_a]"/>

set_equipment_wares_* and set_ship_wares_* (absolute / included / excluded) let modders extend or restrict what a station can build.

Ware itself is a passive data type — most “ware operations” live on the Container (cargo, prices, supply) or in higher-level libraries. Ware-specific helpers in lib_generic.xml are sparse:

LibraryPurposeSource line
md.LIB_Generic.Add_Wares_For_ModuleAdd the production wares of a module to a station’s list5089
md.LIB_Generic.FindShipMacroForCargoPick a ship macro that can carry given ware1427

For per-ware reasoning (price queries, quantity availability, recipe lookup), use container accessors ($station.cargo.{$ware}.amount, $container.buyprice.{$ware}, $ware.resources.list) rather than libraries.

Ware-related events are container-side (trade) or entity-side (inventory). There is no event_ware_* family.

EventWhenNotes
event_trade_completedA trade finished (cargo moved + money moved)Attrs: seller=, buyer=, tradeoffer=. Use tradeoffer=$X to track a specific trade offer
event_trade_startedA trade was initiated (cargo may not yet have moved)Use this when you want to detect intent, not completion
event_player_trade_completedPlayer-side wrapper of trade_completedPlayer-only convenience
event_object_changed_trade_subscriptionContainer’s subscription list changedUsed by trade UI
  • add_inventory ware="$string" silently no-ops — money is charged, ware is not delivered. Must be ware.{$string} to resolve to a wareref. Same applies to add_cargo, transfer_inventory.
  • DeployObjectAtPosition reads ammostorage.{macro}, not inventory. For player deployables, use add_ammo macro= not add_inventory ware=. Memorable mistake: 48 errors / 2 hours before realising.
  • $ware.resources returns a wareamountlist that DEGRADES when stored in a variable. Access .resources.list inline every time:
    <do_for_each name="$res" in="$ware.resources.list"> <!-- OK every iteration -->
    Storing <set_value name="$res" exact="$ware.resources"/> and using $res.list later silently returns null.
  • Module recipes via $Mod.macro.ware.resources, NOT $Mod.products.list.{1}.resources. The latter returns null silently because .products.list items are not full ware-refs.
  • sellprice/buyprice in debug logs are × 100. Internal representation is 1/100-credit integer. A log line sellprice=1000000 means 10 000 Cr. Same for .money.
  • Ware uses .name, NOT .knownname. Wares don’t have unknown-status the way components do; .knownname returns null. For display use .name.
  • Price math: pre-divide by 100 before multiplying. Chained (pct × count × price) can overflow int32 to negative when intermediate exceeds 2^31. Vanilla pattern: (pct * price) / 100 first, then * count.
  • Race-specific recipes: Boron, Terran, Khaak may have different production recipes for the same ware. Use $ware.raceresources.{$race} if your script cares about who is producing.

Example 1: Compute the total value of a ship’s loadout

Section titled “Example 1: Compute the total value of a ship’s loadout”
<set_value name="$ShipValue"
exact="$ship.macro.ware.averageprice"/>
<do_for_each name="$missile" in="$ship.cargo.list">
<set_value name="$ShipValue"
operation="add"
exact="$missile.ware.averageprice * $ship.cargo.{$missile}.amount"/>
</do_for_each>
<write_to_logbook
text="$ship.knownname + ' is worth ' + $ShipValue"/>

Pattern from vanilla lib_generic.xml:464.

Example 2: Reward the player with mission ware

Section titled “Example 2: Reward the player with mission ware”
<add_inventory
ware="ware.inv_securitybypasssystem"
exact="3"
entity="player.entity"/>
<write_to_logbook
text="'Received: 3 × ' + ware.inv_securitybypasssystem.name"/>

Example 3: Deploy 4 satellites for the player

Section titled “Example 3: Deploy 4 satellites for the player”
<add_ammo object="player.ship"
macro="macro.eq_arg_satellite_02_macro"
amount="4"/>
<write_to_logbook
text="'Added 4 advanced satellites to ' + player.ship.knownname"/>

For the ware-side accessor: ware.eq_arg_satellite_02.objectmacro returns the deployable macro.

<do_for_each name="$res" in="ware.advancedelectronics.resources.list">
<write_to_logbook
text="$res.name + ': ' + ware.advancedelectronics.resources.{$res}"/>
</do_for_each>

Use ware.X.resources.list inline every iteration — do not store .resources into a variable.

  • How faction economies decide what to produce, build, buy: Architectural overview Faction economy — per-sector shortage formula reads ware demand vs supply, picks corrective action.
  • Trade offer lifecycle: Architectural overview Trade offer lifecycle — buy/sell offer creation, event_trade_startedevent_trade_completed, partial deliveries.
  • Workforce wares: Architectural overview Workforceworkforce.resources per race, consumption rates, bonus formula.
  • Research tree: Architectural overview Researchresearch.precursors, research.resources, unlock cascade.
  • Cargo — container of wares.
  • Trade offer — what offers wares.
  • Subscription — trade-offer subscription mechanism.
  • Macro — how wares map to objects (data layer).
  • Faction — owner of stations producing wares, source of buy/sell restrictions.
  • Container — abstract carrier of wares (station, ship, buildstorage).