Gridbase
Paid releasesDime SkillsEvents

Server Events

Server-side events for Dime Skills

Server Events

All server-side events that can be triggered or listened to in Dime Skills.

dime_skills:addXP

Adds XP to a player's skill (client → server).

TriggerServerEvent('dime_skills:addXP', skill, amount)

Parameters

  • skill (string): Skill name/identifier
  • amount (number): XP amount to add

Example

-- Client-side trigger
TriggerServerEvent('dime_skills:addXP', 'mining', 15)

-- After completing action
RegisterNetEvent('mining:oreCollected', function(oreType)
    local xpAmounts = {
        copper = 5,
        iron = 10,
        gold = 20
    }
    
    local xp = xpAmounts[oreType] or 5
    TriggerServerEvent('dime_skills:addXP', 'mining', xp)
end)

Server-side Handling

-- The event is handled internally
-- But you can listen to it for logging/analytics
RegisterNetEvent('dime_skills:addXP', function(skill, amount)
    local _source = source
    print(('Player %d gained %d XP in %s'):format(_source, amount, skill))
end)

Security

This event is protected by safety checks (rewardMax). Don't disable safety checks in production.

  • Server validates the XP amount
  • Checks against rewardMax in config
  • Logs suspicious activity if Debug enabled
  • May block excessive XP grants

Usage

Use this event when:

  • Player completes an action
  • Rewarding from client-side systems
  • Integrating with minigames
  • Activity-based progression

For server-side XP grants, use the export exports.dime_skills:addEXP() instead for better control.


dime_skills:removeXP

Removes XP from a player's skill (client → server).

TriggerServerEvent('dime_skills:removeXP', skill, amount)

Parameters

  • skill (string): Skill name/identifier
  • amount (number): XP amount to remove

Example

-- Client-side trigger
TriggerServerEvent('dime_skills:removeXP', 'driving', 25)

-- After failed action
RegisterNetEvent('crafting:craftFailed', function(itemName)
    -- Small penalty for failure
    TriggerServerEvent('dime_skills:removeXP', 'crafting', 10)
end)

-- Death penalty
AddEventHandler('gameEventTriggered', function(name, args)
    if name == 'CEventNetworkEntityDamage' then
        local victim = args[1]
        if victim == PlayerPedId() and IsEntityDead(victim) then
            -- Lose XP on death
            TriggerServerEvent('dime_skills:removeXP', 'strength', 30)
        end
    end
end)

Server-side Handling

-- Listen for XP removal (for logging)
RegisterNetEvent('dime_skills:removeXP', function(skill, amount)
    local _source = source
    print(('Player %d lost %d XP in %s'):format(_source, amount, skill))
end)

Security

XP removal is capped at reduceMax from skill config.

  • Server validates the amount
  • Checks against reduceMax
  • Prevents excessive XP loss
  • Can cause level downs

Usage

Use this event for:

  • Failure penalties
  • Death penalties
  • Punishment systems
  • Balancing mechanics

For server-side XP removal, use exports.dime_skills:remoEXP() for direct control.


dime_skills:saveSkills

Forces a save of all player skills (server-only).

TriggerEvent('dime_skills:saveSkills')

This is a server-only event. Calling from client will result in player kick.

Parameters

None

Example

-- Force save all skills
TriggerEvent('dime_skills:saveSkills')

-- Before server shutdown
AddEventHandler('txAdmin:events:serverShuttingDown', function()
    print('Saving all skills before shutdown...')
    TriggerEvent('dime_skills:saveSkills')
    Wait(5000) -- Give time to save
end)

-- Periodic backup
CreateThread(function()
    while true do
        Wait(1800000) -- 30 minutes
        print('Performing periodic skill save...')
        TriggerEvent('dime_skills:saveSkills')
    end
end)

-- Admin command
RegisterCommand('saveskills', function(source)
    if source == 0 then -- Console only
        TriggerEvent('dime_skills:saveSkills')
        print('Skills saved successfully')
    end
end, true)

Behavior

