This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
AgrarianGameArchive/Docs/TechnicalDesignDocument.md
T

39 KiB

Agrarian Technical Design Document

Purpose

This document defines the technical shape of Agrarian at the foundation stage. It translates the core design direction into practical architecture decisions, runtime boundaries, data contracts, build lanes, and near-term implementation rules.

Detailed designs for multiplayer/networking, persistence, Earth-scale terrain streaming, economy/AGR, and art/code standards are intentionally split into their own roadmap documents.

Current Technical Baseline

Agrarian is an Unreal Engine 5.7 C++ project with Blueprint assets layered on top for early gameplay content and testable prototype objects.

Current project direction:

  • authoritative gameplay state lives on the server;
  • clients receive replicated state for UI and presentation;
  • core gameplay systems are C++ components or actors;
  • content-facing configuration uses Data Assets where possible;
  • MVP terrain starts with one real 1 km x 1 km Ground Zero tile;
  • tile packages can be served from the MVP map tile server;
  • Windows-Builder is the primary Unreal/Visual Studio build VM;
  • Ubuntu-Codex is the source-control and automation workstation;
  • Unraid DevBox hosts shared project storage and supporting VMs.

Runtime Architecture

Server Authority

The server is authoritative for gameplay outcomes.

Server-owned state includes:

  • player survival values;
  • inventory changes;
  • crafting results;
  • world time;
  • weather state applied to gameplay;
  • resource depletion/harvest results;
  • wildlife state;
  • placed structures;
  • persistence save/load decisions.

Clients may request actions, but the server validates and applies results.

Client Responsibilities

Clients are responsible for:

  • player input;
  • camera and local presentation;
  • UI/HUD;
  • local animation;
  • local audio/visual feedback;
  • displaying replicated survival, inventory, weather, and world state;
  • local tile cache storage once streaming matures.

Clients should not directly call public weather APIs or mutate authoritative world state.

Gameplay System Boundaries

Early runtime systems should remain small and explicit:

  • AAgrarianGameState: world time, weather, ambient temperature, replicated environment state.
  • UAgrarianSurvivalComponent: health, hunger, thirst, stamina, body temperature, injury, and survival damage.
  • Inventory component/classes: item stacks, item definitions, resource intake, and crafting inputs/outputs.
  • Crafting component/classes: recipes, validation, output creation. Current primitive recipes include campfire, shelter parts, primitive shelter, basic tool, bandage, and simple_container; the simple container is an inventory craftable foundation for later placed storage and trade-container systems.
  • Interaction component/classes: player-facing use/gather/build entry points.
  • Resource actors: gatherable wood, stone, fiber, water, wildlife, and future natural resources.
  • Buildable actors: campfire, one-piece primitive shelter kits, and later settlement infrastructure. For the version 0.1 MVP, shelter construction is intentionally kit-based: frame, wall panel, and roof panel items are crafted as inventory parts and then combined into a single placeable primitive shelter actor. Fully modular wall-by-wall construction is deferred to permanent structures so the first survival loop remains reliable.
  • The MVP wall piece is primitive_wall_panel, a craftable inventory construction part consumed by the primitive shelter recipe rather than an independently placed wall actor.
  • The MVP roof piece is primitive_roof_panel, a craftable inventory construction part consumed by the primitive shelter recipe rather than an independently placed roof actor.
  • MVP primitive shelters use an open entrance and do not include an interactive door. Door actors, locks, ownership permissions, and modular openings are deferred to permanent structures.
  • AAgrarianShelterActor includes a version 0.1 structure damage placeholder: replicated current/max health, authority-only damage, repair, and deconstruction hooks, TakeDamage integration, depletion destruction, and persistent health state. This gives fire, weather, tools, and future ownership systems a safe structure-health contract to extend.
  • UAgrarianBuildingPlacementComponent owns the MVP placement preview. It traces from the player view, snaps to the configured grid, validates distance and collision, broadcasts Blueprint-readable preview state, and draws a green/red wireframe ghost footprint in development builds so placement can be tested before final mesh/material ghost assets exist.
  • Persistence layer: save/load contracts for player and world state.

Blueprints can compose and expose these systems, but core replicated behavior should remain in C++ as much as practical.

