Reload time can mean a duration or a rate

The gun descriptor's reloadTime is a duration. In the garage calculation layer, VehicleParams.reloadTime obtains a rate in shots per minute for supported guns. The field name alone is insufficient to choose the unit.

reloadTimeSecs is a separate interface. Magazine and autoreloader vehicle rows return None there; that means the single-duration row is unavailable, not that reload takes zero seconds. Special gun providers have additional contracts.

A magazine rate includes the firing cycle

getShotsPerMinute combines reload time with magazine and burst intervals. For a conventional four-shot magazine, a 30-second reload and two-second interval between shots give 4 × 60 / (30 + 3 × 2), or about 6.67 shots per minute. This example describes the configured cyclic rate, not the time until the next shot.

The autoreloader branch treats the rate calculation differently: it uses one clip-count unit and floors the supplied reload duration at the intra-clip interval. Preserve the per-shell timing data when explaining that mechanic.

Configured DPM is an estimate

A configured rate combined with the active shell's average damage describes a theoretical damage rate. It does not prove sustained battle damage, hit probability, penetration, a chosen autoreloader firing sequence or server acceptance of a shot. Keep the selected shell and firing model attached to the estimate.

Dual-gun timing fields describe separate projections

The dual-gun reload utility scales the configured reload entries. The dual branch of VehicleParams takes adjusted reload-time extrema through the shared rate helper; it does not preserve the original reload-entry order. Public fields then expose different representations:

FieldDual-gun contract
reloadTimeUnavailable for dual guns, rather than a public scalar rate.
reloadTimeSecsConverts computed rate components with 60/rate on its dual branch; earlier clip/autoreloader guards make this field unavailable.
clipFireRateOn its dual branch: sum of adjusted reload times, configured rateTime, and entry count. Earlier clip handling and the public auto-shoot gate remain separate.
chargeTimeConfigured charge time and reload-lock time as a separate pair.

Charge and lock durations are not automatically added to those rate inputs or the compound clip row. Situational skill factors have their own provider paths. Preserve the field shape, branch and units instead of assembling a salvo-cycle formula or treating the clip row as one elapsed duration.

Selected utility, rate and provider methods were checked with a synthetic gun and controlled trait/skill dependencies. They confirmed that scaling reload entries changed the derived rates and compound reload component while leaving the charge pair unchanged; changing charge time did not change those rate inputs. Actual gun configuration, reload progression, salvo cadence, achievable DPM and rendered rows were not exercised.

Twin-gun rows can preserve different identities

The getTwinGunReloadTime utility returns adjusted one-gun and twin-gun durations in that named order. The vehicle provider instead takes their extrema through the shared rate calculation, then reverses the rate components before converting them with 60/rate for reloadTimeSecs. Its earlier clip/autoreloader guards can make that row unavailable.

That projection loses the original field identity. With synthetic ordinary single-shot inputs and neutral skill factors, configured durations (12, 6) and (6, 12) both produce the vehicle duration pair (6, 12). This illustrates numeric projection, not an assertion about supported vehicle configurations or live mode timing.

By contrast, GunParams.reloadTimeSingleGun and reloadTimeTwinGun return the selected gun's separately named raw configuration fields. The module tooltip lists those separate keys; the vehicle tooltip changes the title of the existing vehicle row to twinGunReloadTime without rebuilding its components. A renamed row does not restore named one-gun/twin-gun positions. Keep the provider, units and component identities attached to copied values.

Selected readable helper, provider and module getter checks used inert descriptors and controlled dependencies. Actual configurations, firing-mode changes, runtime reload behavior, rendering and the client Python 2 runtime were not exercised.

Unlimited-clip classification keeps loading time separate

The gun reader derives unlimitedClip when auto-shoot configuration is present and clip capacity equals maxAmmo; the default auto-shoot branch removes the tag. The parameter predicate reads that tag. This classification describes configured clip capacity, rather than querying remaining ammunition or establishing inexhaustible ammunition.

