Random Pairing with Auto Mode
Problem
You want to pair two strangers automatically — no lobby, no invite code, no client-side negotiation. Whoever is waiting should be matched with the next person to arrive.
Solution
Enter a pool with mode: "auto". The server pairs waiting members in FIFO order once groupSize clients are available and sends each a matched event carrying a new session name. Listen for that event, then call join() with the returned session. Matchmaking precedes session membership — there's no lobby to join first.
This recipe shows the ad-hoc form (the client supplies the pool config), which works in an implicit Project — ideal for local development. To move the config server-side so clients join by name, see Matchmaking as a Policy.
Code
import { StarfishClient } from "@starfish/client";
const client = new StarfishClient({ server: "ws://localhost:4000" });
await client.connect();
// When the server matches you, join the session it created.
client.pool.matched$.subscribe(async ({ session, peers }) => {
console.log("Matched with", peers.map((p) => p.id));
await client.join(session); // join the matched session
});
// Enter the pool. create: true opens it if it doesn't exist yet.
await client.pool.enter("duets", { groupSize: 2, mode: "auto", create: true });from starfish import StarfishClient, StarfishClientOptions, PoolEnterOptions
client = StarfishClient(StarfishClientOptions(server="ws://localhost:4000"))
await client.connect()
# When the server matches you, join the session it created.
async def on_match(result):
print("Matched with", [p.id for p in result.peers])
await client.join(result.session)
client.pool_matched.subscribe(on_match)
# Enter the pool. create=True opens it if it doesn't exist yet.
await client.pool_enter(PoolEnterOptions(pool="duets", group_size=2, mode="auto", create=True))Explanation
groupSizesets how many clients form one match —2for pairs, higher for groups. It is fixed when the pool is created.- The server fires the match atomically: all members of a group are removed from the pool and notified together, so there are no partial matches.
- Matched clients are not auto-joined. You receive the session name and call
join()yourself — this gives you a moment to show a "matched" screen or load assets first. create: trueopens the pool on first entry. Omittingcreate(in both SDKs) means the pool is only used if it already exists — entering a missing pool returnspool.not_found.
Variations
Attach metadata to your entry
Member metadata is opaque data carried with your pool membership — useful for filtering or for display in claim-based modes. The TypeScript SDK names it meta; the Python SDK names it attributes (both map to the wire field attributes).
await client.pool.enter("duets", {
groupSize: 2,
mode: "auto",
create: true,
meta: { skill: "intermediate", region: "eu" },
});await client.pool_enter(PoolEnterOptions(
pool="duets",
group_size=2,
mode="auto",
attributes={"skill": "intermediate", "region": "eu"},
))Only match a compatible region
Add a filter so the server only pairs you with members whose attributes match. "@self" means "the same value as my own attribute." See Attribute Filtering for details.
await client.pool.enter("duets", {
groupSize: 2,
mode: "auto",
create: true,
meta: { region: "eu" },
filter: { region: "@self" }, // only match same-region members
});await client.pool_enter(PoolEnterOptions(
pool="duets",
group_size=2,
mode="auto",
attributes={"region": "eu"},
filter={"region": "@self"}, # only match same-region members
))