A Valorant bot developed by a Computer Science student as a practical application of Data Engineering and Software Architecture. This project is maintained alongside university commitments, following a weekly sprint cycle to ensure continuous improvement and code quality. It uses web scraping with Selenium on vlr.gg to archive data from VCT matches. It analyzes this data and makes it available for visualization via Discord and a Streamlit Website. We use a PostgreSQL database (hosted on Neon Tech's free plan) to store information about teams and matches.
Data changes: Our ecosystem now searches for the new data twice a day. Scraping scheduled for 2:00 UTC and 14:00 UTC, while the bot and website reload data at 7:30 UTC and 19:30 UTC. All of this to ensure that the data is up to date before the matches, allowing users to consult it before or during a match.
Visualization: Website (Linked in the "About" section of the repository) is now available. It features the same commands from the original Discord Bot, but with interactive dashboards for better visualization.
The ecosystem now provides two distinct interfaces for data consumption, adapting to the user's needs.
- Bot: Using slash commands (
/[command_name]) - Website: Using the sidebar (top-left):
- Bot: To ensure precision, this command lists all available teams and their corresponding tags, helping users find exactly what they are looking for.
- Website: A short explanation (in Portuguese) about how to use the website and its commands, while still dynamically showing each team's tag grouped by region.
-
Bot: The core command of the bot. It provides a multi-page "book" interface with deep insights into VCT teams.
- Page 1: Performance Summary: Shows average stats from the latest tournament (e.g., Rating, ACS, KAST, ADR) and the team's match history
- Pages 2-8: Map Performance: Displays win rates for the last 3 compositions used in the current map pool, including Attack vs. Defense efficiency.
- Page 9: Historical records: Average stats but using the mean of all registered tournaments.
|
|
- Website: Displays the same data structured into interactive dashboards (excluding the Historical Records page).
|
|
|
|
An advanced comparison command that merges data from two distinct /info_time targets into a single, unified Embed Book for enhanced matchup visualization.
- First Page: Performance Summary (Overview): Side-by-side metric comparison from the latest tournament and recent match histories.
- Intermediary Pages: Map Performance: Matchup-specific analytics comparing win rates and side advantages (Attack vs. Defense efficiency) on selected maps.
- Final Page: Historical Records: Lifetime average stats compared across all database records.
|
|
Note: Above is the first response of the bot, prompt-asking for the maps for comparison with
Menu(tipo=1)
|
|
Note: Above is each page of the
Versus Embed Book
- Website: A seamless interface allowing the selection of both teams and displaying interactive side-by-side dashboards:
|
|
|
|
| File/Folder | Type | Summary |
|---|---|---|
| Starting v2 | .ipynb |
Initial planning and first steps for the SQL database. |
| Auto | .py |
Web scraping logic featuring vlr_stealer and stats_manager classes. |
| DB_handler | .py |
INSERT logic handled by the DB_handler class. |
| Auto_scraper.py | .py |
Integration of auto.py and DB_handler.py (Scraping then inserting into DB). |
| Disc_buttons | .py |
Interactive buttons for navigating Discord embeds. |
| Main | .py |
Discord interface and bot command handling. |
| Site | .py |
Main entry point for the Streamlit web application. |
| Website | dir/ .py |
Modular components and utility files for the website. |
| ⤷ Data Loader | .py |
Handles data retrieval and caching operations. |
| ⤷ Pages | .py |
Contains rendering functions for each individual page of the web application. |
| Brain | .py |
Back-end logic: handles database, caching, and data analysis. |
| Scraper | .yml |
Automation logic for GitHub Actions. |
| Agents | dir/ .png |
PNG files used to create Discord emojis for each agent. |
| Teams | dir/ .png |
PNG files used to create Discord emojis for each team. |
| Screenshots | dir/ .png |
Screenshots of the bot working. All of them, except info_time3, were already shown above. |
| Documentation | dir/ .md |
Project documentation and UML Diagram. |
| ⤷ Requirements | .md |
Functional and Non-Functional Requirements. |
| ⤷ Classes | .md |
Class Diagram representing the system structure. |
| ⤷ Sequence | .md |
Sequence Diagram showing object interactions. |
| ⤷ Deployment | .md |
Deployment Diagram showing infrastructure and cloud services. |
| ⤷ Privacy | .md |
Privacy Policy regarding data handling. |
| ⤷ Terms | .md |
Terms of Service for bot and dashboard usage. |
| DB Sch | .svg |
Database Schema diagram. |
| SQL_Script | .sql |
Database creation script. |
Below is the deployment architecture of the system, ilustrating how the different cloud services and containers interact:
further diagrams or detailed description is contained in
docs\files. Consult File Structure to find them.
Data Mapping Note:
stats_playerstable may raise errors during insertion if a record contains "N/A". This usually happens when a team changes its tag on vlr.gg (e.g., when DRX changed to KRX), causing a mismatch with the existing database records. While new players are added automatically, team tags must be updated manually in thetimestable to maintain Referential Integrity.
Hosted on PostgreSQL (Neon Tech free plan: 0.5GB storage, 100 CU-hours). The database consists of 9 tables. Descriptions of Portuguese attributes:
- Agentes: Agents ('nome' = name)
- Mapas_lista: Map list
- Composicoes: Team compositions
- Mapas_jogados: Played maps ('vencedor_mapa' = map winner)
- Partidas: Matches ('vencedor_time_letra' = winning team letter)
- Campeonatos: Tournaments ('completo' = completed)
- Times: Teams ('regiao' = region)
Technical Details:
- Emojis: Attributes like
emojiandemoji_discordfollow the Discord format:<:mibr:1370182490953748490>. - Pickban Log: Formatted as JSON:
{ "Abans": [12, 2], "Bbans": [7, 9], "Apicks": [5], "Bpicks": [4], "decider": 1 }, where numbers refer tomapas_lista.id. - Team References:
atk_str,vencedor_mapa, andvencedor_time_letrause 'A' or 'B' values. - Round History:
rounds_stringresemblesBBBBABBBABBBXAABAAAABAB. 'A'/'B' indicates the winner of that round; 'X' at position 13 marks half-time, and at position 26 marks overtime. - Percentage-based attributes: Stored as decimals (e.g.,
0.55for 55%). Examples are HS and KAST.
DISCORD_TOKEN: Your Discord bot token.DATABASE_URL: Your PostgreSQL connection string.GUILD_ID: Server ID for testing (removeguild=...from commands to sync globally, though this is slower).CREATOR_ID: Your Discord ID (restricts RAM cache updates to the owner).
- Clone the repository.
- Install dependencies:
pip install -r requirements.txt. - Set up the Database (see QuickBuild).
- Create a
.envfile with your credentials (rename .env.example and fill it in). - Run
python src/auto_scraper.pyto populate your database. - Run
python src/main.pyto start the bot.
To replicate the database on Neon Tech:
- Access Neon Tech Console.
- Create a new project.
- Open the SQL Editor.
- Copy and execute the SQL script provided to generate the tables and foreign keys.
- Copy your connection string from the dashboard.
Note: Ensure
sslmode=requireis present in the URL. - Manual Data Seeding: Some tables do not auto-populate in this version. You should checkout the
discBot_prototypebranch and usemigrar.ipynbto populate thetimes,mapas_lista, andagentestables. Note that some records (likecampeonatos) must be added manually. You will also need to manually update these tables when new maps or agents are released, or when the map pool changes.
This project follows Agile/Scrum principles for development. You can track real-time progress, upcoming features, and technical backlogs on our board, or join our community to chat and get direct support:
Current Focus:
- Expanding capabilities by implementing and structuring new commands.






















