Spawn Hints

Optional Spawn Hints - can be used by all spawner types

The Spawn Hints System provides authored control over where units appear during runtime. Instead of relying entirely on procedural sampling, designers can place EnemySpawnHintPoint markers to bias or constrain spawn placement.

When enabled, the spawner will first attempt to use valid hint points near the spawn request location. If no hints qualify, it can either fall back to normal sampling or skip the spawn entirely depending on your configuration.


1. Enabling Spawn Hints

  1. Select your RuntimeSpawner in the scene.

  2. Enable Use Spawn Hints in the inspector.

  3. Create and assign a Spawn Hint Settings asset:

    Create → Runtime Spawner → Spawn Hint Settings
  4. Place SpawnHintPoint components throughout your level:

    GameObject → Runtime Spawner → Create Enemy Spawn Hint

Tip: If you want strictly authored placement, enable Hint-Only in the settings to disable fallback sampling entirely.


2. How It Works

For each spawn request (Global, Region, or Wave):

  1. Build a search circle:

    • Global: Radius = Cull Distance × Global Search Fraction

    • Region: Region bounds + Region Search Padding

    • Wave: Wave anchor range + Wave Search Padding

  2. Filter by tags: If a WaveSpawnPoint has Anchor Tags, hints with matching tags are preferred first.

  3. Evaluate candidates (up to Max Hint Attempts):

    • Check distance to player against hint MinPlayerDist / MaxPlayerDist.

      • If Ignore Spawner’s Global Min Range is OFF, the spawner’s global minimum range is also enforced.

    • If Deny Line Of Sight is true, reject hints visible to the player (uses LOS Block Mask).

    • If Require NavMesh is true, project the position to the NavMesh (respecting the hint’s override area mask or the spawner’s default).

    • When a hint passes all checks, it’s soft-reserved for Reservation Seconds to avoid overlapping bursts.

  4. No hint qualifies:

    • Hint-Only OFF → Fall back to standard procedural sampling.

    • Hint-Only ON → Skip the spawn entirely.


3. Key Settings (Spawn Hint Settings Asset)

Setting
Description

Hint-Only (no fallback)

Only spawn on hints; skip spawns if none qualify.

Ignore Spawner’s Global Min Range

Allows near-player hints even when the spawner’s Minimum Spawn Range is large.

Global Search Fraction / Region & Wave Padding

How far the system searches for hints per mode.

NavMesh Sample Max Dist

Maximum projection distance when Require NavMesh is true.

LOS Block Mask

Layers used for Line-of-Sight checks (camera visibility).

Reservation Seconds

Cooldown before a used hint becomes available again.

Max Hint Attempts

Cap on how many hints are evaluated per query.

Prefer Scoped First

Prefer hints inside the immediate scope (wave/region) before global search.

Debug Logs

Enable for detailed reasoning about candidate rejection (distance, LOS, reservation, etc.).


4. Authoring Tips

  • Place 2–5 hints per tile or encounter pocket (flanks, corners, behind cover).

  • Use Deny Line Of Sight to prevent pop-in near the player’s view direction.

  • Adjust Min/Max Player Distance per hint to control when it becomes eligible.

  • For grounded AI or uneven terrain, enable Require NavMesh on the hint.

  • Keep the cellSize in settings modest (e.g., 4–8) for efficient spatial queries.


5. Example Workflow

  1. Create a Spawn Hint Settings asset and assign it to your Runtime Spawner.

  2. Place several EnemySpawnHintPoint components around likely encounter spots.

  3. Adjust hint distances and line-of-sight options.

  4. Toggle Debug Logs while testing to visualize hint use and rejection reasons.

  5. In Play Mode, validate that enemies appear at expected authored locations.

  6. If spawns are too sparse, lower Reservation Seconds or increase Global Search Fraction.


6. Troubleshooting

“Nothing spawns with Hint-Only”

  • Hints may be inside the spawner’s Minimum Spawn Range.

    • Enable Ignore Spawner’s Global Min Range, or lower the spawner’s min distance.

  • Player may be too far (outside hint’s MaxPlayerDist).

  • NavMesh projection failed — increase NavMesh Sample Max Dist or relax the area mask.

  • For waves, ensure at least one hint shares the wave’s Anchor Tags (or clear the tags to accept any).

“Hints are ignored even when close”

  • Search radius too small — adjust padding or global fraction.

  • Hint may still be reserved — wait out the Reservation Seconds or increase available hints.

  • Enable Debug Logs in settings to see exact rejection causes (distance, LOS, reservation, NavMesh).

“Spawner warns about all hints being ineligible”

  • This happens when the Minimum Spawn Range exceeds all hint distances.

    • Enable Ignore Spawner’s Global Min Range in settings to fix it.


7. Debug Visualization

When Debug Logs are active:

  • Each tested hint draws a color-coded gizmo:

    • Green = valid and selected

    • Yellow = reserved

    • Red = rejected (LOS, distance, NavMesh)

  • Console logs show detailed reasoning for candidate failures and fallback decisions.


8. Best-Practice Patterns

Goal
Recommended Setup

Fully curated encounters

Enable Hint-Only, place hints manually, tune distances.

Semi-authored procedural mix

Use Prefer Scoped First with fallback enabled.

Fast waves / horde gameplay

Lower Reservation Seconds, increase Max Hint Attempts.

Dynamic or large maps

Adjust Global Search Fraction to cover broader areas.


✅ Summary

Spawn Hints give you granular control over where the Runtime Spawner places enemies, balancing authored intent with runtime flexibility.

