Niemand wartet allein: die Stammgäste
Einen Raum zu eröffnen hieß früher, allein zu warten, bis man aufgab. Jetzt füllen zwölf Stammgäste mit echten Namen, festen Persönlichkeiten und menschlichem Tempo die leeren Plätze.

Kurz gesagt
Bis zu diesem Update trat nie jemand einem Raum bei, den du erstellt hattest. Du hast einen Modus gewählt, einen Tisch eröffnet und gewartet – und meistens hast du allein gewartet. Die Zahlen aus den sechs Wochen davor sind unmissverständlich:
| Was wir gemessen haben | Ergebnis |
|---|---|
| Von Spielern eröffnete Räume, die nie starteten | 38 |
| Durchschnittliche Wartezeit bis zum Aufgeben | ~3,2 Stunden |
| Ein Raum, der 4/4 voll war und trotzdem nie startete | wartete 2 Tage |
| Beendete Partien mit mehr als einem Menschen | 46 von 231 |
Jetzt füllt sich der Tisch von selbst. Irgendwann zwischen zwanzig Sekunden und vier Minuten nach dem Eröffnen deines Raums setzt sich jemand dazu. Ein Dutzend Stammgäste rotiert durch die Lobby – gewöhnliche Spitznamen, kein RoboBaron –, und jeder von ihnen ist jedes Mal derselbe Spieler, wenn du ihm begegnest:
- eine feste Persönlichkeit: derselbe Gegner spielt immer vorsichtig oder bietet immer zu hoch;
- ein Beitrittsdatum und ein Erfahrungsstand, die nicht heute Morgen erfunden wurden;
- ein eigenes Tempo – sie brauchen zwischen einer und sechs Sekunden zum Nachdenken, nicht metronomische zwei;
- gelegentlich eine kurze Zeile im Chat statt eines Stickers;
- kein „Bot“-Abzeichen im Warteraum, weil sie sich am Tisch wie Spieler verhalten.
Sie tauchen auch in der Bestenliste auf, was die ehrliche Lösung ist, wenn sie schon echte Partien spielen – aber mit einer harten Tagesobergrenze für das, was sie verdienen können, sodass sie wie ein normaler Spieler aufsteigen, statt die Liste abzugrasen.
Für technisch Neugierige
Die zwölf Stammgäste werden beim Start des Spiel-Daemons idempotent angelegt und mit einem Wert markiert, den die Profiltabelle bereits unterstützte – das ganze Feature kam also ohne Datenbank-Migration und ohne Änderung an irgendeiner Spielregel an Land.
Der Auffüller ist ein Scheduler-Tick, kein Timer pro Raum. Jede Verzögerung wird aus einem gesetzten Zufallswert abgeleitet, der auf Raum und Platz beruht, und an einem Zeitstempel verankert, der in der Datenbank liegt – ein Neustart des Daemons nimmt also exakt denselben Plan wieder auf, statt für bereits eingeplante Räume neue Verzögerungen zu würfeln:
// 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;| Stellschraube | Wert |
|---|---|
| Verzögerung beim Auffüllen eines Platzes | 20 s – 4 min, gesetzt pro Platz |
| Letzter Platz | 3 – 8 min |
| Automatischer Start, sobald voll und still | 3 min |
| Bedenkzeit der Bots | 1 – 6 s, je nach Stammgast skaliert |
| XP der Stammgäste | höchstens eine Vergabe pro UTC-Tag |
Drei Fehler zeigten sich erst, als das Ganze tatsächlich lief, und kein Unit-Test hätte einen davon gefunden: Volle Räume waren aus der Kandidatenabfrage des Auffüllers ausgeschlossen, sodass der automatische Start genau den Fall nie sah, für den er existiert; die Sperre für die Bedenkzeit war pro Partie statt pro Bot gesetzt, sodass eine Pause in einem Zug auch das Auktionsgebot desselben Bots blockierte, bis er aus seinem eigenen Zeitfenster automatisch herausgepasst wurde; und eine vom Daemon gestartete Partie weckte die Scheduler nie aus ihrer Leerlauf-Verzögerung, was zwischen Start und erstem Bot-Wurf 11,6 Sekunden statt 49 Millisekunden legte.
