{"record":{"id":"91de5e2ec17c3ba1","repo":"OpenRA/OpenRA","slug":"could-not-fit-tiles-for-sand-sand-cliffs-91de5e","errorCode":null,"errorMessage":"Could not fit tiles for sand-sand cliffs","messagePattern":"Could not fit tiles for sand-sand cliffs","errorType":"exception","errorClass":"MapGenerationException","httpStatus":null,"severity":"error","filePath":"OpenRA.Mods.D2k/Traits/World/D2kMapGenerator.cs","lineNumber":343,"sourceCode":"\t\t\t\t\tparam.SmoothingThreshold, /*smoothingThresholdOutOf=*/FractionMax,\n\t\t\t\t\tparam.MinimumSandCliffThickness,\n\t\t\t\t\tfalse);\n\t\t\t\tvar contours = MatrixUtils.BordersToPoints(plan);\n\t\t\t\tvar partitionMask = cliffMask.Map(masked => masked ? sandSandCliffZone : sandZone);\n\t\t\t\tvar tilingPaths = terraformer.PartitionPaths(\n\t\t\t\t\tcontours,\n\t\t\t\t\t[sandSandCliffZone, sandZone],\n\t\t\t\t\tpartitionMask,\n\t\t\t\t\tparam.SegmentedBrushes,\n\t\t\t\t\tparam.MinimumSandCliffStraight);\n\t\t\t\tforeach (var tilingPath in tilingPaths)\n\t\t\t\t{\n\t\t\t\t\tvar brush = tilingPath\n\t\t\t\t\t\t.OptimizeLoop()\n\t\t\t\t\t\t.ExtendEdge(4)\n\t\t\t\t\t\t.SetAutoEndDeviation()\n\t\t\t\t\t\t.Tile(sandSandCliffTilingRandom)\n\t\t\t\t\t\t\t?? throw new MapGenerationException(\"Could not fit tiles for sand-sand cliffs\");\n\t\t\t\t\tterraformer.PaintTiling(pickAnyRandom, brush);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Sand Detail\n\t\t\tif (param.SandDetail > 0)\n\t\t\t{\n\t\t\t\tvar space = terraformer.CheckSpace(param.PlayableTerrain);\n\t\t\t\tvar passages = terraformer.PlanPassages(\n\t\t\t\t\ttopologyRandom,\n\t\t\t\t\tterraformer.ImproveSymmetry(space, true, (a, b) => a && b),\n\t\t\t\t\tparam.SandDetailCutout,\n\t\t\t\t\tparam.MaximumSandDetailCutoutSpacing);\n\t\t\t\tvar plan = terraformer.BooleanNoise(\n\t\t\t\t\tsandDetailRandom,\n\t\t\t\t\tparam.SandDetailFeatureSize,\n\t\t\t\t\tparam.SandDetail,\n\t\t\t\t\tparam.SandDetailClumpiness);","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/OpenRA/OpenRA/blob/a520984d91eda9de48a62b1d15c1e3bad0d4fb1a/OpenRA.Mods.D2k/Traits/World/D2kMapGenerator.cs#L325-L361","documentation":"Thrown when PathTile.Tile(sandSandCliffTilingRandom) returns null while tiling the sand-sand cliff contours. Tile returns null when the SegmentedBrushes-based tiling cannot fit the brush pieces along a contour loop after OptimizeLoop/ExtendEdge/SetAutoEndDeviation. This is a MapGenerationException specific to the sand-cliff generation branch (param.SandCliffs > 0).","triggerScenarios":"The sand cliff branch runs: contours are sliced into tilingPaths, each path is optimized and tiled with sand-sand cliff brushes (param.SegmentedBrushes); if any single path cannot be tiled, the ?? throws.","commonSituations":"SandCliffs parameter set high relative to map size; segmented cliff brushes with insufficient straight-segment pieces to satisfy MinimumSandCliffStraight; a contour that is too jagged for the available brush set; modded cliff templates missing required segments.","solutions":["Reduce param.SandCliffs or relax MinimumSandCliffStraight so contours need fewer straight pieces.","Enlarge the map so cliff contours are longer and smoother.","Retry with a different seed to get more tileable contours.","Ensure the SegmentedBrushes set includes all required straight and corner segments for the sand-sand cliff zone."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-check cliff brush segment availability against minimum straight requirement\nif (param.SandCliffs > 0 &&\n    param.SegmentedBrushes.Brushes.Count(b => b.IsStraight) < param.MinimumSandCliffStraight)\n    throw new MapGenerationException(\"SegmentedBrushes lack enough straight segments.\");","typeGuard":null,"tryCatchPattern":"for (int attempt = 0; attempt < 8; attempt++)\n{\n    try { return generator.Generate(modData, args.WithSeed(baseSeed + attempt)); }\n    catch (MapGenerationException) when (attempt < 7) { }\n}\nthrow new MapGenerationException(\"Sand cliff tiling failed after retries.\");","preventionTips":["Tune SandCliffs and MinimumSandCliffStraight to brush availability.","Use seed-retry for contour-dependent tiling failures.","Ensure SegmentedBrushes include all required straight/corner segments."],"tags":["map-generation","d2k","tiling","procedural","cliffs","retry"],"backgroundTag":null,"analyzedSha":"a520984d91eda9de48a62b1d15c1e3bad0d4fb1a","analyzedAt":"2026-08-13T15:30:14.787Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}