Skip to content

improvement: consolidation - shared weather smoothing, state guards, cache pattern #162

Description

@MBarkerUK

Summary

Consolidation audit: what's duplicated across addons and should be one shared source. The macro layer is already consolidated (addons/main/script_macros + script_mod, every addon includes them — the ACE3 pattern, verified). The function layer has three genuine consolidation opportunities and one already-fixed item.

Already Consolidated (verified, no action)

  1. Shared macros: addons/main/script_mod.hpp, script_macros.hpp, script_debug.hpp — every addon's script_component.hpp includes them. Correct.
  2. World latitude: fnc_getWorldLatitude.sqf in core — the single source of truth (the comment references fix: codebase-wide pattern audit - 6 recurring bug classes #154 Pattern 3; returns [signedDeg, magnitudeDeg] so consumers pick the meaning). Coriolis, solar, biome, space weather all call it. The fix: codebase-wide pattern audit - 6 recurring bug classes #154 Pattern-3 inconsistency was already fixed in HEAD.
  3. Eye state: fnc_getEyeState.sqf in optics — single source, consumed by 4 optics functions. Correct pattern.
  4. 108 files reference core cross-addon via EFUNC/EGVAR — the shared-state architecture works.

Consolidation Opportunities (the genuine duplicates)

1. Weather smoothing (EMA) — the biggest one

fnc_getSmoothedWeather.sqf lives in optics but the EMA pattern repeats across 9 optics functions AND cross-addon:

  • optics: applyNightGrain, applyThermalVision, calculateAtmosphericSeeing, calculateAttenuation, calculateMirageIntensity, calculatePrecipitationVisibility, applyEngineThermal (7)
  • maritime: calculateSeaState (1)
  • mobility: applyFlightTurbulence (1)

Action: the EMA weather-smoothing is a shared core concern (all addons need smoothed weather). Move the smoothing primitive to core (or a shared aee_common), have optics re-export it. The 9 optics consumers + 2 cross-addon consumers should call one function, not each hand-roll the EMA.

2. The per-frame state cache pattern

getEyeState caches by diag_frameNo in missionNamespace. The NVG, rain droplets, illuminance, and glare all consume it. The same "one computation per frame, cached, N consumers" pattern should be the standard for expensive per-frame reads (eye position, lux, weather). Consolidate the CACHE PATTERN into one helper (a tiny fnc_getFrameCachedValue or the established convention documented in one place) so new systems don't re-invent it.

3. The state-read guard pattern

The codebase repeatedly does:

private _lux = missionNamespace getVariable [QGVAR(x), default];
if !(_lux isEqualType 0) then { _lux = default; };

The type-guard on state reads (protecting against a nil/garbage value from test edge cases) repeats everywhere. A single fnc_readState [varName, default, type] or a documented macro would remove the boilerplate — and would have caught the #154 Pattern-1 (the , 0 fallback gates) if the guard enforced "sane default, never 0 for a gate."

What Should Be SHARED SOURCE (the design rule)

Component Current home Should be Reason
Shared macros main/ main/ ✅ done
World latitude core/ core/ ✅ done (#154 fix)
Weather smoothing optics/ core or common/ 9 optics + 2 cross-addon consumers
Eye state optics/ core or common/ non-optics systems need it (map lighting #155, glare)
Frame-cache pattern optics/ one documented helper stops re-invention
State-read guard everywhere inline one helper catches the #154 class

The "Common Addon" Question

The mod has no aee_common — core doubles as the shared-state hub. With 108 cross-addon references and the consolidation targets above, the question: should a new aee_common addon hold the shared runtime (weather smoothing, eye state, frame cache, state guards), leaving core as the state publisher? OR keep them in core (fewer addons, simpler)?

Recommendation: keep in core for now — the consolidation is a move into core, not a new addon. A new addon only pays off when the shared runtime exceeds ~10 functions AND core's state-hub role is cleanly separated. At 108 references the plumbing works; adding a 20th addon is a cost, not a win.

Implementation

  1. Move the weather-smoothing EMA primitive into core/functions/fnc_smoothWeather.sqf (the optics getSmoothedWeather becomes a thin wrapper)
  2. Add core/functions/fnc_readState.sqf — the type-guarded state read (with the "never 0 for a gate" rule from fix: codebase-wide pattern audit - 6 recurring bug classes #154)
  3. Document the frame-cache convention in one place (the getEyeState comment is the model)
  4. Update the 11 consumers to the shared functions
  5. NO new addon — consolidation into core

Test Vectors

  • getSmoothedWeather (optics) returns the same values via the core primitive
  • readState with a nil var returns the sane default, never 0 for a gate
  • All 11 EMA consumers produce identical output to today

Related

Labels

core, P2-medium, effort/M, type/improvement, phase/2-expansion, infra

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P2-mediumMedium priority — important but not blockingcoreCore systems, main tick, deterministiceffort/MMedium — 3-5 days, cross-systeminfraInfrastructure and toolingphase/2-expansionPhase 2 — cross-addon wiring, integrationtype/improvementEnhancement to existing feature

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions