docsresourcesQb Trucking

QB-Trucking - Freight Delivery System

The qb-trucking resource provides a comprehensive freight delivery and logistics system for QBCore servers, featuring cargo missions, delivery routes, truck management, and logistics company operations.

Overview

QB-Trucking creates a realistic freight industry experience with cargo hauling, delivery contracts, route planning, and trucking company management. Players can operate as independent truckers or work for logistics companies.

Key Features

  • Cargo Missions: Various freight delivery contracts
  • Delivery Routes: Short and long-haul trucking routes
  • Truck Fleet: Multiple truck and trailer combinations
  • Cargo Management: Different cargo types and handling requirements
  • Route Planning: GPS navigation and optimal routing
  • Fuel Management: Fuel consumption and refueling stops
  • Weight Regulations: Cargo weight limits and inspections
  • Company Operations: Trucking business management
  • Driver Licensing: CDL requirements and training

Installation

Prerequisites

  • QBCore Framework
  • qb-target (for interaction system)
  • qb-menu (for trucking menus)
  • qb-fuel (for fuel management)
  • qb-vehiclekeys (for truck access)

Installation Steps

  1. Download the Resource
cd resources/[qb]
git clone https://github.com/qbcore-framework/qb-trucking.git
  1. Database Setup
-- Trucking tables
CREATE TABLE IF NOT EXISTS `trucking_deliveries` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `driver_citizenid` varchar(50) DEFAULT NULL,
  `cargo_type` varchar(100) DEFAULT NULL,
  `pickup_location` varchar(255) DEFAULT NULL,
  `delivery_location` varchar(255) DEFAULT NULL,
  `distance` float DEFAULT 0,
  `payment` int(11) DEFAULT 0,
  `fuel_cost` int(11) DEFAULT 0,
  `status` varchar(50) DEFAULT 'pending',
  `completed_at` timestamp NULL DEFAULT NULL,
  `created_at` timestamp DEFAULT current_timestamp(),
  PRIMARY KEY (`id`)
);
 
CREATE TABLE IF NOT EXISTS `trucking_licenses` (
  `citizenid` varchar(50) NOT NULL,
  `license_type` varchar(50) DEFAULT 'Class A',
  `issued_date` timestamp DEFAULT current_timestamp(),
  `expires_date` timestamp DEFAULT NULL,
  `status` varchar(50) DEFAULT 'active',
  PRIMARY KEY (`citizenid`)
);
 
CREATE TABLE IF NOT EXISTS `trucking_companies` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `owner_citizenid` varchar(50) DEFAULT NULL,
  `employees` longtext DEFAULT NULL,
  `fleet` longtext DEFAULT NULL,
  `contracts` longtext DEFAULT NULL,
  `created_at` timestamp DEFAULT current_timestamp(),
  PRIMARY KEY (`id`)
);
  1. Add Job Configuration
['trucker'] = {
    label = 'Truck Driver',
    defaultDuty = true,
    offDutyPay = false,
    grades = {
        ['0'] = {
            name = 'Trainee Driver',
            payment = 75
        },
        ['1'] = {
            name = 'Local Driver',
            payment = 100
        },
        ['2'] = {
            name = 'Long Haul Driver',
            payment = 150
        },
        ['3'] = {
            name = 'Owner Operator',
            payment = 200,
            isboss = true
        }
    }
}

Configuration

Basic Configuration

Config = {}
 
-- General Settings
Config.UseTarget = true
Config.FuelConsumption = 0.8 -- Liters per km
Config.BasePayRate = 2.5 -- $ per km
Config.MaxCargoWeight = 26000 -- kg
Config.SpeedPenalty = 0.1 -- 10% pay reduction for speeding
 
