M2.4: the server decides online (characters, inventory, stats, death, owned graves, per-player saves); death screen with Respawn after 3 s
This commit is contained in:
@@ -6,9 +6,9 @@ concrete decisions for this codebase, as it stands after M1.
|
||||
## 1. Goals
|
||||
- **Self-hosted**, 2-8 players (up to 16 possible). No central service, no
|
||||
accounts: a world lives on whoever hosts it.
|
||||
- **Three ways to play, one code path:**
|
||||
- **Single-player**: the game runs a server inside itself and connects to
|
||||
it (loopback). It plays exactly as now.
|
||||
- **Three ways to play, the same rules (Actions):**
|
||||
- **Single-player**: no server; your game decides, exactly as now
|
||||
(decided in M2.4, §7).
|
||||
- **Host & play**: "Host game" on the title screen, and friends join you.
|
||||
- **Dedicated server**: a headless "server only" process with no local
|
||||
player. It keeps the world running (or paused) for whoever connects.
|
||||
@@ -204,12 +204,32 @@ it needs no syncing.
|
||||
the server, never on top of a player.
|
||||
- The world (fires, regrowth, the clock) pauses while nobody's on.
|
||||
|
||||
Until later phases, while online: your inventory, stats and crafting stay on
|
||||
your own game and aren't saved by the server (M2.4), so the server trusts
|
||||
what you say you're putting into the world (a wall, a chest deposit, a
|
||||
grave's contents) but decides everything taken out. Animals are off (M2.5).
|
||||
Sleeping is off (it needs the sleep rule, M2.5). Respawning ignores beds.
|
||||
The HUD says so.
|
||||
**Your character on the server** *(built in M2.4: `player_net.gd`,
|
||||
`server_player.gd`, autoload PlayerNet)*. Online the server decides;
|
||||
offline there's no server and your game decides, exactly as before.
|
||||
- Each player has a character on the server with their inventory, hotbar
|
||||
choice, cloak, inventory-screen cursor, bed and survival stats. The stats
|
||||
run there: warmth from the server's fires and buildings, rain, hunger and
|
||||
the diet. Sprinting and jumping cost stamina there too.
|
||||
- Online, every `Actions.*` intent becomes a request (`PlayerNet.ask("eat",
|
||||
[slot])`). The server runs the same Actions function on your character
|
||||
and sends back your inventory (after every request, and whenever it
|
||||
changes) and your stats (4 times a second). What your own game has in
|
||||
its bag counts for nothing: a modified game that adds walls to its bag
|
||||
can't build with them.
|
||||
- Clicks in your own bag also happen on your screen at once, so dragging
|
||||
items doesn't wait for the network. The server's copy replaces yours as
|
||||
soon as it has handled every click you sent.
|
||||
- Death happens on the server: a grave with your name on it (only you can
|
||||
open it until the M2.6 rules), then you wake at your bed if it's still
|
||||
standing, otherwise the island start.
|
||||
- Characters are saved in `worlds/<world>/players/<player id>.json`, with
|
||||
the world, so you come back where you left off.
|
||||
|
||||
Until later phases, while online: animals, hunting and fishing are off
|
||||
(M2.5), and so is sleeping (it needs the sleep rule, M2.5). The HUD says so.
|
||||
The server doesn't yet check that you're out of stamina when you sprint
|
||||
(it charges you, but doesn't stop you).
|
||||
|
||||
**Interest.** On a 320 m worldlet with 8 players, the server sends every
|
||||
entity to everyone at first. Distance-based interest is a later
|
||||
@@ -243,10 +263,18 @@ net ids, no owners yet) are written next to `server.json` within 10 s of
|
||||
any change, when a player leaves, and every `autosave_minutes`. (Ctrl+C
|
||||
kills Godot without running any code, so there's no save on the way out.) An
|
||||
existing world keeps the seed it was made with, even if `server.json`
|
||||
changes. Player files, owners and backups come in M2.4 and M2.7.
|
||||
- Single-player saves (today's `world.json` with a `"player"` block) are
|
||||
migrated on first load. That block becomes the local player's file. The
|
||||
test suite keeps an old-format save fixture to prove it.
|
||||
changes. *As of M2.4:* `players/<player id>.json` too (position, facing,
|
||||
inventory, hotbar choice, stats, diet, buffs, cloak, bed), saved with the
|
||||
world, when the player leaves and when they die. Graves carry their
|
||||
owner. Backups come in M2.7.
|
||||
|
||||
*Decision (M2.4):* single-player stays as it is, with no server inside it
|
||||
("if it's single-player there is no server, so the game decides"). So
|
||||
single-player saves need no migration: they keep working unchanged, and
|
||||
`tests/test_save_load.gd` still proves it. The old idea of running
|
||||
single-player as a loopback server is dropped.
|
||||
- *(Originally: single-player saves migrated to a player file on first
|
||||
load. Not needed since the M2.4 decision above.)*
|
||||
- Per-player graves already work, since graves are pieces. With
|
||||
`death_penalty: grave` they get an owner, and only the owner (and friends,
|
||||
depending on locks) can loot them.
|
||||
@@ -274,7 +302,7 @@ player" or "this player":
|
||||
| **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** *(done)* | 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** *(done)* | 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 |
|
||||
| **M2.4** *(done)* | 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 |
|
||||
| **M2.5** | wildlife and wolves server-side, projectiles, fishing, sleeping with the rule | a pack hunts two players at once; arrows hit on both screens |
|
||||
| **M2.6** | server rules: PvP, raiding, locks and friends, death penalty, difficulty; admin console and chat | each preset (co-op, rivals, adversarial) behaves as described in §4 |
|
||||
| **M2.7** | hosting polish: "Host game" button, systemd and launchd samples, backups, a Tailscale how-to in the docs | Paul runs it on the home server, and a friend joins over Tailscale and plays for an hour |
|
||||
@@ -288,9 +316,8 @@ player" or "this player":
|
||||
- **Rules tests:** one per server rule (PvP off means no damage between
|
||||
players; raiding off means you can't dismantle a stranger's wall; locks
|
||||
keep strangers out of your chest).
|
||||
- **Save tests:** world and player file round trips, migration of old
|
||||
saves, backups.
|
||||
- The existing 9 suites keep running in single-player (loopback) mode.
|
||||
- **Save tests:** world and player file round trips, backups.
|
||||
- The single-player suites keep running as they are (no server).
|
||||
- `tests/test_net_shared.gd` (M2.3) is the two-world version: this test is
|
||||
one player and `tests/net_world_bot.gd` (a second process with its own
|
||||
world, following commands the test writes as files) is the other. A
|
||||
|
||||
Reference in New Issue
Block a user