Runtime API

This page covers the public entry points normally needed by a game. The generation subsystems remain public for advanced integrations, but most games should interact only with MapGenerator, MapDefinition and ProceduralMapGenerationResult.

Generate a map

Add MapGenerator to a GameObject, configure its Definition, then call one of the following methods:

using Sorolif.RTS.MapGenerator;
using UnityEngine;

public sealed class MatchMapBootstrap : MonoBehaviour
{
    [SerializeField] private MapGenerator generator;

    private void Start()
    {
        generator.Definition.UseRandomSeed = false;
        generator.Definition.Seed = 12345;

        if (!generator.TryGenerateRuntimeMap(
                out ProceduralMapGenerationResult result))
        {
            foreach (MapGenerationIssue issue in result.ValidationIssues)
                Debug.LogWarning(issue);

            return;
        }

        foreach (Vector3 spawn in result.PlayerSpawnWorldPositions)
            SpawnPlayerAt(spawn);
    }

    private void SpawnPlayerAt(Vector3 position)
    {
        // Connect this position to your own player-spawning system.
    }
}

TryGenerateRuntimeMap returns false for a blocking validation or generation failure and always assigns a result. Unexpected exceptions raised by a client prefab, material or integration are converted into a generation.exception error. The available terrain remains visible as a preview, and the exception is written to the Console as a warning with its stack trace. Recoverable generation failures do not trigger Unity's Error Pause. GenerateRuntimeMap returns the same result object when a Boolean return value is not needed.

Procedural bridge, plateau-access and player-land-route audit errors do not stop the remaining visual stages. Mountains, terrain/water, cliffs, biome props, altitude, packing, cleanup and optional screenshots still run. Missing or invalid bridge decks are skipped; invalid custom deck instantiation is reported as bridges.prefab_invalid. A completed visual map can therefore still have Succeeded == false when its gameplay connectivity is invalid.

Scene gizmos remain available on this preview and after scene reload. They use serialized visual positions belonging to the retained map, without exposing a failed gameplay grid or spawn lists. Access the independent root component through result.MapInformation; its ShowGizmos and ShowLabels properties control the markers. See Generated Map Information. Strategic choke roads also render from their original route plan rather than depending on a successful inter-player route audit.

For other failures, the generator finishes a terrain/water preview from the available grid, keeps the previous map if necessary, or creates a simple terrain with a collider if neither is available. Unsafe bridges are not placed. Inspect result.PreviewRoot to access this visible output. The preview is not a validated gameplay map: Succeeded remains false, MapRoot and Grid remain null, and no player spawns or gameplay score are returned. Fix the issue and regenerate before starting a match or saving a generation recipe.

Generation replaces only the hierarchy previously created below that generator. Keep custom gameplay objects outside the generated root, or spawn them after generation completes.

Select a biome explicitly

Assign MapDefinition.BiomeOverride when runtime code or a reusable prefab must select one exact BiomeSetting. Assign this reference explicitly; direct material and prefab fields on the definition still take final precedence. Leave it null to use only local settings. Biome enums filter Editor choices and do not load assets at runtime.

The included grass fallback library is Art/Prefabs/Grass/GrassPrefabs.asset; assign it to MapDefinition.GrassPrefabs when constructing definitions in runtime code without grass placement rules. Grass materials live in Art/Materials/Grass, and water masks in Art/Textures/Water. The Editor prepares missing grass fallback references on processed scene copies before Play Mode or Player scene processing; runtime-created definitions use the references you supply. For new runtime materials, pass texture references to StylizedGrassPresets.Apply(material, biome, bladeTexture) or StylizedWaterPresets.Apply(material, biome, forestWaveFoam, forestCaustics). Existing assigned water masks are preserved.

Generation result

ProceduralMapGenerationResult exposes:

The generator exposes the same latest value through LastGameplayScore. HasGeneratedPreview reports whether terrain or water remains visible; HasGeneratedGrid requires a successful generation. Diagnostics keep their Error severity in ValidationIssues and the Inspector even when logged as warnings to allow generation to recover without pausing the Editor.

Read gameplay cells

MapGrid.GetCell(x, y) returns null outside the map. A GridCell contains its height and semantic flags such as Walkable, Buildable, IsWater, IsMountain, IsRamp, IsMainBase, IsExpansion, IsChokePoint and resource markers.

GridCell cell = result.Grid.GetCell(x, y);

if (cell != null && cell.Walkable && !cell.IsWater)
{
    // Use the cell in your own placement or navigation layer.
}

The generator does not impose a particular pathfinding, building or unit system. This keeps the returned grid portable. The optional A* Pathfinding integration is detected only when that package is already installed.

Validate before generation

Use the same validator as the Inspector when building a custom setup screen:

foreach (MapGenerationIssue issue in
         MapGenerationValidator.Validate(generator.Definition))
{
    Debug.Log(issue.ToString());
}

Errors block generation. Warnings describe optional or visual configuration that can safely use a fallback. Validation also rejects NaN and Infinity in active numeric setting groups before they can create invalid vertices. A failed validation keeps visible preview geometry available.

Save a reproducible recipe

MapGenerationSaveData stores the definition, fixed seed and strategic positions. After a successful generation:

generator.CaptureCurrentGenerationToSerializedMap(saveData);

To apply and regenerate the recipe:

generator.ReloadSerializedMap(saveData);

The save data stores a recipe rather than duplicating generated meshes. Keep the source image, palette, biome, materials and prefabs referenced by the definition available when reloading.

Included runtime example

UPM installations expose Runtime Generation Example in Package Manager's Samples section. The classic Asset Store package contains the same editable script under Examples/Runtime Generation.