Assignment 4: Network Visualization with Board Game Data¶
Overview¶
BoardGameGeek (BGG) is the largest online database and community for board games, with detailed information on over 100,000 games. For this assignment, you will explore the world of modern board gaming through network analysis and visualization.
Your guiding question:
What can network analysis reveal about how board game designers collaborate and how game mechanics relate to one another?
Import Data¶
import pandas as pd
import networkx as nx
import numpy as np
import altair as alt
alt.renderers.enable("mimetype")
from pyvis.network import Network
import itertools
games = pd.read_csv('data/games.csv')
game_designers = pd.read_csv('data/game_designers.csv')
game_mechanics = pd.read_csv('data/game_mechanics.csv')
games.head()
| BGGId | Name | YearPublished | GameWeight | AvgRating | BayesAvgRating | StdDev | MinPlayers | MaxPlayers | BestPlayers | ... | Rank:thematic | Rank:partygames | Cat:Thematic | Cat:Strategy | Cat:War | Cat:Family | Cat:CGS | Cat:Abstract | Cat:Party | Cat:Childrens | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 3 | Samurai | 1998 | 2.4859 | 7.45601 | 7.23994 | 1.18227 | 2 | 4 | 3 | ... | 21926 | 21926 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 4 | Tal der Könige | 1992 | 2.6667 | 6.60006 | 5.67954 | 1.23129 | 2 | 4 | 0 | ... | 21926 | 21926 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 8 | Lords of Creation | 1993 | 2.4000 | 6.10716 | 5.56602 | 1.32872 | 2 | 5 | 0 | ... | 21926 | 21926 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 9 | El Caballero | 1998 | 3.1824 | 6.45265 | 5.92290 | 1.43335 | 2 | 4 | 3 | ... | 21926 | 21926 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 10 | Elfenland | 1998 | 2.1578 | 6.69695 | 6.47733 | 1.25365 | 2 | 6 | 4 | ... | 21926 | 21926 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
5 rows × 36 columns
Section 1: The Designer Collaboration Network¶
In this section you will construct a collaboration network and analyze its structure.
1a) Build the Network¶
Starting from game_designers.csv, build a weighted, undirected graph where designers are nodes and an edge connects two designers who co-designed at least one game. Edge weight = number of co-designed games.
- Hint: Group by
BGGIdto find games with multiple designers. For each such game, generate all pairs of co-designers usingitertools.combinations. - To keep the network manageable, filter to designers who have designed at least 5 games in the dataset before building edges.
- Report basic network statistics: number of nodes, number of edges, and average degree.
# keep only designers with 5+ games
games_per_designer = game_designers.groupby('Designer')['BGGId'].count()
prolific = games_per_designer[games_per_designer >= 5].index
filtered = game_designers[game_designers['Designer'].isin(prolific)]
# for each game, find all pairs of co-designers
edge_counts = {}
for bgid, group in filtered.groupby('BGGId'):
designers = list(group['Designer'])
if len(designers) < 2:
continue
for a, b in itertools.combinations(sorted(designers), 2):
key = (a, b)
edge_counts[key] = edge_counts.get(key, 0) + 1
# build the graph
G = nx.Graph()
G.add_nodes_from(prolific)
for (a, b), weight in edge_counts.items():
G.add_edge(a, b, weight=weight)
# report stats
print(f"Number of nodes: {G.number_of_nodes()}")
print(f"Number of edges: {G.number_of_edges()}")
avg_degree = sum(dict(G.degree()).values()) / G.number_of_nodes()
print(f"Average degree: {avg_degree:.2f}")
Number of nodes: 666 Number of edges: 727 Average degree: 2.18
1b) Centrality and Communities¶
- Calculate betweenness centrality for each designer.
- Run community detection (e.g.
greedy_modularity_communitiesfrom NetworkX). - Present a table of the top 10 designers by betweenness centrality, showing their community label and number of games designed. Who are the "bridge" designers connecting different design circles?
from networkx.algorithms.community import greedy_modularity_communities
# Betweenness centrality (uses edge weights)
bc = nx.betweenness_centrality(G, weight='weight')
# Community detection
communities = greedy_modularity_communities(G)
# Map each designer to a community ID
community_map = {}
for i, community in enumerate(communities):
for designer in community:
community_map[designer] = i
# Game count per designer
game_counts = filtered.groupby('Designer')['BGGId'].count().to_dict()
# Build summary DataFrame
summary = pd.DataFrame({
'Designer': list(bc.keys()),
'Betweenness': list(bc.values()),
'Community': [community_map.get(d, -1) for d in bc.keys()],
'Games Designed': [game_counts.get(d, 0) for d in bc.keys()]
})
# Top 10 by betweenness centrality
top10 = summary.sort_values('Betweenness', ascending=False).head(10)
print(top10.to_string(index=False))
Designer Betweenness Community Games Designed
Rob Daviau 0.073477 0 51
Reiner Knizia 0.049978 1 261
Mike Elliott 0.035713 0 51
Bruno Faidutti 0.033331 0 61
Eric M. Lang 0.031917 1 61
Mike Selinker 0.027298 0 27
Klaus-Jürgen Wrede 0.026059 2 42
Jonathan Tweet 0.023678 0 8
Dávid Turczi 0.022722 3 21
Devin Low 0.021930 5 5
# Explore top 10 designers: their games and collaborators
top10_names = top10['Designer'].tolist()
for name in top10_names:
print(f"\n{'='*50}")
print(f"DESIGNER: {name}")
print(f"{'='*50}")
print("\n-- Games --")
ids = game_designers[game_designers['Designer'] == name]['BGGId'].values
designer_game_list = games[games['BGGId'].isin(ids)][['Name', 'YearPublished', 'AvgRating', 'GameWeight']].sort_values('AvgRating', ascending=False)
print(designer_game_list.to_string(index=False))
print("\n-- Collaborators --")
neighbors = list(G.neighbors(name))
if neighbors:
weights = [G[name][n]['weight'] for n in neighbors]
collabs = pd.DataFrame({'Collaborator': neighbors, 'Shared Games': weights}).sort_values('Shared Games', ascending=False)
print(collabs.to_string(index=False))
else:
print('No collaborators in filtered network')
==================================================
DESIGNER: Rob Daviau
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Pandemic Legacy: Season 0 2020 8.64327 3.0127
Pandemic Legacy: Season 1 2015 8.59678 2.8336
Unmatched Game System 2019 8.46701 2.0000
Unmatched: Little Red Riding Hood vs. Beowulf 2020 8.45761 2.0000
Unmatched: Cobble & Fog 2020 8.25578 2.0270
Unmatched: Jurassic Park – InGen vs Raptors 2020 8.21107 1.8750
Cthulhu: Death May Die 2019 8.14790 2.3782
Unmatched: Robin Hood vs. Bigfoot 2019 8.13702 2.0000
Pandemic Legacy: Season 2 2017 8.11266 3.2389
Unmatched: Battle of Legends, Volume One 2019 7.94522 1.9022
Unmatched: Buffy the Vampire Slayer 2020 7.89510 1.8750
Betrayal Legacy 2018 7.76612 2.8382
Heroscape Master Set: Swarm of the Marro 2007 7.62578 2.2544
Star Wars: The Queen's Gambit 2000 7.56360 2.4873
Heroscape Master Set: Battle for the Underdark 2010 7.49587 2.4681
Heroscape Master Set: Rise of the Valkyrie 2004 7.43488 2.2909
Risk Legacy 2011 7.40980 2.5935
Downforce 2017 7.34177 1.7473
Ultimate Werewolf Legacy 2018 7.12579 2.4000
Betrayal at House on the Hill 2004 7.05841 2.3860
Machi Koro: Legacy 2019 7.05334 2.0357
Stop Thief! 2017 7.01873 1.5294
Heroscape Marvel: The Conflict Begins 2007 7.01470 2.0620
Star Wars: Epic Duels 2002 7.00674 1.7794
ShipShape 2019 6.88647 1.5000
Fireball Island: The Curse of Vul-Kar 2018 6.88362 1.5059
Risk: Star Wars – Original Trilogy Edition 2006 6.82687 2.1165
Indulgence 2017 6.82302 1.9000
Conspiracy: The Solomon Gambit 2019 6.78492 2.5000
Betrayal at Mystery Mansion 2020 6.77279 1.8235
Risk 2210 A.D. 2001 6.69352 2.7197
Axis & Allies: Pacific 2001 6.66765 2.8691
Buffy the Vampire Slayer: The Game 2000 6.63384 2.0065
Heist: One Team, One Mission 2019 6.56062 1.0000
Mountains of Madness 2017 6.54175 2.0556
Dinosaur Tea Party 2018 6.50474 1.2941
Risk: Halo Wars Collector's Edition 2009 6.26772 2.2222
Clue: Harry Potter Edition 2008 6.25335 1.6410
Clue DVD Game 2005 6.25071 1.8824
SeaFall 2016 6.23882 3.7475
Clue: Discover the Secrets 2008 6.11577 1.8169
Risk: Star Wars – The Clone Wars Edition 2005 6.02117 2.2075
Risk (Revised Edition) 2008 5.98813 2.1628
Risk: Balance of Power 2008 5.86568 2.3077
Monopoly: Tropical Tycoon DVD Game 2007 5.79897 2.0000
The Game of Life: Card Game 2002 5.76326 1.5500
Battleship Card Game 2002 5.71699 1.5000
In Pursuit 2001 5.56329 1.8333
Risk: Battlefield Rogue 2013 5.53024 2.0000
Monopoly: The Lord of the Rings Trilogy Edition 2003 5.42894 1.5833
The Game of Life: A Jedi's Path 2002 5.30830 1.3714
-- Collaborators --
Collaborator Shared Games
Justin D. Jacobson 13
Craig Van Ness 8
JR Honeycutt 6
Stephen Baker 4
Matt Leacock 3
Reuben Klamer 2
Chris Dupuis 2
Mike Selinker 1
Colby Dauch 1
Jerry Hawthorne 1
Peter Lee 1
Larry Harris, Jr. 1
Ted Alspach 1
Wolfgang Kramer 1
Ryan Miller 1
Eric M. Lang 1
Masao Suganuma 1
Chris Leder 1
==================================================
DESIGNER: Reiner Knizia
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Yellow & Yangtze 2018 7.88189 3.1364
My City 2020 7.82378 2.0280
The Quest for El Dorado: The Golden Temples 2019 7.80232 1.8333
Witchstone 2021 7.77216 2.7209
Babylonia 2019 7.71737 2.4151
Battle Line: Medieval 2017 7.71531 1.8095
Tigris & Euphrates 1997 7.69599 3.5064
The Quest for El Dorado 2017 7.62258 1.9315
Lord of the Rings: The Confrontation 2005 7.48034 2.1948
Ra 1999 7.47924 2.3498
Samurai 1998 7.45601 2.4859
Modern Art 1992 7.43439 2.2995
Battle Line 2000 7.41340 1.8999
Schotten Totten 1999 7.32098 1.7244
Amun-Re 2003 7.31320 3.0378
The Siege of Runedar 2021 7.30163 2.3077
Schotten Totten 2 2020 7.30125 1.9167
Blue Moon Legends 2014 7.28963 2.2703
Taj Mahal 2000 7.27856 2.9923
Keltis (with Neue Wege, Neue Ziele) 2012 7.23857 2.0000
Lord of the Rings: The Confrontation 2002 7.19790 2.1897
Lost Cities 1999 7.18784 1.4921
Blue Lagoon 2018 7.18428 2.0196
Medici 1995 7.15626 2.2555
Whale Riders 2021 7.13047 1.9545
Ingenious 2004 7.11846 1.9135
Lost Cities: Roll & Write 2021 7.10397 1.1818
Carcassonne: The Castle 2003 7.09732 1.9847
Ingenious: Travel Edition 2006 7.09720 1.8519
High Society 1995 7.09497 1.5000
Heckmeck Deluxe 2018 7.09074 1.1250
L.A.M.A. Party Edition 2020 7.07838 1.1250
Through the Desert 1998 7.07686 2.2044
Equinox 2021 7.07151 2.2222
Dream Factory 2000 7.05277 2.1090
Blue Moon City 2006 7.03864 2.2960
Voodoo Prince 2017 6.99981 1.6364
Tutankhamun 2021 6.99450 1.8333
Winner's Circle 2001 6.97735 1.6047
Kariba 2010 6.95566 1.0714
Art Robbery 2021 6.92034 1.7500
Stephenson's Rocket 1999 6.89849 3.0595
GOLD 2020 6.88194 1.0000
Keltis: Das Orakel 2010 6.87297 2.1148
Marshmallow Test 2020 6.85515 1.6667
Take it Higher! 2009 6.85042 2.1667
Indigo 2012 6.84522 1.4774
Razzia! 2004 6.83183 1.9617
Priests of Ra 2009 6.80929 2.2500
Whoowasit? 2007 6.80546 1.4706
Lost Cities: The Board Game 2008 6.79722 1.7263
Qin 2012 6.78892 2.0204
Sumatra 2020 6.78884 1.8333
Neue Spiele im alten Rom 1994 6.78732 2.2857
Ra: The Dice Game 2009 6.78131 1.7442
Ribbit 2004 6.78094 1.0957
Colossal Arena 1997 6.77120 2.0204
Axio 2017 6.76884 1.6154
Dice Games Properly Explained 1999 6.75740 1.8182
Medici: The Card Game 2016 6.74609 1.6190
The Lord of the Rings 2000 6.74543 2.5648
Axio Rota 2019 6.74489 1.6667
Lost Cities: Rivals 2018 6.73566 1.9565
Strozzi 2008 6.72818 2.2381
Die Insel 2005 6.71607 1.9091
Merchants of Amsterdam 2000 6.71396 2.6319
Amun-Re: The Card Game 2017 6.70797 2.4400
Blue Moon 2004 6.70138 2.1712
Medici: The Dice Game 2020 6.69561 1.4000
Tajuto 2019 6.69197 2.0769
Municipium 2008 6.67770 2.4333
Prosperity 2013 6.67763 2.5566
Keltis: Das Kartenspiel 2009 6.67516 1.4917
Orongo 2014 6.67337 2.2353
Jäger und Sammler 2010 6.67288 1.9574
Schatz der Drachen 2003 6.67046 1.2000
Drachenhort 2015 6.64742 1.5000
Kingdoms 1994 6.64355 1.8297
Wildlife Safari 1994 6.64268 1.2945
Bee Alert 2012 6.64096 1.1250
Modern Art Card Game 2008 6.62631 1.6471
Circus Flohcati 1998 6.62624 1.2233
Tower of Babel 2005 6.62227 2.3344
Rheinländer 1999 6.61795 2.4350
Members Only 1996 6.61413 2.0000
Aristocracy 2019 6.61252 2.0000
Cheeky Monkey 2007 6.61174 1.1494
King's Road 2017 6.60444 1.7692
Chartae 2019 6.59137 1.4783
Merchants 2007 6.58064 1.7308
FITS 2009 6.57767 1.3944
Sakura 2018 6.57702 1.2222
Royal Visit 2006 6.57351 1.6589
Pickomino 2005 6.56408 1.1536
Pędzące Ślimaki 2016 6.56200 1.0000
Rondo 2012 6.55317 1.3714
Tajemnicze podziemia 2016 6.55294 1.1250
The Hobbit: The Desolation of Smaug 2013 6.55246 1.8000
Palazzo 2005 6.54138 2.0600
Ivanhoe 2000 6.53890 1.6103
Whale Riders: The Card Game 2021 6.53778 1.1667
Money! 1999 6.52763 1.5493
Yangtze 2016 6.50061 2.0000
Medici vs Strozzi 2006 6.49881 2.4518
En Garde 1993 6.49615 1.4032
L.L.A.M.A. 2019 6.48772 1.0580
Star Trek: Expeditions 2011 6.47065 2.4016
Thor 2002 6.46915 1.3659
Zero Down 1998 6.46264 1.2444
Quo Vadis? 1991 6.46065 2.0816
Sushizock im Gockelwok 2008 6.45609 1.2406
Turf Horse Racing 1995 6.45224 1.8000
Friday the 13th 2005 6.45011 1.1949
Age of War 2014 6.44876 1.1028
Keltis: Das Würfelspiel 2012 6.44622 1.2432
Keltis: Der Weg der Steine Mitbringspiel 2009 6.43828 1.2621
Spectaculum 2012 6.43793 1.7234
Penguin Party 2008 6.43655 1.1392
Callisto 2015 6.42812 1.8333
Grand National Derby 1996 6.42790 1.7143
BITS 2011 6.42056 1.4400
Mmm! 2015 6.41930 1.3333
Genesis 2006 6.41633 2.0635
Keltis 2008 6.41483 1.6475
Formula Motor Racing 1995 6.41108 1.1810
L.A.M.A. Dice 2021 6.40306 1.2857
Robot Master 2008 6.39794 1.3103
Criss Cross 2017 6.38004 1.0000
Lost Cities: To Go 2018 6.37874 1.4286
Knights of Charlemagne 1995 6.36689 1.4286
Dragon Master 2004 6.36577 1.2667
Connections 2012 6.36554 1.8182
Forbidden City 2018 6.36234 1.8571
Beowulf: The Legend 2005 6.35392 2.2547
Brains Family: Burgen & Drachen 2018 6.35047 1.2000
Los Banditos 2008 6.34914 1.3824
Excape 1998 6.34908 1.1410
Too Many Cooks 2002 6.34060 1.4000
Abandon Ship 2008 6.33842 1.2299
Duell 2004 6.33751 1.3333
Zen Master 2010 6.33513 1.3333
Electronic Labyrinth 2011 6.33062 1.8000
Beowulf: The Movie Board Game 2007 6.32221 2.1325
Rome: Imperium, Circus Maximus, Hannibal vs Rome 2001 6.31624 1.7097
Stonehenge 1994 6.31591 1.8571
Samurai: The Card Game 2009 6.31009 2.0312
Loot 1992 6.29663 1.3779
Reiner Knizia's Decathlon 2003 6.28665 1.2177
Dragonland 2002 6.28254 1.8411
Res Publica: 2230AD 2015 6.28053 2.0000
Galaxy: The Dark Ages 2000 6.27078 2.4154
Risk Express 2006 6.26573 1.1695
Big Five 2010 6.25752 1.3529
Twins 1996 6.25343 1.2500
Heckmeck Barbecue 2010 6.24053 1.4828
Callisto: The Game 2009 6.23728 1.6250
Trendy 2000 6.21793 1.0952
The Hobbit: An Unexpected Journey 2013 6.20706 1.8214
POW! 2016 6.20540 1.2500
Wheedle 2002 6.20158 1.2083
Amphipolis 2015 6.19194 1.8000
Karate Tomate 2018 6.19172 1.2500
Kartel 2018 6.19027 1.2857
Ilium 2008 6.18828 2.1220
Great Wall of China 2006 6.18757 1.8583
King's Gate 2002 6.17315 2.0446
Relationship Tightrope 1999 6.16919 1.3407
Mago Magino 2004 6.16048 1.1600
Marco Polo Expedition 2004 6.16032 1.8049
Buy Low Sell High 1996 6.14406 1.9907
King Arthur: The Card Game 2005 6.11820 1.5185
Tutankhamen 1993 6.10717 1.5839
Miskatonic University: The Restricted Collection 2019 6.10075 1.6000
Euphrates & Tigris: Contest of Kings 2005 6.08033 2.7278
Heckmeck Junior 2010 6.07042 1.1250
Secrets of the Sea 2006 6.06765 1.4000
Gold Armada 2017 6.06643 1.1667
Bucket Brigade 1998 6.06204 1.2759
Ohio 1998 6.03835 1.6000
Inferno 2005 6.03314 1.2857
Scarab Lords 2002 6.02672 1.9167
Khan of Khans 2016 6.01285 1.0667
Bunte Runde 2005 6.00598 1.1739
Mole Hill 1997 6.00392 1.7188
Code Cracker 2007 6.00122 1.2174
Africa 2001 5.99020 1.7500
Schollen Rollen 2017 5.98294 1.0000
Genial Spezial 2009 5.97412 1.8889
The Hobbit 2010 5.96885 1.7576
Piranhas 2012 5.95580 1.0000
Minotaur Lords 2004 5.95137 2.0800
SWAT! 2010 5.94912 1.1333
Alles Tomate! 2007 5.94733 1.0571
Vampire 2000 5.93100 1.3425
Lord of the Rings 2003 5.93046 1.2388
Cat Blues 1998 5.92930 1.4286
Black Sheep 2008 5.92701 1.4211
Easy Come, Easy Go 2004 5.91846 1.0200
Res Publica 1991 5.91715 1.7024
It's Mine! 1998 5.91264 1.0727
Clash of the Gladiators 2002 5.90943 1.5437
Der Herr der Ringe: Die Gefährten – Das Kartenspiel 2001 5.89768 1.9545
Looting London 2008 5.87815 1.4068
Jumbo Grand Prix 1998 5.87424 1.4000
Mini FITS 2010 5.86038 1.2333
Tal der Abenteuer: Die Schatzsuche im Himalaja 2006 5.83840 1.6000
Ingenious Challenges 2010 5.83672 1.3750
Atlanteon 1992 5.81768 2.0267
Toppo 2006 5.81641 1.1923
Reiner Knizia's Amazing Flea Circus 2003 5.81066 1.0617
Star Wars: Attack of the Clones Card Game 2002 5.80688 1.2000
IGOR: The Monster Making Game 2008 5.80576 1.1111
Fruit Spy 2005 5.79432 1.2676
Dragon Parade 2007 5.78684 1.2222
Einfach Genial: Das Kartenspiel 2008 5.78602 1.1923
Queen of the Cupcakes 2005 5.78114 1.3333
Der Herr der Ringe: Die Zwei Türme – das Kartenspiel 2002 5.77527 1.9130
Head-to-Head Poker 2005 5.76850 1.5938
Hopp hopp Häschen 2004 5.76173 1.0000
Pirates! 2005 5.75881 1.5000
Escalation! 2007 5.75010 1.0686
Das letzte Paradies 1993 5.73892 1.8571
RevoltaaA 2015 5.73628 1.1667
Gold Digger 1990 5.73612 1.1882
Gravediggers 2005 5.72881 1.5102
Attacke 1993 5.71611 1.4615
Zombiegeddon 2009 5.70507 2.1304
Kangaroo 2009 5.70000 1.0000
Fish Eat Fish 2003 5.69894 1.3514
Monopoly: Stock Exchange 2001 5.68460 2.3529
Little Italy 2007 5.67996 1.4138
Double or Nothing 2006 5.67661 1.1094
My Word! 2001 5.67490 1.3182
Topas 2009 5.66575 1.0833
Buzz It! 2010 5.64568 1.1111
Córdoba 2008 5.63661 1.2000
Castellers 2008 5.63161 1.4000
Gem Dealer 2008 5.57873 1.2581
Maginor 2001 5.51051 1.8636
Spy 2004 5.50063 1.2742
Hochstapler 2009 5.48644 1.2500
Einfach Genial: Das Würfelspiel 2012 5.47176 1.2857
Battleship Express 2007 5.46248 1.1176
Crafty Badger 2000 5.45203 1.0000
Ramses Return 2011 5.40595 1.0000
Pan tu nie stał! Demoludy 2015 5.37784 1.2857
Cthulhu Rising 2008 5.37263 1.2917
Monkey Madness 2001 5.36214 1.0000
King Arthur 2003 5.31950 1.4783
Mmm ... Brains! 2006 5.31000 1.0625
Figaro 2006 5.30702 1.0976
Shoot Out 1995 5.28320 1.1875
Game of Thrones: Westeros Intrigue 2014 5.27915 1.0794
Simply Ingenious 2008 5.27780 1.1667
SuDoku: The Card Game 2006 5.23937 1.2500
Scary Tales: Snow White vs. The Giant 2009 5.22294 1.5000
Scary Tales: Little Red vs. Pinocchio 2009 5.16929 1.3684
Ramses Pyramid 2009 5.02440 1.2308
Wapi 2003 5.02182 1.1333
Penguin 2007 4.65287 1.0725
SuDoku: Das Brettspiel 2005 4.63419 1.2632
-- Collaborators --
Collaborator Shared Games
Cephas Howard 2
Don Greenwood 1
Klaus-Jürgen Wrede 1
Christian T. Petersen 1
Eric M. Lang 1
Jeff Tidball 1
Max J. Kobbert 1
Sebastian Bleasdale 1
Martino Chiacchiera 1
==================================================
DESIGNER: Mike Elliott
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Alhambra: Mega Box 2019 8.13331 2.2500
Thunderstone Quest 2018 7.86815 2.8400
Quarriors! Qultimate Quedition 2019 7.81869 2.3333
Thunderstone Advance: Worlds Collide 2014 7.75201 2.8276
Shadowrun Crossfire: Prime Runner Edition 2018 7.73795 3.0000
Dungeons & Dragons Dice Masters: Faerûn Under Siege 2016 7.56736 2.4000
Stargrunt II 1996 7.55411 2.9600
Star Trek: Fleet Captains 2011 7.50418 3.0531
DC Comics Dice Masters: World's Finest 2016 7.42878 2.3333
Marvel Dice Masters: The Amazing Spider-Man 2015 7.36784 2.1000
Thunderstone Advance: Towers of Ruin 2012 7.35845 2.7386
Thunderstone: Dragonspire 2011 7.33814 2.7000
DC Comics Dice Masters: Justice League 2015 7.33550 2.2941
Marvel Dice Masters: Civil War 2016 7.31904 2.6667
Teenage Mutant Ninja Turtles Dice Masters: Heroes in a Half Shell 2017 7.30294 3.0000
Marvel Dice Masters: Iron Man and War Machine Starter Set 2017 7.29894 0.0000
Thunderstone Advance: Numenera 2013 7.28680 2.7385
DC Comics Dice Masters: War of Light 2015 7.27962 2.2727
Dirtside II 1993 7.27415 2.9688
Marvel Dice Masters: Age of Ultron 2015 7.25369 2.4615
Dungeons & Dragons Dice Masters: Battle for Faerûn 2015 7.24870 2.1864
Dragonfire 2017 7.23807 3.2152
Marvel Dice Masters: Uncanny X-Men 2014 7.19258 2.3684
Dreamblade 2006 7.17108 2.6950
Warhammer 40,000 Dice Masters: Battle for Ultramar Campaign Box 2018 7.15640 2.5000
Shadowrun: Crossfire 2014 7.15378 2.8208
Marvel Dice Masters: Avengers vs. X-Men 2014 7.14698 2.2996
Teenage Mutant Ninja Turtles Dice Masters 2016 7.08294 2.3333
Axis & Allies: War at Sea 2007 7.03635 2.0769
Thunderstone: Starter Set 2013 6.94972 2.3125
Thunderstone 2009 6.93338 2.5048
Yu-Gi-Oh! Dice Masters 2015 6.83391 2.0000
Terror Below 2019 6.81162 1.9000
Quarriors! Light vs. Dark 2014 6.80696 2.1333
Quarriors! 2011 6.75252 1.9683
Speechless 2016 6.74589 1.2500
Lost Legends 2013 6.43495 2.4500
Immortals 2017 6.41674 3.3333
Hecatomb 2005 6.36728 2.4615
Snowman Dice 2019 6.28578 1.0000
Duel Masters Trading Card Game 2004 6.26320 1.9412
Harry Potter Trading Card Game 2001 6.16491 1.9620
Halo ActionClix 2007 6.12933 1.8947
Final Touch 2016 6.02345 1.0909
Star Wars PocketModel TCG 2007 5.79655 1.6197
Earthquake 1998 5.76401 1.0556
Instinct 1998 5.76175 1.3636
Agent Hunter 2013 5.72152 1.0952
The Lord of the Rings Dice Building Game 2013 5.63339 2.1951
Sword & Skull 2005 5.48285 1.5056
Simpsons Trading Card Game 2003 5.05182 1.3846
-- Collaborators --
Collaborator Shared Games
Eric M. Lang 19
Rob Heinsoo 4
Ethan Pasternack 3
Mark Wootton 3
Tyler Bielman 2
Jonathan Tweet 2
Dirk Henn 2
Randall N. Bills 1
Rüdiger Dorn 1
Michael Schacht 1
Michael Rieneck 1
Klaus-Jürgen Wrede 1
Emanuele Ornella 1
Paul Peterson 1
Jeph Stahl 1
Skaff Elias 1
Brent Keith 1
Bryan Kinsella 1
Michael Mulvihill 1
Mike Selinker 1
James Ernest 1
Stefan Feld 1
==================================================
DESIGNER: Bruno Faidutti
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Mission: Red Planet (Second Edition) 2015 7.44101 2.2033
Vampire: The Masquerade – Vendetta 2020 7.38902 2.5789
Raptor 2015 7.30664 2.0631
Citadels 2016 7.30356 2.0055
Reigns: The Council 2020 7.19039 1.8333
Citadels 2000 7.07887 2.0524
Ohne Furcht und Adel 2012 7.04134 2.4483
Mystery of the Abbey with The Pilgrims' Chronicles 2007 7.02183 2.2500
Greedy Kingdoms 2018 6.92805 1.4286
Mission: Red Planet 2005 6.90308 2.3178
Ad Astra 2009 6.86818 2.6784
Warrior Knights 2006 6.86673 3.5210
Diamant 2005 6.82644 1.1122
Dreadful Circus 2021 6.81866 2.0000
Isla Dorada 2010 6.71402 2.1667
Tonari 2019 6.61491 1.1429
Key Largo 2005 6.61096 2.0448
Mascarade 2013 6.60499 1.5314
The Dwarf King 2011 6.54648 1.4253
Mystery of the Abbey 1995 6.53720 2.2025
Boomtown 2004 6.52866 1.6961
Fist of Dragonstones: The Tavern Edition 2018 6.52475 2.0000
Secrets 2017 6.48761 1.4706
Pony Express 2009 6.47557 1.5849
Miaui 2017 6.45725 1.2857
Dragons 2018 6.44044 1.5714
Dragon's Gold 2001 6.43477 1.6947
Valley of the Mammoths 1991 6.42210 2.5214
Queen's Necklace 2003 6.40895 1.9005
Red November 2008 6.29860 2.0747
Vabanque 2001 6.26674 1.6875
Warehouse 51 2015 6.19853 1.8333
Waka Tanka 2016 6.18756 1.0000
Formula E 2014 6.17981 1.5000
HMS Dolores 2016 6.17308 1.3333
Fist of Dragonstones 2002 6.15807 1.8634
Castle 2000 6.10280 1.9024
Bongo! 2000 6.07702 1.4130
Argo 2016 6.03133 2.5000
Tomahawk 2006 5.96746 1.4375
Iglu Iglu 2004 5.94882 2.0000
Kheops 2008 5.93467 2.1429
Silk Road 2006 5.89111 2.2424
Chicago Poker 2007 5.88899 1.7455
Lost Temple 2011 5.87049 1.7391
China Moon 1996 5.84366 1.5849
Corruption 2000 5.81656 1.8276
Double Agent 2005 5.78225 1.7500
Terra 2003 5.71490 1.6557
Attila 2015 5.69668 1.3750
Gold und Rum 2003 5.60568 1.6471
Babylon 2003 5.54249 1.6296
Animocrazy 豬事議會 2000 5.53104 1.2804
The Hollywood! Card Game 2005 5.52349 1.3061
Draco & Co 2001 5.50186 1.4848
SmileyFace 2010 5.48248 1.2414
Bugs & Co 2011 5.44467 1.0000
Knock! Knock! 2004 5.41813 1.2424
Stonehenge: An Anthology Board Game 2007 5.38195 2.1930
Soluna 2012 5.26711 1.2000
Letter of Marque 2009 4.77234 1.1458
-- Collaborators --
Collaborator Shared Games
Bruno Cathala 8
Serge Laget 6
Michael Schacht 4
Alan R. Moon 3
Mike Selinker 2
Eric M. Lang 2
Sérgio Halaban 2
André Zatz 2
Pier Giorgio Paglia 1
Alex Randolph 1
Hayato Kisaragi 1
Thomas Vuarchex 1
Pierrick Yakovenko 1
Corey Konieczka 1
Andrea Angiolino 1
Antoine Bauza 1
Leo Colovini 1
Richard Garfield 1
Richard Borg 1
James Ernest 1
Ludovic Maublanc 1
Ted Cheatham 1
Hervé Marly 1
==================================================
DESIGNER: Eric M. Lang
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Marvel United: X-Men 2021 8.28797 2.3333
A Song of Ice & Fire: Tabletop Miniatures Game – Stark vs Lannister Starter Set 2018 8.18652 2.8966
Cthulhu: Death May Die 2019 8.14790 2.3782
Bloodborne: The Board Game 2021 7.99815 2.9333
Blood Rage 2015 7.99408 2.8778
Ankh: Gods of Egypt 2021 7.97652 3.0492
Arcadia Quest: Inferno 2017 7.97258 2.4091
Rising Sun 2018 7.84200 3.2831
Quarriors! Qultimate Quedition 2019 7.81869 2.3333
Marvel United 2020 7.69318 1.8413
Arcadia Quest 2014 7.68101 2.5350
Chaos in the Old World 2009 7.67437 3.1915
Starcadia Quest 2020 7.63832 2.7500
Dungeons & Dragons Dice Masters: Faerûn Under Siege 2016 7.56736 2.4000
A Game of Thrones: The Card Game (Second Edition) 2015 7.55302 3.5333
The Godfather: Corleone's Empire 2017 7.54646 2.6207
Lord of the Rings: The Confrontation 2005 7.48034 2.1948
DC Comics Dice Masters: World's Finest 2016 7.42878 2.3333
The Others 2016 7.36895 3.0291
Marvel Dice Masters: The Amazing Spider-Man 2015 7.36784 2.1000
Warhammer 40,000: Conquest 2014 7.36592 3.0373
DC Comics Dice Masters: Justice League 2015 7.33550 2.2941
Marvel Dice Masters: Civil War 2016 7.31904 2.6667
Teenage Mutant Ninja Turtles Dice Masters: Heroes in a Half Shell 2017 7.30294 3.0000
Marvel Dice Masters: Iron Man and War Machine Starter Set 2017 7.29894 0.0000
DC Comics Dice Masters: War of Light 2015 7.27962 2.2727
Marvel Dice Masters: Age of Ultron 2015 7.25369 2.4615
Dungeons & Dragons Dice Masters: Battle for Faerûn 2015 7.24870 2.1864
Warhammer: Invasion 2009 7.22739 2.7330
Marvel Dice Masters: Uncanny X-Men 2014 7.19258 2.3684
Star Wars: The Card Game 2012 7.18217 2.9672
Warhammer 40,000 Dice Masters: Battle for Ultramar Campaign Box 2018 7.15640 2.5000
Marvel Dice Masters: Avengers vs. X-Men 2014 7.14698 2.2996
Teenage Mutant Ninja Turtles Dice Masters 2016 7.08294 2.3333
XCOM: The Board Game 2015 7.04053 2.9033
Victorian Masterminds 2019 6.91248 2.1852
Munchkin Dungeon 2020 6.90856 2.1538
Call of Cthulhu: The Card Game 2008 6.90844 2.8940
Bloodborne: The Card Game 2016 6.90451 2.0833
Call of Cthulhu: Collectible Card Game 2004 6.85561 2.5484
A Game of Thrones Collectible Card Game 2002 6.84305 2.8955
Yu-Gi-Oh! Dice Masters 2015 6.83391 2.0000
A Game of Thrones: The Card Game 2008 6.82936 3.2532
Quarriors! Light vs. Dark 2014 6.80696 2.1333
Arcane Academy 2016 6.77919 2.1579
Quarriors! 2011 6.75252 1.9683
Kaosball: The Fantasy Sport of Total Domination 2014 6.60492 2.5143
Midgard 2007 6.57595 2.3689
Secrets 2017 6.48761 1.4706
Mystick Domination 2000 6.43333 2.8333
Ancestree 2017 6.31883 2.0000
Munchkin Collectible Card Game 2018 6.27308 2.6667
Game of Thrones: The Card Game 2012 6.23040 2.7037
HMS Dolores 2016 6.17308 1.3333
Mutant Chronicles Collectible Miniatures Game 2008 6.12701 2.4419
Trains and Stations 2013 5.79465 1.8246
The Lord of the Rings Dice Building Game 2013 5.63339 2.1951
Frenzy 2003 5.61512 1.1818
Dilbert: The Board Game 2006 5.58663 1.7619
Senator 2004 5.51907 2.0429
Fantasía S.A. 2008 5.36388 1.6667
-- Collaborators --
Collaborator Shared Games
Mike Elliott 19
Nate French 5
Christian T. Petersen 4
Kevin Wilson 3
Andrea Chiarvesio 3
Bruno Faidutti 2
Michael Shinall 2
Reiner Knizia 1
Jeph Stahl 1
Brad Andres 1
Antoine Bauza 1
Rob Daviau 1
==================================================
DESIGNER: Mike Selinker
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Pathfinder Adventure Card Game: Mummy's Mask – Base Set 2016 8.01635 2.9167
Pathfinder Adventure Card Game: Core Set 2019 7.80477 3.0000
Pathfinder Adventure Card Game: Wrath of the Righteous – Base Set 2015 7.47087 3.1000
Lords of Vegas 2010 7.34356 2.3556
Pathfinder Adventure Card Game: Skull & Shackles – Base Set 2014 7.30364 2.9333
Pathfinder Adventure Card Game: Rise of the Runelords – Base Set 2013 7.19748 2.7127
Betrayal at House on the Hill 2004 7.05841 2.3860
Trogdor!! The Board Game 2019 6.96586 1.8636
Apocrypha Adventure Card Game: Box One – The World 2017 6.72433 3.7143
Axis & Allies 2004 6.69576 3.2137
Key Largo 2005 6.61096 2.0448
12 Days 2011 6.51782 1.2131
Unspeakable Words: Deluxe Edition 2015 6.49794 1.1429
Axis & Allies: D-Day 2004 6.42433 2.3618
Thornwatch 2018 6.41669 2.3333
The Ninth World: A Skillbuilding Game for Numenera 2018 6.31653 2.7143
Risk: Godstorm 2004 6.27305 2.6923
Unspeakable Words 2007 6.22688 1.3211
Pirates of the Spanish Main 2004 6.08275 1.7730
Gloria Mundi 2006 6.06444 2.6149
Fightball 2002 5.82763 2.1200
Yetisburg: Titanic Battles in History, Vol. 1 2008 5.73127 1.3600
Pirates: Quest for Davy Jones' Gold 2006 5.58261 1.5600
Cowpoker 2006 5.44937 1.5600
Stonehenge: An Anthology Board Game 2007 5.38195 2.1930
Simpsons Trading Card Game 2003 5.05182 1.3846
Dungeonville 2004 4.86650 1.4000
-- Collaborators --
Collaborator Shared Games
James Ernest 13
Chad Brown 7
Paul Peterson 6
Tanis O'Connor 5
Gaby Weidling 5
Liz Spain 4
Bruno Faidutti 2
Michael Mulvihill 2
Larry Harris, Jr. 2
Richard Borg 1
Mike Elliott 1
Ethan Pasternack 1
Jordan Weisman 1
Rob Daviau 1
Tyler Bielman 1
Rodney Thompson 1
Richard Garfield 1
==================================================
DESIGNER: Klaus-Jürgen Wrede
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Carcassonne: 20th Anniversary Edition 2021 8.19789 1.7692
Carcassonne Big Box 6 2017 8.15176 1.9467
Alhambra: Mega Box 2019 8.13331 2.2500
Carcassonne Big Box 5 2014 7.91916 2.2656
Carcassonne Big Box 3 2010 7.90321 2.0909
Каркассон: Королевский Подарок 2013 7.89645 1.7778
Carcassonne Big Box 2 2008 7.82536 2.0000
Carcassonne Big Box 4 2012 7.78212 2.0317
Carcassonne: 10 Year Special Edition 2011 7.68229 2.0204
Carcassonne Big Box 2006 7.56939 2.3125
Carcassonne: Winter Edition 2012 7.49811 1.8529
Carcassonne 2000 7.41883 1.9064
Carcassonne: Over Hill and Dale 2015 7.33272 2.0000
Travel Carcassonne 2007 7.25055 1.8889
Carcassonne: The City 2004 7.20741 2.2644
Carcassonne: Gold Rush 2014 7.16322 1.9444
The Downfall of Pompeii 2004 7.13964 1.8469
Carcassonne: Hunters and Gatherers 2002 7.12853 1.9197
Carcassonne für 2 2017 7.11672 1.7143
Carcassonne: The Castle 2003 7.09732 1.9847
Carcassonne: Safari 2018 7.08956 1.8571
Carcassonne: Amazonas 2016 7.07557 1.9250
Carcassonne: South Seas 2013 7.07368 1.8819
Carcassonne: Wheel of Fortune 2009 7.02213 2.0615
The Ark of the Covenant 2003 6.96159 1.9242
Calavera 2019 6.82309 1.0769
Bali 2017 6.78730 2.0714
Rapa Nui 2011 6.76200 2.0714
Carcassonne: Star Wars 2015 6.71792 1.6275
Mesopotamia 2005 6.50631 2.4394
Carcassonne: The Discovery 2005 6.48922 1.9304
New World: A Carcassonne Game 2008 6.47153 2.0533
Die Fugger 2003 6.42596 1.9556
Mistkäfer 2017 6.37000 1.3333
The Architects of the Colosseum 2016 6.31046 2.1667
Venedig 2007 6.27521 2.0769
Cardcassonne 2009 6.27477 1.7556
Albion 2009 6.05729 2.5161
Krone & Schwert 2002 6.01699 2.5278
Dragonriders 2005 5.00165 1.6316
Carcassonne: The Dice Game 2011 4.94141 1.1111
Anasazi 2006 4.92409 1.8298
-- Collaborators --
Collaborator Shared Games
Bernd Brunnhofer 1
Reiner Knizia 1
Leo Colovini 1
Jean du Poël 1
Karl-Heinz Schmiel 1
Dirk Henn 1
Emanuele Ornella 1
Michael Rieneck 1
Michael Schacht 1
Mike Elliott 1
Rüdiger Dorn 1
Stefan Feld 1
==================================================
DESIGNER: Jonathan Tweet
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Dreamblade 2006 7.17108 2.6950
Star Wars Miniatures 2004 6.88735 2.3161
Dungeons & Dragons Basic Game 2004 6.80566 3.0351
Dungeons & Dragons Miniatures 2003 6.54616 2.5667
Axis & Allies Miniatures 2005 6.52120 2.2971
Dungeons & Dragons Adventure Game 2000 6.49704 2.4118
Hecatomb 2005 6.36728 2.4615
On the Edge 1994 6.21685 2.3913
-- Collaborators --
Collaborator Shared Games
Rob Heinsoo 2
Mike Elliott 2
Skaff Elias 1
Bill Slavicsek 1
Jeff Grubb 1
Peter Lee 1
Devin Low 1
==================================================
DESIGNER: Dávid Turczi
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Anachrony: Infinity Box 2020 9.07609 3.9737
Trickerion: Collector's Edition 2019 8.85098 4.5698
Anachrony Leader Box 2017 8.28736 3.0000
Snowdonia: Deluxe Master Set 2019 8.16327 3.0571
Anachrony 2017 8.11379 4.0068
Imperium: Legends 2021 8.07832 3.6889
Tekhenu: Obelisk of the Sun 2020 7.87978 4.0943
Imperium: Classics 2021 7.87167 3.4579
Kitchen Rush (Revised Edition) 2019 7.68972 2.0811
Tawantinsuyu: The Inca Empire 2020 7.64651 4.0735
Rush M.D. 2020 7.56540 2.3333
Excavation Earth 2021 7.40742 3.7333
Days of Ire: Budapest 1956 2016 7.36685 2.8222
Kitchen Rush 2017 7.33730 2.2131
Nights of Fire: Battle for Budapest 2019 7.31533 3.1667
Rome & Roll 2020 7.01530 3.3171
Dice Settlers 2018 6.96891 2.9394
Venice 2021 6.68495 3.0000
[redacted] 2014 6.19086 2.9250
[microfilms] 2015 5.93683 1.8333
Steal This Game 2016 5.62460 1.0000
-- Collaborators --
Collaborator Shared Games
Richard Amann 4
Viktor Peter 4
David J. Mortimer 2
Vangelis Bagiartakis 2
Alan Paull 1
Błażej Kubacki 1
David Brain 1
Hisashi Hayashi 1
Matthew Dunstan 1
Sebastian Bleasdale 1
Tony Boydell 1
Andrei Novac 1
Konstantinos Kokkinis 1
Daniele Tascini 1
==================================================
DESIGNER: Devin Low
==================================================
-- Games --
Name YearPublished AvgRating GameWeight
Legendary: A James Bond Deck Building Game 2019 7.80886 2.1667
Legendary: A Marvel Deck Building Game – Villains 2014 7.58636 2.7067
Legendary: A Marvel Deck Building Game 2012 7.56408 2.4399
Legendary: A Marvel Deck Building Game – Marvel Studios, Phase 1 2018 7.05444 2.4000
Axis & Allies Miniatures 2005 6.52120 2.2971
-- Collaborators --
Collaborator Shared Games
Jonathan Tweet 1
Ben Cichoski 1
Daniel Mandel 1
# Compare Daviau vs Elliott: communities of collaborators
for name in ['Rob Daviau', 'Reiner Knizia', 'Mike Elliott']:
neighbors = list(G.neighbors(name))
weights = [G[name][n]['weight'] for n in neighbors]
collabs = pd.DataFrame({'Collaborator': neighbors, 'Shared Games': weights}).sort_values('Shared Games', ascending=False)
print(f"\n{name}")
print(f"Degree (number of collaborators): {len(neighbors)}")
print(f"Communities of collaborators: {set(community_map.get(n, -1) for n in neighbors)}")
print(collabs.to_string(index=False))
Rob Daviau
Degree (number of collaborators): 18
Communities of collaborators: {0, 1, 2, 6, 9}
Collaborator Shared Games
Justin D. Jacobson 13
Craig Van Ness 8
JR Honeycutt 6
Stephen Baker 4
Matt Leacock 3
Reuben Klamer 2
Chris Dupuis 2
Mike Selinker 1
Colby Dauch 1
Jerry Hawthorne 1
Peter Lee 1
Larry Harris, Jr. 1
Ted Alspach 1
Wolfgang Kramer 1
Ryan Miller 1
Eric M. Lang 1
Masao Suganuma 1
Chris Leder 1
Reiner Knizia
Degree (number of collaborators): 9
Communities of collaborators: {1, 2, 3, 6, 7}
Collaborator Shared Games
Cephas Howard 2
Don Greenwood 1
Klaus-Jürgen Wrede 1
Christian T. Petersen 1
Eric M. Lang 1
Jeff Tidball 1
Max J. Kobbert 1
Sebastian Bleasdale 1
Martino Chiacchiera 1
Mike Elliott
Degree (number of collaborators): 22
Communities of collaborators: {0, 1, 2, 7}
Collaborator Shared Games
Eric M. Lang 19
Rob Heinsoo 4
Ethan Pasternack 3
Mark Wootton 3
Tyler Bielman 2
Jonathan Tweet 2
Dirk Henn 2
Randall N. Bills 1
Rüdiger Dorn 1
Michael Schacht 1
Michael Rieneck 1
Klaus-Jürgen Wrede 1
Emanuele Ornella 1
Paul Peterson 1
Jeph Stahl 1
Skaff Elias 1
Brent Keith 1
Bryan Kinsella 1
Michael Mulvihill 1
Mike Selinker 1
James Ernest 1
Stefan Feld 1
1c) Static Network Visualization¶
Create a static network visualization of the designer collaboration network using Altair (recommended), matplotlib, or any other package of your choice:
- Node size ∝ number of games designed
- Node color = community membership
- Edge width distinguishes strong collaborations (many shared games) from single co-designs
- Label the 10–15 most prolific designers
- Use an appropriate layout algorithm (e.g.
spring_layout,kamada_kawai_layoutfrom NetworkX) to compute node positions, then plot with your chosen library
Write 2–3 sentences interpreting the visualization. Do you see tightly-knit design teams? Are there designers who bridge multiple communities?
# Compute layout
pos = nx.kamada_kawai_layout(G, weight='weight')
# Only keep communities with more than 1 member
community_sizes = {}
for node, comm in community_map.items():
community_sizes[comm] = community_sizes.get(comm, 0) + 1
# Assign "Other" to small communities, keep top N largest
top_communities = sorted(community_sizes, key=community_sizes.get, reverse=True)[:10]
node_data = []
for node in G.nodes():
x, y = pos[node]
comm = community_map.get(node, -1)
comm_label = str(comm) if comm in top_communities else "Other"
node_data.append({
'Designer': node,
'x': x,
'y': y,
'Games': game_counts.get(node, 0),
'Community': comm_label
})
nodes_df = pd.DataFrame(node_data)
edge_data = []
for u, v, data in G.edges(data=True):
x0, y0 = pos[u]
x1, y1 = pos[v]
edge_data.append({
'x': x0, 'y': y0,
'x2': x1, 'y2': y1,
'weight': data.get('weight', 1)
})
edges_df = pd.DataFrame(edge_data)
top15_labels = nodes_df.nlargest(15, 'Games')
# name legend entries by most prominent designer in each community
community_labels = {}
for comm in top_communities:
members = [n for n, c in community_map.items() if c==comm]
top_member = max(members, key=lambda n: game_counts.get(n, 0))
community_labels[str(comm)] = f"{top_member}"
#remap community column to named lables
def label_community(c):
return community_labels.get(c, "Other")
nodes_df["CommunityLabel"] = nodes_df["Community"].apply(label_community)
top15_labels = nodes_df.nlargest(15, 'Games')
# Compute offsets and push labels away from center
cx = nodes_df['x'].mean()
cy = nodes_df['y'].mean()
top15_labels = nodes_df.nlargest(15, 'Games').copy()
dx = top15_labels['x'] - cx
dy = top15_labels['y'] - cy
dist = np.sqrt(dx**2 + dy**2) + 1e-6
top15_labels['x_label'] = top15_labels['x'] + (dx / dist) * 0.08
top15_labels['y_label'] = top15_labels['y'] + (dy / dist) * 0.08
edge_chart = alt.Chart(edges_df).mark_rule(opacity=0.3).encode(
x=alt.X('x:Q', axis=None),
y=alt.Y('y:Q', axis=None),
x2=alt.X2('x2:Q'),
y2=alt.Y2('y2:Q'),
strokeWidth=alt.StrokeWidth('weight:Q', scale=alt.Scale(range=[0.3, 3]), legend=None),
color=alt.value('#aaaaaa')
)
node_chart = alt.Chart(nodes_df).mark_circle(opacity=0.85).encode(
x=alt.X('x:Q', axis=None),
y=alt.Y('y:Q', axis=None),
size=alt.Size('Games:Q', scale=alt.Scale(range=[30, 800]), legend=None),
color=alt.Color(
'CommunityLabel:N',
scale=alt.Scale(scheme='tableau10'),
legend=alt.Legend(title='Community (top 10 designers)')
),
tooltip=['Designer:N', 'Games:Q', 'CommunityLabel:N']
)
label_chart = alt.Chart(top15_labels).mark_text(
fontSize=10,
fontWeight='normal',
color='gray',
strokeWidth=2
).encode(
x=alt.X('x_label:Q', axis=None),
y=alt.Y('y_label:Q', axis=None),
text=alt.Text('Designer:N')
)
chart = (edge_chart + node_chart + label_chart).properties(
width=2000,
height=1200,
title='Board Game Designer Collaboration Network'
).configure_view(strokeWidth=0)
chart
<VegaLite 5 object> If you see this message, it means the renderer has not been properly enabled for the frontend that you are using. For more information, see https://altair-viz.github.io/user_guide/display_frontends.html#troubleshooting
chart.save('designer_network.html')
Interpretation:
The designer collaboration network is sparse, with an average degree of 2.18. The pink cluster in the centre corresponds to the Reiner Knizia community. Another visible cluster is Bruno Cathala's community (blue).
Rob Daviau stands out as the strongest strucutral bridge, with collaborators spanning multiple communities. In contrast, Dean Essig and Richard H Berg sit on the periperhy with single long edges connecting them to the core. This suggests that they are niche designers who rarely cross collaborate with the broader network.
The periperhy is full of isolated nodes conneced by single thin edges, confirming that most designers in the filtered network have few collaborations. i.e. Most designers work primarily solo, or in small tightly bonded teams (e.g. Mike Elliot and Eric M. Lang codesigned 19 games).
Section 2: The Mechanics Co-occurrence Network¶
Network connecting game mechanics rather than people.
2a) Build and Visualize Interactively¶
From game_mechanics.csv, build a co-occurrence network: two mechanics share an edge when they appear in the same game, weighted by co-occurrence count. Filter out edges with fewer than 30 co-occurrences and remove any mechanics that become isolated after filtering.
Create an interactive visualization using PyVis:
- Node size ∝ how many games use that mechanic
- Node tooltip showing the mechanic name and game count
- Edge width ∝ co-occurrence count
- Node color based on community detection
Write 3–5 sentences interpreting the result. What clusters of mechanics emerge? Do the communities correspond to recognizable game styles (e.g. "Euro-strategy", "party games", "wargames")?
# build co-occurence edge counts
mechanic_edge_counts = {}
for bgid, group in game_mechanics.groupby('BGGId'):
mechanics = list(group['Mechanic'])
if len(mechanics) < 2:
continue
for a, b in itertools.combinations(sorted(mechanics), 2):
key = (a, b)
mechanic_edge_counts[key] = mechanic_edge_counts.get(key, 0) + 1
#build graph, filter edges with < 30 co-occurrences, remove isolated nodes
G_mech = nx.Graph()
for (a, b), weight in mechanic_edge_counts.items():
if weight >= 30:
G_mech.add_edge(a, b, weight=weight)
#remove isolated nodes
isolated = list(nx.isolates(G_mech))
G_mech.remove_nodes_from(isolated)
#Game count per mechanic
mechanic_counts = game_mechanics['Mechanic'].value_counts().to_dict()
#report stats
print(f"Number of nodes: {G_mech.number_of_nodes()}")
print(f"Number of edges: {G_mech.number_of_edges()}")
Number of nodes: 71 Number of edges: 553
#community detection on mechanics
mech_communities = greedy_modularity_communities(G_mech)
mech_community_map = {}
for i, community in enumerate(mech_communities):
for mechanic in community:
mech_community_map[mechanic] = i
print(f"Number of communities: {len(mech_communities)}")
Number of communities: 4
comm_top_mechanic = {}
for node in G_mech.nodes():
count = mechanic_counts.get(node, 0)
comm = mech_community_map.get(node, -1)
if comm not in comm_top_mechanic or count > mechanic_counts.get(comm_top_mechanic[comm],0):
comm_top_mechanic[comm] = node
print(comm_top_mechanic)
{1: 'Area Majority / Influence'}
{1: 'Area Majority / Influence', 0: 'Hand Management'}
{1: 'Area Majority / Influence', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Hexagon Grid', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Push Your Luck'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
{1: 'Set Collection', 0: 'Hand Management', 2: 'Dice Rolling', 3: 'Cooperative Game'}
# show top 5 mechanics per community by game count
for comm_id, community in enumerate(mech_communities):
top_mechanics = sorted(community, key=lambda m: mechanic_counts.get(m, 0), reverse=True)[:5]
print(f"\nCommunity {comm_id}({len(community)} mechanics):")
for m in top_mechanics:
print(f" {m} ({mechanic_counts.get(m, 0)} games)")
Community 0(24 mechanics): Hand Management (2910 games) Variable Player Powers (1829 games) Betting and Bluffing (850 games) Simultaneous Action Selection (701 games) Deduction (681 games) Community 1(23 mechanics): Set Collection (1852 games) Drafting (1350 games) Tile Placement (1161 games) Area Majority / Influence (1154 games) Modular Board (1151 games) Community 2(19 mechanics): Dice Rolling (3091 games) Grid Movement (755 games) Simulation (712 games) Hexagon Grid (684 games) Campaign / Battle Card Driven (338 games) Community 3(5 mechanics): Cooperative Game (1011 games) Push Your Luck (574 games) Dexterity (478 games) Real-Time (458 games) Pattern Recognition (270 games)
print(f"Number of communities detected: {len(mech_communities)}")
print(f"\nComm ID -> Top mechanic (legend label):")
for comm, mechanic in sorted(comm_top_mechanic.items()):
color = colors[comm % len(colors)]
size = len([n for n in G_mech.nodes() if mech_community_map.get(n) == comm])
print(f" Community {comm}: {mechanic} | color: {color} | size: {size} mechanics")
Number of communities detected: 4 Comm ID -> Top mechanic (legend label): Community 0: Hand Management | color: #e41a1c | size: 24 mechanics Community 1: Set Collection | color: #377eb8 | size: 23 mechanics Community 2: Dice Rolling | color: #4daf4a | size: 19 mechanics Community 3: Cooperative Game | color: #984ea3 | size: 5 mechanics
#pyvis interactive network
from pyvis.network import Network
colors = ['#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00','#a65628','#f781bf','#999999','#66c2a5','#fc8d62']
net = Network(notebook=True, height='100vh', width='100%', bgcolor='#ffffff', font_color='#333333')
net.barnes_hut()
for node in G_mech.nodes():
count = mechanic_counts.get(node, 0)
comm = mech_community_map.get(node, -1)
color = colors[comm % len(colors)]
size = 5 + count / 400
net.add_node(node, label=node, size=size, color=colors[comm % len(colors)], title=f"{node}<br>Games: {count} <br> Community: {comm}")
for u, v, data in G_mech.edges(data=True):
weight = data.get('weight', 1)
net.add_edge(u, v, width = weight / 100, title = f"co-occurrences: {weight}")
net.show('mechanics_network.html')
Warning: When cdn_resources is 'local' jupyter notebook has issues displaying graphics on chrome/safari. Use cdn_resources='in_line' or cdn_resources='remote' if you have issues viewing graphics in a notebook. mechanics_network.html
net.save_graph('mechanics_network.html')
# Build legend
legend_items = ""
for comm, mechanic in sorted(comm_top_mechanic.items()):
color = colors[comm % len(colors)]
legend_items += f"""
<div style="display:flex;align-items:center;margin-bottom:6px;">
<div style="width:14px;height:14px;border-radius:50%;background:{color};margin-right:8px;flex-shrink:0;"></div>
<span style="font-size:13px;color:#333;">{mechanic}</span>
</div>"""
legend_html = f"""
<div style="position:fixed;top:20px;right:20px;background:white;padding:14px 18px;
border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,0.15);z-index:9999;max-width:240px;">
<div style="font-weight:bold;margin-bottom:10px;font-size:14px;">Community (top mechanic)</div>
{legend_items}
</div>"""
with open('mechanics_network.html', 'r') as f:
html = f.read()
# More reliable injection point
if '</body>' in html:
html = html.replace('</body>', legend_html + '\n</body>')
else:
html = html + legend_html
with open('mechanics_network.html', 'w') as f:
f.write(html)
print('Saved - open mechanics_network.html in browser')
Saved - open mechanics_network.html in browser
Interpretation
The mechanics co-occurence network reveals 4 distinct communities which correspond to recognisable game styles.
Community 0 (red - hand management, 24 mechanics) captures card and social game mechanics such as Hand Management (2910 games), Variable Player Powers (1829 games), Betting and Bluffing (850 games), Simultaneous Action Selection (701 games), and Deduction (681 games). This seems to be the most popular mechanic.
Community 1 (blue - set collection, 23 mechanics) captures card and game mechanicss such as Set Collection (1852 games), Drafting (1350 games), Tile Placement (1161 games), Area Majority / Influence, (1154 games), Modular Board (1151 games).
Community 2 (green- dice rolling, 19 mechanics) groups Dice Rolling (3091 games), Grid Movement (755 games), Simulation (712 games), Hexagon Grid (684 games), Campaign / Battle Card Driven (338 games).
Commnity 3 (purple - cooperative, 5 mechanics) groups Cooperative Game (1011 games), Push Your Luck (574 games), Dexterity (478 games), Real-Time (458 games), Pattern Recognition (270 games).
Community 3 (purple) stands apart as a smaller cooperative compared to the rest. Cross community edges visible in the centre of the network suggest that some mechanics, such as Hand Management (red) and Dice Rolling (green) are versatile to bridge multiple game styles.
2b) Adjacency Heatmap (Optional — Bonus)¶
Produce an adjacency heatmap of co-occurrence strength between the top 25–30 most frequent mechanics, using Altair or seaborn.
- Sort rows and columns by community membership so that clusters are visually grouped.
- Hint: Build a square DataFrame from the co-occurrence counts. Use a diverging or sequential color scale for intensity.
Write 2–3 sentences comparing the heatmap with the force-directed graph from 2a: which view makes it easier to identify clusters? Which better reveals specific strong or surprising pairings?
# Top 30 mechanics by game count
top30 = sorted(mechanic_counts, key=mechanic_counts.get, reverse=True)[:30]
# Build square co-occurrence matrix
matrix = pd.DataFrame(0, index=top30, columns=top30)
for (a, b), weight in mechanic_edge_counts.items():
if a in top30 and b in top30:
matrix.loc[a, b] = weight
matrix.loc[b, a] = weight
# Sort rows and columns by community membership
top30_comm = [mech_community_map.get(m, -1) for m in top30]
top30_sorted = sorted(top30, key=lambda m: mech_community_map.get(m, -1))
matrix = matrix.loc[top30_sorted, top30_sorted]
# Melt matrix to long format for Altair
matrix_long = matrix.reset_index().melt(id_vars='index')
matrix_long.columns = ['Mechanic_A', 'Mechanic_B', 'Co_occurrences']
# Preserve community-sorted order
sort_order = top30_sorted
heatmap = alt.Chart(matrix_long).mark_rect().encode(
x=alt.X('Mechanic_A:N', sort=sort_order, axis=alt.Axis(labelAngle=-45, labelFontSize=10)),
y=alt.Y('Mechanic_B:N', sort=sort_order, axis=alt.Axis(labelFontSize=10)),
color=alt.Color('Co_occurrences:Q', scale=alt.Scale(scheme='blues'), legend=alt.Legend(title='Co-occurrences')),
tooltip=['Mechanic_A:N', 'Mechanic_B:N', 'Co_occurrences:Q']
).properties(
width=600,
height=600,
title='Top 30 Mechanics Co-occurrence Heatmap'
)
heatmap
<VegaLite 5 object> If you see this message, it means the renderer has not been properly enabled for the frontend that you are using. For more information, see https://altair-viz.github.io/user_guide/display_frontends.html#troubleshooting
heatmap.save('mechanics_heatmap.html')
print("Saved to mechanics_heatmap.html")
Saved to mechanics_heatmap.html
Interpretation:
The adjacency heatmap confirms the 4 community clusters identified in the force-directed graph, with 3 visible blocks along the diagonal corresponding to the mechanics (set collection, drafting, tile placement), (Hand Management, Variable Player Powers, Deduction), (Dice Rolling, Grid Movement, Hexagon Grid). the heatmap makes it easy to identify strength of specific pairings. E.g. hand management and variable player powers show the darkest cell in the top left block, suggesting they're the most frequent co-occuring pair in the dataset. The force directed graph from 2a is better at showing overall network structure and cross community connections. While the heatmap pinpoints exact co-occurence counts between specific mechanic pairs that might be hard to read from edge widths alone.