# Data dictionary

Generated by `pnpm apply` from the schemas and the data. Do not edit. Game build 25677108.

## Conventions

- **Units.** Distances are meters, speeds meters per second, mass kilograms, angles degrees, time seconds. The game stores centimeters; the single conversion is divide by 100, applied when the data is built. Files with a `units` field say so; fields with a unit in their name (`massKg`, `diameterMm`, `max_speed_kmh`) keep it.
- **Ids.** Item and vehicle ids are the game's own tags (`Id.Item.AK74M`, `Vehicle.Variant.Air.Rotary.Havoc.Default`). The game compares tags without regard to case, and its own data is not consistent (`Id.Item.SKSBarrel` and `ID.Item.SKSBarrel` both occur), so compare ids case-insensitively. Every other file refers to items by these ids.
- **Coordinates.** One system per world: X and Y on the ground, Z up, in meters. A map image pixel is `(world - bounds.min) / metersPerPixel`, and image rows increase with world Y. Each world has its own `bounds`, and the terrain heightmap has its own bounds and `zRange`, so use each file's own values.
- **Versions.** Every file records the Steam `gameBuild` it came from and a `schemaVersion`. A game update shows up as a diff of these files.
- **Developer items.** The game ships a few items for development (test and debug). They stay in the data, flagged `developer: true` in `items.json`; join on that flag to leave them out of weapons, ammunition and other files that refer to items.
- **Absent fields.** An optional field that is not in a record means the game does not define it. It is never filled with a default.
- **Generated.** Everything under `data/` is written by `pnpm apply`; do not edit it by hand. `pnpm verify` checks every file against `MANIFEST.json`.

## Completeness

How much of the game each part of the data covers, and what is missing or uncertain.

| Area | Status | Files | Missing or uncertain |
| --- | --- | --- | --- |
| Items, prices, unlocks, icons | Complete | `items.json` | Some items have no icon because the game has no UI entry for them. The default stack size is the engine default, inferred from items with known stacks. |
| Weapons, ammunition, attachments | Complete | `weapons.json`<br>`ammo.json`<br>`attachments.json` | As stored in the game files. |
| Armor and equipment | Complete | `equipment.json` | - |
| Damage model | Complete | `damage.json` | Hit locations, ammo types, armor and vehicle damage rules. |
| Vehicles | Partial | `vehicles.json`<br>`vehicle-configs.json` | The hull mass of tracked vehicles is not in the game files, only the track and sprocket masses. |
| Buildable structures | Complete | `buildables.json` | - |
| Cosmetics | Complete | `cosmetics.json` | - |
| Loot | Partial | `loot.json` | Loot tables are complete. Spawn positions are created at runtime and are not in the game files. |
| Player movement | Partial | `movement.json` | Multipliers and rules are complete. The base walk and sprint speed, stamina pool and sprint cost are engine defaults and are not in the game files. |
| Role skills | Partial | `skills.json` | Every skill has its text and almost every skill its tree position, but fewer than half have per-level effects in the game files. Point costs and prerequisites are held by the server. |
| Role levels | Partial | `roles.json` | XP for each role level. The overall career level has no table; the game says all role levels combine into it, without a formula. |
| Event rewards | Partial | `challenge-rewards.json`<br>`rewards.json` | The game's own formulas for cash and role XP. The server can override them, and the two tables disagree on some numbers (for example kill cash), without saying which is live. |
| Meta game | Partial | `meta.json` | Currencies, the gold market, passive missions and achievements. Season definitions and gold bar exchange rates are empty in the game files. |
| Maps | Partial | `maps/<world>/map.json`<br>`maps/<world>/terrain.json`<br>`maps/<world>/buildings.json`<br>`maps/<world>/objectives.json`<br>`maps/<world>/objects.json` | Metadata, terrain (about 2 m, the native resolution), building boxes, objectives and placed gameplay objects. Towers and industrial buildings are art only, so their placement is not available. |
| Live server values | Not in the game files | - | Anything the server decides or overrides, the server list and player counts. The data is what the game files hold for one build. |

## Files

| Data | Files | JSON Schema | CSV |
| --- | --- | --- | --- |
| Items and vehicles | `data/items.json` | `data/schema/items.schema.json` | `data/csv/items.csv`<br>`data/csv/prices.csv` |
| Ammunition ballistics | `data/ammo.json` | `data/schema/ammo.schema.json` | `data/csv/ammo.csv` |
| Weapons | `data/weapons.json` | `data/schema/weapons.schema.json` | `data/csv/weapon-compatibility.csv`<br>`data/csv/weapon-damage.csv`<br>`data/csv/weapon-slots.csv`<br>`data/csv/weapons.csv` |
| Attachments | `data/attachments.json` | `data/schema/attachments.schema.json` | `data/csv/attachment-modifiers.csv`<br>`data/csv/attachments.csv` |
| Equipment | `data/equipment.json` | `data/schema/equipment.schema.json` | `data/csv/armor.csv`<br>`data/csv/equipment-modifiers.csv`<br>`data/csv/weight-classes.csv` |
| Buildables | `data/buildables.json` | `data/schema/buildables.schema.json` | `data/csv/buildables.csv` |
| Tag text | `data/tags.json` | `data/schema/tags.schema.json` | `data/csv/tags.csv` |
| Cosmetics | `data/cosmetics.json` | `data/schema/cosmetics.schema.json` | `data/csv/cosmetics.csv` |
| Loot tables | `data/loot.json` | `data/schema/loot.schema.json` | `data/csv/loot-items.csv`<br>`data/csv/loot-tables.csv` |
| Player movement | `data/movement.json` | `data/schema/movement.schema.json` | - |
| Role skills | `data/skills.json` | `data/schema/skills.schema.json` | `data/csv/skill-levels.csv`<br>`data/csv/skills.csv` |
| Challenge rewards | `data/challenge-rewards.json` | `data/schema/challenge-rewards.schema.json` | `data/csv/challenge-reward-events.csv`<br>`data/csv/challenge-reward-variables.csv`<br>`data/csv/challenge-rewards.csv`<br>`data/csv/reward-curve-points.csv` |
| Meta game | `data/meta.json` | `data/schema/meta.schema.json` | `data/csv/achievements.csv`<br>`data/csv/gold-market.csv`<br>`data/csv/passive-missions.csv` |
| Role levels | `data/roles.json` | `data/schema/roles.schema.json` | `data/csv/role-levels.csv` |
| Cash rewards | `data/rewards.json` | `data/schema/rewards.schema.json` | `data/csv/reward-curve-points.csv`<br>`data/csv/reward-modifiers.csv`<br>`data/csv/rewards.csv` |
| Damage model | `data/damage.json` | `data/schema/damage.schema.json` | `data/csv/damage-rules.csv`<br>`data/csv/hit-location-multipliers.csv` |
| Vehicle stats | `data/vehicles.json` | `data/schema/vehicles.schema.json` | `data/csv/vehicles.csv` |
| Vehicle configs | `data/vehicle-configs.json` | `data/schema/vehicle-configs.schema.json` | - |
| Map metadata | `data/maps/europe/map.json`<br>`data/maps/kavkazi/map.json`<br>`data/maps/north-america/map.json` | `data/schema/map.schema.json` | - |
| Terrain heightmap metadata | `data/maps/europe/terrain.json`<br>`data/maps/kavkazi/terrain.json`<br>`data/maps/north-america/terrain.json` | `data/schema/terrain.schema.json` | - |
| Match objectives | `data/maps/europe/objectives.json`<br>`data/maps/kavkazi/objectives.json`<br>`data/maps/north-america/objectives.json` | `data/schema/objectives.schema.json` | `data/csv/control-zones.csv` |
| Placed gameplay objects | `data/maps/europe/objects.json`<br>`data/maps/kavkazi/objects.json`<br>`data/maps/north-america/objects.json` | `data/schema/objects.schema.json` | `data/csv/objects-europe.csv`<br>`data/csv/objects-kavkazi.csv`<br>`data/csv/objects-north-america.csv` |
| Buildings | `data/maps/europe/buildings.json`<br>`data/maps/kavkazi/buildings.json`<br>`data/maps/north-america/buildings.json` | `data/schema/buildings.schema.json` | `data/csv/buildings-europe.csv`<br>`data/csv/buildings-kavkazi.csv`<br>`data/csv/buildings-north-america.csv` |
| Building footprints (GeoJSON, same buildings as the box files; `height` and `baseZ` in meters) | `data/maps/europe/buildings.geojson`<br>`data/maps/kavkazi/buildings.geojson`<br>`data/maps/north-america/buildings.geojson` | - | - |

## Items and vehicles

Files: `data/items.json`.

Every item and vehicle: names, tooltip text, icon, inventory size, stacking, vendor prices and unlock requirements.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `items` | list of object | yes | One entry per item and vehicle definition, sorted by id. |
| `items[].id` | string | yes | Stable identifier from the game. Forms seen: `Id.Item.*`, `ID.Item.*` and `Vehicle.*`. |
| `items[].kind` | "item" \| "vehicle" | yes | `vehicle` for ids starting with `Vehicle.`, otherwise `item`. |
| `items[].asset` | string | yes | Path of the item definition inside the game files. |
| `items[].name` | string | yes | Display name: the definition's own name, else the one in the UI tables, else the id. |
| `items[].subtitle` | string | no | Short category line shown under the name in tooltips, such as "Assault Rifle" or "Truck". |
| `items[].description` | string | no | Short tooltip text (a one-line summary or a few stat bullets, joined with newlines). |
| `items[].icon` | string | no | The icon the game shows for this item in the inventory and the shop, as a PNG path relative to the release's `icons/` folder. Several items can share one icon. Absent for parts with no icon in the game (built-in barrels and stocks, vehicle turrets, storage). |
| `items[].developer` | true | no | True for items the game ships for development (test and debug items) that players cannot get. Join on this to leave them out of weapons, ammunition and other files that refer to items. |
| `items[].tags` | list of string | yes | The item's context tags, which describe what it is and where it can go (`Item.Attachment.Muzzle`, `Inventory.Slot.Primary`). |
| `items[].grid` | [integer, integer] | yes | Inventory footprint in cells: [width, height]. |
| `items[].maxStack` | integer | yes | Max units per inventory cell (1 when the item is not stackable). |
| `items[].weight` | number | no | Weight as stored by the game. |
| `items[].durability` | number | no | Durability as stored by the game, for items that wear. |
| `items[].unlock` | object or null | yes | Null when the item is available without unlocking (or is not part of a tree). |
| `items[].unlock.role` | string | yes | Progression tree: Infantry, Support, Medic, Recon, Pilot, Driver, or Wardog (the account-wide career level). |
| `items[].unlock.level` | integer | yes | Minimum level in that tree. |
| `items[].unlock.cost` | number | yes | Cash cost to unlock. |
| `items[].vendor` | list of object | yes | Ways to buy the item. Empty when no shop sells it. |
| `items[].vendor[].tag` | string | yes | Vendor variation tag. Equals the item id for the base item; variants append a suffix. |
| `items[].vendor[].price` | number | yes | Price of one purchase, in the game's cash. |
| `items[].vendor[].amount` | integer | yes | Units sold per purchase at `price` (ammo is sold in lots). |
| `items[].vendor[].categories` | list of string | yes | Vendor categories the entry is listed under, for example `Vendor.Category.Attachment`. |

## Ammunition ballistics

Files: `data/ammo.json`.