Inventory data is defined in Docs/InventoryDataModel.md. The MVP model uses stable ItemId keys, design-time FAgrarianItemDefinition records, runtime and save-game FAgrarianItemStack records, and a server-authoritative UAgrarianInventoryComponent with replicated stack arrays. Pickup, drop, splitting, item use, equipment, carry capacity, persistence, and UI work should extend that contract rather than inventing parallel inventory state.

World pickups use AAgrarianItemPickup, an interactable replicated actor with a static mesh and either a definition-backed or inline FAgrarianItemStack. Player interaction already routes to the server through the Agrarian character, so pickups validate authority, produce a valid stack, add it to the player's inventory, and only then remove the pickup by destroying the world pickup actor. If the inventory is full or the stack is invalid, the pickup remains in the world for another attempt.

Developer item dropping is available through AgrarianDropItem ItemId Quantity. The command routes to the server, extracts stack data before spawning so display name and unit weight survive the drop, spawns an AAgrarianItemPickup in front of the player, and restores the removed stack if pickup spawning fails. This is the baseline behavior future UI-driven drop flows should call through rather than duplicating inventory mutation logic on the client.

Stack splitting is available through AgrarianSplitStack StackIndex SplitQuantity and UAgrarianInventoryComponent::SplitStackByIndex. Splitting is server-authoritative, validates the source stack index, quantity, and free slot capacity, copies the source stack metadata, reduces the source quantity, and creates a separate inventory slot. It intentionally does not re-merge the split stack through AddItem, because the UI needs an actual separate stack to support later drag/drop and partial drop flows.

MVP item use is available through AgrarianUseItem ItemId Quantity. The command routes to the server, extracts the requested stack quantity, applies a whitelisted item effect, and restores the stack if the item is not usable yet. For the first survival loop, food restores hunger, meat restores more hunger but adds sickness risk because it is raw, and bandage is the MVP treatment item: it reduces injury, bleeding, and sprain severity with a small health bump. This gives UI item-use work a concrete authority path while leaving tools, structures, and future complex consumables blocked until they have explicit gameplay rules.

Dedicated equipment slots are intentionally deferred for the 0.1.E MVP. The current basic_tool item can remain an inventory item until an implemented system needs active hand, worn, backpack, armor, weapon, durability, animation, or mesh-attachment state. When that need appears, equipment should be added as server-authoritative, replicated, persisted slot state rather than as local UI selection only.

Carry capacity is active as an MVP placeholder through stack UnitWeight, inventory GetTotalWeight, and character movement penalties. The current character uses 25.0 comfort and 60.0 heavy item-weight thresholds, scales those thresholds by strength, and exposes current carried weight in the debug HUD. Future backpacks, containers, awkward-object rules, and hard overload limits should extend this total-weight path rather than creating a second carry model.

The MVP inventory UI is a compact AAgrarianDebugHUD inventory panel, enabled separately from the full developer HUD. It reads the replicated inventory stack array, shows occupied slots, total carried weight, and a short visible stack list, and leaves mutation actions on the existing server-authoritative commands and RPCs until a full UMG inventory screen is introduced.

The MVP crafting UI is a compact AAgrarianDebugHUD crafting panel. The Agrarian player Blueprint preloads primitive KnownRecipeAssets, and the HUD reads those recipes plus the replicated inventory to show craftable status and ingredient counts. Interactive UMG recipe browsing, hotkeys, and queued crafting controls are deferred until the primitive loop settles.

Crafting debug tools live on the player controller. AgrarianCraftStatus prints known recipes and current craftability, while AgrarianCraft <RecipeId> requests a server-authoritative craft through UAgrarianCraftingComponent. These commands are intended for smoke testing and investor-demo rehearsal until proper UI input exists.

Inventory persistence saves UAgrarianInventoryComponent::Items into FAgrarianSavedPlayer::Inventory and restores through UAgrarianInventoryComponent::RestoreSavedItems. Restore broadcasts OnInventoryChanged, which keeps the MVP HUD panel and future UI listeners in sync after load while preserving total weight as a derived value.

Time And Environment

The MVP gameplay calendar target is:

4 real hours = 1 in-game day

The current C++ default is:

GameHoursPerRealMinute = 0.1

That equals 6 in-game minutes per real minute, or 24 in-game hours over 4 real hours.

