Skip to content

Participant

Represents a match participant.

Source code in nexar/models/match/participant.py
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
@dataclass(frozen=True)
class Participant:
    """Represents a match participant."""

    # Core participant data
    puuid: str
    """Player's universally unique identifier."""

    _summoner_name: str
    """
    Player's summoner name at the time of the match.

    **Deprecated by Riot.** Use `Participant.game_name` instead.
    """

    champion_id: int
    """
    Unique identifier for the champion played.

    Riot docs:
    > Prior to patch 11.4, on Feb 18th, 2021, this field returned invalid championIds.
    We recommend determining the champion based on the championName field for matches played prior
    to patch 11.4.
    """

    champion_name: str
    """
    Name of the champion played.
    """

    @property
    def champion_icon_url(self) -> str:
        """
        Link to champion icon URL via CDragon.

        Useful for Discord embeds or Web UI.
        """
        return (
            f"https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/"
            f"global/default/v1/champion-icons/{self.champion_id}.png"
        )

    team_id: int
    """Team identifier (100 for blue side, 200 for red side)."""

    @property
    def team_color(self) -> str:
        """Team color. Colloquially players use the terms "blue side" or "red side"."""
        return "Blue" if self.team_id == BLUE_TEAM_ID else "Red"

    @property
    @warnings.deprecated("Participant.summoner_name is deprecated. Use Participant.game_name instead.")
    def summoner_name(self) -> str:
        """
        Player's summoner name at the time of the match.

        **Deprecated by Riot.** Use `Participant.game_name` instead.
        """
        return self._summoner_name

    participant_id: int
    """Participant's position in the match (1-10)."""

    # Basic stats
    kills: int
    """Number of enemy champions killed."""

    deaths: int
    """Number of times the participant died."""

    assists: int
    """Number of assists on enemy champion kills."""

    def kda(self, *, as_str: bool = False) -> float | str:
        """
        KDA ratio or formatted KDA string.

        By default returns the KDA ratio as (kills + assists) / max(1, deaths).
        If as_str=True, returns a formatted string like '5/2/10'.

        This is always available since kills, deaths, and assists are present
        for all game modes. For the challenge-specific KDA, use `Participant.challenges.kda`
        (only available when challenges are included in the API response).
        """
        if as_str:
            return f"{self.kills}/{self.deaths}/{self.assists}"
        return (self.kills + self.assists) / max(self.deaths, 1)

    async def get_player(
        self,
        client: "NexarClient",
        *,
        region: "Region | None" = None,
    ) -> "Player":
        """
        Get a Player object for this participant.

        Uses the participant's PUUID to look up their Riot account and create
        a Player, which provides convenient access to summoner data, league
        entries, match history, and more.

        Args:
            client: The NexarClient instance to use for API calls.
            region: The player's region (defaults to client default).

        Returns:
            A Player instance for this participant.

        """
        from nexar.models.player import Player

        return await Player.create(client=client, puuid=self.puuid, region=region)

    champion_level: int
    """Final champion level achieved."""

    gold_earned: int
    """Total gold earned during the match."""

    gold_spent: int
    """Total gold spent on items."""

    vision_score: int
    """Vision score based on wards placed, cleared, etc."""

    win: bool
    """Whether the participant's team won the match."""

    # Items
    item_0: int
    """Item in slot 0 (item ID, 0 if empty)."""

    item_1: int
    """Item in slot 1 (item ID, 0 if empty)."""

    item_2: int
    """Item in slot 2 (item ID, 0 if empty)."""

    item_3: int
    """Item in slot 3 (item ID, 0 if empty)."""

    item_4: int
    """Item in slot 4 (item ID, 0 if empty)."""

    item_5: int
    """Item in slot 5 (item ID, 0 if empty)."""

    item_6: int
    """Trinket item (item ID, 0 if empty)."""

    # Position and role
    individual_position: MatchParticipantPosition
    """
    Individual position assignment (TOP, JUNGLE, MIDDLE, BOTTOM, UTILITY).

    Riot API docs:
    > The individualPosition is the best guess for which position the player actually played in
    isolation of anything else.

    **Generally, you should use the team_position over the this.**
    """

    team_position: MatchParticipantPosition
    """
    Team-based position assignment (TOP, JUNGLE, MIDDLE, BOTTOM, UTILITY).

    Riot API docs:
    > The teamPosition is the best guess for which position the player actually played if we add
    the constraint that each team must have one top player, one jungle, one middle, etc.

    **Generally, you should use the this over the individual_position.**
    """

    lane: str
    """Lane assignment during the match."""

    role: str
    """Role assignment during the match."""

    # Ping stats
    all_in_pings: int
    """Number of 'all in' (Yellow crossed swords) pings used."""

    assist_me_pings: int
    """Number of 'assist me' (Green flag) pings used."""

    command_pings: int
    """Number of command (Blue generic (ALT+click)) pings used."""

    enemy_missing_pings: int
    """Number of 'enemy missing' (Yellow questionmark) pings used."""

    enemy_vision_pings: int
    """Number of 'enemy vision' (Red eyeball) pings used."""

    get_back_pings: int
    """Number of 'get back' (Yellow circle with horizontal line) pings used."""

    hold_pings: int
    """Number of 'hold' pings used."""

    need_vision_pings: int
    """Number of 'need vision' (Green ward) pings used."""

    on_my_way_pings: int
    """Number of 'on my way' (Blue arrow pointing at ground) pings used."""

    push_pings: int
    """Number of 'push' (Green minion) pings used."""

    vision_cleared_pings: int
    """Number of 'vision cleared' pings used."""

    # Kill stats
    baron_kills: int
    """Number of Baron kills."""

    double_kills: int
    """Number of double kills achieved."""

    dragon_kills: int
    """Number of Dragon kills."""

    inhibitor_kills: int
    """Number of inhibitor kills."""

    killing_sprees: int
    """Number of killing sprees achieved."""

    largest_killing_spree: int
    """Largest killing spree achieved."""

    largest_multi_kill: int
    """Largest multi-kill achieved."""

    nexus_kills: int
    """Number of Nexus kills."""

    penta_kills: int
    """Number of penta kills achieved."""

    quadra_kills: int
    """Number of quadra kills achieved."""

    triple_kills: int
    """Number of triple kills achieved."""

    turret_kills: int
    """Number of turret kills."""

    unreal_kills: int
    """
    (Presumably) Number of unreal kills achieved.

    Possibly for legacy/never released 6v6 gamemodes, but is unused and should be ignored.
    """

    # Damage stats
    damage_dealt_to_buildings: int
    """Total damage dealt to buildings."""

    damage_dealt_to_objectives: int
    """Total damage dealt to objectives (Baron, Dragon, etc.)."""

    damage_dealt_to_turrets: int
    """Total damage dealt to turrets."""

    damage_self_mitigated: int
    """Total damage mitigated by shields, resistances, etc."""

    largest_critical_strike: int
    """Largest critical strike damage dealt."""

    magic_damage_dealt: int
    """Total magic damage dealt."""

    magic_damage_dealt_to_champions: int
    """Magic damage dealt to enemy champions."""

    magic_damage_taken: int
    """Total magic damage taken."""

    physical_damage_dealt: int
    """Total physical damage dealt."""

    physical_damage_dealt_to_champions: int
    """Physical damage dealt to enemy champions."""

    physical_damage_taken: int
    """Total physical damage taken."""

    total_damage_dealt: int
    """Total damage dealt (all types combined)."""

    total_damage_dealt_to_champions: int
    """Total damage dealt to enemy champions (all types combined)."""

    total_damage_shielded_on_teammates: int
    """Total damage shielded on teammates."""

    total_damage_taken: int
    """Total damage taken (all types combined)."""

    true_damage_dealt: int
    """Total true damage dealt."""

    true_damage_dealt_to_champions: int
    """True damage dealt to enemy champions."""

    true_damage_taken: int
    """Total true damage taken."""

    # Minion and jungle stats
    neutral_minions_killed: int
    """
    Number of neutral minions (jungle monsters) killed.

    This only includes standard monsters Gromp, Red/Blue Buff, etc.
    Oddly enough, it also includes Ivern's Daisy.

    Riot docs:
    > neutralMinionsKilled = mNeutralMinionsKilled, which is incremented on kills of kPet and
    kJungleMonster
    """

    @property
    def total_jungle_minions_killed(self) -> int:
        """Alias for neutral_minions_killed."""
        return self.neutral_minions_killed

    total_ally_jungle_minions_killed: int
    """Number of allied jungle minions killed."""

    total_enemy_jungle_minions_killed: int
    """Number of enemy jungle minions killed."""

    total_minions_killed: int
    """
    Total number of minions killed.

    Riot docs:
    > totalMillionsKilled = mMinionsKilled, which is only incremented on kills of kTeamMinion,
    kMeleeLaneMinion, kSuperLaneMinion, kRangedLaneMinion and kSiegeLaneMinion
    """

    @property
    def creep_score(self) -> int:
        """
        Total "Creep score" or CS earned throughout the game.

        Combination of lane minions + jungle minions.
        """
        return self.total_minions_killed + self.neutral_minions_killed

    # Healing and support stats
    total_heal: int
    """
    Total healing done.

    Riot docs:
    > Whenever positive health is applied (which translates to all heals in the game but not things
    like regeneration), totalHeal is incremented by the amount of health received. This includes
    healing enemies, jungle monsters, yourself, etc
    """

    total_heals_on_teammates: int
    """
    Total healing done on teammates.

    Riot docs:
    > Whenever positive health is applied (which translates to all heals in the game but not things
    like regeneration), totalHealsOnTeammates is incremented by the amount of health received.
    This is post modified, so if you heal someone missing 5 health for 100 you will get +5
    totalHealsOnTeammates
    """

    total_units_healed: int
    """Total number of units healed."""

    # Time stats
    longest_time_spent_living: int
    """Longest time spent alive in seconds."""

    time_ccing_others: int
    """Time spent crowd controlling enemies in seconds."""

    time_played: int
    """Total time played in the match in seconds."""

    total_time_cc_dealt: int
    """Total crowd control time dealt in seconds."""

    total_time_spent_dead: int
    """Total time spent dead in seconds."""

    # Ward and vision stats
    detector_wards_placed: int
    """Number of detector wards (control wards) placed."""

    sight_wards_bought_in_game: int
    """Number of sight wards bought."""

    vision_wards_bought_in_game: int
    """Number of vision wards bought."""

    wards_killed: int
    """Number of enemy wards destroyed."""

    wards_placed: int
    """Total number of wards placed."""

    # Spell casts
    spell_1_casts: int
    """Number of times ability Q was cast."""

    spell_2_casts: int
    """Number of times ability W was cast."""

    spell_3_casts: int
    """Number of times ability E was cast."""

    spell_4_casts: int
    """Number of times ability R (ultimate) was cast."""

    summoner_1_casts: int
    """Number of times first summoner spell was cast."""

    summoner_1_id: int
    """ID of the first summoner spell."""

    summoner_2_casts: int
    """Number of times second summoner spell was cast."""

    summoner_2_id: int
    """ID of the second summoner spell."""

    # Structure stats
    inhibitor_takedowns: int
    """Number of inhibitor takedowns participated in."""

    inhibitors_lost: int
    """Number of allied inhibitors lost."""

    nexus_takedowns: int
    """Number of Nexus takedowns participated in."""

    nexus_lost: int
    """Number of allied Nexus lost."""

    turret_takedowns: int
    """Number of turret takedowns participated in."""

    turrets_lost: int
    """Number of allied turrets lost."""

    # Objectives
    objectives_stolen: int
    """Number of objectives stolen from enemies."""

    objectives_stolen_assists: int
    """Number of assists on stolen objectives."""

    # Game state
    champ_experience: int
    """Total champion experience gained."""

    champion_transform: int
    """
    Kayn transformation and end of game.

    - 0 = No transformation
    - 1 = Slayer (Red)
    - 2 = Assassin (Blue)

    Riot docs:
    > This field is currently only utilized for Kayn's transformations.
    (Legal values: 0 - None, 1 - Slayer, 2 - Assassin)
    """

    consumables_purchased: int
    """Number of consumable items purchased."""

    eligible_for_progression: bool
    """Whether the participant is eligible for progression."""

    first_blood_assist: bool
    """Whether the participant assisted in first blood."""

    first_blood_kill: bool
    """Whether the participant got first blood."""

    first_tower_assist: bool
    """Whether the participant assisted in first tower kill."""

    first_tower_kill: bool
    """Whether the participant got first tower kill."""

    game_ended_in_early_surrender: bool
    """
    Whether the game ended in an early surrender.

    Riot docs:
    > This is an offshoot of the OneStone challenge. The code checks if a spell with the same
    instance ID does the final point of damage to at least 2 Champions. It doesn't matter if
    they're enemies, but you cannot hurt your friends.
    """

    game_ended_in_surrender: bool
    """Whether the game ended in a surrender."""

    items_purchased: int
    """Total number of items purchased."""

    placement: int
    """Final placement in the match."""

    profile_icon: int
    """Profile icon ID used by the participant."""

    summoner_id: str
    """Summoner ID of the participant."""

    summoner_level: int
    """Summoner level at the time of the match."""

    team_early_surrendered: bool
    """Whether the participant's team early surrendered."""

    # Complex nested objects (optionally included by Riot)
    perks: "Perks | None"
    """Rune and perk information. May be None if not included in the API response."""

    challenges: "Challenges | None"
    """Challenge completion data. May be None if not included in the API response."""

    missions: "Missions | None"
    """Mission completion data. May be None if not included in the API response."""

    # Riot ID
    game_name: str | None = None
    """Riot ID game name, if available."""

    tagline: str | None = None
    """Riot ID tagline, if available."""

    # Game state (optional)
    bounty_level: int | None = None
    """Current bounty level, if applicable."""

    # Player scores (from missions)
    player_score_0: int | None = None
    """Mission score 0, if applicable."""

    player_score_1: int | None = None
    """Mission score 1, if applicable."""

    player_score_2: int | None = None
    """Mission score 2, if applicable."""

    player_score_3: int | None = None
    """Mission score 3, if applicable."""

    player_score_4: int | None = None
    """Mission score 4, if applicable."""

    player_score_5: int | None = None
    """Mission score 5, if applicable."""

    player_score_6: int | None = None
    """Mission score 6, if applicable."""

    player_score_7: int | None = None
    """Mission score 7, if applicable."""

    player_score_8: int | None = None
    """Mission score 8, if applicable."""

    player_score_9: int | None = None
    """Mission score 9, if applicable."""

    player_score_10: int | None = None
    """Mission score 10, if applicable."""

    player_score_11: int | None = None
    """Mission score 11, if applicable."""

    # Player augments (for specific game modes)
    player_augment_1: int | None = None
    """Player augment 1, if applicable (mode-specific)."""

    player_augment_2: int | None = None
    """Player augment 2, if applicable (mode-specific)."""

    player_augment_3: int | None = None
    """Player augment 3, if applicable (mode-specific)."""

    player_augment_4: int | None = None
    """Player augment 4, if applicable (mode-specific)."""

    player_subteam_id: int | None = None
    """Player subteam ID, if applicable (mode-specific)."""

    subteam_placement: int | None = None
    """Subteam placement, if applicable (mode-specific)."""

    @classmethod
    def from_api_response(cls, data: dict[str, Any]) -> "Participant":
        """Create Participant from API response."""
        from .challenges import Challenges, Missions
        from .perks import Perks

        return cls(
            # Core participant data
            puuid=data["puuid"],
            _summoner_name=data["summonerName"],
            champion_id=data["championId"],
            champion_name=data["championName"],
            team_id=data["teamId"],
            participant_id=data["participantId"],
            # Basic stats
            kills=data["kills"],
            deaths=data["deaths"],
            assists=data["assists"],
            champion_level=data["champLevel"],
            gold_earned=data["goldEarned"],
            gold_spent=data["goldSpent"],
            vision_score=data["visionScore"],
            win=data["win"],
            # Items
            item_0=data["item0"],
            item_1=data["item1"],
            item_2=data["item2"],
            item_3=data["item3"],
            item_4=data["item4"],
            item_5=data["item5"],
            item_6=data["item6"],
            # Position and role
            individual_position=MatchParticipantPosition(data["individualPosition"]),
            team_position=MatchParticipantPosition(data["teamPosition"]),
            lane=data["lane"],
            role=data["role"],
            # Ping stats
            all_in_pings=data["allInPings"],
            assist_me_pings=data["assistMePings"],
            command_pings=data["commandPings"],
            enemy_missing_pings=data["enemyMissingPings"],
            enemy_vision_pings=data["enemyVisionPings"],
            get_back_pings=data["getBackPings"],
            hold_pings=data["holdPings"],
            need_vision_pings=data["needVisionPings"],
            on_my_way_pings=data["onMyWayPings"],
            push_pings=data["pushPings"],
            vision_cleared_pings=data["visionClearedPings"],
            # Kill stats
            baron_kills=data["baronKills"],
            double_kills=data["doubleKills"],
            dragon_kills=data["dragonKills"],
            inhibitor_kills=data["inhibitorKills"],
            killing_sprees=data["killingSprees"],
            largest_killing_spree=data["largestKillingSpree"],
            largest_multi_kill=data["largestMultiKill"],
            nexus_kills=data["nexusKills"],
            penta_kills=data["pentaKills"],
            quadra_kills=data["quadraKills"],
            triple_kills=data["tripleKills"],
            turret_kills=data["turretKills"],
            unreal_kills=data["unrealKills"],
            # Damage stats
            damage_dealt_to_buildings=data["damageDealtToBuildings"],
            damage_dealt_to_objectives=data["damageDealtToObjectives"],
            damage_dealt_to_turrets=data["damageDealtToTurrets"],
            damage_self_mitigated=data["damageSelfMitigated"],
            largest_critical_strike=data["largestCriticalStrike"],
            magic_damage_dealt=data["magicDamageDealt"],
            magic_damage_dealt_to_champions=data["magicDamageDealtToChampions"],
            magic_damage_taken=data["magicDamageTaken"],
            physical_damage_dealt=data["physicalDamageDealt"],
            physical_damage_dealt_to_champions=data["physicalDamageDealtToChampions"],
            physical_damage_taken=data["physicalDamageTaken"],
            total_damage_dealt=data["totalDamageDealt"],
            total_damage_dealt_to_champions=data["totalDamageDealtToChampions"],
            total_damage_shielded_on_teammates=data["totalDamageShieldedOnTeammates"],
            total_damage_taken=data["totalDamageTaken"],
            true_damage_dealt=data["trueDamageDealt"],
            true_damage_dealt_to_champions=data["trueDamageDealtToChampions"],
            true_damage_taken=data["trueDamageTaken"],
            # Minion and jungle stats
            neutral_minions_killed=data["neutralMinionsKilled"],
            total_ally_jungle_minions_killed=data["totalAllyJungleMinionsKilled"],
            total_enemy_jungle_minions_killed=data["totalEnemyJungleMinionsKilled"],
            total_minions_killed=data["totalMinionsKilled"],
            # Healing and support stats
            total_heal=data["totalHeal"],
            total_heals_on_teammates=data["totalHealsOnTeammates"],
            total_units_healed=data["totalUnitsHealed"],
            # Time stats
            longest_time_spent_living=data["longestTimeSpentLiving"],
            time_ccing_others=data["timeCCingOthers"],
            time_played=data["timePlayed"],
            total_time_cc_dealt=data["totalTimeCCDealt"],
            total_time_spent_dead=data["totalTimeSpentDead"],
            # Ward and vision stats
            detector_wards_placed=data["detectorWardsPlaced"],
            sight_wards_bought_in_game=data["sightWardsBoughtInGame"],
            vision_wards_bought_in_game=data["visionWardsBoughtInGame"],
            wards_killed=data["wardsKilled"],
            wards_placed=data["wardsPlaced"],
            # Spell casts
            spell_1_casts=data["spell1Casts"],
            spell_2_casts=data["spell2Casts"],
            spell_3_casts=data["spell3Casts"],
            spell_4_casts=data["spell4Casts"],
            summoner_1_casts=data["summoner1Casts"],
            summoner_1_id=data["summoner1Id"],
            summoner_2_casts=data["summoner2Casts"],
            summoner_2_id=data["summoner2Id"],
            # Structure stats
            inhibitor_takedowns=data["inhibitorTakedowns"],
            inhibitors_lost=data["inhibitorsLost"],
            nexus_takedowns=data["nexusTakedowns"],
            nexus_lost=data["nexusLost"],
            turret_takedowns=data["turretTakedowns"],
            turrets_lost=data["turretsLost"],
            # Objectives
            objectives_stolen=data["objectivesStolen"],
            objectives_stolen_assists=data["objectivesStolenAssists"],
            # Game state
            bounty_level=data.get("bountyLevel"),
            champ_experience=data["champExperience"],
            champion_transform=data["championTransform"],
            consumables_purchased=data["consumablesPurchased"],
            eligible_for_progression=data["eligibleForProgression"],
            first_blood_assist=data["firstBloodAssist"],
            first_blood_kill=data["firstBloodKill"],
            first_tower_assist=data["firstTowerAssist"],
            first_tower_kill=data["firstTowerKill"],
            game_ended_in_early_surrender=data["gameEndedInEarlySurrender"],
            game_ended_in_surrender=data["gameEndedInSurrender"],
            items_purchased=data["itemsPurchased"],
            placement=data["placement"],
            profile_icon=data["profileIcon"],
            summoner_id=data["summonerId"],
            summoner_level=data["summonerLevel"],
            team_early_surrendered=data["teamEarlySurrendered"],
            # Complex nested objects (optionally included by Riot)
            perks=Perks.from_api_response(p_data) if (p_data := data.get("perks")) else None,
            challenges=Challenges.from_api_response(c_data) if (c_data := data.get("challenges")) else None,
            missions=Missions.from_api_response(m_data) if (m_data := data.get("missions")) else None,
            # Riot ID (optional fields)
            game_name=data.get("riotIdGameName"),
            tagline=data.get("riotIdTagline"),
            # Player scores (optional fields from missions)
            player_score_0=data.get("playerScore0"),
            player_score_1=data.get("playerScore1"),
            player_score_2=data.get("playerScore2"),
            player_score_3=data.get("playerScore3"),
            player_score_4=data.get("playerScore4"),
            player_score_5=data.get("playerScore5"),
            player_score_6=data.get("playerScore6"),
            player_score_7=data.get("playerScore7"),
            player_score_8=data.get("playerScore8"),
            player_score_9=data.get("playerScore9"),
            player_score_10=data.get("playerScore10"),
            player_score_11=data.get("playerScore11"),
            # Player augments (optional fields for specific game modes)
            player_augment_1=data.get("playerAugment1"),
            player_augment_2=data.get("playerAugment2"),
            player_augment_3=data.get("playerAugment3"),
            player_augment_4=data.get("playerAugment4"),
            player_subteam_id=data.get("playerSubteamId"),
            subteam_placement=data.get("subteamPlacement"),
        )

