Skip to content

AcresFieldSetup.h#

Acres/Source/Acres/AcresFieldSetup.h Generated

Per-session field configuration from the menu's Fields tab: crop type, soil, starting wetness and terrain edits.

Soil can be the mapped SSURGO units, a texture-class preset (Rawls et al.) or custom hydraulic values. Terrain edits are a height offset (m) on the survey DTM grid (1001 x 1001 nodes, 1.524 m apart), confined to field polygons and clamped to +/- 1 m. The edits are applied consistently to wheel contact (AcresVehicle), the routed-water bed and crop positions (AcresFarmRuntime), the rendered ground (AcresSoilVisuals, persistent tiles) and ground-cover instances. Chassis rigid-body collision keeps the survey mesh (as with ruts); the +/- 1 m limit keeps that safe.

The menu (AcresMenu.cpp) edits a FAcresFieldSetup inside the session and saves it to a folder; the game process is started with -FieldSetup=<folder> and every system reads it through FAcresFieldSetup::Active().

Coordinates: "world" means Unreal world metres (X east, Y south). "UV" means survey-grid coordinates in cells: U = (X - Origin) / Step, V = (Y - Origin) / Step, so node (I, J) sits at UV (I, J).

FAcresSoilPreset#

struct FAcresSoilPreset

One soil texture preset offered in the menu.

"ssurgo" and "custom" are placeholders with all numbers 0 (Saturated == 0 means "not a real preset").

Name Type Unit Default Description
Id const TCHAR* Id: stable key stored in field-setup.json ("loam", "silt_loam", ...).
Label const TCHAR* Label: text shown in the menu.
KsProfileMmH, KsSealedMmH, SuctionM, Saturated, FieldCapacity, Wilting double KsProfileMmH: unsealed saturated conductivity, mm/h. KsSealedMmH: crusted-surface conductivity, mm/h. SuctionM: Green-Ampt wetting-front suction, m. Saturated, FieldCapacity, Wilting: water contents at saturation, -33 kPa and -1500 kPa, m3/m3.

FAcresFieldOverride#

struct FAcresFieldOverride

Menu settings for one field. Fields without an override use the defaults of the map.

Name Type Unit Default Description
Field int 0 Field number, 1-59 (the "Fxx" id).
Crop FString "" keeps the planted crop; "corn", "soybean" or "potato" swaps it; "empty" leaves the field bare (planted fields only).
Soil FString TEXT("ssurgo") Soil source: "ssurgo" (mapped units, default), a preset id, or "custom" (use the numbers below). A preset that names a soil library class also sets the field's terramechanics (SoilClassOf).
KsMmH, KsSealedMmH, SuctionM, Saturated, FieldCapacity, Wilting double Custom or preset hydraulics. KsMmH: unsealed Ks, mm/h. KsSealedMmH: crusted Ks, mm/h. SuctionM: Green-Ampt suction, m. Saturated, FieldCapacity, Wilting: water contents, m3/m3. Choosing a preset in the menu copies its values here; the runtime clamps them (Ks >= 0.01 mm/h, sealed <= Ks, suction 0.01-1 m, saturated 0.25-0.6, field capacity and wilting at least 0.02 below the level above).
Wetness double -1 Starting surface wetness. < 0: use the global default (farm.json, 0.5). 0 = wilting point, 1 = field capacity, above 1 moves toward saturation (1.3 = 30 % of the way from field capacity to saturation).

FAcresFieldOverride::IsDefault#

True when nothing is overridden (such entries are not saved).

Returns: True if Crop is empty, Soil is "ssurgo" and Wetness < 0.

bool IsDefault() const ;

FAcresFieldInfo#

struct FAcresFieldInfo

Geometry of one field from ACRE/fields.json.

Name Type Unit Default Description
Id int 0 Field number, 1-59.
Cover FString Land cover label from fields.json. Fields marked "unassigned" (or with no label) are planted with corn by default: Cover reads "corn" and bGenerated is set.
bGenerated bool false True when the level has no crop meshes for this field; AcresFarmRuntime generates its patches at start.
LabelUv FVector2D FVector2D::ZeroVector Label position from fields.json (label_uv), survey UV; the bounds centre when missing.
PolygonUv TArray&lt;FVector2D> Outer ring of the field polygon in survey UV (cells).
BoundsUv FBox2D Bounding box of PolygonUv, UV.
AreaHa double 0 Field area, hectares (shoelace formula on the polygon).

FAcresSeasonField#

struct FAcresSeasonField

One field of the crop season file (Content/Simulation/ACRE/crops_<season>.json, Tools/ACRE/Map/game_crops.py).

