Skip to content

AcresEnvironmentModel.h#

Acres/Source/Acres/AcresEnvironmentModel.h Generated

Weather, sky and clock model for the ACRE site (pure C++, no Unreal objects).

One AcresEnv::Model turns a Settings block (date, site, temperature range, wind, clouds, rain plan, fog) into a State snapshot every time Step is called: sun position, clear-sky and cloudy irradiance, air temperature, dew point and humidity, wind at 10 m and at crop height, rain rate, visibility, evaporation and a surface water film. Everything is SI plus a few meteorological conventions (degrees, mm, mm/h, hours of local civil time).

The equations come from the literature: NOAA solar position, Haurwitz (1945) clear-sky irradiance, Kasten and Czeplak (1980) cloud transmission, Parton and Logan (1981) diurnal temperature, Magnus humidity (Alduchov and Eskridge 1996), Priestley-Taylor evaporation with FAO-56 constants, Koschmieder visibility. Random variability uses exact Ornstein-Uhlenbeck updates driven by a seeded SplitMix64 generator, so a given seed and step sequence always gives the same weather.

The Unreal adapter (FAcresEnvironmentRuntime in AcresEnvironment.h) owns one model and steps it on the physics thread. The model has no Unreal types, so it compiles and can be tested without the engine.

SolarPosition#

Sun position from the NOAA "General Solar Position Calculations" (fractional-year series).

Argument Description
DayOfYear Day of year, 1 to 365.
LocalHour Local civil time, h.
UtcOffsetH Local time minus UTC, h (-4 for EDT).
LatDeg Latitude, degrees north.
LonDeg Longitude, degrees east (negative in the Americas).
ElevationDeg Output, geometric elevation above the horizon, degrees (no refraction).
AzimuthDeg Output, degrees clockwise from north.
void SolarPosition(double DayOfYear, double LocalHour, double UtcOffsetH, double LatDeg, double LonDeg, double& ElevationDeg, double& AzimuthDeg);

Example

double El, Az;
AcresEnv::SolarPosition(196, 13.9, -4, 40.47, -86.99, El, Az); // El ~ 71 deg, Az ~ 180 deg

SunriseSunset#