The vehicle provider keeps different timing rows: for an unlimited-clip gun, shellLoadingTime selects the loading component of the private clip row. The separate continuousShotsPerMinute computes round_py2_style(60 / clipInterval) for auto-shoot guns. The finite-magazine autoShootClipFireRate row is unavailable when the gun is unlimited-clip. An absent row does not make loading duration zero or turn the continuous rate into a complete firing cycle.

A selected-body check used a synthetic 100-round clip equal to its configured maximum, a 0.2-second interval and a supplied reload helper returning nine seconds. It produced loading time 9, continuous rate 300 and no finite-magazine row. Changing only clip capacity to 64 selected the finite row (9, 64) instead. These values illustrate provider branches, not a real gun or sustained battle cadence.

The module tooltip's auto-shoot layout also lists loading duration and continuous rate separately; module and vehicle providers retain their own context and aggregation rules. Parser-region and provider checks used inert fields and controlled reload/rounding dependencies. Actual XML parsing, provider construction, ammunition consumption, overheating, rendering, server behavior and the client Python 2 runtime were not exercised.

Burst rows retain different component provenance

The VehicleParams.burstFireRate getter returns (interval, number of bursts, shots per burst) for its configured gun: the middle component is clip capacity divided by burst size. It requires a burst-capable descriptor and excludes the chargeable-burst mechanic. Despite the getter name, its first component is an interval, not shots per minute.

The module raw-parameter builder instead appends an interval/size pair for each eligible descriptor and retains that sequence. GunParams.burstTimeInterval and burstSize read its first pair. burstCount divides the separately aggregated minimum clip capacity, shellsCount[0], by that first size. These module fields are not all bounds or guaranteed to come from one variant.

For an illustrative raw sequence (0.2, 3, 0.5, 2) and clip-capacity bounds (6, 12), the module getters select interval 0.2, size 3 and count 2. Reordering only the pairs selects 0.5, size 2 and count 3. This demonstrates reader provenance with synthetic inputs, not a claim about real cache order or supported vehicle combinations. The module tooltip lists interval, count and size as separate fields in its magazine/autoreloader branches. Preserve their identities and provider context when adapting them to another view.

Selected readable property checks used inert raw maps, gun fields and trait/division adapters; producer and tooltip routing were source-inspected. Actual cache construction, live configurations, firing sequences, rendering, server cadence and the client Python 2 runtime were not exercised.

Heated aiming values are configured endpoints

The garage VehicleParams.aimingTime temperature-gun branch returns (heated, base). The getHeatedAimingTime helper multiplies the supplied base by the aiming-time modifier from the final configured thermal state. The thermal-state reader sorts states by their temperature thresholds, so this selects the highest-threshold state, rather than searching for the smallest aiming-time value.

Preserve those state labels and tuple positions. This is a configured endpoint/base pair, not a sample of the gun's current heat, a current battle aiming duration or a guaranteed numeric minimum/maximum pair. If that final state has no matching aiming modifier, the helper returns the base unchanged, so equal endpoints are possible.

For example, a supplied base of five seconds and final-state multiplier 0.6 produce (3, 5). Selected readable helper/provider checks used synthetic state lists and inert descriptors; parser ordering was inspected statically. No thermal simulation, live configuration, native calculation, client rendering or Python 2 runtime was exercised.

Enabling server aim seeds a presentation value

When the marker decorator enables SERVER_MODE_ENABLED, it copies the client marker's current position and sizes into the server marker. Later updates are routed by marker type. The first visible server-mode position can therefore be an initialization value copied locally; it is not evidence that a fresh server sample has arrived.

Game files and evidence

These links follow the public repository's default branch. Search each file for the symbols below. They establish client-side calculations and state handling; they do not verify server configuration or live behavior.

Game fileSymbols to inspectWhat it establishes
gui/shared/items_parameters/__init__.pygetShotsPerMinuteMagazine, burst and autoreloader rate calculation.
gui/shared/items_parameters/params.pyreloadTime; reloadTimeSecs; __calcReloadTimeGarage rate and duration interfaces and mechanic branches.
AvatarInputHandler/gun_marker_ctrl.pysetFlag; update; createGunMarkerMarker initialization and client/server update routing.

Use this in a mod

Read Vehicle Calculation Contracts for parameter and shell selection, and Input, Cursor & Camera for aiming presentation ownership.