Skip to main content
summer-parties is a skill from the Summer skill library: a guide your AI agent reads when the task matches, so it builds the good version on the first try. Let a Summer party play together: the leader presses Play, members follow into the same match. Hosted only.

When your agent uses it

  • Friends in a Summer party should land in the same multiplayer match: party play, play with friends, squad up
  • Adding invite-friends and party buttons, a party roster or ready checks to a Summer game’s menu
  • A party join fails with party_member_offline, party_not_searching or capability_unavailable

Install

summer setup installs every skill for your agent. To add only this one:
Swap claude-code for your agent, such as codex or cursor. See Skills for every option.

The skill

Overview

A Summer party belongs to the player’s Summer account, not to your game. The Summer app creates parties, sends invites, kicks, transfers leadership and runs party chat. Your game sees a read-only view through Summer.client.party:
  • who is in the party, who leads, and which members have this game open;
  • small text data your game shares with the party;
  • whether the leader started a search in one of your queues.
To bring the party into a match, the leader joins SummerJoinTarget.party_queue(queue). Every other member joins the same target when search_started fires. Summer puts them all in one match, each with their own Session. The match itself is ordinary: the authority sees normal join Commands and Sessions. Hosted only. is_available() is false and every call fails with capability_unavailable:
  • in Local Play and editor runs;
  • for guests;
  • for accounts the platform keeps out of social features (age_restricted, under 13);
  • in Summer apps without the player.party@1 capability.
Outside a party, or when parties are unavailable, getters are empty and is_in_party() is false. So the same Play button works everywhere: no party means an ordinary SummerJoinTarget.queue(...) join. Build that path first. This skill extends the Courtyard game from multiplayer-project (network/game.gd as Game, client/main.gd with command()).

Steps

1. Join from a Play button, not from _ready

A party member must not join on their own the moment the game starts. Move the join out of client/main.gd’s _ready into enter(target), and keep every signal connection from multiplayer-movement and multiplayer-state:
Move the Local Play bot hook from multiplayer-testing into enter(), after the joined line.

2. Add the party node

client/party.gd, added as a child Party of Main in client/main.tscn. It is client-only: authority scenes never touch Summer.client.
Connect roster_changed to a Label or ItemList, and status to a status line. Show the buttons by state:

3. Share choices with party data

Party data is plain text that your game reads from every member’s copy of the party. Use it for lobby-style choices before the match starts:
  • Leader’s choices (map, mode): party.set_data(key, value), read with party.get_data(key). Only the leader can write it; a member gets not_party_leader.
  • Each member’s own choices (ready, character): party.set_member_data(key, value), read with member.get_data(key).
Limits: Values pass the Summer chat text filter, so text_not_allowed is possible. Writes return SummerOperation. A conflict is retried once by the engine, then fails with retryable party_version_conflict. React to data_changed(key) and member_data_changed(member, key), or just re-render on changed. Party data is a lobby convenience, not game state. Once the match starts, the authority owns everything (multiplayer-state). It never sees party data; send choices that matter in your join Command and validate them there.

4. Handle join failures

enter() returns false with the code in the warning. For a party join: A member can follow only while the leader’s search is running: from search_started until search_ended.

5. Test

Local Play cannot create a party, so is_available() is false and each client joins solo from _ready. Test that path locally, then the party path on Summer staging with real accounts.

Checklist

  • Local Play: Summer.client.party.is_available() is false, Play joins through the plain queue, and no script errors appear.
  • Invite and Party buttons are hidden when is_available() is false.
  • A member’s Play button doesn’t join on its own.
  • Hosted: the leader presses Play, and every member with the game open lands in the same match.
  • A member who closes the game makes the leader’s Play fail with party_member_offline, and the message names who is missing.
  • Ready and leader choices appear on every member’s screen.

Common mistakes

See also

  • summer-matchmaking: queues, sizes, teams and the accept prompt
  • summer-friends: friends list, profiles and messages
  • multiplayer-project: the client entry scene this extends
  • multiplayer-testing: Local Play, and what needs staging

From a shell

No Summer MCP tools in this session? Run each one as a command; when summer --version is missing or below 4.0, use npx -y summer-engine@latest in place of summer. Fields are flags in kebab-case (--scene-path res://main.tscn) or one --input '<json>', and summer ops describe <op> prints the exact input. The summer-cli skill has the rest.
  • multiplayer: Start here for Summer multiplayer: how authority, clients, Worlds and Sessions fit, and what comes next.
  • multiplayer-project: Set up a Summer multiplayer project: entry scenes, World and queue files, joining, a first Local Play.
  • multiplayer-testing: Test a Summer multiplayer game with Local Play: several players, bad network, bots, a passing run.
  • summer-matchmaking: Get players into matches with Summer matchmaking: queues, teams, accept prompts, join progress and failures.
  • summer-friends: Summer friends in a game: a consented friends list, profile and chat screens, direct messages. Hosted only.
  • summer-world-chat: Add match chat to a Summer game: one World channel shared by everyone in the match. Hosted only.

Source: library/skills/summer-parties/SKILL.md, rendered from summer-engine@4.3.0 on npm.