Development Log

TV Broadcast Overhaul

6 April 2026broadcasttvmilitaryweather
Every broadcast scene redesigned from PowerPoint to ESPN — persistent chrome, data cards, wind compass, military video backgrounds, and 7-second rotation.

The /tv broadcast was flat. Big text on a dark gradient, 50% empty space, no sense of a live feed. Today it got the ESPN treatment.

What changed

  • Broadcast chrome on every scene — live clock (BST + UTC), zone aircraft count, scene label pill, bottom ticker bar with real-time stats, EGPK.info brand bug
  • Military scene — full-screen looping video backgrounds matched to aircraft type. C-17 footage plays for REACH callsigns, C-130 for ASCOT, coastguard helicopter for SAR. Data cards show altitude with flight level conversion, heading with compass arrow, speed, and vertical rate. "Also in zone" strip shows other military traffic
  • Movements scene — ESPN-style scoreboard with inbound vs outbound count header, flight cards with type/operator/altitude/speed, zone aircraft chips at the bottom
  • Weather scene — 3-column layout with active runway, animated wind compass SVG with directional arrow, glass condition cards (visibility, temp, QNH, cloud, flight category), raw METAR bar
  • Standby scene — animated radar sweep, METAR conditions strip
  • 7-second rotation — scenes cycle every 7 seconds instead of 22. Military holds 45 seconds, rare 30 seconds

Technical Details

Director fix

The scene switching had a stale closure bug. The useEffect in DirectorClient captured scene and holdFor from initial state and never updated them, so every poll compared against 'standby' and used a 15-second interval regardless of what the API returned. Fixed by switching to useRef for both values.

The server-side state API depended entirely on Redis for tracking lastScene and rotationIndex. If Redis hiccupped, the director made the same decision every poll (always index 0, always lastScene='standby'). Added a client ?last= query param as fallback and time-based rotation index derivation from wall clock.

Video backgrounds

Three background videos served from /tv/bg/ as static assets. The MilitaryVideoBackground client component handles autoplay in iframe context. A pickVideo() function maps type codes (C17, C130, S92) and callsign prefixes (RCH, ASCOT, RESCUE) to the correct video file.

Empty data rule

New rule: if data is null or empty, don't render the card. No more "-- kt" or "-- fpm" cluttering the screen. Every data card conditionally renders only when it has real data to show.