Aukke Building System / Developer documentation

Build at scale. Keep every piece.

A modular C++ building system for Unreal Engine 5. Geometry stays lightweight as instanced meshes. Interactive pieces become Actors only when they actually need behavior.

Why it is built this way

Building systems usually hit the same wall: make every wall, floor and foundation a full Actor, and performance collapses after a few thousand pieces. Aukke Building System asks one question when a piece is placed: does it need runtime behavior, or is it just geometry?

If it is geometry only, it becomes an entry in an instanced static mesh component, tracked by a GUID. If it needs interaction or custom logic, it becomes a proper Actor. Both representations live in the same registry, so game code can query them the same way.

This Actor versus ISM split is the central idea behind the whole plugin.
UBuildingComponentattached to your Pawn
ABuildingHologrampreview and validation
Actor or ISMregistered by GUID

Everything the game needs to know about a placed piece—health, type, transform and attachment chain—lives in UBuildingRegistrySubsystem. Query the registry, not the Actor: a piece might not have one.

Actor / ISM hybridGUID registryChunked instancingSave-ready

Getting started

Requirements

RequirementValue
EngineUnreal Engine 5.8
DependencyGameplayTags, enabled automatically
PlatformWindows for now

Install the plugin

  1. Copy the AukkeBuildingSystem folder into your project’s Plugins/ directory.
  2. Rebuild, or open the .uproject and accept the Editor rebuild prompt.
  3. Confirm that the plugin is enabled under Edit > Plugins.
Before writing your own setup, play Content/Demo/Level/L_BuildingMap. It is the reference implementation for the systems described here.

Wire up your own build mode

  1. Create a piece Blueprint based on ABuildingPiece. Assign a mesh, a PieceType tag and snap points.
  2. Create a hologram Blueprint, or use the base class, and assign valid and invalid materials.
  3. Add UBuildingComponent to your Character and set its HologramClass.
  4. Bind input for build mode, piece selection, placement, demolish mode and demolition.
ActionCall
Toggle build modeSetBuildingMode(Placing) / SetBuildingMode(None)
Cycle pieceSetCurrentPieceClass(NextClass)
ConfirmTryConfirmPlacement()
Toggle demolish modeSetBuildingMode(Demolishing) / SetBuildingMode(None)
DemolishTryDemolishPiece()

Enter build mode, select a piece, aim and confirm. That is the complete player-facing loop.

Core concepts

Building pieces

ABuildingPiece is the abstract base class for every wall, floor, foundation, door and window.

PropertyWhat it controls
MeshThe visible static mesh. Offset it from PieceRoot when its source pivot is not the desired snap origin.
PieceTypeThe gameplay tag that identifies the piece.
SnapPointsLocations where compatible pieces can attach.
SnapSearchRadiusHow far the hologram searches for a compatible snap point.
MaxHealth / CurrentHealthThe piece health pool. Zero destroys the piece.
AllowedFreePlacementSurfaces / bAllowPlacementOnGenericSurfacesSurfaces accepted when no snap point is used.
RequiredGroundClearancePrevents a piece from floating over an unsupported gap.
bAutoOccupancyCheckExtent / OccupancyCheckBoxThe overlap volume used to prevent invalid placement. Disable automatic sizing for irregular meshes.
IgnoredOverlapTypesPiece types that may overlap without blocking placement.
bAllowFlipToFaceTraceLets a snapped piece flip 180 degrees to face the camera.

Editor-only helpers bAutoCenterMeshX/Y/Z can center mesh bounds on PieceRoot. For multi-leg pieces, bCheckPieceRootClearance and GroundClearanceCheckPoints define the exact support points to test.

The Actor versus instance decision

UBuildingComponent::TryConfirmPlacement checks whether the piece class implements IInteractable.

Implements IInteractableDoes not
BecomesA real ABuildingPiece ActorAn ISM instance tracked by GUID
Use forDoors, chests, levers and per-instance logicWalls, floors, foundations, roofs and stairs
CostA full Actor and componentsA small instance entry; thousands are affordable
Avoid implementing IInteractable “just in case”. Every class that does pays the Actor cost for every placed piece.
Damage and demolition

Demolition is player-driven through TryDemolishPiece. It bypasses health and is gated by CanDemolishPiece.

Damage uses ABuildingPiece::ApplyDamage, clamps CurrentHealth, broadcasts OnHealthChanged, and destroys the piece at zero. The engine’s TakeDamage path is supported, so UGameplayStatics::ApplyDamage works for Actor-backed pieces.