Day/night presentation should mimic the represented Earth region's local solar and weather context as the system matures. This means the gameplay calendar can be compressed while visual lighting, seasonal direction, and weather mapping still derive from the represented map tile.

Near-term technical work:

  • add Ground Zero local time-zone metadata; completed for the current C++ game-state default.
  • add sunrise/sunset lookup or approximation by latitude/longitude; completed as a tile-aware NOAA approximation in AAgrarianGameState.
  • map real weather snapshots into internal Agrarian weather states;
  • cache weather snapshots server-side;
  • keep deterministic fallback weather when external data is unavailable.

The repeatable solar metadata data path is Scripts/generate_tile_solar_metadata.py. It reads the tile registry and emits metadata only for source-backed, generated, validated, packaged, or published tiles with explicit time-zone data. Placeholder/unknown tiles are skipped so the future Earth-scale registry does not generate or fetch data for theoretical tiles that do not exist yet.

Calendar conversion helpers live in AAgrarianGameState and keep the MVP target of 4 real hours = 1 in-game day. The same game state now exposes replicated calendar year/day, absolute-day, season, real-hour conversion, long-task progress, and crop-season fit helpers. Crop checks use the active tile's growing-zone profile, including frost-free days and a crop safety buffer, so a long-maturity crop can be rejected or marked marginal in regions with short seasons.

The repeatable growing-zone metadata data path is Scripts/generate_tile_growing_zone_metadata.py. It reads the tile registry and emits metadata only for source-backed, generated, validated, packaged, or published tiles with explicit growing-zone data. Ground Zero currently uses a conservative Pacifica coastal profile; later regional expansion should replace or enrich these overrides with authoritative zone, climate, and temperature datasets.

Temperature is authoritative on AAgrarianGameState. The MVP curve uses the active tile's sunrise and solar noon to place the daily low near sunrise and the daily high after solar noon, then applies weather modifiers for rain, cold wind, and storms. Regional daily low/high values provide the deterministic fallback. When a server-side weather adapter is available, it should set observed regional temperature and blend weight through the game-state hook rather than allowing clients to call public weather APIs directly. This keeps real-world temperature and weather tied to the represented map tile while preserving a deterministic fallback if an external provider is unavailable.

Primitive shelters expose a replicated protection volume and WeatherProtection rating. Server-side survival ticks calculate the best overlapping shelter protection for each character, replicate the current protection value, reduce ambient weather exposure and cold damage by that percentage, and trend the care-history shelter quality field toward the active protection level. The dev HUD shows current shelter protection so weather pressure can be tuned during MVP tests.

Weather exposure zones use AAgrarianWeatherExposureZone volumes placed by the Ground Zero setup script. They describe local ridge, coastal-wind, and drainage cooling effects with an exposure multiplier and temperature offset. Server-side survival ticks select the strongest overlapping zone effect, replicate the current multiplier and offset, then apply them to ambient body-temperature drift and cold damage after shelter protection. This lets future generated tiles add biome, slope, elevation, hydrology, and coastal modifiers without changing the core survival calculation.

The safe Ground Zero spawn is selected by Scripts/setup_ground_zero_demo_map.py from declared candidate coordinates and a known safe fallback coordinate. The setup validates the selected player start against terrain elevation, terrain slope, a minimum above-terrain Z offset, freshwater spacing, and resource-cluster spacing before saving the map. Scripts/verify_ground_zero_safe_spawn.py rechecks the placed AGR_DemoPlayerStart against the same constraints so future map, resource, water, or terrain changes cannot silently move the player below sea level, into steep terrain, into water, or into a dense resource cluster.

The Ground Zero map also contains AGR_GroundZeroMapBoundary, a native AAgrarianMapBoundaryVolume centered on the 1 km x 1 km MVP tile. For the MVP, the boundary clamps server-authoritative player pawns back inside the loaded tile with a small padding rather than allowing players to walk into missing neighbor terrain. The actor exposes a warning distance hook so later UI can present an in-world or HUD notice before a clamp occurs.

Developer testing supports server-authoritative developer travel through AgrarianTravel X Y Z on AAgrarianGamePlayerController. The command teleports the controlled pawn to explicit Unreal world coordinates, stops any current character movement, and reports the destination to the issuing player. AgrarianTravelHome returns the player to the validated Ground Zero safe-spawn fallback near AGR_DemoPlayerStart, above sea level and above terrain by the same safe offset used by the map setup pass.

