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#
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#
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.
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<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#
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#
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<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.
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).
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<FAcresFieldOverride> |
Per-field overrides, at most one entry per field. | ||
Delta |
TArray<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.
FAcresFieldSetup::Fields#
Field polygons from Content/Simulation/ACRE/fields.json, sorted by id. Loaded once.
Returns: All fields (empty if the file is missing).
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.
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.
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).
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.
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).
FAcresFieldSetup::Find#
Look up a field's override without creating one.
| Argument | Description |
|---|---|
Field |
Field id 1-59. |
Returns: The override, or nullptr.
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".
FAcresFieldSetup::HasEdits#
Whether any node has a non-zero terrain edit.
Returns: True if Delta holds at least one non-zero value.
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.
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).
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).
FAcresFieldSetup::ResetField#
Remove all terrain edits inside one field's polygon.
| Argument | Description |
|---|---|
Field |
Field id 1-59. |
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). |
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.
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). |
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.
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.
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.