Skip to main content
summer-friends 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. Summer friends in a game: a consented friends list, profile and chat screens, direct messages. Hosted only.

When your agent uses it

  • Showing a friends list, who is online or which friends are playing this Summer game
  • Opening a player’s Summer profile, friends list or chat screen from inside a game
  • Reading or writing a player’s direct messages, or a friends call fails with permission_undeclared or permission_declined

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

Friendships belong to the player’s Summer account. The Summer app owns the social graph itself:
  • friend requests;
  • blocking;
  • the friends list screen;
  • profiles;
  • chat.
Your game gets two client-only facades. Summer.client.friends
  • Two screens need no consent: show_friends() and show_chat(user_id). They ask the Summer app to show its own screen over the game.
  • show_profile(user_id) is the same. The profile includes add friend, message, invite to party and report, so it is the social feature most games need.
  • With consent, it reads the list: each friend’s name, handle and whether they are offline, online, in_this_game or in_other_game. Another game is never named.
Summer.client.messages
  • Reads and sends the player’s direct messages, with a separate consent for each kind of access.
  • Prefer show_chat(user_id) unless chat is central to your game.
Reading friends or messages needs two things:
  1. The Build declares the permission in summer.build.json.
  2. The player grants it in the Summer app’s consent sheet, which your game asks for with request_access.
Declining never blocks play. A game must work without these permissions. Availability:
  • Engine release. This needs an engine release that includes SummerClientFriends. On older engines, Summer.client.friends does not exist and scripts that use it fail to parse. Check the class reference for SummerClientFriends before using this skill.
  • Hosted only. is_available() is false in Local Play and editor runs, for guests, for accounts the platform keeps out of social features (age_restricted, under 13), and in Summer apps without player.friends@1 (friends) or player.messaging@1 (messages).
  • Overlays. The screens need the Summer app to offer friends and parties; otherwise they fail with capability_unavailable or ui_unavailable.

Steps

1. Declare the permissions you use

Add a top-level permissions array to summer.build.json, next to schema and gameId. List only what the game uses; each entry is an upper bound on what you may ask for.
Unknown or duplicate entries are rejected when you publish. Without a declaration, get_access() reports undeclared, and request_access() fails at once with permission_undeclared.

2. The friends node

client/friends.gd, a child Friends of Main. In client/main.gd’s _ready(), call $Friends.start() right after Summer.initialize succeeds:
How it behaves:
  • When the list is read again. With a handler on changed, the engine re-reads the list on every change hint, after a consent decision, on refresh(), and about every 60 seconds while the game is in front. Never poll yourself.
  • Statuses. Show in_this_game friends first. unknown means presence couldn’t be read; it is not offline.
  • Rows. Key them by user_id; each read replaces the SummerFriend objects.
  • Profiles of other players. For the people in the current match, use the user ids your authority publishes (the players map in summer-world-chat, step 1) and call show_profile(user_id). Your own id fails with invalid_argument.
  • Inviting a friend into a match. Use the party invite sheet (summer-parties).

3. Direct messages (only if chat is central)

Reading a thread works the same way:
  • Read a page. Ask for social.messages.read, then messages.list_messages(user_id). Read op.messages, newest page first; pass op.next_cursor for older pages.
  • Catch up. After messages_changed, call list_messages_after(user_id, last_sequence). Today messages_changed fires only after a stream resync, so also reload when the chat screen opens.
  • Mark read. mark_read(user_id, sequence) needs social.messages.read_state.write. It marks the thread read on every device.
  • Send rules. send takes 1–4000 characters and no control characters except newline and tab. Each call is one message; the engine never sends it twice.

4. Failure codes

5. Test

Local Play has no accounts, so check the hidden path locally:
  • is_available() is false;
  • buttons are hidden;
  • there are no script errors.
Then test on Summer staging with two accounts that are friends: grant, decline and revoke access in the Summer app, and watch access_changed.

Checklist

  • The engine’s class reference lists SummerClientFriends.
  • summer.build.json declares exactly the permissions the code asks for.
  • Local Play: friends features are hidden, with no script errors.
  • Declining consent leaves the game fully playable, and the button can ask again later.
  • Hosted: a friend playing the game shows in_this_game; show_profile opens for another player in the match.
  • No polling timer: updates come from changed.

Common mistakes

See also

  • summer-parties: playing together, the invite sheet
  • summer-world-chat: chat inside a match
  • multiplayer-publish: summer.build.json and publishing a Build
  • multiplayer-testing: what Local Play can and can’t test

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-testing: Test a Summer multiplayer game with Local Play: several players, bad network, bots, a passing run.
  • summer-parties: Let a Summer party play together: the leader presses Play, members follow into the same match. 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-friends/SKILL.md, rendered from summer-engine@4.3.0 on npm.