First-pass sky and lighting use AAgrarianSkyLightingController. The controller owns movable sun, skylight, and exponential-height-fog components and reads the replicated AAgrarianGameState time, active tile sunrise/sunset, weather state, and mapped cloud cover. It adjusts sun pitch, sun intensity/color, sky-light intensity, and fog density every tick so the Ground Zero demo visually tracks the represented local day/night cycle and current weather without hard-coded static light settings. The Ground Zero map setup script places this controller and removes the earlier static demo sun/skylight/fog actors.

First-pass biome and weather audio uses AAgrarianWeatherAudioController. The controller owns ambient, rain, wind, and storm audio components with assignable loop sound slots. The ambient component is explicitly the Ground Zero coastal-scrub biome bed through BiomeAmbientLoopSound, with separate day and night volume targets so the map can carry wind, surf, insects, distant birds, or other realistic low-level biome texture before final authored assets are available. It reads replicated weather state, provider wind speed, provider cloud data, and local night/day state, then fades component volumes so rain, wind, and storm cues follow the same authoritative weather mapping used by temperature and lighting. The current MVP can ship without final sound assets because the controller is silent until loops are assigned; placeholder or final audio can be added by setting the exposed sound properties on the placed controller or a Blueprint child.

Player movement audio starts with native footstep placeholders on AAgrarianGameCharacter. The character owns a spatialized FootstepAudioComponent plus assignable walk, sprint, crouch, and prone sound slots. Cadence is state-aware and driven by horizontal movement, so the MVP can remain silent until placeholder or final surface-aware cues are assigned while still giving designers a real hook for step audio in packaged builds.

Gathering audio is owned by AAgrarianResourceNode. Successful server-authoritative harvests call a multicast placeholder cue so nearby clients can hear the action without trusting client-side gathering requests. Each resource node exposes GatheringSound and DepletedGatheringSound slots, with a spatialized GatheringAudioComponent; the system remains silent until resource-specific placeholder or final cues are assigned.

Campfire audio is split between a persistent spatialized loop and short server-triggered event cues. AAgrarianCampfire exposes FireLoopSound, IgniteSound, and ExtinguishSound slots. Replicated lit-state updates start or stop the loop on clients, while the authoritative server multicasts ignition and extinguish events so the audio follows the same state changes as light, smoke, warmth, fuel, and persistence.

Campfires now track unattended and poorly maintained fire risk on the server. AAgrarianCampfire records lit duration, seconds since maintenance, whether the area has been cleared, whether the fire is contained, and a replicated FireRiskScore. Risk grows after a fire has been left unattended, grows faster when excessive fuel is burning, and is reduced by maintenance, cleared area, containment, and wet weather. This first risk layer does not yet ignite nearby vegetation or structures; later 0.1.P items consume the replicated risk score.

Grass and forest ignition checks consume that risk score. Campfires query AAgrarianFoliagePatch for nearby grass, shrub, and tree instance counts inside VegetationIgnitionCheckRadius. Unsafe placement near dry fuel accumulates separate replicated grass/brush and forest ignition risk, adjusted by burn duration, wind speed, current weather, cleared-area maintenance, and the campfire's current risk ratio. Reaching the threshold marks the relevant ignition flag, while later spread rules decide how active fires propagate.

Structure ignition risk uses the same server-authoritative campfire risk model. Open fires check nearby primitive shelters plus flammable wood/fiber resource nodes as MVP stand-ins for wood piles, flammable crafting stations, and future settlement objects. Contained fires skip this structure check; otherwise structure risk accumulates with distance-based fuel presence, burn duration, weather/wind, and the current fire-risk ratio before setting a replicated structure ignition flag.

Campfires expose native extinguish logic through AAgrarianCampfire::Extinguish. Extinguishing clears remaining fuel, turns off replicated lit state, and reuses the same visual update path as natural fuel depletion.

Campfires also expose a minimal replicated cooking placeholder. While lit and enabled, AAgrarianCampfire advances CookingProgressSeconds toward CookingSecondsRequired on the server and exposes CanCook plus a normalized progress ratio for future recipe UI, food transformation, and interaction hooks.

