Quick answer: A friend system maintains a shared relationship between two players plus presence that must stay in sync across clients and platforms. Most friend bugs are desyncs, one side sees a friend the other does not, a request stuck pending, or presence showing offline when a player is online. Capture each player's view of the friend state and the relevant request and presence data so you can find which side disagrees.

Friend systems feel like a small social convenience until they break, and then they undermine the whole reason players came to play together. A request that never arrives, a friend who is always shown offline, a friends list that differs between two people who are clearly friends, these are the bugs that quietly erode a community. Under the hood, a friendship is a shared relationship that has to stay consistent across two clients, your server, and often two different platforms, while presence layers a constantly changing online status on top. Almost every friend bug is a desync between these views. This post is about capturing friend state so you can see which view is wrong.

Friendship is a shared, two-sided relationship

A friendship is not a property of one player, it is an edge in a social graph connecting two of them, and both ends must agree. Player A has player B in their friends list, player B has player A, and your server holds the authoritative relationship. When these three views diverge, you get the classic friend bugs, A sees B as a friend while B does not see A, or both think they are friends but the server has no record. From one player's screen you cannot tell which view is correct, only that something disagrees.

This is why friend reports need both sides, just like trades. A player reporting that a friend disappeared from their list is describing a divergence, and the fix depends entirely on whether the friend is still present on the other side and on the server. Capturing one side gives you a symptom, capturing the relationship across both players and the server gives you the diagnosis. The unit of debugging is the relationship, not the player, and the report should reflect that by carrying enough to reconstruct all three views of the edge.

Capture friend state and request state

For any friend report, capture the player's own user id and the id of the other party involved, plus the state of the relationship as this client sees it, friends, pending outgoing, pending incoming, blocked, or none. The state name is what you compare against the server and the other client to locate the desync. A request that the sender sees as pending outgoing but the recipient never received as pending incoming is a stuck request, and only capturing both states reveals it.

Capture the request timeline too, when the request was sent, when it was accepted or declined, and through which entry point, because friend requests can originate from many places, a recent players list, a profile, an invite link, or a platform import. Different entry points exercise different code paths, so knowing the origin narrows the search. Include the platform of each player as well, since cross-platform friendships add a translation layer between platform identities and your internal ids, and a surprising share of friend bugs live exactly in that translation. With these fields, a friend report points at a specific edge and a specific transition rather than a vague complaint.

Presence sync is its own problem

Presence, the online or offline status and what a player is currently doing, is a separate and harder subsystem than the friend relationship itself. Presence changes constantly, it is often pushed through a different channel than friend data, and it has to fan out to everyone who has that player as a friend. The common bug is presence showing stale, a player is online but their friends see them offline, or they appear stuck in a game they left. These are timing and propagation bugs, not relationship bugs, and they need different evidence.

Capture the presence state the reporting player saw for their friend, the timestamp of that presence, and ideally the friend's actual presence state at report time so you can measure the staleness. A presence that is several minutes behind reality points at a propagation or subscription bug, while presence that is simply wrong points at a state bug. Cross-platform presence is especially fragile because each platform reports availability differently, so capturing the platform on both ends again pays off. Separating presence evidence from relationship evidence keeps you from chasing a friends-list bug when the real problem is a stale status update.

Setting it up with Bugnet

With Bugnet, the in-game report button captures your custom fields automatically, so a friend report arrives carrying the reporting player's id, the other party's id, the relationship state, the request timeline and origin, the presence state with its timestamp, and the platform on both ends, all without the player describing it. They just say a friend went missing, and the report already holds both their view of the edge and the data needed to compare it against the server. If a social action triggers a crash, Bugnet captures the stack trace with the same friend context attached.

Because Bugnet folds duplicate reports into one grouped issue with an occurrence count, a systemic desync, say requests from a specific platform import path failing to deliver, surfaces as a rising count on a single issue rather than scattered complaints. Filter the dashboard by your platform and request-origin custom fields to isolate cross-platform or specific-entry-point failures, and sort by occurrence to find the social paths breaking most often. Player attributes let you see whether desyncs cluster around a platform or a client version, turning fuzzy social complaints into a targeted list of edges and transitions to fix.

Protecting the social fabric

Friend systems are load-bearing for retention, because the players most likely to stay are the ones connected to others, and every broken request or invisible friend is a small fracture in that connection. Make both-sides capture and presence state standard on every social report so that when a friendship looks broken, your first move is comparing the three views rather than guessing. Resolving these quickly and visibly tells players the social side of your game is cared for, which matters more than the bug count suggests.

Watch occurrence counts for clusters around platform boundaries and client versions, because those are where friend systems most often rot, and a desync that grows after a platform update is an urgent signal. With friend state, request state, and presence captured on every report, you can tell relationship bugs from presence bugs, cross-platform translation bugs from internal ones, and fix the source. A healthy social graph is invisible when it works, and keeping it that way means being able to see exactly which edge disagrees the moment a player notices.

Make social state observable

Aim for a friend system where any relationship and its presence can be inspected from either end using the player ids involved, and where every report inherits that observability automatically. When the three views of an edge are always available in a report, triage on social bugs becomes a quick comparison rather than a slow reconstruction, and you stop relying on players to describe state they can only half see. That observability is what lets you respond to social complaints with confidence instead of asking the player to try logging out and back in.

As your game grows across platforms and adds new social entry points, recent players, profile invites, link sharing, each is a new place for the friend graph and presence to drift, and keeping both-sides state on every report means those new paths are debuggable from day one. The social layer is quietly load-bearing for how long players stay, so treating its state as something you can always observe, rather than something you reconstruct after each complaint, is what keeps the connections between your players intact as the game evolves.

Friend bugs are disagreements between two players and the server. Capture both views plus presence, and you can see which side is wrong instead of guessing.