Pepper.SFX
All Guidance pages

Guidance / API reference

Netcode (Multiplayer)

Namespace: AudioSystem.Netcode Assemblies: SFXSystem.Netcode (core, references Runtime only) · SFXSystem.Netcode.Ngo / .FishNet (adapters, auto-gated on their package)

Backend-agnostic networked audio. See the User Guide → Multiplayer (Netcode) for concepts, setup, and the mental model. No audio crosses the wire — only a ~36-byte descriptor.

NetworkedAudioManager

The static gameplay façade.

Method Description
AudioHandle PostNetworkedEvent(string eventName, Vector3 position, GameObject emitter = null, bool? independentVariation = null) One-shot: plays locally now (echo) + relays to other peers. Returns the local handle. emitter attaches it to a moving networked object (null = static). independentVariation: null = the event’s authored default; true/false = override. Warns + plays local-only if the event has no stable ID.
AudioHandle PostNetworkedEvent(int stableId, …) Same, by stable ID.
NetworkedSoundHandle PostNetworkedLoop(string eventName, Vector3 position, GameObject emitter = null, bool? independentVariation = null) Starts a shared persistent (loop) sound tracked for stop, culling + late-join (phase per the event’s Loop Sync Tier). Returns a handle carrying the shared instance ID + the local echo. On a dedicated server, warns and redirects to PostServerLoop.
void StopNetworked(NetworkedSoundHandle handle) Stops the local echo now and broadcasts the stop (scope All for server-authored, else Others). Safe on a null / pure-local handle.
AudioHandle PostServerEvent(string / int, …) Server-authored one-shot to everyone (scope All), no local echo. Warns + no-ops on a client. Off-session → plain local play.
NetworkedSoundHandle PostServerLoop(string eventName, …) Server-authored loop to everyone; handle’s Local is null, ServerAuthored is true. Tracked for late-join.
AudioHandle PostNetworkedScheduled(string / int, Vector3 position, double networkTime, …) Fire at a shared network time; returns the scheduled local echo. Warns if the event name/id is unknown.
void PostServerScheduled(string / int, …, double networkTime, …) Server-authored scheduled one-shot (scope All).
AudioHandle PostNetworkedQuantized(string, Vector3, Quantize, …) Schedule on the next beat/bar of the shared musical grid. Requires a transport (SetTempo); warns + returns null otherwise.
void PostServerQuantized(string, Vector3, Quantize, …) Server-authored quantized cue.
void ResyncClock() Force the network clock to hard-re-sample its offset next tick.

NetworkedSoundHandle

Member Description
ulong InstanceId Shared cross-client identity, `(ownerClientId << 32
AudioHandle Local The instigator’s local-echo handle. Null off-session and for server-authored / Tier-2 loops.
bool IsValid True when InstanceId != 0.
bool ServerAuthored True for PostServerLoop — selects the stop scope (All).

NetworkMusicTransport & NetworkClock

NetworkMusicTransport (static) — shared tempo/phase:

Member Description
void SetTempo(double bpm, int beatsPerBar) Server only. Author the transport; networked on change, replayed to late joiners. A mid-session change re-anchors seamlessly at the next bar.
bool IsSet · double Bpm · int BeatsPerBar · double PhaseAnchor Current grid state (PhaseAnchor = network time of beat 0).
double NextBeatNetworkTime(double from) / NextBarNetworkTime(double from) The next grid slot ≥ from, in network time.

NetworkClock (static) — network-time ↔ local dsp:

Member Description
double NetworkTime This machine’s current network time (synced server time; local dsp off-session).
double NetworkToLocalDsp(double t) Map a network-time target to local AudioSettings.dspTime for PlayScheduled.
void ResyncClock() Force a hard re-sample of the offset.

NetworkAudioSettings

MonoBehaviour — scene config + game-supplied hooks.

Member Description
bool ProximityCulling Opt into culling. Default off.
Func<ulong, Vector3?> ListenerPositionProvider Game-supplied per-client listener position (server calls it). Null → culling inert. Assigned in code.
NetworkAudioValidator ServerValidator Server-side authority gate. Null → allow-all. Assigned in code.
float DefaultAudibleRadius · float LoopReevalSeconds Culling fallback radius + loop re-eval rate.
clock/lead tunables ClockSmoothing, ClockResyncThreshold, ScheduleLeadFloor, ScheduleLeadRttFactor.

NetworkAudioEvent & NetworkAudioScope

NetworkAudioEvent (struct) — the wire payload:

Field Description
int EventId The AudioEvent.StableId to play.
Vector3 Position World position — also the emitter fallback/anchor.
ulong EmitterNetId Optional network-object id to attach to. 0 = static.
ulong InstanceId Shared identity for a persistent/loop sound. 0 = a one-shot.
int Seed Variation seed. Non-zero forces the SAME variant on every client; 0 = independent.

Plus Pack / Unpack — the canonical 36-byte wire format (round-trip covered by NetworkAudioEventPackTests).

NetworkAudioScope (enum): Others (default — everyone but the sender) · All (server-authored) · Owner (reserved) · Proximity (reserved enum value; culling is realised on the Others/All paths as “don’t send”). Passing an unhonored scope logs a warning and relays as Others.

Per-event authoring (AudioEvent, Multiplayer foldout, shown only with a backend installed): Unreliable Delivery, Independent Variation (default), Loop Sync Tier (0/1/2; Tier 2 is experimental — see User Guide §17.4). For the INetworkAudioTransport boundary — implementing a new backend — see User Guide §17.9.

From the Pepper.SFX 3.1 guides (API_REFERENCE.md). Something wrong or unclear? Tell me.