Skip to main content

Module reticle_import

Module reticle_import 

Source
Expand description

MBA-1440: import Bero’s “Ventum” reticle spec into the engine’s ReticleDescription.

A reticle drawn in Bero’s Ventum tool is a single JSON object: reticle-level metadata (name, focal plane, calibration magnification, angular unit) plus a spec list of drawing elements. This module is the one-way transform from that authoring format into the engine’s own ReticleDescription, so a Ventum reticle can be hold-solved by the existing hold_point_in_reticle without any of the CLI/FFI/WASM surfaces having to learn a second schema. It is a converter, not new physics — every coordinate is carried straight through, only unit-normalized to milliradians and repeat-expanded.

§What is kept, what is dropped

The Ventum spec mixes hold-bearing marks with decoration:

  • dot and tick are the holdable marks. A dot becomes a MarkKind::Dot; a tick becomes a MarkKind::Hash whose hold point is its own (x, y) anchor.
  • text is a standalone label positioned in reticle coordinates. Following the schema’s recommended “option (b)”, each text is bound to the nearest hold-bearing mark within DEFAULT_TEXT_BIND_MIL and becomes that mark’s label; unattached text is dropped.
  • line, circle, rect, grid, and any unknown future element type are pure decoration and are dropped.

§Coordinate and unit conventions

Ventum uses +x = right, +y = down, origin at the reticle center — identical to the engine’s ReticleMark::right_mil / ReticleMark::down_mil, so no sign flips are needed. All coordinates are expressed in the reticle’s own unit; MOA input is converted to milliradians with 1 MOA = 0.2908882 mil (MOA_TO_MIL). Auto-numbered ladder labels are NOT unit-converted — a label is the reticle-unit value it names.

Confirmed by the format’s author (2026-08-01): +y is down because a reticle is numbered downward (a 4-unit holdover is y: 4; a stadia mark 5 up is y: -5), which is plain SVG screen convention and happens to match shooter intuition.

§Arc angles (not yet consumed — recorded so the mapping is not guessed later)

Ventum draws arcs as a circle element carrying start/end angles. Those angles are measured from 3 o’clock (0° = +x, right) and sweep CLOCKWISE:

  0° = right      90° = down      180° = left      270° = UP

The one counterintuitive consequence, worth stating because it is the opposite of a compass: since +y is down, the TOP of the reticle is 270°, not 90°. A horseshoe opening downward is therefore start: 200, end: 340. This is the same system as the coordinates (+x right, +y down, 0° at 3 o’clock, clockwise), so the format never mixes conventions.

A point on an arc of radius r about the reticle center is therefore

  x = r * cos(θ)          y = r * sin(θ)          (θ in degrees, +y DOWN)

Note the PLUS on the sine: in a y-up math convention this term is negated, and that single sign is the whole trap. Verified against the author’s reference diagram — its 0/90/180/270 markers and the start: 200, end: 340 horseshoe endpoints reproduce exactly under the formula above, and the arc’s 140° clockwise sweep passes through 270° (the top), leaving the gap at the bottom.

This module currently drops circle as decoration (see above), so nothing here depends on these angles yet; the note exists so that whoever makes arcs hold-bearing does not have to re-derive the convention.

§Safety

The mark cap (crate::reticle::MAX_RETICLE_MARKS) is enforced during repeat expansion, so a hostile repeat.n (or a huge mirrored ladder) can never allocate an unbounded vector: expansion stops the instant the running instance count would exceed the cap, having materialized at most one instance past it. This is the same defense as the 0.31.0 reticle generator size guards.

Constants§

DEFAULT_TEXT_BIND_MIL
Largest (x, y) distance (in milliradians) at which a text element binds to a hold-bearing mark and becomes its label. Text farther than this from every mark is treated as free-floating decoration and dropped.
MOA_TO_MIL
Milliradians per minute of angle (1 MOA = 0.2908882 mil). Ventum reticles authored in MOA are converted to the engine’s milliradian marks with this factor.

Functions§

import_ventum_reticle
Import a Ventum reticle spec into a ReticleDescription.