Parsing a Counter-Strike 2 Demo

In this notebook, we show how to install Awpy and parse a Counter-Strike 2 demo file, also called a replay file or simply, demo. To start, install Awpy via pip by running pip install awpy. Python >= 3.11 is a prerequisite! You can get a demo either through the game itself, or by visiting a website like HLTV or FACEIT. Then, to parse the demo, you can run the following:

[1]:
from awpy import Demo

# Demo: https://www.hltv.org/matches/2372746/spirit-vs-natus-vincere-blast-premier-spring-final-2024 (de_dust2, Map 2)
dem = Demo("spirit-vs-natus-vincere-m2-dust2.dem", verbose=True)
dem.parse()

# Available properties (all demos)
print(f"\nHeader: \n{dem.header}")
print(f"\nRounds: \n{dem.rounds.head(n=3)}")
print(f"\nKills: \n{dem.kills.head(n=3)}")
print(f"\nDamages: \n{dem.damages.head(n=3)}")
print(f"\nWeapon Fires: \n{dem.shots.head(n=3)}")
print(f"\nBomb: \n{dem.bomb.head(n=3)}")
print(f"\nSmokes: \n{dem.smokes.head(n=3)}")
print(f"\nInfernos: \n{dem.infernos.head(n=3)}")
print(f"\nGrenades: \n{dem.grenades.head(n=3)}")
print(f"\nFootsteps: \n{dem.footsteps.head(n=3)}")
print(f"\nTicks: \n{dem.ticks.head(n=3)}")


2025-02-17 11:27:34.708 | DEBUG    | awpy.demo:parse:214 - Starting to parse spirit-vs-natus-vincere-m2-dust2.dem
2025-02-17 11:27:39.170 | SUCCESS  | awpy.demo:parse:258 - Finished parsing spirit-vs-natus-vincere-m2-dust2.dem, took 4.46 seconds

Header:
{'game_directory': '/home/csserver001/cs2/game/csgo', 'allow_clientside_entities': True, 'demo_version_guid': '8e9d71ab-04a1-4c01-bb61-acfede27c046', 'server_name': 'BLAST Premier 2024', 'demo_file_stamp': 'PBDEMS2\x00', 'client_name': 'SourceTV Demo', 'allow_clientside_particles': True, 'fullpackets_version': '2', 'addons': '', 'demo_version_name': 'valve_demo_2', 'map_name': 'de_dust2', 'network_protocol': '14011'}

Rounds:
shape: (3, 9)
┌───────────┬───────┬────────────┬───────┬───┬────────┬──────────┬────────────┬─────────────┐
│ round_num ┆ start ┆ freeze_end ┆ end   ┆ … ┆ winner ┆ reason   ┆ bomb_plant ┆ bomb_site   │
│ ---       ┆ ---   ┆ ---        ┆ ---   ┆   ┆ ---    ┆ ---      ┆ ---        ┆ ---         │
│ u32       ┆ i32   ┆ i32        ┆ i32   ┆   ┆ str    ┆ str      ┆ i64        ┆ str         │
╞═══════════╪═══════╪════════════╪═══════╪═══╪════════╪══════════╪════════════╪═════════════╡
│ 1         ┆ 576   ┆ 7461       ┆ 12853 ┆ … ┆ CT     ┆ t_killed ┆ null       ┆ not_planted │
│ 2         ┆ 13301 ┆ 14581      ┆ 17224 ┆ … ┆ CT     ┆ t_killed ┆ null       ┆ not_planted │
│ 3         ┆ 17672 ┆ 18952      ┆ 22872 ┆ … ┆ CT     ┆ t_killed ┆ null       ┆ not_planted │
└───────────┴───────┴────────────┴───────┴───┴────────┴──────────┴────────────┴─────────────┘