Sunrise and sunset times from the NOAA hour-angle formula (zenith 90.833 deg: refraction plus the sun's radius).

Near the poles the hour-angle cosine is clamped, so polar day gives sunrise and sunset 12 h either side of solar noon and polar night puts both at solar noon, instead of NaN.

Argument Description
DayOfYear Day of year, 1 to 365.
UtcOffsetH Local time minus UTC, h.
LatDeg Latitude, degrees north.
LonDeg Longitude, degrees east.
SunriseH Output, local sunrise, h.
SunsetH Output, local sunset, h.
void SunriseSunset(double DayOfYear, double UtcOffsetH, double LatDeg, double LonDeg, double& SunriseH, double& SunsetH);

ClearSkyGhi#

Clear-sky global horizontal irradiance, Haurwitz (1945): 1098 cos(z) exp(-0.057 / cos(z)).

Argument Description
ElevationDeg Sun elevation, degrees.

Returns: Irradiance on a horizontal surface, W/m2. 0 when the sun is below the horizon.

double ClearSkyGhi(double ElevationDeg);

CloudTransmission#

Fraction of clear-sky irradiance that gets through cloud, Kasten and Czeplak (1980): 1 - 0.75 N^3.4.

Argument Description
Cover Cloud cover fraction N, 0 to 1 (clamped).

Returns: Transmission, 1 (clear) down to 0.25 (overcast).

double CloudTransmission(double Cover);

DiurnalTemperature#

Air temperature through the day, Parton and Logan (1981).

Daytime (from 0.17 h before sunrise to sunset) is a truncated sine from LowC that peaks about 1.7 h after solar noon. After sunset the temperature decays exponentially (b = 2.2) toward the next morning's low, with a linear correction so the curve lands on the low.

Argument Description
Hour Local time, h (0 to 24).
Sunrise Local sunrise, h.
Sunset Local sunset, h.
LowC Today's minimum, deg C (used before dawn and for the daytime sine).
HighC Today's maximum, deg C.
NextLowC Tomorrow's minimum, deg C (the evening decays toward it).

Returns: Air temperature, deg C. No cloud damping or noise; Model::Step adds those.

double DiurnalTemperature(double Hour, double Sunrise, double Sunset, double LowC, double HighC, double NextLowC);

RelativeHumidity#

Relative humidity from air temperature and dew point with the Magnus formula (Alduchov and Eskridge 1996 coefficients 17.625 and 243.04 deg C).

Argument Description
AirC Air temperature, deg C.
DewC Dew point, deg C (capped at AirC).

Returns: Relative humidity, 0 to 1.

double RelativeHumidity(double AirC, double DewC);

PriestleyTaylorMmH#

Potential evaporation, Priestley and Taylor (1972) with alpha 1.26.

Uses FAO-56 constants: saturation slope from the Tetens form, psychrometric constant 0.0665 kPa/deg C, latent heat 2.45 MJ/kg, and hourly soil heat flux G = 0.1 Rn by day and 0.5 Rn at night.

Argument Description
NetRadiationWm2 Net radiation at the surface, W/m2.
AirC Air temperature, deg C.

Returns: Evaporation rate, mm/h (never negative; no dew formation).

double PriestleyTaylorMmH(double NetRadiationWm2, double AirC);

RainPlanFraction#

Cumulative fraction of the storm total that has fallen at relative time U.

The storm hyetograph (rain rate over time) follows a Beta(1.6, 3) density, which puts the peak about a quarter of the way through and a long tail after it, like a convective storm. The regularised incomplete Beta function is integrated numerically (64-panel Simpson).

Argument Description
U Relative storm time, (hour - start) / (end - start). Clamped to 0 to 1.

Returns: Fraction of the total delivered, 0 to 1 (0.765 at U = 0.5).

double RainPlanFraction(double U);

DayOfYear#

Day of year (1-based) for a Gregorian date, with leap years. Month is clamped to 1-12; Day is not checked.

int DayOfYear(int Year, int Month, int Day);

Example

AcresEnv::DayOfYear(2026, 7, 15); // 196

FogMode#

enum class FogMode : uint8_t

How visibility is decided.

Auto: radiation fog forms and clears by itself from humidity, wind, cloud and sun (plus haze and rain). Off: no fog layer; humidity haze and rain still reduce visibility. Fixed: visibility is pinned to Settings::FixedVisibilityM.

Value Description
Auto
Off
Fixed

CloudPreset#

enum class CloudPreset : uint8_t

Base sky type. Each preset sets a base cloud cover fraction: Clear 0.04, FairCumulus 0.25, PartlyCloudy 0.5, Overcast 0.93. Afternoon convection (not for Overcast), storms and noise are added on top.

Value Description
Clear
FairCumulus
PartlyCloudy
Overcast

Settings#

struct Settings

Scenario inputs for the model. Defaults are a mid-July fair-weather day at ACRE and match Acres/Content/Simulation/environment.json.

Times of day are local civil time in hours. The rain window uses the simulation's continuous clock: hours after local midnight of the start day, so 26 means 02:00 the next day.

Name Type Unit Default Description
Year, Month, Day int Start date (Gregorian). Year, Month (1-12), Day (1-31). ACRE observes US Eastern time.
StartHourLocal double 10 Local clock time at simulation start, h (0 to 24).
UtcOffsetH double -4 Local time minus UTC, h (-4 for EDT in summer, -5 for EST).
LatitudeDeg, LongitudeDeg double Site latitude and longitude, degrees (WGS84, east positive). Default is the ACRE tile centre, about 1 m accuracy.
SecondsPerGameMinute double 60 Real seconds per simulated minute. 60 is real time, 1 runs the day 60 times faster.
LowC double °C 16 See above.
HighC double °C 28 The start day's minimum and maximum air temperature, deg C.
DayToDaySigmaC double °C 1.2 Standard deviation of the random shift applied to later days' low and high, deg C (0 repeats the same day).
WindMps double m/s 3.5 Mean wind speed at 10 m under full daytime mixing, m/s (nights run at 65 % of it).
WindFromDeg double ° 225 Mean direction the wind blows FROM, degrees clockwise from north.
TurbulenceIntensity double .2 Standard deviation of speed over mean speed (0.2 is typical over farmland).
RoughnessM double m .03 Aerodynamic roughness length of the surface, m (0.03 is open farmland), used for the crop-height wind.
Clouds CloudPreset CloudPreset::FairCumulus Base sky type.
Rain bool false Whether the scheduled rain event below happens.
RainStartH double 15 See above.
RainEndH double 16 Rain window on the continuous clock, h after local midnight of the start day.
RainTotalMm double mm 10 Storm total depth, mm, delivered with a front-loaded shape (see RainPlanFraction).
PriorRainMm double mm 0 Rain assumed to have fallen before the start, mm.
PriorRainHours double 12 How long before the start it fell, h. The model itself ignores both; the farm runtime uses them to pre-wet the soil.
Fog FogMode FogMode::Auto Fog mode.
FixedVisibilityM double m 800 Visibility used when Fog is FogMode::Fixed, m (the model floors it at 20 m).
ManualRainMmH double -1 Manual rain rate, mm/h. A value >= 0 replaces the scheduled rain (the in-game J key sets 20 or 0); negative follows the schedule.
Seed uint64_t 42 Seed for all random variability. Same seed and same step sequence give the same weather.

State#

struct State

Everything the model computed at the current simulated time. Read it with Model::Current().

Name Type Unit Default Description
SimS double s 0 Simulated seconds since the start, s.
DayIndex int 0 Day number since the start day, 0-based.
LocalHour double 0 Local civil clock, h in [0, 24).
DayOfYear double 0 Day of year of the current day, 1-based (keeps counting past 365; the solar maths wraps it).
SunElevationDeg double ° 0 Geometric sun elevation above the horizon, degrees (no refraction).
SunAzimuthDeg double ° 0 Degrees clockwise from north. SunriseH,
SunriseH double 0 See above.
SunsetH double 0 Today's sunrise and sunset, local h (refraction-corrected, NOAA 90.833 deg).
ClearGhiWm2 double 0 Clear-sky global horizontal irradiance, W/m2.
GhiWm2 double 0 Irradiance after cloud and storm, W/m2.
CloudTransmission double 1 GhiWm2 / ClearGhiWm2, 0 to 1.
AirC double °C 20 Air temperature, deg C.
DewPointC double °C 12 Dew point, deg C.
RelativeHumidity double .6 0 to 1. DayLowC,
DayLowC double °C 16 See above.
DayHighC double °C 28 Today's planned minimum and maximum, deg C (the farm's crop model reads these).
CloudCover double .3 Sky fraction covered, 0 to 1.
StormDarkness double 0 How dark the storm deck is, 0 (none) to 1 (heavy rain under cumulonimbus); dims light, lowers clouds and turns on the work lights.
RainMmH double 0 Current rain rate, mm/h.
RainTotalMm double mm 0 Rain delivered since the start, mm.
RainPlannedMm double mm 0 Scheduled storm total that falls after the start, mm.
WindMps double m/s 3 Turbulent wind speed at 10 m, m/s.
GustMps double m/s 4 Gust speed, m/s.
WindFromDeg double ° 225 Direction the wind blows from, degrees clockwise from north.
WindCropMps double m/s 2 Wind at 2.5 m (crop height) from the log profile, m/s.
VisibilityM double m 30000 Meteorological visibility, m.
Fogginess double 0 Radiation fog amount, 0 to 1 (1 means about 150 m).
EvaporationMmH double 0 Priestley-Taylor potential evaporation, mm/h (0 while raining).
NetRadiationWm2 double 0 Net radiation at the surface, W/m2 (negative at night).
SurfaceFilmMm double mm 0 Water film on roofs, roads and leaves, mm (0 to 0.3; rain fills it, evaporation empties it).
SurfaceWetness double 0 SurfaceFilmMm / 0.3, 0 to 1, fed to materials so surfaces look wet.