all_in_pings instance-attribute

Number of 'all in' (Yellow crossed swords) pings used.

assist_me_pings instance-attribute

Number of 'assist me' (Green flag) pings used.

assists instance-attribute

Number of assists on enemy champion kills.

baron_kills instance-attribute

Number of Baron kills.

bounty_level = None class-attribute instance-attribute

Current bounty level, if applicable.

challenges instance-attribute

Challenge completion data. May be None if not included in the API response.

champ_experience instance-attribute

Total champion experience gained.

champion_icon_url property

Link to champion icon URL via CDragon.

Useful for Discord embeds or Web UI.

champion_id instance-attribute

Unique identifier for the champion played.

Riot docs:

Prior to patch 11.4, on Feb 18th, 2021, this field returned invalid championIds. We recommend determining the champion based on the championName field for matches played prior to patch 11.4.

champion_level instance-attribute

Final champion level achieved.

champion_name instance-attribute

Name of the champion played.

champion_transform instance-attribute

Kayn transformation and end of game.

  • 0 = No transformation
  • 1 = Slayer (Red)
  • 2 = Assassin (Blue)

Riot docs:

This field is currently only utilized for Kayn's transformations. (Legal values: 0 - None, 1 - Slayer, 2 - Assassin)

command_pings instance-attribute