Kills:
shape: (3, 41)
┌────────────┬────────────┬────────────┬────────────┬───┬───────────┬───────────┬───────────┬──────┐
│ assistedfl ┆ assister_X ┆ assister_Y ┆ assister_Z ┆ … ┆ weapon_fa ┆ weapon_it ┆ weapon_or ┆ wipe │
│ ash        ┆ ---        ┆ ---        ┆ ---        ┆   ┆ uxitemid  ┆ emid      ┆ iginalown ┆ ---  │
│ ---        ┆ f32        ┆ f32        ┆ f32        ┆   ┆ ---       ┆ ---       ┆ er_xuid   ┆ i32  │
│ bool       ┆            ┆            ┆            ┆   ┆ str       ┆ str       ┆ ---       ┆      │
│            ┆            ┆            ┆            ┆   ┆           ┆           ┆ str       ┆      │
╞════════════╪════════════╪════════════╪════════════╪═══╪═══════════╪═══════════╪═══════════╪══════╡
│ false      ┆ null       ┆ null       ┆ null       ┆ … ┆ 172938225 ┆ 327493063 ┆           ┆ 0    │
│            ┆            ┆            ┆            ┆   ┆ 691435991 ┆ 75        ┆           ┆      │
│            ┆            ┆            ┆            ┆   ┆ 44        ┆           ┆           ┆      │
│ false      ┆ null       ┆ null       ┆ null       ┆ … ┆ 172938225 ┆ 327493063 ┆           ┆ 0    │
│            ┆            ┆            ┆            ┆   ┆ 691435991 ┆ 75        ┆           ┆      │
│            ┆            ┆            ┆            ┆   ┆ 44        ┆           ┆           ┆      │
│ false      ┆ null       ┆ null       ┆ null       ┆ … ┆ 172938225 ┆ 374009057 ┆           ┆ 0    │
│            ┆            ┆            ┆            ┆   ┆ 691357348 ┆ 41        ┆           ┆      │
│            ┆            ┆            ┆            ┆   ┆ 45        ┆           ┆           ┆      │
└────────────┴────────────┴────────────┴────────────┴───┴───────────┴───────────┴───────────┴──────┘

Damages:
shape: (3, 22)
┌───────┬────────────┬────────────┬────────────┬───┬────────────┬────────────┬─────────┬───────────┐
│ armor ┆ attacker_X ┆ attacker_Y ┆ attacker_Z ┆ … ┆ victim_nam ┆ victim_ste ┆ weapon  ┆ dmg_healt │
│ ---   ┆ ---        ┆ ---        ┆ ---        ┆   ┆ e          ┆ amid       ┆ ---     ┆ h_real    │
│ i32   ┆ f32        ┆ f32        ┆ f32        ┆   ┆ ---        ┆ ---        ┆ str     ┆ ---       │
│       ┆            ┆            ┆            ┆   ┆ str        ┆ str        ┆         ┆ i32       │
╞═══════╪════════════╪════════════╪════════════╪═══╪════════════╪════════════╪═════════╪═══════════╡
│ 85    ┆ -407.51477 ┆ -328.71130 ┆ 0.913547   ┆ … ┆ zont1x     ┆ 7656119899 ┆ ssg08   ┆ 100       │
│       ┆ 1          ┆ 4          ┆            ┆   ┆            ┆ 5880877    ┆         ┆           │
│ 0     ┆ -462.22937 ┆ 28.99902   ┆ 0.499369   ┆ … ┆ donk       ┆ 7656119838 ┆ ssg08   ┆ 31        │
│       ┆            ┆            ┆            ┆   ┆            ┆ 6265483    ┆         ┆           │
│ 100   ┆ 1593.97204 ┆ 1501.21667 ┆ 0.608216   ┆ … ┆ b1t        ┆ 7656119824 ┆ hkp2000 ┆ 100       │
│       ┆ 6          ┆ 5          ┆            ┆   ┆            ┆ 6607476    ┆         ┆           │
└───────┴────────────┴────────────┴────────────┴───┴────────────┴────────────┴─────────┴───────────┘