Ammunition ballistics: damage, size, drag, penetration and explosive data per projectile, with the ammo items that fire each one.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. Speeds are meters per second. |
| `projectiles` | list of object | yes | One entry per projectile definition, sorted by id. |
| `projectiles[].id` | string | yes | Projectile id from the game, for example `Item.Caliber.556mm`. |
| `projectiles[].asset` | string | yes | Path of the projectile data asset inside the game files. |
| `projectiles[].damage` | number | yes | Damage of one hit before distance falloff, armor and hit location. |
| `projectiles[].damageType` | string | no | Damage type tag, for example `Meta.Damage.Bullet.556mm`. |
| `projectiles[].damageContext` | list of string | yes | Extra damage context tags, for example the body parts the type is tuned for. |
| `projectiles[].massKg` | number | no | Projectile mass in kilograms. |
| `projectiles[].diameterMm` | number | no | Projectile diameter in millimeters. |
| `projectiles[].lengthMm` | number | no | Projectile length in millimeters. |
| `projectiles[].drag` | object | no | Aerodynamic drag: the coefficient and, when the game names one, the drag model it comes from (such as G7). |
| `projectiles[].drag.coefficient` | number | no | Drag coefficient. |
| `projectiles[].drag.model` | string | no | Name of the drag model (a row of the game's drag table), for example `G7 (Boat Tail)`. |
| `projectiles[].typicalSpeed` | number | no | The speed the game treats as typical for the projectile. Weapons set their own muzzle velocity. |
| `projectiles[].penetration` | object | no | How the projectile behaves against surfaces. Absent when the game defines nothing. |
| `projectiles[].penetration.penetrates` | boolean | no | False when the projectile never passes through surfaces. Absent when the game does not say. |
| `projectiles[].penetration.penetratesThinSurfaces` | boolean | no | True when the projectile always passes through thin surfaces. |
| `projectiles[].penetration.exitSpeedMultiplier` | number | no | Fraction of the speed kept after passing through a surface. |
| `projectiles[].penetration.effectivenessMultiplier` | number | no | Multiplier on how well the projectile penetrates, as stored. |
| `projectiles[].penetration.ricochetMinAngle` | number | no | Impact angle in degrees above which the projectile ricochets. |
| `projectiles[].explosive` | object | no | Area damage. Absent for projectiles that do none. |
| `projectiles[].explosive.radius` | number | no | Distance at which damage has fallen to its minimum. |
| `projectiles[].explosive.effectiveRadius` | number | no | Distance within which full damage applies. |
| `projectiles[].explosive.falloff` | number | no | How fast explosive damage falls with distance, as stored. |
| `projectiles[].explosive.minimumDamage` | number | no | Least damage inside the radius. |
| `projectiles[].explosive.bluntDamage` | number | no | Blunt (non-penetrating) damage of the explosion. |
| `projectiles[].suppression` | number | no | Suppression a near miss causes. |
| `projectiles[].propulsion` | object | no | Set for rockets and missiles that keep accelerating or steer after launch. |
| `projectiles[].propulsion.thrustSpeed` | number | no | Speed in meters per second the motor accelerates the projectile to. |
| `projectiles[].propulsion.fuel` | number | no | Motor fuel, as stored. |
| `projectiles[].propulsion.guided` | boolean | no | True when the projectile steers after launch. |
| `projectiles[].items` | list of string | yes | Ammo items (ids from items.json) that fire this projectile. |

## Weapons

Files: `data/weapons.json`.

Weapon statistics (fire rate, ballistics, recoil, accuracy) and the attachment slots of each weapon. Weapon ids are item ids from items.json.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. Speeds are meters per second. |
| `weapons` | list of object | yes | One entry per weapon, sorted by item id. |
| `weapons[].id` | string | yes | Item id from items.json. |
| `weapons[].name` | string | no | Display name, as in items.json (the game's UI table). Absent when the game has none. |
| `weapons[].asset` | string | yes | Path of the weapon stats asset inside the game files. |
| `weapons[].fireModes` | list of string | yes | Fire modes: `Automatic`, `SemiAutomatic`, `Burst`. |
| `weapons[].rpm` | number | no | Rounds per minute. |
| `weapons[].roundsPerBurst` | integer | no | Rounds fired per burst. |
| `weapons[].calibers` | list of string | yes | Calibers the weapon fires (the game's `Item.Caliber.*` tags without the prefix). |
| `weapons[].muzzleVelocity` | number | no | Muzzle velocity in meters per second. |
| `weapons[].effectiveRange` | number | no | Range in meters the game tunes the weapon for. |
| `weapons[].damageFalloff` | list of object | no | Damage multiplier by distance. Between points the game interpolates as each point's `interpolation` says (linear when absent), and holds the first value before the first point and the last after the last. |
| `weapons[].damageFalloff[].distance` | number | yes | Distance in meters. |
| `weapons[].damageFalloff[].multiplier` | number | yes | Damage multiplier at that distance (1 is full damage). |
| `weapons[].damageFalloff[].interpolation` | "Cubic" \| "Constant" | no | How the game interpolates from this point to the next, when it is not linear. Absent means linear. A cubic segment follows the game's own tangents, which are not published, so treat it as a smooth curve between the two points. |
| `weapons[].accuracy` | number | no | Accuracy rating as stored. Larger values go with looser weapons in the data (SV98 0.56, AK74M 0.825, M500 1.5, RPG-7 3.0), so compare weapons of one class. |
| `weapons[].randomDeviation` | number | no | Random aim deviation in degrees. |
| `weapons[].adsTime` | number | no | Seconds to aim down sights through iron sights. |
| `weapons[].zeroing` | object | no | Sight zeroing range in meters. Absent for weapons without zeroing. |
| `weapons[].zeroing.min` | number | no | Shortest zeroing distance. |
| `weapons[].zeroing.max` | number | no | Longest zeroing distance. |
| `weapons[].zeroing.step` | number | no | Distance between zeroing settings. |
| `weapons[].meleeDamage` | number | no | Damage of a melee hit. |
| `weapons[].suppressionMultiplier` | number | no | Multiplier on the suppression the weapon causes. |
| `weapons[].windupTime` | number | no | Seconds between pulling the trigger and the first shot, for weapons that spin up. |
| `weapons[].recoil` | object | no | Recoil. Absent for weapons the game gives no pattern. |
| `weapons[].recoil.pattern` | list of object | yes | The game's `RecoilPattern`: one x and y pair per shot, as stored. In the data x is sideways and y is upward for nearly every shot (a few shots of two weapons pull slightly down); the game gives no unit. |
| `weapons[].recoil.pattern[].x` | number | yes | Sideways kick of this shot. |
| `weapons[].recoil.pattern[].y` | number | yes | Upward kick of this shot. |
| `weapons[].recoil.patternResetTime` | number | no | Seconds without firing before the pattern restarts. |
| `weapons[].recoil.viewKickMultiplier` | number | no | Multiplier on the camera kick. |
| `weapons[].recoil.afterPatternPitch` | [number, number] | no | Random extra upward kick once the pattern has ended, [min, max], as stored (the game's `PostPatternRandomPitchRecoil`). |
| `weapons[].recoil.afterPatternYaw` | [number, number] | no | Random extra sideways kick once the pattern has ended, [min, max], as stored (the game's `PostPatternRandomYawRecoil`). |
| `weapons[].shotgun` | object | no | Spread of a shotgun's pellets. Absent for other weapons. |
| `weapons[].shotgun.chokeFactor` | number | no | Choke, as stored (higher tightens the spread). |
| `weapons[].shotgun.outerConeHalfAngle` | number | no | Half angle of the outer spread cone, in degrees. |
| `weapons[].shotgun.innerConeMultiplier` | number | no | Inner cone size as a multiple of the outer cone. |
| `weapons[].shotgun.randomConeHalfAngleRange` | [number, number] | no | Random extra half angle added to the cone: [min, max] in degrees. |
| `weapons[].slots` | list of object | yes | Attachment slots from the weapon's item definition. |
| `weapons[].slots[].slot` | string | yes | Slot type, for example `Sight` or `Magazine` (the game's `Item.Attachment.*` tag without its prefix). |
| `weapons[].slots[].items` | list of string | yes | Items accepted by name. |
| `weapons[].slots[].contexts` | list of string | yes | Item context tags accepted: anything carrying one of these tags fits. |
| `weapons[].slots[].filter` | string | yes | The game's filter mode: `AllowList` accepts only the listed items and contexts, `BlockPriority` accepts all except what is blocked. |
| `weapons[].slots[].blockedItems` | list of string | yes | Items refused by name. |
| `weapons[].slots[].blockedContexts` | list of string | yes | Context tags refused. |
| `weapons[].slots[].default` | string | no | Item the weapon starts with in this slot. |
| `weapons[].slots[].hidden` | boolean | yes | Slot is not shown to players (chamber, built-in parts). |

## Attachments

Files: `data/attachments.json`.

Weapon attachments: the attribute changes each one makes, and capacity and calibers for magazines. Ids are item ids from items.json.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `attachments` | list of object | yes | One entry per attachment item, sorted by item id. |
| `attachments[].id` | string | yes | Item id from items.json. |
| `attachments[].name` | string | no | Display name, as in items.json (the game's UI table). Absent when the game has none. |
| `attachments[].type` | string | yes | Attachment type, for example `Magazine`, `Muzzle`, `Sight` (the game's `Item.Attachment.*` tag). |
| `attachments[].contexts` | list of string | yes | Item context tags, which weapon slots match against. |
| `attachments[].modifiers` | list of object | yes | Changes applied to the weapon while the attachment is fitted. |
| `attachments[].modifiers[].attribute` | string | yes | Attribute, for example `Weapon.AimTime` (the game's `Attribute.Gameplay.*` tag without the prefix). |
| `attachments[].modifiers[].op` | "multiplyCompound" \| "multiply" \| "add" \| "override" | yes | How the value combines: `multiplyCompound` and `multiply` scale the attribute (1.1 is +10%), `add` adds, `override` replaces. Several `multiplyCompound` modifiers multiply together. |
| `attachments[].modifiers[].value` | number | yes | The number applied. For `multiply` and `multiplyCompound`, 1.1 means +10%. |
| `attachments[].characterModifiers` | list of object | yes | Changes applied to the character carrying the weapon, such as sway. |
| `attachments[].characterModifiers[].attribute` | string | yes | Attribute, for example `Weapon.AimTime` (the game's `Attribute.Gameplay.*` tag without the prefix). |
| `attachments[].characterModifiers[].op` | "multiplyCompound" \| "multiply" \| "add" \| "override" | yes | How the value combines: `multiplyCompound` and `multiply` scale the attribute (1.1 is +10%), `add` adds, `override` replaces. Several `multiplyCompound` modifiers multiply together. |
| `attachments[].characterModifiers[].value` | number | yes | The number applied. For `multiply` and `multiplyCompound`, 1.1 means +10%. |
| `attachments[].magazine` | object | no | Magazines: how many rounds fit, and which calibers. |
| `attachments[].magazine.capacity` | integer | yes | Rounds the magazine holds. |
| `attachments[].magazine.calibers` | list of string | yes | Calibers the magazine takes (the game's `Item.Caliber.*` tags without the prefix). |

## Equipment

Files: `data/equipment.json`.

Worn protection and the effect of carried weight.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `armor` | list of object | yes | Armor and helmets, sorted by item id. |
| `armor[].id` | string | yes | Item id from items.json. |
| `armor[].name` | string | no | Display name, as in items.json (the game's UI table). Absent when the game has none. |
| `armor[].slot` | string | yes | Equipment slot: `Armor` (body) or `Helmet`. |
| `armor[].damageContext` | string | yes | The target tag damage rules use for this piece, such as `Armor.Heavy` or `Helmet.SuperHeavy` (see `target` in damage.json). The `Meta.Damage.` prefix is dropped. |
| `armor[].coveredLocations` | list of string | yes | Body parts the piece protects, such as `Torso.Upper` or `Head`. |
| `armor[].durability` | number | no | Hit points of the armor before it is spent. |
| `armor[].stages` | list of object | yes | How protection changes as the armor wears down, from new to nearly spent. |
| `armor[].stages[].damageReduction` | number | yes | Percent of damage the armor absorbs at this stage. |
| `armor[].stages[].thickness` | number | yes | Plate thickness at this stage, as stored. |
| `armor[].stages[].density` | number | yes | Plate density at this stage, as stored. |
| `armor[].modifiers` | list of object | yes | Changes the piece makes to the wearer's attributes (speed, stamina and so on). Plain numbers only. |
| `armor[].modifiers[].attribute` | string | yes | Attribute, for example `Weapon.AimTime` (the game's `Attribute.Gameplay.*` tag without the prefix). |
| `armor[].modifiers[].op` | "multiplyCompound" \| "multiply" \| "add" \| "override" | yes | How the value combines: `multiplyCompound` and `multiply` scale the attribute (1.1 is +10%), `add` adds, `override` replaces. Several `multiplyCompound` modifiers multiply together. |
| `armor[].modifiers[].value` | number | yes | The number applied. For `multiply` and `multiplyCompound`, 1.1 means +10%. |
| `weightClasses` | list of object | yes | Carried-weight tiers, lightest first. Item weights are in items.json. |
| `weightClasses[].name` | string | yes | Weight class: `Lightest`, `Light`, `Medium`, `Heavy`, `SuperHeavy`. |
| `weightClasses[].minWeightKg` | number | yes | Carried weight in kilograms from which the class applies. |
| `weightClasses[].modifiers` | list of object | yes | Changes to the player while in this class (speed, jump, stamina regeneration, aim sway, aim time). |
| `weightClasses[].modifiers[].attribute` | string | yes | Attribute, for example `Weapon.AimTime` (the game's `Attribute.Gameplay.*` tag without the prefix). |
| `weightClasses[].modifiers[].op` | "multiplyCompound" \| "multiply" \| "add" \| "override" | yes | How the value combines: `multiplyCompound` and `multiply` scale the attribute (1.1 is +10%), `add` adds, `override` replaces. Several `multiplyCompound` modifiers multiply together. |
| `weightClasses[].modifiers[].value` | number | yes | The number applied. For `multiply` and `multiplyCompound`, 1.1 means +10%. |

## Buildables

Files: `data/buildables.json`.

Structures players can build (fortifications, FOB parts, stations): cost, health, size, where they can be placed and how they take damage.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. |
| `buildables` | list of object | yes | Buildables, sorted by id. |
| `buildables[].id` | string | yes | The game's buildable id, for example `Id.Buildable.Bunker`. |
| `buildables[].name` | string | no | Display name. |
| `buildables[].icon` | string | no | Path of the buildable's icon inside `assets/icons/` (the same folder as the item icons). Absent when the game has no icon for it. |
| `buildables[].cost` | number | yes | Building supplies it costs to place. |
| `buildables[].maxHealth` | number | yes | Hit points when fully built. |
| `buildables[].repairSpeedMultiplier` | number | no | How fast it repairs compared with the standard rate, when the game states one. |
| `buildables[].maxStack` | integer | no | How many can be carried or placed as a stack, when the game states one. |
| `buildables[].damageEntity` | string | no | The `entity` of its rules in damage.json, such as `Buildable.Bunker`. |
| `buildables[].size` | [number, number, number] | no | Size of the finished stage's bounding box as the game stores it: [x, y, z] in meters. Structures built in several pieces (a bunker with a floor and a roof) have a separate entry per piece. |
| `buildables[].tools` | list of string | yes | Build tools that offer it (`SmallHammer`, `MediumHammer`, `LargeHammer`). |
| `buildables[].placementRules` | list of string | yes | Names of the placement conditions the game checks, such as `WithinFobBounds` or `SafeZone` (no building in a safe zone). |

## Tag text

Files: `data/tags.json`.

Display text for the game's gameplay tags, to turn tags such as `Item.Archetype.AR` into words. Only tags with text are listed.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `tags` | list of object | yes | Tags with text, sorted by tag then source. A tag can appear under more than one source with different text. |
| `tags[].tag` | string | yes | The game's gameplay tag, as it appears in the other files (item tags, weapon archetypes, calibers, damage types, roles, slots). |
| `tags[].text` | string | yes | The text the game shows for the tag. |
| `tags[].source` | string | yes | The game's table the text comes from, for example `Archetypes`, `Calibers` or `Roles`. |

## Cosmetics

Files: `data/cosmetics.json`.

The cosmetic catalog: skin sets and what each cosmetic applies to. Prices and availability are not in the game files read.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `sets` | list of object | yes | Named sets, in collection order. |
| `sets[].id` | string | yes | Set id, as used by `set` in a cosmetic. |
| `sets[].name` | string | yes | Display name. |
| `sets[].sortIndex` | integer | yes | Order in the collection screen. |
| `sets[].hidden` | boolean | yes | True when the set is hidden in the collection screen. |
| `cosmetics` | list of object | yes | Cosmetics, sorted by id. |
| `cosmetics[].id` | string | yes | Cosmetic id: the game's tag without its `Meta.Cosmetic.` prefix, for example `BlackAndGold.AK74`. |
| `cosmetics[].item` | string | yes | What it applies to: an item id from items.json, or an emote id (`Id.Emote.*`), or a vehicle variant for taxi liveries. |
| `cosmetics[].set` | string | yes | The cosmetic set or category it belongs to (`BlackAndGold`, `Emote`, `FactionLogo`, `Taxi`). |
| `cosmetics[].archetype` | string | no | Weapon archetype it is for, such as `AR` or `Pistol`. Absent for emotes. |
| `cosmetics[].source` | string | yes | The game's table the cosmetic was read from, for example `Season01_Skins`. |

## Loot tables

Files: `data/loot.json`.

What spawns as loot (in towers and other lootables): items, amounts, weights and respawn rules.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `tables` | list of object | yes | Loot tables, sorted by id. |
| `tables[].id` | string | yes | Loot table id: the game's tag without its `Lootable.` prefix, such as `Tower` or `AbandonedTower`. |
| `tables[].spawnChance` | number | yes | Percent chance the loot spawns. |
| `tables[].spawnByDefault` | boolean | no | True when it spawns at the start of a match. |
| `tables[].spawnByPoints` | boolean | no | True when spawning is paced by spawn points. |
| `tables[].initialSpawnTime` | number | no | Seconds into the match before the first spawn. |
| `tables[].initialSpawnPoints` | number | no | Spawn points available at the start. |
| `tables[].canRespawn` | boolean | no | True when the loot comes back after it is taken. |
| `tables[].respawnTime` | number | no | Seconds until it respawns, as stored. |
| `tables[].neverSelectPreviousItem` | boolean | no | True when a respawn never repeats the previous item. |
| `tables[].spawnInsideControlZoneOnly` | boolean | no | True when it only spawns inside the control zone. |
| `tables[].items` | list of object | yes | What can spawn. |
| `tables[].items[].item` | string | yes | Item id from items.json. |
| `tables[].items[].amount` | integer | yes | Units spawned. |
| `tables[].items[].weight` | number | yes | Relative chance this entry is picked among the table's entries. |
| `tables[].items[].subItems` | list of object | yes | Items that spawn together with this one (attachments, magazines, grenades). |
| `tables[].items[].subItems[].item` | string | yes | Item id from items.json. |
| `tables[].items[].subItems[].chance` | number | yes | Percent chance it spawns with the main item. |
| `tables[].items[].subItems[].amount` | integer | yes | Units spawned. |

## Player movement

Files: `data/movement.json`.

How the player moves: stance sizes and speeds, jumping, falling and fall damage, ladders, body dragging, stamina regeneration and the traversal moves. The base top speed is not in the client files (the data holds only multipliers of it), so speeds are given as multipliers.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. Speeds are meters per second. |
| `stances` | list of object | yes | Stand, crouch and prone, in that order. |
| `stances[].name` | string | yes | `Stand`, `Crouch` or `Prone`. |
| `stances[].capsuleHalfHeight` | number | yes | Half the height of the player's collision capsule, in meters. |
| `stances[].capsuleRadius` | number | yes | Radius of the player's collision capsule, in meters. |
| `stances[].eyeHeight` | number | yes | Height of the camera above the ground, in meters. |
| `stances[].staminaCost` | number | yes | Stamina it costs to change into this stance, as stored. |
| `stances[].maxSpeedMultiplier` | number | no | Multiplier on the player's top speed while in this stance. Absent when the game gives the stance no explicit multiplier. |
| `stanceTransitions` | list of object | yes | How long each stance change takes. |
| `stanceTransitions[].from` | string | yes | Stance changed from. |
| `stanceTransitions[].to` | string | yes | Stance changed to. |
| `stanceTransitions[].seconds` | number | yes | How long the change takes. |
| `ground` | object | yes | Walking and running. |
| `ground.minSpeed` | number | no | The game's `MinSpeed`, in meters per second. |
| `ground.backMaxSpeedScale` | number | no | Multiplier on top speed when moving backward. |
| `ground.strafeMaxSpeedScale` | number | no | Multiplier on top speed when moving sideways. |
| `ground.forwardStrafeScale` | number | no | Multiplier when moving forward and sideways at once, as stored. |
| `ground.forwardStrafeScaleSprinting` | number | no | The same while sprinting, as stored. |
| `ground.slowWalk` | object | yes | The slow-walk settings and the fraction of speed each gives, by name (`Slow`, `Moderate`, `Fast`). |
| `ground.leanTime` | number | no | Seconds to lean out. |
| `ground.unleanTime` | number | no | Seconds to come back from a lean. |
| `ground.blockSprintTime` | number | no | Seconds sprinting is blocked after being interrupted, as stored. |
| `ground.blockTacticalSprintTime` | number | no | Seconds tactical sprinting is blocked after being interrupted, as stored. |
| `ground.minStartTacticalSprint` | number | no | Fraction of stamina needed to start a tactical sprint, as stored. |
| `jump` | object | yes | Jumping. |
| `jump.velocity` | number | no | Upward speed of a jump, in meters per second. |
| `jump.maxStamina` | number | no | Jump stamina pool, as stored. |
| `jump.staminaCost` | number | no | Stamina one jump costs, as stored. |
| `jump.staminaRegenPerSecond` | number | no | Jump stamina regained per second, as stored. |
| `jump.cooldown` | number | no | Seconds between jumps. |
| `falling` | object | yes | Falling. |
| `falling.maxSpeed` | number | no | Top horizontal speed in the air, in meters per second. |
| `falling.airControl` | number | no | Fraction of ground control the player has in the air, as stored. |
| `falling.terminalSpeed` | number | no | Fastest fall speed, in meters per second. |
| `falling.landingDamage` | list of object | yes | Fall damage by landing speed: no damage below the first point, rising linearly between points. The curve's x axis is in the game's speed unit (centimeters per second) and is published in meters per second. |
| `falling.landingDamage[].speed` | number | yes | Landing speed in meters per second. |
| `falling.landingDamage[].damage` | number | yes | Damage taken at that speed. |
| `ladder` | object | yes | Ladders. |
| `ladder.climbUpMaxSpeed` | number | no | Fastest climb up, in meters per second. |
| `ladder.climbDownMaxSpeed` | number | no | Fastest climb down, in meters per second. |
| `ladder.slideDownSpeed` | number | no | Speed of sliding down a ladder, in meters per second. |
| `bodyDragging` | object | yes | The same scales while dragging a body. |
| `bodyDragging.backMaxSpeedScale` | number | no | Multiplier on top speed when moving backward while dragging a body. |
| `bodyDragging.strafeMaxSpeedScale` | number | no | Multiplier on top speed when moving sideways while dragging a body. |
| `bodyDragging.forwardStrafeScale` | number | no | Multiplier when moving forward and sideways at once while dragging a body, as stored. |
| `bodyDragging.backwardStrafeScale` | number | no | Multiplier when moving backward and sideways at once while dragging a body, as stored. |
| `stamina` | object | yes | Stamina regeneration. The base pool size and the sprint cost are not in the files the client holds. |
| `stamina.regenPerSecond` | number | no | Stamina regained per second, as stored. |
| `stamina.regenDelay` | number | no | Seconds before regeneration starts. |
| `stamina.depletedRegenDelay` | number | no | Seconds before regeneration starts after the stamina ran out. |
| `stamina.stanceRegenPerSecond` | number | no | Stamina regained per second by the stance stamina pool, as stored. |
| `stamina.stanceRegenDelay` | number | no | Seconds before the stance pool regenerates. |
| `stamina.stanceCooldown` | number | no | Seconds between stance changes. |
| `slopes` | object | yes | Slopes. |
| `slopes.maxWalkableAngle` | number | no | Steepest slope that can be walked, in degrees. |
| `friction` | number | no | The game's ground friction, as stored. |
| `swimming` | object | yes | Swimming. |
| `swimming.waterAcceleration` | number | no | Acceleration in water, in meters per second squared. |
| `swimming.inputDeceleration` | number | no | Deceleration without input in water, in meters per second squared. |
| `vaulting` | object | yes | Vaulting over low obstacles. |
| `vaulting.vaultDistance` | number | no | Farthest obstacle distance for a vault, in meters. |
| `vaulting.baseTraversalSpeed` | number | no | Speed of the vault, in meters per second. |
| `mantling` | object | yes | Mantling over ledges. |
| `mantling.maxHeightAboveLedge` | number | no | Highest the ledge may be above the player's reach to scale over, in meters. |
| `mantling.forwardOnlyHeight` | number | no | Highest ledge that can be mantled when moving straight forward, in meters. |
| `mantling.maxTargetFloorHeight` | number | no | Greatest height of the floor to land on, in meters. |
| `mantling.maxWallWidth` | number | no | Widest wall that can be scaled over, in meters. |
| `mantling.maxWallAngle` | number | no | Steepest wall angle, in degrees. |
| `mantling.baseScaleOverSpeed` | number | no | Speed of scaling over, in meters per second. |
| `climbing` | object | yes | Climbing up walls. |
| `climbing.maxLedgeLookAngle` | number | no | Widest angle between the view and a ledge for a climb, in degrees. |
| `climbing.baseTraversalSpeed` | number | no | Climbing speed, in meters per second. |
| `climbing.baseScaleOverSpeed` | number | no | Speed of scaling over the top, in meters per second. |
| `parachute` | object | yes | Parachuting. |
| `parachute.minFallHeight` | number | no | Least height above the ground to open a parachute, in meters. |
| `parachute.gliderAcceleration` | number | no | Forward acceleration while gliding, in meters per second squared. |
| `parachute.pullUpDragAcceleration` | number | no | Braking acceleration when pulling up, in meters per second squared. |
| `parachute.pullUpStaminaPerSecond` | number | no | Stamina a pull-up uses per second, as stored. |
| `parachute.pullUpStaminaRegenPerSecond` | number | no | Stamina regained per second while not pulling up, as stored. |
| `parachute.minPitch` | number | no | Lowest pitch, in degrees. |
| `parachute.maxPitch` | number | no | Highest pitch, in degrees. |
| `parachute.maxRoll` | number | no | Largest roll, in degrees. |

## Role skills

Files: `data/skills.json`.

Role skills: names, descriptions, place in the role's tree and the value of each effect by skill level. Item unlocks by role and level are in items.json. Skill point costs and prerequisites are not in the client files.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `trees` | list of object | yes | The skill tree grid of each role, sorted by role. |
| `trees[].role` | string | yes | Role id. |
| `trees[].rows` | integer | yes | Number of rings in the role's tree grid. |
| `trees[].columns` | integer | yes | Number of positions around each ring. |
| `trees[].shape` | string | yes | The game's grid type: `Circle` (a half circle, drawn from the start angle over a total angle of 180 degrees). |
| `skills` | list of object | yes | Role skills, sorted by id. |
| `skills[].id` | string | yes | Skill id: the game's skill tag without the `Meta.Role.` prefix, for example `Infantry.SprintBreach`. |
| `skills[].role` | string | yes | The role whose tree holds the skill: Infantry, Support, Medic, Recon, Pilot or Driver. |
| `skills[].name` | string | no | Name shown in the skill tree. |
| `skills[].description` | string | no | Description shown in the skill tree. |
| `skills[].layout` | object | no | Position in the role's tree. Absent for a skill the game does not place in the tree. |
| `skills[].layout.row` | integer | yes | Ring of the tree, 0 for the innermost. Rings are farther from the center as the number grows (checked against the canvas positions). |
| `skills[].layout.column` | integer | yes | Position around the ring, counted from 0. |
| `skills[].layout.x` | number | yes | Horizontal canvas position of the node in the game's skill tree widget. |
| `skills[].layout.y` | number | yes | Vertical canvas position of the node in the game's skill tree widget. |
| `skills[].effects` | list of object | yes | What the skill does. Empty when the client files hold the skill's text and place in the tree but no effect data (the effects are applied by the server or by code). |
| `skills[].effects[].trigger` | string | yes | When the effect applies, the game's skill trigger without its `Meta.Skill.` prefix (`Character`, `Character.HeldItemUpdated`, ...). |
| `skills[].effects[].effect` | string | yes | Name of the game's gameplay effect the skill applies. For skills that only unlock an ability this is the whole effect. |
| `skills[].effects[].attribute` | string | no | Attribute the skill level scales, such as `Movement.ReadyToFirePlayRate`. Absent when the effect has no level-scaled value. |
| `skills[].effects[].curve` | string | no | Name of the game's curve the values come from. |
| `skills[].effects[].levels` | list of object | no | Value by skill level, from the curve. The game interpolates linearly between points. |
| `skills[].effects[].levels[].level` | number | yes | Skill level. |
| `skills[].effects[].levels[].value` | number | yes | Value of the attribute at that level (a multiplier unless the attribute says otherwise). |

## Challenge rewards

Files: `data/challenge-rewards.json`.

How much cash and role XP each in-match event pays, as the game's own formulas: the formula, the numbers behind its names, the situations that change them, and the curves that scale them. The game can change these values from its server ('live curves' and the challenge reward registry have a server source), so a live game may differ from the files.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `events` | list of object | yes | The game's definitions of the in-match events, sorted by id. A reward id (`Challenges.Rewards.` prefix removed) equals an event id only for some events: the game pays most events through several reward rows (one per vehicle, item or building), and which rows an event uses is in the game's logic, not in these tables. |
| `events[].id` | string | yes | Event id: the game's event tag without the `Challenges.SessionEvents.` prefix, for example `PlayerKill.Assist`. |
| `events[].name` | string | yes | The game's name for the event. |
| `events[].description` | string | no | The game's note on when the event pays, when it has one. |
| `rewards` | list of object | yes | Rewards, sorted by id. |
| `rewards[].id` | string | yes | The game's reward tag without the `Challenges.Rewards.` prefix, for example `PlayerKill`, `PlayerKill.CrewAssist` or `Spotting.Added.Kodiak`. |
| `rewards[].resources` | list of object | yes | What the reward pays: cash, usually together with role XP. |
| `rewards[].resources[].resource` | string | yes | What is paid, without the `Attribute.Meta.` prefix: `Currency.Cash`, or role XP as `XP.Role` (the game decides which role it goes to) or `XP.Role.<Role>` for one role. |
| `rewards[].resources[].formula` | string | yes | The amount, as the game's formula. Functions: clamp(value, min, max), pow(base, exponent), max(a, b). Each name is an entry of `inputs` or a variable. |
| `rewards[].resources[].inputs` | list of object | yes | Names in the formula that depend on the situation. Names not listed here are variables. |
| `rewards[].resources[].inputs[].name` | string | yes | The name the formula uses. |
| `rewards[].resources[].inputs[].default` | string | yes | The variable the name stands for when no option applies. |
| `rewards[].resources[].inputs[].options` | list of object | yes | Choices tried in order: the first whose `when` holds decides which variable the name stands for. |
| `rewards[].resources[].inputs[].options[].when` | object | yes | A test on the tags that describe what just happened (a headshot, a friendly kill, the player standing in a hot zone). It is the game's gameplay tag query, decoded. |
| `rewards[].resources[].inputs[].options[].when.match` | "all" \| "any" \| "none" | yes | How the parts combine: `all` of them, `any` of them, or `none` of them. |
| `rewards[].resources[].inputs[].options[].when.tags` | list of string | no | Context tags tested directly (for example `Challenges.Context.Headshot`). `all` needs every tag, `any` needs at least one, `none` needs none of them. Present when the condition tests tags. |
| `rewards[].resources[].inputs[].options[].when.of` | list of object | no | Groups of tags that are combined with `match`. Present when the condition combines several groups, such as `all` of (`any` of A and B) and (`none` of C). |
| `rewards[].resources[].inputs[].options[].when.of[].match` | "all" \| "any" \| "none" | yes | How this part combines its tags. |
| `rewards[].resources[].inputs[].options[].when.of[].tags` | list of string | yes | Context tags tested by this part. |
| `rewards[].resources[].inputs[].options[].use` | string | yes | The variable the name stands for when `when` holds. |
| `rewards[].resources[].variables` | list of any | yes | The numbers the formula and the inputs use. |
| `curves` | list of object | yes | Curves the rewards use, sorted by id. |
| `curves[].id` | string | yes | The game's tag for the curve, for example `LiveCurves.Challenges.SessionEvents.PlayerKill.DistanceScalar`. |
| `curves[].points` | list of object | yes | Points in the order the game stores them (rising input). |
| `curves[].points[].input` | number | yes | The value being looked up, in the game's units (distances are as stored by the game, not converted). |
| `curves[].points[].value` | number | yes | The curve's value from this input on. |
| `curves[].points[].interpolation` | "constant" \| "linear" \| "cubic" | yes | How the curve moves from this point to the next: `constant` holds the value until the next input (a step). |

## Meta game

Files: `data/meta.json`.

The meta game around matches: currencies and starting balances, the gold bar market, passive missions and achievements.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `currencies` | list of object | yes | Currencies, sorted by id. |
| `currencies[].id` | string | yes | Currency id: the game's tag without the `Attribute.Meta.Currency.` prefix: `Cash` or `GoldBars`. |
| `currencies[].name` | string | yes | Name shown in the game. |
| `currencies[].initialBalance` | number | yes | Balance a new profile starts with. |
| `currentSeason` | integer | yes | The season number the game files declare as current. The season definition list and the gold bar exchange rates are empty in the files. |
| `goldMarket` | list of object | yes | Cosmetics sold for gold bars, sorted by id. |
| `goldMarket[].id` | string | yes | Offer id: the game's tag without the `Meta.Cosmetic.` prefix, for example `DigitalWood.M4`. The same id as the skin or emote in cosmetics.json. |
| `goldMarket[].category` | string | yes | The set the offer belongs to, for example `DigitalWood` or `Emote` (the `set` of the cosmetic). |
| `goldMarket[].entity` | string | yes | The item, vehicle variant or emote the offer is for: an `id` from items.json or vehicles.json, or the emote's id. |
| `goldMarket[].goldBars` | number | yes | Price in gold bars. |
| `goldMarket[].gridIndex` | integer | yes | Position of the tile in the market grid of its category. |
| `goldMarket[].tile` | string | yes | Tile size in the market: `HERO_TILE`, `LARGE_SQUARE`, `SMALL_SQUARE` or `SMALL_RECTANGLE`. |
| `goldMarket[].expiration` | string | yes | The game's expiration rule for the offer: `NO_EXPIRATION` or `EXPIRATION_NO_END_TIME`. |
| `goldMarket[].expirationTime` | string | no | The time stored with the offer, UTC, when the game stores one. The game labels the offers that carry one `EXPIRATION_NO_END_TIME`, so it may be unused. |
| `passiveMissions` | list of object | yes | Passive missions, sorted by id. |
| `passiveMissions[].id` | string | yes | Mission id: the game's tag without the `Mission.Passive.` prefix: `EarnCash`, `EarnAnyRoleXp` or `TimePlayed`. |
| `passiveMissions[].difficultyWeight` | number | yes | The game's difficulty weight for the mission. |
| `passiveMissions[].challenges` | list of object | yes | The mission's tiers, in the game's order. |
| `passiveMissions[].challenges[].id` | string | yes | Challenge id: the game's tag without the `Challenges.Challenge.Mission.Passive.` prefix, for example `EarnCash.3`. The number is the tier. |
| `passiveMissions[].challenges[].name` | string | yes | Name shown in the game. |
| `passiveMissions[].challenges[].description` | string | no | Description shown in the game; `X` stands for the target. |
| `passiveMissions[].challenges[].objective` | string | yes | What is counted: the game's objective tag without the `Challenges.Objective.` prefix: `CashEarned`, `RoleXpEarned` or `TimePlayed`. |
| `passiveMissions[].challenges[].target` | number | yes | The amount of the objective to complete the challenge. Time is in seconds. Whether the amount accumulates over the tiers or counts again for each is not stated in the data. |
| `passiveMissions[].challenges[].reward` | object | yes | What completing the challenge pays. |
| `passiveMissions[].challenges[].reward.currency` | string | yes | Currency paid, without the `Attribute.Meta.Currency.` prefix. `Intel` is not in the currency table. |
| `passiveMissions[].challenges[].reward.amount` | number | yes | Amount paid. |
| `achievements` | list of object | yes | Achievements, sorted by id. |
| `achievements[].id` | string | yes | Achievement id: the game's tag without the `Achievement.` prefix, for example `Combat.LongShot`. |
| `achievements[].steamId` | string | yes | The achievement's id on Steam. |
| `achievements[].name` | string | yes | Name shown in the game. |
| `achievements[].description` | string | no | What the achievement asks for, in the game's words. The game words only some of them. |
| `achievements[].thresholds` | object | no | The numbers the game sets for the achievement's condition, by the game's parameter name, as stored: `CashThreshold` (cash), `RequiredSeconds` (seconds), `DistanceThreshold` (game units, which are centimeters). Absent for achievements with no such number. |

## Role levels

Files: `data/roles.json`.

Role mastery: the XP needed for each level of each role. Items unlock at a role level (`unlock` in items.json), so this turns a level gate into an amount of XP. The overall Wardog (career) level, which gates some items up to level 150, has no table of its own: the game's text says all role levels combine into it, without giving the formula.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `roles` | list of object | yes | Roles, sorted by id. |
| `roles[].id` | string | yes | Role id: the game's role tag without the `Meta.Role.` prefix: Infantry, Support, Medic, Recon, Pilot or Driver. The same ids as `unlock.role` in items.json. |
| `roles[].xpResource` | string | yes | The game's attribute that holds the role's XP, without the `Attribute.Meta.` prefix, for example `XP.Role.Infantry`. |
| `roles[].levels` | list of object | yes | Every level from 0 up, sorted by level. |
| `roles[].levels[].level` | integer | yes | Role level. |
| `roles[].levels[].xp` | number | yes | Total role XP needed to reach this level, counted from zero (level 0 needs 0). The game's progress display reads `current XP / next level XP`, so the values are totals, not per-level costs. |

## Cash rewards

Files: `data/rewards.json`.

Cash rewards for in-game actions (kills, heals, revives, repairs, building, objectives) with their base amounts and modifiers. The game also has a challenge reward system (challenge-rewards.json) with its own formulas and different numbers (a player kill has a base of 250 here and 300 there); the files do not say which one the live game pays by.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `rewards` | list of object | yes | Reward cases, sorted by action then by the order of the game's table. |
| `rewards[].action` | string | yes | What earns the reward, from the game's table name: `PlayerKill`, `Heal`, `Revive`, `VehicleDestroyed`, `Repair`, `Refuel`, `Spotting`, `ControlZoneReward`, ... |
| `rewards[].context` | string | yes | The case within the action, the game's context tag without its `Meta.Progression.Context.` prefix (a vehicle variant id for vehicle-specific rewards). |
| `rewards[].description` | string | no | The game's own note on when the case applies. |
| `rewards[].resource` | string | yes | What is paid: `Cash`. |
| `rewards[].base` | number | yes | Base amount. |
| `rewards[].modifiers` | object | yes | The other numbers of the row, named as the game names them (`FriendlyModifier`, `ModifierCZ` for control zones, `ModifierHZ` for hot zones, `AssistBaseModifier`, ...). They scale or adjust the base amount depending on who and where. |

## Damage model

Files: `data/damage.json`.

The game's damage model: percentage rules by source, target and hit location (ammo types, calibers, armor, vehicles), body-part multipliers by weapon class, ammo-type penetration, and occupant protection in vehicles. Base damage per hit is in ammo.json; this file says what happens to it.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `rules` | list of object | yes | The damage rules, grouped by entity in the game's order. Order inside an entity matters to the game. |
| `rules[].entity` | string | yes | What the rule belongs to: the damageable entity the game's table row names, such as `Infantry`, `Armor`, `Helmet`, `Armor.Ghillie`, `Vehicle` or one vehicle (`Vehicle.Air.Rotary.Havoc`). The `Meta.Damage.` prefix is dropped. |
| `rules[].source` | list of string | yes | Tags the incoming damage must carry for the rule to apply, such as `Bullet`, `Bullet.556mm`, `Bullet.AmmoModifier.HollowPoint` or `Explosive.Rocket.84mm`. All of them must match. Empty means any damage. |
| `rules[].target` | list of string | yes | Tags the target must carry, such as `Armor`, `Helmet.SuperHeavy`. Empty means any target. |
| `rules[].instigator` | list of string | yes | Tags the attacker must carry. Empty means any attacker. |
| `rules[].hitLocations` | list of string | yes | Hit locations the rule is limited to (`Vehicle.MainRotor`, `Infantry.Head`), or attribute tags for vehicle parts. Empty means anywhere. |
| `rules[].alignment` | string | no | `Friendly` for rules that only apply to damage between teammates. Absent otherwise. |
| `rules[].category` | string | yes | The group the game applies the rule in, such as `Weapon`, `Calibre`, `AmmoModifier`, `Armor`, `Bone`, `Penetration`. Rules of one category do not stack the way different categories do. |
| `rules[].operation` | string | yes | How the amount changes the damage. `Percentage_Ongoing` reads as a percentage change to the running damage: -20 is 20% less and 100 doubles it. `Add` adds a flat amount of damage (tracked vehicles crushing buildables). The game's own code decides the exact order rules apply in. |
| `rules[].amount` | number | yes | The amount: a percentage for `Percentage_Ongoing`, damage points for `Add`. |
| `rules[].custom` | string | no | Name of the game's own code that computes the real effect when the rule is not a plain percentage (for example `B_BoneDamageModifiers_C`, which applies the hit-location multipliers). Absent for plain rules. |
| `hitLocationMultipliers` | list of object | yes | Body-part multipliers by weapon class. |
| `hitLocationMultipliers[].weaponClass` | string | yes | `Universal`, or the weapon class the multipliers are for, such as `Weapon.AR`, `Weapon.Sniper`. The `Meta.Damage.` prefix is dropped. |
| `hitLocationMultipliers[].multipliers` | object | yes | Damage multiplier per hit location, keyed by location (`Head`, `Neck`, `Torso.Upper`, ...). |
| `ammoTypes` | list of object | yes | Penetration effectiveness by ammo type. |
| `ammoTypes[].ammoType` | string | yes | Ammo type: `FMJ`, `HollowPoint`, `ArmorPiercing`, with `.Tracer` variants. |
| `ammoTypes[].modifier` | number | yes | Penetration effectiveness multiplier of the ammo type. |
| `ammoTypes[].byArmsClass` | object | yes | Multiplier by weapon arms class (`Small`, `Medium`, `High`, `Special`) that replaces `modifier` for that class. Empty when the game gives none. |
| `vehicleSeats` | list of object | yes | Occupant protection by vehicle. |
| `vehicleSeats[].vehicle` | string | yes | Vehicle variant id from items.json. |
| `vehicleSeats[].rules` | list of object | yes | Damage reduction for a person sitting in the vehicle, by arms class. |
| `vehicleSeats[].rules[].damageSources` | list of string | yes | Arms classes the reduction applies to (`Small`, `Medium`, `High`, `Special`). |
| `vehicleSeats[].rules[].reduction` | number | yes | Percent change to damage the occupant takes; -90 is 90% less. |

## Vehicle stats

Files: `data/vehicles.json`.

Vehicle statistics as the game shows them in the vehicle shop. Ids are vehicle items in items.json.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `vehicles` | list of object | yes | One entry per vehicle variant, sorted by id. |
| `vehicles[].id` | string | yes | Vehicle variant id from items.json. |
| `vehicles[].name` | string | no | Display name, as in items.json (the game's UI table). Absent when the game has none. |
| `vehicles[].asset` | string | yes | Path of the vehicle stats asset inside the game files. |
| `vehicles[].maxSpeed` | number | yes | Top speed as shown in the vehicle shop (km/h). |
| `vehicles[].maxFuel` | number | yes | Fuel tank size in liters. |
| `vehicles[].fuelEconomy` | number | yes | Fuel use as shown in the shop, in liters per kilometer (the shop rounds `1 / kmPerLiter` to one decimal). |
| `vehicles[].seats` | integer | yes | Number of seats. |
| `vehicles[].weapons` | list of string | yes | Names of the weapons listed in the shop. |
| `vehicles[].weaponIcons` | object | no | Icon of each weapon in `weapons` that the game has one for, by weapon name: a path inside `assets/icons/`. The game's UI tables name the vehicle's weapon extensions with the same names. |
| `vehicles[].counterMeasures` | list of string | yes | Names of the countermeasures listed in the shop. |
| `vehicles[].damageEntity` | string | no | The `entity` of this vehicle's damage rules in damage.json, such as `Vehicle.Land.Wheeled.Humvee.Default`. Variants of one platform can share it. |
| `vehicles[].health` | object | no | Vehicle health. Absent when the vehicle has no gameplay systems asset. |
| `vehicles[].health.initial` | number | yes | Hit points of a new vehicle. |
| `vehicles[].health.criticalThreshold` | number | no | Health at or below which the vehicle is in a critical state, as stored. |
| `vehicles[].health.bleedOutTime` | number | no | Seconds a vehicle in the critical state lasts before it is destroyed, as stored. |
| `vehicles[].kmPerLiter` | number | no | Distance in kilometers one liter of fuel lasts, as stored (`1 / kmPerLiter` is liters per kilometer). |
| `vehicles[].destroyedExplosion` | object | no | The explosion when the vehicle is destroyed. |
| `vehicles[].destroyedExplosion.radius` | number | no | Distance in meters at which the wreck's explosion damage reaches its minimum. |
| `vehicles[].destroyedExplosion.effectiveRadius` | number | no | Distance in meters within which the wreck's explosion does full damage. |
| `vehicles[].destroyedExplosion.falloff` | number | no | How fast the explosion's damage falls with distance, as stored. |
| `vehicles[].mass` | number | no | Mass of the vehicle body as the game's physics stores it (kg). Wheeled vehicles and helicopters only: tracked vehicles store no body mass in their files (no mass override in the blueprint's body; the track and sprocket masses are in `tracks`), so none is published. |
| `vehicles[].engine` | object | no | Engine of a wheeled or tracked vehicle. Helicopters have no engine curve in the data read. |
| `vehicles[].engine.torqueCurve` | list of object | yes | Engine torque by engine speed, as the keys of the game's curve (rpm and torque as stored, sorted by rpm). The game interpolates between keys. |
| `vehicles[].engine.torqueCurve[].rpm` | number | yes | Engine speed of this key. |
| `vehicles[].engine.torqueCurve[].torque` | number | yes | Torque at that speed, as stored. |
| `vehicles[].engine.torqueScale` | number | no | Multiplier on the curve's torque. Absent when the game leaves it at its default. |
| `vehicles[].engine.frictionTorque` | number | no | Engine braking torque, as stored. Absent when the game leaves it at its default. |
| `vehicles[].engine.idleRpm` | number | no | Idle speed. Absent when the game leaves it at its default. |
| `vehicles[].engine.limitRpm` | number | no | Rev limiter speed. Absent when the game leaves it at its default. |
| `vehicles[].engine.inertia` | number | no | Engine inertia, as stored. |
| `vehicles[].engine.boostScale` | number | no | Torque multiplier while boosting, as stored. |
| `vehicles[].engine.extraPowerRatio` | number | no | Extra power multiplier of a tracked vehicle's engine, as stored. |
| `vehicles[].transmission` | object | no | Gearbox of a wheeled or tracked vehicle. |
| `vehicles[].transmission.gearRatios` | list of number | yes | Gear ratios in the order the game stores them. A wheeled vehicle's last entry is reverse; tracked vehicles list some entries the game does not document, so read them with care. |
| `vehicles[].transmission.finalGearRatio` | number | no | Final drive ratio (a tracked vehicle's differential ratio). |
| `vehicles[].transmission.changeTime` | number | no | Time a gear change takes, as stored. |
| `vehicles[].transmission.clutchTime` | number | no | Clutch engagement time, as stored. |
| `vehicles[].transmission.gearUpRatio` | number | no | Engine load at which an automatic gearbox shifts up, as stored. |
| `vehicles[].transmission.gearDownRatio` | number | no | Engine load at which an automatic gearbox shifts down, as stored. |
| `vehicles[].tracks` | object | no | Masses of a tracked vehicle's track parts, when the game sets them. |
| `vehicles[].tracks.trackMass` | number | no | Mass of the track, as stored. Absent when the game leaves it at its default. |
| `vehicles[].tracks.sprocketMass` | number | no | Mass of a drive sprocket, as stored. Absent when the game leaves it at its default. |

## Vehicle configs

Files: `data/vehicle-configs.json`.

Everything the game stores about how each vehicle behaves: the config assets and the assets they link to (physics, engine, gearbox, axles, wheels, tire models, suspension, helicopter flight and drag, tracked engine and dynamics, input controls, camera spring arms, sensors, gameplay systems and effects, prediction settings, curves), with every stored property. Meant for tools that simulate or compare vehicles; `vehicles.json` has the curated numbers.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `configs` | list of object | yes | One entry per vehicle config asset, sorted by package. |
| `configs[].package` | string | yes | Package path of the config asset, also its entry in `assets`. |
| `configs[].type` | string | yes | Config class: `MWheeledVehicleConfigDataAsset`, `MTrackedVehicleConfigDataAsset`, `BHRotaryVehicleConfigDataAsset` or `BHAirplaneVehicleConfigDataAsset` or `BHBaseVehicleConfigDataAsset` (stationary weapons and drones). |
| `configs[].family` | "wheeled" \| "tracked" \| "rotary" \| "airplane" \| "stationary" | yes | Vehicle family, from the config class. |
| `configs[].damageEntity` | string | no | The `entity` of the vehicle's damage rules in damage.json, from the config's gameplay systems asset. |
| `configs[].variants` | list of string | yes | Vehicle variants (ids from vehicles.json) of the same family that share this config's damage entity. A platform with several configs lists its variants under each; empty for configs of things the shop does not sell. |
| `configs[].assets` | list of string | yes | Package paths of every asset reachable from the config by following its references (the config itself included), sorted. Each is an entry in `assets`. |
| `assets` | list of object | yes | Every asset reachable from a config, once each, sorted by package. Shared assets (curves, a platform's characteristics used by several configs) appear once. |
| `assets[].package` | string | yes | The game's package path (`/WHL_05/Data/DA_Characteristics_WHL_05_Humvee`), which is what a `ref` in a property names. |
| `assets[].asset` | string | yes | Path of the asset inside the game files. |
| `assets[].exports` | list of object | yes | The package's objects, in the game's order. |
| `assets[].exports[].name` | string | yes | The export's name inside its package. |
| `assets[].exports[].type` | string | yes | The export's class, as the game names it (`MWheeledVehicleCharacteristicsDataAsset`, `CurveFloat`). |
| `assets[].exports[].outer` | string | no | Name of the export this one is embedded in, when it is not the package's own object. |
| `assets[].exports[].properties` | object | yes | Every property the game stores for it, under the game's own names. Values are stored units (centimeters, degrees, milliseconds as the game keeps them). A reference to another object is `{ ref, object? }` (see `assets[].package`), a gameplay tag is `{ tag }`, text is `{ text, table?, key? }` with the string table entry it comes from. Properties the game leaves at their default are not in its files and are absent. |
| `skipped` | list of object | yes | Packages the configs link to that hold art or audio content rather than properties (static meshes and their collision, MetaSound audio graphs, particle systems, materials, textures). They are named here and not published. Sorted by package. |
| `skipped[].package` | string | yes | Package path. |
| `skipped[].types` | list of string | yes | Classes of its objects. |
| `unresolved` | list of string | yes | Packages the configs and their assets reference that are not in the game files (or are engine classes under `/Script/`). Sorted. |

## Map metadata

Files: `data/maps/europe/map.json`, `data/maps/kavkazi/map.json`, `data/maps/north-america/map.json`.

Metadata that places a world's map image and tiles in world coordinates. All distances are meters.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `id` | string | yes | Short id of the world, also its folder name under `data/maps`. |
| `name` | string | yes | Map name shown in the game's server browser. |
| `world` | string | yes | Name of the world (level) the map belongs to. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. |
| `bounds` | object | yes | Area the map covers, as world X and Y. Pixel (0, 0) of the image is the minimum corner. |
| `bounds.min` | [number, number] | yes | Minimum corner: [x, y] in meters. |
| `bounds.max` | [number, number] | yes | Maximum corner: [x, y] in meters. |
| `image` | object | yes | The single full-size map image the tiles were cut from. |
| `image.width` | integer | yes | Image width in pixels. |
| `image.height` | integer | yes | Image height in pixels. |
| `image.metersPerPixel` | number | yes | World meters per image pixel. `pixel = (world - bounds.min) / metersPerPixel`; rows increase with world Y. |
| `image.padding` | object | yes | Pixels past the bounds on the right and bottom edges. They hold padding, not map. |
| `image.padding.right` | integer | yes | Padding columns on the right edge. |
| `image.padding.bottom` | integer | yes | Padding rows on the bottom edge. |
| `tiles` | object | yes | The tile pyramid published as a release asset. |
| `tiles.size` | 256 | yes | Tile size in pixels (tiles are square). |
| `tiles.minZoom` | 0 | yes | Lowest zoom level (one tile covers the whole map). |
| `tiles.maxZoom` | integer | yes | At this zoom the tiles cover the full image at 1:1 (`image.width = 256 * 2^maxZoom`). |
| `tiles.format` | "webp" | yes | Tile image format. |
| `tiles.urlTemplate` | string | yes | Path of a tile inside the release's map folder; replace `{z}`, `{x}` and `{y}`. |

## Terrain heightmap metadata

Files: `data/maps/europe/terrain.json`, `data/maps/kavkazi/terrain.json`, `data/maps/north-america/terrain.json`.

Metadata for a world's baked terrain height image (a release asset, `heightmap.png`). All distances are meters.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `id` | string | yes | Short id of the world, also its folder name under `data/maps`. |
| `world` | string | yes | Name of the world (level) the terrain belongs to. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. |
| `bounds` | object | yes | Area the heightmap covers, as world X and Y. Pixel (0, 0) is the minimum corner. |
| `bounds.min` | [number, number] | yes | Minimum corner: [x, y] in meters. |
| `bounds.max` | [number, number] | yes | Maximum corner: [x, y] in meters. |
| `zRange` | object | yes | World Z of pixel value 0 and of pixel value 65535. |
| `zRange.min` | number | yes | World Z in meters of pixel value 0. |
| `zRange.max` | number | yes | World Z in meters of pixel value 65535. |
| `heightmap` | object | yes | The 16-bit grayscale height image. |
| `heightmap.file` | "heightmap.png" | yes | File name inside the release's map folder. |
| `heightmap.width` | integer | yes | Image width in pixels. |
| `heightmap.height` | integer | yes | Image height in pixels. |
| `heightmap.bitDepth` | 16 | yes | Bits per pixel. |
| `heightmap.metersPerPixel` | [number, number] | yes | World meters per pixel along X and Y. Rows increase with world Y. |
| `heightmap.encoding` | "z = zRange.min + value / 65535 * (zRange.max - zRange.min)" | yes | How to turn a pixel value into a height. |
| `check` | object | yes | Self-check against the buildings: base of each building minus the terrain height under its centre. |
| `check.buildings` | integer | yes | Buildings used in the check. |
| `check.medianOffset` | number | yes | Median offset in meters. |
| `check.p5Offset` | number | yes | 5th percentile offset in meters. |
| `check.p95Offset` | number | yes | 95th percentile offset in meters. |
| `check.fractionWithin5m` | number | yes | Share of buildings whose base is within 5 m of the terrain. |

## Match objectives

Files: `data/maps/europe/objectives.json`, `data/maps/kavkazi/objectives.json`, `data/maps/north-america/objectives.json`.

Match objectives of one world: where the control zone and its hot zone are, how big they are, and how the hot zone moves.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `world` | string | yes | Name of the world (level) the objectives are in. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. |
| `configs` | list of object | yes | One entry per control zone configuration the game has for the world. |
| `configs[].config` | string | yes | Name of the game's control zone configuration asset. |
| `configs[].mode` | string | yes | `Standard` for the normal match, otherwise the name of the game mode variant (for example `SniperShowdown`). |
| `configs[].zone` | object | yes | The default control zone. |
| `configs[].zone.center` | [number, number, number] | yes | Center of the control zone: [x, y, z] in meters. |
| `configs[].zone.extents` | [number, number, number] | yes | Size of the control zone as the game stores it, in meters: for a cylinder, x and y are the radius and z the half height. |
| `configs[].zone.shape` | string | no | Zone shape, for example `Cylinder`. Absent when the game leaves it at its default. |
| `configs[].zone.hotZone` | object | yes | The hot zone inside the control zone. |
| `configs[].zone.hotZone.extents` | [number, number, number] | yes | Size of the hot zone (the moving capture area inside the control zone), in meters, read like `extents`. |
| `configs[].zone.hotZone.shape` | string | no | Hot zone shape. Absent when the game leaves it at its default. |
| `configs[].alternatives` | list of object | yes | Other places the control zone can be put at the start of a match. Empty when the zone never moves. |
| `configs[].alternatives[].id` | string | yes | The game's tag for this placement, for example `ZoneAlternator.Bakurani.Farmland.Circle`. |
| `configs[].alternatives[].weight` | number | yes | Relative chance the placement is chosen. 0 means it is never chosen. |
| `configs[].alternatives[].zone` | object | yes | A control zone and the hot zone inside it. |
| `configs[].alternatives[].zone.center` | [number, number, number] | yes | Center of the control zone: [x, y, z] in meters. |
| `configs[].alternatives[].zone.extents` | [number, number, number] | yes | Size of the control zone as the game stores it, in meters: for a cylinder, x and y are the radius and z the half height. |
| `configs[].alternatives[].zone.shape` | string | no | Zone shape, for example `Cylinder`. Absent when the game leaves it at its default. |
| `configs[].alternatives[].zone.hotZone` | object | yes | The hot zone inside the control zone. |
| `configs[].alternatives[].zone.hotZone.extents` | [number, number, number] | yes | Size of the hot zone (the moving capture area inside the control zone), in meters, read like `extents`. |
| `configs[].alternatives[].zone.hotZone.shape` | string | no | Hot zone shape. Absent when the game leaves it at its default. |
| `configs[].hotZoneMovement` | object | yes | How the hot zone moves inside the control zone. |
| `configs[].hotZoneMovement.firstMoveDelay` | number | no | Seconds before the hot zone first moves. |
| `configs[].hotZoneMovement.moveDelay` | number | no | Seconds of delay before the hot zone moves, as stored (the game's `MoveDelay`). |
| `configs[].hotZoneMovement.innerRadiusFraction` | number | no | The game's `HotZoneInnerRadiusPercentage`, as stored (0.95 on the standard configurations). It limits how far toward the control zone's edge the hot zone may go. |
| `configs[].hotZoneMovement.defaultSpeed` | number | no | Hot zone speed multiplier, as stored (the game's `DefaultSpeed`). |
| `configs[].hotZoneMovement.dynamicSpeeds` | boolean | no | True when the hot zone uses the speeds listed in `speeds` (the game's `bUseDynamicHotzoneSpeeds`). |
| `configs[].hotZoneMovement.speeds` | list of number | yes | The game's `HotzoneSpeeds` list, as stored. |
| `configs[].hotZoneMovement.minMoveDistance` | number | no | Shortest move of the hot zone, in meters. |

## Placed gameplay objects

Files: `data/maps/europe/objects.json`, `data/maps/kavkazi/objects.json`, `data/maps/north-america/objects.json`.

Gameplay objects placed in one world: shops, safe zones, spawn managers and volumes, vehicle deployment boards and fuel refills. Coordinates are the same as in map.json.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `world` | string | yes | Name of the world (level) the objects are in. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. |
| `count` | integer | yes | Number of objects. |
| `objects` | list of object | yes | Objects, sorted by kind and then position. |
| `objects[].id` | string | yes | Stable id derived from the placed actor's name and the level it is in. |
| `objects[].kind` | "equipment-vendor" \| "vehicle-vendor" \| "garage-vendor" \| "safe-zone" \| "safe-zone-camera" \| "spawn-manager" \| "spawn-volume" \| "vehicle-deployment-board" \| "fuel-refill" | yes | What the object is: a shop (`equipment-vendor`, `vehicle-vendor`, `garage-vendor`), a team `safe-zone` with its `safe-zone-camera`, a team `spawn-manager`, a `spawn-volume` that vehicles appear in, a `vehicle-deployment-board` or a `fuel-refill` crate. |
| `objects[].class` | string | yes | Blueprint class of the actor. |
| `objects[].position` | [number, number, number] | yes | Position: [x, y, z] in meters. |
| `objects[].yaw` | number | no | Heading in degrees. Absent when the object is not rotated. |
| `objects[].scale` | [number, number, number] | no | Actor scale as stored. For a safe zone this sizes its trigger box. Absent when the game leaves it at 1. |
| `objects[].faction` | string | no | The team the object belongs to (`Alpha` or `Bravo`). Absent for neutral objects. |
| `objects[].tags` | list of string | no | Tags the object applies to people inside it (safe zones). |
| `objects[].allowedVehicles` | list of string | no | Vehicle ids a spawn volume may spawn (see items.json). |
| `objects[].disallowedVehicles` | list of string | no | Vehicle ids and vehicle families a spawn volume never spawns. |

## Buildings

Files: `data/maps/europe/buildings.json`, `data/maps/kavkazi/buildings.json`, `data/maps/north-america/buildings.json`.

Destructible buildings of one world as axis-aligned boxes. Z is up. Boxes enclose, so they overestimate.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `schemaVersion` | 1 | yes | Version of this file's layout. It changes only when the layout does. |
| `world` | string | yes | Name of the world (level) the buildings are in. |
| `gameBuild` | string | yes | Steam build id the data was extracted from. |
| `units` | "meters" | yes | Unit of every distance in the file. |
| `shape` | "axis-aligned bounding box" | yes | How each building is represented. |
| `count` | integer | yes | Number of buildings. |
| `buildings` | list of object | yes | Buildings, sorted by id. |
| `buildings[].id` | string | yes | Stable id derived from the placed actor's name. |
| `buildings[].kind` | "bungalow" \| "house" \| "apartment" \| "warehouse" \| "market" \| "shop" \| "garage" \| "office" \| "supply" \| "pool" | yes | Building category, derived from the blueprint class. |
| `buildings[].class` | string | yes | Blueprint class of the building. |
| `buildings[].min` | [number, number, number] | yes | Minimum corner of the box: [x, y, z] in meters. |
| `buildings[].max` | [number, number, number] | yes | Maximum corner of the box: [x, y, z] in meters. |
| `buildings[].parts` | integer | yes | Number of mesh parts whose bounds were merged into the box. |

## CSV tables

Flat copies of the data for spreadsheets. The first row is the header, cells are comma separated with RFC 4180 quoting, and empty means absent. Lists inside a cell are separated by `;`.

### `data/csv/achievements.csv`

One row per achievement.

| Column | Meaning |
| --- | --- |
| `id` | Achievement id. |
| `steam_id` | The achievement's id on Steam. |
| `name` | Name shown in the game. |
| `description` | What the achievement asks for, when the game words it. |
| `thresholds` | The numbers the game sets for the condition, as `name=value` separated by `;`. |

### `data/csv/ammo.csv`

One row per projectile definition (ballistics).

| Column | Meaning |
| --- | --- |
| `id` | Projectile id. |
| `asset` | Game asset path (several projectiles can share an id). |
| `damage` | Damage of one hit before falloff, armor and hit location. |
| `damage_type` | Damage type tag. |
| `mass_kg` | Projectile mass in kilograms. |
| `diameter_mm` | Diameter in millimeters. |
| `length_mm` | Length in millimeters. |
| `drag_coefficient` | Drag coefficient. |
| `drag_model` | Drag model, such as G7. |
| `typical_speed_mps` | Typical speed in meters per second. |
| `penetrates` | False when the projectile never passes through surfaces. |
| `exit_speed_multiplier` | Fraction of speed kept after passing through a surface. |
| `ricochet_min_angle_deg` | Impact angle above which it ricochets. |
| `explosive_radius_m` | Distance at which explosive damage reaches its minimum. |
| `explosive_effective_radius_m` | Distance within which explosive damage is full. |
| `suppression` | Suppression caused by a near miss. |
| `items` | Ammo items that fire it, separated by `;`. |
| `item_names` | Display names of those ammo items, separated by `;`. |

### `data/csv/armor.csv`

One row per armor or helmet item.

| Column | Meaning |
| --- | --- |
| `id` | Item id. |
| `name` | Display name from items.json. |
| `slot` | `Armor` or `Helmet`. |
| `damage_context` | Target tag the damage rules use for this piece. |
| `covered_locations` | Body parts protected, separated by `;`. |
| `durability` | Hit points of the armor. |
| `damage_reduction_new` | Percent of damage absorbed when new. |
| `damage_reduction_worn` | Percent of damage absorbed at the last wear stage. |
| `density_new` | Plate density when new, as stored. |
| `density_worn` | Plate density at the last wear stage, as stored. |

### `data/csv/attachment-modifiers.csv`

One row per change an attachment makes.

| Column | Meaning |
| --- | --- |
| `attachment_id` | Item id of the attachment. |
| `attachment_name` | Display name of the attachment. |
| `target` | `weapon` for changes to the weapon, `character` for changes to the carrier. |
| `attribute` | Attribute changed. |
| `op` | How the value combines. |
| `value` | The value (1.1 on a multiplier is +10%). |

### `data/csv/attachments.csv`

One row per attachment.

| Column | Meaning |
| --- | --- |
| `id` | Item id. |
| `name` | Display name from items.json. |
| `type` | Attachment type. |
| `contexts` | Item context tags, separated by `;`. |
| `magazine_capacity` | Rounds a magazine holds. |
| `magazine_calibers` | Calibers a magazine takes, separated by `;`. |

### `data/csv/buildables.csv`

One row per buildable structure.

| Column | Meaning |
| --- | --- |
| `id` | Buildable id. |
| `name` | Display name. |
| `cost` | Building supplies it costs. |
| `max_health` | Hit points when fully built. |
| `repair_speed_multiplier` | Repair speed compared with the standard rate. |
| `max_stack` | Stack size when the game states one. |
| `damage_entity` | The `entity` of its rules in damage.json. |
| `size_x_m` | Bounding box X in meters. |
| `size_y_m` | Bounding box Y in meters. |
| `size_z_m` | Bounding box Z in meters. |
| `tools` | Build tools that offer it, separated by `;`. |
| `placement_rules` | Placement conditions, separated by `;`. |

### `data/csv/buildings-europe.csv`

One row per destructible building of the europe world, as an axis-aligned box in meters.

| Column | Meaning |
| --- | --- |
| `id` | Building id. |
| `kind` | Building kind. |
| `class` | Blueprint class. |
| `min_x` | Minimum X. |
| `min_y` | Minimum Y. |
| `min_z` | Minimum Z (the base). |
| `max_x` | Maximum X. |
| `max_y` | Maximum Y. |
| `max_z` | Maximum Z (the roof). |
| `parts` | Mesh parts merged into the box. |

### `data/csv/buildings-kavkazi.csv`

One row per destructible building of the kavkazi world, as an axis-aligned box in meters.

| Column | Meaning |
| --- | --- |
| `id` | Building id. |
| `kind` | Building kind. |
| `class` | Blueprint class. |
| `min_x` | Minimum X. |
| `min_y` | Minimum Y. |
| `min_z` | Minimum Z (the base). |
| `max_x` | Maximum X. |
| `max_y` | Maximum Y. |
| `max_z` | Maximum Z (the roof). |
| `parts` | Mesh parts merged into the box. |

### `data/csv/buildings-north-america.csv`

One row per destructible building of the north-america world, as an axis-aligned box in meters.

| Column | Meaning |
| --- | --- |
| `id` | Building id. |
| `kind` | Building kind. |
| `class` | Blueprint class. |
| `min_x` | Minimum X. |
| `min_y` | Minimum Y. |
| `min_z` | Minimum Z (the base). |
| `max_x` | Maximum X. |
| `max_y` | Maximum Y. |
| `max_z` | Maximum Z (the roof). |
| `parts` | Mesh parts merged into the box. |

### `data/csv/challenge-reward-events.csv`

One row per in-match event the game defines, with its name and note.

| Column | Meaning |
| --- | --- |
| `event` | Event id. |
| `name` | The game's name for the event. |
| `description` | The game's note on when the event pays. |

### `data/csv/challenge-reward-variables.csv`

One row per number a reward formula uses.

| Column | Meaning |
| --- | --- |
| `reward` | Reward id. |
| `resource` | What the payment is. |
| `name` | Variable name. |
| `type` | `literal`, `game` or `scaling`. |
| `value` | The number, for a literal. |
| `game_value` | The game value that fills it in, for type `game`. |
| `curve` | The curve it is read from, for type `scaling`. |
| `curve_input` | The value looked up on the curve, for type `scaling`. |

### `data/csv/challenge-rewards.csv`

One row per payment of a reward: the formula in the game's own notation.

| Column | Meaning |
| --- | --- |
| `reward` | Reward id. |
| `resource` | What is paid. |
| `formula` | The amount as a formula over the names in the variables table. |
| `inputs` | Names in the formula that change with the situation (see the JSON for the conditions), separated by `;`. |

### `data/csv/control-zones.csv`

One row per control zone placement of every world: the default one and each alternative.

| Column | Meaning |
| --- | --- |
| `world` | World name. |
| `config` | The game's control zone configuration asset. |
| `mode` | `Standard` or the name of a game mode variant. |
| `placement` | `default`, or the game's tag for an alternative placement. |
| `weight` | Relative chance an alternative is chosen (empty for the default). |
| `x` | Center X in meters. |
| `y` | Center Y in meters. |
| `z` | Center Z in meters. |
| `shape` | Zone shape when the game states one. |
| `radius_m` | Control zone radius (x extent) in meters. |
| `half_height_m` | Control zone half height (z extent) in meters. |
| `hot_zone_radius_m` | Hot zone radius in meters. |

### `data/csv/cosmetics.csv`

One row per cosmetic (skin, emote, faction logo, taxi livery).

| Column | Meaning |
| --- | --- |
| `id` | Cosmetic id. |
| `item` | Item, emote or vehicle it applies to. |
| `item_name` | Display name of the item, when it is one. |
| `set` | Set or category id. |
| `set_name` | Display name of the set, when it has one. |
| `archetype` | Weapon archetype. |
| `source` | The game's table it was read from. |

### `data/csv/damage-rules.csv`

One row per damage rule. Tag lists are separated by `;`.

| Column | Meaning |
| --- | --- |
| `entity` | What the rule belongs to (`Infantry`, `Armor`, one vehicle, a buildable). |
| `source` | Tags the incoming damage must carry, separated by `;`. |
| `target` | Tags the target must carry, separated by `;`. |
| `instigator` | Tags the attacker must carry, separated by `;`. |
| `hit_locations` | Hit locations the rule is limited to, separated by `;`. |
| `alignment` | `Friendly` for teammate-only rules. |
| `category` | The group the game applies the rule in. |
| `operation` | How the amount changes the damage. |
| `amount` | The amount (a percentage for `Percentage_Ongoing`). |
| `custom` | The game's own code for rules that are not plain percentages. |

### `data/csv/equipment-modifiers.csv`

One row per change worn armor or a carried-weight class makes to the player.

| Column | Meaning |
| --- | --- |
| `source` | An armor item id, or `weight:<class>` for a carried-weight class. |
| `attribute` | Attribute changed. |
| `op` | How the value combines. |
| `value` | The value (0.95 on a multiplier is -5%). |

### `data/csv/gold-market.csv`

One row per cosmetic offered for gold bars.

| Column | Meaning |
| --- | --- |
| `id` | Offer id, the same as the cosmetic's id in cosmetics.json. |
| `category` | The set the offer belongs to. |
| `entity` | The item, vehicle variant or emote it is for. |
| `gold_bars` | Price in gold bars. |
| `grid_index` | Position of the tile in the market grid of its category. |
| `tile` | Tile size in the market. |
| `expiration` | The game's expiration rule. |
| `expiration_time` | The time stored with the offer, UTC, when there is one. |

### `data/csv/hit-location-multipliers.csv`

Damage multiplier per body part and weapon class.

| Column | Meaning |
| --- | --- |
| `weapon_class` | `Universal` or a weapon class such as `Weapon.AR`. |
| `hit_location` | Body part, such as `Head` or `Torso.Upper`. |
| `multiplier` | Damage multiplier. |

### `data/csv/items.csv`

One row per item and vehicle.

| Column | Meaning |
| --- | --- |
| `id` | Item id (the key every other table uses). |
| `kind` | `item` or `vehicle`. |
| `name` | Display name. |
| `subtitle` | Short category line from the tooltip. |
| `description` | Short tooltip text; line breaks are kept inside the quoted cell. |
| `icon` | Icon file under the release's `icons/` folder. |
| `developer` | True for development-only items (test and debug) that players cannot get. |
| `grid_width` | Inventory footprint width in cells. |
| `grid_height` | Inventory footprint height in cells. |
| `max_stack` | Units per inventory cell. |
| `weight` | Weight as stored by the game. |
| `durability` | Durability as stored by the game. |
| `unlock_role` | Progression tree that unlocks the item (empty when it needs no unlock). |
| `unlock_level` | Level needed in that tree. |
| `unlock_cost` | Cash cost to unlock. |
| `tags` | Item context tags, separated by `;`. |

### `data/csv/loot-items.csv`

One row per item a loot table can spawn.

| Column | Meaning |
| --- | --- |
| `table` | Loot table id. |
| `item` | Item id. |
| `item_name` | Display name of the item. |
| `amount` | Units spawned. |
| `weight` | Relative chance among the table's entries. |
| `sub_items` | Items that spawn with it as `item*amount@chance%`, separated by `;`. |

### `data/csv/loot-tables.csv`

One row per loot table.

| Column | Meaning |
| --- | --- |
| `id` | Loot table id. |
| `spawn_chance` | Percent chance the loot spawns. |
| `spawn_by_default` | Spawns at the start of a match. |
| `initial_spawn_time_s` | Seconds before the first spawn. |
| `initial_spawn_points` | Spawn points at the start. |
| `can_respawn` | Comes back after being taken. |
| `respawn_time` | Respawn time as stored. |
| `never_repeat_previous` | A respawn never repeats the previous item. |
| `control_zone_only` | Spawns only inside the control zone. |
| `entries` | Number of items that can spawn. |

### `data/csv/objects-europe.csv`

One row per placed gameplay object of the europe world.

| Column | Meaning |
| --- | --- |
| `id` | Object id. |
| `kind` | What the object is. |
| `class` | Blueprint class. |
| `x` | Position X in meters. |
| `y` | Position Y in meters. |
| `z` | Position Z in meters. |
| `yaw_deg` | Heading in degrees. |
| `faction` | Team (`Alpha` or `Bravo`). |
| `scale_x` | Actor scale X as stored. |
| `scale_y` | Actor scale Y as stored. |
| `scale_z` | Actor scale Z as stored. |
| `allowed_vehicles` | Vehicles a spawn volume may spawn, separated by `;`. |
| `disallowed_vehicles` | Vehicles a spawn volume never spawns, separated by `;`. |

### `data/csv/objects-kavkazi.csv`

One row per placed gameplay object of the kavkazi world.

| Column | Meaning |
| --- | --- |
| `id` | Object id. |
| `kind` | What the object is. |
| `class` | Blueprint class. |
| `x` | Position X in meters. |
| `y` | Position Y in meters. |
| `z` | Position Z in meters. |
| `yaw_deg` | Heading in degrees. |
| `faction` | Team (`Alpha` or `Bravo`). |
| `scale_x` | Actor scale X as stored. |
| `scale_y` | Actor scale Y as stored. |
| `scale_z` | Actor scale Z as stored. |
| `allowed_vehicles` | Vehicles a spawn volume may spawn, separated by `;`. |
| `disallowed_vehicles` | Vehicles a spawn volume never spawns, separated by `;`. |

### `data/csv/objects-north-america.csv`

One row per placed gameplay object of the north-america world.

| Column | Meaning |
| --- | --- |
| `id` | Object id. |
| `kind` | What the object is. |
| `class` | Blueprint class. |
| `x` | Position X in meters. |
| `y` | Position Y in meters. |
| `z` | Position Z in meters. |
| `yaw_deg` | Heading in degrees. |
| `faction` | Team (`Alpha` or `Bravo`). |
| `scale_x` | Actor scale X as stored. |
| `scale_y` | Actor scale Y as stored. |
| `scale_z` | Actor scale Z as stored. |
| `allowed_vehicles` | Vehicles a spawn volume may spawn, separated by `;`. |
| `disallowed_vehicles` | Vehicles a spawn volume never spawns, separated by `;`. |

### `data/csv/passive-missions.csv`

One row per tier of a passive mission.

| Column | Meaning |
| --- | --- |
| `mission` | Mission id. |
| `tier` | Tier, counted from 1 in the game's order. |
| `challenge` | Challenge id. |
| `name` | Name shown in the game. |
| `objective` | What is counted. |
| `target` | Amount of the objective to complete the tier (time in seconds). |
| `reward_currency` | Currency paid. |
| `reward_amount` | Amount paid. |

### `data/csv/prices.csv`

One row per way to buy an item. Ammo is sold in lots: `price` buys `amount` units.

| Column | Meaning |
| --- | --- |
| `item_id` | Item id. |
| `item_name` | Display name. |
| `variation` | Vendor variation tag. |
| `price` | Price of one purchase. |
| `amount` | Units one purchase gives. |
| `unit_price` | Price per unit (`price / amount`). |
| `categories` | Vendor categories, separated by `;`. |

### `data/csv/reward-curve-points.csv`

One row per point of a reward curve.

| Column | Meaning |
| --- | --- |
| `curve` | Curve id. |
| `input` | The value looked up. |
| `value` | The curve's value from this input on. |
| `interpolation` | `constant` (a step), `linear` or `cubic`. |

### `data/csv/reward-modifiers.csv`

One row per modifier of a reward case, named as the game names it.

| Column | Meaning |
| --- | --- |
| `action` | What earns the reward. |
| `context` | The case within the action. |
| `modifier` | Modifier name. |
| `value` | Modifier value. |

### `data/csv/rewards.csv`

One row per cash reward case.

| Column | Meaning |
| --- | --- |
| `action` | What earns the reward. |
| `context` | The case within the action. |
| `resource` | What is paid. |
| `base` | Base amount. |
| `description` | The game's own note on when the case applies. |

### `data/csv/role-levels.csv`

One row per role level.

| Column | Meaning |
| --- | --- |
| `role` | Role id. |
| `level` | Role level. |
| `xp` | Total role XP needed to reach the level. |
| `xp_to_next` | XP from this level to the next; empty at the top level. |

### `data/csv/skill-levels.csv`

One row per point of a skill's level curve: the value of an attribute at a skill level.

| Column | Meaning |
| --- | --- |
| `skill_id` | Skill id. |
| `attribute` | Attribute the level scales. |
| `curve` | The game's curve name. |
| `level` | Skill level. |
| `value` | Value at that level. |

### `data/csv/skills.csv`

One row per role skill.

| Column | Meaning |
| --- | --- |
| `id` | Skill id. |
| `role` | Role whose tree holds the skill. |
| `name` | Name shown in the skill tree. |
| `description` | Description shown in the skill tree. |
| `tree_row` | Ring of the role's tree, 0 for the innermost; empty when the skill is not placed. |
| `tree_column` | Position around the ring; empty when the skill is not placed. |
| `effects` | Names of the gameplay effects the skill applies, separated by `;`. Empty when the client files hold no effect data for the skill. |

### `data/csv/tags.csv`

One row per tag with the text the game shows for it.

| Column | Meaning |
| --- | --- |
| `tag` | The game's gameplay tag. |
| `text` | Display text. |
| `source` | The game's table the text comes from. |

### `data/csv/vehicles.csv`

One row per vehicle variant.

| Column | Meaning |
| --- | --- |
| `id` | Vehicle item id. |
| `name` | Display name from items.json. |
| `max_speed_kmh` | Top speed in km/h. |
| `max_fuel_l` | Fuel tank in liters. |
| `fuel_economy_l_per_km` | Fuel use as shown in the shop, liters per kilometer. |
| `km_per_liter` | Distance one liter of fuel lasts, as stored. |
| `health` | Hit points of a new vehicle. |
| `critical_threshold` | Health at or below which the vehicle is critical, as stored. |
| `bleed_out_time` | Seconds a critical vehicle lasts, as stored. |
| `damage_entity` | The `entity` of its damage rules in damage.json. |
| `wreck_explosion_radius_m` | Distance at which the wreck explosion reaches its minimum damage. |
| `wreck_explosion_effective_radius_m` | Distance within which the wreck explosion does full damage. |
| `mass_kg` | Mass of the vehicle body as the game's physics stores it (wheeled vehicles and helicopters). |
| `idle_rpm` | Engine idle speed, when the game stores one. |
| `limit_rpm` | Engine rev limiter, when the game stores one. |
| `peak_torque` | Highest torque on the engine's curve, as stored. |
| `gear_ratios` | Gear ratios in stored order, separated by `;`. |
| `final_gear_ratio` | Final drive ratio. |
| `seats` | Number of seats. |
| `weapons` | Weapons listed in the shop, separated by `;`. |
| `counter_measures` | Countermeasures listed in the shop, separated by `;`. |

### `data/csv/weapon-compatibility.csv`

One row per weapon, slot and item that fits it, resolved from the slot rules in weapons.json and the items' tags. The chamber slot lists the ammo each weapon accepts.

| Column | Meaning |
| --- | --- |
| `weapon_id` | Item id of the weapon. |
| `weapon_name` | Display name of the weapon. |
| `slot` | Slot type. |
| `item_id` | Item that fits the slot. |
| `item_name` | Display name of the item. |
| `is_default` | True when the weapon starts with this item in the slot. |

### `data/csv/weapon-damage.csv`

One row per weapon and projectile it can fire, with the damage per hit and the raw damage per second. These are before distance falloff, armor and hit location: see `damage.json` for what happens to them.

| Column | Meaning |
| --- | --- |
| `weapon_id` | Item id of the weapon. |
| `weapon_name` | Display name of the weapon. |
| `projectile` | Projectile id (caliber). |
| `projectile_items` | Ammo items that fire it, separated by `;`. |
| `damage_per_hit` | Base damage of one hit. |
| `rpm` | Rounds per minute. |
| `raw_dps` | Damage per second at the weapon's rate of fire: `damage_per_hit * rpm / 60`. |
| `muzzle_velocity_mps` | Muzzle velocity in meters per second. |
| `effective_range_m` | Range in meters the weapon is tuned for. |
| `full_damage_range_m` | Distance up to which damage is not reduced by falloff. |

### `data/csv/weapon-slots.csv`

One row per attachment slot of a weapon.

| Column | Meaning |
| --- | --- |
| `weapon_id` | Item id of the weapon. |
| `weapon_name` | Display name of the weapon. |
| `slot` | Slot type. |
| `filter` | `AllowList` accepts only what is listed; `BlockPriority` accepts all except what is blocked. |
| `hidden` | True for slots players do not see (chamber, built-in parts). |
| `default` | Item the weapon starts with. |
| `default_name` | Display name of the default item. |
| `items` | Items accepted by name, separated by `;`. |
| `contexts` | Item context tags accepted, separated by `;`. |
| `blocked_items` | Items refused by name, separated by `;`. |
| `blocked_contexts` | Context tags refused, separated by `;`. |

### `data/csv/weapons.csv`

One row per weapon, with the headline numbers. Recoil patterns and damage falloff are in the JSON.

| Column | Meaning |
| --- | --- |
| `id` | Item id. |
| `name` | Display name from items.json. |
| `fire_modes` | Fire modes, separated by `;`. |
| `rpm` | Rounds per minute. |
| `rounds_per_burst` | Rounds per burst. |
| `calibers` | Calibers fired, separated by `;`. |
| `muzzle_velocity_mps` | Muzzle velocity in meters per second. |
| `effective_range_m` | Range in meters the weapon is tuned for. |
| `accuracy` | Accuracy rating as stored. |
| `random_deviation_deg` | Random aim deviation in degrees. |
| `ads_time_s` | Seconds to aim down sights with iron sights. |
| `zeroing_min_m` | Shortest zeroing distance in meters. |
| `zeroing_max_m` | Longest zeroing distance in meters. |
| `zeroing_step_m` | Zeroing step in meters. |
| `melee_damage` | Damage of a melee hit. |
| `suppression_multiplier` | Suppression multiplier. |
| `windup_time_s` | Spin-up time in seconds. |
| `recoil_pattern_length` | Shots in the recoil pattern. |

### `data/csv/weight-classes.csv`

One row per carried-weight class.

| Column | Meaning |
| --- | --- |
| `name` | Class name. |
| `min_weight_kg` | Carried weight in kilograms from which the class applies. |
