Berlin Tech Meetup: The Future of Relational Foundation Models, Systems, and Real-World Applications

Register now:
PyG/Use Case11 min read

Player Churn: Social + Behavioral Graph for Gaming

Mobile games lose 75% of players within 3 days. Players with active friends stay 3x longer. Here is how to build a GNN that combines social connections with behavioral patterns to predict and prevent churn.

PyTorch Geometric

TL;DR

  • 1Gaming churn is fundamentally social. Players with active friends, guild members, or competitive rivals stay 3x longer. The social graph is the strongest retention predictor.
  • 2GATConv on a heterogeneous player-guild-match graph captures social anchoring, progression patterns, and spending behavior in a unified model.
  • 3On RelBench benchmarks, GNNs achieve 75.83 AUROC vs 62.44 for flat-table LightGBM. Social graph signals account for most of the improvement.
  • 4The PyG model is ~35 lines, but production gaming churn systems need real-time event ingestion, LiveOps integration, and intervention automation.
  • 5KumoRFM predicts player churn with one PQL query (76.71 AUROC zero-shot), handling social graphs and high-frequency behavioral data automatically.

The business problem

Mobile games lose 75% of players within the first 3 days and 90% within 30 days. For a game generating $100M annually, every 1% improvement in Day-30 retention is worth $5-10M in incremental revenue. The challenge: identifying players at risk of churning before they disengage, while there is still time to intervene with targeted offers, social features, or content recommendations.

Traditional churn models use individual player metrics: sessions per week, levels completed, in-app purchases. They miss the social context that is the strongest predictor of retention. A player whose guild is thriving has fundamentally different churn risk than one whose friends have all gone silent, even if their individual metrics are identical.

Why flat ML fails

  • No social anchoring: Players with 5+ active friends churn at 1/3 the rate of solo players. Flat models reduce this to “friend_count = 5”, losing the activity and engagement patterns of those friends.
  • No contagion modeling: Churn is contagious in gaming. When a guild leader quits, members follow within days. Flat models cannot propagate this risk signal.
  • Progression context: Being stuck at level 20 means something different in a game where most players quit at level 18 vs one where they quit at level 50. The player graph provides this context.
  • Spending patterns: A whale (high spender) whose co-players are churning may be about to stop spending. The social graph signals spending risk before individual spending changes.

The relational schema

schema.txt
Node types:
  Player  (id, level, total_playtime, iap_spend, days_since_install)
  Guild   (id, member_count, avg_activity, founded_date)
  Match   (id, mode, duration, result, timestamp)

Edge types:
  Player --[friends_with]--> Player  (since_date)
  Player --[member_of]-->    Guild   (role, join_date)
  Player --[played_in]-->    Match   (score, kills, assists)
  Player --[co_played]-->    Player  (match_count, last_played)

Social edges (friends, guild, co-play) carry the strongest signal. Match participation edges capture behavioral patterns.

PyG architecture: GATConv on social-behavioral graph

player_churn_model.py
import torch
import torch.nn.functional as F
from torch_geometric.nn import GATConv, HeteroConv, Linear

class PlayerChurnGNN(torch.nn.Module):
    def __init__(self, hidden_dim=64, heads=4):
        super().__init__()
        self.player_lin = Linear(-1, hidden_dim)
        self.guild_lin = Linear(-1, hidden_dim)
        self.match_lin = Linear(-1, hidden_dim)

        self.conv1 = HeteroConv({
            ('player', 'friends_with', 'player'): GATConv(
                hidden_dim, hidden_dim // heads, heads=heads),
            ('player', 'member_of', 'guild'): GATConv(
                hidden_dim, hidden_dim // heads, heads=heads),
            ('player', 'played_in', 'match'): GATConv(
                hidden_dim, hidden_dim // heads, heads=heads),
            ('player', 'co_played', 'player'): GATConv(
                hidden_dim, hidden_dim // heads, heads=heads),
        }, aggr='sum')

        self.conv2 = HeteroConv({
            ('player', 'friends_with', 'player'): GATConv(
                hidden_dim, hidden_dim // heads, heads=heads),
            ('player', 'member_of', 'guild'): GATConv(
                hidden_dim, hidden_dim // heads, heads=heads),
            ('player', 'co_played', 'player'): GATConv(
                hidden_dim, hidden_dim // heads, heads=heads),
        }, aggr='sum')

        self.classifier = Linear(hidden_dim, 1)

    def forward(self, x_dict, edge_index_dict):
        x_dict['player'] = self.player_lin(x_dict['player'])
        x_dict['guild'] = self.guild_lin(x_dict['guild'])
        x_dict['match'] = self.match_lin(x_dict['match'])

        x_dict = {k: F.elu(v) for k, v in
                  self.conv1(x_dict, edge_index_dict).items()}
        x_dict = self.conv2(x_dict, edge_index_dict)

        return torch.sigmoid(
            self.classifier(x_dict['player']).squeeze(-1))

GATConv attention weights learn which social connections matter: active co-players get higher attention than dormant friends. Two hops propagate guild-level health signals.

Expected performance

  • Engagement heuristics: ~55 AUROC
  • LightGBM (flat-table): 62.44 AUROC
  • GNN (GATConv social graph): 75.83 AUROC
  • KumoRFM (zero-shot): 76.71 AUROC

Or use KumoRFM in one line

KumoRFM PQL
PREDICT is_churned FOR player
USING player, guild, match, session

One PQL query. KumoRFM constructs the social-behavioral graph, captures friend activity patterns, and outputs churn probabilities per player.

Frequently asked questions

Why is player churn different from SaaS churn?

Gaming churn is heavily social. Players with active friends stay 3x longer than solo players. Guild membership, co-play sessions, and competitive rivalries create social anchoring that SaaS products rarely match. The social graph is the strongest predictor of retention in most games.

What graph features matter most for player churn?

Social connectivity (friend count, guild activity, co-play frequency), progression signals (level velocity, achievement rate, time-to-milestones), and spending patterns (IAP frequency, virtual economy engagement). The graph combines all three into a unified representation per player.

How do you handle the temporal dynamics of gaming data?

Gaming data is high-frequency: session logs, match results, and chat messages arrive continuously. Use daily graph snapshots with temporal features (7-day, 14-day, 30-day activity windows). The GNN should see declining engagement trajectories across the social neighborhood.

Can GNNs predict churn for new players with few sessions?

Yes. New players can be embedded through the matchmaking and social graphs: who they played with, what game modes they tried, and how their early behavior compares to similar players. The graph provides context that sparse individual histories cannot.

How does KumoRFM handle gaming churn prediction?

KumoRFM takes your game database (players, sessions, matches, guilds, transactions) and predicts churn with one PQL query. It automatically constructs the social and behavioral graph, handles high-frequency temporal data, and outputs churn probabilities per player.

Learn more about graph ML

PyTorch Geometric is the open-source foundation for graph neural networks. Explore more layers, concepts, and production patterns.