Weapon Fires:
shape: (3, 10)
┌──────────┬──────┬────────────┬────────────┬───┬────────────┬────────────┬────────────┬───────────┐
│ silenced ┆ tick ┆ player_X   ┆ player_Y   ┆ … ┆ player_las ┆ player_nam ┆ player_ste ┆ weapon    │
│ ---      ┆ ---  ┆ ---        ┆ ---        ┆   ┆ t_place_na ┆ e          ┆ amid       ┆ ---       │
│ bool     ┆ i32  ┆ f32        ┆ f32        ┆   ┆ me         ┆ ---        ┆ ---        ┆ str       │
│          ┆      ┆            ┆            ┆   ┆ ---        ┆ str        ┆ str        ┆           │
│          ┆      ┆            ┆            ┆   ┆ str        ┆            ┆            ┆           │
╞══════════╪══════╪════════════╪════════════╪═══╪════════════╪════════════╪════════════╪═══════════╡
│ false    ┆ 41   ┆ -407.51477 ┆ -328.71130 ┆ … ┆ TopofMid   ┆ b1t        ┆ 7656119824 ┆ weapon_ss │
│          ┆      ┆ 1          ┆ 4          ┆   ┆            ┆            ┆ 6607476    ┆ g08       │
│ false    ┆ 128  ┆ -413.88311 ┆ 1693.21997 ┆ … ┆ MidDoors   ┆ donk       ┆ 7656119838 ┆ weapon_aw │
│          ┆      ┆ 8          ┆ 1          ┆   ┆            ┆            ┆ 6265483    ┆ p         │
│ false    ┆ 214  ┆ 195.1064   ┆ -357.82635 ┆ … ┆ OutsideLon ┆ w0nderful  ┆ 7656119906 ┆ weapon_kn │
│          ┆      ┆            ┆ 5          ┆   ┆ g          ┆            ┆ 3068840    ┆ ife_m9_ba │
│          ┆      ┆            ┆            ┆   ┆            ┆            ┆            ┆ yonet     │
└──────────┴──────┴────────────┴────────────┴───┴────────────┴────────────┴────────────┴───────────┘

Bomb:
shape: (3, 8)
┌──────┬────────┬─────────────┬─────────────┬────────────┬──────────────────┬───────────┬──────────┐
│ tick ┆ event  ┆ X           ┆ Y           ┆ Z          ┆ steamid          ┆ name      ┆ bombsite │
│ ---  ┆ ---    ┆ ---         ┆ ---         ┆ ---        ┆ ---              ┆ ---       ┆ ---      │
│ i32  ┆ str    ┆ f32         ┆ f32         ┆ f32        ┆ str              ┆ str       ┆ str      │
╞══════╪════════╪═════════════╪═════════════╪════════════╪══════════════════╪═══════════╪══════════╡
│ 449  ┆ pickup ┆ -367.0      ┆ -808.0      ┆ 83.744965  ┆ 7656119817687830 ┆ jL        ┆ null     │
│      ┆        ┆             ┆             ┆            ┆ 3                ┆           ┆          │
│ 7503 ┆ drop   ┆ -639.103088 ┆ -832.525757 ┆ 116.030685 ┆ 7656119906306884 ┆ w0nderful ┆ null     │
│      ┆        ┆             ┆             ┆            ┆ 0                ┆           ┆          │
│ 7569 ┆ pickup ┆ -167.492432 ┆ -806.045715 ┆ 34.974846  ┆ 7656119801324332 ┆ Aleksib   ┆ null     │
│      ┆        ┆             ┆             ┆            ┆ 6                ┆           ┆          │
└──────┴────────┴─────────────┴─────────────┴────────────┴──────────────────┴───────────┴──────────┘

