Clash Royale Card Synergy: A Network Analysis Tutorial

Network Analysis
Data Visualization
igraph
R
A network analysis tutorial exploring card synergy in Clash Royale using Season 3 deck data.
Authors
Affiliation

Kevin Euyoque

St. Lawrence University

Ivan Ramler

St. Lawrence University

Published

April 1, 2026

Please note that these materials have not yet completed the required pedagogical and industry peer-reviews to become a published module on the SCORE Network. However, instructors are still welcome to use these materials if they are so inclined.

1 Welcome Video

If you are unfamiliar with Clash Royale, you can watch this short gameplay video for an introduction to the game:

1.1 Introduction:

Clash Royale is a real-time strategy mobile game developed by Supercell in which players build decks of eight cards and compete in one on one battles. Each card represents a troop, spell, or building with distinct mechanics and strategic roles.

Success in the game depends heavily on card combinations, as certain cards perform more effectively when used together. Because of this emphasis on synergy, Clash Royale provides a natural setting for studying relationships between elements using network analysis.

By the end of this tutorial, you will be able to:

  • explain how a card-pair dataset can be represented as a network
  • construct matrices showing pair counts, pair wins, and pair win rates
  • convert a matrix of card relationships into an edge list
  • build and visualize a weighted network using igraph
  • interpret what a card synergy network suggests about the Clash Royale meta

This module could be used as a short in-class lab that lasts about 60 minutes or part of a larger unit on network analysis and data visualization.

Technology Requirement:

This activity is designed to be completed in R using RStudio and Quarto.

Packages used in this module:

Some previous experience with data wrangling in R is helpful, but no previous experience with network analysis is required.

1.2 Data

The main dataset used in this module is cr_season3_5000decks.csv, which contains deck-level Clash Royale data from Season 3. Each row corresponds to a card appearing in a specific deck, along with whether that deck won.

We will reshape this data so that each deck becomes one row and each card becomes its own column. From there, we will calculate how often pairs of cards appear together, how often those pairs win, and their overall paired win rates.

Download Data: cr_season3_5000decks.csv

Variable Descriptions
Variable Description
id Unique identifier for each deck
card Name of the Clash Royale card appearing in the deck
winner Indicator for whether the deck won the match
Data Notes

The analysis in this module focuses on building a card-by-card relationship structure. Specifically, we want to create:

  • the number of decks containing each pair of cards
  • the number of wins for each pair
  • the paired win rate for each pair
  • a binary version of the win rate matrix
  • a filtered edge list for network construction
  • The diagonal of each matrix is removed because a card is not paired with itself in this analysis.

1.3 Goal of this module

In this tutorial, we will treat Clash Royale cards as nodes in a network.

Two cards are connected by an edge if they perform well together, measured by paired win rate.

We will treat:

  • Cards -> nodes
  • Strong pair win-rates -> edges
  • Win-rate value -> edge weight

By the end, we will:

  • Build a synergy network from paired win rates
  • Learn network vocabulary (nodes, edges, weights, degree)
  • Compute centrality (who matters most)
  • Find cliques / communities (tight synergy groups)

1.4 Get started

Code
library(readr)
cr_season3_5000decks <- read_csv("cr_season3_5000decks.csv")

cards_id <- pivot_wider(data = cr_season3_5000decks, names_from = card, values_from = winner)

clash_decks <- cards_id |> mutate(across(-id, ~replace(.,!is.na(.),1))) |>
  mutate(across(-id, ~replace(.,is.na(.),0)))

# gets rid of first column
clash_deck_n <- t(as.matrix(clash_decks[,-1])) %*% as.matrix(clash_decks[,-1])


# Clash deck wins
clash_wins <- cards_id |>
  mutate(across(-id, ~ ifelse(is.na(.), 0, as.integer(.))))

clash_deck_wins <- t(as.matrix(clash_wins[, -1])) %*% as.matrix(clash_wins[, -1])


# Clash deck win rate
clash_deck_rate <- clash_deck_wins / clash_deck_n
Code
clash_deck_wins["Zap", "Hog Rider"]
[1] 233
Code
clash_deck_n["Zap", "Hog Rider"]
[1] 430
Code
clash_deck_rate["Zap", "Hog Rider"]
[1] 0.5418605

2 Network Representation

To represent Clash Royale synergy as a network, we will model the data as a graph.