When triggered:

  1. Iterates through all loaded players
  2. Saves each player's skills to database
  3. Logs operation time (if Debug enabled)
  4. Ensures data persistence

Security

  • Server-only: Cannot be called from client
  • Source Check: Validates source == 0 or nil
  • Kick Protection: Drops players who try to trigger it

Usage

Use this event for:

  • Manual backups
  • Before server restart
  • Scheduled saves
  • Admin tools
  • Testing

Skills are automatically saved on player disconnect and resource stop. Manual saves are usually not needed.


dime_skills:craftItemSuccess

Triggered after successful item crafting in ox_inventory.

TriggerEvent('dime_skills:craftItemSuccess', source, itemData)

Parameters

  • source (number): Player's server ID
  • itemData (table): Craft recipe data

itemData Structure:

{
    name = 'item_name',
    label = 'Item Label',
    skills = {
        required = {
            crafting = 5,
            chemistry = 3
        },
        reward = {
            crafting = 10,
            chemistry = 5
        }
    },
    -- ... other recipe data
}

Example

-- Hook into crafting system
RegisterNetEvent('ox_inventory:craftComplete', function(itemName, recipe)
    -- Trigger skill rewards
    TriggerEvent('dime_skills:craftItemSuccess', source, recipe)
    
    -- Additional logging
    print(('Player %d crafted %s'):format(source, itemName))
end)

-- Custom crafting integration
RegisterNetEvent('mycrafting:success', function(recipeData)
    local itemData = {
        name = recipeData.item,
        skills = {
            reward = {
                crafting = recipeData.xpReward or 10
            }
        }
    }
    
    TriggerEvent('dime_skills:craftItemSuccess', source, itemData)
end)

Behavior

When triggered:

  1. Checks if craftingSkills is enabled in config
  2. Validates itemData.skills.reward exists
  3. Awards XP for each skill in rewards
  4. Triggers skill notifications

Integration

This event works with the ox_inventory hook:

-- Automatic integration (built-in)
exports.ox_inventory:registerHook('craftItem', function(payload)
    local itemData = payload.recipe
    local source = payload.source
    
    -- Check requirements (handled automatically)
    -- On success, trigger reward event
    
    return true
end, {print = false})

Usage

Use this event for:

  • ox_inventory integration
  • Custom crafting systems
  • Skill rewards after crafting
  • Custom XP calculations

If craftingSkills = true in config, this is automatically handled. Manual triggering is for custom systems.


Usage Examples

Custom Skill Progression System

-- Progressive difficulty with skill checks
RegisterNetEvent('mining:attemptMine', function(nodeId, difficulty)
    local skill = exports.dime_skills:grabSkill(source, 'mining')
    
    if not skill or skill.level < difficulty then
        TriggerClientEvent('ox_lib:notify', source, {
            type = 'error',
            description = ('Mining level %d required'):format(difficulty)
        })
        return
    end
    
    -- Success - grant XP based on difficulty
    local xpReward = difficulty * 5
    exports.dime_skills:addEXP(source, 'mining', xpReward)
    
    -- Grant resources
    TriggerClientEvent('mining:grantReward', source, nodeId)
end)

Death Penalty System

-- Configurable death penalties
local deathPenalties = {
    strength = 20,
    stamina = 15,
    shooting = 10
}

AddEventHandler('playerDied', function(playerId, killer, deathReason)
    for skill, xpLoss in pairs(deathPenalties) do
        exports.dime_skills:remoEXP(playerId, skill, xpLoss)
    end
    
    TriggerClientEvent('ox_lib:notify', playerId, {
        type = 'error',
        title = 'Death Penalty',
        description = 'You lost skill XP from dying'
    })
end)

Crafting Integration Example

