Project Deep Dive

Detailed breakdown of my Lua scripting and game development projects

Quick Jump

Tofu-Job System

Full job management for 5,000+ concurrent players — salaries, performance metrics, and real-time sync.

Lua Database Real-time

Overview

A comprehensive job management system designed for gaming servers, featuring dynamic job creation, player employment mechanics, salary systems, and workplace interactions. The system includes real-time job tracking, performance analytics, and administrative controls.

Multi-player job assignment
Dynamic salary calculation
Performance tracking
Admin management panel

Key Code Snippets

Job Registration System

-- Job registration and player assignment
function RegisterJob(jobName, maxPlayers, baseSalary, requirements)
    local jobData = {
        name = jobName,
        maxPlayers = maxPlayers,
        currentPlayers = 0,
        baseSalary = baseSalary,
        requirements = requirements,
        activeWorkers = {},
        createdAt = os.time()
    }
    
    Jobs[jobName] = jobData
    TriggerClientEvent('tofu-job:jobCreated', -1, jobData)
    
    print(string.format('[TOFU-JOB] Job "%s" registered with %d max players', 
          jobName, maxPlayers))
end

-- Player job assignment with validation
function AssignPlayerToJob(playerId, jobName)
    local player = GetPlayerPed(playerId)
    local job = Jobs[jobName]
    
    if not job then
        TriggerClientEvent('tofu-job:notify', playerId, 'Job does not exist', 'error')
        return false
    end
    
    if job.currentPlayers >= job.maxPlayers then
        TriggerClientEvent('tofu-job:notify', playerId, 'Job is full', 'error')
        return false
    end
    
    -- Add player to job
    job.activeWorkers[playerId] = {
        startTime = os.time(),
        performance = 0,
        earnings = 0
    }
    
    job.currentPlayers = job.currentPlayers + 1
    PlayerJobs[playerId] = jobName
    
    TriggerClientEvent('tofu-job:jobAssigned', playerId, job)
    return true
end

Salary Calculation Engine

-- Dynamic salary calculation based on performance
function CalculateSalary(playerId, workDuration)
    local job = Jobs[PlayerJobs[playerId]]
    local worker = job.activeWorkers[playerId]
    
    if not job or not worker then return 0 end
    
    local basePay = job.baseSalary
    local performanceMultiplier = 1 + (worker.performance / 100)
    local timeBonus = math.min(workDuration / 3600, 2.0) -- Max 2x for time
    
    local totalSalary = basePay * performanceMultiplier * timeBonus
    
    -- Add random bonus events
    if math.random(1, 100) <= 10 then -- 10% chance
        totalSalary = totalSalary * 1.5
        TriggerClientEvent('tofu-job:notify', playerId, 'Bonus earned!', 'success')
    end
    
    return math.floor(totalSalary)
end

-- Performance tracking system
function UpdatePerformance(playerId, taskCompleted, quality)
    local job = Jobs[PlayerJobs[playerId]]
    if not job or not job.activeWorkers[playerId] then return end
    
    local performanceGain = quality * 2 -- Quality ranges 1-10
    job.activeWorkers[playerId].performance = 
        math.min(job.activeWorkers[playerId].performance + performanceGain, 100)
    
    TriggerClientEvent('tofu-job:performanceUpdate', playerId, 
                       job.activeWorkers[playerId].performance)
end

Technical Highlights

  • Real-time Data Sync: Efficient player state management across server instances
  • Performance Metrics: Dynamic calculation system with bonus mechanics
  • Scalable Architecture: Modular design supporting multiple job types
  • Database Integration: Persistent storage for player progress and earnings

Zendo-Racing Engine

Custom race engine with precision lap timing, checkpoint validation, and dynamic leaderboards.

Lua Multiplayer Real-time

Overview

Advanced racing system featuring custom track creation, precise lap timing, competitive leaderboards, and seamless multiplayer support. Includes checkpoint validation, comprehensive race statistics, and tournament management capabilities for competitive gaming environments.

Precision timing system
Leaderboard rankings
Custom track builder
Tournament system

Key Code Snippets

Race Management System

-- Race state management and timing
local RaceManager = {}
RaceManager.activeRaces = {}
RaceManager.playerRaces = {}

