Nadie espera solo: conoce a los habituales
Abrir una sala significaba esperar solo hasta rendirse. Ahora doce habituales con nombres reales, personalidades fijas y ritmo humano ocupan los asientos vacíos.

En palabras sencillas
Hasta esta actualización, nada se unía nunca a una sala creada por ti. Elegías un modo, abrías una mesa y esperabas: casi siempre solo. Los números de las seis semanas anteriores son contundentes.
| Lo que medimos | Resultado |
|---|---|
| Salas abiertas por un jugador que nunca empezaron | 38 |
| Espera media antes de rendirse | ~3,2 horas |
| Una sala que se llenó 4/4 y aun así no empezó | esperó 2 días |
| Partidas terminadas con más de un humano | 46 de 231 |
Ahora la mesa se llena sola. Entre veinte segundos y cuatro minutos después de abrir la sala, alguien se sienta. Una docena de habituales rota por el vestíbulo (apodos normales, nada de RoboBaron) y cada uno es el mismo jugador cada vez que te lo encuentras:
- una personalidad fija: el mismo rival siempre juega con cautela, o siempre puja de más;
- una fecha de registro y un nivel de experiencia que no se inventaron esta mañana;
- un ritmo propio: tardan entre uno y seis segundos en pensar, no dos exactos como un metrónomo;
- alguna frase corta en el chat en lugar de un sticker;
- sin etiqueta de "bot" en la sala de espera, porque en la mesa se comportan como jugadores.
También aparecen en la clasificación, que es lo honesto si van a jugar partidas de verdad, pero con un techo diario estricto sobre lo que pueden ganar: suben como un jugador normal, no farmeando la tabla.
Para los más técnicos
Los doce personajes se aprovisionan de forma idempotente al arrancar el servidor de juego y se marcan con un valor que la tabla de perfiles ya admitía, así que toda la función salió sin ninguna migración de base de datos y sin tocar ninguna regla del juego.
El relleno es un tick del planificador, no un temporizador por sala. Cada retardo se deriva de un aleatorio con semilla en la sala y el asiento, y se ancla a una marca de tiempo guardada en la base de datos, de modo que un reinicio retoma exactamente el mismo calendario en lugar de sortear retardos nuevos:
// scheduler.ts — seeded per (room, seat), anchored on a DB timestamp
const rng = createRng(`${game.id}:fill:${seat}`);
const isLastSeat = freeSeats === 1;
const delayMs = isLastSeat
? rng.int(LAST_SEAT_MIN_MS, LAST_SEAT_MAX_MS) // 3-8 min: leave room for a human
: rng.int(SEAT_MIN_MS, SEAT_MAX_MS); // 20 s - 4 min
if (Date.now() - Date.parse(game.created_at) < delayMs) continue;| Parámetro | Valor |
|---|---|
| Retardo para ocupar un asiento | 20 s – 4 min, con semilla por asiento |
| Último asiento | 3 – 8 min |
| Inicio automático con la mesa llena y en silencio | 3 min |
| Tiempo de reflexión del bot | 1 – 6 s, escalado por personaje |
| XP de los personajes | como mucho un premio por día UTC |
Tres defectos solo aparecieron con el sistema en marcha, y ninguna prueba unitaria habría cazado ninguno: las salas llenas quedaban fuera de la consulta de candidatas del relleno, así que el inicio automático nunca veía justo el caso para el que existe; la espera de reflexión estaba indexada por partida y no por bot, de modo que una pausa en un turno también bloqueaba la puja de ese mismo bot hasta que se le pasaba automáticamente su ventana; y una partida iniciada por el servidor no despertaba a los planificadores de su modo inactivo, lo que dejaba 11,6 segundos entre el inicio y la primera tirada de un bot en lugar de 49 milisegundos.
