F.A.Q

3 min readUpdated Today

Setup

No. It runs on QBox, QBCore, ESX and standalone through ml_bridge.

In the ml_skills_trees MySQL table, one row per category, versioned. Edits made in the in-game editor save with version + 1. The default trees shipped with the resource seed the table on first boot only, subsequent boots load the highest-version row per category.

With /skills or the J key by default. Both are configurable through Config.OpenCommand and Config.OpenKey.

Editor

The current player needs the permission level set in Config.AdminPermission.level (default 'supervisore'). Open the UI with /skills, switch to admin mode from the header, then enter the editor for any category.

Yes. The save action writes to ml_skills_trees with INSERT ... ON DUPLICATE KEY UPDATE, bumps the version counter, and the resource loads the highest-version row on boot.

Yes. The editor's Import button opens a modal where you paste a Config.DefaultTrees-style Lua snippet. The parser validates the fields, flags duplicates, adapts the other tree formats, and previews the diff before committing the skills into the current category canvas. Existing skill UIDs in the target tree are detected so re-imports do not create collisions.

Yes. In the editor, click a skill and use the snippet button. The exact exports.ml_skills:AddXp(...) / UnlockSkill(...) / AddPoints(...) line lands in the clipboard with the right category UID and skill UID already filled in.

Players

Only when Config.AllowReset = true. By default the reset action is admin-only.

The client watches the entries in Config.XpListeners and reports activity to the server at random intervals. The server checks the timing, confirms the ped has moved since the previous fire (when XpListenerMovementCheck = true), and enforces a per-minute cap plus a per-day cap per category.

Config.LockedPreviewGrayscale = true desaturates the hover image until the requirements are met. Set it to false to always show full color.

Integration

lua
1exports.ml_skills:AddXp('personal', 25, src)

The fourth argument is a free-form source string that appears in the webhook.

lua
1if exports.ml_skills:HasUnlockedSkill('medical', 'reviveSpeed_3', src) then
2    -- expose the advanced revive UI
3end

Yes. In the achievement editor, add a trigger with the target resource name and either the export name or the event name. When the player claims the achievement, the trigger fires server-side.

Yes. Add a requiresJob = 'mechanic' field in the skill definition. The lock helpers return a job-related reason in the tooltip.

Prestige

Set Config.PrestigeEnabled = true. Each prestige tier adds Config.PrestigeBonus (default 0.10 = +10%) to all future XP gains in that category, up to Config.MaxPrestige tiers.

Yes. Prestige is part of the category_data JSON column in ml_skills_players and persists across any restart.

Performance

Drop Config.PerformanceMode to 'performance'. Heavy animations pause and the LOD system renders simple nodes regardless of zoom. The LodNodeThreshold and LodZoomThreshold values control where the cutoff kicks in when PerformanceMode = 'auto'.

Updates

  1. Download the latest from CFX Portal
  2. Backup shared/config.lua, server/config_server.lua, the locales/ folder, and any custom open/ overrides
  3. Replace every other file
  4. Restart the resource

Pre-1.0 installs migrate automatically on boot (dedupe of duplicate tree rows, addition of the category UNIQUE constraint, addition of the idx_category_version covering index). No manual SQL needed.