Historical account, vehicle, and dossier data is useful only after its owner and content readiness are established. The hard part is not the formula; it is proving that the baseline is populated, belongs to the current identity, and was not overwritten by an early empty cache.
Baseline sources
| Source | Strength | Risk |
|---|---|---|
| Garage-visible dossier | Best public baseline when synchronized | Not always available once already in battle |
| Disk-backed native cache | Can survive reconnect or immediate queueing | Record presence can still decode to an empty default record |
| Mod-owned snapshot | Controlled schema and validation | Only exists after the mod previously saw a valid baseline |
| Battle result record | Final authoritative outcome | Arrives too late for live projection |
Empty cache is not zero
A private cache can contain a vehicle record before it contains meaningful vehicle history. Do not treat membership as proof that the value is valid. For an established vehicle, require a populated discriminator such as a positive battle count or another verified non-default field before accepting the cache as a baseline.
Never overwrite good data with empty data
If a previously confirmed snapshot exists and the current cache decodes to an empty/default dossier, keep the confirmed snapshot and show a loading or unavailable state instead of replacing it with zero.
Dossier readiness is content readiness
A native or cached dossier object can exist before it contains the battle-start baseline that a feature needs. Validate the decoded content, not just the cache key or object membership.
- Require a discriminator that proves the record is populated, such as a positive historical battle count or another verified non-default field for an established vehicle.
- Keep the last confirmed good baseline when the current cache temporarily decodes as empty.
- Log the owner identity, vehicle identity, cache generation, and discriminator together when rejecting a baseline.
- During reconnect, hold the previous confirmed baseline until the current battle context either confirms replacement data or ends.
Snapshot policy
- Write snapshots only after a source has been positively validated.
- Store the vehicle identity, arena-independent account identity, client version marker if useful, and the data timestamp.
- Validate schema and numeric ranges before loading.
- Keep battle-only entity IDs out of persistent data.
- Do not cross-use snapshots between vehicles, accounts, or regions.
def _select_baseline(vehicle_key):
garage = _read_valid_garage_dossier(vehicle_key)
if garage and garage.battle_count > 0:
_save_snapshot(vehicle_key, garage)
return garage
cached = _read_native_cache_dossier(vehicle_key)
if cached and cached.battle_count > 0:
_save_snapshot(vehicle_key, cached)
return cached
snapshot = _load_confirmed_snapshot(vehicle_key)
if snapshot and snapshot.battle_count > 0:
return snapshot
return None # Show loading/unavailable instead of pretending the baseline is zero.
Live projection versus final result
Live feedback is useful for projection, but final result records may include corrections, merged events, assists, mode modifiers, or late-delivered data. Keep the live ledger separate from final reconciliation.
- Build live projection from the currently verified battle-event sources.
- Deduplicate repeated or summarized events.
- Handle respawn or controlled-vehicle changes explicitly.
- Reconcile against final results when available.
- Update the next baseline only from an authoritative or verified source.
Preserve native field shapes
Derived values should return to the type and precision used by the native dossier contract before they are persisted or published. A mathematically convenient float is not automatically a valid replacement for an integer-owned field.
For example, the current vehicle dossier stores movingAvgDamage as an integer damage
value. A projected rolling update should round back to an integer at the contract boundary;
repeatedly persisting floats can drift away from the game-shaped value.
- Inspect the producer, serializer, and consumers to establish the native field shape.
- Keep higher precision inside a temporary calculation only when needed.
- Normalize once at the persistence or publication boundary, using the verified rounding rule.
Reconnects and replays
Reconnects can enter battle before the normal garage synchronization path completed. Replays may lack the same account services entirely. Treat both contexts as partial-data modes and make the UI honest about uncertainty.
- Use last verified snapshots for reconnect recovery.
- Reject empty cache records for established vehicles.
- Do not assume replay playback has account-owned services.
- Clear live ledgers on arena identity changes and replay seeks.
Diagnostics
| Question | Diagnostic |
|---|---|
| Was this baseline actually synchronized? | Log source, vehicle key, battle count, timestamp, and validation result. |
| Did a reconnect use stale data? | Compare arena identity and snapshot timestamp. |
| Did final results disagree? | Keep live event ledger IDs so repeated summaries can be audited. |
| Did a replay seek corrupt state? | Log seek/rewind, clear cached entities, and rebuild from replay-visible data. |
Denominator and counter provenance
Dossier assistance, blocked-damage and stun averages can use distinct eligible-battle denominators rather than all career battles. Hit counters also cross a mapping boundary between result directEnemyHits and the dossier field named directHits. Preserve native unavailable conventions and raw field provenance before formatting. See dossier accounting contracts; a baseline snapshot alone does not establish which denominator belongs to a metric.
Battle Royale average level uses two stored histograms
BattleRoyaleVehicleStats.getAverageLevel divides the weighted level sum from brlevels by its battle count, which is derived separately from brplaces. It does not divide by the number of entries or total counts in brlevels, and it does not look up the vehicle descriptor's tier. Preserve both stored sources when reproducing this metric.
The account provider sums the per-vehicle level totals and battle counts before dividing and rounding to one decimal place. For supplied records with two battles at level three and eight at level seven, this gives (6 + 56) / (2 + 8) = 6.2, rather than averaging the two vehicle means. The profile's Battle Royale average-level field formats that getter result.
Selected original getters and rounding code were checked with inert stored maps. Controlled changes to the level and placement maps confirmed their separate numerator and denominator roles. This establishes a client read contract; it does not prove how a server creates or synchronizes those histograms, that inconsistent records occur, or what a rendered profile displays.
Profile chart percentages scale against the largest row
The profile payload helper setChartDataPercentages writes percentValue = int(100 * yField // maxYField). Its denominator is the largest supplied row value, not the sum of rows or the dossier's battle count. Ordinary type, nation and level chart builders and the Battle Royale chart builders use this helper.
For a nonempty chart of nonnegative counts with a positive maximum, the largest rows receive 100; the values need not sum to 100. Supplied counts (2, 4, 4) produce (50, 100, 100), while (1, 3) produce (33, 100). An all-zero chart uses denominator one and retains zero outputs. The original yField values remain in the payload.
Keep these scale values separate from count shares and statistical percentages. Callers can also supply unavailable-category sentinels; the nonnegative-count example does not define their visual treatment. Selected original helper checks used inert row dictionaries, with actual chart builders inspected statically. Profile rendering, native models and server counter production were not exercised.