CRoommaker

Overview

UCRoommaker is the core room generation engine. It implements ICCell, ICRoomBoundable and ICCoordBoundable. It generates clusters of rooms, connects them with MST-based corridors, assigns spatial cells for fast lookup, creates box collisions for overlap detection, and computes a longest-path ordering for progression.

Instantiation

Name Description
instantiate Static factory. Creates a singleton UCRoommaker bound to a scene component, with a random stream and cluster configuration
// Called by ACRoomSpawner::init()
UCRoommaker::instantiate(GetRootComponent(), roommaker, stream, *data);

Generation

Name Description
buildASync Entry point for async generation. Delegates to drawRoom then finalize_sync via queue
drawRoom Generates all rooms and clusters: random placement, relaxation, Delaunay, MST, edge breaking, cell assignment
createRoom Creates rooms for a single FCRoomCountStruct within a cluster
finalize_sync Dequeues generation results and creates metadata (UCRoomMetadata, UCClusterMetadata)
finishWorldObject Spawns box collisions per room after both room and world spawners are ready
// buildASync is called on tick by ACRoomSpawner.
// It runs drawRoom asynchronously, then finalize_sync on the game thread.
roommaker->buildASync(singleDoRun);

// drawRoom pipeline:
// 1. For each FCRoomMakerCountStruct, create rooms with random positions
// 2. Relax rooms using the configured CAlgoRelaxType until stable
// 3. Relax clusters in a second pass
// 4. Delaunay triangulation for room connectivity
// 5. MST for corridor paths (straight or flex)
// 6. Break edges with noise for organic corridors
// 7. Assign rooms, clusters and edges to spatial cells

// finalize_sync creates UCRoomMetadata per room (doors, tags)
// and UCClusterMetadata per cluster (fog of war, specific noise).
// After all clusters are finalized, longestOrderedPath computes
// room ordering along the MST for progression.

// finishWorldObject spawns UCRoomBoxCollision per room
// for overlap detection (quest/skill triggers).

Retrieval

Name Description
retrieveClusterById Returns a cluster FCRectangle by cluster ID
retrieveRoomById Returns a room FCRectangle by cluster ID and room ID
retrieveRoomDetailById Returns FCRoomDetailData for a cluster
retrieveClusterByTag Returns all clusters matching a FName tag
retrieveRoomByTag Returns all rooms matching a FName tag
retrieveEdgeById Returns a corridor FCEdge by cluster ID and edge ID
retrieveClusterByRoom Returns the parent cluster of a room via its metadata
retrieveClusterMetadata Casts a cluster’s metadata to UCClusterMetadata
retrieveRoomMetadata Casts a room’s metadata to UCRoomMetadata
retrieveSpecificNoiseData Returns per-cluster specific noise and shift noise
// Retrieve a room by IDs:
FCRectangle* room = roommaker->retrieveRoomById(clusterId, roomId);

// Retrieve all rooms with a specific tag:
TArray<FCRectangle*> treasureRooms = roommaker->retrieveRoomByTag(FName("treasure"));

// Get room metadata (doors, tag, consumption state):
UCRoomMetadata* meta = roommaker->retrieveRoomMetadata(room);

// Get cluster-specific noise for terrain modulation:
auto [noise, shiftNoise] = roommaker->retrieveSpecificNoiseData(cluster);

Iterators

Name Description
iterateOnCluster Iterates over all clusters. Callback returns true to break
iterateOnClusterRoom Iterates over all rooms in all clusters. Callback returns true to break
// Iterate all clusters:
roommaker->iterateOnCluster([](FCRectangle* cluster) {
    // process cluster
    return false; // true to break
});

// Iterate all rooms across all clusters:
roommaker->iterateOnClusterRoom([](FCRectangle* cluster, FCRectangle* room) {
    // process room within its cluster
    return false; // true to break
});

Geometry Finders

Name Description
closestCluster Finds the closest cluster containing a 2D point (cell-limited)
closestRoom Finds the closest room containing a 2D point with optional tolerance (cell-limited)
closestEdgeWithin Returns all corridor edges within a distance from a 2D point (cell-limited)
closestEdge Finds the single closest corridor edge to a 2D point (cell-limited)
nearEdge Finds the nearest edge within its influence width (cell-limited)
fogOfWarPart Returns the fog of war rectangle for a cluster
// Find closest room at a world position:
FCRectangle* rect;
if (roommaker->closestRoom(FVector2D(x, y), rect)) {
    // rect is the room containing or nearest to (x, y)
}

// Find corridor edges within 500 units:
TArray<FCEdge> edges = roommaker->closestEdgeWithin(FVector2D(x, y), 500.0f);

// Check if a point is near a corridor (within edge width):
FCEdge edge;
if (roommaker->nearEdge(FVector2D(x, y), edge)) {
    // point is within the corridor influence zone
}

Overlap & Interaction

Name Description
OnBeginOverlap Triggered when an actor enters a room box collision
OnEndOverlap Triggered when an actor leaves a room box collision
isRoomEligibleForTagProba Checks room content eligibility based on character tags and probability ranges
longestOrderedPath Computes the longest path through the MST for room progression ordering
// Room overlap triggers quest actions and skill consumption:
// On begin overlap: checks quest system first, then skill system.
// If interactWithPlayerOnly is true, only the player pawn triggers.
// If canOnlyBeConsumedOnce is true, the room is marked consumed after first interaction.

// Room eligibility for content:
int contentCount;
if (roommaker->isRoomEligibleForTagProba(contentCount, room, charMainTag, charTagArray, true)) {
    // room is eligible, contentCount indicates how many tags matched
}