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