When only a trace hit is available, call UBuildingCombatLibrary::ApplyDamageToHitResult. It resolves whether the hit belongs to an Actor or an instance. For a game-wide destruction event covering both representations, bind to UBuildingRegistrySubsystem::OnAnyPieceDestroyed.

Snap points, tags and placement rules

An FBuildingSnapPoint is a compatible attachment location on a piece.

FieldPurpose
RelativeTransformLocation and rotation relative to the owning piece.
AcceptsTypesGameplay-tag filter for accepted piece types.
bIsOccupiedWhether another piece is currently attached; managed automatically.

Snap-point helpers bAutoCenterX/Y/Z keep points aligned to changing mesh bounds. Native tags ship below Building.Piece.* for foundation, floor, wall, doorframe, windowframe, roof, door, window and stair, with wood and stone examples. Extend them with native tags or through Project Settings > GameplayTags.

UBuildingPieceRules is an optional data asset for required-parent rules such as “a door requires a doorframe”. Assign it to the hologram’s PlacementRules. Omitted piece types remain unrestricted.

The runtime systems

The hologram

ABuildingHologram mirrors the selected PieceClass: mesh, offset, snap radius, occupancy and clearance settings. It traces up to TraceDistance every frame, or on the configured PlacementUpdateInterval, finds compatible snap points, checks blocking and reports through IsPlacementValid().

Assign ValidMaterial and InvalidMaterial for visual feedback. The class can be extended with particles, audio and UI. The current attachment is exposed through GetMatchedParentPiece(), GetMatchedParentPieceID(), IsMatchedParentInstance() and GetMatchedSnapPointIndex().

The Pawn component

UBuildingComponent drives placement and demolition from your own input bindings. It does not depend on Enhanced Input.

FunctionPurpose
EnterBuildMode() / ExitBuildMode()Spawn or destroy the hologram.
SetCurrentPieceClass(Class)Switch the selected piece.
TryConfirmPlacement()Place the real piece when validation succeeds.
EnterDemolishMode() / ExitDemolishMode()Start or stop demolition targeting.
TryDemolishPiece()Destroy the target when CanDemolishPiece agrees.
SetBuildingMode(EBuildingMode)Single switch for all modes.
IsInBuildMode() / IsInDemolishMode() / GetBuildingMode()Read the active mode for UI and gameplay.

CurrentDemolishTarget and CurrentDemolishTargetID expose the current target. Feedback delegates include OnPiecePlaced, OnPieceDemolished and OnDemolishTargetChanged. Instance highlighting uses SetPieceInstanceCustomDataValue.

The registry

UBuildingRegistrySubsystem is created automatically once per world. It is the source of truth for both Actors and instances.

C++ — query a piece
FBuildingPieceData Data;
if (Registry->GetPieceData(SomePieceID, Data))
{
    // Data.CurrentHealth, Data.PieceType, Data.Transform...
}

Use HasPiece and GetAllRegisteredPieceIDs for reads. DestroyInstancePiece is the complete removal path for an instance, including its snap data and ISM entry. Delegates OnPieceRegistered, OnPieceUnregistered and OnAnyPieceDestroyed expose world-level lifecycle events.

Chunking

The world is split into a grid of chunks, 5000 units per cell by default. Each active chunk owns one ISM component per distinct mesh used inside it. Chunks are created only when pieces are placed.

UBuildingChunkSubsystem resolves AddPieceInstance, RemovePieceInstance, UpdatePieceInstanceTransform and SetPieceInstanceCustomDataValue, including transparent movement across chunk boundaries. To drive material highlights, configure NumInstanceCustomDataFloats before placing pieces and read the values with a Per Instance Custom Data material node.

Collision channels

Building traces use Visibility by default.

PropertyOwner
TraceChannelABuildingHologram
DemolishTraceChannelUBuildingComponent
InteractionTraceChannelUInteractionComponent
If Visibility is already used by camera collision or AI, assign these properties to a dedicated trace channel under Project Settings > Collision.

Saving & loading

The plugin supplies serializable data, not a complete save-slot system. UBuildingSaveSubsystem::CaptureState fills an FBuildingSaveData; RestoreState rebuilds the world from it. Your own USaveGame decides when and where that data is written.

C++ — your USaveGame
UPROPERTY()
FBuildingSaveData BuildingData;

