fix(protocol): drop PROTOCOL_VERSION lockstep — D-192 (#875)

Removes the version-mismatch guard from Protocol.decode_snapshot() and the
PROTOCOL_VERSION constant from the client (server side done in #874).

Core changes:
- protocol.gd: remove const PROTOCOL_VERSION, remove version mismatch guard,
  remove "version" from return dict, add gauntlet_mode/room_id decode
- sim_bridge.gd: remove handshake version check; relax handshake guard to
  require only a valid Dictionary (server no longer sends protocol_version);
  emit handshake_complete(0) for API compat
- loading_screen.gd: drop "· protocol N" suffix from version label
- test_harness.gd: replace Protocol.PROTOCOL_VERSION with literal 23

Test updates (21 files): replace "version": Protocol.PROTOCOL_VERSION with
"version": 23 in all snapshot bytes dicts; remove snapshot.version == N
assertions; remove version-rejection tests (test_rejects_version_6,
test_decode_snapshot_rejects_missing_version, test_decode_snapshot_rejects_old_version,
test_protocol_rejects_version_mismatch, test_sim_bridge_test_snapshot_uses_current_protocol_version).

Also includes: #872 bookmark_catalog carry-forward regression test, and
#873 merge-path flow tests (test_merge_path_flows_sprint37.gd).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-21 17:29:49 +02:00
co-authored by Claude Sonnet 4.6
parent 708ab25614
commit d72fcc7847
21 changed files with 490 additions and 193 deletions
+15 -20
View File
@@ -9,13 +9,6 @@ extends Node
## Unit enum variants (no data) → bare strings ("MoveNorth", "Npc")
## Data enum variants → single-element maps ({"UsePerceptionMode": "thermal"})
## Protocol version — must match server PROTOCOL_VERSION in bridge/types.rs.
## Reject snapshots where version != this value.
## v20: adds settings_response field to ObserverSnapshot (#627, D-138).
## v21: adds economy_snapshot field to ObserverSnapshot (#822, D-181).
## v23: adds bookmark_catalog field to ObserverSnapshot (#614).
const PROTOCOL_VERSION: int = 23
# -- Decode: bytes from server → GDScript types --------------------------------
@@ -34,17 +27,6 @@ static func decode_snapshot(bytes: PackedByteArray) -> Variant:
push_error("Protocol: snapshot missing required fields")
return null
# Version check: reject snapshots from incompatible server
var version: Variant = raw.get("version")
if version != PROTOCOL_VERSION:
push_error(
(
"Protocol: version mismatch (got %s, expected %s). Server and client are out of sync."
% [version, PROTOCOL_VERSION]
)
)
return null
var entities: Array[Dictionary] = []
var raw_entities: Array = raw["entities"]
var dropped := 0
@@ -67,7 +49,7 @@ static func decode_snapshot(bytes: PackedByteArray) -> Variant:
# in any realistic scenario (would require ~29 billion years at 10 ticks/game-minute per D-031).
var tick: int = raw["tick"]
# version already checked above; game_time for HUD display
# game_time for HUD display
var game_time: Variant = raw.get("game_time")
# player_facing: FacingDirection is a unit enum → bare string in rmp_serde
@@ -223,6 +205,18 @@ static func decode_snapshot(bytes: PackedByteArray) -> Variant:
"speaker_entity_id": int(raw_dr.get("speaker_entity_id", -1)),
}
# v8: gauntlet_mode and room_id (#496) — present only in Gauntlet sessions.
# gauntlet_mode is a bool flag; room_id is a String room identifier or absent.
# Snapshot handler (snapshot_handler.gd) reads these via snapshot.has() guards.
var gauntlet_mode: bool = false
var raw_gauntlet: Variant = raw.get("gauntlet_mode")
if raw_gauntlet == true:
gauntlet_mode = true
var room_id: Variant = null
var raw_room_id: Variant = raw.get("room_id")
if raw_room_id is String:
room_id = raw_room_id
# v9: conversation_events (#535, D-078) — overheard NPC-to-NPC dialogue lines.
# Each event carries pre-occluded text plus speaker/target attribution.
var conversation_events: Array = []
@@ -484,7 +478,6 @@ static func decode_snapshot(bytes: PackedByteArray) -> Variant:
"tick": tick,
"entities": entities,
"decode_errors": dropped,
"version": version,
"game_time": game_time,
"player_facing": player_facing,
"player_stance": player_stance,
@@ -508,6 +501,8 @@ static func decode_snapshot(bytes: PackedByteArray) -> Variant:
"current_ticker": current_ticker,
"settings_response": settings_response,
"bookmark_catalog": bookmark_catalog,
"gauntlet_mode": gauntlet_mode,
"room_id": room_id,
}
+1 -1
View File
@@ -272,7 +272,7 @@ func snapshot() -> Dictionary:
return {
"tick": tick,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"game_time":
{
"day": 0,