Model#

class Model

The weather model: holds settings, random state and the latest State.

Call Reset once with the settings, then Step with the simulated seconds elapsed. Step size does not change the rain total and the random processes use exact updates, so 1 s or 60 s steps give statistically the same weather. Not thread-safe: FAcresEnvironmentRuntime wraps it in a lock, steps it on the physics thread and copies Current() for the game thread.

Example

AcresEnv::Settings S;
S.Rain = true; S.RainStartH = 14; S.RainEndH = 16; S.RainTotalMm = 25;
AcresEnv::Model M;
M.Reset(S);
for (int I = 0; I < 3600; ++I) M.Step(10); // 10 simulated hours
const double MmH = M.Current().RainMmH;

Model::Reset#

Stores the settings, reseeds the random generator, clears all noise states and evaluates the start state (Step(0)).

If the start time falls inside the rain window, the part of the storm before the start counts as already fallen: RainPlannedMm is only what remains and there is no catch-up burst. HighC is raised to LowC + 1 if needed.

Argument Description
S Scenario settings.
void Reset(const Settings& S);

Model::Step#

Advances the model by DtS simulated seconds and recomputes the whole State.

Argument Description
DtS Simulated seconds to advance, s (0 re-evaluates without advancing time or accumulators).
void Step(double DtS);

Model::TimeScale#

Simulated seconds per real second (60 / SecondsPerGameMinute). 1 is real time.

double TimeScale() const ;

Model::Current#

Latest computed state.

const State& Current() const ;

Model::Config#

Settings in use (after Reset's fix-ups and any runtime changes).

const Settings& Config() const ;

Model::SetManualRain#

Sets a manual rain rate, mm/h, that replaces the schedule. A negative value returns to the schedule.

void SetManualRain(double MmH) ;

Model::SetSecondsPerGameMinute#

Changes the clock speed at runtime. S is real seconds per simulated minute, floored at 0.001 s.

void SetSecondsPerGameMinute(double S) ;