BF6 datamine toolkit: live game-file extractor (TOC/EBX -> JSON) + Python port of raymdl's weapon-analyzer sim - TTK, recoil, spread, attachment costs from the current patch.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-19 07:02:33 +02:00
bf6sim fix(sim): atts displays hidden headshot/limb mult deltas for ammo 2026-09-19 07:02:33 +02:00
docs feat: bf6 data extractor, weapon sim package, and research docs 2026-09-18 05:44:15 +02:00
.gitattributes feat: bf6 data extractor, weapon sim package, and research docs 2026-09-18 05:44:15 +02:00
.gitignore feat: bf6 data extractor, weapon sim package, and research docs 2026-09-18 05:44:15 +02:00
bf6_extract.py feat(extract): site aliases for all 63 analyzer weapons 2026-09-19 01:42:37 +02:00
pyproject.toml feat: bf6 data extractor, weapon sim package, and research docs 2026-09-18 05:44:15 +02:00
README.md feat(sim): comp 100 default, radius override, pattern-mastery doctrine 2026-09-19 06:54:09 +02:00
uv.lock feat: bf6 data extractor, weapon sim package, and research docs 2026-09-18 05:44:15 +02:00

bf6-datamine

Battlefield 6 weapons research toolkit: a live game-file extractor and a Python port of the raymdl BF6 Weapon Analyzer simulation, plus the research docs produced with them.

Python 3.13, uv-managed, stdlib only.

Layout

bf6_extract.py      EBX datamine extractor (toc_bf6 driver + GameRemixer/parser)
bf6sim/             weapon sim package (attachments, recoil, spread, damage, ballistics, TTK)
docs/
  gunplay-research.md   build research + verified in-game tables (master report)
  mechanics.md          game mechanics tech reference (patch 1.4.3.0 baseline)
  raymdl-model-notes.md condensed compilation of the analyzer's model docs
extracts/           output of the extractor, per date (gitignored, regenerable)
tools/              ResHax BF6 TOC tools (gitignored, see below)

Setup

uv sync

tools/ needs id-daemon's ResHax BF6 tools (toc_bf6.exe + DLLs). If missing, the extractor says where it looked; pass --tools <dir> to override.

Extractor

Dumps EBX from the installed game (Steam, Data\ root required — layout.toc anchor), then parses GameRemixer live-tuning values, killswitches, attachment wrappers, damage curves, WB raws. Reading game files is passive and anticheat-safe; never write game files or install mods.

uv run bf6_extract.py --out extracts/<patch>            # full run: dump + parse (~5-10 min)
uv run bf6_extract.py --skip-dump --dump-dir <dir> ...  # reparse existing dumps
uv run bf6_extract.py --skip-dump --dump-dir <d> --site-dir <analyzer-data>  # + site merge

Outputs per extract: weapons.json (all live grx/kst fields + site layer + ingame_name from game files), attachments.json (name/slug/points cost/modifier GUIDs), damage_curves.json (per-caliber StartDamage/EndDamage/falloff/drag/gravity), hit_zone_constants.json, generic_tweakables.json, meta.json, site/ (raymdl data JSONs).

Simulator

uv run bf6sim weapons <filter> --class ar,smg          # class aliases: ar, carbine, smg, lmg, dmr, sr, sg, sidearm
uv run bf6sim atts tr7                                  # per-slot attachments: pts + stat deltas vs stock (+ legend)
uv run bf6sim atts tr7 --slot muzzle                    # single slot
uv run bf6sim stats tr7
uv run bf6sim build tr7 --muzzle long_supp --grip bcg_light --mag 20_rnd   # applied stats + pts
uv run bf6sim ttk tr7 --ranges 0,21,50 --zone head --headshots 0
uv run bf6sim spread tr7 --shots 20 --move
uv run bf6sim recoil tr7 --seed 0 --comp 50 --hip
uv run bf6sim cadence tr7 --mode tap --tap auto --range 15 --target head --runs 2000

Every command takes --json for machine-readable output (full applied stat vector included). Unknown attachment ids fail closed with nearest-match suggestions and exit code 1.

Cadence, compensation and hit probability (cadence)