IGRAPH ad35bea UN-- 69 1572 -- 
+ attr: name (v/c), decks (e/n), wins (e/n), winrate (e/n)
+ edges from ad35bea (vertex names):
 [1] Hog Rider     --Zap Valkyrie      --Zap Giant Skeleton--Zap
 [4] Baby Dragon   --Zap Mini P.E.K.K.A--Zap Witch         --Zap
 [7] Musketeer     --Zap Balloon       --Zap Arrows        --Zap
[10] Skeleton Army --Zap Electro Wizard--Zap Mega Knight   --Zap
[13] Lumberjack    --Zap Executioner   --Zap P.E.K.K.A     --Zap
[16] Royal Giant   --Zap Goblin Barrel --Zap Inferno Tower --Zap
[19] Sparky        --Zap Minions       --Zap Lightning     --Zap
[22] Mega Minion   --Zap Goblin Gang   --Zap Wizard        --Zap
+ ... omitted several edges

In this we see there are 69 cards that pass the greater than 50 decks filter

  • 69 nodes

There is a total of 1572 card pair connections

  • 1572 edges

2.1 Nodes

A node represents one Clash Royale card.

Examples of nodes could be:

  • Hog Rider
  • Fireball
  • Miner
  • Ice Spirit

In the network, each card appears once as a node.

2.2 Edges

An edge represents a connection between two nodes (two cards).

In this module, an edge means:

The two cards are commonly used together and they perform well together based on paired win rate

So if two cards have strong synergy, they will be connected.

2.3 Edge weights

Edges can also have a weight, which measures how strong the connection is.

For Clash Royale synergy, the edge weight will be the paired win rate for that card pair.

Interpretation:

  • Higher paired win rate → stronger connection
  • Lower paired win rate → weaker connection

2.4 Why use a network?

A network is useful here because it lets us study:

  • which cards connect to many others
  • which groups of cards form groups of synergy
  • how the meta might be structured through relationships, not just individual win rates

There are over 37,235,730,424,788 possible unique deck combinations

(Pick 16 cards from the dataset for which we will use, go back to adjacency matrix, only 16 nodes and only have edges for nodes with higher than 50% win rate)

2.5 Centrality of Cards

Up to this point, we have visualized relationships between cards. However, we can go further by measuring how important each card is within the network.

This is done using centrality, which measures how connected or influential a node is in a network.

2.5.1 Degree Centrality

The simplest measure is degree centrality, which counts how many connections each card has.

  • High degree → card appears with many other cards
  • Low degree → card appears with fewer pairings

Cards with high degree centrality are often:

  • flexible across many strategies
  • commonly used in decks
  • important to the overall meta

2.6 Try it yourself

Either choose 16 cards yourself or choose to use the randomizer code

Code
all_cards <- unique(cr_season3_5000decks$card)

random_16 <- sample(all_cards, 16)

random_16
 [1] "P.E.K.K.A"       "Sparky"          "Electro Dragon"  "Earthquake"     
 [5] "Dark Prince"     "Knight"          "Electro Wizard"  "Freeze"         
 [9] "Skeleton Barrel" "Wizard"          "X-Bow"           "Furnace"        
[13] "Minion Horde"    "Fire Spirits"    "Royal Recruits"  "Fireball"       

This bit of code allows for a random sample of any 16 cards within the dataset

Code
pair_data_random <- pair_data |>
  filter(card1 %in% random_16, card2 %in% random_16)
  
network_random <- graph_from_data_frame(pair_data_random, directed = FALSE)
  
plot(network_random,
       layout = layout_with_fr(network_random),
       vertex.size = 8,
       vertex.label.cex = 0.8,
       edge.width = E(network_random)$winrate * 8)

2.7 Conclusion

In this module, we explored how network analysis can be used to understand relationships between cards in Clash Royale.

Starting from raw deck data, we transformed the dataset into pairwise matrices that captured how often cards appear together and how successful those pairings are. By converting this information into a network, we were able to visualize and analyze card synergy in a more meaningful way.

Through this process, we observed that:

  • some cards are highly connected and appear across many strategies
  • certain card pairings consistently perform well together
  • groups of cards form clusters that reflect common deck archetypes

We also extended this analysis by generating random sets of cards and comparing how their network structure changes, reinforcing how different combinations influence overall performance.

Finally, by introducing centrality, we identified which cards play a more influential role within the network, helping us better understand the structure of the game’s meta.

Overall, this module demonstrates how network analysis can reveal patterns and relationships in complex systems where interactions between elements are more important than the elements themselves.