-- Trucking Company Locations
Config.Locations = {
    ["rsm"] = {
        label = "RSM Logistics",
        coords = vector3(1240.35, -3251.93, 7.09),
        blip = {
            sprite = 477,
            color = 17,
            scale = 0.8
        },
        zones = {
            duty = vector3(1240.35, -3251.93, 7.09),
            garage = vector4(1249.23, -3242.11, 6.03, 270.0),
            fuel = vector3(1207.84, -3196.41, 6.03)
        }
    },
    ["lsdocks"] = {
        label = "LS Docks Freight",
        coords = vector3(797.44, -2989.72, 6.02),
        zones = {
            duty = vector3(797.44, -2989.72, 6.02),
            garage = vector4(809.44, -2988.72, 6.02, 0.0)
        }
    }
}
 
-- Cargo Types
Config.CargoTypes = {
    ["general"] = {
        label = "General Freight",
        weight = 15000,
        payment_multiplier = 1.0,
        special_requirements = false
    },
    ["hazmat"] = {
        label = "Hazardous Materials",
        weight = 10000,
        payment_multiplier = 2.5,
        special_requirements = true,
        required_license = "hazmat"
    },
    ["oversized"] = {
        label = "Oversized Load",
        weight = 25000,
        payment_multiplier = 3.0,
        special_requirements = true,
        escort_required = true
    },
    ["refrigerated"] = {
        label = "Refrigerated Goods",
        weight = 18000,
        payment_multiplier = 1.8,
        temperature_critical = true
    }
}

Delivery Routes

-- Delivery Locations
Config.DeliveryPoints = {
    ["lsia"] = {
        label = "LS International Airport",
        coords = vector3(-1336.95, -3044.85, 13.94),
        cargo_types = {"general", "refrigerated"},
        unload_time = 120 -- seconds
    },
    ["paleto_lumber"] = {
        label = "Paleto Lumber Mill",
        coords = vector3(-596.59, 5252.93, 70.28),
        cargo_types = {"general", "oversized"},
        unload_time = 180
    },
    ["sandy_warehouse"] = {
        label = "Sandy Shores Warehouse",
        coords = vector3(2533.84, 2594.17, 37.95),
        cargo_types = {"general", "hazmat"},
        unload_time = 150
    },
    ["grapeseed_farm"] = {
        label = "Grapeseed Farm Co-op",
        coords = vector3(2204.78, 5578.64, 53.75),
        cargo_types = {"refrigerated"},
        unload_time = 90
    }
}
 
-- Route Configurations
Config.Routes = {
    ["local_short"] = {
        label = "Local Delivery",
        distance_range = {5, 25}, -- km
        payment_range = {500, 1500},
        cargo_types = {"general"}
    },
    ["regional"] = {
        label = "Regional Haul",
        distance_range = {25, 75},
        payment_range = {1500, 4000},
        cargo_types = {"general", "refrigerated"}
    },
    ["long_haul"] = {
        label = "Long Distance",
        distance_range = {75, 150},
        payment_range = {4000, 8000},
        cargo_types = {"general", "hazmat", "oversized"}
    }
}

API Reference

Client Exports

StartDelivery

Start a new delivery mission.

-- Start random delivery
exports['qb-trucking']:StartDelivery()
 
-- Start specific cargo type delivery
exports['qb-trucking']:StartDelivery("hazmat")
 
-- Start delivery with specific route
exports['qb-trucking']:StartDelivery("general", "long_haul")

AttachTrailer

Attach trailer to truck.

local success = exports['qb-trucking']:AttachTrailer(truck, trailer)
 
-- Returns: boolean success status

GetCargoInfo

Get information about current cargo.

local cargoInfo = exports['qb-trucking']:GetCargoInfo()
 
-- Returns:
-- {
--   type = string,
--   weight = number,
--   destination = string,
--   special_requirements = boolean
-- }

Server Exports

CreateDeliveryContract

Create a new delivery contract.

local contractId = exports['qb-trucking']:CreateDeliveryContract(data)
 
-- Parameters:
-- data: {
--   driver_citizenid = string,
--   cargo_type = string,
--   pickup_location = string,
--   delivery_location = string,
--   distance = number,
--   payment = number
-- }

ProcessDeliveryPayment

Process payment for completed delivery.

local success = exports['qb-trucking']:ProcessDeliveryPayment(source, contractId, bonuses)
 