Smokes:
shape: (3, 13)
┌───────────┬───────────┬──────────┬───────────┬───┬───────────┬───────────┬───────────┬───────────┐
│ entity_id ┆ start_tic ┆ end_tick ┆ thrower_X ┆ … ┆ thrower_s ┆ X         ┆ Y         ┆ Z         │
│ ---       ┆ k         ┆ ---      ┆ ---       ┆   ┆ teamid    ┆ ---       ┆ ---       ┆ ---       │
│ i64       ┆ ---       ┆ i64      ┆ f64       ┆   ┆ ---       ┆ f64       ┆ f64       ┆ f64       │
│           ┆ i64       ┆          ┆           ┆   ┆ str       ┆           ┆           ┆           │
╞═══════════╪═══════════╪══════════╪═══════════╪═══╪═══════════╪═══════════╪═══════════╪═══════════╡
│ 219       ┆ 9601      ┆ 11013    ┆ 847.12634 ┆ … ┆ 765611990 ┆ 394.15988 ┆ 1967.7786 ┆ 98.03125  │
│           ┆           ┆          ┆ 3         ┆   ┆ 63238565  ┆ 2         ┆ 87        ┆           │
│ 108       ┆ 11885     ┆ 13297    ┆ -1508.248 ┆ … ┆ 765611980 ┆ -1286.896 ┆ 2265.1994 ┆ 4.593013  │
│           ┆           ┆          ┆ 657       ┆   ┆ 13243326  ┆ 729       ┆ 63        ┆           │
│ 507       ┆ 14801     ┆ 16213    ┆ 579.01184 ┆ … ┆ 765611980 ┆ -150.5394 ┆ 2082.2810 ┆ -123.6676 │
│           ┆           ┆          ┆ 1         ┆   ┆ 81484775  ┆ 9         ┆ 06        ┆ 94        │
└───────────┴───────────┴──────────┴───────────┴───┴───────────┴───────────┴───────────┴───────────┘

Infernos:
shape: (3, 13)
┌───────────┬───────────┬──────────┬───────────┬───┬───────────┬───────────┬───────────┬───────────┐
│ entity_id ┆ start_tic ┆ end_tick ┆ thrower_X ┆ … ┆ thrower_s ┆ X         ┆ Y         ┆ Z         │
│ ---       ┆ k         ┆ ---      ┆ ---       ┆   ┆ teamid    ┆ ---       ┆ ---       ┆ ---       │
│ i64       ┆ ---       ┆ i64      ┆ f64       ┆   ┆ ---       ┆ f64       ┆ f64       ┆ f64       │
│           ┆ i64       ┆          ┆           ┆   ┆ str       ┆           ┆           ┆           │
╞═══════════╪═══════════╪══════════╪═══════════╪═══╪═══════════╪═══════════╪═══════════╪═══════════╡
│ 371       ┆ 12801     ┆ 13250    ┆ -1513.689 ┆ … ┆ 765611980 ┆ -1101.931 ┆ 2602.0991 ┆ 60.730347 │
│           ┆           ┆          ┆ 087       ┆   ┆ 81484775  ┆ 763       ┆ 21        ┆           │
│ 488       ┆ 15122     ┆ 15437    ┆ -1517.362 ┆ … ┆ 765611989 ┆ -1993.518 ┆ 1637.2847 ┆ 33.104042 │
│           ┆           ┆          ┆ 061       ┆   ┆ 95880877  ┆ 311       ┆ 9         ┆           │
│ 487       ┆ 15132     ┆ 15485    ┆ 1254.0328 ┆ … ┆ 765611990 ┆ 534.49383 ┆ 661.59167 ┆ 18.419727 │
│           ┆           ┆          ┆ 37        ┆   ┆ 63238565  ┆ 5         ┆ 5         ┆           │
└───────────┴───────────┴──────────┴───────────┴───┴───────────┴───────────┴───────────┴───────────┘

