examples/MusicCatalogFeaturesExample.cs

Example helper class that creates a MusicRuntime for a participant and exposes convenience methods to play events, stop tracks, start a rhythm with a queued accent, and play a death cue. It builds MusicDecisionBatch objects, assigns incremental decision ids, and calls MusicRuntime.Apply or SetLifecycle.

using SboxDirector;

namespace AdaptiveDirectorExamples;

/// <summary>Small direct runtime demo for priority, ducking, blocking, timing tags, and after-death cues.</summary>
public sealed class MusicCatalogFeaturesExample
{
    readonly MusicRuntime _runtime;
    long _decisionId = 1;

    public MusicCatalogFeaturesExample(string participantId) { _runtime = new MusicRuntime(participantId, ExampleMusicSetup.CreateCatalog()); ParticipantId = participantId; }
    public string ParticipantId { get; }

    public MusicRuntimeBatch Play(string eventId, double time)
    {
        var decisions = new MusicDecisionBatch { Time = time };
        decisions.Decisions.Add(new MusicDecision(_decisionId++, MusicDecisionKind.Play, ParticipantId, eventId, "example"));
        return _runtime.Apply(decisions);
    }

    public MusicRuntimeBatch StopTrack(string trackId, float fadeSeconds, double time)
    {
        var decisions = new MusicDecisionBatch { Time = time };
        decisions.Decisions.Add(new MusicDecision(_decisionId++, MusicDecisionKind.StopTrack, ParticipantId, trackId, "example") { FadeSeconds = fadeSeconds });
        return _runtime.Apply(decisions);
    }

    public MusicRuntimeBatch StartRhythmAndQueueAccent(double time)
    {
        var first = new MusicDecision(_decisionId++, MusicDecisionKind.Play, ParticipantId, "game.rhythm.master", "start master");
        var accent = new MusicDecision(_decisionId++, MusicDecisionKind.Play, ParticipantId, "game.rhythm.accent", "sync to tag 2");
        var decisions = new MusicDecisionBatch { Time = time }; decisions.Decisions.Add(first); decisions.Decisions.Add(accent);
        return _runtime.Apply(decisions); // The accent is deferred to the master's four-second tag plus 0.25 seconds.
    }

    public MusicRuntimeBatch PlayDeathCue(double time)
    {
        _runtime.SetLifecycle(participantDead: true, scenarioEnded: false);
        return Play("game.player.death", time); // Allowed because this event has AllowAfterDeath.
    }
}