This workbook provides a step-by-step practical guide to translating the Rogue 5.4.4 dungeon generation algorithm into a high-performance, thread-safe system within Unreal Engine 5.7.
Before writing the algorithm, ensure your Unreal Project is configured to handle the Procedural Content Generation (PCG) framework and the Gameplay Ability System. Add the plugins to your project.
Open your project's main Build.cs file (e.g., Source/Rogue_LBFF_UE/Rogue_LBFF_UE.Build.cs) and ensure the following modules are included:
PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
"InputCore",
"EnhancedInput",
"PCG",
"GameplayAbilities",
"GameplayTags",
"GameplayTasks"
});
For a clean implementation, follow this directory structure within your Source/[ProjectName]/ folder:
Public/World/
RogueWorldSubsystem.h: The engine hook that manages the dungeon state.RogueDungeonTypes.h: Contains all shared USTRUCT and UENUM definitions.Private/World/
RogueWorldSubsystem.cpp: Implementation of the 3x3 partitioning and connectivity.Public/PCG/
PCGRogueGenerator.h: The custom PCG node settings and execution element.Private/PCG/
PCGRogueGenerator.cpp: Translating C++ grid data into PCG Points.Define the "Rogue Logic" in a way Unreal understands.
In RogueDungeonTypes.h, define your tile types and room structures. Use UPROPERTY to ensure visibility in the Editor.
UENUM(BlueprintType)
enum class ERogueTileType : uint8 {
Void,
Floor,
Wall,
Door,
Corridor
};
USTRUCT(BlueprintType)
struct FRogueRoom {
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly)
int32 SectorID;
UPROPERTY(BlueprintReadOnly)
FBox2D Bounds;
UPROPERTY(BlueprintReadOnly)
bool bIsGone = false;
};
[!IMPORTANT]
Verification Milestone 1: Compilation & Class Visibility
- Compile the project.
- In the Unreal Editor, create a new Blueprint inheriting from
Actor.- Verify you can add a variable of type
ERogueTileTypeand see the enum options in the dropdown. This confirms your header is correctly reflected.
The URogueWorldSubsystem is the "Brain" of our dungeon.
In RogueWorldSubsystem.cpp, implement the logic to divide DungeonSize by 3. Generate a FRogueRoom for each of the 9 sectors.
Use DrawDebugRect() to draw the calculated sector bounds in the viewport.
[!IMPORTANT]
Verification Milestone 2: Geometry Debugging
- In the Editor, place an empty Actor with a reference to the
RogueWorldSubsystem.- Trigger
GenerateDungeon().- Validation: Check the viewport. You should see a perfect 3x3 grid of debug rectangles. If they vary in size or overlap, check your loop math (X * SectorWidth).
Now we connect the rooms using the classic L-shaped corridors.
When connecting Sector A to Sector B, calculate an "Elbow" point to prevent diagonal lines.
// Horizontal-First or Vertical-First logic
if (RandomStream.GetFraction() > 0.5f) {
Elbow = FVector(End.X, Start.Y, 0.0f);
} else {
Elbow = FVector(Start.X, End.Y, 0.0f);
}
[!IMPORTANT]
Verification Milestone 3: Topology Check
- Use
DrawDebugLine()to connectStart -> ElbowandElbow -> End.- Validation: Every line should be strictly horizontal or vertical. Identify "Disconnected Islands"—if any room is not reachable from Sector 0, your Spanning Tree logic needs refinement.
The final step is converting your abstract C++ grid into PCG Points.
In FPCGElement::ExecuteInternal, iterate through your grid data and output a UPCGPointData collection. Each point should have an attribute TileType.
[!NOTE]
Verification Milestone 4: PCG Inspection
- Create a PCG Graph and add your "Get Rogue Grid" node.
- Right-click the node and select Inspect.
- Validation: Check the attribute list. Ensure the
TileTypeintegers match your C++ Enum (e.g., 0 for Void, 1 for Floor).- Add a "PCG Filter" node to isolate only "Floor" points. Verify that the correct number of meshes spawn only within the room boundaries.
ExecuteInternal logic in a TRACE_CPUPROFILER_EVENT_SCOPE to monitor generation time.Seed value in your Data Asset. Ensure the entire dungeon shifts predictably while maintaining connectivity.Next Step: Proceed to Chapter 3 for GAS Integration.