-
Notifications
You must be signed in to change notification settings - Fork 3
Mod Integration Gate
The Gate primitive silences or muffles a player's voice. It covers the majority of role voice behaviours: "shut this player up while X", "muffle their hearing while Y", "mute everyone while a system is active".
← Back to Mod Integration
Register a callback that, for each player each frame, returns a verdict:
PerfectCommsApi.RegisterVoiceRule("com.me.mymod", ctx =>
{
// ctx.Player : PlayerControl being evaluated
// ctx.Phase : Lobby / Tasks / Meeting / Exile
// ctx.IsLocal : is this the local player?
// ctx.IsDead : is this player dead?
if (ctx.Phase == VoicePhaseKind.Meeting && MyRoles.IsGagged(ctx.Player))
return VoiceRuleResult.Mute("Gagged"); // fully silenced, HUD shows "Gagged"
if (MyRoles.IsConfused(ctx.Player))
return VoiceRuleResult.Muffle("Confused"); // heard but low-pass filtered
return VoiceRuleResult.Pass; // no opinion - defer to other rules
});| Verdict | Effect |
|---|---|
VoiceRuleResult.Mute(reason) |
Player cannot be heard. reason shows in the HUD. |
VoiceRuleResult.Muffle(reason) |
Player is heard through a low-pass filter. |
VoiceRuleResult.Pass |
No opinion. Built-in rules and other mods decide. |
The first non-Pass verdict wins across all registered mods, so keep rules specific - return Pass whenever your role does not apply.
For "everyone is muted while this system/effect is active" (jam fields, blackout events), use a phase-scoped global gate instead of checking every player:
PerfectCommsApi.RegisterGlobalGate(
"com.me.mymod",
VoicePhaseKind.Meeting, // phase it applies in
() => MySystems.IsJamActive, // cheap predicate, checked once per phase
"Jammed"); // HUD reasonWhile the predicate returns true, all voice in that phase is muted.
-
Phase-aware. Gates only apply in the phase you check (
ctx.Phase) or the phase you registered a global gate for. The four phases areLobby,Tasks,Meeting,Exile. - Your own mic too. If a rule mutes the local player, their microphone is gated locally - they cannot transmit. This is automatic.
-
Fail-closed. If your callback throws, it is treated as
Pass. The voice frame never breaks. - Local-only. Verdicts are computed on each client from your own role state, so all clients converge - no networking.
Mute while a modifier is present:
PerfectCommsApi.RegisterVoiceRule("com.me.mymod", ctx =>
ctx.Player.GetModifier<SilencedModifier>() != null
? VoiceRuleResult.Mute("Silenced")
: VoiceRuleResult.Pass);Mute only the local player (e.g. a self-inflicted effect):
PerfectCommsApi.RegisterVoiceRule("com.me.mymod", ctx =>
ctx.IsLocal && MyState.SelfMuted
? VoiceRuleResult.Mute("Muted")
: VoiceRuleResult.Pass);Gate behind a host option (see Host Options):
PerfectCommsApi.RegisterVoiceRule("com.me.mymod", ctx =>
ctx.GetOption("MuteSilenced") && MyRoles.IsSilenced(ctx.Player)
? VoiceRuleResult.Mute("Silenced")
: VoiceRuleResult.Pass);- Channels - let players hear each other, instead of muting.
- Host Options & Tabs - make a rule host-configurable.