Ir al contenido

Protocolo TCP

El avatar acepta una sola conexión TCP en el puerto 4500 (override con -AvatarPort=N en la línea de comandos del juego). Una segunda conexión concurrente se rechaza — el backend debe cerrar y reconectar, no multiplexar.

Cada frame en el cable tiene la misma forma:

1 byte
Tipo
4 bytes LE
Largo payload N
N bytes
Payload
offset 0
offset 1
offset 5 → 5 + N
TipoPayloadSignificado
0PCM crudoChunk de audio (48 kHz, 16-bit signed little-endian, mono).
1JSON UTF-8Comando — emoción, microexpresión, gesto, mirada, config, listen, stop, reset.

No hay frame de acknowledgement. El backend produce, el avatar consume. La contrapresión la da el ring buffer de audio, no un handshake.

  • Sample rate: 48000 Hz, exacto. Otros rates se rechazan en la capa de lip-sync con un warning de compliance.
  • Formato: 16-bit signed little-endian.
  • Canales: 1 (mono).
  • Encoding: bytes PCM crudos — sin header WAV/MP3/Opus.

Cadencia de chunks y semántica de silencio: ver Ajustes de lip-sync.

El payload es un objeto JSON UTF-8. Ejemplos:

{ "type": "emotion", "name": "joy", "intensity": 0.8 }
{ "type": "microexpression", "name": "smirk" }
{ "type": "anim_gesture", "name": "greet" }
{ "type": "look_at", "target": "camera" }
{ "type": "config", "key": "lipsync_chunk_size", "value": 480 }
{ "type": "listen", "value": 1 }
{ "type": "stop", "target": "speaking" }
{ "type": "reset" }

Cada comando se despacha al game thread antes de leer o escribir estado de animación. El backend no necesita pensar en threading de UE — produce JSON, envía el frame, el motor se encarga del resto.

  • Audio resampleado a un formato distinto de 48 kHz mono 16-bit LE.
  • Canales multiplexados.
  • Conexiones concurrentes desde el mismo host.
  • Frames con Tipo fuera de {0, 1}. El worker TCP los descarta sin despachar.