Block 1 — Foundation (2 days)

Goal: Walkable blockout hideout and city map with interactable station volumes, the core data model compiled and instantiable, and all subsystem stubs in place. No gameplay — just the shell everything plugs into.

Depends on: Nothing — this is the foundation.


Deliverables

Home Base Blockout (L_Hideout)

UE5 Modeling Tools geometry (not BSP) defining the tunnel layout: main corridor, alcoves for stations, dead ends for boundaries. Sized for 7 station spots plus walking paths. Use Cube Grid tool → PolyEdit to extrude alcoves. Flat unlit materials with distinct colors per zone. Scale for raccoon height: tunnels ~60–80 cm tall, 80–100 cm wide.

City Map Sublevel (L_City)

Separate sublevel added to L_Hideout persistent level via Levels panel. Streaming method set to “Always Loaded” — L_City stays resident at all times because raccoon AI pawns navigate it during active raids and NavMesh must persist regardless of whether the player is viewing the city map. At blockout scale the memory cost is negligible; revisit if L_City grows to production art with significant asset weight. Contains: flat ground plane (road grid mesh), 2 box-primitive buildings (ATNTBuilding actors) for Average Home and The Dump, ANavMeshBoundsVolume covering road network, ATNTHideoutExit marker at map edge, ATNTCityCamera overhead camera actor with pan/zoom support.

First-Person Movement

ATNTPlayerPawn extending ACharacter with UCharacterMovementComponent in walking-only mode. Disable jumping and crouching. UCapsuleComponent at 30 cm half-height, UCameraComponent at raccoon eye height. CMC handles gravity and floor pinning — avoids floating on uneven geometry. No paw hands or character model yet — camera only.

Player Controller

ATNTPlayerController with two Enhanced Input mapping contexts:

IMC_Hideout:

Input ActionTypeBinding
IA_MoveVector2DWASD
IA_LookVector2DMouse XY
IA_InteractBool (pressed)E

IMC_CityMap:

Input ActionTypeBinding
IA_PanVector2DWASD / mouse drag (middle button)
IA_ZoomFloat (axis)Scroll wheel
IA_ClickBool (pressed)Left mouse
IA_EscapeBool (pressed)Escape

Interaction system: Overlap-based (not line trace). ATNTStationBase has UBoxComponent set to overlap. When player pawn overlaps a station volume → controller caches reference + shows interact prompt on HUD. On IA_InteractStation->OnPlayerInteract(). On end overlap → clear prompt. Only one station overlap active at a time (nearest or most recent). For MVP blockout: print to screen confirming which station was activated.

Game Mode

ATNTGameMode extending AGameModeBase. Sets default pawn class and player controller class. No gameplay init yet (that’s Block 2+).

Station Volumes

7 instances of ATNTStationBase placed at intended locations. Each is the same class, configured per-instance:

ATNTStationBase : AActor
  UBoxComponent* InteractionVolume      // Overlap volume — generates overlap events with player pawn
  UStaticMeshComponent* PlaceholderMesh // Differently colored cube per station
  UWidgetComponent* LabelWidget         // Floating text: "Raid Board", "Pantry", etc.
  UStationDataAsset* StationData        // Assigned in editor — drives behavior
  EStationType StationType              // Cached from DataAsset on BeginPlay

  void OnPlayerInteract()
    // Branch logic:
    // if StationType == RaidBoard → UCityMapSubsystem::SetOverheadCamera(true)
    //   (SetViewTargetWithBlend to ATNTCityCamera + switch input to IMC_CityMap)
    // else → spawn StationData->UIWidgetClass, add to viewport,
    //   set input mode Game+UI, show cursor

  int32 GetEffectiveStat(EStatType)     // Delegates to UStationSubsystem

No subclasses. UStationDataAsset specifies station type, relevant stats, base storage cap, upgrade cost curve, and which UMG widget class to spawn on interact. Raid Board leaves UIWidgetClass null — uses city map flow instead.

City Map Actors (stubs)

ClassBasePurpose
ATNTBuildingAActorUStaticMeshComponent (box) + UBoxComponent (hover detect). References UBuildingDataAsset. Highlight material on hover. Click to select target.
ATNTRaccoonAIPawnAPawnStub class only — spawning/AI wired in Block 4.
ATNTCityCameraAActor with UCameraComponentTop-down overhead. Not possessed — PlayerController uses SetViewTargetWithBlend to switch view to this actor. Controller moves camera transform directly via IMC_CityMap input (pan = translate XY, zoom = adjust arm length or Z height).
ATNTHideoutExitAActorSpawn point marker for raccoon AI pawns at map edge.

Core Data Model (C++)

All enums, structs, and subsystem stubs compiled and instantiable:

Enums:

EnumValues
ERaccoonTypeScout, Hauler, Distractor (post-MVP: Sorter, Scrapper, Fence, Lookout, Climber)
ERaccoonStatusIdle, Raiding, Assigned, Injured, Hungry, Deserted, Training
EStatTypeSpeed, Stealth, Strength, Cunning, Luck
EStationTypeRaidBoard, TrainingCorner, LootSortingStation, OnlineSales, Pantry, GearBench, UpgradeDesk
EResourceTypeTrash, Currency, Scrap
EEncounterConsequenceNone, Injury, Capture, Abort, LootLoss, BonusLoot, TimeReduction

Structs:

StructKey FieldsNotes
FStatBlockSpeed, Stealth, Strength, Cunning, Luck (int32, 1–100)GetStat(EStatType), ModifyStat(EStatType, Delta), operator+ for crew summing. All BlueprintCallable.
FRaccoonDataId (FGuid), Name, Type, BaseStats, TrainingBonus (FStatBlock, default 0s), EquippedGearRowName (FName), AssignedStation, bHasAssignment, Status, InjuryRaidsRemaining, ConsecutiveHungryTicksRuntime raccoon instance. BaseStats immutable after creation. TrainingBonus accumulates from training sessions. See Raccoon Stats.
FResourceLedgerTrash, Currency, Scrap (int32)Global counters owned by UResourceSubsystem.
FValuableItemItemId, Tier (1–3), BaseSellPrice, HiddenCeiling (post-MVP)Individual valuable in loot payload.
FLootPayloadTrash, Currency, Scrap amounts + TArray<int32> FoodItems + TArray<FValuableItem> Valuables + bRecruitAvailable + RecruitTypeTransient. Generated at raid dispatch, consumed at loot sorting.
FActiveRaidRaidId, Target (soft ref), CrewRaccoonIds, TotalDuration, ElapsedTime, EncounterTriggerTimes, NextEncounterIndex, PendingLoot, SpawnedPawns (weak ptrs)Active raid state. Tracks AI pawns on city map.
FStationRuntimeStateAssignedRaccoonId, CurrentStorage, CapTierMutable per-station state.
FCostDataTrash, Currency, Scrap (int32)Multi-resource cost for upgrades/crafting.
FMilestoneProgressCurrentCount (int32), bCompleted (bool)Per-milestone runtime state. Referenced by UProgressionSubsystem’s TMap. Stub here, populated Block 9.
FEncounterResultbPassed, Consequence (EEncounterConsequence), AffectedRaccoonId, EncounterNameOutcome of encounter resolution. Stub here, used by URaidSubsystem in Block 4.

DataAsset classes (C++ headers, no content authored yet):

DataAsset ClassKey Properties
URaccoonTypeDataAssetType enum, starting stat ranges (min/max per stat), primary/secondary stat tags, unlock condition
UStationDataAssetStation type enum, relevant stat types, base storage cap, TArray<FCostData> upgrade cost tiers, TSubclassOf<UTNTStationUIBase> UIWidgetClass
URaidTargetDataAssetName, loot bias weights (per resource type), difficulty, TArray<TSoftObjectPtr<UEncounterDataAsset>> encounter pool, unlock condition
UEncounterDataAssetType enum, stat check type, threshold, pass consequence, fail consequence
UBuildingDataAssetDisplay name, linked URaidTargetDataAsset, visual type enum, hover tooltip data

Subsystem stubs (C++ — UGameInstanceSubsystem subclasses, empty implementations):

SubsystemInternal StateTypePurpose
URaccoonSubsystemRaccoonsTArray<FRaccoonData>Live roster of all raccoon instances
NamePoolTArray<FString>Curated name list for GenerateName. Avoids duplicates against current roster
UResourceSubsystemLedgerFResourceLedgerGlobal resource counters (Trash, Currency, Scrap)
UStationSubsystemStationStatesTMap<EStationType, FStationRuntimeState>Per-station mutable runtime state
PendingPayloadsTMap<EStationType, TArray<FLootPayload>>Loot queued for station processing (populated Block 5)
URaidSubsystemActiveRaidsTArray<FActiveRaid>All in-progress raids
UProgressionSubsystemMilestoneProgressTMap<FName, FMilestoneProgress>Per-milestone runtime state
UUpkeepSubsystem(no owned collections)Reads/writes FRaccoonData::ConsecutiveHungryTicks via URaccoonSubsystem. Timer callback driven by Game Clock
UCityMapSubsystemBuildingUnlockStatesTMap<FName, bool>Tracks which buildings are unlocked
UGameClockSubsystemGameClockTimefloatCurrent time in game-minutes (0–1440). See Game Clock

Content Browser Layout (initial)

Content/TrashNTreasure/
  Data/
    RaccoonTypes/     (empty — populated Block 2)
    Stations/         (empty — populated Block 3+)
    RaidTargets/      (empty — populated Block 3)
    Encounters/       (empty — populated Block 3)
    Buildings/        (empty — populated Block 3)
    Tables/           (empty — populated Block 8–9)
  Blueprints/
    Stations/         BP_StationBase
    Player/           BP_PlayerPawn, BP_PlayerController, BP_GameMode
    CityMap/          BP_Building, BP_RaccoonAIPawn, BP_CityCamera, BP_HideoutExit
  UI/                 (empty — populated Block 2+)
  Maps/
    L_Hideout.umap
    L_City.umap
  Materials/          M_BlockoutBase (parameterized color instance)

Done When

  • Player walks around blockout hideout in first person at raccoon height
  • 7 labeled station volumes placed and interactable (print to screen on interact)
  • Raid Board interact switches to city sublevel overhead camera with pan/zoom
  • City sublevel has 2 box buildings with hover highlight, NavMesh on roads, hideout exit marker
  • Escape from city view returns to hideout camera
  • All enums, structs compile — can instantiate an FRaccoonData, read its stats, check a resource counter in a C++ test
  • All 7 subsystem stubs instantiate via GetGameInstance()->GetSubsystem<T>()
  • All DataAsset C++ headers compile (no content assets yet)

References

Station Operation Model · Vision