Number of command (Blue generic (ALT+click)) pings used.

consumables_purchased instance-attribute

Number of consumable items purchased.

creep_score property

Total "Creep score" or CS earned throughout the game.

Combination of lane minions + jungle minions.

damage_dealt_to_buildings instance-attribute

Total damage dealt to buildings.

damage_dealt_to_objectives instance-attribute

Total damage dealt to objectives (Baron, Dragon, etc.).

damage_dealt_to_turrets instance-attribute

Total damage dealt to turrets.

damage_self_mitigated instance-attribute

Total damage mitigated by shields, resistances, etc.

deaths instance-attribute

Number of times the participant died.

detector_wards_placed instance-attribute

Number of detector wards (control wards) placed.

double_kills instance-attribute

Number of double kills achieved.

dragon_kills instance-attribute

Number of Dragon kills.

eligible_for_progression instance-attribute

Whether the participant is eligible for progression.

enemy_missing_pings instance-attribute

Number of 'enemy missing' (Yellow questionmark) pings used.

enemy_vision_pings instance-attribute

Number of 'enemy vision' (Red eyeball) pings used.

first_blood_assist instance-attribute

Whether the participant assisted in first blood.

first_blood_kill instance-attribute

Whether the participant got first blood.

first_tower_assist instance-attribute

