Console
Docs/Integrate

Godot

aurix_voice GDExtension for Godot 4.3+ — native UDP/QUIC client on desktop and mobile, a GDScript client on the same API for web exports.

Install#

Unzip aurix-godot-addon-1.13.0.zip from the release into your project's addons/ (it contains addons/aurix_voice with the prebuilt GDExtension for Windows, Linux, macOS and Android plus the web client). Godot 4.3 or newer.

Connect and join#

gdscript
var voice := AurixVoiceClient.new()      # AurixWebVoiceClient in web exports — same calls and signals
add_child(voice)
voice.session_ready.connect(_on_session_ready)
voice.participant_speaking.connect(_on_speaking)
voice.request_failed.connect(func(_rid, code, msg): push_warning(code + ": " + msg))

if voice.connect_to_server(token.endpoint.ws_url, token.token) != AurixVoiceClient.RESULT_OK:
    push_error(voice.get_last_error())

func _on_session_ready(_session: Dictionary) -> void:
    voice.join_channel(token.channels[0].channel_id)   # returns the request id; capture starts automatically (auto_capture)

connect_to_server returns a result code and join_channel the request id; results arrive as signals (session_ready, channel_joined, participant_joined, participant_left, participant_speaking, recovering, recovered, disconnected).

Positional audio#

gdscript
func _physics_process(_d: float) -> void:
    voice.update_transforms(channel_id, { my_user_id: player.global_transform })   # or update_positions(channel_id, [...])

By default the client plays a server-panned mix. For Godot-side spatialisation add an AurixParticipantPlayer (an AudioStreamPlayer3D) under each remote avatar with user_id set — the player claims that participant's stream and your attenuation, buses and reverb apply.

Push-to-talk, mute, devices#

gdscript
voice.set_push_to_talk_action("ptt")      # or voice.set_muted(...) yourself
voice.set_input_gain(1.0)
voice.set_vad_threshold(0.02)
# capture: the client records from Godot's input device (AudioServer.input_device) through an AudioEffectCapture bus;
# set auto_capture = false and call push_capture() to feed PCM yourself

Exports#

  • Desktop and mobile exports use the native client: AURX over UDP (QUIC optional) with a TLS tunnel fallback; microphone permission on Android/iOS as usual.
  • Web exports use AurixWebVoiceClient on top of the Web SDK (WebTransport → WebRTC → WebSocket); the page must be served over HTTPS for microphone access, and the browser owns capture (set_input_device, enumerate_devices).

Channel patterns#

PatternChannels per playerNotes
Co-op / squadone teammute = PTT off; nothing positional
Shooter with proximitypositional (shard) + team (squad)transmit on the team channel by default, hold a key to speak locally
Open worldpositional (shard), optional whisper for direct callsroster_radius keeps the participant list small
Event / stageaudience-shaped channel, hosts with prioritythousands of listeners, a few speakers

The transmit channel is a client-side choice: join several, send to one, hear all with receive. Positional audio needs positions roughly 10 times a second; between updates the node interpolates.

Latency and quality#

Expect 30–60 ms mouth-to-ear on the same continent over QUIC, more over TURN. Opus runs at 32 kbps with DTX by default; the spending ladder may lower it to 16 kbps when your forecast exceeds the limit. Server-side noise suppression is on by default and costs nothing on the client.

Testing without a full build#

  • Two players: the rooms demo in a browser plus your build — they share a cell, so a token from your backend joins the same channel by name.
  • Mic path: an echo channel plays your own voice back through the real pipeline.
  • Network: throttle UDP on one machine and watch the transport fall back to WebRTC / WebSocket in the SDK's connection state.

Troubleshooting#

SymptomCheck
connected, no audiocapture started? channel grant speak/receive? OS microphone permission?
audio but no spatialisationpositions sent on the positional channel id, not the team channel
random drops on mobilethe SDK pauses capture in the background by design; resume on foreground
QUOTA_EXCEEDED on connectplan concurrency cap or spending ladder step 4 — see Spending limit