Groups & Collaboration
Groups are real-time, multi-peer communication channels. They enable features like multiplayer games, live quizzes, collaborative editing, and group chat.
How groups work
Groups use a host-relayed model. The peer that creates a group acts as the hub. Every member opens a long-lived bidirectional stream to the host, and the host relays messages between members.
Member A <--stream--> Host <--stream--> Member B
|
(fan-out relay)
This model works naturally because the host already serves the site, stores data, and knows its visitors.
Group types
| Type | Lifecycle | Visibility | Use case |
|---|---|---|---|
| Ephemeral | Auto-dissolves when activity ends | Activity-scoped | Games, quizzes |
| Persistent | Exists until explicitly closed | Ongoing | Study groups, teams |
| Open | Any peer can join | Listed in UI | Community chat |
| Invite-only | Requires invitation | Private | Private projects |
Creating a group
Groups are created by the host peer, typically through a template's UI. The group is stored in the host's SQLite database and made available to visitors.
Joining a group
Members join by opening a stream to the host on the /goop/group/1.0.0 protocol. The join flow is:
- Member sends
{"type":"join","group":"<group-id>"}. - Host validates and adds the member.
- Host sends a
welcomemessage with the current member list and state. - Host broadcasts an updated
memberslist to all other members.
Message types
| Type | Direction | Purpose |
|---|---|---|
join |
Member to Host | Request to join a group |
welcome |
Host to Member | Confirmation with current state |
members |
Host to Members | Updated member list |
msg |
Both directions | Application message (chat, game move) |
state |
Host to Member | Full state sync (for reconnection) |
leave |
Member to Host | Member leaving |
close |
Host to Members | Group is being closed |
error |
Host to Member | Error response |
JavaScript API
Templates interact with groups through the Goop.group API:
// List available groups
const groups = await Goop.data.query("_groups");
// Join a group
Goop.group.join("chess-42", function(msg) {
console.log("Received:", msg);
});
// Send a message
Goop.group.send({ move: "e2e4" });
// Leave the group
Goop.group.leave();
Use cases
Multiplayer game
- Host creates an ephemeral group for a chess match.
- Opponent joins via the game UI.
- Moves are exchanged in real time through the group channel.
- Move history is stored in the host's database.
- When the game ends, the group dissolves but the history persists.
Live quiz
- Teacher creates an open group for a quiz session.
- Students join the group.
- Timer synchronization and leaderboard updates flow through the group.
- Answers are stored in the teacher's database for grading.
Study group
- Host creates a persistent group.
- Members join for real-time discussion.
- Shared notes and resources are stored in the host's database.
- The group persists across sessions until the host closes it.
Interaction with other protocols
| Task | Protocol |
|---|---|
| Serve the UI | /goop/site/1.0.0 |
| Store persistent data | /goop/data/1.0.0 |
| Real-time messaging | /goop/group/1.0.0 |
| Discover groups | Query _groups via /goop/data/1.0.0 |