Release alpha 10 with bilingual UI and social co-op

This commit is contained in:
Emporex committed 2026-10-10 12:50:27 +02:00
1 parent 7d5cad7277
commit d53467baf2
22 files changed
+1714 -271

No files matched your search

+24 -5
View File
@@ -32,7 +32,7 @@ func _run() -> void:
assert(not info.is_exception(), "Die Godot-Anbindung muss Server-RPCs erreichen.")
var info_data = JSON.parse_string(info.payload)
assert(info_data is Dictionary and info_data.get("status") == "online", "Der Server muss seinen Onlinestatus melden.")
assert(info_data.get("version") == "0.23", "Der Server muss die aktuelle Runtime 0.23 geladen haben: %s" % info_data)
assert(info_data.get("version") == "0.25", "Der Server muss die aktuelle Runtime 0.25 geladen haben: %s" % info_data)
var deletion_client: NakamaClient = nakama.create_client("voidbastion-public-v1", test_host, test_port, test_scheme, 5, NakamaLogger.LOG_LEVEL.ERROR)
var deletion_session: NakamaSession = await deletion_client.authenticate_device_async("voidbastion_delete_test_" + suffix, "delete_test_" + suffix, true)
@@ -51,13 +51,13 @@ func _run() -> void:
var public_leaderboard_name := "Rangpilot %s" % suffix.right(6)
var renamed_a = await client_a.rpc_async(session_a, "update_display_name", JSON.stringify({"display_name": public_leaderboard_name}))
assert(not renamed_a.is_exception() and bool(JSON.parse_string(renamed_a.payload).get("accepted", false)), "Der Ranglistenpilot muss einen öffentlichen Namen setzen können.")
var run_payload := JSON.stringify({"map": 1, "difficulty": 1, "mode": "mission", "wave": 4, "score": 4700, "client_version": "0.23-integration"})
var run_payload := JSON.stringify({"map": 1, "difficulty": 1, "mode": "mission", "wave": 4, "score": 4700, "client_version": "0.25-integration"})
var submitted = await client_a.rpc_async(session_a, "submit_run", run_payload)
assert(not submitted.is_exception(), "Ein plausibles Ergebnis muss serverseitig angenommen werden.")
var records = await client_a.list_leaderboard_records_async(session_a, "mission_map1_difficulty1", null, null, 10)
assert(not records.is_exception() and records.records.size() >= 1, "Das Ergebnis muss über das Godot-SDK aus der Rangliste lesbar sein.")
var records = await client_a.list_leaderboard_records_async(session_a, "mission_map1_difficulty1", [session_a.user_id], null, 10)
assert(not records.is_exception() and (records.records.size() >= 1 or records.owner_records.size() >= 1), "Das Ergebnis muss über das Godot-SDK aus der Rangliste lesbar sein.")
var own_record = null
for record in records.records:
for record in records.owner_records:
if record.owner_id == session_a.user_id:
own_record = record
break
@@ -67,6 +67,17 @@ func _run() -> void:
var socket_b: NakamaSocket = nakama.create_socket_from(client_b)
assert(not (await socket_a.connect_async(session_a, true, 5)).is_exception(), "Spieler A benötigt eine Echtzeitverbindung.")
assert(not (await socket_b.connect_async(session_b, true, 5)).is_exception(), "Spieler B benötigt eine Echtzeitverbindung.")
var friend_request = await client_a.add_friends_async(session_a, null, PackedStringArray([session_b.username]))
assert(not friend_request.is_exception(), "Spieler A muss eine Freundschaftsanfrage senden können.")
var friend_accept = await client_b.add_friends_async(session_b, PackedStringArray([session_a.user_id]))
assert(not friend_accept.is_exception(), "Spieler B muss die Freundschaftsanfrage bestätigen können.")
var friend_list = await client_a.list_friends_async(session_a, 0, 100)
assert(not friend_list.is_exception() and friend_list.friends.size() == 1 and friend_list.friends[0].user.id == session_b.user_id,
"Die bestätigte Freundschaft muss beim Gastgeber sichtbar sein.")
var received_invites: Array = []
socket_b.received_notification.connect(func(note):
if int(note.code) == 101:
received_invites.append(JSON.parse_string(note.content)))
socket_a.received_matchmaker_matched.connect(func(value): matched_a = value)
socket_b.received_matchmaker_matched.connect(func(value): matched_b = value)
socket_a.received_match_state.connect(func(value): _capture_snapshot(value, true))
@@ -124,6 +135,14 @@ func _run() -> void:
assert(room_code.length() == 6 and not private_match_id.is_empty(), "Der Server muss einen sechsstelligen Raumcode und eine Partie liefern.")
var private_match_a = await socket_a.join_match_async(private_match_id)
assert(not private_match_a.is_exception(), "Der Gastgeber muss seinem privaten Raum beitreten können.")
var invite = await client_a.rpc_async(session_a, "invite_friend", JSON.stringify({"friend_id": session_b.user_id, "room_code": room_code}))
assert(not invite.is_exception() and bool(JSON.parse_string(invite.payload).get("accepted", false)), "Der Gastgeber muss einen bestätigten Freund einladen können.")
for attempt in 30:
if not received_invites.is_empty():
break
await create_timer(0.05).timeout
assert(not received_invites.is_empty() and received_invites[0] is Dictionary and String(received_invites[0].get("room_code", "")) == room_code,
"Die Einladung muss als Echtzeitbenachrichtigung mit dem richtigen Raumcode ankommen.")
var found_room = await client_b.rpc_async(session_b, "join_private_room", JSON.stringify({"room_code": room_code.to_lower()}))
assert(not found_room.is_exception(), "Der Mitspieler muss den Raumcode unabhängig von Groß-/Kleinschreibung finden können.")
var found_data = JSON.parse_string(found_room.payload)