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
+12 -40
View File
@@ -24,33 +24,12 @@ func _load_fixture(name: String) -> PackedByteArray:
return file.get_buffer(file.get_length())
# -- Protocol version upgrade -------------------------------------------------
# Tautological "PROTOCOL_VERSION == N" assertions deleted: they assert a constant
# equals its own literal, fail mechanically on every protocol bump, and have
# never caught a real bug. Mismatch handling is exercised by test_rejects_version_6
# below; field-presence is exercised by the per-version decode tests.
func test_fixtures_at_protocol_version_8() -> void:
# NOTE: These binary fixtures embed version 8 and are rejected by the version
# mismatch guard in decode_snapshot(). This test is pre-existing broken since v9+.
# Fixtures need regeneration via `make fixtures-gauntlet` to match current protocol.
# Skipping rather than deleting to preserve the fixture round-trip pattern.
pass
func test_rejects_version_6() -> void:
var raw := {"tick": 1, "version": 6, "entities": []}
var encoded = Messagepack.encode(raw)
var snapshot = Protocol.decode_snapshot(encoded.value)
assert_that(snapshot).is_null()
# -- player_stance decode (D-053) ---------------------------------------------
func test_decode_player_stance_walk() -> void:
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_stance": "Walk",
"player_inventory": [],
@@ -64,7 +43,7 @@ func test_decode_player_stance_walk() -> void:
func test_decode_player_stance_sprint() -> void:
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_stance": "Sprint",
"player_inventory": [],
@@ -77,7 +56,7 @@ func test_decode_player_stance_sprint() -> void:
func test_decode_player_stance_careful() -> void:
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_stance": "Careful",
"player_inventory": [],
@@ -90,7 +69,7 @@ func test_decode_player_stance_careful() -> void:
func test_decode_player_stance_crouch() -> void:
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_stance": "Crouch",
"player_inventory": [],
@@ -104,7 +83,7 @@ func test_decode_player_stance_missing_defaults_to_walk() -> void:
# v6 snapshot without player_stance → should default to "Walk"
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
}
var encoded = Messagepack.encode(raw)
@@ -118,7 +97,7 @@ func test_decode_player_stance_missing_defaults_to_walk() -> void:
func test_decode_empty_inventory() -> void:
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_stance": "Walk",
"player_inventory": [],
@@ -132,7 +111,7 @@ func test_decode_smuggler_inventory_3_items() -> void:
# D-065: smuggler carries 3 specific items
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_stance": "Walk",
"player_inventory": [
@@ -161,7 +140,7 @@ func test_decode_full_9_slot_inventory() -> void:
items.append({"item_id": 100 + i, "name": "Item %d" % i, "slot": i})
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_inventory": items,
}
@@ -177,7 +156,7 @@ func test_decode_full_9_slot_inventory() -> void:
func test_decode_inventory_missing_defaults_to_empty() -> void:
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
}
var encoded = Messagepack.encode(raw)
@@ -188,7 +167,7 @@ func test_decode_inventory_missing_defaults_to_empty() -> void:
func test_decode_inventory_skips_malformed_items() -> void:
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_inventory": [
{"item_id": 100, "name": "Valid Item", "slot": 0},
@@ -209,7 +188,7 @@ func test_decode_inventory_skips_malformed_items() -> void:
func test_decode_inventory_item_slot_defaults_to_zero() -> void:
var raw := {
"tick": 1,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"entities": [],
"player_inventory": [
{"item_id": 100, "name": "No Slot"},
@@ -281,12 +260,6 @@ func test_sim_bridge_test_snapshot_has_player_inventory() -> void:
assert_that(snap.player_inventory is Array).is_true()
func test_sim_bridge_test_snapshot_uses_current_protocol_version() -> void:
SimBridge.reset_test_state()
var snap = SimBridge._test_snapshot()
assert_that(snap.version).is_equal(Protocol.PROTOCOL_VERSION)
# -- Fixture: v6 snapshots include new fields ----------------------------------
func test_fixture_snapshots_have_v6_defaults() -> void:
@@ -334,7 +307,7 @@ func test_full_v6_snapshot_decode() -> void:
# Simulate a realistic v6 snapshot with all fields populated
var raw := {
"tick": 100,
"version": Protocol.PROTOCOL_VERSION,
"version": 23,
"game_time": {"day": 1, "time_of_day": 720, "day_phase": "Evening", "tick_rate": "Full"},
"player_facing": "Southeast",
"player_stance": "Careful",
@@ -367,7 +340,6 @@ func test_full_v6_snapshot_decode() -> void:
assert_that(snapshot).is_not_null()
assert_that(snapshot.tick).is_equal(100)
assert_that(snapshot.version).is_equal(Protocol.PROTOCOL_VERSION)
assert_that(snapshot.player_facing).is_equal("Southeast")
assert_that(snapshot.player_stance).is_equal("Careful")
assert_that(snapshot.player_inventory.size()).is_equal(3)