Whether the participant assisted in first tower kill.

first_tower_kill instance-attribute

Whether the participant got first tower kill.

game_ended_in_early_surrender instance-attribute

Whether the game ended in an early surrender.

Riot docs:

This is an offshoot of the OneStone challenge. The code checks if a spell with the same instance ID does the final point of damage to at least 2 Champions. It doesn't matter if they're enemies, but you cannot hurt your friends.

game_ended_in_surrender instance-attribute

Whether the game ended in a surrender.

game_name = None class-attribute instance-attribute

Riot ID game name, if available.

get_back_pings instance-attribute

Number of 'get back' (Yellow circle with horizontal line) pings used.

gold_earned instance-attribute

Total gold earned during the match.

gold_spent instance-attribute

Total gold spent on items.

hold_pings instance-attribute

Number of 'hold' pings used.

individual_position instance-attribute

Individual position assignment (TOP, JUNGLE, MIDDLE, BOTTOM, UTILITY).

Riot API docs:

The individualPosition is the best guess for which position the player actually played in isolation of anything else.

Generally, you should use the team_position over the this.

inhibitor_kills instance-attribute

Number of inhibitor kills.

inhibitor_takedowns instance-attribute

Number of inhibitor takedowns participated in.

inhibitors_lost instance-attribute

