mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 00:14:00 +00:00
feat(multiplayer): Phase 1 transport, connection, and lobby
Lands tasks 1.0-1.8 of multiplayer-todo.md: the pure-function test runner, net_codec (wire format quantizers/pack-unpack), NetworkManager (ENet transport, manual polling, min-RTT clock sync), MatchNet (handshake, protocol/tick-rate gating, roster with team+ready state), lobby.tscn (team columns, switch team, ready toggle), server_boot.tscn (headless dedicated server with structured logging and an overrun watchdog), and main_menu.gd's Host/Join-by-IP UI (connecting overlay, cancel, bounded failure path). Followed by an adversarial review (Opus subagent) that found and fixed two real bugs - an unvalidated player_name broadcast that let one client's oversized name head-of-line-block the reliable channel for everyone, and a server-side roster leak across a host/re-host cycle - plus three gaps in the test suite itself where a claim of "verified" wasn't actually backed by what the test checked. All five two-process smoke tests plus the pure-function suite are green with the strengthened assertions in place.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
extends CanvasLayer
|
||||
|
||||
# Autoload: toggleable network debug overlay (F4 by default — see
|
||||
# toggle_net_overlay in project.godot's [input]). Read-only against
|
||||
# NetworkManager's clock state (task 1.8). Mirrors perf_overlay.gd's pattern
|
||||
# — headless-guarded, hidden by default, no gameplay-state writes.
|
||||
|
||||
var _label: Label
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if DisplayServer.get_name() == "headless":
|
||||
set_process(false)
|
||||
return
|
||||
layer = 100
|
||||
_label = Label.new()
|
||||
_label.add_theme_font_size_override("font_size", 14)
|
||||
_label.add_theme_color_override("font_color", Color(0.5, 0.8, 1.0))
|
||||
_label.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.85))
|
||||
_label.add_theme_constant_override("shadow_offset_x", 1)
|
||||
_label.add_theme_constant_override("shadow_offset_y", 1)
|
||||
_label.position = Vector2(12, 90)
|
||||
_label.visible = false
|
||||
add_child(_label)
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("toggle_net_overlay") and _label:
|
||||
_label.visible = not _label.visible
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if not _label or not _label.visible:
|
||||
return
|
||||
if NetworkManager.is_server:
|
||||
_label.text = "NET: server, %d peer(s)" % (MatchNet.roster.size())
|
||||
elif NetworkManager.is_client:
|
||||
if NetworkManager.rtt_ms < 0.0:
|
||||
_label.text = "NET: client, connecting (no clock sample yet)"
|
||||
else:
|
||||
_label.text = "NET: client RTT %.1fms clock offset %.1fms" % [NetworkManager.rtt_ms, NetworkManager.clock_offset_ms]
|
||||
else:
|
||||
_label.text = "NET: offline"
|
||||
Reference in New Issue
Block a user