# Rifle

The rifle itself: its name, cartridge, barrel length and muzzle device (for people only), and the twist, twist direction and sight height the solver uses.

## Generated table

**Record:** profile · **Covers:** `rifle.name`, `rifle.cartridge`, `rifle.barrel_length_in`, `rifle.muzzle_device`, `rifle.twist_in`, `rifle.twist_dir`, `rifle.sight_height_in`

| Field | Type | Required | Limits in the schema | Solver reads | In a shared log |
|---|---|---|---|---|---|
| `rifle.barrel_length_in` | number | no | - | no | as stored |
| `rifle.cartridge` | string | no | - | no | as stored |
| `rifle.muzzle_device` | string | no | - | no | as stored |
| `rifle.name` | string | yes | - | no | as stored |
| `rifle.sight_height_in` | number | yes | - | yes | as stored |
| `rifle.twist_dir` | `'R'` or `'L'` | yes | - | yes | as stored |
| `rifle.twist_in` | number | yes | min 3; max 40 | yes | as stored |

## What it holds

These fields of a profile version describe the rifle as a physical object. Three of them are values the solver uses: the barrel's twist (inches per turn), which way it twists, and the sight height (the scope's centre above the bore). The other four, the rifle's name, the cartridge, the barrel length and the muzzle device, are notes for the people who read the profile; no calculation looks at them. The zero fields also sit under `rifle`, but they are described on the [zero](zero.md) page.

## What to know first

**Sight height, twist and twist direction reset a calibration by default.** Editing any of the three is a "shape" edit, like changing the bullet. Unlike a zero edit, it starts with "reset" chosen, because a fitted curve was fitted for the old value.

**Sight height is from the centre of the bore to the centre of the scope, in inches.** A tenth of an inch wrong moves every come-up by roughly 0.02 to 0.03 mil on a 100 yd zero, the same at every range. A longer zero range makes it smaller.

**Twist is inches per turn: a 1:10 barrel is 10.** It sets the stability, the spin drift, the aerodynamic jump and the spin of the Spin model. The direction is R or L; anything but R is flown as left-hand.

**Name, cartridge, barrel length and muzzle device are for people only.** They change no answer. They stay visible in a shared log when notes are hidden.

**The connector can set all four.** Since 2026-10-17 `edit_profile` and `create_profile` take the cartridge, barrel length and muzzle device beside the rifle's name, as guided setup does.

## The fields

**`rifle.name`** The make and model of the rifle, or whatever the shooter calls it ("Long rifle"). Free text; required to be present, but an empty string is fine, and a new profile starts empty. It is not the profile's own name, which is a different field. Example: "Custom long action".

**`rifle.cartridge`** What the rifle is chambered for, as text. Optional; absent when left blank. Example: ".375 CheyTac".

**`rifle.barrel_length_in`** Barrel length in inches, from the bolt face to the muzzle, without a brake or suppressor. Optional; absent when left blank. Nothing uses it today. Example: 29.

**`rifle.muzzle_device`** What is on the muzzle. Guided setup offers "None" (`none`), "Brake" (`brake`) and "Suppressor" (`suppressor`), and "Not said", which stores no key. Stored `none` therefore means the shooter said there is no device, and an absent key means nothing was said. The record accepts any text here.

**`rifle.twist_in`** The barrel's twist in inches per turn: one turn in N inches is N. Required; a new profile made with the app's button starts at 10. Larger is slower. Example: 9. "Don't know yet" in guided setup keeps the number that is there and lists it as not measured.

**`rifle.twist_dir`** The direction of the twist: `R` for right-hand, `L` for left-hand. Required; a new profile starts at `R`. The solver treats any stored value other than `R` as left-hand.

**`rifle.sight_height_in`** The distance from the centre of the bore to the centre of the scope, in inches. Required; a new profile starts at 2.5. Plus is a scope above the bore. "Don't know yet" works as for the twist. Example: 2.1.

**Limits, by writer.** App: the save check the profile screen's sections share. Connector: the input of `edit_profile` and `create_profile`. Conversion: the step every solve goes through first; a profile that fails it cannot be solved, and `edit_profile` and `create_profile` refuse to save it. Solve: what the solver itself refuses.

| Field | App | Connector | Conversion | Solve |
|---|---|---|---|---|
| `rifle.twist_in` | 3 to 40 | 3 to 40 | > 0 | > 0 |
| `rifle.sight_height_in` | none | -10 to 20 | none | none |
| `rifle.barrel_length_in` | > 0 | 4 to 60 | n/a | n/a |