Campfire visuals include an assetless SmokeEffect particle-system component placeholder. It is attached above the fire, starts inactive, and follows the same replicated lit-state visual update path as fire light intensity so final smoke or ember assets can be assigned later without changing gameplay code.

Campfire persistence uses the shared UAgrarianPersistentActorComponent world actor path. AAgrarianCampfire implements the persistence-state provider hook to write lit state, remaining fuel, cooking enabled state, required cook time, and cooking progress into numeric save state, then restores those values before reapplying the fire visual state on load.

Campfires now read the replicated AAgrarianGameState::Weather value while burning. Rain and storms increase fuel drain through tunable multipliers, and wet weather can deterministically extinguish a low-fuel fire so weather affects fire reliability without adding random outcomes to save/load or multiplayer state.

The first real-weather adapter is UAgrarianWeatherProviderSubsystem. It uses Open-Meteo forecast requests keyed by tile center latitude/longitude, parses the current temperature, daily low/high, precipitation, wind, humidity, cloud cover, pressure, provider timestamp, and weather code, then applies the mapped state to AAgrarianGameState on the server. It is tile-driven rather than Ground-Zero hard-coded: Scripts/generate_tile_weather_manifest.py emits every source-backed, generated, validated, packaged, or published tile with center coordinates, while placeholder/unknown tiles are skipped. Future source-backed tiles therefore become weather-eligible when their registry entries are added.

Ground Zero weather lookup coordinates are explicit in the tile registry. The current MVP tile gz_us_ca_pacifica_utm10n_e544_n4160 uses its tile center, latitude 37.5925 and longitude -122.4995, as the canonical real-world weather lookup point. Scripts/generate_tile_weather_manifest.py reads weather_lookup_metadata when present, falls back to the tile center for source-backed tiles, and emits the provider routing used by the weather subsystem.

Open-Meteo is the first global MVP weather source. The provider contract is stored in Data/Weather/open_meteo_mvp_source.json, including the forecast endpoint, requested current/daily variables, tile lookup rule, and Agrarian mapping notes. Scripts/verify_open_meteo_mvp_source.py validates the static contract and can perform a live Open-Meteo request for every source-backed tile in Data/Tiles/tile_weather_manifest.json. This keeps the provider global for all future real tiles instead of adding one-off Ground Zero weather code.

NOAA/NWS is the US-only fallback and enrichment path. The provider contract is stored in Data/Weather/noaa_nws_us_fallback.json. The weather provider subsystem can check whether an active tile center coordinate is inside the approximate NWS coverage window, request api.weather.gov/points/{lat},{lon}, follow properties.forecastGridData, and parse gridded temperature, precipitation probability, and wind speed as fallback inputs. The NWS path is only used for eligible US/NWS-covered tiles; Open-Meteo remains the global source for all tiles.

Real-weather snapshots are cached server-side in UAgrarianWeatherProviderSubsystem::ServerWeatherSnapshotCache. Cache keys use provider plus tile ID, and the default TTL is 15 minutes. Server requests first try to apply a fresh cached snapshot to AAgrarianGameState; only cache misses call Open-Meteo or NOAA/NWS. Clients never call Open-Meteo or NOAA/NWS directly. They receive weather, temperature, source, and state through replicated game state fields.

Real-weather provider values are mapped into FAgrarianMappedWeatherInputs before they affect gameplay. The mapped snapshot keeps tile ID, tile center coordinate, temperature, precipitation, wind, cloud cover, humidity, pressure, visibility, and provider weather code available alongside the collapsed Agrarian weather state. Open-Meteo fills those fields directly where available; NOAA/NWS fills them from grid data where available and derives provisional visibility/weather-state values until a deeper provider-specific mapping pass is added.

The applied weather state also has a replicated debug snapshot: FAgrarianWeatherDebugSnapshot. It records the weather source, provider timestamp, tile ID, tile center coordinate, provider weather code, input values, and final in-game EAgrarianWeatherType after mapping. Save files persist both the mapped inputs and the applied debug snapshot so weather issues can be traced back to a specific provider response and tile without inferring those values from separate systems.

