Commit Graph
7 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Opus 4.6 57da75c509 feat(client): upgrade protocol decoder and GameState for v2 snapshot
Server shipped ObserverSnapshot v2 with game_time, player_facing,
visible_tiles (with visibility sectors), and per-entity visibility.
Protocol decoder was silently ignoring these fields. Now extracts
all v2 data with null defaults for backward compatibility.

GameState gains game_time, player_facing, visibility_sectors vars.
Derives visible_positions from visible_tiles when present (for real
server mode). Test snapshot updated with v2 fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 00:53:18 +01:00
jpmschweitzerandClaude Opus 4.6 2338941721 fix(client): batch-encode inputs as Vec<PlayerInput> per server wire format
Server expects a MessagePack array of PlayerInput objects in one framed
message per tick, not individual inputs per frame. Added
Protocol.encode_player_inputs() for batch encoding. Changed SimBridge to
buffer raw input dicts and batch-encode in _process(). Also fixed server
port default (9876) and positional arg format to match server CLI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:44:14 +01:00
jpmschweitzerandClaude Opus 4.6 3befd2309c fix(client): address PR #5 review — race condition, buffer corruption, input error
Critical fixes from Hoshe review:
1. Race condition: defer TCP connect to _process() with retry logic
   (MAX_CONNECT_RETRIES=20, 100ms interval) so server has time to bind.
2. Buffer corruption: disconnect on oversized message instead of
   clearing valid buffered data (_corrupt flag, fail-safe).
3. Silent input drop: send_input() returns Error so callers can detect
   encode/validation failures.

Warnings addressed:
- ServerProcess validates server_path exists before spawning
- SIGKILL and health check TODOs documented for future work
- Diagonal keybindings documented as intentional deferral
- send_message uses single put_data() call (no partial write risk)
- Static frame helpers documented as D-030 Layer 2 test-only

New tests (36 total, up from 33):
- Partial read scenario (chunked TCP delivery)
- Multi-message sequential decode (exercises buffer corruption fix)
- send_input error return on invalid action

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:14:52 +01:00
jpmschweitzerandClaude Opus 4.6 6dfaf2831f feat(client): add LocalBridge TCP transport and ServerProcess manager
LocalBridge wraps StreamPeerTCP with 4-byte big-endian length-prefix
framing matching server/src/bridge/framing.rs. ServerProcess manages
the Rust server as a subprocess via OS.create_process(). Together
they form the D-020 IPC transport layer for ticket #79.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:59:34 +01:00
jpmschweitzerandClaude Opus 4.6 5a539991e4 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>
2026-02-11 20:12:39 +01:00
jpmschweitzerandClaude Opus 4.6 bc9a691bc1 fix(client): address PR #4 review feedback
Hoshe critical fixes:
- _action_enum_to_wire uses InputMapper.Action constants instead of
  fragile integer literals; OPEN_MENU explicitly handled as client-only
- Remove int() coercion on tick/entity_id — use direct assignment since
  GDScript int is signed 64-bit (safe for realistic tick values)
- Check encode result before buffering in send_input() — reject empty
  bytes instead of corrupting the outbound stream
- Test snapshot now uses Protocol format {tick, entities} instead of
  legacy schema; GameState updated to derive player position from
  entity data; main.gd and world_renderer.gd updated accordingly

Hoshe warnings:
- 5 negative tests added (truncated bytes, wrong type, missing fields,
  empty bytes, encode validation) — 20/20 tests pass
- receive_bytes signal is emitted at consume time in poll_snapshot by
  design (documented in code)

Tyre suggestions:
- Remove duplicated root-level fixtures — single source of truth in
  client/tests/fixtures/msgpack/
- gen_fixtures.rs writes directly to client/ directory
- Add `make fixtures` target for regeneration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:32:49 +01:00
jpmschweitzerandClaude Opus 4.6 b5dd44313e feat(client): add Protocol codec with cross-language tests (#77)
Protocol.gd decodes ObserverSnapshot and PlayerInput from Rust's
rmp_serde wire format, and encodes PlayerInput for sending to server.
Handles rmp_serde enum encoding: unit variants as bare strings,
data variants as single-element maps.

8 fixture-based tests verify decode of Rust-generated fixtures,
GDScript encode/decode roundtrips, and cross-language compatibility.
All 15 tests pass (3 suites).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:16:56 +01:00