Grenades:
shape: (3, 9)
┌──────────────┬─────────┬─────────────┬──────┬───┬────────────┬───────────┬───────────┬───────────┐
│ thrower_stea ┆ thrower ┆ grenade_typ ┆ tick ┆ … ┆ Y          ┆ Z         ┆ entity_id ┆ round_num │
│ mid          ┆ ---     ┆ e           ┆ ---  ┆   ┆ ---        ┆ ---       ┆ ---       ┆ ---       │
│ ---          ┆ str     ┆ ---         ┆ i32  ┆   ┆ f32        ┆ f32       ┆ i32       ┆ u32       │
│ u64          ┆         ┆ str         ┆      ┆   ┆            ┆           ┆           ┆           │
╞══════════════╪═════════╪═════════════╪══════╪═══╪════════════╪═══════════╪═══════════╪═══════════╡
│ 765611980132 ┆ Aleksib ┆ flashbang   ┆ 8238 ┆ … ┆ -393.78125 ┆ 100.84375 ┆ 445       ┆ 1         │
│ 43326        ┆         ┆             ┆      ┆   ┆            ┆           ┆           ┆           │
│ 765611980132 ┆ Aleksib ┆ flashbang   ┆ 8239 ┆ … ┆ -384.03125 ┆ 107.90625 ┆ 445       ┆ 1         │
│ 43326        ┆         ┆             ┆      ┆   ┆            ┆           ┆           ┆           │
│ 765611980132 ┆ Aleksib ┆ flashbang   ┆ 8240 ┆ … ┆ -374.3125  ┆ 114.90625 ┆ 445       ┆ 1         │
│ 43326        ┆         ┆             ┆      ┆   ┆            ┆           ┆           ┆           │
└──────────────┴─────────┴─────────────┴──────┴───┴────────────┴───────────┴───────────┴───────────┘

Footsteps:
shape: (3, 11)
┌──────────┬────────┬───────┬──────┬───┬───────────────┬──────────────┬─────────────┬──────────────┐
│ duration ┆ radius ┆ step  ┆ tick ┆ … ┆ player_health ┆ player_last_ ┆ player_name ┆ player_steam │
│ ---      ┆ ---    ┆ ---   ┆ ---  ┆   ┆ ---           ┆ place_name   ┆ ---         ┆ id           │
│ f32      ┆ i32    ┆ bool  ┆ i32  ┆   ┆ i32           ┆ ---          ┆ str         ┆ ---          │
│          ┆        ┆       ┆      ┆   ┆               ┆ str          ┆             ┆ str          │
╞══════════╪════════╪═══════╪══════╪═══╪═══════════════╪══════════════╪═════════════╪══════════════╡
│ 0.5      ┆ 1100   ┆ true  ┆ 4    ┆ … ┆ 100           ┆ MidDoors     ┆ zont1x      ┆ 765611989958 │
│          ┆        ┆       ┆      ┆   ┆               ┆              ┆             ┆ 80877        │
│ 0.1      ┆ 597    ┆ false ┆ 15   ┆ … ┆ 100           ┆ MidDoors     ┆ zont1x      ┆ 765611989958 │
│          ┆        ┆       ┆      ┆   ┆               ┆              ┆             ┆ 80877        │
│ 0.5      ┆ 1100   ┆ true  ┆ 16   ┆ … ┆ 100           ┆ UnderA       ┆ chopper     ┆ 765611980458 │
│          ┆        ┆       ┆      ┆   ┆               ┆              ┆             ┆ 98864        │
└──────────┴────────┴───────┴──────┴───┴───────────────┴──────────────┴─────────────┴──────────────┘

Ticks:
shape: (3, 4)
┌──────┬───────────────────┬───────────┬───────────┐
│ tick ┆ steamid           ┆ name      ┆ round_num │
│ ---  ┆ ---               ┆ ---       ┆ ---       │
│ i32  ┆ u64               ┆ str       ┆ u32       │
╞══════╪═══════════════════╪═══════════╪═══════════╡
│ 577  ┆ 76561198386265483 ┆ donk      ┆ 1         │
│ 577  ┆ 76561199063238565 ┆ magixx    ┆ 1         │
│ 577  ┆ 76561199063068840 ┆ w0nderful ┆ 1         │
└──────┴───────────────────┴───────────┴───────────┘

Getting player and global properties

Awpy uses demoparser2 as its parsing backend. This means that you can pass a list of player_props or other_props. In the following example, we get some player position properties. If you do not pass any props, we choose a default list of properties (which is already quite extensive). To see a list of available properties, visit demoparser2’s repository.

[3]:
dem = Demo("spirit-vs-natus-vincere-m2-dust2.dem")
dem.parse(player_props=["X", "Y", "Z", "health", "armor_value", "has_helmet", "has_defuser", "inventory"])

