Claude-skill-registry game-analyzer
Analyze TraitorSim game logs, trust matrix evolution, voting patterns, mission outcomes, and emergent social behaviors. Use when examining game results, debugging gameplay issues, analyzing agent strategies, or when asked about game analysis, trust matrices, voting patterns, or emergent behaviors.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/game-analyzer" ~/.claude/skills/majiayu000-claude-skill-registry-game-analyzer && rm -rf "$T"
skills/data/game-analyzer/SKILL.mdGame Analyzer
Analyze TraitorSim game logs to understand trust matrix evolution, voting patterns, mission performance, and emergent social dynamics. This skill helps debug gameplay issues, validate agent behaviors, and identify interesting strategic patterns.
Quick Start
# Analyze a completed game from src.traitorsim.analysis.game_analyzer import GameAnalyzer analyzer = GameAnalyzer(game_log_path="data/logs/game_2025_12_21.json") # Get summary statistics summary = analyzer.get_summary() print(f"Winner: {summary['winner']}") print(f"Days survived: {summary['days']}") print(f"Faithfuls banished: {summary['faithfuls_banished']}") print(f"Traitors banished: {summary['traitors_banished']}") # Analyze trust matrix evolution trust_evolution = analyzer.analyze_trust_evolution() analyzer.plot_trust_evolution(player_id="player_03") # Analyze voting patterns voting_analysis = analyzer.analyze_voting_patterns() print(f"Most accurate voter: {voting_analysis['most_accurate']}") print(f"Most swayed voter: {voting_analysis['most_swayed']}")
What to Analyze
1. Trust Matrix Evolution
What to look for:
- Do agents update suspicions based on evidence?
- Are Bayesian updates working correctly?
- Do high Openness agents update beliefs more readily?
- Do Traitors maintain low suspicion scores?
Analysis:
def analyze_trust_evolution(game_log): """Track how each agent's trust matrix changes over time""" trust_history = defaultdict(list) # player_id -> [(day, target_id, suspicion)] for event in game_log["events"]: if event["type"] == "trust_matrix_update": trust_history[event["player_id"]].append({ "day": event["day"], "target_id": event["target_id"], "suspicion_before": event["suspicion_before"], "suspicion_after": event["suspicion_after"], "evidence": event["evidence"] }) # Analyze patterns for player_id, updates in trust_history.items(): player = get_player(player_id) # Check if high Openness correlates with more updates num_updates = len(updates) openness = player["personality"]["openness"] # Expected: High O = more updates print(f"{player['name']} (O={openness:.2f}): {num_updates} trust updates") # Check if updates are evidence-based for update in updates: delta = abs(update["suspicion_after"] - update["suspicion_before"]) if delta > 0.2: # Significant update print(f" Day {update['day']}: {update['target_id']} " f"{update['suspicion_before']:.2f} → {update['suspicion_after']:.2f}") print(f" Evidence: {update['evidence']}")
Visualization:
import matplotlib.pyplot as plt def plot_trust_evolution(game_log, player_id): """Plot how one agent's suspicions evolve over time""" fig, ax = plt.subplots(figsize=(12, 6)) # Get trust updates for this player updates = [e for e in game_log["events"] if e["type"] == "trust_matrix_update" and e["player_id"] == player_id] # Group by target by_target = defaultdict(list) for update in updates: by_target[update["target_id"]].append({ "day": update["day"], "suspicion": update["suspicion_after"] }) # Plot each target's suspicion over time for target_id, data in by_target.items(): days = [d["day"] for d in data] suspicions = [d["suspicion"] for d in data] target = get_player(target_id) color = "red" if target["role"] == "TRAITOR" else "blue" ax.plot(days, suspicions, marker='o', label=target["name"], color=color, alpha=0.7) ax.set_xlabel("Day") ax.set_ylabel("Suspicion Score (0=trust, 1=certain traitor)") ax.set_title(f"Trust Evolution: {get_player(player_id)['name']}") ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') ax.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(f"analysis/trust_evolution_{player_id}.png") print(f"Saved to analysis/trust_evolution_{player_id}.png")
2. Voting Pattern Analysis
What to look for:
- Are voting blocs forming?
- Do agents vote consistently based on suspicions?
- Are Traitors coordinating votes?
- Do high Conscientiousness agents vote more consistently?
Analysis:
def analyze_voting_patterns(game_log): """Analyze voting behaviors and patterns""" voting_history = [] # List of {day, voter, nominee, banished, was_traitor} for event in game_log["events"]: if event["type"] == "round_table_vote": voting_history.append({ "day": event["day"], "voter": event["voter_id"], "nominee": event["nominee_id"], "banished": event.get("was_banished", False), "nominee_was_traitor": event.get("nominee_was_traitor", False) }) # 1. Calculate voting accuracy (voted for actual Traitors) accuracy = defaultdict(lambda: {"correct": 0, "incorrect": 0}) for vote in voting_history: if vote["banished"]: # Only count votes for banished players voter = vote["voter"] if vote["nominee_was_traitor"]: accuracy[voter]["correct"] += 1 else: accuracy[voter]["incorrect"] += 1 # Most accurate voter most_accurate = max(accuracy.items(), key=lambda x: x[1]["correct"] / (x[1]["correct"] + x[1]["incorrect"])) print(f"Most accurate voter: {get_player(most_accurate[0])['name']}") print(f" Correct: {most_accurate[1]['correct']}, Incorrect: {most_accurate[1]['incorrect']}") # 2. Detect voting blocs (agents who vote together frequently) vote_alignment = defaultdict(int) # (player_a, player_b) -> times voted same nominee for day in set(v["day"] for v in voting_history): day_votes = [v for v in voting_history if v["day"] == day] # For each pair of voters voters = list(set(v["voter"] for v in day_votes)) for i, voter_a in enumerate(voters): for voter_b in voters[i+1:]: # Did they vote for the same nominee? nominee_a = [v["nominee"] for v in day_votes if v["voter"] == voter_a] nominee_b = [v["nominee"] for v in day_votes if v["voter"] == voter_b] if nominee_a and nominee_b and nominee_a[0] == nominee_b[0]: vote_alignment[(voter_a, voter_b)] += 1 # Top voting blocs top_blocs = sorted(vote_alignment.items(), key=lambda x: x[1], reverse=True)[:5] print("\nTop voting blocs (voted together most often):") for (player_a, player_b), count in top_blocs: print(f" {get_player(player_a)['name']} & {get_player(player_b)['name']}: {count} times") # 3. Check if Traitors coordinate traitors = [p["id"] for p in game_log["players"] if p["role"] == "TRAITOR"] if len(traitors) >= 2: traitor_coordination = sum( count for (a, b), count in vote_alignment.items() if a in traitors and b in traitors ) print(f"\nTraitor coordination: {traitor_coordination} aligned votes") return { "most_accurate": most_accurate, "voting_blocs": top_blocs, "traitor_coordination": traitor_coordination if len(traitors) >= 2 else 0 }
3. Mission Performance Analysis
What to look for:
- Do mission outcomes correlate with agent stats?
- Are Traitors sabotaging effectively?
- Can we detect sabotage vs. genuine failure?
Analysis:
def analyze_mission_performance(game_log): """Analyze mission outcomes and detect sabotage patterns""" missions = [e for e in game_log["events"] if e["type"] == "mission_result"] for mission in missions: print(f"\nDay {mission['day']}: {mission['mission_name']}") print(f"Outcome: {'✅ SUCCESS' if mission['success'] else '❌ FAILURE'}") print(f"Prize pot: £{mission['prize_pot_change']:+,}") # Analyze participants participants = mission["participants"] # Calculate expected success rate expected_success_rate = 0 for participant in participants: player = get_player(participant["player_id"]) stat_name = mission["primary_stat"] # e.g., "intellect" stat_value = player["stats"][stat_name] # Success probability = stat - stress - personality_modifier stress = participant.get("stress", 0) prob = max(0, min(1, stat_value - stress)) expected_success_rate += prob / len(participants) print(f"Expected success rate: {expected_success_rate:.1%}") # Detect sabotage if not mission["success"] and expected_success_rate > 0.7: print("⚠️ Likely sabotage (high expected success but failed)") # Who sabotaged? saboteurs = [] for participant in participants: player = get_player(participant["player_id"]) if player["role"] == "TRAITOR": saboteurs.append(player["name"]) if saboteurs: print(f"Traitors present: {', '.join(saboteurs)}") # Check if failure was due to low stats elif not mission["success"]: low_performers = [ get_player(p["player_id"])["name"] for p in participants if get_player(p["player_id"])["stats"][mission["primary_stat"]] < 0.5 ] if low_performers: print(f"Low performers: {', '.join(low_performers)}")
4. Personality-Behavior Correlation
What to look for:
- Do high Extraversion agents dominate Round Tables?
- Do low Agreeableness agents make more accusations?
- Do personality traits correlate with survival?
Analysis:
def analyze_personality_behavior(game_log): """Correlate personality traits with behaviors""" import numpy as np from scipy.stats import pearsonr players = game_log["players"] # 1. Extraversion vs. Round Table participation extraversion_scores = [] speaking_counts = [] for player in players: extraversion = player["personality"]["extraversion"] extraversion_scores.append(extraversion) # Count how many times they spoke at Round Table speaking_count = len([ e for e in game_log["events"] if e["type"] == "round_table_statement" and e["player_id"] == player["id"] ]) speaking_counts.append(speaking_count) correlation, p_value = pearsonr(extraversion_scores, speaking_counts) print(f"Extraversion vs. Speaking: r={correlation:.3f}, p={p_value:.3f}") # 2. Agreeableness vs. Accusations agreeableness_scores = [] accusation_counts = [] for player in players: agreeableness = player["personality"]["agreeableness"] agreeableness_scores.append(agreeableness) # Count accusations made accusation_count = len([ e for e in game_log["events"] if e["type"] == "accusation" and e["accuser_id"] == player["id"] ]) accusation_counts.append(accusation_count) correlation, p_value = pearsonr(agreeableness_scores, accusation_counts) print(f"Agreeableness vs. Accusations: r={correlation:.3f}, p={p_value:.3f}") print(f"Expected: Negative correlation (low A = more accusations)") # 3. Neuroticism vs. Survival neuroticism_scores = [] survival_days = [] for player in players: neuroticism = player["personality"]["neuroticism"] neuroticism_scores.append(neuroticism) # Find when eliminated elimination = next(( e for e in game_log["events"] if e["type"] in ["banishment", "murder"] and e["victim_id"] == player["id"] ), None) survival_days.append(elimination["day"] if elimination else game_log["final_day"]) correlation, p_value = pearsonr(neuroticism_scores, survival_days) print(f"Neuroticism vs. Survival: r={correlation:.3f}, p={p_value:.3f}")
5. Emergent Behavior Detection
What to look for:
- Unexpected alliances forming
- "Bus throwing" (Traitors betraying each other)
- "Shield bluffing" (false Shield claims)
- Alliance betrayals
Analysis:
def detect_emergent_behaviors(game_log): """Identify interesting emergent patterns""" # 1. Detect "Bus Throwing" (Traitor voting for Traitor) traitors = [p["id"] for p in game_log["players"] if p["role"] == "TRAITOR"] bus_throws = [] for event in game_log["events"]: if event["type"] == "round_table_vote": if event["voter_id"] in traitors and event["nominee_id"] in traitors: bus_throws.append({ "day": event["day"], "thrower": get_player(event["voter_id"])["name"], "thrown": get_player(event["nominee_id"])["name"], "was_banished": event.get("was_banished", False) }) if bus_throws: print("🚌 Bus Throwing Detected:") for bt in bus_throws: status = "BANISHED" if bt["was_banished"] else "survived" print(f" Day {bt['day']}: {bt['thrower']} voted for {bt['thrown']} ({status})") # 2. Detect Shield Bluffs shield_claims = [e for e in game_log["events"] if e["type"] == "shield_claim"] actual_shields = [e for e in game_log["events"] if e["type"] == "shield_used"] bluffs = [] for claim in shield_claims: # Check if shield was actually used by this player actual = any(s["player_id"] == claim["player_id"] for s in actual_shields) if not actual: bluffs.append({ "day": claim["day"], "bluffer": get_player(claim["player_id"])["name"] }) if bluffs: print("\n🛡️ Shield Bluffs Detected:") for bluff in bluffs: print(f" Day {bluff['day']}: {bluff['bluffer']} falsely claimed Shield") # 3. Detect Unlikely Alliances (high suspicion but still voting together) for day in range(1, game_log["final_day"] + 1): day_votes = [e for e in game_log["events"] if e["type"] == "round_table_vote" and e["day"] == day] # Find players who voted for same nominee despite high mutual suspicion # (Would need trust matrix data)
Instructions
When Analyzing a Game
-
Load game log:
import json with open("data/logs/game_2025_12_21.json") as f: game_log = json.load(f) -
Run all analyses:
from src.traitorsim.analysis.game_analyzer import GameAnalyzer analyzer = GameAnalyzer(game_log) analyzer.run_all_analyses() -
Generate report:
analyzer.generate_report(output_path="analysis/game_report.md")
When Debugging Agent Behavior
-
Focus on specific agent:
agent_analysis = analyzer.analyze_agent(player_id="player_03") -
Check expected behavior:
- High O agents should update trust frequently
- High E agents should speak more at Round Table
- Low A agents should make more accusations
- High C agents should perform better in missions
-
Identify anomalies:
- Traitors maintaining perfect cover
- Faithfuls with no trust updates
- Agents not using their archetype advantages
Common Analysis Patterns
Pattern 1: Why Did X Win?
winner = game_log["winner"] winner_analysis = analyzer.analyze_agent(winner["id"]) # Check strategic decisions print(f"Voting accuracy: {winner_analysis['voting_accuracy']}") print(f"Mission performance: {winner_analysis['mission_success_rate']}") print(f"Alliances formed: {winner_analysis['alliances']}") print(f"Times targeted: {winner_analysis['times_nominated']}")
Pattern 2: Why Did Traitors Lose?
traitors = [p for p in game_log["players"] if p["role"] == "TRAITOR"] for traitor in traitors: analysis = analyzer.analyze_agent(traitor["id"]) # Check if they were detected if traitor["id"] in game_log["banishments"]: print(f"{traitor['name']} was banished on day {analysis['banished_day']}") print(f" Voting patterns: {analysis['voting_consistency']}") print(f" Mission sabotages: {analysis['sabotage_count']}") print(f" Suspicion level at banishment: {analysis['average_suspicion']}")
Pattern 3: Most Interesting Moment
# Find days with most dramatic events drama_scores = [] for day in range(1, game_log["final_day"] + 1): day_events = [e for e in game_log["events"] if e["day"] == day] drama_score = ( len([e for e in day_events if e["type"] == "banishment"]) * 10 + len([e for e in day_events if e["type"] == "recruitment"]) * 15 + len([e for e in day_events if e["type"] == "shield_used"]) * 8 + len([e for e in day_events if e["type"] == "mission_result" and not e["success"]]) * 5 ) drama_scores.append((day, drama_score)) most_dramatic = max(drama_scores, key=lambda x: x[1]) print(f"Most dramatic day: Day {most_dramatic[0]} (score: {most_dramatic[1]})")
When to Use This Skill
Use this skill when:
- Analyzing completed games to understand outcomes
- Debugging agent behavior issues
- Validating personality-behavior correlations
- Identifying interesting emergent patterns
- Generating game reports and highlights
- Comparing different game configurations
When NOT to Use This Skill
Don't use this skill for:
- Real-time game state monitoring (use game engine directly)
- Generating personas (use persona-pipeline skill)
- Validating content (use world-bible-validator skill)
- Managing memory systems (use memory-debugger skill)