Number of allied inhibitors lost.

item_0 instance-attribute

Item in slot 0 (item ID, 0 if empty).

item_1 instance-attribute

Item in slot 1 (item ID, 0 if empty).

item_2 instance-attribute

Item in slot 2 (item ID, 0 if empty).

item_3 instance-attribute

Item in slot 3 (item ID, 0 if empty).

item_4 instance-attribute

Item in slot 4 (item ID, 0 if empty).

item_5 instance-attribute

Item in slot 5 (item ID, 0 if empty).

item_6 instance-attribute

Trinket item (item ID, 0 if empty).

items_purchased instance-attribute

Total number of items purchased.

killing_sprees instance-attribute

Number of killing sprees achieved.

kills instance-attribute

Number of enemy champions killed.

lane instance-attribute

Lane assignment during the match.

largest_critical_strike instance-attribute

Largest critical strike damage dealt.

largest_killing_spree instance-attribute

Largest killing spree achieved.

largest_multi_kill instance-attribute

Largest multi-kill achieved.

longest_time_spent_living instance-attribute

Longest time spent alive in seconds.

magic_damage_dealt instance-attribute

Total magic damage dealt.

magic_damage_dealt_to_champions instance-attribute

Magic damage dealt to enemy champions.

magic_damage_taken instance-attribute

Total magic damage taken.

missions instance-attribute

Mission completion data. May be None if not included in the API response.

need_vision_pings instance-attribute

Number of 'need vision' (Green ward) pings used.

neutral_minions_killed instance-attribute

Number of neutral minions (jungle monsters) killed.

