From 550d73f1d785d64728641948a00c021afef6ccfe Mon Sep 17 00:00:00 2001 From: Josh Creek <8179928+jcreek@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:39:42 +0100 Subject: [PATCH] fix: preserve active matchmaking on transient errors --- Game/scripts/control_plane_client.gd | 20 ++++++++++++++++---- Game/scripts/matchmaking_state.gd | 9 +++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Game/scripts/control_plane_client.gd b/Game/scripts/control_plane_client.gd index 6173d703..871ba6da 100644 --- a/Game/scripts/control_plane_client.gd +++ b/Game/scripts/control_plane_client.gd @@ -40,7 +40,10 @@ func queue_create(ticket_id: String, playlist: String, client_build: String, pro return ERR_INVALID_PARAMETER if not state.begin_queue(ticket_id, playlist): return ERR_INVALID_PARAMETER - return _start_request("queue_create", HTTPClient.METHOD_POST, "/v1/queue", {"ticket_id": ticket_id, "playlist": playlist, "client_build": client_build, "protocol_version": protocol_version}, _idempotency_key("queue")) + var err := _start_request("queue_create", HTTPClient.METHOD_POST, "/v1/queue", {"ticket_id": ticket_id, "playlist": playlist, "client_build": client_build, "protocol_version": protocol_version}, _idempotency_key("queue")) + if err != OK: + state.fail("Could not start matchmaking: %s" % error_string(err)) + return err func recover_queue(ticket_id: String) -> Error: @@ -102,17 +105,26 @@ func _on_request_completed(result: HTTPRequest.Result, response_code: int, _head var operation := _operation _operation = "" if result != HTTPRequest.RESULT_SUCCESS: - state.fail("Control-plane request failed") + if operation == "queue_create" or operation == "queue_recover": + state.fail("Control-plane request failed") + else: + state.set_notice("Control-plane request failed; retrying is safe") request_failed.emit(operation, response_code, "network error") return var parsed = JSON.parse_string(body.get_string_from_utf8()) if not parsed is Dictionary: - state.fail("Control-plane returned invalid JSON") + if operation == "queue_create" or operation == "queue_recover": + state.fail("Control-plane returned invalid JSON") + else: + state.set_notice("Control-plane returned invalid JSON; retrying is safe") request_failed.emit(operation, response_code, "invalid JSON") return if response_code < 200 or response_code >= 300: var detail := String(parsed.get("error", "request rejected")) - state.fail(detail) + if operation == "queue_create" or operation == "queue_recover": + state.fail(detail) + else: + state.set_notice(detail) request_failed.emit(operation, response_code, detail) return var payload: Dictionary = parsed diff --git a/Game/scripts/matchmaking_state.gd b/Game/scripts/matchmaking_state.gd index 389a515b..3ae4ad05 100644 --- a/Game/scripts/matchmaking_state.gd +++ b/Game/scripts/matchmaking_state.gd @@ -68,6 +68,8 @@ func apply_ticket_update(update: Dictionary) -> bool: expires_at_unix = int(update["expires_at_unix"]) if update.has("message"): message = String(update["message"]) + else: + message = "" _emit_changed() return true @@ -104,6 +106,8 @@ func apply_proposal_update(update: Dictionary) -> bool: return _request_resync(proposal_id) proposal_revision = incoming_revision proposal_state = incoming_proposal_state + if incoming_proposal_state == "OPEN" or incoming_proposal_state == "ACCEPTED": + message = "" if update.has("expires_at_unix"): expires_at_unix = int(update["expires_at_unix"]) _emit_changed() @@ -134,6 +138,11 @@ func fail(reason: String) -> void: _emit_changed() +func set_notice(notice: String) -> void: + message = notice + _emit_changed() + + func can_cancel() -> bool: return phase == QUEUED or phase == PROPOSED or phase == ALLOCATING