Deterministic fallback weather keeps the game playable when external providers are disabled, unreachable, or return unusable data. The fallback snapshot is derived from tile ID and Agrarian day, then mapped through the same FAgrarianMappedWeatherInputs path as live providers. It produces seasonal daily low/high temperatures, current temperature, cloud cover, humidity, wind, pressure, precipitation, visibility, and the collapsed Agrarian weather state. Fallback snapshots use provider deterministic-fallback and are cached server-side with the normal weather cache TTL.

Terrain And Tile Delivery

MVP Tile

The MVP starts with one real Ground Zero tile:

  • 1 km x 1 km tile;
  • real elevation data imported into Unreal;
  • metadata tracked in JSON registry files;
  • static delivery package available from the map tile server.

Tile Server

Current MVP endpoint:

http://maps.agrariangame.com:18080

Current backing VM:

Agrarian-TileServer

The tile server currently serves static files through nginx:

  • /health
  • /manifest.json
  • /ground_zero_tiles.json
  • /schemas/tile_registry.schema.json
  • /tiles/<tile_id>/v<package_version>/...

The current tile client verification script proves:

  • manifest download;
  • registry lookup;
  • package file download;
  • checksum validation;
  • neighbor metadata presence;
  • delete/redownload cache recovery.

Long-Term Tile Direction

The long-term tile system should support:

  • 1 km x 1 km canonical tile IDs;
  • versioned tile packages;
  • server-side registry and package metadata;
  • client local tile cache;
  • cache retention and scrub policy;
  • package revalidation and redownload;
  • tile adjacency/stitching contracts;
  • safe terrain updates that do not corrupt persisted player/world state.

The first implementation should stay static and simple until gameplay proves why a database-backed tile service is needed.

Data Contracts

Data Assets

Use Unreal Data Assets for designer-facing definitions such as:

  • item definitions;
  • recipes;
  • gatherable resource configuration;
  • wildlife configuration;
  • buildable structure definitions;
  • future skill/knowledge definitions.

Data Assets should describe content. Server code should enforce gameplay rules.

Gatherable Resources

The 0.1.F resource baseline uses AAgrarianResourceNode for simple gatherable world resources. Wood, fiber, stone, and edible plants each have item definitions or yield definitions, resource Blueprints, deterministic Ground Zero placements, replicated remaining harvest counts, and bare-hand gathering through the shared interaction path.

Stone specifically is represented by DA_Item_Stone and BP_StoneResourceNode. Ground Zero includes stone nodes in slope, exposed terrain, and valley-edge positions so primitive tools, campfires, and early construction recipes have an in-world source instead of relying on debug grants. Edible plants are represented by BP_EdiblePlantResourceNode, which yields the MVP food item from scrub, grassland, and drainage-candidate forage patches.

Freshwater gathering uses AAgrarianWaterSource instead of the depleting resource-node class. The placed BP_FreshWaterSource is still an IAgrarianInteractable, appears through the same focused interaction prompt, and restores thirst through UAgrarianSurvivalComponent::AddWater on server authority. This keeps drinking compatible with the existing replicated survival component while leaving later container filling, water quality, and source depletion rules for future water-system work.

For the MVP, renewable MVP resource nodes respawn only after they are fully depleted. Wood, fiber, and edible plant nodes are renewable because they represent surface materials and forage that should return during continued prototype play. Stone remains nonrespawning because it represents a slower geologic resource and should push players to explore once local easy stone is gone. Respawn timing is configurable per Blueprint through bRespawnsForMvp, RespawnDelaySeconds, and MaxHarvests; the native node uses a server-side timer and restores replicated RemainingHarvests when the delay expires.

Tool requirement rules remain inventory-based for the MVP because dedicated equipment slots are deferred. A resource node can declare RequiredToolItemId, bAllowBareHandGathering, and ToolQuantityBonus. Current Ground Zero wood, fiber, and stone nodes still allow bare-hand gathering so the first survival loop cannot deadlock before the player can craft a tool. When the player has a basic_tool in inventory, those nodes grant an extra unit per harvest. Edible plants remain pure bare-hand gathering. Later nodes can disable bAllowBareHandGathering when the game has proper tool equipment, durability, and feedback UI.