This only includes standard monsters Gromp, Red/Blue Buff, etc. Oddly enough, it also includes Ivern's Daisy.

Riot docs:

neutralMinionsKilled = mNeutralMinionsKilled, which is incremented on kills of kPet and kJungleMonster

nexus_kills instance-attribute

Number of Nexus kills.

nexus_lost instance-attribute

Number of allied Nexus lost.

nexus_takedowns instance-attribute

Number of Nexus takedowns participated in.

objectives_stolen instance-attribute

Number of objectives stolen from enemies.

objectives_stolen_assists instance-attribute

Number of assists on stolen objectives.

on_my_way_pings instance-attribute

Number of 'on my way' (Blue arrow pointing at ground) pings used.

participant_id instance-attribute

Participant's position in the match (1-10).

penta_kills instance-attribute

Number of penta kills achieved.

perks instance-attribute

Rune and perk information. May be None if not included in the API response.

physical_damage_dealt instance-attribute

Total physical damage dealt.

physical_damage_dealt_to_champions instance-attribute

Physical damage dealt to enemy champions.

physical_damage_taken instance-attribute

Total physical damage taken.

placement instance-attribute

Final placement in the match.

player_augment_1 = None class-attribute instance-attribute

Player augment 1, if applicable (mode-specific).

player_augment_2 = None class-attribute instance-attribute

Player augment 2, if applicable (mode-specific).

player_augment_3 = None class-attribute instance-attribute

Player augment 3, if applicable (mode-specific).

player_augment_4 = None class-attribute instance-attribute

Player augment 4, if applicable (mode-specific).

player_score_0 = None class-attribute instance-attribute

Mission score 0, if applicable.

player_score_1 = None class-attribute instance-attribute

Mission score 1, if applicable.

player_score_10 = None class-attribute instance-attribute

Mission score 10, if applicable.

player_score_11 = None class-attribute instance-attribute

Mission score 11, if applicable.

player_score_2 = None class-attribute instance-attribute

Mission score 2, if applicable.

player_score_3 = None class-attribute instance-attribute

Mission score 3, if applicable.

player_score_4 = None class-attribute instance-attribute

Mission score 4, if applicable.

player_score_5 = None class-attribute instance-attribute

Mission score 5, if applicable.

player_score_6 = None class-attribute instance-attribute

Mission score 6, if applicable.

player_score_7 = None class-attribute instance-attribute

Mission score 7, if applicable.

player_score_8 = None class-attribute instance-attribute

Mission score 8, if applicable.

player_score_9 = None class-attribute instance-attribute

Mission score 9, if applicable.

player_subteam_id = None class-attribute instance-attribute

Player subteam ID, if applicable (mode-specific).

profile_icon instance-attribute

Profile icon ID used by the participant.

push_pings instance-attribute

Number of 'push' (Green minion) pings used.

puuid instance-attribute

Player's universally unique identifier.

quadra_kills instance-attribute

Number of quadra kills achieved.

role instance-attribute

Role assignment during the match.

sight_wards_bought_in_game instance-attribute

Number of sight wards bought.

spell_1_casts instance-attribute

Number of times ability Q was cast.

spell_2_casts instance-attribute

Number of times ability W was cast.

spell_3_casts instance-attribute

Number of times ability E was cast.

spell_4_casts instance-attribute

Number of times ability R (ultimate) was cast.

subteam_placement = None class-attribute instance-attribute

Subteam placement, if applicable (mode-specific).

summoner_1_casts instance-attribute

Number of times first summoner spell was cast.

summoner_1_id instance-attribute

ID of the first summoner spell.

summoner_2_casts instance-attribute

Number of times second summoner spell was cast.

summoner_2_id instance-attribute

ID of the second summoner spell.

summoner_id instance-attribute

Summoner ID of the participant.

summoner_level instance-attribute

Summoner level at the time of the match.

summoner_name property

Player's summoner name at the time of the match.

Deprecated by Riot. Use Participant.game_name instead.

tagline = None class-attribute instance-attribute

Riot ID tagline, if available.

team_color property

Team color. Colloquially players use the terms "blue side" or "red side".

team_early_surrendered instance-attribute

Whether the participant's team early surrendered.

team_id instance-attribute

Team identifier (100 for blue side, 200 for red side).

team_position instance-attribute

Team-based position assignment (TOP, JUNGLE, MIDDLE, BOTTOM, UTILITY).

Riot API docs:

The teamPosition is the best guess for which position the player actually played if we add the constraint that each team must have one top player, one jungle, one middle, etc.

Generally, you should use the this over the individual_position.

time_ccing_others instance-attribute

Time spent crowd controlling enemies in seconds.

time_played instance-attribute

Total time played in the match in seconds.

total_ally_jungle_minions_killed instance-attribute

Number of allied jungle minions killed.

total_damage_dealt instance-attribute

Total damage dealt (all types combined).

total_damage_dealt_to_champions instance-attribute

Total damage dealt to enemy champions (all types combined).

total_damage_shielded_on_teammates instance-attribute

Total damage shielded on teammates.

total_damage_taken instance-attribute

Total damage taken (all types combined).

total_enemy_jungle_minions_killed instance-attribute

Number of enemy jungle minions killed.

total_heal instance-attribute

Total healing done.

Riot docs:

Whenever positive health is applied (which translates to all heals in the game but not things like regeneration), totalHeal is incremented by the amount of health received. This includes healing enemies, jungle monsters, yourself, etc

total_heals_on_teammates instance-attribute

Total healing done on teammates.

Riot docs:

Whenever positive health is applied (which translates to all heals in the game but not things like regeneration), totalHealsOnTeammates is incremented by the amount of health received. This is post modified, so if you heal someone missing 5 health for 100 you will get +5 totalHealsOnTeammates

total_jungle_minions_killed property