-- Custom crafting system with skill rewards
RegisterNetEvent('crafting:craftItem', function(itemName)
    local recipes = {
        weapon_pistol = {
            required = { weaponary = 10 },
            reward = { weaponary = 15 }
        },
        lockpick = {
            required = { crafting = 5 },
            reward = { crafting = 10 }
        }
    }
    
    local recipe = recipes[itemName]
    if not recipe then return end
    
    -- Check requirements
    for skill, level in pairs(recipe.required) do
        local playerSkill = exports.dime_skills:grabSkill(source, skill)
        if not playerSkill or playerSkill.level < level then
            TriggerClientEvent('ox_lib:notify', source, {
                type = 'error',
                description = 'Insufficient skill level'
            })
            return
        end
    end
    
    -- Grant item (your inventory system)
    -- ...
    
    -- Award skill XP
    for skill, xp in pairs(recipe.reward) do
        exports.dime_skills:addEXP(source, skill, xp)
    end
end)

Admin Tools

-- Admin commands for skill management
RegisterCommand('giveskillxp', function(source, args)
    -- giveskillxp <player_id> <skill> <amount>
    if source ~= 0 and not IsPlayerAceAllowed(source, 'command.admin') then
        return
    end
    
    local targetId = tonumber(args[1])
    local skill = args[2]
    local amount = tonumber(args[3])
    
    if targetId and skill and amount then
        local success = exports.dime_skills:addEXP(targetId, skill, amount)
        
        if success then
            print(('Granted %d XP in %s to player %d'):format(amount, skill, targetId))
        else
            print('Failed to grant XP')
        end
    end
end, true)

RegisterCommand('setskill level', function(source, args)
    -- setskilllevel <player_id> <skill> <level>
    if source ~= 0 and not IsPlayerAceAllowed(source, 'command.admin') then
        return
    end
    
    local targetId = tonumber(args[1])
    local skill = args[2]
    local level = tonumber(args[3])
    
    if targetId and skill and level then
        exports.dime_skills:setLevel(targetId, skill, level)
        print(('Set %s to level %d for player %d'):format(skill, level, targetId))
    end
end, true)

Event Logging System

-- Log all skill changes
local skillLogs = {}

RegisterNetEvent('dime_skills:addXP', function(skill, amount)
    local playerId = source
    local citizenId = getPlayerIdentifier(playerId)
    
    table.insert(skillLogs, {
        timestamp = os.time(),
        player = citizenId,
        skill = skill,
        amount = amount,
        type = 'gain'
    })
end)

RegisterNetEvent('dime_skills:removeXP', function(skill, amount)
    local playerId = source
    local citizenId = getPlayerIdentifier(playerId)
    
    table.insert(skillLogs, {
        timestamp = os.time(),
        player = citizenId,
        skill = skill,
        amount = amount,
        type = 'loss'
    })
end)

-- Save logs periodically
CreateThread(function()
    while true do
        Wait(600000) -- 10 minutes
        
        if #skillLogs > 0 then
            -- Save to database or file
            print(('Logged %d skill changes'):format(#skillLogs))
            skillLogs = {}
        end
    end
end)

Best Practices

Security

  1. Validate Source: Always validate the event source
  2. Check Permissions: Use ACE permissions for admin events
  3. Rate Limiting: Implement cooldowns to prevent spam
  4. Sanitize Input: Validate all parameters

Performance

  1. Batch Operations: Group multiple XP grants when possible
  2. Async Operations: Use callbacks for database queries
  3. Cache Data: Don't query skills repeatedly
  4. Debounce Saves: Don't save too frequently

Error Handling

  1. Check Returns: Always check export return values
  2. Graceful Failure: Handle errors without breaking gameplay
  3. Log Errors: Use Debug mode during development
  4. Inform Players: Give feedback on failures

Integration

  1. Use Exports: Prefer exports over events for server-side code
  2. Event Documentation: Document custom event usage
  3. Compatibility: Test with different frameworks
  4. Version Checking: Ensure compatible versions

Event Flow Diagram

Client Action → TriggerServerEvent('dime_skills:addXP')

Server Receives Event

Validate Parameters & Safety Checks

Update Player Skills (exports.dime_skills:addEXP)

Update Database

TriggerClientEvent('dime_skills:sendPlayerSkills')

TriggerClientEvent('dime_skills:skillNotify')

Client Updates UI & Shows Notification