M2.1: dedicated server, joining, identity handshake, names, lobby
- Net autoload: headless dedicated server (--server) on UDP 24242 via ENet, server.json preferences (flags override per run, never saved), reserved names in names.json - Identity: RSA-2048 key per install (Godot has no Ed25519), player id = key hash, challenge/response so ids can't be faked; profile with name and limited appearance (tunic, hair, beard) - Server refuses bans, allowlist misses, duplicate logins, bad or taken names, wrong passwords, old protocol versions and a full server, each with a clear reason; first player on a new server becomes admin - Title screen: Profile, Join Game, and a lobby with server info, rules and who's online - test_net_lobby: real headless server + bot processes over UDP (38 checks); --exit-with so test servers never outlive the test
This commit is contained in:
@@ -17,6 +17,13 @@ concrete decisions for this codebase, as it stands after M1.
|
||||
- **Co-op or adversarial**, chosen by server rules (§5).
|
||||
|
||||
## 2. Running a server
|
||||
*Built in M2.1* (`scripts/net/net.gd`, `server_config.gd`, `identity.gd`).
|
||||
As of M2.1 the server accepts players, checks who they are and keeps the
|
||||
player list. The world itself isn't served yet (M2.3). Flags: `--server`,
|
||||
`--port`, `--config`, `--server-name`, `--max-players`, `--password`,
|
||||
`--world`, and `--exit-with <pid>` (quit when that process exits; the tests
|
||||
use it so a crashed test never leaves a server running). Flags apply to
|
||||
that run only and are never written to `server.json`.
|
||||
```bash
|
||||
# Dedicated server (no window, no player)
|
||||
godot --headless --path . -- --server --config server.json
|
||||
@@ -42,7 +49,9 @@ godot --headless --path . -- --server --world "Valley of Us" --port 24242
|
||||
|
||||
## 3. Players: identity and names
|
||||
- **Identity:** on first run each game install generates a private key
|
||||
(Ed25519) and keeps it in `user://identity.key`. The public key's hash is
|
||||
(RSA-2048, since Godot's Crypto has no Ed25519) and keeps it in
|
||||
`user://identity/key.pem`, with the name and appearance in
|
||||
`user://identity/profile.json`. The public key's hash is
|
||||
the **player id**. On joining, the client signs a server-chosen challenge,
|
||||
so nobody can claim someone else's id. No passwords and no central
|
||||
accounts.
|
||||
@@ -199,7 +208,7 @@ player" or "this player":
|
||||
| Phase | Delivers | Done when |
|
||||
|---|---|---|
|
||||
| **M2.0** | worldlet W0 (terrain from data, no visible change), recommended first | seed 1337 generates the same height grid as today; all suites pass |
|
||||
| **M2.1** | network skeleton: `--server`, ENet on 24242, Join screen (address, name), handshake with identity and challenge, name rules, player list | two clients and a headless server on one Mac connect, see the player list, and disconnect cleanly |
|
||||
| **M2.1** *(done)* | network skeleton: `--server`, ENet on 24242, Join screen (address, name), handshake with identity and challenge, name rules, player list | two clients and a headless server on one Mac connect, see the player list, and disconnect cleanly |
|
||||
| **M2.2** | player bodies and name tags; predicted movement, interpolation for others | two players walk around together at 100 ms simulated latency without visible rubber-banding |
|
||||
| **M2.3** | world state replicated: resource nodes, pickups, pieces, chests, fires, doors, clock, weather | one chops a tree and the other sees it fall; one builds a wall and the other walks into it |
|
||||
| **M2.4** | intents as RPCs; per-player inventory, stats, diet, death and graves; per-player saves and migration | two players craft, eat, die and loot their own graves; an old single-player save loads |
|
||||
|
||||
@@ -44,7 +44,7 @@ Detailed plan in `docs/MULTIPLAYER_PLAN.md` (hosting on UDP 24242 via Tailscale
|
||||
or port forwarding, player identity and names, server rules for co-op/PvP, and
|
||||
phases M2.0-M2.7).
|
||||
- [ ] Refactor state to server-authoritative (single-player becomes loopback server)
|
||||
- [ ] Headless dedicated server mode (`--headless -- --server`)
|
||||
- [x] Headless dedicated server, joining, identity handshake, names, player list *(M2.1)*
|
||||
- [ ] ENet transport, client prediction for local movement, interpolation for others
|
||||
- [ ] Replicate resource nodes, inventory, building, health
|
||||
- [ ] Persistence: world save/load on the server
|
||||
|
||||
@@ -36,6 +36,8 @@ godot --headless --path . --script res://tests/test_terrain_edges.gd
|
||||
godot --headless --path . --script res://tests/test_survival_core.gd
|
||||
# Save/load round trip + world slots (uses user://test_worlds, not your saves)
|
||||
godot --headless --path . --script res://tests/test_save_load.gd
|
||||
# Multiplayer lobby: a real headless server on UDP 24343 + scripted bot players
|
||||
godot --headless --path . --script res://tests/test_net_lobby.gd
|
||||
# Survival stats: hunger, warmth, fire fuel, cooking, foraging, death + grave
|
||||
godot --headless --path . --script res://tests/test_survival_stats.gd
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user