Alias for neutral_minions_killed.

total_minions_killed instance-attribute

Total number of minions killed.

Riot docs:

totalMillionsKilled = mMinionsKilled, which is only incremented on kills of kTeamMinion, kMeleeLaneMinion, kSuperLaneMinion, kRangedLaneMinion and kSiegeLaneMinion

total_time_cc_dealt instance-attribute

Total crowd control time dealt in seconds.

total_time_spent_dead instance-attribute

Total time spent dead in seconds.

total_units_healed instance-attribute

Total number of units healed.

triple_kills instance-attribute

Number of triple kills achieved.

true_damage_dealt instance-attribute

Total true damage dealt.

true_damage_dealt_to_champions instance-attribute

True damage dealt to enemy champions.

true_damage_taken instance-attribute

Total true damage taken.

turret_kills instance-attribute

Number of turret kills.

turret_takedowns instance-attribute

Number of turret takedowns participated in.

turrets_lost instance-attribute

Number of allied turrets lost.

unreal_kills instance-attribute

(Presumably) Number of unreal kills achieved.

Possibly for legacy/never released 6v6 gamemodes, but is unused and should be ignored.

vision_cleared_pings instance-attribute

Number of 'vision cleared' pings used.

vision_score instance-attribute

Vision score based on wards placed, cleared, etc.

vision_wards_bought_in_game instance-attribute

Number of vision wards bought.

wards_killed instance-attribute

Number of enemy wards destroyed.

wards_placed instance-attribute

Total number of wards placed.

win instance-attribute

Whether the participant's team won the match.

from_api_response(data) classmethod

Create Participant from API response.

Source code in nexar/models/match/participant.py
@classmethod
def from_api_response(cls, data: dict[str, Any]) -> "Participant":
    """Create Participant from API response."""
    from .challenges import Challenges, Missions
    from .perks import Perks

    return cls(
        # Core participant data
        puuid=data["puuid"],
        _summoner_name=data["summonerName"],
        champion_id=data["championId"],
        champion_name=data["championName"],
        team_id=data["teamId"],
        participant_id=data["participantId"],
        # Basic stats
        kills=data["kills"],
        deaths=data["deaths"],
        assists=data["assists"],
        champion_level=data["champLevel"],
        gold_earned=data["goldEarned"],
        gold_spent=data["goldSpent"],
        vision_score=data["visionScore"],
        win=data["win"],
        # Items
        item_0=data["item0"],
        item_1=data["item1"],
        item_2=data["item2"],
        item_3=data["item3"],
        item_4=data["item4"],
        item_5=data["item5"],
        item_6=data["item6"],
        # Position and role
        individual_position=MatchParticipantPosition(data["individualPosition"]),
        team_position=MatchParticipantPosition(data["teamPosition"]),
        lane=data["lane"],
        role=data["role"],
        # Ping stats
        all_in_pings=data["allInPings"],
        assist_me_pings=data["assistMePings"],
        command_pings=data["commandPings"],
        enemy_missing_pings=data["enemyMissingPings"],
        enemy_vision_pings=data["enemyVisionPings"],
        get_back_pings=data["getBackPings"],
        hold_pings=data["holdPings"],
        need_vision_pings=data["needVisionPings"],
        on_my_way_pings=data["onMyWayPings"],
        push_pings=data["pushPings"],
        vision_cleared_pings=data["visionClearedPings"],
        # Kill stats
        baron_kills=data["baronKills"],
        double_kills=data["doubleKills"],
        dragon_kills=data["dragonKills"],
        inhibitor_kills=data["inhibitorKills"],
        killing_sprees=data["killingSprees"],
        largest_killing_spree=data["largestKillingSpree"],
        largest_multi_kill=data["largestMultiKill"],
        nexus_kills=data["nexusKills"],
        penta_kills=data["pentaKills"],
        quadra_kills=data["quadraKills"],
        triple_kills=data["tripleKills"],
        turret_kills=data["turretKills"],
        unreal_kills=data["unrealKills"],
        # Damage stats
        damage_dealt_to_buildings=data["damageDealtToBuildings"],
        damage_dealt_to_objectives=data["damageDealtToObjectives"],
        damage_dealt_to_turrets=data["damageDealtToTurrets"],
        damage_self_mitigated=data["damageSelfMitigated"],
        largest_critical_strike=data["largestCriticalStrike"],
        magic_damage_dealt=data["magicDamageDealt"],
        magic_damage_dealt_to_champions=data["magicDamageDealtToChampions"],
        magic_damage_taken=data["magicDamageTaken"],
        physical_damage_dealt=data["physicalDamageDealt"],
        physical_damage_dealt_to_champions=data["physicalDamageDealtToChampions"],
        physical_damage_taken=data["physicalDamageTaken"],
        total_damage_dealt=data["totalDamageDealt"],
        total_damage_dealt_to_champions=data["totalDamageDealtToChampions"],
        total_damage_shielded_on_teammates=data["totalDamageShieldedOnTeammates"],
        total_damage_taken=data["totalDamageTaken"],
        true_damage_dealt=data["trueDamageDealt"],
        true_damage_dealt_to_champions=data["trueDamageDealtToChampions"],
        true_damage_taken=data["trueDamageTaken"],
        # Minion and jungle stats
        neutral_minions_killed=data["neutralMinionsKilled"],
        total_ally_jungle_minions_killed=data["totalAllyJungleMinionsKilled"],
        total_enemy_jungle_minions_killed=data["totalEnemyJungleMinionsKilled"],
        total_minions_killed=data["totalMinionsKilled"],
        # Healing and support stats
        total_heal=data["totalHeal"],
        total_heals_on_teammates=data["totalHealsOnTeammates"],
        total_units_healed=data["totalUnitsHealed"],
        # Time stats
        longest_time_spent_living=data["longestTimeSpentLiving"],
        time_ccing_others=data["timeCCingOthers"],
        time_played=data["timePlayed"],
        total_time_cc_dealt=data["totalTimeCCDealt"],
        total_time_spent_dead=data["totalTimeSpentDead"],
        # Ward and vision stats
        detector_wards_placed=data["detectorWardsPlaced"],
        sight_wards_bought_in_game=data["sightWardsBoughtInGame"],
        vision_wards_bought_in_game=data["visionWardsBoughtInGame"],
        wards_killed=data["wardsKilled"],
        wards_placed=data["wardsPlaced"],
        # Spell casts
        spell_1_casts=data["spell1Casts"],
        spell_2_casts=data["spell2Casts"],
        spell_3_casts=data["spell3Casts"],
        spell_4_casts=data["spell4Casts"],
        summoner_1_casts=data["summoner1Casts"],
        summoner_1_id=data["summoner1Id"],
        summoner_2_casts=data["summoner2Casts"],
        summoner_2_id=data["summoner2Id"],
        # Structure stats
        inhibitor_takedowns=data["inhibitorTakedowns"],
        inhibitors_lost=data["inhibitorsLost"],
        nexus_takedowns=data["nexusTakedowns"],
        nexus_lost=data["nexusLost"],
        turret_takedowns=data["turretTakedowns"],
        turrets_lost=data["turretsLost"],
        # Objectives
        objectives_stolen=data["objectivesStolen"],
        objectives_stolen_assists=data["objectivesStolenAssists"],
        # Game state
        bounty_level=data.get("bountyLevel"),
        champ_experience=data["champExperience"],
        champion_transform=data["championTransform"],
        consumables_purchased=data["consumablesPurchased"],
        eligible_for_progression=data["eligibleForProgression"],
        first_blood_assist=data["firstBloodAssist"],
        first_blood_kill=data["firstBloodKill"],
        first_tower_assist=data["firstTowerAssist"],
        first_tower_kill=data["firstTowerKill"],
        game_ended_in_early_surrender=data["gameEndedInEarlySurrender"],
        game_ended_in_surrender=data["gameEndedInSurrender"],
        items_purchased=data["itemsPurchased"],
        placement=data["placement"],
        profile_icon=data["profileIcon"],
        summoner_id=data["summonerId"],
        summoner_level=data["summonerLevel"],
        team_early_surrendered=data["teamEarlySurrendered"],
        # Complex nested objects (optionally included by Riot)
        perks=Perks.from_api_response(p_data) if (p_data := data.get("perks")) else None,
        challenges=Challenges.from_api_response(c_data) if (c_data := data.get("challenges")) else None,
        missions=Missions.from_api_response(m_data) if (m_data := data.get("missions")) else None,
        # Riot ID (optional fields)
        game_name=data.get("riotIdGameName"),
        tagline=data.get("riotIdTagline"),
        # Player scores (optional fields from missions)
        player_score_0=data.get("playerScore0"),
        player_score_1=data.get("playerScore1"),
        player_score_2=data.get("playerScore2"),
        player_score_3=data.get("playerScore3"),
        player_score_4=data.get("playerScore4"),
        player_score_5=data.get("playerScore5"),
        player_score_6=data.get("playerScore6"),
        player_score_7=data.get("playerScore7"),
        player_score_8=data.get("playerScore8"),
        player_score_9=data.get("playerScore9"),
        player_score_10=data.get("playerScore10"),
        player_score_11=data.get("playerScore11"),
        # Player augments (optional fields for specific game modes)
        player_augment_1=data.get("playerAugment1"),
        player_augment_2=data.get("playerAugment2"),
        player_augment_3=data.get("playerAugment3"),
        player_augment_4=data.get("playerAugment4"),
        player_subteam_id=data.get("playerSubteamId"),
        subteam_placement=data.get("subteamPlacement"),
    )

