Inspiration

League of Legends players often receive vague advice like “farm better” or “ward more,” but lack personalized, data-driven insights. We wanted to build a coaching AI that actually understands your gameplay — not just stats — and provides actionable advice based on your match history, strengths, and social synergies. This project was inspired by:

  • Amazon Bedrock’s new agentic AI stack
  • Gaming Dashboard Design
  • Valorant 2024 Year End Review Review
  • Our desire to make coaching accessible, measurable, and fun through social comparisons.

How the Coaching Agent Works

The coaching agent provides insights by performing a detailed, real-time analysis of a player's recent performance and computing all scores on demand.

1. Strengths & Weaknesses Analysis This analysis is handled by the StrengthAndWeaknessesLambda. When a user requests an analysis, the process is as follows:

  • Data Collection: The function queries the Riot API for a player's 20 most recent matches.
  • Raw Metrics: It processes these matches to calculate aggregate and average statistics, such as KDA (Kills/Deaths/Assists), CS (Creep Score), gold, damage dealt, vision score, and win rate.
  • Scoring Logic: These raw metrics are then normalized against a set of predefined benchmarks to generate six key scores on a 0-100 scale:
    • Farming: Scored based on average CS and gold per game.
    • Vision: Scored based on average vision score per game.
    • Aggression: A combined score of KDA and average damage per game.
    • Teamplay: A combined score of win rate and assist-to-kill ratio.
    • Consistency: Calculated from the standard deviation of a player's "impact score" (Kills + Assists - Deaths) across their games. A lower deviation results in a higher consistency score.
    • Versatility: A combined score based on the number of unique champions played and the player's average champion mastery score.

2. Social Comparison & Synergy Analysis This analysis is handled by the SocialComparisonLambda and uses the 6-score profiles generated above.

  • Playstyle Archetype: The agent first determines a player's primary "playstyle archetype" (e.g., Carry/Farmer, Aggressor/Slayer, Support/Team Player) by identifying their single highest score. A priority list is used to break any ties.
  • Synergy Check: It then checks if the two players' archetypes form a "complementary pair" as defined in its logic (e.g., a Carry/Farmer pairs well with a Support/Team Player).
  • Playstyle Similarity: Finally, it calculates a cosine similarity score. This treats the two players' 6-point score profiles as vectors and calculates the angular similarity between them, resulting in a percentage (0-100%) that represents how similar their overall playstyles are.

Project Architecture

System Architechture Design

Here is the technical breakdown of the project components shown in the diagram.

1. Data Layer

  • Riot API: The primary data source, used to retrieve real-time player account, match history, mastery, and champion data.
  • AWS DynamoDB: A NoSQL database used as a cache. It stores the computed results of player analyses (like the 6-score profile) to reduce redundant Riot API calls, minimize latency, and stay within API rate limits.

2. Computation Layer

  • AWS Lambda Functions: Serverless functions that contain the core business logic.
    • StrengthAndWeaknessesLambda: Invoked to perform the detailed performance analysis described above, fetching data from the Riot API and calculating the six key scores.
    • SocialComparisonLambda: Invoked to compare two players. It retrieves their cached profiles (or computes them) and runs the playstyle archetype, synergy, and similarity logic.
    • YearEndSummaryLambda: Generates an annual performance summary for a player, similar to a "Spotify Wrapped" for League of Legends.

3. AI Reasoning Layer

  • Amazon Bedrock Agents: This is the "brain" of the conversational interface, powered by the Anthropic Claude 3 Sonnet model. Its job is to understand natural language requests from the user.
  • Action Groups: These are the crucial connectors that allow the Bedrock Agent to be functional. They map the user's intent to a specific computational task.
    • When the agent understands a user's request (e.g., "How well do I play with my friend?"), it calls the appropriate action group (e.g., the social-comparison-analysis group).
    • This action group then invokes the corresponding SocialComparisonLambda function, passes it the required parameters (like the player names), and receives the resulting JSON report.
    • The Bedrock Agent then formats this JSON data into a helpful, easy-to-read natural language response for the user.

4. Frontend

A lightweight React dashboard, hosted and deployed using AWS Amplify, visualizes:

  • Performance Radar Chart
  • Role Distribution Pie Chart
  • Duo Synergy Matrix
  • Archetype Badges

Challenges we ran into

Challenge 1: Regional Routing Complexity Problem: Riot API uses different routing values for account vs. match endpoints (e.g., "sea" vs "asia" for SG2 servers). Solution: Implemented dual-layer routing:

REGION_TO_PLATFORMS = {
    'americas': ['na1', 'br1', 'la1', 'la2', 'oc1'],
    'asia': ['kr', 'jp1'],
    'sea': ['sg2', 'ph2', 'th2', 'tw2', 'vn2']
}

The system tries each platform within a region until a valid response is received.

Challenge 2: Rate Limiting Problem: Riot API has strict rate limits (20 requests/second, 100 requests/2 minutes). Solution: Implemented exponential backoff with retry-after header parsing:

def request_with_retry(url, max_retries=3):
    for attempt in range(max_retries):
        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 1))
            time.sleep(retry_after)

Challenge 3: Champion Name Normalization Problem: API returns champion names with inconsistent formatting (e.g., "Nunu & Willump" vs "Nunu"). Solution: Created normalized lookup dictionaries:

NORMALIZED_ID_MAP = {
    _normalize_champion_name(name): champ_id 
    for name, champ_id in champion_id_map.items()
}
_ID_ALIAS_SOURCE = {
    "nunuwillump": "nunu",
    "renataglasc": "renata",
    "wukong": "monkeyking",
}

Challenge 4: Caching Strategy Problem: Repeated analysis requests were slow and hit API limits. Solution: Implemented DynamoDB-based caching with composite keys:

Accomplishments that we're proud of

Built a fully functional AI coach that converses naturally using AWS Bedrock. Integrated real-world match data pipelines end-to-end (Riot → AWS → Agent). Created an interpretable scoring system that transforms raw metrics into human-readable insights. Achieved sub-3 second response times for cached analyses. Seamlessly connected AI reasoning + gameplay analytics + social insight.

What we learned

  • How to architect a serverless multi-agent pipeline using AWS Bedrock, DynamoDB, and Lambda.
  • How embedding-based retrieval (RAG) enables contextual game knowledge.
  • Importance of normalizing esports data schemas across multiple APIs.
  • How to balance game analytics with natural language explanation — a bridge between data science and coaching.

What's next for Worlds 2026 Ticket Winner

  1. Deepening AWS Integration: explore more possibilities with AWS services such as Bedrock, Lambda, OpenSearch, and SageMaker to enhance scalability, latency handling, and model performance.
  2. Riot Production API Access: request access to Riot’s production API to overcome current rate-limit constraints and enable full-scale player analytics at competitive reliability levels.
  3. Unified Data Pipeline: consolidate and optimize all API calls across Riot endpoints into a single, orchestrated data flow to significantly reduce redundant requests and improve efficiency.
  4. Web Dashboard Expansion: enhance player experience with interactive coaching timelines, match replay integration, and voice-based insights powered by Bedrock Agents.
  5. Open Beta at Worlds 2026: launch a community leaderboard for global testing, with winners receiving exclusive Worlds 2026 tickets.

Built With

Share this project:

Updates