By combining hint tagging, distance/LOS checks, and per-hint NavMesh validation, you can design encounters that feel deliberate, performant, and adaptable across multiple game modes.

Recommended setup:

  • Use hints for high-impact encounters (ambushes, flanks, scripted reveals).

  • Keep procedural fallback enabled for background or ambient spawns.


Fundamentals

SpawnHintPoint is a lightweight authoring component that marks good spawn locations in the scene. These hints are used at runtime by the spawn locator (ISpawnLocator / SpawnLocator) when Spawn Hints are enabled in RuntimeSpawner.

Hints:

  • Are placed directly in the level (tiles, rooms, corridors).

  • Encode simple rules about player distance, line of sight, and NavMesh.

  • Can be tagged so waves or specials can request specific types of positions (“Flank”, “Ambush”, etc.).

When a SpawnHintPoint is enabled, it automatically registers with SpawnHintRegistry. When disabled, it unregisters.


Typical Usage

  1. Place SpawnHintPoint components in areas that work well for combat:

    • Corners, flanks, behind cover, balcony edges, etc.

  2. Adjust:

    • minPlayerDist and maxPlayerDist to avoid spawns too close/too far from the player.

    • denyLineOfSight to prevent obvious pop-in directly in front of the player.

  3. Optionally:

    • Enable requireNavMesh so hints are validated against the NavMesh.

    • Set tags and have your waves/specials request those tags via their spawn context (SpawnContext.HintTags).

The RuntimeSpawner config controls whether spawn hints are used at all:

spawner.UseSpawnHints = true;
spawner.HintSettings  = yourSpawnHintSettings;

Once enabled, the locator will query SpawnHintRegistry and prefer hint positions over purely random sampling.


Fields and Rules

Visual Radius & Weight

[Min(0.1f)]
public float radius = 2f;

[Min(0f)]
public float weight = 1f;
  • radius

    • Visual radius for the hint.

    • May also be treated as a local sampling radius if your game chooses to jitter positions around the hint.

  • weight

    • Optional weighting value for custom selection strategies.

    • The built-in SpawnLocator does not use this by default, but it can be read by custom systems if needed.


Player Distance Rules

[Header("Rules")]
[Min(0f)]
public float minPlayerDist = 12f;

[Min(0f)]
public float maxPlayerDist = 0f;  // 0 = no upper limit
  • minPlayerDist Minimum allowed distance between the player and this hint for it to be considered eligible.

  • maxPlayerDist Maximum allowed distance:

    • 0 means “no upper limit”.

    • Any value > 0 will be treated as a hard maximum.

Hints outside the [minPlayerDist, maxPlayerDist] range for the current player position are ignored.


Line of Sight & NavMesh

[Tooltip("If true, reject if player has clear line of sight to the spawn point.")]
public bool denyLineOfSight = true;

[Tooltip("Require NavMesh within this hint's radius.")]
public bool requireNavMesh = true;
  • denyLineOfSight

    • If true, this hint is rejected when the player has a clear line of sight to it.

    • LOS checks use SpawnHintSettings.losBlockMask.

  • requireNavMesh

    • If true, the hint is only accepted if a valid NavMesh position can be found near it.

    • Sampling distance and area mask are controlled by SpawnHintSettings.navSampleMaxDist and the hint’s overrideAreaMask (if set).

These rules are evaluated by the locator when it filters potential hints.


Tags and NavMesh Area Overrides

[Tooltip("Restrict to these tags if the spawn request asks for them.")]
public string[] tags;

[Tooltip("Optional: prefer specific NavMesh areas for this hint (0 = use spawner's mask).")]
public int overrideAreaMask = 0;
  • tags Optional semantic tags (e.g., "Flank", "Ambush", "Backline"). When a spawn request includes HintTags in its SpawnContext, the locator:

    • First searches for hints whose tags share at least one entry with the request.

    • If none are found, it falls back to any eligible hint.

  • overrideAreaMask Optional NavMesh area mask override:

    • 0 means “use the global area mask from the spawner/locator”.

    • A non-zero value can constrain this hint to specific NavMesh areas (e.g., only walkable, only cover areas, etc.).


Registration Lifecycle

private void OnEnable()  => SpawnHintRegistry.Register(this);
private void OnDisable() => SpawnHintRegistry.Unregister(this);
  • OnEnable Registers this hint with the global SpawnHintRegistry.

  • OnDisable Unregisters this hint and clears any reservations.

Hints are therefore only considered for placement while their component is enabled.


Example Workflows

1. Basic hint layout on a combat tile

  • Place 4–6 SpawnHintPoint objects around a combat arena:

    • Two behind cover (tags = ["Flank"], denyLineOfSight = true).

    • One or two at long range (minPlayerDist = 18, maxPlayerDist = 30).

    • A couple of mid-range hints (minPlayerDist = 12, maxPlayerDist = 24).

At runtime, with spawn hints enabled in RuntimeSpawner, ambient or wave spawns will naturally gravitate to these positions instead of appearing in awkward spots.


2. Using tags from a wave or special

When building a SpawnContext for a wave or special, you can provide hint tags:

var ctx = spawner.BuildWaveContext(trigger, point, range, groupParent);
ctx.HintTags = new[] { "Flank", "Ambush" };

The locator will then:

  • Prefer hints whose SpawnHintPoint.tags contains "Flank" or "Ambush".

  • Apply distance, LOS and NavMesh checks to those candidates.

  • Only fall back to generic hints if no tagged candidates are valid.

This allows different encounter types to express “where” they want to appear without hand-picking positions in code.

Last updated