get_player(client, *, region=None) async

Get a Player object for this participant.

Uses the participant's PUUID to look up their Riot account and create a Player, which provides convenient access to summoner data, league entries, match history, and more.

Parameters:

Name Type Description Default
client NexarClient

The NexarClient instance to use for API calls.

required
region Region | None

The player's region (defaults to client default).

None

Returns:

Type Description
Player

A Player instance for this participant.

Source code in nexar/models/match/participant.py
async def get_player(
    self,
    client: "NexarClient",
    *,
    region: "Region | None" = None,
) -> "Player":
    """
    Get a Player object for this participant.

    Uses the participant's PUUID to look up their Riot account and create
    a Player, which provides convenient access to summoner data, league
    entries, match history, and more.

    Args:
        client: The NexarClient instance to use for API calls.
        region: The player's region (defaults to client default).

    Returns:
        A Player instance for this participant.

    """
    from nexar.models.player import Player

    return await Player.create(client=client, puuid=self.puuid, region=region)

kda(*, as_str=False)

KDA ratio or formatted KDA string.

By default returns the KDA ratio as (kills + assists) / max(1, deaths). If as_str=True, returns a formatted string like '5/2/10'.

This is always available since kills, deaths, and assists are present for all game modes. For the challenge-specific KDA, use Participant.challenges.kda (only available when challenges are included in the API response).

Source code in nexar/models/match/participant.py
def kda(self, *, as_str: bool = False) -> float | str:
    """
    KDA ratio or formatted KDA string.

    By default returns the KDA ratio as (kills + assists) / max(1, deaths).
    If as_str=True, returns a formatted string like '5/2/10'.

    This is always available since kills, deaths, and assists are present
    for all game modes. For the challenge-specific KDA, use `Participant.challenges.kda`
    (only available when challenges are included in the API response).
    """
    if as_str:
        return f"{self.kills}/{self.deaths}/{self.assists}"
    return (self.kills + self.assists) / max(self.deaths, 1)