function RaceManager:StartRace(raceId, trackId, participants)
    local race = {
        id = raceId,
        trackId = trackId,
        participants = participants,
        startTime = GetGameTimer(),
        status = 'active',
        leaderboard = {},
        currentLap = {}
    }
    
    -- Initialize participant data
    for _, playerId in pairs(participants) do
        race.currentLap[playerId] = 1
        race.leaderboard[playerId] = {
            lapTimes = {},
            bestLap = 999999,
            totalTime = 0,
            position = #participants,
            checkpoints = 0
        }
        
        self.playerRaces[playerId] = raceId
        TriggerClientEvent('zendo-racing:raceStart', playerId, race)
    end
    
    self.activeRaces[raceId] = race
    print(string.format('[RACING] Race %s started with %d participants', 
          raceId, #participants))
end

-- Checkpoint validation and timing
function RaceManager:ValidateCheckpoint(playerId, checkpointId)
    local raceId = self.playerRaces[playerId]
    local race = self.activeRaces[raceId]
    
    if not race then return false end
    
    local track = Tracks[race.trackId]
    local player = race.leaderboard[playerId]
    local expectedCheckpoint = (player.checkpoints % #track.checkpoints) + 1
    
    -- Validate checkpoint sequence
    if checkpointId ~= expectedCheckpoint then
        TriggerClientEvent('zendo-racing:invalidCheckpoint', playerId)
        return false
    end
    
    player.checkpoints = player.checkpoints + 1
    local currentTime = GetGameTimer() - race.startTime
    
    -- Lap completion detection
    if checkpointId == #track.checkpoints then
        self:CompleteLap(playerId, currentTime)
    end
    
    TriggerClientEvent('zendo-racing:checkpointPassed', playerId, checkpointId)
    return true
end

Lap Timing and Leaderboard

-- Precise lap timing calculation
function RaceManager:CompleteLap(playerId, currentTime)
    local raceId = self.playerRaces[playerId]
    local race = self.activeRaces[raceId]
    local player = race.leaderboard[playerId]
    
    -- Calculate lap time
    local lapStartTime = player.lapTimes[race.currentLap[playerId] - 1] or race.startTime
    local lapTime = currentTime - lapStartTime
    
    -- Record lap time
    table.insert(player.lapTimes, currentTime)
    
    -- Update best lap
    if lapTime < player.bestLap then
        player.bestLap = lapTime
        TriggerClientEvent('zendo-racing:newBestLap', playerId, lapTime)
    end
    
    race.currentLap[playerId] = race.currentLap[playerId] + 1
    
    -- Update leaderboard positions
    self:UpdateLeaderboard(raceId)
    
    -- Check race completion
    local track = Tracks[race.trackId]
    if race.currentLap[playerId] > track.totalLaps then
        self:PlayerFinished(playerId, currentTime)
    end
end

-- Dynamic leaderboard calculation
function RaceManager:UpdateLeaderboard(raceId)
    local race = self.activeRaces[raceId]
    local sortedPlayers = {}
    
    -- Create sortable player array
    for playerId, data in pairs(race.leaderboard) do
        table.insert(sortedPlayers, {
            id = playerId,
            lap = race.currentLap[playerId],
            checkpoints = data.checkpoints,
            totalTime = #data.lapTimes > 0 and data.lapTimes[#data.lapTimes] or 999999
        })
    end
    
    -- Sort by lap, then checkpoints, then time
    table.sort(sortedPlayers, function(a, b)
        if a.lap ~= b.lap then return a.lap > b.lap end
        if a.checkpoints ~= b.checkpoints then return a.checkpoints > b.checkpoints end
        return a.totalTime < b.totalTime
    end)
    
    -- Update positions and broadcast
    for position, playerData in ipairs(sortedPlayers) do
        race.leaderboard[playerData.id].position = position
        TriggerClientEvent('zendo-racing:positionUpdate', playerData.id, position)
    end
    
    TriggerClientEvent('zendo-racing:leaderboardUpdate', -1, sortedPlayers)
end

Technical Highlights

  • Precision Timing: Millisecond-accurate lap and split times
  • Anti-cheat Validation: Checkpoint sequence verification system
  • Real-time Leaderboards: Dynamic position updates during races
  • Tournament Framework: Bracket management and scoring system

Dynamic Speedometer

TypeScript speedometer with smooth 60fps animations, RPM tracking, and customizable HUD themes.

TypeScript Real-time Animation

Overview

Real-time vehicle speedometer built with TypeScript, featuring customizable UI elements, multiple unit support (MPH/KMH), and comprehensive performance metrics display. Features smooth animations, responsive design elements, type-safe implementation, and integration with vehicle systems for accurate speed calculation.

Real-time speed tracking
Customizable themes
Responsive design
Performance metrics

Key Code Snippets

Speed Calculation Engine

-- Accurate speed calculation and smoothing
local Speedometer = {}
Speedometer.config = {
    updateInterval = 50, -- Update every 50ms for smooth animation
    smoothingFactor = 0.8,
    maxSpeed = 300,
    units = 'mph' -- 'mph' or 'kmh'
}

local speedHistory = {}
local currentSpeed = 0
local targetSpeed = 0

-- Calculate vehicle speed with smoothing
function Speedometer:CalculateSpeed(vehicle)
    if not DoesEntityExist(vehicle) then return 0 end
    
    local velocity = GetEntityVelocity(vehicle)
    local speed = math.sqrt(velocity.x^2 + velocity.y^2 + velocity.z^2)
    
    -- Convert to appropriate units
    if self.config.units == 'mph' then
        speed = speed * 2.236936 -- m/s to mph
    else
        speed = speed * 3.6 -- m/s to kmh
    end
    
    -- Apply smoothing to prevent jittery display
    table.insert(speedHistory, speed)
    if #speedHistory > 5 then
        table.remove(speedHistory, 1)
    end
    
    local smoothedSpeed = 0
    for _, historicalSpeed in pairs(speedHistory) do
        smoothedSpeed = smoothedSpeed + historicalSpeed
    end
    
    return smoothedSpeed / #speedHistory
end

-- Update speedometer display
function Speedometer:UpdateDisplay()
    local playerVehicle = GetVehiclePedIsIn(PlayerPedId(), false)
    
    if playerVehicle ~= 0 then
        targetSpeed = self:CalculateSpeed(playerVehicle)
        
        -- Get additional vehicle data
        local rpm = GetVehicleCurrentRpm(playerVehicle)
        local gear = GetVehicleCurrentGear(playerVehicle)
        local fuel = GetVehicleFuelLevel(playerVehicle)
        local engineHealth = GetVehicleEngineHealth(playerVehicle)
        
        -- Smooth speed transition
        currentSpeed = currentSpeed + (targetSpeed - currentSpeed) * self.config.smoothingFactor
        
        -- Send to UI
        SendNUIMessage({
            type = 'updateSpeed',
            speed = math.floor(currentSpeed),
            rpm = rpm,
            gear = gear,
            fuel = fuel,
            engineHealth = engineHealth,
            maxSpeed = self.config.maxSpeed,
            units = self.config.units
        })
    else
        -- Vehicle exited, hide speedometer
        SendNUIMessage({
            type = 'hideSpeedometer'
        })
    end
end

UI Animation System

// Client-side UI animation and rendering
class SpeedometerUI {
    constructor() {
        this.canvas = document.getElementById('speedometer-canvas');
        this.ctx = this.canvas.getContext('2d');
        this.animationFrame = null;
        this.currentRotation = 0;
        this.targetRotation = 0;
        
        this.setupCanvas();
    }
    
    // Smooth needle animation
    animateNeedle(speed, maxSpeed) {
        const speedPercentage = Math.min(speed / maxSpeed, 1);
        this.targetRotation = (speedPercentage * 270) - 135; // 270° range, start at -135°
        
        // Smooth rotation transition
        const rotationDiff = this.targetRotation - this.currentRotation;
        this.currentRotation += rotationDiff * 0.15;
        
        this.drawSpeedometer();
        
        if (Math.abs(rotationDiff) > 0.5) {
            this.animationFrame = requestAnimationFrame(() => 
                this.animateNeedle(speed, maxSpeed)
            );
        }
    }
    
    // Draw speedometer with modern styling
    drawSpeedometer() {
        const centerX = this.canvas.width / 2;
        const centerY = this.canvas.height / 2;
        const radius = 120;
        
        // Clear canvas
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        
        // Draw outer ring
        this.drawGradientCircle(centerX, centerY, radius + 10, '#6366f1', '#4f46e5');
        
        // Draw speed markings
        this.drawSpeedMarkings(centerX, centerY, radius);
        
        // Draw needle
        this.drawNeedle(centerX, centerY, radius - 20);
        
        // Draw center hub
        this.drawGradientCircle(centerX, centerY, 15, '#1f2937', '#111827');
    }
    
    drawGradientCircle(x, y, radius, color1, color2) {
        const gradient = this.ctx.createRadialGradient(x, y, 0, x, y, radius);
        gradient.addColorStop(0, color1);
        gradient.addColorStop(1, color2);
        
        this.ctx.beginPath();
        this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
        this.ctx.fillStyle = gradient;
        this.ctx.fill();
    }
}

Technical Highlights

  • Smooth Animation: 60fps canvas rendering with interpolated transitions
  • Accurate Calculations: Physics-based speed measurement with smoothing
  • Customizable Themes: Dynamic color schemes and layout options
  • Performance Optimized: Efficient rendering with minimal resource usage

Available Downloads

Get the complete TypeScript-based Speedometer system! Includes full source code and documentation.

Speed-Zones Manager

Intelligent speed zone system with violation tracking, fine calculation, and enforcement integration.

Lua Zone System Admin Tools

Overview

Intelligent speed zone management system with automatic speed limit detection, comprehensive violation tracking, and configurable enforcement mechanisms. Features dynamic zone creation, administrative controls, and integration with law enforcement systems.

Dynamic zone creation
Violation detection
Law enforcement integration
Administrative controls

Key Code Snippets

Zone Management System

-- Speed zone creation and management
local SpeedZones = {}
SpeedZones.zones = {}
SpeedZones.playerZones = {}
SpeedZones.violations = {}

function SpeedZones:CreateZone(zoneId, coords, radius, speedLimit, zoneType)
    local zone = {
        id = zoneId,
        coords = vector3(coords.x, coords.y, coords.z),
        radius = radius,
        speedLimit = speedLimit,
        type = zoneType, -- 'residential', 'highway', 'school', 'construction'
        active = true,
        createdAt = os.time(),
        violations = 0,
        enforcementLevel = 'warning' -- 'warning', 'fine', 'arrest'
    }
    
    self.zones[zoneId] = zone
    
    -- Create client-side zone blip
    TriggerClientEvent('speed-zones:createZone', -1, zone)
    
    print(string.format('[SPEED-ZONES] Created %s zone %s: %d mph limit', 
          zoneType, zoneId, speedLimit))
    
    return zone
end

-- Real-time zone detection and speed monitoring
function SpeedZones:MonitorPlayer(playerId)
    local playerPed = GetPlayerPed(playerId)
    local playerCoords = GetEntityCoords(playerPed)
    local vehicle = GetVehiclePedIsIn(playerPed, false)
    
    if vehicle == 0 then 
        self.playerZones[playerId] = nil
        return 
    end
    
    local speed = GetEntitySpeed(vehicle) * 2.236936 -- Convert to MPH
    local currentZone = nil
    
    -- Check all zones for player position
    for zoneId, zone in pairs(self.zones) do
        if zone.active then
            local distance = #(playerCoords - zone.coords)
            
            if distance <= zone.radius then
                currentZone = zone
                break
            end
        end
    end
    
    -- Handle zone entry/exit
    if currentZone then
        self:HandleZoneEntry(playerId, currentZone, speed)
    else
        self:HandleZoneExit(playerId)
    end
end

-- Zone entry and speed limit enforcement
function SpeedZones:HandleZoneEntry(playerId, zone, currentSpeed)
    local previousZone = self.playerZones[playerId]
    
    -- First entry into this zone
    if not previousZone or previousZone.id ~= zone.id then
        self.playerZones[playerId] = zone
        TriggerClientEvent('speed-zones:enterZone', playerId, zone)
    end
    
    -- Check for speed violations
    if currentSpeed > zone.speedLimit then
        local violation = {
            playerId = playerId,
            zoneId = zone.id,
            speed = currentSpeed,
            speedLimit = zone.speedLimit,
            excessSpeed = currentSpeed - zone.speedLimit,
            timestamp = os.time(),
            coords = GetEntityCoords(GetPlayerPed(playerId))
        }
        
        self:ProcessViolation(violation, zone)
    end
end

Violation Processing System

-- Comprehensive violation handling
function SpeedZones:ProcessViolation(violation, zone)
    local playerId = violation.playerId
    local excessSpeed = violation.excessSpeed
    
    -- Initialize player violation history
    if not self.violations[playerId] then
        self.violations[playerId] = {}
    end
    
    table.insert(self.violations[playerId], violation)
    zone.violations = zone.violations + 1
    
    -- Determine enforcement action based on excess speed and history
    local action = self:DetermineEnforcementAction(playerId, excessSpeed, zone)
    
    -- Execute enforcement action
    if action.type == 'warning' then
        TriggerClientEvent('speed-zones:warning', playerId, {
            message = string.format('Speed limit: %d mph | Your speed: %d mph', 
                     zone.speedLimit, math.floor(violation.speed)),
            excessSpeed = excessSpeed
        })
        
    elseif action.type == 'fine' then
        local fineAmount = self:CalculateFine(excessSpeed, zone.type)
        TriggerClientEvent('speed-zones:fine', playerId, {
            amount = fineAmount,
            reason = 'Speeding violation',
            zone = zone.id
        })
        
        -- Notify law enforcement if enabled
        if zone.enforcementLevel ~= 'warning' then
            TriggerEvent('police:speedingViolation', violation, fineAmount)
        end
        
    elseif action.type == 'serious' then
        -- Serious violation - notify all law enforcement
        TriggerEvent('police:seriousSpeedingViolation', violation)
        TriggerClientEvent('speed-zones:seriousViolation', playerId, violation)
    end
    
    -- Log violation for analytics
    self:LogViolation(violation, action)
end

-- Smart fine calculation based on multiple factors
function SpeedZones:CalculateFine(excessSpeed, zoneType)
    local baseFine = 50
    local speedMultiplier = math.max(1, excessSpeed / 10) -- $5 per mph over
    
    -- Zone type modifiers
    local zoneModifiers = {
        residential = 1.5,
        school = 2.0,
        construction = 1.8,
        highway = 0.8
    }
    
    local modifier = zoneModifiers[zoneType] or 1.0
    local totalFine = baseFine * speedMultiplier * modifier
    
    return math.floor(totalFine)
end

-- Administrative zone management
function SpeedZones:AdminUpdateZone(adminId, zoneId, updates)
    local zone = self.zones[zoneId]
    if not zone then return false end
    
    -- Validate admin permissions
    if not self:HasAdminPermission(adminId, 'zone_management') then
        TriggerClientEvent('speed-zones:notify', adminId, 'Insufficient permissions', 'error')
        return false
    end
    
    -- Apply updates
    for key, value in pairs(updates) do
        if key ~= 'id' and key ~= 'createdAt' then
            zone[key] = value
        end
    end
    
    -- Broadcast updates to all clients
    TriggerClientEvent('speed-zones:zoneUpdated', -1, zone)
    
    print(string.format('[SPEED-ZONES] Admin %s updated zone %s', adminId, zoneId))
    return true
end

Technical Highlights

  • Intelligent Detection: Efficient spatial algorithms for zone boundaries
  • Graduated Enforcement: Smart violation escalation based on severity
  • Administrative Tools: Real-time zone modification and management
  • Integration Ready: Seamless connection with law enforcement systems

Interaction Core System

Extensible FiveM interaction framework — 2,500+ downloads across 200+ active servers.

Lua Framework API Design

Overview

Advanced interaction framework for FiveM servers providing a flexible, extensible system for creating interactive elements. Features multiple interaction types, conditional logic, performance optimization, and a comprehensive API with extensive documentation for developers.

Development Status: This project is in active development. New features, improvements, and bug fixes are released regularly. Check back often for the latest version, as updates are deployed at random intervals based on development progress.
Multiple interaction types
Conditional logic system
Performance optimized
Comprehensive API

Key Code Snippets

Core Interaction Framework

-- Advanced interaction creation system
function InteractionCore:CreateInteraction(data)
    local interactionId = data.id or self:GenerateId()
    
    local interaction = {
        id = interactionId,
        coords = data.coords or vector3(0, 0, 0),
        distance = data.distance or self.Config.maxInteractionDistance,
        type = data.type or self.Types.SIMPLE,
        helpText = data.helpText or 'Press ~INPUT_CONTEXT~ to interact',
        callback = data.callback,
        conditions = data.conditions or {},
        cooldown = data.cooldown or self.Config.cooldownTime,
        
        -- Advanced features
        animation = data.animation,
        progressBar = data.progressBar,
        menu = data.menu,
        
        -- Conditional requirements
        job = data.job,
        gang = data.gang,
        item = data.item,
        
        -- Visual elements
        blip = data.blip,
        marker = data.marker,
        
        active = true,
        lastUsed = 0
    }
    
    self.interactions[interactionId] = interaction
    
    -- Create visual elements
    if interaction.blip then
        self:CreateInteractionBlip(interaction)
    end
    
    if interaction.marker then
        self:CreateInteractionMarker(interaction)
    end
    
    return interactionId
end

-- Intelligent interaction processing
function InteractionCore:ProcessInteraction()
    local playerPed = PlayerPedId()
    local closestInteraction = self:GetClosestActiveInteraction()
    
    if not closestInteraction then return end
    
    -- Cooldown check
    if GetGameTimer() - closestInteraction.lastUsed < closestInteraction.cooldown then
        return
    end
    
    -- Advanced condition validation
    if not self:ValidateConditions(closestInteraction, playerPed) then
        return
    end
    
    closestInteraction.lastUsed = GetGameTimer()
    self:HandleInteractionType(closestInteraction, playerPed)
end

Multiple Interaction Types Handler

-- Flexible interaction type system
function InteractionCore:HandleInteractionType(interaction, playerPed)
    local interactionType = interaction.type
    
    if interactionType == self.Types.SIMPLE then
        -- Immediate callback execution
        self:HandleSimpleInteraction(interaction)
        
    elseif interactionType == self.Types.ANIMATED then
        -- Animation-based interaction
        if interaction.animation then
            local animDict = interaction.animation.dict
            local animName = interaction.animation.name
            local duration = interaction.animation.duration or 2000
            
            RequestAnimDict(animDict)
            while not HasAnimDictLoaded(animDict) do Wait(100) end
            
            TaskPlayAnim(playerPed, animDict, animName, 8.0, 8.0, duration, 0, 0, false, false, false)
            Wait(duration)
            ClearPedTasks(playerPed)
            RemoveAnimDict(animDict)
        end
        
        if interaction.callback then
            interaction.callback(interaction.data)
        end
        
    elseif interactionType == self.Types.PROGRESSIVE then
        -- Progress bar interaction
        if interaction.progressBar then
            local progressData = {
                duration = interaction.progressBar.duration or 5000,
                label = interaction.progressBar.label or 'Processing...',
                canCancel = interaction.progressBar.canCancel or true,
                disableMovement = interaction.progressBar.disableMovement or true
            }
            
            self:ShowProgressBar(progressData, function(success)
                if success and interaction.callback then
                    interaction.callback(interaction.data)
                end
            end)
        end
        
    elseif interactionType == self.Types.CONDITIONAL then
        -- Advanced conditional logic
        self:HandleConditionalInteraction(interaction)
        
    elseif interactionType == self.Types.TIMED then
        -- Time-based interaction requiring sustained presence
        local timerDuration = interaction.timer or 10000
        local startTime = GetGameTimer()
        
        Citizen.CreateThread(function()
            while GetGameTimer() - startTime < timerDuration do
                local currentCoords = GetEntityCoords(playerPed)
                if #(currentCoords - interaction.coords) > interaction.distance then
                    return -- Player moved away, cancel
                end
                Wait(100)
            end
            
            if interaction.callback then
                interaction.callback(interaction.data)
            end
        end)
    end
end

Advanced Condition Validation System

-- Comprehensive condition validation
function InteractionCore:ValidateConditions(interaction, playerPed)
    -- Job requirement validation
    if interaction.job then
        local PlayerData = QBCore.Functions.GetPlayerData()
        if PlayerData.job.name ~= interaction.job then
            return false
        end
    end
    
    -- Gang requirement validation
    if interaction.gang then
        local PlayerData = QBCore.Functions.GetPlayerData()
        if PlayerData.gang.name ~= interaction.gang then
            return false
        end
    end
    
    -- Item requirement validation
    if interaction.item then
        if not self:PlayerHasItem(interaction.item) then
            return false
        end
    end
    
    -- Custom conditions validation
    if interaction.conditions and type(interaction.conditions) == 'table' then
        for _, condition in pairs(interaction.conditions) do
            if type(condition) == 'function' and not condition() then
                return false
            end
        end
    end
    
    return true
end

-- Performance-optimized distance checking
function InteractionCore:StartInteractionThread()
    Citizen.CreateThread(function()
        while true do
            local sleep = 500
            local playerPed = PlayerPedId()
            local playerCoords = GetEntityCoords(playerPed)
            
            self.activeInteractions = {}
            
            -- Efficient spatial checking
            for id, interaction in pairs(self.interactions) do
                if self:IsInteractionValid(interaction, playerPed, playerCoords) then
                    local distance = #(playerCoords - interaction.coords)
                    
                    if distance <= interaction.distance then
                        self.activeInteractions[id] = interaction
                        sleep = 0 -- Active interaction found, reduce sleep
                        
                        if self.Config.showHelpText and interaction.helpText then
                            self:ShowHelpText(interaction.helpText)
                        end
                    end
                end
            end
            
            Wait(sleep)
        end
    end)
end

Technical Highlights

  • Modular Architecture: Extensible design supporting custom interaction types
  • Performance Optimization: Dynamic sleep values and spatial optimizations
  • Advanced Conditions: Job, gang, item, and custom function-based validation
  • Developer Experience: Clean API with comprehensive documentation and examples
  • Visual Integration: Support for blips, markers, and help text systems
  • Framework Agnostic: Easy integration with any FiveM framework

Zendo-Lockpick System FREE DOWNLOAD

Lockpicking job system with skill progression, MySQL persistence, and anti-exploit protection.

Lua MySQL Job System Free

Overview

Zendo-Lockpick: Complete lockpicking job system for FiveM servers featuring skill progression, dynamic rewards, database integration, and comprehensive administrative controls. Includes anti-exploit protection and extensive customization options. Available as a free download with full source code!

Development Status: This project is in active development. New features, improvements, and bug fixes are released regularly. Check back often for the latest version, as updates are deployed at random intervals based on development progress.
Skill progression system
MySQL integration
Anti-exploit protection
Admin controls

Key Code Snippets

Job Management and Assignment

-- Dynamic job creation and player assignment
function StartLockpickJob()
    local randomLocation = Config.Locations[math.random(1, #Config.Locations)]
    
    currentJobData = {
        location = randomLocation,
        startTime = GetGameTimer(),
        completed = false
    }
    
    isDoingLockpickJob = true
    CreateJobBlip(randomLocation.coords)
    
    QBCore.Functions.Notify('New lockpick job available! Check your GPS.', 'success')
    TriggerServerEvent('lockpick-job:server:jobStarted', currentJobData)
end

-- Advanced lockpicking minigame with skill-based success rates
function StartLockpickingMinigame(difficulty)
    local success = false
    local attempts = 3
    
    while attempts > 0 and not success do
        QBCore.Functions.Notify(string.format('Lockpicking... Attempt %d/3', 4 - attempts), 'primary')
        
        -- Skill-based success calculation
        local skillChance = math.min((lockpickSkill / Config.MaxSkillLevel) * 100, 85)
        local difficultyModifier = (1 - (difficulty * 0.15))
        local finalChance = skillChance * difficultyModifier
        
        Wait(3000) -- Minigame simulation
        
        local randomRoll = math.random(1, 100)
        
        if randomRoll <= finalChance then
            success = true
            QBCore.Functions.Notify('Lock picked successfully!', 'success')
        else
            attempts = attempts - 1
            if attempts > 0 then
                QBCore.Functions.Notify('Failed! Try again.', 'error')
            end
        end
    end
    
    return success
end

Skill Progression and Reward System

-- Intelligent skill progression and reward calculation
function CompleteLockpickJob(success)
    if not isDoingLockpickJob then return end
    
    local reward = 0
    local skillGain = 0
    
    if success then
        local difficulty = currentJobData.location.difficulty
        -- Dynamic reward calculation based on skill and difficulty
        reward = Config.BaseReward * difficulty * (1 + (lockpickSkill / Config.MaxSkillLevel))
        skillGain = Config.SkillIncrement * difficulty
        
        -- Progressive skill system with diminishing returns
        lockpickSkill = math.min(lockpickSkill + skillGain, Config.MaxSkillLevel)
        
        QBCore.Functions.Notify(string.format('Job completed! Earned $%d and %d skill XP', 
                               math.floor(reward), skillGain), 'success')
    end
    
    -- Clean up job state
    if currentJobData.blip then
        RemoveBlip(currentJobData.blip)
    end
    
    isDoingLockpickJob = false
    currentJobData = {}
    
    -- Server synchronization
    TriggerServerEvent('lockpick-job:server:jobCompleted', {
        success = success,
        reward = reward,
        skillGain = skillGain,
        newSkillLevel = lockpickSkill
    })
end

-- Server-side reward processing and validation
RegisterNetEvent('lockpick-job:server:jobCompleted', function(completionData)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    
    if completionData.success then
        -- Update player skill and statistics
        playerSkillData[Player.PlayerData.citizenid].skillLevel = completionData.newSkillLevel
        playerSkillData[Player.PlayerData.citizenid].jobsCompleted = 
            playerSkillData[Player.PlayerData.citizenid].jobsCompleted + 1
        
        -- Award money with validation
        Player.Functions.AddMoney('cash', completionData.reward, 'lockpick-job-reward')
        
        -- Persistent storage
        SavePlayerSkillData(Player.PlayerData.citizenid)
        
        -- Update client
        TriggerClientEvent('lockpick-job:client:updateSkill', src, completionData.newSkillLevel)
    end
end)

Database Integration and Admin Tools

-- Persistent player skill tracking with MySQL
local function LoadPlayerSkillData(citizenid)
    MySQL.Async.fetchAll('SELECT * FROM player_lockpick_skills WHERE citizenid = ?', {citizenid}, 
    function(result)
        if result[1] then
            playerSkillData[citizenid] = {
                skillLevel = result[1].skill_level or 0,
                jobsCompleted = result[1].jobs_completed or 0,
                lastJobTime = result[1].last_job_time
            }
        else
            -- Create new player record
            MySQL.Async.execute('INSERT INTO player_lockpick_skills (citizenid) VALUES (?)', {citizenid})
            playerSkillData[citizenid] = {skillLevel = 0, jobsCompleted = 0, lastJobTime = nil}
        end
        
        -- Sync with client
        local Player = QBCore.Functions.GetPlayerByCitizenId(citizenid)
        if Player then
            TriggerClientEvent('lockpick-job:client:updateSkill', Player.PlayerData.source, 
                             playerSkillData[citizenid].skillLevel)
        end
    end)
end

-- Administrative commands for server management
QBCore.Commands.Add('setlockpickskill', 'Set a player\'s lockpick skill level (Admin Only)', {
    {name = 'id', help = 'Player ID'},
    {name = 'skill', help = 'Skill Level (0-100)'}
}, true, function(source, args)
    local targetId = tonumber(args[1])
    local skillLevel = tonumber(args[2])
    
    if skillLevel < 0 or skillLevel > Config.MaxSkillLevel then
        TriggerClientEvent('QBCore:Notify', source, 
                          'Skill level must be between 0 and ' .. Config.MaxSkillLevel, 'error')
        return
    end
    
    local TargetPlayer = QBCore.Functions.GetPlayer(targetId)
    if TargetPlayer then
        local citizenid = TargetPlayer.PlayerData.citizenid
        
        if not playerSkillData[citizenid] then
            playerSkillData[citizenid] = {skillLevel = 0, jobsCompleted = 0}
        end
        
        playerSkillData[citizenid].skillLevel = skillLevel
        SavePlayerSkillData(citizenid)
        
        TriggerClientEvent('lockpick-job:client:updateSkill', targetId, skillLevel)
        TriggerClientEvent('QBCore:Notify', source, 
                          string.format('Set %s\'s lockpick skill to %d', 
                                       TargetPlayer.PlayerData.name, skillLevel), 'success')
    end
end, 'admin')

Technical Highlights

  • Skill Progression: Dynamic skill system with configurable progression rates
  • Database Integration: MySQL storage for persistent player data
  • Anti-Exploit: Server-side validation and cooldown systems
  • Administrative Tools: Complete admin commands for player management
  • Framework Integration: Native QBCore integration with easy adaptation
  • Customizable Locations: Easy configuration of job locations and difficulty

Free Download Package

Get the complete Zendo-Lockpick system absolutely free! Includes full source code, documentation, and installation guide.

What's Included:

  • ✅ Complete source code for both client and server
  • ✅ MySQL database schema and setup
  • ✅ Comprehensive installation documentation
  • ✅ Configuration examples and customization guide
  • ✅ Admin commands and management tools
  • ✅ Framework integration instructions

Zendo-Transmission System COMING SOON

Realistic transmission simulation — manual/automatic modes and clutch mechanics. Coming soon.

Lua Vehicle System Physics Work in Progress

Overview

Advanced vehicle transmission system for FiveM servers featuring realistic gear shifting mechanics, manual and automatic transmission modes, clutch system, and performance tuning capabilities. Provides immersive driving experience with customizable shift patterns, engine sounds, and visual indicators. Designed for realistic roleplay servers seeking authentic vehicle behavior.

Work in Progress: This project is currently under active development. The system is being built with attention to realism and performance optimization. It will be available for download once core features are complete and thoroughly tested. Check back soon for release updates!
Manual & Automatic modes
Realistic RPM simulation
Clutch mechanics
Performance tuning

Preview: Key Code Concepts

Note: These are conceptual snippets showing the planned architecture. Final implementation may vary.

Transmission Core System

-- Advanced transmission management system
local Transmission = {}
Transmission.vehicles = {}
Transmission.config = {
    manualMode = false,
    clutchEnabled = true,
    shiftTime = 200, -- ms
    realisticStalling = true
}

-- Initialize vehicle transmission
function Transmission:InitVehicle(vehicle)
    local vehicleData = {
        vehicle = vehicle,
        currentGear = 1,
        rpm = 0,
        maxRPM = 8000,
        mode = 'automatic', -- 'automatic' or 'manual'
        clutchEngaged = true,
        engineStalled = false,
        gearRatios = self:GetGearRatios(vehicle),
        shiftPoints = self:CalculateShiftPoints(vehicle)
    }
    
    self.vehicles[vehicle] = vehicleData
    return vehicleData
end

-- Realistic gear shifting with RPM management
function Transmission:ShiftGear(vehicle, direction)
    local vehData = self.vehicles[vehicle]
    if not vehData then return false end
    
    -- Check if shifting is allowed
    if not vehData.clutchEngaged and self.config.clutchEnabled then
        TriggerEvent('transmission:notify', 'Engage clutch to shift!', 'error')
        return false
    end
    
    local newGear = vehData.currentGear + direction
    local maxGear = #vehData.gearRatios
    
    -- Validate gear range
    if newGear < 1 or newGear > maxGear then
        return false
    end
    
    -- Perform shift
    vehData.currentGear = newGear
    
    -- Calculate RPM change based on gear ratio
    local oldRatio = vehData.gearRatios[vehData.currentGear - direction]
    local newRatio = vehData.gearRatios[newGear]
    vehData.rpm = vehData.rpm * (oldRatio / newRatio)
    
    -- Visual and audio feedback
    self:PlayShiftAnimation(vehicle)
    self:PlayShiftSound(vehicle, direction)
    
    return true
end

-- Calculate optimal shift points based on vehicle stats
function Transmission:CalculateShiftPoints(vehicle)
    local maxSpeed = GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveMaxFlatVel')
    local acceleration = GetVehicleHandlingFloat(vehicle, 'CHandlingData', 'fInitialDriveForce')
    
    local shiftPoints = {}
    local baseShiftRPM = 6500
    
    -- Adjust for vehicle performance
    local performanceFactor = (acceleration / 1.0) * (maxSpeed / 150.0)
    
    for gear = 1, 6 do
        shiftPoints[gear] = {
            upshift = baseShiftRPM * (1 - (gear * 0.05)),
            downshift = baseShiftRPM * 0.4
        }
    end
    
    return shiftPoints
end

Clutch and Engine Stall System

-- Realistic clutch mechanics with stalling
function Transmission:UpdateClutch(vehicle, clutchInput)
    local vehData = self.vehicles[vehicle]
    if not vehData or not self.config.clutchEnabled then return end
    
    -- Clutch is analog (0.0 to 1.0)
    local previousState = vehData.clutchEngaged
    vehData.clutchEngaged = clutchInput < 0.5
    
    -- Check for stall conditions
    if self.config.realisticStalling then
        local speed = GetEntitySpeed(vehicle) * 3.6 -- Convert to km/h
        
        -- Stall if releasing clutch too fast in low gear at low speed
        if not previousState and vehData.clutchEngaged then
            if vehData.currentGear <= 2 and speed < 5 and vehData.rpm < 1500 then
                self:StallEngine(vehicle)
                return
            end
        end
    end
    
    -- Update power delivery based on clutch engagement
    local powerMultiplier = vehData.clutchEngaged and 1.0 or clutchInput
    SetVehicleEnginePowerMultiplier(vehicle, powerMultiplier)
end

-- Engine stall handling
function Transmission:StallEngine(vehicle)
    local vehData = self.vehicles[vehicle]
    if not vehData then return end
    
    vehData.engineStalled = true
    vehData.rpm = 0
    
    SetVehicleEngineOn(vehicle, false, true, false)
    
    -- Visual feedback
    TriggerEvent('transmission:notify', 'Engine Stalled! Press [IGNITION] to restart', 'warning')
    
    -- Play stall sound
    PlaySoundFromEntity(-1, 'Engine_fail', vehicle, 'DLC_PILOT_ENGINE_FAILURE_SOUNDS', true, 0)
end

-- Restart stalled engine
function Transmission:RestartEngine(vehicle)
    local vehData = self.vehicles[vehicle]
    if not vehData or not vehData.engineStalled then return end
    
    -- Check if conditions are right for restart
    if vehData.clutchEngaged or vehData.currentGear == 0 then
        SetVehicleEngineOn(vehicle, true, false, true)
        vehData.engineStalled = false
        vehData.rpm = 1000 -- Idle RPM
        
        TriggerEvent('transmission:notify', 'Engine started', 'success')
    else
        TriggerEvent('transmission:notify', 'Engage clutch or put in neutral first', 'error')
    end
end

Automatic vs Manual Mode

-- Intelligent automatic transmission logic
function Transmission:UpdateAutomatic(vehicle, deltaTime)
    local vehData = self.vehicles[vehicle]
    if not vehData or vehData.mode ~= 'automatic' then return end
    
    local throttle = GetVehicleThrottleOffset(vehicle)
    local brake = GetVehicleHandbrake(vehicle)
    local currentGear = vehData.currentGear
    local shiftPoint = vehData.shiftPoints[currentGear]
    
    -- Upshift logic
    if vehData.rpm > shiftPoint.upshift and throttle > 0.3 then
        if currentGear < #vehData.gearRatios then
            -- Smooth automatic shift
            self:AutoShift(vehicle, 1)
        end
    end
    
    -- Downshift logic
    if vehData.rpm < shiftPoint.downshift and currentGear > 1 then
        -- Only downshift if throttle is applied or braking
        if throttle > 0.1 or brake then
            self:AutoShift(vehicle, -1)
        end
    end
    
    -- Kickdown detection (for quick acceleration)
    if throttle > 0.9 and vehData.rpm < shiftPoint.upshift * 0.7 then
        if currentGear > 2 then
            self:AutoShift(vehicle, -1) -- Downshift for more power
            TriggerEvent('transmission:notify', 'Kickdown activated', 'info')
        end
    end
end

-- Smooth automatic shifting with delay
function Transmission:AutoShift(vehicle, direction)
    local vehData = self.vehicles[vehicle]
    
    -- Reduce power during shift
    SetVehicleEnginePowerMultiplier(vehicle, 0.3)
    
    Citizen.SetTimeout(self.config.shiftTime, function()
        self:ShiftGear(vehicle, direction)
        
        -- Restore power after shift
        Citizen.SetTimeout(100, function()
            SetVehicleEnginePowerMultiplier(vehicle, 1.0)
        end)
    end)
end

-- Toggle between automatic and manual
function Transmission:ToggleMode(vehicle)
    local vehData = self.vehicles[vehicle]
    if not vehData then return end
    
    if vehData.mode == 'automatic' then
        vehData.mode = 'manual'
        TriggerEvent('transmission:notify', 'Manual mode activated', 'success')
    else
        vehData.mode = 'automatic'
        TriggerEvent('transmission:notify', 'Automatic mode activated', 'success')
    end
    
    -- Update UI
    SendNUIMessage({
        type = 'updateMode',
        mode = vehData.mode
    })
end

Planned Features

  • Dual Transmission Modes: Seamless switching between automatic and manual
  • Realistic Physics: Accurate gear ratios and RPM calculations
  • Clutch System: Analog clutch control with stalling mechanics
  • Performance Tuning: Customizable shift points and gear ratios
  • Visual Indicators: Modern UI showing gear, RPM, and mode
  • Engine Sounds: Dynamic audio feedback for shifts and stalls
  • Anti-Stall Assist: Optional helper for beginners
  • Sequential Shifting: Support for paddle shifters and sequential gearboxes

Coming Soon

This project is currently in active development. We're working hard to deliver a realistic and immersive transmission system that will enhance your driving experience. The system will be released once it meets our quality standards and includes comprehensive documentation.

Current Development Status:

  • ✅ Core transmission logic architecture designed
  • 🔄 Gear shifting mechanics in development
  • 🔄 Clutch system implementation in progress
  • ⏳ UI/HUD system planned
  • ⏳ Sound integration pending
  • ⏳ Performance optimization phase upcoming
  • ⏳ Documentation and examples to be written

Stay tuned! Follow this portfolio for updates on the release. Once available, full source code and installation instructions will be provided for free download.

AI Clip Generator

Automated vertical video editing — 10x faster than manual. TikTok, Shorts, and Reels optimized.

AI/ML Video Processing Automation Content Creation

Transform Your Content Creation Workflow

The AI Clip Generator is a powerful automated video editing service designed specifically for content creators who want to maximize their reach on TikTok, YouTube Shorts, Instagram Reels, and other vertical video platforms. Upload your long-form content and let AI handle the heavy lifting—from identifying viral-worthy moments to generating captions and reformatting for mobile viewers.

AI-powered clip selection
Auto-generated captions
Automatic vertical conversion
10x faster than manual editing
Customizable output settings
High-quality exports

⚡ Key Features That Save You Hours

  • Smart Content Detection: AI analyzes your video to identify the most engaging moments automatically
  • Professional Captions: Auto-generated, perfectly timed subtitles that boost engagement and accessibility
  • Vertical Format Optimization: Seamlessly converts horizontal videos to 9:16 format for TikTok, Shorts, and Reels
  • Batch Processing: Upload multiple videos and process them all at once—wake up to ready-to-post content
  • Customizable Styling: Choose caption styles, fonts, colors, and animations that match your brand
  • Multiple Clip Variations: Get several versions of each clip with different timings and focus points
  • High-Quality Output: Export in multiple resolutions up to 4K for crystal-clear quality
  • Time Stamps & Highlights: Automatically detects funny moments, key quotes, and viral-worthy segments

🎯 Perfect For

  • Podcasters: Turn full episodes into shareable highlight clips
  • YouTubers: Repurpose long-form content for Shorts and maximize reach
  • Streamers: Convert Twitch streams into viral TikTok moments
  • Educators: Break down lectures into bite-sized learning clips
  • Business Coaches: Transform webinars into promotional content
  • Content Agencies: Scale your production without hiring more editors

💪 Why Content Creators Love It

  • Massive Time Savings: What takes 5 hours manually takes 15 minutes with AI
  • Consistent Quality: Every clip looks professional with perfect captions and formatting
  • Higher Engagement: Auto-captions increase view time by up to 80%
  • More Content, Less Work: Turn one video into 10+ clips for your content calendar
  • Stay Competitive: Post more frequently and dominate the algorithm
  • Focus on Creating: Spend time making great content, not editing it

Let's Work Together

Ready to transform your content workflow? I offer flexible pricing packages tailored to your needs—whether you're a solo creator or running a content agency.

📦 Pricing Packages

Starter Package

$75

per video

  • ✓ Up to 10 clips per video
  • ✓ Auto-generated captions
  • ✓ Vertical format conversion
  • ✓ 1080p HD export
  • ✓ 48-hour turnaround
Pro Package ⭐

$250

per month (4 videos)

  • ✓ Up to 15 clips per video
  • ✓ Custom caption styling
  • ✓ Priority processing
  • ✓ 4K export option
  • ✓ 24-hour turnaround
  • ✓ Multiple revisions
Enterprise

Custom

Let's talk

  • ✓ Unlimited videos
  • ✓ White-label options
  • ✓ API access available
  • ✓ Dedicated support
  • ✓ Custom integrations
  • ✓ Volume discounts

All prices are negotiable! I'm happy to create a custom package that fits your budget and needs.

Get a Custom Quote

Every content creator has unique needs. Let's chat about your project and find a pricing solution that works for both of us. I'm flexible and open to negotiation!

Email Me for Pricing Contact Form
📞 Quick Response Guaranteed

I respond to all inquiries within 24 hours, usually much faster! Send me an email with your content type, monthly volume, and budget—I'll send you a personalized quote with flexible payment options.

Back to Portfolio