-- Parameters:
-- source: Player server ID
-- contractId: Delivery contract ID
-- bonuses: Additional payment modifiers

GetDriverLicense

Check driver’s commercial license status.

local license = exports['qb-trucking']:GetDriverLicense(citizenId)
 
-- Returns license information or nil

Events

Client Events

-- Delivery started
RegisterNetEvent('qb-trucking:client:deliveryStarted', function(contractData)
    -- Handle delivery start
end)
 
-- Cargo loaded
RegisterNetEvent('qb-trucking:client:cargoLoaded', function(cargoInfo)
    -- Handle cargo loading
end)
 
-- Delivery completed
RegisterNetEvent('qb-trucking:client:deliveryCompleted', function(payment, bonuses)
    -- Handle delivery completion
end)
 
-- Trailer attached
RegisterNetEvent('qb-trucking:client:trailerAttached', function(trailer)
    -- Handle trailer attachment
end)

Usage Examples

Delivery Mission System

-- Start delivery mission
RegisterNetEvent('qb-trucking:client:startMission', function(missionType)
    local player = QBCore.Functions.GetPlayerData()
    if player.job.name == "trucker" and player.job.onduty then
        
        -- Check for CDL license
        QBCore.Functions.TriggerCallback('qb-trucking:server:hasLicense', function(hasLicense)
            if not hasLicense then
                QBCore.Functions.Notify("You need a Commercial Driver's License", "error")
                return
            end
            
            -- Generate delivery contract
            local contractData = GenerateContract(missionType)
            
            -- Set pickup waypoint
            SetNewWaypoint(contractData.pickup.x, contractData.pickup.y)
            
            QBCore.Functions.Notify("Contract accepted! Head to pickup location", "success")
            
            -- Store contract data
            currentContract = contractData
            
        end)
    end
end)
 
