CHexamaker

Overview

UCHexamaker is the hexagonal generation engine. It manages async tile computation, probabilistic mesh selection, multi-criteria filtering, and UHierarchicalInstancedStaticMeshComponent creation/removal. It inherits from UObject and implements ICCell and ICSingleDoRun.

Build Pipeline

Name Description
buildASync Entry point called by the spawner. Runs drawHexa async then updateISM_sync on the game thread
wantDraw Checks if a new draw is needed: room state, pawn movement, queue status
drawHexa Computes the tile grid around the pawn, runs calculateTile in ParallelFor, enqueues batches
updateISM_sync Dequeues a batch, creates ISMs, removes old ones, broadcasts delegates
// buildASync is the main entry point, called each tick by ACHexaSpawner:
hexamaker->buildASync(singleDoRun, pawnX, pawnY);

// Internally:
// 1. wantDraw() checks if a new pass is needed
// 2. drawHexa() computes the UV grid, runs calculateTile() in ParallelFor
// 3. Results are queued as FCHexaDataQueue
// 4. updateISM_sync() dequeues and creates ISMs on the game thread

Tile Calculation

Name Description
calculateTile Computes a tile: probabilistic mesh selection, Z position, jitter, rotation, scale, filtering
bannedLocationCandidatToAdd Checks if the position is inside a banned area
worldmakerCandidatToAdd Checks altitude, slope, slope alignment via WorldUtility
roomMakerCandidatToAdd Checks room type (ROOM/CORRIDOR/WALL) and distances
// calculateTile applies filters in this order:
// 1. Check enable and existing ISM
// 2. Convert coordinates → pixel
// 3. Biome noise filter (biomeSelectLowerBound/UpperBound)
// 4. Probabilistic mesh selection (meshProbaRHArray)
// 5. Rotation calculation (random if rotate=true)
// 6. Scale calculation (random between minScalePercent/maxScalePercent)
// 7. Jitter calculation (random between minJitterForce/maxJitterForce × tileSize)
// 8. Banned area filter (bannedLocationCandidatToAdd)
// 9. Worldmaker filter: altitude (withBound), slope (withNormal), alignment (alignToSlope)
// 10. Room filter: room type, distance to center/edge

ISM Management

Name Description
proceedIsm Prepares transform batches per mesh index for ISM creation
updateISM_sync Creates UCHierarchicalInstancedStaticMeshComponent, configures shadow/collision/cull, assigns instances
removeTile (static) Removes ISM instances by UV coordinates
removeTile (location) Removes the closest tile to a world position
// ISM creation in updateISM_sync:
// For each mesh index, a UCHierarchicalInstancedStaticMeshComponent is created.
// Configuration applied: shadow, collision, cull distance, ghost material.
// Instances are added in batch via AddInstances().
// The index handler (FCIndexHandler) maintains the UV ↔ instance mapping.

// Tile removal:
UCHexamaker::removeTile(tileArray);           // by FCHexaMakerTile array
UCHexamaker::removeTile(ismIndexArrayMap);    // by ISM → UV index map
hexamaker->removeTile(FVector2D(x, y));       // by world position
hexamaker->removeTile(FVector2D(x, y), ism);  // by world position + specific ISM

Ghost Mode

Each group of layers generates two hexamakers: one normal and one ghost. The ghost uses a transparent material (MAT_CdryxGhostEffect) applied to all meshes, and inverts the banned area logic (displays only inside banned areas).

UCHierarchicalInstancedStaticMeshComponent

Extension of UHierarchicalInstancedStaticMeshComponent with an integrated FCIndexHandler for instance tracking.

Name Description
indexHandler Maintains the bidirectional mapping between UV coordinates and ISM instance indices

FCIndexHandler

Index manager for ISM instance tracking. Listens to OnInstanceIndexUpdated events to maintain consistency during additions/removals.

Name Description
mapIndexToInstanceMap UV → instance map (find instance number from a UV index)
mapInstanceToIndexMap Instance → UV map (find UV index from an instance number)
assignIndexWithInstance Associates an array of UV indices with an array of instance indices
onInstanceIndexUpdatedHandler ISM callback: updates maps on Relocated/Removed/Cleared/Destroyed
// FCIndexHandler is created automatically by UCHierarchicalInstancedStaticMeshComponent.
// It listens to FInstancedStaticMeshDelegates::OnInstanceIndexUpdated.

// Find the ISM instance from UV coordinates:
if (int32* instance = chISM->indexHandler.mapIndexToInstanceMap.Find(uvIndex)) {
    // *instance is the instance number in the ISM
}

// Find UV coordinates from an instance number:
if (FCUVIndex* uvIdx = chISM->indexHandler.mapInstanceToIndexMap.Find(instanceId)) {
    // *uvIdx contains the (u, v) coordinates
}

FCHexaMakerTile

Tile structure inheriting from FCTile (CCOREUMODULE). Stores the computed placement data for a cell.

Name Description
meshRotation Computed mesh rotation
meshPosition Computed world position (with jitter and Z)
meshScale Computed scale
key UV coordinates of the tile (FCUVIndex)
meshIdxInHexaMakerStruct Index of the selected mesh in meshProbaRHArray
ismWeakRef Weak reference to the ISM containing this instance
coordToPixel Converts coordinates (q,r) → pixel (dispatches hexa/square)
pixelToCoord Converts pixel → coordinates (q,r) (dispatches hexa/square)
// Coordinate ↔ pixel conversion:
FVector2D pixel = FCHexaMakerTile::coordToPixel(q, r, tileSize, true);  // hexa
FVector2D pixel = FCHexaMakerTile::coordToPixel(q, r, tileSize, false); // square

FVector2D coord = FCHexaMakerTile::pixelToCoord(x, y, tileSize, true);  // hexa
FVector2D coord = FCHexaMakerTile::pixelToCoord(x, y, tileSize, false); // square