Event Recording
- Lossless capture — recording sits in the publish path, not as a subscriber
- JSON replay format — human-readable, diffable, version-able
- Speed multipliers — replay at 0.5x / 1x / 4x for debug repro
The type-safe priority-driven bus you already trust, plus three things you asked for: recording with replay, attribute-routed filter chains, and a live inspector window with real-time metrics. Free upgrade for everyone who already owns v1.0.
[EventFilter(typeof(...))] on the handlerv1.0 shipped the core: typed subscribe, priority, history ring buffer, an Editor monitor. v1.1 closes the three gaps people kept hitting in production.
When a state bug shows up at minute 47 of a playtest, “could you reproduce that?” is the wrong question. Recording captures the full event stream in JSON. Replay it in the editor, scrub through it, ship a regression test from it.
if treesA subscriber that should only fire for DamageEvent where amount > threshold can declare that with [EventFilter] on the method. The filter chain runs before dispatch — cheaper, more declarative, easier to audit.
The v1.0 monitor showed subscriptions. The v1.1 inspector shows everything — live metrics, per-type tails, recording controls. It is where you debug bus traffic; not a side window you check occasionally.
Recording is opt-in. When off, the publish path costs one bool check.
using AvanatroTools.EventBusPro;
// Start recording — captures every Publish from now until Stop
EventBus.Recorder.Start();
// ... your game runs, events fly ...
// Stop and save to JSON
EventRecording rec = EventBus.Recorder.Stop();
File.WriteAllText("repro.json", EventRecording.Serialize(rec));
Load a recording in the editor, hit play in the inspector window, or do it from code in a test.
// Load a recording and replay onto the live bus
var json = File.ReadAllText("repro.json");
var rec = EventRecording.Deserialize(json);
EventBus.Replayer.Replay(rec, speedMultiplier: 2.0f);
// In tests, inject a VirtualReplayClock to skip the waits:
EventBus.Replayer.Replay(rec, clock: new VirtualReplayClock());
Filter chains run before dispatch. Declarative, composable, easy to audit.
// Only fires for DamageEvent where amount > 100
[EventFilter(typeof(HighDamageFilter))]
void OnBigHit(DamageEvent e) { /* ... */ }
public class HighDamageFilter : IEventFilter<DamageEvent> {
public bool Allow(DamageEvent e) => e.amount > 100;
}
// Open the live inspector:
// Tools → Avanatro Tools → EventBus Pro → Live Inspector
ReflectionEventSerializer by default in test environments (no UnityEngine required). For shipping games, set EventBusInstance.SetInstance(new EventBusInstance(historyCapacity, new UnityJsonEventSerializer())) in your bootstrap — it’s faster and rounds-trips Unity types correctly.
| Subsystem | What you get |
|---|---|
| Recorder | EventBus.Recorder.Start / Stop, opt-in capture in publish path, JSON serializer |
| Replayer | EventBus.Replayer.Replay, IReplayClock abstraction, VirtualReplayClock for tests |
| Serializer | EventRecordingSerializer, hand-rolled writer/reader, int64 ticks-precise |
| Filter chain | IEventFilter<T>, [EventFilter] attribute, AND / OR / NOT composition |
| Live inspector | EditorWindow with metrics (events/sec, dispatch time, subscriber counts), per-type tail, recording controls |
| v1.0 carry-over | Type-safe Subscribe<T>, priority levels, ring-buffer history, StopPropagation |
Free upgrade for v1.0 buyers
If you own EventBus Pro v1.0 on the Unity Asset Store, v1.1 is a re-download. No new SKU. New buyers pay the v1.0 price; the v1.1 features are included.
View on the Unity Asset Store → (v1.1 update pending submission)