Units are inches (twist: inches per turn). Every layer also refuses a value that is not a number, such as NaN. The app's range for the twist, 3 to 40, is a plausibility check for a real rifle; a twist outside it, down to anything above 0, is still accepted by the conversion and the solver. The sight height has no range in the app, the conversion or the solver: a stored 0 or a negative value is solved as it stands, a bore above the scope. The connector's `what_if` on `solve` and `range_card` takes a sight height of -10 to 20, the same as `edit_profile`. Text limits: the connector's `rifle_name` and `cartridge` are at most 80 characters, and its `muzzle_device` is one of `none`, `brake` and `suppressor` (or null); the app has no limit on the name or the cartridge. The twist direction is `R` or `L` in the connector's input; the app's save check and the conversion do not look at it.

## Who writes it

**The app.** The profile screen asks for the rifle's name, cartridge, twist, twist direction, barrel length and muzzle device in its Rifle section, and for the sight height in its Scope section. Blank cartridge, barrel length and muzzle device remove the key; a blank rifle name is stored as an empty string. A profile started in the app begins with an empty rifle name, a 10 inch twist, right-hand, and a 2.5 in sight height. Every section saves through one check.

**The connector.** `edit_profile` takes `rifle_name`, `cartridge`, `barrel_length_in`, `muzzle_device`, `sight_height_in`, `twist_in` and `twist_dir`; `create_profile` takes the same, and needs the sight height and the twist. It starts from an empty rifle name, a right-hand twist and no cartridge, barrel length or muzzle device, which the call's own values replace. As in guided setup, an empty `cartridge` and a null `barrel_length_in` or `muzzle_device` remove the key, and `none` is stored as said. An input the tool does not know is not used, and the reply names it ("I ignored: ..."). Give only what changes: a value equal to the stored one is not a change.

**Copies and restores.** Copying a shared profile (in the app or with `copy_shared_profile`) writes the rifle exactly as the sharer's record held it, and restoring a deleted profile writes it as the deleted version held it; neither applies the limits above. The [origin](origin.md) and [versions](versions.md) pages describe the two.

**Never fitted.** No calibration writes any of these fields, and the server does not set them. A fit carries them to the new version unchanged.

## Who reads it

**The solver.** The conversion from the stored profile passes the twist, the twist direction and the sight height on, and refuses a twist that is not above 0 and a sight height that is not a number. The name, cartridge, barrel length and muzzle device are not passed.

**Sight height** is where the bullet starts: that far below the line of sight, at the muzzle. The zero is found from that start, so the bore angle at the zero already includes it, and a change of sight height moves every come-up by the same small angle. In a made-up profile (350 gr .375 bullet 2.074 in long, G7 0.414, 1:10, 3,048 fps, 59 F, 50 % humidity, 29.92 inHg station pressure, 100 yd zero, level, Standard model), 0.1 in more sight height lowers the come-up by 0.022 mil at 500 yd, 0.025 mil at 1,000 yd and 0.026 mil at 2,000 yd; with a 200 yd zero the figure at 1,000 yd is 0.011 mil. On a slope the [angle](../options/angle.md) option's Classic value divides the sight height by the cosine of the slope, and every other value keeps it as typed.

**Twist** is read in several places. The stability factor of the bullet comes from the twist, the bullet, the speed and the air, and the Standard and Physics models use it for spin drift and aerodynamic jump; the [spinDrift](../options/spinDrift.md) option's Classic value ignores that factor and takes a fraction of the come-up that the twist alone sets, and the [aeroJump](../options/aeroJump.md) option's Classic value ignores the twist but reads its direction. The Spin model flies the bullet with a spin rate of speed over twist, chosen by the [dynamics](../options/dynamics.md) option, and the Spin model's crosswind jump option, [aeroJumpSpin](../options/aeroJumpSpin.md), in either of its forms, reads the twist and takes its sign from the twist direction. When no measured coefficient set exists, the estimate of the coefficients takes the twist too, with the rules chosen by [estimatorRules](../options/estimatorRules.md). In the same profile at latitude 45 degrees, no wind, 1,500 yd, the Standard model's windage is 0.416 mil of correction at 1:8, 0.339 at 1:10 and 0.297 at 1:12, all to the left for a right-hand twist; the elevation does not change with the twist in the Standard model.

