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:
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
SpecialsTelemetryProviderusing 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.
Recommended Scales
Keep telemetry values normalized between 0 and 1. This keeps thresholds predictable across different rule sets:
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 dataAny call to SetTelemetryProvider() overrides the inspector field until the next scene load or reinitialization.
Summary
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