mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 08:23:45 +00:00
chore(multiplayer): Phase 0 refactors + graphics/perf settings groundwork
Lands the non-networked Phase 0 tasks from multiplayer-todo.md (ship/camera/ arena refactors, sim constants, background FPS handling) plus a first pass at exposing graphics/performance settings (presets, resolution scaling, vsync, FPS cap, perf overlay) and a GPU profiling harness for the real-hardware follow-up in task 0.15b.
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
class_name AIShipController
|
||||
extends ShipController
|
||||
|
||||
# Emitted if a cached teammate/opponent reference is found freed and dropped
|
||||
# from the roster (see _decide). No despawn path exists anywhere in this
|
||||
# codebase today — rosters are fixed at match start — so this never fires in
|
||||
# practice; it's cheap insurance against ShipObservations.build() crashing on
|
||||
# a stale reference if that ever changes.
|
||||
signal roster_changed
|
||||
|
||||
# Drives a ship from a trained self-play policy (see TRAINING.md). Builds the
|
||||
# same canonical observation as training (ShipObservations) and runs the
|
||||
# policy MLP in GDScript (PolicyNetwork) — the shipped bot has no Python,
|
||||
@@ -50,6 +57,13 @@ var _scene_refs_ready := false
|
||||
func _ready():
|
||||
if not model_path.is_empty():
|
||||
load_policy(model_path)
|
||||
# Stagger the first decision across [1, reaction_ticks] so bots sharing a
|
||||
# reaction cadence don't all run policy inference on the same physics
|
||||
# tick — six bots landing together is a ~2.4 ms spike in a 16.7 ms budget
|
||||
# (policy_network.gd's forward pass). The phase offset this establishes
|
||||
# persists across subsequent decisions since each one re-arms the same
|
||||
# period from wherever _ticks_until_decision currently sits.
|
||||
_ticks_until_decision = randi_range(1, maxi(reaction_ticks, 1))
|
||||
|
||||
|
||||
# League training swaps a frozen opponent's policy between episodes without
|
||||
@@ -83,6 +97,11 @@ func get_action() -> ShipAction:
|
||||
|
||||
|
||||
func _decide() -> void:
|
||||
if _teammates.any(func(s): return not is_instance_valid(s)) \
|
||||
or _opponents.any(func(s): return not is_instance_valid(s)):
|
||||
_teammates = _teammates.filter(is_instance_valid)
|
||||
_opponents = _opponents.filter(is_instance_valid)
|
||||
roster_changed.emit()
|
||||
var obs := ShipObservations.build(_ship, _teammates, _opponents, _ball, _attack_goal_position)
|
||||
var out := _policy.forward(obs)
|
||||
# See ShipActionCodec for the decode — the single source of truth shared
|
||||
|
||||
Reference in New Issue
Block a user