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:
Succeeded: whether a complete usable map was created.
ValidationIssues: stable issue codes, messages and warning/error severity.
MapRoot: root Transform of the editable generated hierarchy.
PreviewRoot: visible generated output on both success and failure; equals
MapRoot on success, and can contain an incomplete or retained map on failure.
IsPreviewOnly: true when the last attempt failed and the visible output is
only an error preview.
Grid: the logical MapGrid used to build meshes and gameplay metadata.
MainBaseCells, PlayerExpansionCells, ContestedExpansionCells and
ChokePointCells: strategic grid coordinates.
PlayerSpawnWorldPositions: spawn positions already converted to world
space using the configured cell size and terrain height.
GameplayScore: nullable strategic diagnostic from 0 to 100 for procedural
maps. It measures base spacing, expansion fairness, rush safety and ground
connectivity; it is not a visual-quality rating. It remains null when the
layout was not scored, such as an image import without strategic bases.
ScreenshotPath: absolute PNG path when automatic capture was enabled and
succeeded; otherwise null or empty.
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.