cadence fires a string under a controlled cadence and scores it against a target, so recovery packages, grip rows and accuracy bloom can be judged per playstyle instead of per stat:

  • Modes: --mode spray (continuous), --mode burst --burst N --gap MS (N-shot bursts with a pause), --mode tap --tap MS (paced single shots) or --tap auto — a solver that binary-searches the smallest tap interval holding the steady-state pre-shot recoil residual under --tol (default 0.05 deg); the solved interval and residual are printed, and the per-shot table carries cumulative t(ms) timestamps.
  • --comp PCT models open-loop pull compensation (same math as the analyzer; >100 = overpull). Default is 100 — full pattern mastery, the CS-spray-pattern doctrine: the sim models the machine ceiling and treats the learned pattern as a skill assumption, not a random variable. At --comp 100 with --perfect every shot lands on the same point — muzzle choice stops mattering for placement. --perfect zeroes recoil direction variance only.
  • Bullet dispersion is still sampled (--runs N Monte Carlo, u^distExp radius + uniform angle from the game's spread model) — even a 100% macro misses "like a real shooting range".
  • Target geometry: --target torso|head (r = 0.20/0.10 m, override with --radius) + --range M prints per-shot and overall hit% at that range plus the full-cadence range — the max range where every shot of the string stays on target. Target radii are screenshot-calibrated against the in-game range silhouettes (110 deg FOV, 35 m lane): silhouette torso 0.39 m wide ≈ sim r 0.20; in-game arm capsules push the effective body radius to ~0.30–0.35 m. Tap cadence fully recovers dispersion between shots; spray/burst climb with bloom, which is where barrel adsSpread* multipliers (e.g. Cryogenic) show up.

Delta-row signs (atts legend): recoil/hiprecoil +N = less kick, cone/hipcone +N = tighter, ADS/mADS +N = faster/tighter, hip +N = wider, strafe −N = slower, sprint/draw −N = faster. Deltas are vs the stock gun (default mag/ammo/barrel, iron sights) and come from the sim's own tier-mod sums, so hidden stock bonuses (e.g. TR-7's default mag −1 sprint/draw tier, Basic barrel's +1 ADS tier on most weapons) show up as losses when swapped away. Continuous attachment multipliers display as x ratios in atts (e.g. Cryogenic's adsbloom -0.136 · adsfiredec x1.837 · adsfireoff x0.667); multiplier fields the sim models are adsSpreadIncMult (ADS bloom per shot) and the adsSpreadFiring/NotFiringDec* recovery multipliers.

Data resolution: --data <dir> or auto (cwd data/, then newest extracts/<date>/). Loads either an extract dir (site layer merged per weapon) or the analyzer repo data/ directly.

Numerical parity with the analyzer's JS is exact (RNG bit-exact, same rounding/clamping); the JS _ctx globals are explicit parameters instead. Sim requires the weapon's site layer (derived fields) — all 63 analyzer weapons merge (2026-09-19, codename drift resolved in SITE_ALIASES via the damageSource <Name>_WB ↔ grx-key-prefix match); leftover extract codenames (gadgets, portal assets, KSG) have no analyzer record and list as unsupported.

Known source conflict: the in-game ADS-move penalty for Variable High / Thermal optics (−1 strafe row, e.g. 0.67→0.60 and 0.475→0.42 mult, verified 2026-09-19) is absent from both the analyzer data and the datamine (noEffect: true). atts prints a warning on those sights; the sim does not model the penalty.

Patch workflow

  1. Full extractor run into extracts/<patch>/ with --site-dir pointing at a fresh clone of the analyzer repo's data/.
  2. Diff weapons.json grx fields vs the previous extract = what DICE changed (ground truth).
  3. Diff site/ = what the analyzer models changed.
  4. Unmatched weapons (codename drift) — add to SITE_ALIASES in bf6_extract.py.

Tools & credits

  • ResHax — game reverse-engineering forum; the BF6 TOC tools (toc_bf6.exe + DLLs) are id-daemon's work, distributed through ResHax's tools section. Vendored locally in tools/ (gitignored — grab your own copy there).
  • raymdl/BF6-Weapon-Analyzer — community datamine site; source of the site/ data layers, the sim this package ports, and the model docs summarized in docs/raymdl-model-notes.md (live site).
  • sym.gg — community weapon-data baseline the analyzer builds on.
  • Frosty Tool Suite — Frostbite EBX export tooling; the analyzer uses a BF6 fork with a scriptable FrostyCmd.
  • Python 3.13, uv package manager.

Provenance

  • Live values: GameRemixer (grx_weapons.ebx) + killswitch layer, current installed patch.
  • Attachment costs: decoded from attachment_<weapon>_<slug>.ebx (+0x4c), matches in-game.
  • Site layers: raymdl analyzer (sym.gg baseline + Frosty export + tier-ladder modeling).
  • Per-attachment effect magnitudes, protectionIndex, ballistics remain analyzer-side (CAS-partition layer); see docs/raymdl-model-notes.md.