Technical Design

Source Code Structure (C++)

This defines how the C++ source is organized so it mirrors the design and stays maintainable. It complements the content layout in 03-Content-Folder-Structure.md(03-Content-Folder-Structure.md).

Status: reviewOwner: UnassignedUpdated: 2026-09-23

Production schedule — 2026-09-13: PIPE-ROADMAP now defines 32 focused phases (P00–P31). Phase 0/1/2/3 references retained in this document are legacy scope bands, not the new phase numbers. The owner confirmed limited-area core-loop proof before full-map expansion; see the roadmap for dependencies, audited status and remaining work.

Production context

Deprecated source referenceGDD/05-Technical/04-Source-Code-Structure.md
Decision markers0 confirmed · 3 recommendations · 0 TBD
Browser document roleThis standalone HTML file is authoritative; edit this file directly through the project workflow.

Verified implementation evidence

The current C++ hardening pass verifies the source boundaries and tests below; it does not reclassify unrelated planned modules.

  • Source/Lambeer/Persistence/LambeerSQLiteStore.*
  • Source/Lambeer/Interaction/LambeerInteractableRegistry.*
  • Source/Lambeer/UI/LambeerInventoryWidget*.cpp

Relationships

Document contract coverage

Use these required Technical Design areas during review. The HTML content below is authoritative; items not stated explicitly remain unresolved.

  • ReviewProblem & Scope
  • ReviewCurrent vs Proposed
  • ReviewArchitecture
  • ReviewData Model
  • ReviewInterfaces & Events
  • ReviewReplication / Persistence
  • ReviewPerformance & Failure Handling
  • ReviewImplementation Plan
  • ReviewVerification Strategy
  • ReviewTechnical Decisions / TBDs

Authoritative project content

This defines how the C++ source is organized so it mirrors the design and stays maintainable. It complements the content layout in 03-Content-Folder-Structure.md.

C++ review implementation — 2026-09-23

[IMPLEMENTED; owner PIE acceptance pending] The owner authorized correctness and performance fixes identified in the current-source review. The canonical save contract describes failure recovery, exclusive background SQLite access and critical flush ordering.

  • Persistence/LambeerSQLiteStore.* is plain C++ storage logic. SQLiteSaveBackend retains the existing UObject/interface boundary; SaveSubsystem owns worker lifetime and synchronization.
  • Interaction/LambeerInteractableRegistry.* maintains weak references from actor-spawn and level add/remove events. A single initial world walk seeds the index. Proximity fallback filters this interactable-only index using current actor positions, per-target distances and CanInteract, preserving collisionless/Blueprint targets and valid-target priority. It no longer enumerates every world actor on each trace miss. Candidate selection still scales with loaded interactables; this is not a measured FPS gain or a spatial-tree implementation.
  • Focused prompt content refreshes when action text, quantity, denied reason or hold duration changes. The existing prompt widget is reused. Position tracking remains in the prompt host and does not force a full HUD refresh on every target movement.
  • World/LambeerDoor uses a stable PlacementRoot with a rotating child Hinge; opening and closing preserve the actor placement transform. Existing saved Kit Proof Town doors were inspected through MCP after reload.
  • UI/LambeerInventoryWidget.cpp now holds lifecycle, input and refresh coordination. Existing member implementations were moved without behavior changes into LambeerInventoryWidgetDetails.cpp, LambeerInventoryWidgetTransfer.cpp, LambeerInventoryWidgetLayout.cpp and LambeerInventoryWidgetPreview.cpp. Shared presentation constants/helpers live in a private header. The UCLASS, Blueprint properties, bindings and approved UI layout remain the same.

Validation and owner acceptance