Resource node persistence is map/tile state, not a spawned-actor replay path. UAgrarianSaveGame stores FAgrarianSavedResourceNode records keyed by AAgrarianResourceNode::PersistenceNodeId, with the actor name as a fallback. UAgrarianPersistenceSubsystem captures only resource nodes that exist in the currently loaded world and restores matching existing nodes by stable id. This keeps the MVP compatible with later Earth-scale tiles: a tile contributes resource depletion state only when its resource actors actually exist, and tile generation/placement scripts should assign deterministic node ids.

Wildlife Navigation

MVP wildlife movement is server authoritative. AAgrarianWildlifeBase uses an AI controller and Unreal navigation when nav data exists: wander targets are chosen from reachable nav points, chase/flee targets are projected onto navmesh, and movement requests use MoveToLocation. If a test map or early generated tile has no nav data, wildlife falls back to direct movement input so damage, flee, chase, and harvest loops remain functional while map navigation is being authored.

Wildlife Spawning

AAgrarianWildlifeSpawnManager owns MVP wildlife population seeding on the server. Designers can assign a wildlife class, initial count, max active count, spawn radius, and respawn interval. Spawn points optionally project to navigation before spawning so the first wildlife prototype favors reachable positions while still falling back cleanly on maps without complete nav data.

Wildlife Performance Limits

MVP wildlife uses simple server-side performance guardrails before the later AI-scaling pass. Nearby wildlife updates every tick for responsive flee/chase behavior. Wildlife outside FullUpdateRadius batches server thinking on FarUpdateIntervalSeconds, dead wildlife disables ticking, and spawn managers enforce MaxActiveWildlife so prototype populations cannot grow without a cap.

JSON Metadata

Use JSON files for external terrain/tile pipeline metadata while the pipeline is still early:

  • tile registry;
  • terrain generation metadata;
  • heightmap metadata;
  • landform analysis;
  • water/shoreline analysis;
  • neighbor edge verification.

JSON metadata should have schemas when it becomes a contract. The tile registry already has an MVP schema.

Save Data

Save data must be treated as a long-term compatibility contract. Do not store temporary prototype assumptions in a way that blocks future migration.

Persistence should include version fields for:

  • save format;
  • game build;
  • tile package version;
  • world state records;
  • player records;
  • placed object records.

Persistence Strategy

Persistence should begin narrow and explicit.

MVP persistence scope:

  • player survival snapshot;
  • inventory snapshot;
  • placed campfire/shelter/basic structures;
  • depleted/changed resource nodes where needed;
  • world time/weather state;
  • active Ground Zero tile/package version.

Do not persist every temporary actor by default. Actors should opt into persistence with a stable identifier and a clear serialization contract.

Future persistence design should address:

  • server database vs file save split;
  • migration/versioning;
  • world partition state;
  • tile package changes;
  • player-owned structures;
  • family/generation data;
  • family and community NPC memory, relationships, teaching history, emotional state, task state, and offline stewardship logs;
  • economy and transaction records;
  • settlement governance records.

Family, Community NPC, And Offline Stewardship Intelligence

Long-term NPC and family behavior should be built as inspectable simulation systems before relying on any generative AI layer.

Core rules:

  • The server remains authoritative for NPC choices, movement, resource use, combat, teaching, learning, economy effects, and offline character outcomes.
  • Nearby characters can run fuller behavior/state-tree logic, while distant settlement members use cheaper task simulation and ledger updates.
  • Family and community characters need persistent needs, relationships, memories, skills, roles, emotional state, task state, and contribution logs.
  • Logged-off player characters may contribute locally from their last valid home, claim, or assigned post, but should not explore, learn new skills, complete major projects, accept strategic risk, or gain hidden progression.
  • Core behavior must remain deterministic, debuggable, and functional without model inference.
  • Any AI model layer should be proprietary-first: local or self-hosted where practical, privacy-safe, replaceable, and limited to optional dialogue variation, event summarization, teaching flavor, memory compression, and settlement reports unless explicitly promoted after review.
  • External AI services must not receive private player history, unreleased world state, economy data, or proprietary design context for core gameplay.

Multiplayer Strategy

The MVP should prove at least two players on the same server.

Near-term rule:

  • server validates gameplay actions;
  • replicated state is kept minimal;
  • client prediction is deferred unless interaction feels bad without it;
  • RPCs should be narrow and action-specific;
  • avoid letting Blueprint-only paths mutate critical authoritative state.

Detailed replication policy belongs in the multiplayer/networking design document.

