Creating a Custom Telemetry Provider

Once you’ve confirmed your Special Encounter rules respond correctly using the sample asset, you can connect your real gameplay data by creating your own telemetry provider.

The telemetry system is intentionally flexible - you can feed in any data source as long as it provides two values:

Metric
Description
Typical Range

Pressure

How intense or “busy” the game currently feels.

0–1 (normalized)

Average Player HP

The team’s mean health percentage.

0–1 (normalized)

There are two main ways to implement a provider:

an Inspector-based ScriptableObject (plug-and-play) or a runtime C# provider (for live data).


Option A - ScriptableObject Provider (Inspector Setup)

Use this approach when you want a configurable, reusable asset that can read or proxy values from your systems.

1. Create a subclass of SpecialsTelemetryProvider

using UnityEngine;
using MegaCrush.Spawner;

[CreateAssetMenu(menuName = "Runtime Spawner/Specials Telemetry/Game Linked")]
public sealed class GameLinkedTelemetry : SpecialsTelemetryProvider
{
    public override bool TryGetPressure(out float value)
    {
        // Example: pull from your own difficulty or director service
        value = GameServices.Difficulty.CurrentPressure01;
        return true;
    }

    public override bool TryGetAveragePlayerHP(out float value)
    {
        value = GameServices.Players.GetAverageHealth01();
        return true;
    }
}

2. Create the asset

In Unity: Create → Runtime Spawner → Specials Telemetry → Game Linked

3. Assign it to the Manager

Select your SpecialEncounterManager and drag your new asset into the Telemetry Provider field.

That’s it - your manager will now query your game’s live values automatically every evaluation cycle.


Pros

  • Editable and swappable via inspector or profiles.

  • Works with Addressables or asset-based pipelines.

  • Ideal for designers tuning different pacing profiles.

Cons

  • Slightly more setup than a code-only provider.

  • Requires script access to your global systems or singletons.


Option B - Runtime Provider (Code Injection)

If your telemetry data already lives in runtime systems (e.g., GameState, DifficultyManager, PlayerService), you can implement the lightweight ISpecialsTelemetry interface and inject it directly.

1. Implement the interface

using MegaCrush.Spawner;

public sealed class RuntimeTelemetry : ISpecialsTelemetry
{
    private readonly DifficultyManager _difficulty;
    private readonly PlayerService _players;

    public RuntimeTelemetry(DifficultyManager difficulty, PlayerService players)
    {
        _difficulty = difficulty;
        _players = players;
    }

    public bool TryGetPressure(out float value)
    {
        value = _difficulty.PressureNormalized;  // 0..1
        return true;
    }

    public bool TryGetAveragePlayerHP(out float value)
    {
        value = _players.GetAverageHealth01();
        return true;
    }
}

2. Inject it at runtime

var manager = FindAnyObjectByType<SpecialEncounterManager>();
manager.SetTelemetryProvider(new RuntimeTelemetry(difficulty, players));

You can inject it right after initializing the Runtime Spawner or during your bootstrap sequence.


Pros

  • No asset setup required.

  • Works cleanly with dependency injection and services.

  • Easy to test and mock.

Cons

  • Not visible in the inspector.

  • Requires code changes if you want to swap providers.


Keep telemetry values normalized between 0 and 1. This keeps thresholds predictable across different rule sets:

Value
Interpretation

0.0

Calm / no intensity / players near death

0.5

Normal tension / moderate health

1.0

Extreme intensity / full health

Rules like

“Spawn a miniboss when Pressure ≥ 0.8 and AvgHP ≥ 0.5” will be easier to tune when all systems use a consistent scale.


Advanced: Combining Providers

You can dynamically swap telemetry sources:

// During a cutscene or transition
manager.SetTelemetryProvider(new NullTelemetry());  // disables telemetry temporarily
// Later
manager.SetTelemetryProvider(liveTelemetry);        // re-enable live data

Any call to SetTelemetryProvider() overrides the inspector field until the next scene load or reinitialization.


Summary

Goal
Recommended Provider

Quick iteration in editor

BasicSpecialsTelemetry sample

Connect to real data (asset-based)

Subclass SpecialsTelemetryProvider

Integrate live runtime data

Implement ISpecialsTelemetry and inject at runtime

Switch dynamically

Use SetTelemetryProvider() between different providers

Tip: For most projects, start with a ScriptableObject subclass for clarity, then move to a runtime provider once your gameplay systems are stable.


In short: Custom telemetry gives your Special Encounter Manager true awareness of your game’s pacing - so your boss waves, ambushes, or rare encounters appear exactly when the tension and player condition are right.

Last updated