team3 f97d741c91 Spielstart zuverlaessig machen, Client wieder scharf rendern
Der Client steckte die Partie in einen SubViewport. Der rendert mit der
Basisaufloesung 1280x720 und wurde danach hochskaliert - das Bild wurde
matschig und die Kantenglaettung fiel weg. Den eigenen Physikraum braucht
aber nur der Server, weil dort viele Partien nebeneinander laufen. Also
bekommt nur er SubViewports; der Client haengt die Partie direkt in die
Szene. Die Knotennamen bleiben gleich, daran haengt das RPC-Ziel.

Der Healthcheck oeffnete alle 30 Sekunden eine nackte TCP-Verbindung auf
den WebSocket-Port. Der Server lehnte sie ab ("Missing or invalid header
'upgrade'"), und dabei ging reproduzierbar ein Paket an einen echten
Spieler verloren. Traefik braucht den Check nicht, also raus damit.

Blieb ein seltener Verlust des Startpakets: der Spieler sass in der Lobby,
waehrend die anderen spielten. Der Server legt jetzt nach, bis jeder den
Start quittiert hat.

Ein Verbindungsabbruch im Menue lud ausserdem die Szene neu und warf die
Meldung dazu gleich wieder weg.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 22:43:02 +02:00
2026-09-05 23:19:46 +02:00
2026-09-05 23:19:46 +02:00
2026-09-07 18:07:53 +02:00
2026-09-05 23:19:46 +02:00
2026-09-07 18:07:53 +02:00
2026-09-07 18:39:02 +02:00
2026-09-05 23:19:46 +02:00
2026-09-07 18:39:02 +02:00

Liar's Dice 3D

Würfel-Bluffspiel in Godot 4.7 mit echter 3D-Physik, Mehrspieler über Raum-Codes, KI-Bots und einem Booster-System aus Buffs und Debuffs.

Starten

godot --path .          # oder das Projekt im Godot-Editor öffnen

Das Startmenü hat drei Punkte:

  • Einzelspieler – nur die Bot-Anzahl (1–7) einstellen und starten. Es wird kein Netzwerk geöffnet.
  • Mehrspieler – nur den Namen eintragen, dann Hosten oder Beitreten. Hosten führt direkt in die Lobby; dort steht der Code. Beitreten fragt zuerst nach dem Code. Niemand braucht eine IP oder eine Portfreigabe.
  • Lobby – zeigt den Code, wer schon da ist und die Bot-Anzahl. Nur der Host stellt die Bots ein und startet, sobald mindestens 2 Teilnehmer zusammen sind (Menschen und Bots zusammengezählt, maximal 8).
  • Beenden – schließt das Spiel.

Mehrspieler: wie es zusammenhängt

Die Partie läuft nicht beim Host, sondern auf dice.marha.de:

Spieler ──wss://443──> ein Serverprozess ──> Raum MQG4 (SubViewport + World3D)
                                        └──> Raum 4YPV (SubViewport + World3D)
  • Ein Prozess, ein Port. Der Server trägt alle Räume gleichzeitig und spricht WebSocket. Traefik reicht das auf 443 durch, es muss kein Port freigegeben werden.
  • Ein Raum ist ein Knoten unter /root/Main/Raeume/<CODE>. Darin ein SubViewport mit own_world_3d – nur so hat jede Partie ihren eigenen Physikraum, sonst lägen alle Würfel im selben.
  • Die Knotennamen sind auf Server und Client gleich. Daran hängt das Ziel jedes RPC, deshalb dürfen sie nicht auseinanderlaufen.
  • Broadcasts (rpc) würden alle Räume treffen. Deshalb geht alles gezielt per rpc_id an die Peers des eigenen Raums.
  • Der Server sitzt nicht mit am Tisch: local_seat bleibt −1, kein HUD.
  • Der Host ist der erste Spieler im Raum. Geht er, rückt der nächste nach. Nur er stellt die Bots ein und startet.
  • Der letzte macht das Licht aus: verlässt der letzte Spieler den Raum, wird er samt Code sofort abgeräumt.

Gemessen mit sechs gleichzeitigen Partien zu acht Plätzen: 3,7 MB je Raum, im Leerlauf unter 1 % eines Kerns, kurze Spitzen beim Würfelwurf.

Lokal entwickeln

make server         # Spielserver auf :8000, trägt alle Räume
make dev            # Spiel, zeigt auf den lokalen Server

Ohne PIRATE_DICE_SERVER zeigt das Spiel auf wss://dice.marha.de.

Auf dem Server

git pull
make prod           # baut und startet, holt Godot selbst
make logs
make down

Mehr ist nicht nötig. Der Docker-Build lädt Godot 4.7.2 herunter (Version steht im Dockerfile), importiert das Projekt einmal vor und startet den Server. restart: unless-stopped bringt ihn nach einem Neustart von selbst wieder hoch.

Es muss kein Port freigegeben werden: alles läuft als WebSocket über Traefik auf 443.

Aufbau

Datei Inhalt
scripts/net.gd Autoload: WebSocket-Verbindung, Räume, Lobby, Spielstart
scripts/boosters.gd Autoload: Booster-Katalog
scripts/game.gd Spiellogik (host-autoritativ), RPCs, Zustandsabgleich
scripts/table.gd Aufbau der 3D-Szene: Tisch, Würfelzonen, Becher, Kamera
scripts/die.gd Physik-Würfel, Ablesen der Augenzahl aus der Ruhelage
scripts/ai.gd Bot-Entscheidungen (Binomialabschätzung für Gebot/Anfechtung)
scripts/hud.gd Spiel-UI
scripts/menu.gd Startmenü und Lobby

Die gesamte Spiellogik und die Würfelphysik laufen beim Host. Clients erhalten nur ihre eigenen Würfel als Transform-Stream, gegnerische Werte erst beim Aufdecken – Mitlesen fremder Würfel ist damit nicht möglich.

Description
No description provided
Readme 1.5 MiB
Languages
GDScript 97.2%
Shell 1.6%
Makefile 0.7%
Dockerfile 0.5%