Name Type Unit Default Description
Crop int -1 Crop kind (AcresCrops: 0 corn, 1 soybean, 2 potato) or -1 for an unplanted field.
PlantDay int -1 Planting date as days since 1 January of the season's year (0-based), or -1 when the field is unplanted.
bMapped bool false True when the 2026 call was used; false when the documented default applies (low confidence, no call).
Rule FString Rule that decided, from the file (for logs and the menu).

FAcresCropSeason#

struct FAcresCropSeason

A crop season: per-field crop and planting date, and the daily air temperature the degree days are summed over.

Selected with -CropSeason=<name> (default "2026"; "legacy" keeps the old assignment: surveyed patches, corn on unassigned fields, growth from -FarmInitialGrowth). -CropStage=date grows each field from its planting date to the session's environment date; the default "mature" keeps full-grown crops (growth 1) as before.

Name Type Unit Default Description
Name FString Season name ("2026"); empty for legacy (no file).
Year int 0 Year the day numbers count from.
Fields FAcresSeasonField Fields 1..59 (index 0 unused).
MinC, MaxC TArray&lt;double> Daily minimum and maximum air temperature, deg C, from FirstDay (days since 1 January of Year).

FAcresCropSeason::IsValid#

Whether a season file is loaded.

bool IsValid() const ;

FAcresCropSeason::DegreeDaysSincePlanting#

Sum of a degree-day function from the planting day up to (not including) a day, over the recorded days.

Argument Description
Field Field id 1-59.
Day Session day, days since 1 January of Year.
DegreeDays Daily degree days from (min, max) deg C.

Returns: Degree days since planting, deg C day (0 before planting or for an unplanted field).

double DegreeDaysSincePlanting(int Field, int Day, TFunctionRef<double(double, double)> DegreeDays) const;

FAcresFieldSetup#

class FAcresFieldSetup

Field overrides and terrain edits for one session.

The menu builds and edits an instance (Override, Brush, ResetField) and writes it with Save(). The game reads the session's copy through Active(), which loads the folder named by -FieldSetup= once. The static helpers (SoilPresets, Fields, SurveyHeights, FieldAtUv) load their data on first use and cache it.

Example

FAcresFieldSetup S;
S.Override(12).Soil = TEXT("clay");
S.Brush(12, XM, YM, 10, .3, .05, 0, 0); // raise 1.5 cm at the centre of a 10 m brush
S.Save(Dir);
// in the game process, started with -FieldSetup=<Dir>:
const double Z = FAcresFieldSetup::Active().GroundAt(XM, YM);
Name Type Unit Default Description
N static constexpr int 1001 Survey grid nodes per side.
Step static constexpr double 1.524003048006096 Survey grid spacing, m (5 US survey ft).
Origin static constexpr double -762.001524003048 World X and Y of node (0, 0), m.
MaxEditM static constexpr double m 1.0 Largest allowed terrain edit up or down, m.
Overrides TArray&lt;FAcresFieldOverride> Per-field overrides, at most one entry per field.
Delta TArray&lt;float> Terrain edit per survey node, m, row-major J * N + I. Empty means no edits.

FAcresFieldSetup::SoilPresets#

Soil presets in menu order: ssurgo, sand, loamy sand, sandy loam, loam, silt loam, silty clay loam, clay loam, clay, custom.

Returns: The static preset table.

static const TArray<FAcresSoilPreset>& SoilPresets();

FAcresFieldSetup::Fields#

Field polygons from Content/Simulation/ACRE/fields.json, sorted by id. Loaded once.

Returns: All fields (empty if the file is missing).

static const TArray<FAcresFieldInfo>& Fields();

FAcresFieldSetup::SurveyHeights#

Survey heights from ACRE/heights.f32, loaded once.

Returns: 1001 x 1001 heights, m relative to the tile origin (NAVD88 datum), row-major J * N + I. Empty if the file is missing or the wrong size.

static const TArray<float>& SurveyHeights();

FAcresFieldSetup::FieldAtUv#

Field under a survey-grid point (bounding box, then point-in-polygon test).

Argument Description
U Survey U, cells.
V Survey V, cells.

Returns: Field id 1-59, or 0 for none.

static int FieldAtUv(double U, double V);

FAcresFieldSetup::SurfaceMap#

Surface classes of the tile from Content/Simulation/ACRE/surface_polygons.json (Tools/ACRE/Map/game_layer.py), loaded once: roads, yards, grass lanes, verges and dirt tracks as polygons, field elsewhere. Empty when the file is missing (callers then fall back to surfaces.u8).

Returns: The shared map (Unreal world metres, X east, Y south).

static const AcresSim::FSurfaceMap& SurfaceMap();

FAcresFieldSetup::CropSeason#

The session's crop season (-CropSeason=, default 2026), loaded once.

Returns: The season; IsValid() is false for -CropSeason=legacy or a missing file.

static const FAcresCropSeason& CropSeason();

FAcresFieldSetup::Override#

