Por qué Dish se siente como un cable.
La latencia es la única métrica que importa en un mando. Dish se construyó alrededor de ella desde el día uno.
El presupuesto de latencia
Un mando Xbox con cable hace polling a 250 Hz en Windows. Eso significa que tu juego puede leer una pulsación hasta 4 ms después de que ocurra, solo por la frecuencia de sondeo. Pon un frame de 60 fps encima y el peor caso dedo-a-píxel en un mando con cable queda en torno a 20 ms.
Dish se construyó para añadir casi nada a ese presupuesto en una LAN Wi-Fi 6 normal. Aquí está a dónde se va cada milisegundo:
| Etapa | Tiempo típico |
|---|---|
| El evento de toque / botón emerge en el SO | < 1 ms |
| Dish construye + cifra un paquete de 12 bytes | < 0.1 ms |
| Envío UDP + airtime Wi-Fi + recepción UDP | 1–4 ms (5 GHz) |
| Satellite verifica + inyecta vía ViGEmBus | < 0.5 ms |
| El juego sondea el nuevo estado del mando | 0–4 ms (depende del juego) |
| Frame renderizado al monitor | 0–16 ms (depende de los fps) |
| Extremo a extremo (típico) | ~6–25 ms |
Como referencia, los mandos Bluetooth suelen añadir de 8 a 15 ms encima de sus hermanos con cable. El peor caso de Dish en una LAN sana es aproximadamente el mejor caso de un mando Bluetooth.
Cómo lo mantenemos ajustado
- Sin cola, sin runtime asíncrono. El manejador del evento de entrada llama a
sendtoen línea. Sin cola productor/consumidor, sin salto de event loop, sin Combine, sin corrutina Kotlin. El hilo de entrada es el hilo de red. - UDP puro. Ni TCP, ni WebSockets, ni gRPC, ni QUIC, ni siquiera
NWConnectionen plataformas Apple. Sockets POSIX puros para poder configurarIP_TOSnosotros mismos. - Marcado DSCP EF. Los paquetes salientes se etiquetan con la clase DSCP EF (0xB8). Los routers y puntos de acceso con QoS los adelantan al tráfico masivo.
- Paquetes diminutos. 12 bytes de payload, unos 50 bytes en el cable una vez que entran las cabeceras UDP, IP y 802.11. Un frame Wi-Fi.
- Cero asignaciones en el hot path. Los buffers están en pila o preasignados. Ninguna pausa del GC puede estirar un envío de paquete.
- Inyección directa al kernel. Satellite llama a
DeviceIoControldirectamente a ViGEmBus. Sin marshalling de DLL, sin IPC, sin viaje de ida y vuelta a un servicio. El hot path del receptor son tres syscalls con cero asignaciones:recvfrom()→memcpy()→DeviceIoControl(). - Hilo de recepción crítico en tiempo. Satellite fija su hilo de recepción UDP a
THREAD_PRIORITY_TIME_CRITICALen Windows y a afinidad al core 0, así una pestaña de navegador desbocada no puede ahogar tus entradas.
Qué se come la latencia en la práctica
Cada informe "Dish se siente con lag" que hemos visto se rastrea a uno de estos. Ninguno es culpa de Dish, todos tienen solución:
- Wi-Fi de 2.4 GHz. Interferencia de microondas, congestión de vecinos, techo de ancho de banda más bajo. Solución: pon tu teléfono y tu PC gaming en 5 GHz o 6 GHz.
- Wi-Fi power-save en Android. Algunos teléfonos Android retrasan los paquetes salientes entre 30 y 100 ms cuando la pantalla está quieta. Dish mantiene un latido cada 2 segundos: lo bastante pequeño para ser gratis en la radio, lo bastante frecuente para evitar que el SO duerma el chip Wi-Fi.
- Repetidores mesh. Cada salto añade de 1 a 3 ms. Pon Satellite en un nodo cableado al router principal si puedes.
- Dock USB-C con Ethernet sobre un hub Thunderbolt. Algunos docks baratos hacen buffering. Usa el Wi-Fi integrado del portátil o un adaptador passthrough.
- 120 Hz vs 60 Hz. Un monitor a 120 Hz parte por la mitad la peor porción de frame time del presupuesto. 8 ms gratis.
¿Quieres medirlo tú mismo?
La UI web de Satellite en localhost:9877 muestra RTT en vivo por conexión, los últimos microsegundos de bucle, los microsegundos pico de bucle, contadores de éxito y fallo de envío y conteos de descarte por repetición. La página /debug es la lectura completa de rendimiento del receptor. Si ves algo por encima de 10 ms de RTT en la misma Wi-Fi, algo más en tu red está actuando. Abre una incidencia con una captura de la página debug y te ayudaremos a indagar.