Build And Automation

Windows Editor Build

Primary build path:

Scripts\BuildEditor-Windows.bat

Codex runs this through Windows-Builder using:

/home/nathan/bin/winbuilder cmd 'set AGRARIAN_NO_PAUSE=1 && pushd \\DevBox\projects\AgrarianGameBulid && Scripts\BuildEditor-Windows.bat'

Unreal Python Verification

Command-mode Unreal Python scripts are used for repeatable editor validation:

  • map checks;
  • Ground Zero terrain verification;
  • playable Blueprint verification;
  • resource and foliage placement checks.

These scripts should remain deterministic and safe to run repeatedly.

Packaged Demo Builds

Investor/demo packages should be produced when a milestone version's roadmap items are complete. The build should use Ground Zero as the default map and include current splash/startup/copyright notices.

Linux Dedicated Server

Dedicated server build instructions exist, but the MVP can continue proving gameplay through the current available server path until dedicated server packaging is required for closed testing.

Infrastructure

Current supporting machines:

  • DevBox Unraid: shared project storage and VM host.
  • Ubuntu-Codex: source-control/automation machine.
  • Windows-Builder: Unreal/Visual Studio/GPU build machine.
  • Agrarian-TileServer: dedicated Ubuntu VM for MVP tile delivery.

Current public tile DNS:

maps.agrariangame.com:18080

Infrastructure rules:

  • do not run project application services directly on the Unraid OS;
  • run services inside VMs or external hosts;
  • keep the tile server small and static for MVP;
  • keep GitHub/LFS usage within free-tier guardrails as long as practical;
  • avoid committing generated build output, local caches, or secrets.

Source Control And Assets

The repo uses Git plus Git LFS for Unreal binary assets.

Rules:

  • commit source, config, docs, scripts, and curated assets;
  • do not commit Binaries/, Intermediate/, Saved/, local build artifacts, or generated packages;
  • keep large generated terrain packages out of Git unless explicitly curated;
  • prefer small, focused commits tied to roadmap items;
  • do not commit credentials or machine-local configuration.

The project currently has unrelated .uasset modifications in the working tree from prior editor activity. Do not stage those unless intentionally addressing that content.

Security And Secrets

Secrets must stay out of the repository and handoff files.

Examples:

  • DigitalOcean API tokens;
  • server passwords;
  • Mailgun credentials;
  • database passwords;
  • private SSH keys;
  • admin reset files.

Use environment variables, machine-local config, or secret managers for credentials. Documentation may describe where a secret is expected, but should not include secret values.

Testing Gates

Minimum gate for code changes:

  • relevant C++ compiles through Windows-Builder;
  • relevant Unreal Python verification passes when touching maps/assets;
  • targeted script checks pass when touching scripts/data;
  • docs-only changes receive a text sanity check.

Minimum gate for milestone/demo builds:

  • editor build succeeds;
  • Ground Zero map check passes;
  • playable loop smoke test passes;
  • package launches on Windows test machine;
  • current roadmap milestone is marked complete;
  • known blockers are documented.

Performance Profiling

Agrarian gameplay code exposes a dedicated Unreal stat group named STATGROUP_Agrarian. Use stat Agrarian during editor or packaged sessions for game-specific cycle counters, and capture Unreal Insights traces for matching CPU scopes. The current markers cover authoritative game-state time/weather ticking, survival ticking, sky-light refresh, weather-audio refresh, foliage instance mutation, and weather-provider request/parse/fallback work.

Near-Term Technical Priorities

Next technical foundation work should focus on:

  • technical details for multiplayer/networking;
  • persistence contract and versioning;
  • Earth-scale tile streaming design;
  • real-weather provider adapter;
  • real-region day/night presentation;
  • local tile cache layout and retention;
  • MVP character-selection landing page;
  • first closed-test readiness gate.

Open Questions

  • Should public tile serving remain on the LAN-hosted Agrarian-TileServer VM during closed testing, or move to an external cloud host before testers join?
  • Which persistence backend should replace or supplement file saves first?
  • How much client prediction is needed for gathering, inventory, and building?
  • What is the first stable dedicated server packaging target?
  • Which systems need migration/versioning before the first closed test?
  • How much real sunrise/sunset accuracy is needed before the MVP feels regionally grounded?