Skip to content

Architecture

Artmines edited this page Nov 3, 2025 · 3 revisions

Architecture

Complete overview of QC-AdvancedMedic's system design, file structure, and data flow.


System Design Philosophy

QC-AdvancedMedic uses a client-authoritative damage detection system with server-side validation and persistence. This means:

  • Clients detect wounds immediately (no lag)
  • Server validates and stores everything
  • Database keeps medical history permanently

File Structure

QC-AdvancedMedic/
├── fxmanifest.lua              # Resource manifest
├── config.lua                  # Main configuration (weapon damage, treatments, etc.)
├── ConfigMissions.lua          # Training mission configurations
│
├── client/                     # Client-side Lua (9 files)
│   ├── client_shared.lua       # Shared utility functions
│   ├── client.lua              # Main UI, death system, NUI callbacks
│   ├── wound_system.lua        # Core damage detection & wound tracking
│   ├── treatment_system.lua    # Bandages, tourniquets, medicines, injections
│   ├── infection_system.lua    # Infection progression & cure system
│   ├── wound_healing.lua       # Healing wounds to scars
│   ├── bag.lua                 # Medical bag crafting/deployment
│   ├── job_system.lua          # Medic missions & NPC patients
│   └── envanim_system.lua      # Fall damage, animal attacks, fractures
│
├── server/                     # Server-side Lua (6 files)
│   ├── server.lua              # Commands, item registration, duty pay
│   ├── database.lua            # All database operations
│   ├── medical_events.lua      # Network event handlers
│   ├── medical_server.lua      # Medical profiles, /inspect command
│   ├── sv_bag.lua              # Medical bag server logic
│   └── versionchecker.lua      # GitHub version checking
│
├── ui/                         # React NUI (TypeScript)
│   ├── src/                    # Source code (React + TypeScript)
│   │   ├── App.tsx             # Main app component
│   │   ├── index.tsx           # React entry point
│   │   ├── components/         # UI components
│   │   │   ├── DeathScreen.tsx       # Death screen component
│   │   │   ├── MedicalPanel.tsx      # Self-examination panel
│   │   │   └── InspectionPanel.tsx   # Medic inspection UI
│   │   └── assets/             # Images and CSS
│   │       ├── css/            # Component stylesheets
│   │       └── imgs/           # Body part images
│   ├── build/                  # Production build (compiled)
│   │   ├── index.html
│   │   └── static/             # Bundled JS/CSS
│   └── package.json            # React dependencies (v18.2)
│
├── locales/                    # Translations
│   ├── en.json                 # English
│   ├── es.json                 # Spanish
│   └── fr.json                 # French
│
└── INSTALL_FIRST/              # Installation files
    ├── schema.sql              # Database schema
    ├── shared_items.lua        # Items for rsg-core
    └── IMAGES/                 # Item images

Note

The NUI is a React 18.2 + TypeScript application. Full source code is included in ui/src/ with components for death screen, medical panel, and inspection UI. Run bun run build in the ui folder to rebuild.


Core Files Breakdown

Client-Side (9 files, 7500+ lines)

File Lines Purpose Update Frequency
wound_system.lua 2024 Damage detection, wound tracking, progression Every 100ms (damage), 2 min (progression)
treatment_system.lua 787 Treatment application (4 types) On-demand (item use)
infection_system.lua 616 Infection progression & cure Every 2 minutes
wound_healing.lua 231 Healing wounds to scars Every 2 minutes
client.lua 2000+ Death system, UI, NUI callbacks Variable (UI-driven)
envanim_system.lua 516 Fall damage, animal attacks, fractures Every 1 second
job_system.lua 1333 Medic missions, NPC patients On-demand
bag.lua 216 Medical bag deployment On-demand
client_shared.lua 60 Helper functions N/A (utilities)

Server-Side (6 files, 3000+ lines)

File Lines Purpose
database.lua 713 All database operations, logging, persistence
medical_events.lua 684 Network event handlers, client-server sync
medical_server.lua 929 Medical profiles, /inspect command, wound progression
server.lua 549 Commands, item registration, duty pay, admin tools
sv_bag.lua 83 Medical bag crafting validation
versionchecker.lua 27 GitHub version checking

Data Flow