function GenerateContract(missionType)
    local routeConfig = Config.Routes[missionType or "local_short"]
    local pickupPoint = Config.DeliveryPoints[math.random(1, #Config.DeliveryPoints)]
    local deliveryPoint = Config.DeliveryPoints[math.random(1, #Config.DeliveryPoints)]
    
    -- Ensure pickup and delivery are different
    while deliveryPoint == pickupPoint do
        deliveryPoint = Config.DeliveryPoints[math.random(1, #Config.DeliveryPoints)]
    end
    
    local distance = #(pickupPoint.coords - deliveryPoint.coords) / 1000 -- Convert to km
    local payment = math.floor(distance * Config.BasePayRate * math.random(80, 120) / 100)
    
    return {
        id = math.random(10000, 99999),
        pickup = pickupPoint,
        delivery = deliveryPoint,
        distance = distance,
        payment = payment,
        cargo_type = routeConfig.cargo_types[math.random(1, #routeConfig.cargo_types)],
        created_at = os.time()
    }
end

Cargo Loading System

-- Load cargo at pickup location
RegisterNetEvent('qb-trucking:client:loadCargo', function()
    if not currentContract then
        QBCore.Functions.Notify("No active delivery contract", "error")
        return
    end
    
    local ped = PlayerPedId()
    local vehicle = GetVehiclePedIsIn(ped, false)
    local trailer = GetVehicleTrailerVehicle(vehicle)
    
    if not trailer or trailer == 0 then
        QBCore.Functions.Notify("You need a trailer to load cargo", "error")
        return
    end
    
    -- Check if at pickup location
    local playerCoords = GetEntityCoords(ped)
    local distance = #(playerCoords - currentContract.pickup.coords)
    
    if distance > 10.0 then
        QBCore.Functions.Notify("You're not at the pickup location", "error")
        return
    end
    
    QBCore.Functions.Progressbar("loading_cargo", "Loading cargo...", 15000, false, true, {
        disableMovement = true,
        disableCarMovement = true,
        disableMouse = false,
        disableCombat = true,
    }, {
        animDict = "mini@repair",
        anim = "fixing_a_ped",
    }, {}, {}, function()
        -- Cargo loaded successfully
        TriggerServerEvent('qb-trucking:server:cargoLoaded', currentContract.id)
        
        -- Set delivery waypoint
        SetNewWaypoint(currentContract.delivery.coords.x, currentContract.delivery.coords.y)
        
        QBCore.Functions.Notify("Cargo loaded! Deliver to destination", "success")
        cargoLoaded = true
        
        -- Create delivery blip
        local deliveryBlip = AddBlipForCoord(currentContract.delivery.coords.x, currentContract.delivery.coords.y, currentContract.delivery.coords.z)
        SetBlipSprite(deliveryBlip, 477)
        SetBlipColour(deliveryBlip, 2)
        SetBlipRoute(deliveryBlip, true)
        BeginTextCommandSetBlipName("STRING")
        AddTextComponentString("Delivery Location")
        EndTextCommandSetBlipName(deliveryBlip)
        currentContract.deliveryBlip = deliveryBlip
        
    end, function()
        QBCore.Functions.Notify("Cargo loading cancelled", "error")
    end)
end)

Fuel Management Integration

-- Monitor fuel consumption during delivery
CreateThread(function()
    while true do
        Wait(30000) -- Check every 30 seconds
        
        if currentContract and cargoLoaded then
            local ped = PlayerPedId()
            local vehicle = GetVehiclePedIsIn(ped, false)
            
            if vehicle and GetPedInVehicleSeat(vehicle, 0) == ped then
                local speed = GetEntitySpeed(vehicle) * 3.6 -- Convert to km/h
                local fuelLevel = exports['qb-fuel']:GetFuel(vehicle)
                
                -- Calculate fuel consumption based on speed and cargo weight
                local cargoWeight = Config.CargoTypes[currentContract.cargo_type].weight
                local weightMultiplier = 1 + (cargoWeight / Config.MaxCargoWeight)
                local speedMultiplier = 1 + (speed / 100) -- Higher speed = more consumption
                
                local consumption = Config.FuelConsumption * weightMultiplier * speedMultiplier * (30/3600) -- Per 30 seconds
                
                if fuelLevel - consumption <= 5 then
                    QBCore.Functions.Notify("Low fuel! Find a gas station soon", "warning")
                end
                
                -- Apply fuel consumption
                exports['qb-fuel']:SetFuel(vehicle, math.max(0, fuelLevel - consumption))
            end
        end
    end
end)

Troubleshooting

Common Issues

Trailer Attachment Problems

-- Check trailer compatibility
function IsTrailerCompatible(truck, trailer)
    local truckModel = GetEntityModel(truck)
    local trailerModel = GetEntityModel(trailer)
    
    -- Add compatibility checks
    local compatibleCombos = {
        [GetHashKey("phantom")] = {GetHashKey("trailers"), GetHashKey("trailers2")},
        [GetHashKey("hauler")] = {GetHashKey("trailers3"), GetHashKey("trailers4")}
    }
    
    if compatibleCombos[truckModel] then
        for i = 1, #compatibleCombos[truckModel] do
            if compatibleCombos[truckModel][i] == trailerModel then
                return true
            end
        end
    end
    
    return false
end

Delivery Payment Issues

  • Verify contract completion status in database
  • Check for proper distance calculations
  • Ensure fuel costs are being deducted correctly

License Verification Problems

-- Debug license checking
RegisterCommand('checklicense', function()
    QBCore.Functions.TriggerCallback('qb-trucking:server:hasLicense', function(hasLicense, licenseData)
        if hasLicense then
            print("License valid:", json.encode(licenseData))
        else
            print("No valid license found")
        end
    end)
end)

Debug Commands

-- Complete current delivery (admin only)
/completedelivery
 
-- Give CDL license
/givetrucklicense [player_id]
 
-- Spawn truck and trailer
/spawnrig [truck_model] [trailer_model]
 
-- Check delivery stats
/truckstats [driver_name]
⚠️

Test cargo weight calculations and fuel consumption to ensure realistic gameplay balance.