Tool created as part of a dissertation at the University of York on analysing the quality of smoke grenade usage in CS:GO.
Consists of 4 parts - Web scraping, parsing, analysis and visualisations.
- Python logging module used throughout the scripts
- Configuration file for file locations, visualisation colours etc.
Python script utilising Selenium WebDriver (Browser automation) - Downloads every demo file from HLTV from 29/01/2020
- Navigates to HLTV events page with the correct filters on (LAN tournaments & Date range)
- Navigates to every event (using xPaths) and opens its results page and saves the URLs of all matches (unless the map mirage was not played).
- Clicks the GOTV button to download the file - Each match has a unique ID, this is saved after each download to ensure if the program closed unexpectedly, it would not try to redownload matches.
- Extracts downloaded demo files
- Extracts all demos into the same directory. Any that are not mirage are deleted. Some other maps might be in there as if the match was a best of three and one of the maps was mirage, it will also download the 1-2 other maps that were played.
Logging Example:
Python script utilising the awpy python package (now updated for CS2). CS:GO demos use Google’s Protocol Buffers to serialize the game objects. The awpy package allows you to parse these files into python dictionaries or output to json files.
The script generates an overall dataset.json
file containing all the relevant information from every match.
Iterates through all .demo
files extracted previously and for each one:
- Parses them into a python dictionary using awpy
- Extracts only the relevant information about each smoke grenade used and discards the rest.
- Appends the smoke grenade information to the
dataset.json
file.
Final Dataset Breakdown:
Demos (matches) | Rounds | Smokes | Players | Teams |
---|---|---|---|---|
229 | 6,011 | 35,177 | 658 | 145 |
Grenade Info Example
{
"demoID": "BLAST-Premier-Fall-Final-2021-astralis-vs-faze-bo3-mirage",
"throwerName": "karrigan",
"throwerTeam": "FaZe Clan",
"throwerSide": "T",
"roundNum": 5,
"throwTime": "01:54",
"grenadeX": -224.5,
"grenadeY": -503.5625,
"grenadeZ": -165.875,
"roundWon": false
}
Python script primarily utilising NumPy. The program uses a simplified 2D model, where smokes are circles and doorways are lines. The smokes’ locations have been collected using the web scraper and parser. The doorway locations were manually collected in game and stored in a separate json file. 2 classes were created - one for the Doorways and one for the Smokes.
- Loads smokes in by converting each smoke from the
dataset.json
file into theSmoke
python object. - Loads doorways in by converting each doorway from the
doorway.json
file into theDoorway
python object. - Assigns the smoke grenades to the doorway they are within the detection area of (pre-determined size from a config file). Discards any not in any doorway’s range.
- Calculates the coverage for each of the valid smokes. Unit tests written for coverage calculations.
Python script primarily utilising matplotlib, scipy and seaborn.
Using the coverage statistics determined earlier, creates a set of different diagrams that can be used in different industry contexts.
- Possible application for post match analysis and visualisations of this nature e.g.
Player | Success Rate (%) |
---|---|
Twistzz | 86.67 |
olofmeister | 75.00 |
broky | 83.33 |
rain | 84.62 |
karrigan | 50.00 |
Team Success Rate (%) | 80.00 |
- Restricted only to
de_mirage
to reduce effort required for manual collection of doorways / common locations, could be extended to include more. - Out of date now CS2 has been released with new smoke grenades
- Inaccurate for one-way smokes where players are not aiming for exactly 100% coverage
- Only 60.8% of the dataset were thrown in the common locations, further work would be to look into possibilities to classify these too.