Release v0.34.0 - "Crimson Marksman"
Release Date: July 02, 2026
This release upgrades the physics engine to ballistics-engine 0.22.0 — a large correctness release landing 44 confirmed fixes from a full adversarial logic-and-math audit of the crate, spanning drag, atmosphere, ground and zero geometry, wind, spin/rotational physics, Monte Carlo, and cross-surface consistency, plus a performance improvement.
Read this first: numeric output shifts for most trajectories versus the previous engine. These are corrections, not regressions — but if you keep dope tables, DOPE cards, or automated reference baselines, re-validate them against this release.
Highlights (the ones that move your numbers)
- Transonic drag is no longer double-counted. The G1/G7 tables already contain the full McCoy transonic rise; the engine was stacking a second multiplier (up to 2.5×) on top near Mach 1. That extra drag is gone, so bullets retain more velocity and drop less anywhere they touch roughly Mach 0.85–1.2 — and for the entire flight of subsonic loads (.22 LR, subsonic .300 BLK). Example: a .308 168 gr at 2700 fps now carries about +56 fps more velocity at 1000 yd.
- Ground-impact range convention fixed. Flat-fire shots were flying to twice the bore height below the muzzle before registering a ground strike, overstating impact range and time-of-flight (about +37% range / +45% TOF in a typical case). Ground is now consistent across CLI, FFI, WASM, and Monte Carlo.
- Drag constant corrected (~1.75%). The retardation constant was the Army Standard Metro value while density was normalized to ICAO sea level — a mismatch that ran drag uniformly ~1.75% low for any modern ICAO-referenced BC. Now matches py-ballisticcalc.
- Inclined fire (
--shooting-angle) is now actually applied. The flag was accepted on every surface but read by no solver. Gravity is now rotated into the shot-aligned frame everywhere, including the fast/binding integration path.
- Mach and air density now use the same resolved atmosphere. Speed-of-sound was computed from raw input temperature while density used the ICAO-lapse station temperature at altitude — so altitude shots looked up drag at the wrong Mach. Now consistent, and it also feeds Miller stability and Magnus.
- Monte Carlo statistics corrected. CEP is now the median target-plane radial miss (was off by up to ~100×); short-falling shots are no longer miscounted as hits; vertical dispersion is no longer sampled twice (was inflating spread ~41%); and the simulation range is sized to the target instead of silently truncating at the 1000 m integrator default.
Zeroing & Geometry
zero now zeroes to the line of sight, not the bore line — it was ignoring sight height entirely (~1.9 MOA at typical heights).
--auto-zero now solves with your drag model and atmosphere instead of a hardcoded G1 / ISA-sea-level assumption.
- Sight-adjustment MOA sign fixed (was telling you to dial the wrong direction); point-blank range now reads the downrange axis, referenced to the line of sight.
true-velocity drop no longer double-counts barrel elevation or flips the sight-height sign (was up to +11% effective-velocity error).
- Trajectory bullet length now honors the supplied value instead of a hardcoded 4.5-caliber estimate, so stability, spin drift, and aerodynamic jump match the
stability subcommand.
Atmosphere & Rotational Physics
- Miller Sg density correction and the fast/Monte-Carlo Mach lookup now use the resolved station atmosphere, not raw sea-level input — affecting stability, spin drift, and Magnus at altitude.
- Moist-air speed-of-sound and CIPM-2007 coefficients corrected (mole-fraction and Pa unit fixes; small but real).
- Magnus moment coefficient is now continuous at Mach 1.2 (was a 33% jump between branches).
Monte Carlo, Wind & Cross-Surface Consistency
- FFI and WASM Monte Carlo now use the same ground/bore convention as the CLI (previously reported the integrator cap with zero standard deviation); FFI Monte Carlo now honors its atmosphere argument instead of running every sample at ICAO sea level.
- Wind beyond the last
--wind-segment correctly drops to zero on the shear-enabled fast path; fast_integrate_with_segments now steps through segments by downrange distance instead of applying only the first for the whole flight.
estimate-bc drop values are inches on both CLI and WASM (was a 36× unit mismatch); WASM twist-rate is mm/turn in metric mode, its Drop column is referenced to the line of sight, its default wind direction is headwind (matching the CLI), and its powder-temperature model matches the native solver.
- FFI trajectory samples report real Mach and spin rate (were hardcoded to 0); metric
--bc-table lookups convert to the tables' native inches/fps units; --bc-adjustment now affects the trajectory when a BC table is also supplied.
- Metric PDF dope cards convert to imperial fields; density-altitude no longer applies the 120 ft/°C rule to a Fahrenheit delta (~1.8× overstatement fixed).
Numerical & Performance
fast_integrate no longer returns NaN when the solution is queried at its own reported event time; the sampled-trajectory Apex flag is no longer misplaced on flat or descending shots.
- Performance: speed-of-sound, temperature, and pressure are resolved once per solve and threaded through the drag and Magnus paths, instead of re-running a vapor-pressure polynomial on every RK4/RK45 stage.
Platforms & Ecosystem
Engine 0.22.0 shipped end to end:
- crates.io —
ballistics-engine 0.22.0
- 12 platform binaries — Linux (x86_64, aarch64), Windows x86_64, and FreeBSD / OpenBSD / NetBSD on both x86_64 and aarch64, plus the new linux-mips64el target
- WASM — live on ballistics.sh and ballistics.rs
- Docs — docs.ballistics.rs regenerated
- Python —
ballistics-engine 0.22.0 on PyPI; Ruby — ballistics-engine 0.22.0 on RubyGems
- Production API — this service (ballistics-api) now runs engine 0.22.0
← All Releases