Editor save path: single/batch chunk PUT, 409 retry, non-joined Edit World entry
Implements world_persistence_impl.md §9 client/editor task items 2-3: - ChunkSaveService (scripts/editor/chunk_save_service.gd): single-chunk PUT with base_revision, batch PUT for multi-chunk edits, and a real 409 -> re-fetch -> retry loop. Full-chunk overwrite (§8.2 D5) means "re-apply the edit" is just retrying with the locally-edited payload at the freshly-learned revision, not delta replay. - InGameEditor gets a Save button (+ Ctrl+S) that surfaces live_session as an explicit warning instead of ignoring it, per §6 D4. - "Edit World" entry point on the world list (owner-gated) that calls Session.begin_edit() instead of ApiClient.join_world() -- editing never joins, opens no ENet connection, spawns no dedicated server. - game.gd wires Session.editing to fetch the real (0,0,0) chunk over HTTP and open the editor against it, falling back to an empty chunk for an unwritten coordinate. Verified against a real backend (register/world/save/reload, a genuine 409 from two racing saves, atomic 2-chunk batch, live_session field) -- new scripts/smoke_test_editor_save.gd (19/19) plus an extended smoke_test_world_list.gd covering the non-joined entry point (11/11). Full existing Godot smoke suite (18 files) and backend pytest (132) still pass unchanged. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y2FESCaMXeJpC9gSctiEeD
This commit is contained in:
@@ -6,11 +6,19 @@ extends Node
|
||||
## POST /api/worlds/{id}/join; game.gd reads it in _ready() to decide whether
|
||||
## to run networked or fall back to local single-player (e.g. game.tscn opened
|
||||
## directly, or the backend has no orchestration).
|
||||
##
|
||||
## world_list.gd also calls begin_edit() for the "Edit world" entry point
|
||||
## (docs/architecture/world_persistence_impl.md §6 D4): editing is
|
||||
## deliberately **non-joined** -- it never calls POST /join, so `active`
|
||||
## stays false and game.gd never opens an ENet connection for it. `editing`
|
||||
## is the separate signal game.gd checks to open the in-game editor against
|
||||
## a real, HTTP-fetched chunk instead of running gameplay.
|
||||
|
||||
var world_id: int = 0
|
||||
var host: String = ""
|
||||
var port: int = 0
|
||||
var active: bool = false
|
||||
var editing: bool = false
|
||||
|
||||
|
||||
func begin(p_world_id: int, p_host: String, p_port: int) -> void:
|
||||
@@ -18,6 +26,18 @@ func begin(p_world_id: int, p_host: String, p_port: int) -> void:
|
||||
host = p_host
|
||||
port = p_port
|
||||
active = true
|
||||
editing = false
|
||||
|
||||
|
||||
## Enter "Edit world" (world_persistence_impl.md §6 D4): non-joined, no
|
||||
## ENet connection, no dedicated server. game.gd loads/saves chunks over
|
||||
## HTTP instead.
|
||||
func begin_edit(p_world_id: int) -> void:
|
||||
world_id = p_world_id
|
||||
host = ""
|
||||
port = 0
|
||||
active = false
|
||||
editing = true
|
||||
|
||||
|
||||
func clear() -> void:
|
||||
@@ -25,3 +45,4 @@ func clear() -> void:
|
||||
host = ""
|
||||
port = 0
|
||||
active = false
|
||||
editing = false
|
||||
|
||||
Reference in New Issue
Block a user