Files
CosmicClash/TODO.md
T
Josh Creek 9bdeb73fa7 docs: mark trained-bot compatibility items resolved in TODO.md
Records the drag/aperture/collider-bake/beyond-1v1 items as done, with a
short note on what actually shipped (scoped up to 5v5 mid-implementation)
and the explicit non-goals (no 2v2+ curriculum, no team-size UI) so it's
clear what's still open.
2026-08-05 09:18:08 +01:00

6.2 KiB

TODO

Deferred work, in rough priority order. The current architecture (ShipAction/ShipController seam, Arena/GameMode split, code-driven spawning, group-tagged ball/goals) was chosen specifically so these bolt on without rework.

AI opponent (reinforcement learning)

The training pipeline is built — see TRAINING.md (self-play PPO via the vendored godot_rl_agents bridge, JSON policy export, in-game GDScript inference, eval ladder). Remaining:

  • Long training runs on the Linux/3090 box to produce actually-good bots; promote further checkpoints into Game/bots/promoted/ as medium/hard tiers once they clear easy.json in evaluate.py.
  • Frozen-opponent league: train the live policy against a pool of past exported checkpoints, sampled per-episode (today's --opponent-mode=frozen only supports one fixed model per run) to prevent self-play strategy collapse on long runs.
  • Richer state setter / curriculum: aerial states, wall plays, rebound scenarios as skill grows (beyond the score/defend/draw staging already in place).

Correctness

Bugs found in an adversarial review. None are gameplay- or physics-affecting, so all are safe to land against the current Game/bots/ checkpoints.

  • Goal scoring volume (3.5 x 1.5, objects/goal.tscn) is smaller than the drawn mouth (3.7 x 1.65, ArenaBoundary.GOAL_APERTURE_*) — a ball crossing the visible edge doesn't score. Fixed: GOAL_APERTURE_HALF_WIDTH/HEIGHT now match the sensor exactly (1.75/1.5).
  • Delete the duplicate 1 MB texture — assets/textures/planet_surface.png and assets/models/nebula_planet_planet_surface.png are byte-identical.

Performance

  • Measure nebula_dust.gdshader's per-fragment depth-texture sample across 500 large soft billboards before adding more particle work.
  • ~Bake ArenaBoundary's 160 runtime-generated CollisionShape3D nodes into the scene. Done: ArenaBoundary.bake_colliders() + Game/tools/bake_arena_boundary.gd (re-run after any future geometry change). _ready() self-heals — skips regenerating when a bake already matches the current goal_mode, regenerates at runtime otherwise (e.g. the _elevated arena variants, not yet baked).

Presentation / AAA polish

The largest gap between this and a AAA-feeling product is presentation, not code. Sequenced after the above for pragmatic reasons, but this is the highest impact per hour.

  • Audio — there is none. Zero sound files, zero AudioStreamPlayer nodes, no bus layout. Needs: engine hum pitched to throttle, turbo whoosh, ball impacts scaled by collision impulse, wall scrapes, goal explosion, crowd bed, UI clicks, countdown beeps, music. Can be driven off Ship's existing telemetry signals.
  • SSAO/SSIL in the arena Environments — cheapest single perceived-quality win available; grounds the ships against the deck and gives the fillets and goal recesses real depth.
  • VFX on anything that moves: EngineGlowL/R are static meshes that don't respond to throttle. No thruster plume, turbo flame, ball trail, impact sparks or goal burst. arena_02 is the only scene with any particles at all.
  • Impact feedback — screen shake, hit-stop, flash, controller rumble on ball contact.
  • Camera feel in ship_camera.gd — fixed distance/height/FOV today. Speed-based FOV widening, turbo kick, impact shake.
  • Goal celebration sequence: today it's a print() and a label scale-pop. Wants an explosion, team-tinted screen flash, camera cut, slow-mo, title card. HUDController's ResultOverlay animation is a reasonable template.
  • Local lighting / LightmapGI bake — two directional lights and low ambient, no local lights anywhere. arena_deck.gdshader's hull_fill uniform is explicitly a "stand-in for bounce light", i.e. the shader is compensating for lighting that isn't there. The arena is fully static, so a bake is viable; retire hull_fill afterwards.
  • Dress arena_03 — its Decoration node is empty, while arena_02 has stations, debris, a planet and volumetric dust.
  • Custom font + a real Theme resource for the HUD. The procedural instruments are well-engineered, but ThemeDB.fallback_font at 10-13 px reads as a debug overlay.
  • Post-processing beyond glow: DoF, motion blur, vignette, chromatic aberration on turbo.

Resolved — trained-bot compatibility (2026-08-05 retrain-from-scratch reset)

The four items below all took their architecturally-correct form instead of their zero-risk form, since Game/bots/promoted/*.json are being retrained from scratch anyway (those two checkpoints are left in place and are expected to go stale, not migrated). Scoped up further mid-implementation to a genuine 5v5 ceiling with a proportionally resized arena, since the observation-space plumbing is the expensive part to redo twice.

  • Per-tick drag (ship.gd) — delta-scaled via _tick_scaled(k, state.step), invariant to physics_ticks_per_second.
  • Goal aperture — real navigable hole cut into each end wall's collision (ArenaBoundary._build_end_wall_colliders), sized to the actual scoring sensor and correct for both FLOOR and ELEVATED goal modes.
  • Collider bake — done alongside the geometry changes above (see Performance).
  • Beyond 1v1ShipObservations now takes padded teammate/opponent arrays (MAX_TEAMMATES=4, MAX_OPPONENTS=5, SIZE=83), ordered by a new persistent Ship.spawn_index so slots never reorder mid-match. training_mode.gd/match_mode.gd gained a team_size export (default 1, so existing 1v1 behaviour is unchanged) and the arena was resized 1.5x to fit 5v5. This pass is plumbing only: no 2v2+ curriculum, no team-play reward design, and no match-mode UI to pick team size — those are still open work.

Multiplayer (long term)

  • RemoteShipController extends ShipController — feeds replicated ShipActions from a network peer into the local ship simulation.
  • Networked GameMode subclass: per-peer ship spawning (MultiplayerSpawner or custom), authoritative server for ball/score.
  • C# backend / online servers per README roadmap (not started).
  • Possible v0.2 split-screen: spawn one ship_camera_rig + viewport per local player (camera is already outside the ship scene to allow this).