fix(client): address PR #4 round 2 review feedback

- decode_snapshot() reports dropped entities via push_error and returns
  decode_errors count so callers can detect partial data (D-010
  information boundary compliance)
- receive_bytes() warns when overwriting unconsumed snapshot, documents
  latest-wins semantics
- Rename misleading test to test_encode_produces_nonempty_bytes
- Fix tick rate comment: 10 ticks/game-minute per D-031

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 20:12:39 +01:00
co-authored by Claude Opus 4.6
parent bc9a691bc1
commit 5a539991e4
3 changed files with 15 additions and 4 deletions
+4
View File
@@ -75,9 +75,13 @@ func poll_snapshot() -> Variant:
return null
# Called by transport layer (ticket #79) when raw bytes arrive from the server.
# Latest-wins semantics: newer snapshots replace unconsumed ones. This is correct
# for real-time rendering (stale frames are worthless). Upgrade to queue if needed.
func receive_bytes(bytes: PackedByteArray) -> void:
var snapshot = Protocol.decode_snapshot(bytes)
if snapshot != null:
if _last_snapshot != null:
push_warning("SimBridge: overwriting unconsumed snapshot (tick %s replaced by %s)" % [_last_snapshot.tick, snapshot.tick])
_last_snapshot = snapshot
# Drain the outbound buffer. Called by transport layer (ticket #79) to get encoded messages.
+10 -2
View File
@@ -26,17 +26,25 @@ static func decode_snapshot(bytes: PackedByteArray) -> Variant:
return null
var entities: Array[Dictionary] = []
for raw_entity in raw["entities"]:
var raw_entities: Array = raw["entities"]
var dropped := 0
for raw_entity in raw_entities:
var entity = _decode_entity(raw_entity)
if entity != null:
entities.append(entity)
else:
dropped += 1
if dropped > 0:
push_error("Protocol: %d/%d entities failed to decode (D-010 information boundary violation)" % [dropped, raw_entities.size()])
# GDScript int is signed 64-bit. Rust tick is u64 but will not exceed 2^63
# in any realistic scenario (would require ~29 billion years at 10 ticks/min).
# in any realistic scenario (would require ~29 billion years at 10 ticks/game-minute per D-031).
var tick: int = raw["tick"]
return {
"tick": tick,
"entities": entities,
"decode_errors": dropped,
}
+1 -2
View File
@@ -164,7 +164,6 @@ func test_decode_player_input_empty_bytes() -> void:
assert_that(result).is_null()
func test_encode_returns_empty_on_failure() -> void:
# Verify that a valid encode produces non-empty bytes
func test_encode_produces_nonempty_bytes() -> void:
var bytes = Protocol.encode_player_input(1, "MoveNorth")
assert_that(bytes.size()).is_greater(0)