feat(client): protocol v6 bridge — stance, inventory, input mapping

Upgrade client protocol bridge from v5 to v6 to match server.
Adds player_stance (4 variants) and player_inventory decode to
ObserverSnapshot. Adds TOGGLE_STANCE_UP/DOWN to InputMapper.
Includes 25 gdUnit4 tests for v6 decode + server serialization
test gap fix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 23:05:47 +01:00
co-authored by Claude Opus 4.6
parent f3550577a9
commit 24cce41379
7 changed files with 444 additions and 4 deletions
+21 -1
View File
@@ -11,7 +11,7 @@ class_name Protocol
## Protocol version — must match server PROTOCOL_VERSION in bridge/types.rs.
## Reject snapshots where version != this value.
const PROTOCOL_VERSION: int = 5
const PROTOCOL_VERSION: int = 6
# -- Decode: bytes from server → GDScript types --------------------------------
@@ -104,6 +104,24 @@ static func decode_snapshot(bytes: PackedByteArray) -> Variant:
"duration_seconds": float(raw_monologue.get("duration_seconds", 5.0)),
}
# v6: player_stance (#449, D-053) — unit enum → bare string
var player_stance: String = "Walk"
var raw_stance: Variant = raw.get("player_stance")
if raw_stance is String:
player_stance = raw_stance
# v6: player_inventory (#449, D-065) — array of {item_id, name, slot}
var player_inventory: Array = []
var raw_inventory: Variant = raw.get("player_inventory")
if raw_inventory is Array:
for raw_item in raw_inventory:
if raw_item is Dictionary and raw_item.has("item_id") and raw_item.has("name"):
player_inventory.append({
"item_id": int(raw_item["item_id"]),
"name": str(raw_item["name"]),
"slot": int(raw_item.get("slot", 0)),
})
return {
"tick": tick,
"entities": entities,
@@ -111,6 +129,8 @@ static func decode_snapshot(bytes: PackedByteArray) -> Variant:
"version": version,
"game_time": game_time,
"player_facing": player_facing,
"player_stance": player_stance,
"player_inventory": player_inventory,
"visible_tiles": visible_tiles,
"nearby_interactions": nearby_interactions,
"current_monologue": current_monologue,