#!/usr/bin/env bash # Full networked game flow, two real client processes: # register -> POST /api/worlds/{id}/join -> Session -> game.tscn -> networked. # Client A must see client B rendered as a remote player and its own movement # must round-trip. Requires a backend with GAME_SERVERS_ENABLED and the Godot # binary reachable from it. # # Usage: scripts/run_game_multiplayer_test.sh set -uo pipefail cd "$(dirname "$0")/.." BASE_URL="${1:?usage: run_game_multiplayer_test.sh }" WORLD_ID="${2:?usage: run_game_multiplayer_test.sh }" GODOT_BIN="${GODOT_BIN:-godot}" command -v "$GODOT_BIN" >/dev/null 2>&1 || GODOT_BIN="$HOME/godot/godot" export AGP_API_BASE_URL="$BASE_URL" cleanup() { kill "${B_PID:-}" 2>/dev/null; wait 2>/dev/null; } trap cleanup EXIT echo "=== client B: join world $WORLD_ID and hold ===" "$GODOT_BIN" --headless --path . --script res://scripts/mp_game_flow_client.gd -- \ --role b --world "$WORLD_ID" >/tmp/mpflow_b.log 2>&1 & B_PID=$! for _ in $(seq 1 40); do grep -q 'RESULT b in_world' /tmp/mpflow_b.log && break; sleep 1; done grep -q 'RESULT b in_world' /tmp/mpflow_b.log || { echo "B never entered the world:"; tail -5 /tmp/mpflow_b.log; echo "=== SMOKE RESULT: FAIL ==="; exit 1; } echo "=== client A: join world $WORLD_ID, move, look for B ===" "$GODOT_BIN" --headless --path . --script res://scripts/mp_game_flow_client.gd -- \ --role a --world "$WORLD_ID" 2>&1 | tee /tmp/mpflow_a.log A_LINE=$(grep '^RESULT a' /tmp/mpflow_a.log || true) echo echo "A: ${A_LINE:-}" echo "B: $(grep '^RESULT b' /tmp/mpflow_b.log || echo '')" if echo "$A_LINE" | grep -q 'moved=true' && echo "$A_LINE" | grep -qE 'remotes=[1-9]'; then echo "=== SMOKE RESULT: PASS ===" exit 0 fi echo "=== SMOKE RESULT: FAIL ===" exit 1