spaceship/controllers
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Claude 37e2e89cd3 Stop the first play of each sound paying for its own load
Reported from the game: sounds sometimes start a bit late. The samples were
the suspect, so they were measured first - and they are clean. True digital
silence at the head of each file:

  seven of nine start on sample 1
  sfx_gas_blast    0.2ms
  sfx_black_hole   1.5ms, then a deliberate swell

The black hole's slow attack is the sound it was written to be - make_sfx.py
says it "swells across most of its length instead of decaying from the first
sample" - so there is nothing to trim without breaking it.

The delay was in the playback path, and "sometimes" was the clue:

  play() called load() every time. A cache hit after the first, but the
  FIRST play of each sound was a synchronous read and decode on the frame
  the sound was asked for. Ten sounds, ten occasional late starts.

  _pool() built its twelve AudioStreamPlayer nodes lazily, on the first
  play() call - one bigger stall, every session.

The catalog is preloaded now, so play() never touches the disk, and
Sfx.warm() builds the voices next to Music.ensure() at startup.

Case F pins the thing that was originally suspected, since make_sfx.py
regenerates these and a lazy envelope would hide the delay somewhere nobody
would look. It reads the source .wav's RIFF chunks rather than the imported
stream: these import as QOA (compress/mode=2), so AudioStreamWAV.data is not
PCM. The first version of that check was vacuous for exactly that reason and
passed at a 0.5ms threshold; it now reports "9 samples checked, worst attack
sfx_black_hole.wav at 1.5ms" and fails when tightened.

Not touched: project.godot has no [audio] section, so output_latency is at
its default. On Android that buffer is usually the dominant latency, but
lowering it risks crackle on real hardware - worth doing with someone
listening, not blind.

172/172.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
2026-09-09 11:40:28 +02:00
..
AimedFleetAbilityController.gd Aim the laser by depth, and ease the aim view 2026-09-05 09:32:42 +02:00
AimedFleetAbilityController.gd.uid #84: move 215 root files into a folder hierarchy 2026-08-21 19:44:14 +02:00
BuildController.gd Stop redrawing what only needs moving 2026-09-08 11:35:45 +02:00
BuildController.gd.uid #84: move 215 root files into a folder hierarchy 2026-08-21 19:44:14 +02:00
DashController.gd Sharpen upgrades, mark the convoy's destination, and give the world sound 2026-09-05 12:16:17 +02:00
DashController.gd.uid Resolve pending gameplay tickets 2026-09-02 13:43:56 +02:00
FireStickController.gd Improve aim assist target stickiness 2026-09-02 17:15:12 +02:00
FireStickController.gd.uid #84: move 215 root files into a folder hierarchy 2026-08-21 19:44:14 +02:00
GameController.gd Stop the first play of each sound paying for its own load 2026-09-09 11:40:28 +02:00
GameController.gd.uid #84: move 215 root files into a folder hierarchy 2026-08-21 19:44:14 +02:00
GasBombController.gd Garrison laser vessels and gas bombers, on a shared ability seam 2026-08-23 19:23:35 +02:00
GasBombController.gd.uid #84: move 215 root files into a folder hierarchy 2026-08-21 19:44:14 +02:00
LaserController.gd Sharpen upgrades, mark the convoy's destination, and give the world sound 2026-09-05 12:16:17 +02:00
LaserController.gd.uid #84: move 215 root files into a folder hierarchy 2026-08-21 19:44:14 +02:00
MouseCombatController.gd Resolve pending gameplay tickets 2026-09-02 13:43:56 +02:00
MouseCombatController.gd.uid #84: move 215 root files into a folder hierarchy 2026-08-21 19:44:14 +02:00