# Architecture Documentation ## System Overview The Top Drives Records Analyzer consists of a main analysis binary and a shared library working together to provide comprehensive car performance analysis for the Top Drives racing game. ## Component Architecture ### 1. Records Module (`src/records.rs`) **Primary analysis engine** that processes pre-downloaded JSON timing data. #### Key Responsibilities - **Data Fetching**: Downloads car and track databases from GitHub repository - **File Processing**: Parses JSON timing files for each car configuration - **Performance Analysis**: Compares timing data across RQ ranges and track conditions - **Collection Management**: Identifies owned cars and optimization opportunities #### Key Constants - `MAX_RQ: u8 = 113` — Maximum RQ level used for range analysis (replaces former magic number 115) #### Data Flow ``` GitHub Repository ↓ cars_repo.json + tracks_repo.json ↓ times/*.json (1000+ car files) ↓ JSON Parsing → BestCarRecord Analysis ↓ User Collection (my_cars.json) ↓ Output: CSV/Terminal Results ``` ### 2. Shared Library (`src/lib.rs`) **Common utilities** shared across the project. #### Key Responsibilities - **Track Name Translation**: Converts track codes to human-readable names via `translate_track_name()` - **Track Type Translation**: Converts condition codes to surface descriptions via `translate_track_type()` #### Configuration - Track name mappings are loaded from `track_names.json` at compile time using `include_str!` - This external config file maps track codes (e.g., `"laguna"`) to human-readable names (e.g., `"Laguna Seca"`) ## Data Structures ### Core Types #### TripletKey ```rust type TripletKey = (String, u8, String); // ↓ ↓ ↓ // Track ID RQ Level Surface Condition ``` **Purpose**: Composite key for uniquely identifying track conditions **Usage**: HashMap key for storing best car records #### Car ```rust struct Car { rid: String, // Repository ID brand: String, // Manufacturer only_name: String, // Model name year: u16, // Model year rq: u8, // Rarity level prize: bool, // Prize car status guid: String, // Game GUID } ``` #### BestCarRecord ```rust struct BestCarRecord { car_rid: String, // Car identifier brand: String, // Manufacturer only_name: String, // Model name year: u16, // Year rq: u8, // RQ level config: String, // Tune config (111, 233, etc.) time: f64, // Track time (seconds) owned: bool, // User ownership status guid: String, // Game identifier } ``` ## Global State Management ### BEST_CARS Cache ```rust static BEST_CARS: Lazy>>> ``` **Thread Safety**: Protected by `Mutex` for concurrent access during parsing **Initialization**: Uses `once_cell::Lazy` for one-time setup **Structure**: HashMap with composite keys for efficient lookups ## Algorithm Details ### RQ Range Analysis The system analyzes car performance across multiple RQ brackets: 1. **Base RQ**: Car's natural rarity level 2. **RQ Range**: Tests from car's RQ up to `MAX_RQ` (113) 3. **Cross-RQ Competition**: Allows cars to compete above their base level **Example**: A RQ 85 car might perform well at RQ 90-95 levels against higher-rated cars ### Time Validation Multiple validation layers ensure data quality: 1. **Minimum Time**: Times below 1.2 seconds are discarded 2. **Downvote Filter**: Community-downvoted times are excluded 3. **Special Cases**: Test Bowl track uses inverted time calculation (2000.0 / time) ### Concurrent Processing #### Bounded Concurrency Pattern - **Task Spawning**: One async task per car file - **Semaphore**: Limits concurrent operations to 20 (bounded concurrency) - **Error Isolation**: Individual car failures don't stop batch processing #### Synchronization - **Join Handles**: Waits for all parsing tasks to complete - **Mutex Protection**: Safe concurrent access to shared BEST_CARS cache ## File Organization ### Input Files ``` ├── cars_repo.json # Car database from repository ├── tracks_repo.json # Track definitions ├── track_names.json # Track code → name mappings (compiled in) ├── my_cars.json # User's car collection (game export) └── times/ # Individual car timing files ├── Ferrari_F40_1987.json ├── McLaren_F1_1993.json └── ... ``` ### Output Files ``` ├── best.csv # Best cars analysis results ├── details.csv # Detailed timing data ├── add.csv # Cars to add to wishlist ├── remove.csv # Cars to remove from wishlist ├── trash.csv # Owned cars safe to remove ├── sorted.csv # Best cars sorted by count ├── very_best.csv # Best cars with count ≥ 10 └── wishlist.csv # Missing cars already on wishlist ``` ## Performance Characteristics ### Records Module - **Startup Time**: Fast (uses cached JSON files) - **Memory Usage**: Moderate (loads all timing data into memory) - **Accuracy**: High (comprehensive dataset) - **Update Frequency**: Manual refresh required - **Concurrency**: Bounded at 20 simultaneous operations via semaphore ## Error Handling Strategy ### Graceful Degradation - **Missing Files**: Continue with available data - **Network Errors**: Log errors but don't crash - **Parse Failures**: Use default values or skip invalid entries ### User Feedback - **Progress Indication**: Shows fetching/download progress - **Error Messages**: Clear descriptions of what went wrong ## Extension Points ### Adding New Tracks 1. Update `tracks_repo.json` with new track definitions 2. Add track name mapping in `track_names.json` 3. Add condition mappings in `translate_track_type()` ### Adding New Analysis Types 1. Create new output functions (similar to `print_best_cars()`) 2. Add command parsing in main function 3. Update help text and documentation ## Security Considerations ### Network Access - **HTTPS Only**: All external requests use HTTPS - **Certificate Validation**: Accepts invalid certificates for compatibility - **Rate Limiting**: Respects server limits with controlled concurrency (semaphore limit of 20) ### Local File Access - **Read Only**: No modification of game files - **User Data**: Only reads exported collection data - **No Persistence**: Analysis results are output-only ## Future Enhancements ### Potential Improvements 1. **Caching Layer**: Cache parsed results between runs 2. **Database Backend**: Replace in-memory HashMap with persistent storage 3. **Configuration Files**: External configuration for analysis parameters 4. **GUI Interface**: Web-based interface for non-technical users 5. **Export Formats**: Multiple output formats (JSON, XML, etc.) ### Scalability Considerations 1. **Pagination**: Handle large datasets with pagination 2. **Incremental Updates**: Only fetch changed data 3. **Compression**: Compress large timing files 4. **Streaming**: Process data without loading everything into memory