Verified 2026-09-23: closed-Editor LambeerEditor Win64 Development build succeeded. MCP automation passed 62/62 across Persistence, Interaction, HUD, Frontend, Crafting and World; the only warning is the pre-existing GameplayCueNotifyPaths configuration warning in EntryBeforeBeginPlay. The failure-recovery and interaction fixtures pass without unexpected errors or warnings. Source comparison verified all 102 Inventory Widget member implementations unchanged; the coordinator file decreased from 4,070 to 1,412 lines. HTML validation passed 45 documents with zero errors/warnings. Test results · Build log · Source equivalence. No PIE was started or controlled by the agent; no measured FPS improvement is claimed.

  1. Owner: start Dedicated Server + two Preview clients in a separate test world. Open/close doors facing different directions and confirm prompt text updates without looking away.
  2. Partially collect a pickup and confirm its focused quantity changes. Verify nearby targets after spawning drops and after streaming a cell out/in.
  3. Transfer authored-container loot while background saves run, then Save and Exit/restart/rejoin. Verify player inventory, remaining crate contents and drops without duplicates or loss.
  4. Check Inventory, Item Details, drag/drop, attachment install/remove and preview rotation/zoom in PIE after the source split.
  5. Profile frame time during a populated-world autosave before claiming a performance improvement. Snapshot capture remains on the game thread; only copied-data serialization and database writes run in the worker.

Current state (from disk)

Source/
  Lambeer.Target.cs
  LambeerEditor.Target.cs
  Lambeer/
    Lambeer.Build.cs
    Lambeer.cpp / Lambeer.h
    LambeerCharacter.{h,cpp}
    LambeerGameMode.{h,cpp}
    LambeerPlayerController.{h,cpp}
    Variant_Combat/        # template example — TO BE REMOVED
    Variant_Platforming/   # template example — TO BE REMOVED
    Variant_SideScrolling/ # template example — TO BE REMOVED

The three Variant_* folders are Third Person template demos and will be deleted (see 05-Project-Setup-Steps.md). The base LambeerCharacter/GameMode/PlayerController are kept and evolved.

Target structure — [RECOMMENDATION]

Organize the runtime module by feature. Start with one runtime module (Lambeer) using folders; split into multiple modules only if build times or boundaries demand it later.

Source/
  Lambeer.Target.cs            # client/standalone target
  LambeerEditor.Target.cs      # editor target
  LambeerServer.Target.cs      # dedicated server target (ADD — Linux)  [RECOMMENDATION]
  Lambeer/
    Lambeer.Build.cs
    Lambeer.{h,cpp}            # module impl
    Core/                      # framework: GameMode, GameState, PC, PS, GameInstance, subsystems
    Character/                 # ALambeerCharacter + base pawn logic
    Components/                # shared character components (or co-locate per feature)
    Combat/                    # weapons, damage, projectiles, recoil
    Survival/                  # USurvivalStatsComponent, status effects, wetness/rain exposure
    Inventory/                 # inventory, equipment, item structs
    Building/                  # build component, building piece actors/records
    Crafting/                  # crafting component, recipe resolution
    Interaction/               # interaction component + interactable interface
    AI/                        # zombie pawns, AI controllers, StateTree tasks, EQS
    Items/                     # item data assets + base types
    Vehicles/                  # vehicle pawn(s) (Phase 2)
    Persistence/               # save/load abstraction + subsystem
    Social/                    # squads, clans, group registry
    UI/                        # C++ side of UI (HUD class, widget base classes)
    Data/                      # USTRUCT/UENUM shared data type definitions
    Lambeer.h forwarders, etc.

Within each feature folder, keep headers and sources together (the template style) or split Public//Private/ — pick one and be consistent. The template uses flat folders, which is fine for a single module.

Module / target notes

  • LambeerServer.Target.cs — add a dedicated-server target so the Linux server build is first-class from Phase 1. Critical because the entire game is server-authoritative (see ../04-Multiplayer/01-Network-Architecture.md).
  • Lambeer.Build.cs — declare module dependencies explicitly (e.g., EnhancedInput, StateTreeModule/GameplayStateTreeModule, AIModule, UMG, NetCore, GameplayAbilities if GAS is adopted, ChaosVehicles in Phase 2). Add as features land; don't pre-add unused deps.
  • Editor-only code (tools, custom editor utilities) must be guarded/WITH_EDITOR or live in an editor module if it grows.

Dependency direction

  • Core and Data are low-level; feature modules depend on them, not vice-versa.
  • Features communicate via interfaces (UINTERFACE) and components, not hard cross-feature includes, to keep the graph acyclic.
  • Persistence depends on feature data structs (to save them) but features should depend on a persistence interface, not the backend.

When to split into multiple modules — [RECOMMENDATION]

Defer until justified. Split when: build/iteration times hurt, or you need a clean editor/runtime boundary, or you want a reusable plugin. Candidate first split: an Editor module for custom tooling; later a LambeerAI or LambeerCore if the single module grows large.