The core multiplayer infrastructure landed in one large commit: 2,188 lines of new backend code across 17 files.
Persistent Private Rooms
Persistent private rooms replaced the session-only room concept. Prisma schema gained Room, RoomMember, and RoomInvite models backed by SQLite. RoomManager was largely rewritten to be DB-backed — creating, fetching, and soft-deleting rooms, tracking membership with roles (owner, moderator, member), and enforcing ownership rules for destructive actions like kick and delete. The previous in-memory mainRoom was preserved as a special case so world chat continued to work unchanged.
Invite System (v1)
createInvite generates a CUID token stored in RoomInvite with a default 7-day expiry. acceptInvite validates the token, checks it hasn't been used and hasn't expired, upserts a RoomMember row, then marks the invite accepted. REST endpoints and socket events both backed by the same invite logic.
Translator Mode
A TranslationService was introduced that fans out AI-translated versions of messages to users who have enabled translator mode. Each user can set their target language; the service calls OpenRouter to translate and emits translated-message events per-user. UserManager gained setUserTranslatorLanguage to persist the preference.
Member Management
handleKickUser, handleSetWhitelist, handlePromoteMember socket events round out room governance — all gated on the caller being the room owner or a moderator.
On the frontend, RoomSidebar was built from scratch as the primary room management surface — listing rooms, handling join/leave, exposing invite flows, and showing translator mode controls.
Why it matters
This commit is the architectural backbone of the product. Everything that came after — E2EE, branding, voice, neurons — builds on top of the room/member/invite model introduced here.