Voice chat¶
Turning it on¶
- Experience Settings › Communication: enable the microphone (voice chat).
- VoiceChatService in the Explorer: set
UseAudioApi = Enabled. Without this, voice is an internal black box you can't wire. - Leave
EnableDefaultVoiceon for automatic proximity chat, or turn it off to build your own.
Only voice-eligible players get a microphone stream. That means age-checked or verified accounts that have voice turned on. Everyone else can still hear if their settings allow it. Use VoiceChatService:IsVoiceEnabledForUserIdAsync to tell who can speak.
What Roblox builds for you¶
With UseAudioApi = Enabled and EnableDefaultVoice = true, when a voice-eligible player joins, Roblox creates:
| Object | Parent | Default name |
|---|---|---|
AudioDeviceInput (their mic) |
the Player |
AudioDeviceInput |
AudioEmitter (their mouth) |
their Character, made again on every respawn |
AudioEmitter |
Wire mic → emitter |
||
AudioListener (your ears) |
Workspace.CurrentCamera |
The emitters use VoiceChatService.DefaultDistanceAttenuation: inverse-square, or Legacy (7–80 studs). Acoustic simulation applies to voice when it's enabled.
With EnableDefaultVoice = false, you still get the AudioDeviceInputs. You don't get the emitters or the listener. Wire mics wherever you want: a radio bus, a PA system, or nowhere (speech-to-text only).
Controls you have¶
| Want | Do | Where |
|---|---|---|
| Mute a player for everyone | AudioDeviceInput.Muted = true |
Server |
| Push-to-talk | Toggle the local player's Muted on key down and up |
Client |
| Only teammates can hear | AccessType = Allow + SetUserIdAccessList(teamUserIds) |
Server |
| Block certain people | AccessType = Deny + list |
Server |
| Change the range | emitter:SetDistanceAttenuation(curve) or a preset mode |
Server (replicates) or client (local only) |
| Make voices directional | emitter:SetAngleAttenuation({[0]=1,[90]=0.6,[180]=0.3}) |
Either |
| Process a voice (helmet, radio, robot) | Insert effects between the mic and the emitter | Server to affect everyone, client for one listener |
| See who's talking | Wire the mic to an AudioAnalyzer and poll RmsLevel |
Client |
| Voice commands | Wire the mic to AudioSpeechToText |
Client |
AudioDeviceInput.Active reflects the player's own mic button in the Roblox UI. You can read it but not set it. A player is heard only when Active is true and Muted is false.
Respect the platform
Voice still goes through Roblox's safety systems and the player's own mute and block settings. The API gives you routing and processing, never the raw audio. You can't spectrum-analyze or record a microphone. Don't build mechanics that pressure players to unmute.
Team chat (server)¶
Taken from Roblox's voice chat tutorial and trimmed:
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
local function updateTeam(team: Team)
local userIds = {}
for _, player in team:GetPlayers() do
table.insert(userIds, player.UserId)
end
for _, player in team:GetPlayers() do
local mic = player:FindFirstChild("AudioDeviceInput") :: AudioDeviceInput?
if mic then
mic.AccessType = Enum.AccessModifierType.Allow
mic:SetUserIdAccessList(userIds)
end
end
end
for _, team in Teams:GetTeams() do
team.PlayerAdded:Connect(function() updateTeam(team) end)
team.PlayerRemoved:Connect(function() updateTeam(team) end)
updateTeam(team)
end
-- The mic can arrive after the player joins.
Players.PlayerAdded:Connect(function(player)
player.ChildAdded:Connect(function(child)
if child:IsA("AudioDeviceInput") and player.Team then
updateTeam(player.Team)
end
end)
end)
Push-to-talk (client)¶
-- LocalScript (or a Script with RunContext = Client)
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local mic = Players.LocalPlayer:WaitForChild("AudioDeviceInput") :: AudioDeviceInput
local KEY = Enum.KeyCode.V
mic.Muted = true
UserInputService.InputBegan:Connect(function(input, processed)
if not processed and input.KeyCode == KEY then mic.Muted = false end
end)
UserInputService.InputEnded:Connect(function(input)
if input.KeyCode == KEY then mic.Muted = true end
end)
More voice recipes, including radios, filters and indicators, are in Recipes.