Back to Devlog
    v0.9.7
    AudioFebruary 24, 2026Release notes

    Three Playlists and a UUID

    Team gametypes, the soundtrack streamed out of a PK3 with menu/game/endgame playlists, freefly spectator, and a player profile with a UUID v4.

    Soundtrack, Finally Described

    JSON playlists with name, loop, shuffle and tracks. Three ship:

    text
    menu      looping
    game      shuffled
    endgame   looping

    Streamed from washoi_soundtrack.pk3 via PK3Loader.getFileAsURL() Blob URLs, switching on audio unlock, JoinAccept, MatchPhase.PostGame and disconnect, with fadingOutMusic tracking and a loadingRequestId concurrency lock.

    Documented in docs/research/MUSIC_SYSTEM.md.

    Team Gametypes

    GametypeController supports TeamDeathmatch and Duel against Deathmatch. MatchState tracks team scores with assignTeamBalance; Duel enforces 1v1 and sends the excess to spectator. The headless CLI parses --map and --gametype "to circumvent NPM parameter stripping" — a workaround that describes npm more accurately than npm would.

    Freefly Spectator

    WASD and mouse, Shift for a 3x boost, active on connect before you have joined. Quake-style vertical flight — Space up, C or Ctrl down.

    The Profile

    PlayerProfile.ts with a UUID v4, keybindings and preferences — sensitivity, FOV, crosshair, UI scale. Stored under shag_player_profile in localStorage, auto-migrating shag_keybindings. Names capped at 32 characters via a name command. BotNames.ts supplies 40 themed names with getNextBotName() de-duplicating.

    The Fix Worth Reading

    text
    Slide state (camera tilt, speed decay) was being killed at every server
    reconciliation (~60Hz), preventing camera animation from ever completing

    MIN_WALK_NORMAL went 0.75 → 0.7, because cos(45°) ≈ 0.707 > 0.7. Someone worked out what the constant meant and corrected it.

    Known Issues: none stated.