**Twist direction** is the sign of the spin drift and the jump. Spin drift to the right needs a left correction for a right-hand twist. Reversing the direction reverses the sign of that drift and of the jump in a crosswind. It does not mirror the whole windage, because the Earth's rotation is not mirrored: in the profile above, 1:10 right-hand reads 0.339 mil left and left-hand reads 0.135 mil right at 1,500 yd, the same conditions.

**The fitter.** A calibration solves every group with the twist, direction and sight height of the version being fitted, and first drops the groups shot with a version where any of the three is different. The group is listed as left out, with the reason ("different sight height"). The admins' pooled fit lets each profile's sight height move a little as a working value (a prior of 0.25 in) to absorb a badly measured one; it writes nothing back.

**The app.** Every answer goes through the same conversion. The editor and guided setup show the fields. The Workbench's bullet panel shows the twist and tries another one on a draft copy for its Spin panels. The printable setup worksheet lists all seven fields as blanks to fill in.

**The connector.** Every tool that solves reads the three through the conversion. Some look at them on purpose:

- `check_profile` works out the stability from the twist and the bullet ("a 1:20 twist would not stabilise this bullet" below a stability of 1.0, "marginal" below 1.3) and notes a sight height outside 1.0 to 3.5 in as unusual. It also repeats "not measured yet" for a twist or sight height on the profile's unmeasured list.
- `solve` and `range_card` accept a `what_if` sight height for one answer; nothing is saved.
- `sensitivity` reports what a tenth of an inch of sight height is worth at each range.
- `explain_dope` can offer a different sight height as the explanation of come-ups the shooter confirmed, and accepts a wider range (1.5 to 3.0 in) when the sight height is on the unmeasured list than when it was measured (within 0.25 in of the entry).
- `edit_profile` and `create_profile` write the fields and refuse to save a twist or sight height the conversion refuses.

**The server.** The admins' pooled export lists each profile's twist and sight height beside its zero range. It has no column for the name, cartridge, barrel length, muzzle device or twist direction.

## Why it is stored

**Twist, twist direction and sight height.** They are facts of the rifle that change the answer, and no other field can stand in for them. The sight height decides the start of every flight; the twist and its direction decide the spin the bullet has.

**Name.** To tell rifles apart in a list when one profile name covers rifle and load together.

**Cartridge, barrel length and muzzle device.** Nothing computes with them today. They are kept so that a profile (and a shared log) says what rifle the numbers came from. The guided setup help asks the shooter to use the same muzzle device when zeroing, chronographing and shooting, because the device can move both the zero and the velocity; the app keeps the answer but does not compare it between versions.

## Changing it

An edit saves a new version and each logged group keeps the version it was shot with; the [versions](versions.md) page explains that once for every field.

**The edit category is "shape" for the twist, the twist direction and the sight height.** The default is to reset the calibration. In the app, a profile with anything a reset could remove (a fitted curve, a calibration record, a Spin trim, velocity-temperature rows, a scope tracking factor other than 1) gets the keep-or-reset question with "reset" already chosen, and the warning says the calibration may no longer describe this bullet. The connector asks only when a fitted curve (its knots, factor, DSF table or floor) or a calibration record would be removed: it refuses to save until it is called again with `calibration` set to keep or reset. An edit to the rifle's name, cartridge, barrel length or muzzle device is in no category and never asks. What a reset removes is on the [calibration](calibration.md) page.

**Older groups.** A fit is always of the profile's newest version, and it uses a group only if the version the group was shot with has the same twist, the same twist direction and the same sight height, and the same bullet and zero. A group that fails is listed as left out with the reason; a later version that restores the value makes it usable again. So a sight height changed with the calibration kept leaves a profile with a fitted curve and no usable earlier groups until new ones are shot. A change of name, cartridge, barrel length or muzzle device never changes which groups are used. How a group records its version is on the [observation](../log/observation.md) page.

## Sharing and privacy

All seven fields read "as stored": a reader of a shared log sees the rifle as the owner does, on a share with one person, with the public or with the admins, and whether or not location and notes are hidden. Hiding notes empties the notes field of the profile, the sessions and the groups, and removes each confirmed come-up's note; it does not touch the rifle's name, cartridge or muzzle device, which are typed text and reach every reader as typed. A shared rifle name, cartridge and barrel length can say what rifle someone owns; the twist, direction and sight height let a reader reproduce the shooter's numbers.

---

[All reference pages](../index.md)
