diff --git a/client/scripts/autoloads/sim_bridge.gd b/client/scripts/autoloads/sim_bridge.gd index 98aad66b8..48f530ea3 100644 --- a/client/scripts/autoloads/sim_bridge.gd +++ b/client/scripts/autoloads/sim_bridge.gd @@ -296,12 +296,12 @@ func _test_snapshot() -> Dictionary: return { "tick": _test_tick, - "version": 2, + "version": Protocol.PROTOCOL_VERSION, "game_time": { "day": 0, "time_of_day": _test_tick * 10, "day_phase": "Morning", - "paused": false, + "tick_rate": "Full", }, "player_facing": _test_facing, "entities": entities, diff --git a/client/scripts/protocol/protocol.gd b/client/scripts/protocol/protocol.gd index dad23ca0c..3879a879e 100644 --- a/client/scripts/protocol/protocol.gd +++ b/client/scripts/protocol/protocol.gd @@ -9,6 +9,10 @@ class_name Protocol ## 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. +const PROTOCOL_VERSION: int = 4 + # -- Decode: bytes from server → GDScript types -------------------------------- @@ -27,6 +31,12 @@ 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 @@ -44,8 +54,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"] - # v2 fields — optional for backward compatibility - var version: Variant = raw.get("version") + # version already checked above; 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