Skip to content

Release: proximity voice rework + server fixes - #97

Merged
grishaLR merged 4 commits into
mainfrom
staging
Oct 26, 2026
Merged

grishaLR merged 4 commits into
mainfrom
staging

Conversation

@grishaLR

@grishaLR grishaLR commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Releases staging to production: proto town's voice rework (#96) and two server fixes.

Proto town voice, Gather-style (#96)

Voice in town now uses one LiveKit room per scene. The server decides who's in your conversation, and each client grants and subscribes to audio and video only within it. Walking up to people, away, and back never reconnects anything.

Fixes what we hit in testing:

  • Third person in a call couldn't be heard. Their mic was being switched off by a roster update that arrived mid-connect.
  • Walking away and back from a 1:1 left the pair unable to reconnect without leaving town.
  • New conversations sometimes came up silent. Each one used a fresh browser audio engine that the browser kept paused.
  • Leaving town could crash the page with Cannot read properties of null (reading 'gc') (PROTOIMSG-WEB-1E).

New in town:

  • Join audio, one click per visit (remembered after that), plus Leave audio.
  • A real connection status (Connecting / Audio on / Reconnecting / Couldn't connect) with a Reconnect button.
  • A clearer "tap to hear" prompt when the browser blocks sound.
  • Stay together: stay linked at any distance, only while both people choose it.
  • Inside a house, everyone there is one conversation, wherever they stand.
  • Wider range: connect at 4 tiles, drop past 6, with a 3s grace period.
  • Credits for the tiles, art and rpg.actor sprites, in the town info dialog.
  • A tip linking to rpg.actor when you don't have a sprite yet.

Safety:

  • Others in a scene's room see only anonymous IDs. Hearing or seeing anyone takes their grant, which follows the server's roster.
  • If anyone who knew your voice ID loses sight of you (a block, friends-of-friends mode, a lapsed join pass), you get a fresh ID.

Resilience:

  • A dropped connection keeps your voice spot for 10s, so a quick reconnect resumes the call.
  • The server checks every 5s that the right people are connected. It removes strangers and re-sends a token to anyone who never connected.

Server fixes

  • Duplicate-key error syncing buddy lists (PROTOIMSG-SERVER-E). The WebSocket handler and the Jetstream consumer could sync the same list at once. Syncs are now queued per owner and take a Postgres advisory lock. (3fade64)
  • Staging errors were tagged production in Sentry. A new optional SENTRY_ENVIRONMENT now overrides NODE_ENV, and it's set to staging in fly.staging.toml. (2ccf942)

After release

  • Tabs left open from before the release have no town voice until they reload. They fail safely.
  • Town voice connection failures now reach Sentry, tagged area: town-voice. Watch these to decide whether LiveKit needs a TURN fallback; it has none configured today.

Testing

  • Server: 268 tests pass. Web: 40 tests pass. Typecheck and lint are clean.
  • Not yet tested with real people. Worth a 3-person session on staging that includes walking away and back, and a block mid-conversation.

🤖 Generated with Claude Code

grishaLR and others added 4 commits October 26, 2026 18:27
The WS sync_community handler and the Jetstream consumer can sync the
same buddy list concurrently. The second DELETE can't see rows the first
just inserted, so its INSERT hit buddy_members_pkey (PROTOIMSG-SERVER-E).

Queue syncs per owner in-process so a burst (many tabs, reconnects) holds
one pool connection at a time, and take a transaction-scoped advisory
lock so syncs on different machines can't interleave.

Fixes PROTOIMSG-SERVER-E

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Staging runs with NODE_ENV=production, so its Sentry events were tagged
production. Add an optional SENTRY_ENVIRONMENT override (falls back to
NODE_ENV) and set it to staging in fly.staging.toml.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Proximity voice used to give every conversation its own LiveKit room, so each
split, merge or walk-away-and-back rebuilt the connection — and a third person
or a returning one often ended up silent until they left town.

Now everyone who joins audio in a scene shares one LiveKit room for the visit;
the server only decides who is in your conversation, and each client grants and
subscribes to its conversation's tracks alone. Nothing reconnects as you move.

- server: per-scene voice room + roster (town_voice_room / town_proximity),
  10s parked identity so a WS drop resumes, reconcile watchdog that evicts
  strangers and re-issues tokens (capped), fresh identity whenever someone who
  knew yours loses sight of you (block, friends-of-friends, lapsed pass)
- proximity: 4/6-tile radii, 3s link grace, "stay together" (both must opt in),
  whole-house conversation inside homes
- web: shared unlocked AudioContext, real connection status, Join/Leave audio,
  Reconnect, louder tap-to-hear, Stay together, Sentry reporting; mic only sent
  while someone can hear it, and released otherwise
- fix the "reading 'gc'" crash leaving town (textures freed before Pixi app)
- credits for the tiles, art and rpg.actor sprites; tip linking to rpg.actor
  when you have no sprite yet
- strings in all locales

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
feat(town): scene-wide voice rooms, Gather-style
@vercel

vercel Bot commented Oct 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
protoimsg Ignored Ignored Oct 26, 2026 10:31pm UTC

@grishaLR grishaLR changed the title Staging Release: proximity voice rework + server fixes Oct 26, 2026
@grishaLR
grishaLR merged commit 1c2d21d into main Oct 26, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant