2026-09-07 18:57:38 +02:00
2026-09-05 23:19:46 +02:00
2026-09-05 23:19:46 +02:00
2026-09-07 18:57:38 +02:00
2026-09-07 18:07:53 +02:00
2026-09-05 23:19:46 +02:00
2026-09-07 18:39:02 +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%