// Saving
GetWorld()->GetSubsystem<UBuildingSaveSubsystem>()
    ->CaptureState(BuildingData);

// Loading
GetWorld()->GetSubsystem<UBuildingSaveSubsystem>()
    ->RestoreState(BuildingData);

Restore order

Restore clears the current state, then rebuilds parents before children so attachment chains remain correct at any depth.

Foundationparent
Wallchild
Doordescendant

If a piece Blueprint was renamed or removed after a save was created, that piece is skipped and logged without aborting the rest of the restore.

Compatibility across updates

Every capture carries a version number. Older saves, including version zero, still load. A save written by a newer plugin version is rejected before any world state is modified: RestoreState returns false and logs the reason. This prevents partial or corrupt downgrades.

Extending & customizing

Three overridable functions on UBuildingComponent cover common project-specific behavior.

HookDefaultOverride for
GetTraceStartAndDirectionOwner cameraTop-down view, mouse-to-world or VR controller.
CanConfirmPlacement(Hologram)AllowedResource cost, cooldown and build permissions.
CanDemolishPiece(PieceType, Piece)AllowedOwnership and refunds. Piece is null for instances.
C++ — placement permission
bool UMyBuildingComponent::CanConfirmPlacement_Implementation(
    const ABuildingHologram* Hologram) const
{
    if (!Super::CanConfirmPlacement_Implementation(Hologram))
        return false;

    return MyInventory->HasEnoughResources(Hologram->PieceClass);
}

Blueprint subclasses can override the equivalent events without C++.

Interaction stays separate

IInteractable and UInteractionComponent are independent of the building system. Implement Interact(Instigator, HitComponent) on a door, chest, NPC or any Actor. Add UInteractionComponent to the player, configure InteractionDistance, then call TryInteract() from input. The exact response remains entirely in your Blueprint or C++ class.

Troubleshooting

Logs and debug tools

Failures are reported to LogAukkeBuildingSystem. Use log LogAukkeBuildingSystem Verbose in the console for detailed placement information.

ToggleShows
ABuildingPiece::bShowSnapPointDebugSnap points in the editor viewport.
bShowOccupancyCheckBoxDebugThe occupancy validation volume.
bShowGroundClearanceDebugGround-clearance sample points.
UBuildingChunkSubsystem::bShowChunkBoundsDebugChunk grid boundaries.

All debug rendering is editor-only and removed from Shipping builds.

A piece will not place

Check that a mesh is assigned, verify whether the piece type requires a parent, inspect ground clearance, then read the log message explaining the rejected validation.

A piece is missing after loading

Its Blueprint was probably renamed or deleted after the save was written. The missing piece is logged and the rest of the save continues loading.

Two touching pieces block each other

The automatic occupancy box is slightly smaller than mesh bounds. If collision bounds still extend past the visible mesh, disable bAutoOccupancyCheckExtent and configure OccupancyCheckBox manually.

Demolish mode targets the wrong object

Move DemolishTraceChannel away from Visibility and use a dedicated project collision channel.

Current limitations
  • No networking yet. Placement, demolition and saving are local and non-authoritative. Multiplayer requires an authority layer.
  • Windows only for now. The restriction is currently declared in the .uplugin; the C++ has not been validated on other platforms.
  • No structural integrity system yet. Removing a support does not automatically collapse descendants. ParentPieceID already stores the attachment chain for a future layer.
  • No resource costs or permissions by default. Implement them through CanConfirmPlacement and CanDemolishPiece.

Class index

Class or typeRole
ABuildingPieceBase class for every piece type.
ABuildingHologramPlacement preview and validation.
UBuildingComponentBuild and demolition component for a Pawn.
UBuildingRegistrySubsystemSource of truth for placed pieces.
UBuildingChunkSubsystemAutomatic chunked ISM management.
UBuildingSaveSubsystemConverts runtime state to and from save data.
UBuildingPieceRulesOptional required-parent placement rules.
UBuildingCombatLibraryApplies damage from a trace hit to either representation.
IInteractable / UInteractionComponentGeneric interaction independent of building.
FBuildingPieceDataPer-piece registry and save data.
FBuildingSnapPointOne attachment point on a piece.
FBuildingSaveDataSerializable snapshot of the complete building state.
Every public class and function also carries inline documentation in its header. This page is the map; the headers remain the ground truth.
9 documented classes1 interface3 structsDemo: L_BuildingMap