┌─────────────────────────────────────────────────────────────────┐
│ 1. DAMAGE OCCURS                                                │
│    Player gets shot/stabbed/falls/attacked                      │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ 2. CLIENT DETECTION (wound_system.lua)                          │
│    • Monitors health every 100ms                                │
│    • Detects damage event                                       │
│    • Gets weapon hash & body part hit                           │
│    • Calculates bullet penetration (distance-based)             │
│    • Creates wound in PlayerWounds[bodyPart]                    │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ 3. SERVER PERSISTENCE (medical_events.lua → database.lua)       │
│    • Client sends UpdateWoundData event                         │
│    • Server validates and saves to database                     │
│    • Broadcasts to nearby medics (10m radius)                   │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ 4. TREATMENT (treatment_system.lua)                             │
│    • Medic or self applies bandage/medicine                     │
│    • Immediate healing: +8 to +25 HP                            │
│    • Bleeding reduced to minimum level 1                        │
│    • Treatment tracked in ActiveTreatments[bodyPart]            │
│    • Synced to server → database                                │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ 5. TIME-BASED PROGRESSION (every 2 minutes)                     │
│    • Bandages expire (3-12 min) → 50% symptom return            │
│    • Expired bandages → infection risk                          │
│    • Untreated wounds → pain/bleeding increases                 │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ 6. COMPLICATIONS OR HEALING                                     │
│    • Infection: 4 stages (25% → 50% → 75% → 90%)                │
│    • Healing: Wounds → Scars (if maintained properly)           │
│    • Death: At 0 HP or 10+ bleeding level                       │
└─────────────────────────────────────────────────────────────────┘

Important

All wound data persists across server restarts. When players reconnect, their medical history loads from the database automatically.


Client-Server Communication

Event Flow

Client → Server (Data Sync):

  • UpdateWoundData - Wound changes (every 2 min or on damage)
  • UpdateTreatmentData - Treatment changes (on application/removal)
  • UpdateInfectionData - Infection changes (every 2 min)
  • LoadMedicalData - Request data on spawn

Server → Client (Commands):

  • SyncWoundData - Updated wound data
  • ApplyBandage - Apply bandage to patient
  • ShowInspectionPanel - Show medic UI

Server → Nearby Clients (Broadcasting):

  • Wound updates broadcast to medics within 10m radius
  • Prevents unnecessary network traffic

Data Persistence Flow

Client Wound Detection
         ↓
Client Memory (PlayerWounds table)
         ↓
Server Event (UpdateWoundData)
         ↓
Server Cache (PlayerMedicalData[source])
         ↓
Database (player_wounds table)

Sync Frequency:

  • Immediate: On damage/treatment
  • Periodic: Every 5 minutes (auto-sync)
  • On disconnect: Full save

Database Architecture

5 Tables + Views

  1. player_wounds - Active wounds and scars
  2. medical_treatments - Active treatments (bandages, medicines, etc.)
  3. player_infections - Active infections with progression
  4. player_fractures - Bone fractures/breaks (New in v0.2.9)
  5. medical_history - Complete audit trail

Views:

  • active_medical_status - Joined view for NUI (New in v0.2.9)

Stored Procedures:

  • GetCompleteMedicalProfile - Get all medical data in one call
  • CleanupExpiredMedicalData - Remove old data (>30 days)

See Database Schema for complete details.


Server-Side Caching

The server maintains a cache to reduce database queries by ~90%:

PlayerMedicalData[playerId] = {
    citizenid = "ABC12345",
    wounds = {...},           -- Copy of client wounds
    treatments = {...},       -- Copy of client treatments
    infections = {...},       -- Copy of client infections
    bandages = {...},         -- Legacy bandage tracking
    lastSync = os.time()      -- Last database sync time
}

Cache Management:

  • Initialized on player connect
  • Updated on every medical event
  • Synced to database every 5 minutes
  • Saved on player disconnect

NUI Architecture

Technology: React 18.2 + TypeScript

Source Code: ui/src/ (fully included, customizable)

Components:

  1. DeathScreen.tsx - Death timer, medic count, respawn button
  2. MedicalPanel.tsx - Self-examination with interactive body diagram
  3. InspectionPanel.tsx - Medic inspection UI showing patient wounds

Development:

cd ui
bun install
bun run dev  # Development server
bun run build  # Production build

Communication:

Client Lua (client.lua)
       ↓ SendNUIMessage
NUI React App (ui/build/)
       ↓ RegisterNUICallback
Client Lua (processes action)
       ↓ TriggerServerEvent
Server (validates & applies)

See Client Systems for NUI details.


Performance Considerations

Client-Side Threads

Thread Interval Impact
Damage Detection 100ms ~0.01ms
Bleeding Damage 30s ~0.001ms
Medical Progression 2min ~0.01ms
Death Camera 16ms ~0.12ms ⚠️

Warning

The free-look death camera runs at 62 FPS while dead. Disable Config.DeadMoveCam for production servers.

Database Operations

Queries Reduced:

  • Without cache: ~50 queries/min per player
  • With cache: ~5 queries/min per player
  • 90% reduction via server-side caching

See Performance Optimization for tuning tips.


← Home | Next: Client Systems →

📖 QC-AdvancedMedic

🏠 Home


📚 Documentation

  1. Architecture
  2. Client Systems
  3. Server Systems
  4. Database Schema

⚙️ Configuration

  1. Configuration
  2. Translation System
  3. API Reference

🛠️ Development

  1. Extending the System
  2. Performance Optimization

⚠️ Support

  1. Known Issues

🔗 Links


v0.3.1-alpha

Clone this wiki locally