Get the override for a field, adding a default one if there is none.

Argument Description
Field Field id 1-59.

Returns: Reference into Overrides (invalidated by the next insertion).

FAcresFieldOverride& Override(int Field);

FAcresFieldSetup::Find#

Look up a field's override without creating one.

Argument Description
Field Field id 1-59.

Returns: The override, or nullptr.

const FAcresFieldOverride* Find(int Field) const;

FAcresFieldSetup::SoilClassOf#

Soil library class (AcresSoilModel.h) of a field whose soil override is a texture preset with a library counterpart ("sand", "loamy_sand", "sandy_loam", "loam", "silt_loam", "silty_clay_loam", "clay"). The tyres and the implement tools use it inside that field, so the terramechanics and the water grid see the same texture.

Argument Description
Field Field id 1-59.

Returns: The library index, or -1 for no override, the mapped SSURGO soil, "clay_loam" (not in the library) and "custom".

int SoilClassOf(int Field) const;

FAcresFieldSetup::HasEdits#

Whether any node has a non-zero terrain edit.

Returns: True if Delta holds at least one non-zero value.

bool HasEdits() const;

FAcresFieldSetup::DeltaAt#

Terrain edit at a world point, interpolated on the same two triangles per cell as the survey surface.

Argument Description
XM World X, m (east).
YM World Y, m (south).

Returns: Height offset, m (0 without edits). Points outside the grid clamp to the edge.

double DeltaAt(double XM, double YM) const;

FAcresFieldSetup::DeltaNode#

Terrain edit at one survey node.

Argument Description
I Node column (U), 0..1000.
J Node row (V), 0..1000.

Returns: Height offset, m (0 without edits).

double DeltaNode(int I, int J) const ;

FAcresFieldSetup::GroundAt#

Edited ground height at a world point: survey height plus DeltaAt.

Argument Description
XM World X, m.
YM World Y, m.

Returns: Ground height, m (0 if heights.f32 could not be loaded).

double GroundAt(double XM, double YM) const;

FAcresFieldSetup::ResetField#

Remove all terrain edits inside one field's polygon.

Argument Description
Field Field id 1-59.
void ResetField(int Field);

FAcresFieldSetup::Brush#

Apply one frame of a terrain brush stroke inside one field.

Only nodes inside the field polygon and within RadiusM are touched, weighted by a smoothstep falloff (1 at the centre, 0 at the rim). Results are clamped to +/- MaxEditM. Modes: 0 raise by RateMPerS * Dt * weight; 1 lower by the same; 2 smooth, relaxing the edited surface toward the mean of its 4 neighbours at 6 * Dt * weight per call; 3 flatten, relaxing toward FlattenTo at 3 * Dt * weight per call.

Argument Description
Field Field the stroke is confined to, 1-59.
XM Brush centre X, world m.
YM Brush centre Y, world m.
RadiusM Brush radius, m.
RateMPerS Raise/lower rate at the centre, m/s.
Dt Time since the last call, s.
Mode 0 raise, 1 lower, 2 smooth, 3 flatten.
FlattenTo Target absolute height for mode 3, m (the ground height under the brush centre when the stroke began).
void Brush(int Field, double XM, double YM, double RadiusM, double RateMPerS, double Dt, int Mode, double FlattenTo);

FAcresFieldSetup::ToJson#

Serialise the overrides (non-default ones only) and an edits flag. Schema "acres-field-setup-1".

Returns: JSON object as written to field-setup.json.

TSharedRef<class FJsonObject> ToJson() const;

FAcresFieldSetup::FromJson#

Replace Overrides from JSON written by ToJson. Missing keys keep their defaults; entries with a field id outside 1-59 are dropped. Delta is not touched.

Argument Description
J Parsed JSON (null clears the overrides).
void FromJson(const TSharedPtr<class FJsonObject>& J);

FAcresFieldSetup::Save#

Write field-setup.json and, if there are edits, terrain-edits.f32 (1001 x 1001 little-endian float32, m). Without edits an old terrain-edits.f32 is deleted.

Argument Description
Dir Output folder (created if needed).

Returns: True if every file was written.

bool Save(const FString& Dir) const;

FAcresFieldSetup::Load#

Read a folder written by Save. Missing files leave an empty setup; edits are clamped to +/- MaxEditM and non-finite values become 0.

Argument Description
Dir Folder to read.

Returns: Always true.

bool Load(const FString& Dir);

FAcresFieldSetup::Active#

The session's setup, loaded from -FieldSetup=<dir> on first use (and reloaded if the argument changes); an empty setup when the argument is absent.

Returns: Shared, read-only setup.

Note

Uses function-local statics without a lock. Call it first from the game thread (the runtime and visuals do so during initialisation) before other threads use it.

static const FAcresFieldSetup& Active();