print(f"\nTicks: \n{dem.ticks.head(n=3)}")
2025-02-17 11:27:58.733 | DEBUG    | awpy.demo:parse:214 - Starting to parse spirit-vs-natus-vincere-m2-dust2.dem
2025-02-17 11:28:09.006 | SUCCESS  | awpy.demo:parse:258 - Finished parsing spirit-vs-natus-vincere-m2-dust2.dem, took 10.27 seconds

Ticks:
shape: (3, 12)
┌─────────────┬────────┬─────────────┬────────────┬───┬──────┬─────────────┬───────────┬───────────┐
│ inventory   ┆ health ┆ has_defuser ┆ has_helmet ┆ … ┆ tick ┆ steamid     ┆ name      ┆ round_num │
│ ---         ┆ ---    ┆ ---         ┆ ---        ┆   ┆ ---  ┆ ---         ┆ ---       ┆ ---       │
│ list[str]   ┆ i32    ┆ bool        ┆ bool       ┆   ┆ i32  ┆ u64         ┆ str       ┆ u32       │
╞═════════════╪════════╪═════════════╪════════════╪═══╪══════╪═════════════╪═══════════╪═══════════╡
│ ["knife_but ┆ 100    ┆ false       ┆ false      ┆ … ┆ 577  ┆ 76561198386 ┆ donk      ┆ 1         │
│ terfly",    ┆        ┆             ┆            ┆   ┆      ┆ 265483      ┆           ┆           │
│ "USP-S"]    ┆        ┆             ┆            ┆   ┆      ┆             ┆           ┆           │
│ ["knife_kar ┆ 100    ┆ false       ┆ false      ┆ … ┆ 577  ┆ 76561199063 ┆ magixx    ┆ 1         │
│ ambit",     ┆        ┆             ┆            ┆   ┆      ┆ 238565      ┆           ┆           │
│ "USP-S"]    ┆        ┆             ┆            ┆   ┆      ┆             ┆           ┆           │
│ ["knife_m9_ ┆ 100    ┆ false       ┆ false      ┆ … ┆ 577  ┆ 76561199063 ┆ w0nderful ┆ 1         │
│ bayonet",   ┆        ┆             ┆            ┆   ┆      ┆ 068840      ┆           ┆           │
│ "Glock-18…  ┆        ┆             ┆            ┆   ┆      ┆             ┆           ┆           │
└─────────────┴────────┴─────────────┴────────────┴───┴──────┴─────────────┴───────────┴───────────┘

Obtaining all events

Because we use the demoparser2 backend, we can parse many kinds of events in the demo. To see the default list, you can check Demo.default_events. These events are parsed unless specified otherwise (via the events=[...] argument in .parse()). To access parsed events, after parsing a demo, simply check the .events property, which is a dictionary where the key is the event name and the value is the parsed Polars dataframe.

[5]:
for event_name, event in dem.events.items():
    print(f"{event_name}: {event.shape[0]} rows x {event.shape[1]} columns")
bomb_planted: 12 rows x 13 columns
player_given_c4: 24 rows x 12 columns
bomb_dropped: 63 rows x 13 columns
round_freeze_end: 23 rows x 2 columns
bomb_defused: 2 rows x 13 columns
player_spawn: 242 rows x 12 columns
inferno_startburn: 108 rows x 16 columns
smokegrenade_expired: 135 rows x 16 columns
player_death: 165 rows x 53 columns
weapon_fire: 3402 rows x 14 columns
bomb_pickup: 75 rows x 12 columns
player_sound: 23783 rows x 15 columns
inferno_expire: 108 rows x 16 columns
bomb_exploded: 6 rows x 13 columns
smokegrenade_detonate: 146 rows x 16 columns
round_end: 22 rows x 5 columns
item_pickup: 1724 rows x 15 columns
player_hurt: 588 rows x 29 columns
round_start: 24 rows x 3 columns
hegrenade_detonate: 64 rows x 16 columns
round_officially_ended: 44 rows x 2 columns
flashbang_detonate: 183 rows x 16 columns