# animations Source: https://docs.vorp-core.com/api-reference/animations this script allows you to set up premade animations to use in your scripts Client side Initiate the animations export ```lua theme={null} local Animations = exports.vorp_animations.initiate() ``` Play Animation ```lua theme={null} Animations.playAnimation('campfire', 2000) ``` Stop Animation ```lua theme={null} Animations.endAnimation('campfire') ``` Start Animation indefinitely ```lua theme={null} Animations.startAnimation('campfire') ``` to activate in game , set in config to `devmode true` and use the command `/startanimation campfire` , the ui will allow you to adjust the animation so you can add them to config files # character Source: https://docs.vorp-core.com/api-reference/characters API reference for characters ## Events This event is triggered when a player has successfully selected a character and joined the server. It provides an opportunity to execute custom logic or initialize player-specific data based on the chosen character. The event is fired on both the client and server side Client Side ```lua SelectedCharacter theme={null} RegisterNetEvent("vorp:SelectedCharacter", function(charid) print(charid) end) ``` Server Side ```lua SelectedCharacter theme={null} AddEventHandler("vorp:SelectedCharacter",function(source,character) print(character) end) ``` This event is triggered when a player has created a new character for the server. Example Usage Case: Someone might use this to create/select a first spawn location for a character. Client Side ```lua initNewCharacter theme={null} AddEventHandler("vorp:initNewCharacter", function() print("New Character Created") end) ``` Ability to wait for the first character scene to start in case you need to show a loading screen or something else before the scene starts Client Side ```lua stopLoadingScene theme={null} -- this is just optional -- you can use it to tell character to not start the scene yet like imagine if you have a loading screen with a button to join, this event will make it to wait -- set to true to wait, set to false to continue the scene TriggerEvent("vorpcharacter:stopLoadingScene", boolean) ``` ## Exports Exports to be used in your scripts Client Side This export retrieves all components in the player's cache, useful for updating or modifying the player's appearance based on the components stored in the cache The components in the player's cache. ```lua theme={null} local result = exports.vorp_character:GetAllPlayerComponents() ``` Client Side This export retrieves a specific component The category of the component to retrieve. The components in the player's cache. ```lua theme={null} local component = exports.vorp_character:GetPlayerComponent(category) ``` Server Side This export opens the outfits menu for the player The source of the player. True if the menu can be opened false otherwise. ```lua theme={null} local result = exports.vorp_character:OpenOutfitsMenu(source) ``` ## StateBags Bandana state you can use this in ohter script to check if player is wearing a bandana on his face using characters bandana commands ```lua theme={null} LocalPlayer.state.IsBandanaOn ``` check if player is in character shops ```lua theme={null} LocalPlayer.state.PlayerIsInCharacterShops ``` # core Source: https://docs.vorp-core.com/api-reference/core API reference for core This documentation is for developers who are making scripts for VORP Core Framework ## Export GetCore is a shared export that returns the core table containing all the getters and setters for VORP Core. some of the getters and setters are client side only and some are server side only. Shared The core table containing all the getters and setters. ```lua theme={null} local Core = exports.vorp_core:GetCore() ``` ## Register Server Jobs Allowing you to only give correct jobs and grades to the players and to prevent them from using incorrect jobs and grades. Server Side Register jobs to the server, this will be stored in config/jobs.lua file in vorp core then can be registered automatically using the RegisterJobs function or manually by adding the jobs to the lua file. job data is a table with the following keys: * `jobname`: `string` job name as the key and the job data as the value. * `groups`: `array` optional, if you wish to set this job to only this group can give this job. * `privateJob`: `boolean` if true, the job will be private no one can give this job. * `grades`: `table` only add grades if you use grades * `[grade]`: `table` grade number as the key and the grade data as the value. * `label`: `string` the label of the grade * `privateGrade`: `boolean` if true, the grade will be private no one can give this grade. The resource name to register the jobs to for debug ```lua theme={null} local jobsData = { jobname = { groups = {"admin"} -- optional, if you wish to set this job to only this group can give this job. privateJob = true -- if true, the job will be private no one can give this job. grades = { -- only add grades if you use grades [1] = { label = "Grade Label" privateGrade = true -- if true, the grade will be private no one can give this grade. } } } } if Core.RegisterJobs then Core.RegisterJobs(jobsData, GetCurrentResourceName()) else print("Core.RegisterJobs is not available update vorp core to the latest version") end ``` ## Notifications notifications can also accept -1 as duration to always stay on screen and to clear them you need to use UiFeedClearChannel Shared The title of the notification The subtitle of the notification The dictionary for the icon The icon name Duration in milliseconds Color of the notification ```lua theme={null} Core.NotifyLeft("title", "subtitle", "dict", "icon", 4000, "color") ``` The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyTip("title", 4000) ``` The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyRightTip("title", 4000) ``` The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyObjective("title", 4000) ``` The title of the notification The location to display Duration in milliseconds ```lua theme={null} Core.NotifyTop("title", "location", 4000) ``` The title of the notification The subtitle of the notification Duration in milliseconds ```lua theme={null} Core.NotifySimpleTop("title", "subtitle", 4000) ``` The title of the notification The dictionary for the icon The icon name Color of the notification Duration in milliseconds enables the stars for quality like animal pelt stars shows the quality of the notification ```lua theme={null} Core.NotifyAvanced("title", "dict", "icon", "color", 4000, quality, showQuality) ``` The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyCenter("title", 4000) ``` The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyBottomRight("title", 4000) ``` The title of the notification The subtitle of the notification Duration in milliseconds ```lua theme={null} Core.NotifyFail("title", "subtitle", 4000) ``` The title of the notification The audio reference The audio name Duration in milliseconds ```lua theme={null} Core.NotifyDead("title", "audioref", "audioname", 4000) ``` The title of the notification The subtitle of the notification Duration in milliseconds ```lua theme={null} Core.NotifyUpdate("title", "subtitle", 4000) ``` The title of the notification The subtitle of the notification The audio reference The audio name Duration in milliseconds ```lua theme={null} Core.NotifyWarning("title", "subtitle", "audioref", "audioname", 4000) ``` The title of the notification The subtitle of the notification The dictionary for the icon The icon name Duration in milliseconds Color of the notification ```lua theme={null} Core.NotifyLeftRank("title", "subtitle", "dict", "icon", 4000, "color") ``` The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyOneSimpleTop("title", 4000) ``` The title of the notification The description of the notification The second description of the notification Duration in milliseconds ```lua theme={null} Core.NotifyThreeSimpleTop("title","description","second_description", 4000) ``` The title of the notification The subtitle of the notification The dictionary for the icon The icon name Duration in milliseconds or -1 for infinite Color of the notification ```lua theme={null} Core.NotifyLeftInteractive("title", "subtitle", "dict", "icon", 4000, "color") ``` The player ID The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyTip(source, "title", 4000) ``` The player ID The title of the notification The subtitle of the notification The dictionary for the icon The icon name Duration in milliseconds Color of the notification ```lua theme={null} Core.NotifyLeft(source, "title", "subtitle", "dict", "icon", 4000, "color") ``` The player ID The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyRightTip(source, "title", 4000) ``` The player ID The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyObjective(source, "title", 4000) ``` The player ID The title of the notification The location to display Duration in milliseconds ```lua theme={null} Core.NotifyTop(source, "title", "location", 4000) ``` The player ID The title of the notification The subtitle of the notification Duration in milliseconds ```lua theme={null} Core.NotifySimpleTop(source, "title", "subtitle", 4000) ``` The player ID The title of the notification The dictionary for the icon The icon name Color of the notification Duration in milliseconds Show the quality of the notification The quality of the notification max 3 ```lua theme={null} Core.NotifyAvanced(source, "title", "dict", "icon", "color",showQuality,quality, 4000) ``` The player ID The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyCenter(source, "title", 4000) ``` The player ID The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyBottomRight(source, "title", 4000) ``` The player ID The title of the notification The subtitle of the notification Duration in milliseconds ```lua theme={null} Core.NotifyFail(source, "title", "subtitle", 4000) ``` The player ID The title of the notification The audio reference The audio name Duration in milliseconds ```lua theme={null} Core.NotifyDead(source, "title", "audioref", "audioname", 4000) ``` The player ID The title of the notification The subtitle of the notification Duration in milliseconds ```lua theme={null} Core.NotifyUpdate(source, "title", "subtitle", 4000) ``` The player ID The title of the notification The subtitle of the notification The audio reference The audio name Duration in milliseconds ```lua theme={null} Core.NotifyWarning(source, "title", "subtitle", "audioref", "audioname", 4000) ``` The player ID The title of the notification The subtitle of the notification The dictionary for the icon The icon name Duration in milliseconds Color of the notification ```lua theme={null} Core.NotifyLeftRank(source, "title", "subtitle", "dict", "icon", 4000, "color") ``` The player ID The title of the notification Duration in milliseconds ```lua theme={null} Core.NotifyOneSimpleTop(source, "title", 4000) ``` The player ID The title of the notification The description of the notification The second description of the notification Duration in milliseconds ```lua theme={null} Core.NotifyThreeSimpleTop(source, "title","description","second_description", 4000) ``` The player ID The title of the notification The subtitle of the notification The dictionary for the icon The icon name Duration in milliseconds or -1 for infinite Color of the notification ```lua theme={null} Core.NotifyLeftInteractive(source, "title", "subtitle", "dict", "icon", 4000, "color") ``` ## Characters Get the character data to access getters and setters Server The player ID ```lua theme={null} local user = Core.getUser(source) --[[@as User]] if not user then return end -- is player in session? local character = user.getUsedCharacter --[[@as Character]] ``` The unique identifier of the character ```lua theme={null} local identifier = character.identifier ``` The unique character identifier ```lua theme={null} local charIdentifier = character.charIdentifier ``` The group the character belongs to ```lua theme={null} local group = character.group ``` The multiJobs of the character ```lua theme={null} local multijobs = character.multiJobs for _, job in pairs(multiJobs) do print(job.job, job.grade, job.label) end ``` The job of the character ```lua theme={null} local job = character.job ``` The job grade of the character ```lua theme={null} local jobGrade = character.jobGrade ``` The job label of the character ```lua theme={null} local jobLabel = character.jobLabel ``` The amount of money the character has ```lua theme={null} local money = character.money ``` The amount of gold the character has ```lua theme={null} local gold = character.gold ``` The amount of rol the character has ```lua theme={null} local rol = character.rol ``` The amount of experience points the character has ```lua theme={null} local xp = character.xp ``` The first name of the character ```lua theme={null} local firstname = character.firstname ``` The last name of the character ```lua theme={null} local lastname = character.lastname ``` The status of the character ```lua theme={null} local status = character.status ``` The coordinates of the character ```lua theme={null} local coords = character.coords ``` Whether the character is dead or not ```lua theme={null} local isDead = character.isdead ``` The skin details of the character ```lua theme={null} local skin = character.skin ``` The component details of the character ```lua theme={null} local comps = character.comps ``` The component tints of the character ```lua theme={null} local compTints = character.compTints ``` The age of the character ```lua theme={null} local age = character.age ``` The gender of the character ```lua theme={null} local gender = character.gender ``` The description of the character ```lua theme={null} local charDescription = character.charDescription ``` The nickname of the character ```lua theme={null} local nickname = character.nickname ``` The inventory capacity of the character ```lua theme={null} local invCapacity = character.invCapacity ``` The skills of the character ```lua theme={null} local skills = character.skills local skill = skills.Crafting if not skill then return print("skill not found in core config or it doesn't exist") end local skillExp = skill.Exp local skillLevel = skill.Level ``` The job name to set If true, the job change event won't be triggered ```lua theme={null} character.setJob("job", flag) ``` multijobs can be added to users and they can switch between them using the switch command in vorp core listen for job change events to know when the user switches jobs The job name to set The job grade to set The job label to set ```lua theme={null} character.setMultiJob("job", 1, "label") ``` The job name to remove ```lua theme={null} character.removeMultiJob("job") ``` The number of multijobs the character has ```lua theme={null} local multiJobCount = character.getMultiJobsCount() ``` The job grade to set If true, the job change event won't be triggered ```lua theme={null} character.setJobGrade(1, flag) ``` The job label to set ```lua theme={null} character.setJobLabel("Label") ``` The group to set If true, the group change event won't be triggered ```lua theme={null} character.setGroup("admin", false) ``` Set the amount of Rol of the character ```lua theme={null} character.setRol(1000) ``` Set the amount of XP of the character ```lua theme={null} character.setXp(5000) ``` Set the first name of the character ```lua theme={null} character.setFirstname("Sadie") ``` Set the last name of the character ```lua theme={null} character.setLastname("Adler") ``` The skin in JSON format ```lua theme={null} character.updateSkin("skin") ``` The clothing components in JSON format ```lua theme={null} character.updateComps("comps") ``` The clothing components tints in JSON format ```lua theme={null} character.updateCompTints("comps") ``` The currency type (0 = money, 1 = gold, 2 = rol) The amount to add to character ```lua theme={null} character.addCurrency(0, 1000) ``` The currency type (0 = money, 1 = gold, 2 = rol) The amount to remove from character ```lua theme={null} character.removeCurrency(0, 1000) ``` The amount of XP to add ```lua theme={null} character.addXp(100) ``` The amount of XP to remove ```lua theme={null} character.removeXp(100) ``` The age to set to the character ```lua theme={null} character.setAge(45) ``` The character description to set to the character ```lua theme={null} character.setCharDescription("string") ``` The nickname to set to the character ```lua theme={null} character.setNickName("string") ``` The gender to set (male or female) ```lua theme={null} character.setGender("string") ``` The amount to change the inventory capacity by (can be positive or negative) its also incremental so 1000 will be 1000 + what you already have ```lua theme={null} character.updateInvCapacity(1) ``` The name of the skill to set, these skillNames will be in VORP Core config skills the Exp value to be set to the skillName you passed values are incremental so 1000 exp will be 1000 + what you already have ```lua theme={null} character.setSkills("skillName", 10) -- skillname exp ``` ## Users Get the user data to access getters and setters The player ID ```lua theme={null} local user = Core.getUser(source) --[[@as User]] if not user then return end -- is player in session? ``` The maximum number of jobs allowed for the user ```lua theme={null} user.setMaxJobsAllowed(maxJobs) ``` The character ID ```lua theme={null} local user = Core.getUserByCharId(charid) --[[@as User]] ``` The user group (not character group) ```lua theme={null} local userGroup = user.getGroup ``` The user's source (player ID) ```lua theme={null} local userSource = user.source ``` The maximum number of jobs allowed for the user ```lua theme={null} local maxJobsAllowed = user.maxJobsAllowed ``` The group to set for the user ```lua theme={null} user.SetGroup(group) ``` The steam ID of the user ```lua theme={null} local steam = user.getIdentifier() ``` All characters of the user ```lua theme={null} local data = user.getUserCharacters() ``` The warning status of the user ```lua theme={null} local warnstatus = user.getPlayerwarnings() ``` ## Whitelist Server The identifier of the whitelist entry ```lua theme={null} local data = Core.Whitelist.getEntry(identifier) print(json.encode(data),{ident = true}) ``` The identifier of the whitelist entry ```lua theme={null} Core.Whitelist.whitelistUser(identifier) ``` The identifier of the whitelist entry ```lua theme={null} Core.Whitelist.unWhitelistUser(identifier) ``` ## Webhooks Shared The title of the webhook The webhook link The description of the webhook The color of the webhook The name of the webhook The logo of the webhook The footerlogo of the webhook The avatar of the webhook ```lua theme={null} Core.AddWebhook("title", "webhook", "description", 12345678, "name", "logo", "footerlogo", "avatar") ``` ## Instancing Client to add a players to different instances use his server id + instance number to add players to same instance use only the instanceNumber ```lua theme={null} local instanceNumber = 54123 -- any number VORPcore.instancePlayers(GetPlayerServerId(PlayerId())+ instanceNumber) ``` remove players from instance ```lua theme={null} VORPcore.instancePlayers(0) ``` ## Player Available through core export Server Side
when using these functions you will benefit of the event listeners `OnPlayerDeath` `OnPlayerRevive` `OnPlayerRespawn`
The player ID ```lua theme={null} Core.Player.Heal(source) ``` The player ID ```lua theme={null} Core.Player.Revive(source) ``` The player ID ```lua theme={null} Core.Player.Respawn(source) ``` ## Callbacks Callbacks are available through core export or single exports if you need only the call back system ```lua theme={null} local ServerRPC = exports.vorp_core:ServerRpcCall() --[[@as ServerRPC]] -- for intellisense ``` trigger a synchronous callback from client to server The name of the callback The parameters to pass to the callback The result of the callback ```lua theme={null} local result = Core.Callback.TriggerAwait(name,...) print(result) ``` trigger an asynchronous callback from client to server The name of the callback The parameters to pass to the callback The result of the callback ```lua theme={null} Core.Callback.TriggerAsync(name, function(result) print(result) end, ...) ``` register a callback on the server to receive a client callback The name of the callback The callback function The source of the callback The callback function The parameters to pass to the callback The result of the callback ```lua theme={null} Core.Callback.Register(name, function(source,callback,...) callback(...) end) ``` if you need only the call back system ```lua theme={null} local ClientRPC = exports.vorp_core:ClientRpcCall() --[[@as ClientRPC]] -- for intellisense ``` trigger a server to client callback synchronously The name of the callback The source of the callback The parameters to pass to the callback The result of the callback ```lua theme={null} local result = Core.Callback.TriggerAwait(name,source,...) print(result) ``` trigger an asynchronous callback from client to server The name of the callback The source of the callback The parameters to pass to the callback The result of the callback ```lua theme={null} Core.Callback.TriggerAsync(name, source, function(result) print(result) end, ...) ``` register a callback on the client to receive a server callback The name of the callback The callback function The parameters to pass to the callback The result of the callback ```lua theme={null} Core.Callback.Register(name, function(callback,...) callback(...) end) ``` ## Events Event Listeners to detect changes in the player state when player job and group changes these events are triggered Server Side #### onGroupChange ```lua theme={null} AddEventHandler("vorp:playerGroupChange",function(source, newgroup,oldgroup) end) ``` #### onJobChange ```lua theme={null} AddEventHandler("vorp:playerJobChange", function(source, newjob,oldjob) end) ``` #### onJobGradeChange ```lua theme={null} AddEventHandler("vorp:playerJobGradeChange",function(source, newjobgrade,oldjobgrade) end) ``` #### onPlayerDeath when player dies this event is triggered ```lua theme={null} --CLIENT AddEventHandler("vorp_core:Client:OnPlayerDeath",function(killerserverid,causeofdeath) end) --SERVER RegisterNetEvent("vorp_core:Server:OnPlayerDeath",function(killerserverid,causeofdeath) end) ``` #### onPlayerRevive when player is revived through VORP Core export this event will trigger ```lua theme={null} --SERVER AddEventHandler("vorp_core:Server:OnPlayerRevive",function(source)end) --CLIENT RegisterNetEvent("vorp_core:Client:OnPlayerRevive") ``` #### onPlayerRespawn when player respawns through VORP Core export this event will trigger ```lua theme={null} --SERVER AddEventHandler("vorp_core:Server:OnPlayerRespawn"function(source)end) --CLIENT RegisterNetEvent("vorp_core:Client:OnPlayerRespawn") ``` #### onPlayerHeal when player is healed through VORP Core export this event will trigger ```lua theme={null} --SERVER AddEventHandler("vorp_core:Server:OnPlayerHeal",function(source) end) --CLIENT RegisterNetEvent("vorp_core:Client:OnPlayerHeal") ``` #### onPlayerLevelUp triggered when a player has leveled up or down ```lua theme={null} --SERVER AddEventHandler("vorp_core:Server:OnPlayerLevelUp",function(source,skillName,newLevel,oldLevel) end) --CLIENT RegisterNetEvent("vorp_core:Client:OnPlayerLevelUp",function(skillName,newLevel,oldLevel) end) ``` #### onPlayerSpawned triggered when a player has fully spawned after teleportation and loading screens ```lua theme={null} --CLIENT AddEventHandler("vorp_core:Client:OnPlayerSpawned",function()end) ``` ## Dataview call dataview in your script fxmanifest ```lua theme={null} client_scripts { '@vorp_core/client/dataview.lua' } ``` ## GlobalStates * easily get players count from client or server ```lua theme={null} GlobalState.PlayersInSession ``` ## Statebags statebag getters that allow you to get the character data Shared is player in session? this will return true when player choose his character The IsInSession of the character ```lua theme={null} LocalPlayer.state.IsInSession ``` get the first name of the character The first name of the character ```lua theme={null} LocalPlayer.state.Character.FirstName ``` get the last name of the character The last name of the character ```lua theme={null} LocalPlayer.state.Character.LastName ``` get the job of the character The job of the character ```lua theme={null} LocalPlayer.state.Character.Job ``` get the job label of the character The job label of the character ```lua theme={null} LocalPlayer.state.Character.JobLabel ``` get the grade of the character The grade of the character ```lua theme={null} LocalPlayer.state.Character.Grade ``` get the group of the character The group of the character ```lua theme={null} LocalPlayer.state.Character.Group ``` get the age of the character The age of the character ```lua theme={null} LocalPlayer.state.Character.Age ``` get the gender of the character The gender of the character ```lua theme={null} LocalPlayer.state.Character.Gender ``` get the nickname of the character The nickname of the character ```lua theme={null} LocalPlayer.state.Character.NickName ``` get the character description of the character The character description of the character ```lua theme={null} LocalPlayer.state.Character.CharDescription ``` get the money of the character The money of the character ```lua theme={null} LocalPlayer.state.Character.Money ``` get the gold of the character The gold of the character ```lua theme={null} LocalPlayer.state.Character.Gold ``` get the rol of the character The rol of the character ```lua theme={null} LocalPlayer.state.Character.Rol ``` get the charid of the character The charid of the character ```lua theme={null} LocalPlayer.state.Character.CharId ``` is player in session? this will return true when player choose his character The IsInSession of the character ```lua theme={null} Player(source).state.IsInSession ``` get the first name of the character The first name of the character ```lua theme={null} Player(source).state.Character.FirstName ``` get the last name of the character The last name of the character ```lua theme={null} Player(source).state.Character.LastName ``` get the job of the character The job of the character ```lua theme={null} Player(source).state.Character.Job ``` get the job label of the character The job label of the character ```lua theme={null} Player(source).state.Character.JobLabel ``` get the grade of the character The grade of the character ```lua theme={null} Player(source).state.Character.Grade ``` get the group of the character The group of the character ```lua theme={null} Player(source).state.Character.Group ``` get the age of the character The age of the character ```lua theme={null} Player(source).state.Character.Age ``` get the gender of the character The gender of the character ```lua theme={null} Player(source).state.Character.Gender ``` get the nickname of the character The nickname of the character ```lua theme={null} Player(source).state.Character.NickName ``` get the character description of the character The character description of the character ```lua theme={null} Player(source).state.Character.CharDescription ``` get the money of the character The money of the character ```lua theme={null} Player(source).state.Character.Money ``` get the gold of the character The gold of the character ```lua theme={null} Player(source).state.Character.Gold ``` get the rol of the character The rol of the character ```lua theme={null} Player(source).state.Character.Rol ``` get the charid of the character The charid of the character ```lua theme={null} Player(source).state.Character.CharId ``` ## Version Use vorp version check with change logs feature in your scripts add this in your fxmanifest ```lua theme={null} -- version must match version.file version '0.0.1' vorp_checker 'yes' -- can use color codes ^1 vorp_name '^5your resource name ^4version Check^3' -- path to the github repository, in here it must have a version.file file type where your change logs will be, also must be public repository vorp_github 'https://github.com/repository/resource_name' ``` example of a version.file ```lua theme={null} <0.0.1> -- version must be the same in fxmanifest - new version - added feature - removed feature - fixed something ``` # inputs Source: https://docs.vorp-core.com/api-reference/inputs build an advanced input menu for your scripts Client side This function is used to create advanced input menu. ```lua theme={null} local myInput = { type = "enableinput", -- don't touch inputType = "input", -- input type button = "Confirm", -- button name placeholder = "NAME QUANTITY", -- placeholder name style = "block", -- don't touch attributes = { inputHeader = "GIVE ITEM", -- header type = "text", -- inputype text, number,date,textarea ETC pattern = "[0-9]", -- only numbers "[0-9]" | for letters only "[A-Za-z]+" title = "numbers only", -- if input doesnt match show this message style = "border-radius: 10px; background-color: ; border:none;"-- style } } local result = exports.vorp_inputs:advancedInput(myInput) result = tonumber(result) -- convert result to a number result = tostring(result) -- convert result to a string ``` if you want to split the result into two variables or more you can use this code ```lua theme={null} local result = "your result" local splitString = {} for i in string.gmatch(result, "%S+") do splitString[#splitString + 1] = i end local data1, data2 = splitString[1],splitString[2] ``` # inventory Source: https://docs.vorp-core.com/api-reference/inventory Documentation for vorp inventory system This documentation is for developers who are making scripts for VORP Core Framework ## Exports *** These exports are client side only! ### Getters get all user inventory items `returns` a table containing all the items in the inventory ```lua theme={null} local result = exports.vorp_inventory:getInventoryItems() ``` get user inventory item the item name `returns` a table containing the item name,label,weight,desc metadata, percentage ```lua theme={null} local result = exports.vorp_inventory:getInventoryItem() ``` the item name to get or an table of items to get in one single call, returns the data from items database like label,weight,desc,metadata etc ```lua theme={null} local result = exports.vorp_inventory:getServerItem("water") print(result.label) ``` close inventory ```lua theme={null} exports.vorp_inventory:closeInventory() ``` These exports are server side only! ### Getters get all user ammo The player id callback function syncronous or asyncronous `returns` a table containing all the ammo ```lua theme={null} exports.vorp_inventory:getUserAmmo(source, callback) ``` check if player can carry weapons The player id amount of weapons callback function syncronous or asyncronous weapon name or hash its needed to check weight since 3.6 `returns` true if the player can carry the weapons ```lua theme={null} exports.vorp_inventory:canCarryWeapons(source, amount,callback, weaponName) ``` get user inventory weapon The player id callback function syncronous or asyncronous weapon id `{id:number,name:string,propietary:string,used:boolean,desc:string,group:number,source:number,label:string,serial_number:string,custom_label:string,custom_desc:string}` ```lua theme={null} exports.vorp_inventory:getUserWeapon(source, callback,weaponId) ``` get user inventory weapons The player id callback function syncronous or asyncronous `{id:number,name:string,propietary:string,used:boolean,desc:string,group:number,source:number,label:string,serial_number:string,custom_label:string,custom_desc:string}` ```lua theme={null} exports.vorp_inventory:getUserInventoryWeapons(source, callback) ``` get weapon bullets The player id weapon id callback function syncronous or asyncronous weapon ammo ```lua theme={null} exports.vorp_inventory:getWeaponBullets(source,weaponID, callback) ``` get weapon components The player id weapon id callback function syncronous or asyncronous `returns` a table containing the weapon components ```lua theme={null} exports.vorp_inventory:getWeaponComponents(source, weaponId, callback) ``` ### Setters set weapon custom description The player id weapon id weapon description callback function syncronous or asyncronous `returns` true if the description was successfully set ```lua theme={null} exports.vorp_inventory:setWeaponCustomDesc(weaponId, desc, cb) ``` set weapon custom label The player id weapon id weapon label callback function syncronous or asyncronous `returns`true if the label was successfully set ```lua theme={null} exports.vorp_inventory:setWeaponCustomLabel(weaponId, label, cb) ``` set weapon serial number The player id weapon id weapon serial number callback function syncronous or asyncronous `returns` true if the serial number was successfully set ```lua theme={null} exports.vorp_inventory:setWeaponSerialNumber(weaponId, serial, cb) ``` remove weapon from user inventory The player id weapon id callback function syncronous or asyncronous `returns` true if the weapon was successfully removed ```lua theme={null} exports.vorp_inventory:subWeapon(source, weaponId, callback) ``` give weapon to user The player id weapon id target id callback function syncronous or asyncronous `returns` true if the weapon was successfully given ```lua theme={null} exports.vorp_inventory:giveWeapon(source, weaponId, target,callback) ``` create weapon The player id weapon name amount of ammo weapon components weapon components callback function syncronous or asyncronous leave this as nil, this is used internally only custom serial number for weapon custom label for weapon custom desc for weapons if async ```lua theme={null} exports.vorp_inventory:createWeapon(source, weaponName, ammo, components, comps, callback,serial,label,desc) ``` delete weapon The player id weapon id callback function syncronous or asyncronous if async ```lua theme={null} exports.vorp_inventory:deleteWeapon(source, weaponId, callback) ``` add bullets The player id bullet type amount of bullets callback function syncronous or asyncronous `returns` true if the bullets were successfully added ```lua theme={null} exports.vorp_inventory:addBullets(source, bulletType, amount,callback) ``` remove bullets from weapon weapon id bullet type amount of bullets callback function syncronous or asyncronous `returns` true if the bullets were successfully removed ```lua theme={null} exports.vorp_inventory:subBullets(weaponId, bulletType, amount,callback) ``` remove all user ammo The player id ```lua theme={null} exports.vorp_inventory:removeAllUserAmmo(source) ``` add a component to a weapon The player id weapon id component name or hash slot category callback function syncronous or asyncronous `returns` true if the component was successfully added ```lua theme={null} exports.vorp_inventory:addWeaponComponent(source, weaponId, component, category, callback) ``` add multiple components to a weapon The player id weapon id a table where the key is the component name or hash and the value is the slot category `{ [component] = category }` callback function syncronous or asyncronous `returns` true if the components were successfully added ```lua theme={null} exports.vorp_inventory:addWeaponComponents(source, weaponId, components, callback) ``` remove a component from a weapon The player id weapon id component name or hash slot category callback function syncronous or asyncronous `returns` true if the component was successfully removed ```lua theme={null} exports.vorp_inventory:subWeaponComponent(source, weaponId, component, category, callback) ``` remove multiple components from a weapon The player id weapon id a table where the key is the component name or hash and the value is the slot category `{ [component] = category }` callback function syncronous or asyncronous `returns` true if the components were successfully removed ```lua theme={null} exports.vorp_inventory:subWeaponComponents(source, weaponId, components, callback) ``` ### Getters check if player can carry the item before adding it to the inventory The player id The item name The amount of items The callback function syncronous or asyncronous `returns` true if the player can carry the item ```lua theme={null} exports.vorp_inventory:canCarryItem(source, item, amount, callback) ``` gets all the items in the player inventory The player id The callback function syncronous or asyncronous `returns` a table containing all the items in the inventory ```lua theme={null} exports.vorp_inventory:getUserInventoryItems(source, callback) ``` get item amount from player inventory The player id callback function for syncronous or asyncronous item name item metadata allows to control what items to get, if 0 gets all items with no metadata if meta was not passed if 0 gets items expired, anything above 0 or equal will return those item count `returns` the amount of items in the inventory ```lua usage theme={null} exports.vorp_inventory:getItemCount(source, callback, item, metadata, percentage) ``` get DB item item name callback function asyncronous or syncronous `returns` a table containing item info ```lua theme={null} exports.vorp_inventory:getItemDB(item, callback) ``` get item by main id The player id item id callback function syncronous or asyncronous `{id:number, label:string, name:string, metadata:table, group:number, type:string, count:number, limit:number,canUse:boolean,percenage:integer,description:string,weight:number}` ```lua theme={null} exports.vorp_inventory:getItemById(source, id, callback) ``` get item data The player id item name callback function syncronous or asyncronous item metadata get an item only at a certain percentage, if 0 it gets tems expired if nil gets any item if more than 0 gets any item that equals or is above `{id:number, label:string, name:string, metadata:table, group:number, type:string, count:number, limit:number,canUse:boolean,weight:number,desc:string,percentage:integer}` ```lua theme={null} exports.vorp_inventory:getItem(source, item,callback, metadata,percentage) ``` ### Setters add item to user The player id item name amount of item item metadata callback function syncronous or asyncronous if true will not trigger the event OnItemCreated `returns` true if the item was successfully added ```lua theme={null} exports.vorp_inventory:addItem(source, item, amount, metadata, callback,event) ``` remove item from user inventory The player id item name amount of item item metadata callback function syncronous or asyncronous event OnItemRemoved to be fired, if true it wont be sent, false or nil it will fire the event allows to control percentage of items to remove, if nil removes any, if 0 removes expired items only, if more than 0 it removes anything above or equal `returns` true if the item was successfully removed ```lua theme={null} exports.vorp_inventory:subItem(source, item, amount, metadata, callback,event,percentage) ``` remove item from user inventory by its id exort available on verion 3.9 and up lower versions uses subItemID The player id item id callback function syncronous or asyncronous event OnItemRemoved to be fired, if true it wont be sent, false or nil it will fire the event amount to remove `returns` true if the item was successfully removed ```lua theme={null} exports.vorp_inventory:subItemById(source, itemId,callback,event,amount) ``` * Split a stack and modify only some items (amount must be less than the current stack) * Merge with an existing stack that has matching metadata (amount must be more or equal than the current stack) * Modify the entire stack's metadata (amount must be more or equal than the current stack) this only applies if metadata is the same as current stack The player id item id reserved keys are: * `description` the description of the item to replace * `image` the image of the item to replace must exist in item folder. * `label` the label of the item to replace * `weight` the weight of the item to replace * `tolltip` add extra text to the tooltip * `context` add context buttons to the item * `useExpired` if true allows to use expired items overriding the useExpired setting in the item db amount of item to remove from current stack if less, if more it will remove from here and add to another stack if metadata matches, if not then it updates the entire stack with new meta callback function syncronous or asyncronous `returns` true if the metadata was successfully set ```lua theme={null} -- FOR CONTEXT BUTTONS USE THIS FORMAT local metadata = { context = { -- key word for context buttons { -- array supporting multiple buttons text = "BUTTON", -- label shown in menu close = true, -- close inv on use event = { client = "myscript:contextevent", -- client event to trigger server = "myscript:contextevent" -- server event to trigger }, arguments = { -- arguments to pass to the event if needed "any", } } } } -- listen in your scripts client side AddEventHandler("myscript:contextevent", function(args,itemId) end) -- NOTE: for server side events you must whitelist the event using the exports bellow exports.vorp_inventory:addAllowedContextMenuEvent("myscript:contextevent",GetCurrentResourceName()) -- or as a table exports.vorp_inventory:addAllowedContextMenuEvent({ "myscript:contextevent", "myscript:contextevent2" },GetCurrentResourceName()) -- if you dont whitelist the event it will not be triggered this is to ensure only trusted events are triggered -- to remove a whitelisted event exports.vorp_inventory:removeAllowedContextMenuEvent("myscript:contextevent",GetCurrentResourceName()) -- or as a table exports.vorp_inventory:removeAllowedContextMenuEvents({ "myscript:contextevent", "myscript:contextevent2" },GetCurrentResourceName()) -- server side of your script AddEventHandler("myscript:contextevent", function(source,args,itemId) end) ``` ```lua theme={null} -- SET ITEM METADATA exports.vorp_inventory:setItemMetadata(source, itemId, metadata, amount, callback) ``` register usable item Items cant be registered twice they must be unique item name callback `{source:int, id:number, label:string, name:string, metadata:table, group:number, type:string, count:number, limit:number,canUse:boolean, mainid: integer, percentage:integer}` resource name for debug purposes so users can see in what resource this item is registered at ```lua theme={null} exports.vorp_inventory:registerUsableItem(item, callback,resourceName) ``` un register usable item when you stop a script for example Items cant be registered twice they must be unique item name ```lua theme={null} exports.vorp_inventory:unRegisterUsableItem(item) ``` ### Getters get custom inventory item count inventory id item name callback function syncronous or asyncronous if metadata is provided then it will return the amount of items with the same metadata `returns` the amount of items in the inventory ```lua theme={null} exports.vorp_inventory:getCustomInventoryItemCount(invid,itemName,callback,metadata) ``` get custom inventory items inventory id callback function syncronous or asyncronous `returns` a table containing all the items in the inventory ```lua theme={null} exports.vorp_inventory:getCustomInventoryItems(invid, callback) ``` ### Setters remove item from custom inventory inventory id item name amount of item item crafted id callback function syncronous or asyncronous `returns` true if the item was successfully removed ```lua theme={null} exports.vorp_inventory:removeItemFromCustomInventory(invid,itemName,callback) ``` update item in custom inventory inventory id item id metadata to update amount of item callback function syncronous or asyncronous `returns` true if the item was successfully updated ```lua theme={null} exports.vorp_inventory:updateCustomInventoryItem(invId, item_id, metadata, amount, callback) ``` add items to custom inventory inventory id items to add charidentifier of the owner of the storage if custom inv is not shared , if its shared can be any characteridentifer callback function syncronous or asyncronous `returns` true if the items were successfully added ```lua theme={null} exports.vorp_inventory:addItemsToCustomInventory(invid, items, charid,callback) ``` if in registerCustomInventory you set whitelistItems true then use this export to set which items are whitelisted and their amount inventory id item name item limit callback function syncronous or asyncronous `returns` true if the limit was successfully set ```lua theme={null} exports.vorp_inventory:setCustomInventoryItemLimit(invId, item, limit, callback) ``` ### Getters get custom inventory weapons inventory id callback function syncronous or asyncronous `returns` a table containing all the weapons in the inventory ```lua theme={null} exports.vorp_inventory:getCustomInventoryWeapons(invid, callback) ``` get custom inventory weapon count inventory id weapon name callback function syncronous or asyncronous `returns` the amount of weapons in the inventory ```lua theme={null} exports.vorp_inventory:getCustomInventoryWeaponCount(invid,weaponName,callback) ``` ### Setter remove weapon from custom inventory by weapon id inventory id weapon id callback function syncronous or asyncronous `returns` true if the weapon was successfully removed ```lua theme={null} exports.vorp_inventory:removeCustomInventoryWeaponById(invId, weapon_id, callback) ``` remove weapon from custom inventory inventory id weapon name callback function syncronous or asyncronous `returns` true if the weapon was successfully removed ```lua theme={null} exports.vorp_inventory:removeWeaponFromCustomInventory(invid,weaponName,callback) ``` add weapons to custom inventory inventory id `{name: string, serial_number: string?, custom_label: string?, custom_desc: string?, components: table?}` charidentifier of the owner of the storage if custom inv is not shared , if its shared can be any characteridentifer callback function syncronous or asyncronous `returns` true if the weapons were successfully added ```lua theme={null} exports.vorp_inventory:addWeaponsToCustomInventory(invid, weapons, charid,callback) ``` set custom inventory whitelisted weapons, if in registerCustomInventory you set whitelistWeapons true then use this export to set which weapons are whitelisted and their amount inventory id weapon name weapon limit callback function syncronous or asyncronous `returns` true if the limit was successfully set ```lua theme={null} exports.vorp_inventory:setCustomInventoryWeaponLimit(invId, weapon, limit, callback) ``` ### Getters check if inventory is registered inventory id callback function syncronous or asyncronous `returns` true if the inventory is registered ```lua theme={null} exports.vorp_inventory:isCustomInventoryRegistered(id, callback) ``` add permissions using charids inventory id charid state ```lua theme={null} exports.vorp_inventory:AddCharIdPermissionTakeFromCustom(id,charid,state) ``` add permissions using charids inventory id charid state ```lua theme={null} exports.vorp_inventory:AddCharIdPermissionMoveToCustom(id,charid,state) ``` get cached inventory slots inventory id callback function syncronous or asyncronous ```lua theme={null} exports.vorp_inventory:getCustomInventorySlots(invId,callback) ``` ### Setters delete custom inventory from data base and cache inventory id ```lua theme={null} exports.vorp_inventory:deleteCustomInventory(invId) ``` register custom inventory `{ id:string, name:string, limit:number, acceptWeapons:boolean, shared:boolean, ignoreItemStackLimit:boolean, whitelistItems:boolean, UsePermissions:boolean, UseBlackList:boolean, whitelistWeapons:boolean,webhook:string }` ```lua theme={null} exports.vorp_inventory:registerInventory(data) ``` add permissions to move item to inventory by job and grade inventory id job name job grade ```lua theme={null} exports.vorp_inventory:AddPermissionMoveToCustom(invId, jobName, jobgrade) ``` add permissions to take item from inventory by job and grade inventory id job name job grade ```lua theme={null} exports.vorp_inventory:AddPermissionTakeFromCustom(invId, jobName, jobgrade) ``` black list items or weapons inventory id item name | weapon name ```lua theme={null} exports.vorp_inventory:BlackListCustomAny(invId, item) ``` remove inventory from session inventory id ```lua theme={null} exports.vorp_inventory:removeInventory(invId) ``` update inventory slots inventory id inventory slots ```lua theme={null} exports.vorp_inventory:updateCustomInventorySlots(invId, slots) ``` open inventory main or secondary The player id inventory id ```lua theme={null} exports.vorp_inventory:openInventory(source, invId) ``` close inventory main or secondary The player id inventory id ```lua theme={null} exports.vorp_inventory:closeInventory(source, invId) ``` open player inventory `{ source:int, target:int, title:string, blacklist:table, itemsLimit:table, timeout:number }` ```lua theme={null} local data = { source = source, target = target, title = "Search inventory", blacklist = { -- OPTIONAL water = true, -- item name or weapon name }, itemsLimit = { -- OPTIONAL weapons = { itemType = "item_weapon", limit = 1 }, -- how many weapons user is allowed to take items = { itemType = "item_standard", limit = 2 }, -- how many items user is allowed to take }, timeout = 60, -- OPTIONAL in seconds , if enabled when user reaches limits then a timeout is applied so player cant steal for that amount of time if removed then once limit reached only after restart they can steal again } exports.vorp_inventory:openPlayerInventory(data) ``` *** ## Events Server Side only Listen to when an item is used ```lua theme={null} AddEventHandler("vorp_inventory:Server:OnItemUse",function(data) local source = data.source local itemName = data.item.name local itemMetadata = data.item.metadata end) ``` Listen to when an item is created in player inventory ```lua OnItemCreated theme={null} AddEventHandler("vorp_inventory:Server:OnItemCreated",function(data,source) -- data.count, data.name, data.metadata end) ``` Listen to when an item is removed from player inventory ```lua OnItemRemoved theme={null} AddEventHandler("vorp_inventory:Server:OnItemRemoved",function(data,source) -- data.count , data.name , data.metadata end) ``` Listen to when an item is taken from custom inventory ```lua OnItemTakenFromCustomInventory theme={null} AddEventHandler("vorp_inventory:Server:OnItemTakenFromCustomInventory", function(item, invId, source) -- item.amount , item.name, item.id, item.metadata end) ``` Listen to when an item is moved to custom inventory ```lua OnItemMovedToCustomInventory theme={null} AddEventHandler("vorp_inventory:Server:OnItemMovedToCustomInventory", function(item, invId, source) -- item.amount , item.name, item.id, item.metadata end) ``` Listen for inventory state change `(opens or closes)` including custom inventories ```lua OnInvStateChange theme={null} AddEventHandler("vorp_inventory:Client:OnInvStateChange",function(boolean) print(boolean) end) ``` Block player inventory from server or client side ```lua OnInvBlock server theme={null} TriggerClientEvent("vorp_inventory:blockInventory", player_id, true or false) ``` ```lua OnInvBlock client theme={null} TriggerEvent("vorp_inventory:blockInventory", true or false) ``` Client Side only Listen to when a weapon is equipped ```lua onWeaponEquipped theme={null} AddEventHandler("vorp_inventory:onWeaponEquipped", function(components, weaponId, name, isDual, defaultAttachments) -- components: table of the equipped components, weaponId: weapon id, name: weapon name, isDual: boolean, defaultAttachments: table end) ``` Listen to when a component is added to a weapon ```lua componentAdded theme={null} AddEventHandler("vorp_inventory:componentAdded", function(weaponId, component, category) -- weaponId: weapon id, component: component name, category: slot category end) ``` Listen to when a component is removed from a weapon ```lua componentRemoved theme={null} AddEventHandler("vorp_inventory:componentRemoved", function(weaponId, component, category) -- weaponId: weapon id, component: component name, category: slot category end) ``` ## Statebags contains data from the current weapon used in the inventory or last weapon used. client side ```lua GetEquippedWeaponData theme={null} local key = string.format("GetEquippedWeaponData_%d",weaponHash) local data = LocalPlayer.state[key] local serial = data.serialNumber local id = data.weaponId ``` server side ```lua GetEquippedWeaponData theme={null} local key = string.format("GetEquippedWeaponData_%d",weaponHash) local data = Player(source).state[key] local serial = data.serialNumber local id = data.weaponId ``` check if inventory is active (open or closed) including custom inventories client side ```lua IsInvActive theme={null} LocalPlayer.state.IsInvActive ``` server side ```lua IsInvActive theme={null} Player(source).state.IsInvActive ``` ## Global Statebags returns timestamp from server to be used in client ```lua theme={null} local timestamp = GlobalState.TimeNow -- Get hours, minutes and seconds from timestamp local seconds = GlobalState.TimeNow % 60 local minutes = math.floor(GlobalState.TimeNow / 60) % 60 local hours = math.floor(GlobalState.TimeNow / 3600) % 24 ``` # lib Source: https://docs.vorp-core.com/api-reference/lib VORP Lib is a modular scripting library for RedM that simplifies game development by providing reusable, instance-based components with automatic cleanup. Designed specifically for VORP Core Framework, it helps developers write cleaner, more efficient scripts while eliminating common issues like memory leaks and global variable pollution This documentation is for developers who are making scripts for redm, you should also note that this is a work in progress and anything can be changed at any time until the final release. You cannot Import encrypted files like with escrow etc, only files that aren't encrypted can be imported. ## Lib usage To import modules to your script you must add the following to the script fxmanifest.lua file ```lua theme={null} shared_script "@vorp_lib/import.lua" ``` ## Module Import Only Lua files can be imported ### List of Modules this module contains methods that allows you to create entities like peds, vehicles, objects, etc this module contains methods that allows you to create various types of blips styles and map related stuff this module contains methods that allows you to create input controls this module contains methods that allows you to perform gameplay raycasts from the camera or from an entity this module contains methods that allows you to create prompts this module contains methods that allows you to register commands this module contains methods that allows you to create points enter/exit with debug options this module contains methods that allows you to create polygon, circle, or box detection zones with callbacks and debug tools this module contains methods that allows you to register game events this module contains methods that allows you to use dataview in lua this module contains methods that allows you to call to load several game assets like anim dics models etc this module contains methods that allows you to register commands for the server with permissions options and more this module contains methods that allows you to create classes with inheritance and more this module contains methods that allows you to use like switch setInterval etc this module contains methods that allows you to create formatted logs with time, level, prefix and context data ### Importing Modules Allows to import any modules from the lib, a list of modules available can be found [here](https://github.com/VORPCORE/vorp_lib/blob/main/modules.md) ```lua theme={null} local module = Import "modulename" -- no symbols local prompts = Import("prompts").Prompts -- every module has a table with the module name as the key for readability local Lib = Import "prompts" local Prompts = Lib.Prompts -- [[@as PROMPTS]] -- for intellisense ``` Allows to import any files from the script you are currently in, must always start with `.` or `/` to get the desired path to the file ```lua theme={null} local module = Import "/filename" local module = Import "/folder/filename" ``` Allows to import any files from other scripts, must always start with `@` then use the special characters `/` or `.` to get the desired path to the file ```lua theme={null} local module = Import "@script_name/filename" local module = Import "@script_name/folder/filename" ``` ### Import Usage The module name to import ```lua theme={null} local module = Import "module" ``` The module name to import ```lua theme={null} local module = Import ({"module", "module2", "module3"}) local prompts = module.Prompts ``` The module names to import ```lua theme={null} local module = Import ({"module", "/internal/filename", "@script_name/external/filename"}) local prompts = module.Prompts local commands = module.Commands ``` ## Modules Usage The following modules are available in the lib, you can import them using the `Import` function, documentation for each module will be available below ### Entities This module is used to create entities like peds, vehicles, objects, etc, it has a baseclass for all entities and sub classes for each entity type all creations are instanced objects every creation will have its own instance and wont be shared with other scripts since its imported to your script when you restart your resource the entities will be removed for easy development it has a entity tracker if you wish to track the entities from other scripts (see `collector` file) for exports This is the baseclass for (peds, vehicles, objects) subclasses you can use these methods bellow or use directly the natives Get the handle of the entity, this is a unique identifier for the entity Get the model of the entity Get the position of the entity Get the heading of the entity Get the rotation of the entity Get the networked id of the entity if the entity created had `IsNetworked = true` can use `vector3` or `vector4` to just set heading by passing a table with w `{w = 0.0}` Delete the entity * This sub class is used to create peds (inherits from `Entity` base class ) these are instanced objects every creation will have its own instance * Below are the methods available for the ped class create a ped The model of the ped The position of the ped if the ped is networked if the ped is a script host ped unknown unknown these are optional parameters `PlaceOnGround = boolean`, `OutfitPreset = integer` The function to will be called when the ped is created The function to will be called when the ped is deleted ```lua theme={null} -- Example -- Import the entities module local Entity = Import 'entities' --[[@as ENTITY]] local ped = Entity.Ped:Create({ Model = 'A_C_COW', Pos = vector4(0, 0, 0, 0), IsNetworked = true, Options = { PlaceOnGround = true, OutfitPreset = 0, }, OnCreate = function(self) print('Ped created use your own logic here, handle: ', self:GetHandle()) end, OnDelete = function(handle, netid) print('Ped deleted use your own logic here, handle: ', handle, 'netid: ', netid) end }) -- methods you can use local handle = ped:GetHandle() ped:Delete() ``` * This sub class is used to create vehicles (inherits from `Entity` base class ) these are instanced objects every creation will have its own instance * Below are the methods available for the vehicle class The model of the vehicle The position for the vehicle if the vehicle is networked if the vehicle is a script host vehicle create draft animals if true unknown `PlaceOnGround`, `Seat = { Ped = ped, Index = -1}` The function to call when the vehicle is created The function to call when the vehicle is deleted ```lua theme={null} -- Example -- Import the entities module local Entity = Import 'entities' --[[@as ENTITY]] local vehicle = Entity.Vehicle:Create({ Model = 'wagon01x', Pos = vector4(0, 0, 0, 0), IsNetworked = true, Options = { PlaceOnGround = true, Seat = { -- optional Ped = ped, -- entity Index = -1, -- -1 for driver, 0 for passenger, 1 for passenger, 2 for passenger, etc } }, OnCreate = function(self) print('Vehicle created use your own logic here, handle: ', self:GetHandle()) end, OnDelete = function(self) print('Vehicle deleted use your own logic here, handle: ', self:GetHandle()) end }) local handle = vehicle:GetHandle() vehicle:Delete() ``` * This sub class is used to create objects (inherits from `Entity` base class ) these are instanced objects every creation will have its own instance * Below are the methods available for the object class The model of the object The position for the object if the object is networked if the object is a script host object if the object is dynamic `PlaceOnGround = boolean`, `Rot = vector3`,`Rot.Order = integer`, `Rot.P5 = boolean` The function will be called when the object is created The function will be called when the object is deleted ```lua theme={null} -- Example -- Import the entities module local Entity = Import 'entities' --[[@as ENTITY]] local object = Entity.Object:Create({ Model = 'prop_paper_bag_01', Pos = vector4(0, 0, 0, 0), IsNetworked = true, Options = { -- optional PlaceOnGround = true, Rot = { Pos = vector3(0, 0, 0), Order = 2, P5 = true, } }, OnCreate = function(self) print('Object created use your own logic here, handle: ', self:GetHandle()) end, OnDelete = function(self) print('Object deleted use your own logic here, handle: ', self:GetHandle()) end }) local handle = object:GetHandle() object:Delete() ``` ### Map The map module is used to create blips for now but will be expanded to include more map related features when you restart your resource the blips will be removed for easy development This is the baseclass for blips, you can use these methods below or use directly the natives Get the `handle` of the blip Get the `color value's` for blip colors, can be a `single color string` or `table of color strings` Returns the `color value's` corresponding to the `color name's` ```lua theme={null} -- single string or multiple colors can be requested just for ease of use local blue, red, yellow = Map.Blips:GetBlipColor({ 'blue', 'red', 'yellow' }) blip:AddModifierColor(blue) -- or string "blue" ``` Remove/Delete the blip Set the name/label of the blip Set the coordinates for the blip (pos.x, pos.y, pos.z) Set the style for the blip, see [blip style](https://github.com/femga/rdr3_discoveries/tree/master/useful_info_from_rpfs/blip_styles) Set the sprite icon for the blip. see [blip sprite](https://github.com/femga/rdr3_discoveries/tree/master/useful_info_from_rpfs/textures/blips) Add a modifier for the blip see [blip modifier](https://github.com/femga/rdr3_discoveries/tree/master/useful_info_from_rpfs/blip_modifiers) Remove a modifier from the blip see [blip modifier](https://github.com/femga/rdr3_discoveries/tree/master/useful_info_from_rpfs/blip_modifiers) Add a color modifier for the blip, use the `GetBlipColor` method to get the color value's if needed create a blip The type of blip to create: `entity`, `coords`, `area`, `radius` each will have specific params The blip sprite/hash to use, see [blip sprite hash](https://github.com/femga/rdr3_discoveries/tree/master/useful_info_from_rpfs/blip_styles) Required for 'entity' type - the entity handle to attach the blip to Required for 'coords', 'area', and 'radius' types - the position for the blip Required for 'area' type - the scale dimensions (x, y, z) Required for 'radius' type - the radius size (defaults to 0.5) Optional parameter for 'area' type (defaults to 0) Optional parameters for blip appearance: `sprite = integer|string`, `name = string`, `style = integer|string`, `modifier = integer|string`, `color = string` The function that will be called when the blip is created ```lua theme={null} -- Example -- Import the blips module local Map = Import 'blips' --[[@as BLIPS]] local blip = Map.Blips:Create('radius', { -- type can be entity, coords, area, radius Entity = ped, -- if type is entity, you need to provide a handle Pos = vector3(2865.88, 475.38, 66.09), -- position Radius = 50.0, -- if type is radius or area P7 = 0, -- optional default is 0 Blip = 1673015813, -- blip hash the style of the blip Scale = vector3(1.0, 1.0, 1.0), -- for type area only Options = { -- optional sprite = 1, --string or integer if type is entity or coords name = 'Test', modifier = 'BLIP_MODIFIER_MP_COLOR_1', -- int or string color = 'blue', -- internal color name }, OnCreate = function(self) print('Created', self:GetHandle()) local blue, red, yellow = self:GetBlipColor({ 'blue', 'red', 'yellow' }) self:AddModifier(red) end }) local handle = blip:GetHandle() blip:Remove() ``` ### Inputs this module is used to create input controls for your resource, single or multiple , without the user having to create loops and a bunch of code all creations are instanced objects every creation will have its own instance and wont be shared with other scripts since its imported to your script when you restart your resource the inputs will be removed for easy development use these methods below to manage input controls Destroy the input instance and stop all processing Remove a specific key from multiple inputs or if single input , destroys the input Pause the input processing without destroying the instance Resume the input processing after being paused Update custom parameters for the input if needed Required if using multiple inputs - specifies which input to update Start the input processing if is not running, useful when you set state to false and start this when player is near something or character is selected register an input or multiple inputs The type of input: `Press`, `Hold`, `Release` The key to listen for (e.g., `E`, `W`) these are predefined keys, you can use any hash or string [controls](https://github.com/femga/rdr3_discoveries/tree/master/Controls) Function called when input is triggered - receives (instance, customParams) If true, input will start automatically after registration, useful when you set state to false and start this when player is near something or character is selected ```lua theme={null} -- Example -- Import the inputs module local controls = Import 'inputs' --[[@as INPUTS]] -- Multiple input support local inputs = { { inputType = "Press", key = "E" }, { inputType = "Hold", key = "W" }, { inputType = "Release", key = "S" }, } local input = controls.Inputs:Register(inputs,function(input, customParams) if input.key == "E" then print("E was pressed") elseif input.key == "W" then print("W is being held") elseif input.key == "S" then print("S was released") end end, true) -- auto start on register input:Destroy() ``` ### Raycast this module is used to perform line-of-sight shape tests from the gameplay camera or from an entity it accepts `vector3` values or `{ x, y, z }` tables for coordinates and returns a structured result table with hit data when a flag is missing or invalid, the module falls back to `World` ```lua theme={null} local Raycast = Import('raycast').Raycast --[[@as RAYCAST]] ``` Available flag names: * `World` * `Vehicles` * `Peds` * `Ragdolls` * `Objects` * `Pickups` * `Glass` * `Rivers` * `Foliage` * `All` Cast a ray from the gameplay camera forward Distance of the raycast, defaults to `10.0` Flag name to use for the shape test, invalid or missing values fallback to `World` Entity handle to ignore, defaults to `PlayerPedId()` Optional offset added to the camera coordinates Shape test trace type, defaults to `7` Max wait time in milliseconds for the result, defaults to `1000` Delay between polling attempts, defaults to `0` Returns a result table with `hit`, `coords`, `normal`, `entity`, `material`, `state`, `didHit` and `handle` ```lua theme={null} local Raycast = Import('raycast').Raycast --[[@as RAYCAST]] local result = Raycast:FromCamera(15.0, 'World') if result.hit then print('Hit coords:', result.coords) print('Hit entity:', result.entity) end ``` Cast a ray from an entity forward using its current forward vector Entity handle to cast from, the entity must exist Distance of the raycast, defaults to `10.0` Flag name to use for the shape test, invalid or missing values fallback to `World` Entity handle to ignore, defaults to the provided entity Optional offset added to the entity coordinates before casting Shape test trace type, defaults to `7` Max wait time in milliseconds for the result, defaults to `1000` Delay between polling attempts, defaults to `0` Returns a result table with `hit`, `coords`, `normal`, `entity`, `material`, `state`, `didHit` and `handle` ```lua theme={null} local Raycast = Import('raycast').Raycast --[[@as RAYCAST]] local horse = GetMount(PlayerPedId()) if horse ~= 0 then local result = Raycast:FromEntity(horse, 8.0, 'Peds', horse) if result.hit then print('Entity raycast hit:', result.entity) end end ``` Result fields returned by `FromCamera` and `FromEntity` True when the shape test hit something Native shape test state Shape test handle returned by the native Raw native hit result Hit coordinates Surface normal Hit entity handle, or `0` if no entity was hit Material hash returned by `GetShapeTestResultIncludingMaterial` ### Prompts this module is used to create prompts with coordinate-based activation, multiple prompts can be grouped together and managed as one unit all creations are instanced objects every creation will have its own instance and wont be shared with other scripts since its imported to your script when you restart your resource the prompts will be removed for easy development use these methods below to manage prompts The key identifier of the specific prompt, its whatever you set in the register Get the handle of a specific prompt by key The key identifier of the specific prompt, its whatever you set in the register Get the group ID of a specific prompt The key identifier of the specific prompt, its whatever you set in the register Get the group label of a specific prompt Check if the prompt you registered is currently running New label text for the prompt The key identifier of the prompt to update, its whatever you set in the register New label text for the entire prompt group Whether the prompt should be enabled or disabled The key identifier of the prompt to update, its whatever you set in the register Whether the prompt should be visible or hidden The key identifier of the prompt to update, its whatever you set in the register Number of times the key must be mashed The key identifier of the prompt to update, its whatever you set in the register The key identifier of the prompt to set to indefinite mash mode, its whatever you set in the register Start the prompt system if is not running, useful when you set state to false and start this when player is near something or character is selected Pause the prompt system without destroying it Resume the prompt system after being paused The key identifier of the specific prompt to remove if multiple, if single will destroy Destroy the entire prompt system register prompts The center coordinates where prompts will be active Activation radius from coords (defaults to 2.0) The group label shown at the top of the prompt group Sleep time when not in range (defaults to 700ms) Optional marker configuration: `type`, `color = {r,g,b,a}`, `distance`, `scale = {x,y,z}` can be used for debug as well Array of prompt objects with: `type`, `key`, `label`, `mode`, and mode-specific parameters Types: `Press`, `Hold`, `Release`, `Standard`, `Pressed`, `Released`, `Mash` Modes: `Hold` (holdTime), `Timed` (timedMode), `Mash` (mashCount), `Standard` (releaseMode), `Standardized` (eventHash) Function called when any prompt is triggered - receives `(prompt, index, instance, value)`. `value` is the current entry from the `locations` table, which avoids having to look it up again manually. If true, prompts will start automatically after registration (defaults to false) useful when you set state to false and start this when player is near something or character is selected ```lua theme={null} -- Example -- Import the prompts module local Game = Import 'prompts' --[[@as PROMPTS]] local data = { locations = { { -- index 1 coords = vector3(2868.43, 480.19, 65.02), -- distance based prompts label = 'group label', -- group label distance = 2.0, -- distance from coords marker = { -- optional marker type = 0x94FDAE17, color = { r = 0, g = 255, b = 0, a = 96 }, distance = 4.0, scale = { x = 2.0, y = 2.0, z = 0.5 }, } } }, sleep = 700, -- sleep time when not in range prompts = { -- group prompts or single prompt { type = 'Press', key = 'G', label = 'press', mode = 'Standard' }, { type = 'Hold', key = 'E', label = 'hold', mode = 'Hold', holdTime = 3000 } } } local prompt = Game.Prompts:Register(data, function(prompt, index, self, location) -- location is the current entry from data.locations[index] if index == 1 and location.label == 'group label' then if prompt.key == 'G' then print('G pressed') elseif prompt.key == 'E' then print('E held for 3 seconds') end end end, true) -- auto start on register prompt:Destroy() -- the lib it self will destroy any prompt on script restart ``` ### Commands this module is used to register client-side/server-side commands with permissions, suggestions, and argument validation all creations are instanced objects every creation will have its own instance and wont be shared with other scripts since its imported to your script when you restart your resource the commands will be removed for easy development, if a command is active and suggestion hasnt been marked to add on register, it will be added on character selected automatically use these methods below to manage command controls Removes the command and its suggestion from chat Adds command suggestion to chat Removes the command suggestion from chat Pause the command without removing it (temporarily disables the command) Resume the command after being paused Completely destroy the command instance and clean up Whether to add chat suggestion when registering the command, use this only on runtime, by default when player selects character suggestion is added automatically Start/activate the command its called when the command is executed its called when the command has errors register a command The command name (without the / prefix) Chat suggestion configuration with Description and Arguments array Permission configuration with Ace group settings Function called when command executes - receives (args, rawCommand, instance) Function called on command errors - receives error type string If true, command starts automatically after registration, useful when you set state to false and start this when player is near something or character is selected ```lua theme={null} -- Example -- Import the commands module local Commands = Import 'commands' --[[@as COMMANDS]] local command = Commands.Command:Register("mycommand", { Suggestion = { -- optional Description = "My custom command description", Arguments = { -- if type is number or integer, it will be converted to a number -- if type is message, it will give it as a message { name = "playerId", help = "Target player ID", type = "integer", required = true }, { name = "amount", help = "Amount value", type = "number", required = true }, { name = "message", help = "Optional message", type = "message"} } }, Permissions = { -- optional Ace = "group.admin" -- Restrict to admin group, or remove for public command }, OnExecute = function(args, rawCommand, instance) print("Command executed with args:", json.encode(args)) print("Player ID:", args[1]) -- integer type print("Amount:", args[2]) -- number type print("Message:", args[3]) -- message type (remaining args combined) end, OnError = function(errorType) if errorType == 'missing_arguments' then print('Usage: /mycommand [message]') elseif errorType == 'missing_permission' then print('You do not have permission to use this command') elseif errorType == 'command_active' then print('Command is currently paused') end end }, true) -- Auto-start -- Control methods command:Start(true) -- Start and add suggestion if not have been added yet command:Destroy() -- Clean up completely -- Argument types: -- "integer" - converts to number (whole numbers) -- "number" - converts to number (decimals allowed) -- "message" - combines remaining arguments into string -- (no type) - keeps as string -- Error types: -- "missing_arguments" - Required argument not provided -- "missing_permission" - User lacks required permissions -- "command_active" - Command is paused -- "missing_target" - Target not found (if applicable) ``` use these methods below to manage server command controls Remove the command, its suggestion from all clients, and ACE permissions The player source ID to send suggestion to Add command suggestion to specific player's chat The player source ID to remove suggestion from Remove command suggestion from specific player's chat Pause the command without removing it (temporarily disable) Resume the command after being paused Completely destroy the command instance and clean up Start/activate the command and register ACE permissions if configured Set or update the callback function called when command executes Set or update the callback function called when command has errors register a server command The command name (without the / prefix) Chat suggestion configuration with Description and Arguments array * Description: The description of the command * Arguments: The arguments of the command * name: The name of the argument * help: The help of the argument * type: The type of the argument if type is number or integer, it will be converted to a number if type is message, it will give it as a message * required: Whether the argument is required ```lua theme={null} Suggestion = { -- optional Description = "Admin command with complex permissions", Arguments = { { name = "playerId", help = "Target player ID", type = "integer", required = true }, { name = "amount", help = "Amount value", type = "number", required = true }, { name = "message", help = "Optional message", type = "message" } } } ``` Advanced permission configuration with Ace, Jobs, Groups, and CharIds * Ace: ACE permission (overrides others) leave false if you dont want to use ace permissions * Groups: Group permissions with users (DB users table) and characters (DB characters table) sections * Jobs: Job-based permissions with optional grade restrictions * CharIds: Specific character ID based permissions ```lua theme={null} Permissions = { -- optional Ace = "group.admin", -- ACE permission (overrides others) leave false if you dont want to use ace permissions Groups = { -- optional users = { admin = true, moderator = true }, characters = { gang_leader = true } }, Jobs = { -- optional Police = { -- jobname [0] = false, [1] = true }, Sheriff = true -- All ranks allowed }, CharIds = { -- optional [123] = true, -- Specific character ID [456] = true }, } ``` Function called when command executes - receives (source, args, rawCommand, instance) Function called on command errors - receives error type string If true, command starts automatically after registration (defaults to false) ```lua theme={null} -- Example -- Import the server commands module local LIB = Import 'commands' --[[@as COMMANDS]] local command = LIB.Command:Register("commandName", { Suggestion = { -- optional Description = "Admin command with complex permissions", Arguments = { { name = "playerId", help = "Target player ID", type = "integer", required = true }, { name = "amount", help = "Amount value", type = "number", required = true }, { name = "message", help = "Optional message", type = "message" } } }, Permissions = { -- optional Ace = "group.admin", -- ACE permission (overrides others) leave false if you dont want to use ace permissions Jobs = { -- optional Police = { -- jobname [0] = false, -- Rank 0 not allowed [1] = true, -- Rank 1+ allowed }, Sheriff = true -- All ranks allowed }, Groups = { -- optional users = { admin = true, moderator = true }, characters = { gang_leader = true } }, CharIds = { -- optional [123] = true, -- Specific character ID [456] = true } }, OnExecute = function(source, args, rawCommand, instance) print("Command executed by source:", source) print("Player ID:", args[1]) -- player type (validated) print("Amount:", args[2]) -- number type print("Message:", args[3]) -- message type end, OnError = function(errorType) if errorType == 'missing_arguments' then print('Usage: /admincommand [message]') elseif errorType == 'missing_permission' then print('You do not have permission to use this command') elseif errorType == 'missing_job' then print('You do not have the required job') elseif errorType == 'missing_grade' then print('You do not have the required job rank') elseif errorType == 'missing_group' then print('You do not have the required group') elseif errorType == 'missing_character' then print('Your character is not authorized') elseif errorType == 'missing_user' then print('User not found or console command not supported') elseif errorType == 'command_active' then print('Command is currently paused') end end }, true) -- Auto-start -- Control methods command:Destroy() -- Clean up completely -- Server-specific features: -- - Automatic ACE permission management -- - Complex job/grade validation -- - Character and user group permissions -- - Per-player suggestion management -- - Console command restriction (source = 0) -- Error types (additional server-side): -- "missing_user" - User not found or console command -- "missing_job" - Player doesn't have required job -- "missing_grade" - Player doesn't have required job rank -- "missing_group" - Player doesn't have required group -- "missing_character" - Character not authorized -- "missing_state" - State validation failed -- Permission priority: -- 1. ACE permissions (highest) all others will be ignored -- 2. Job permissions -- 3. Group permissions -- 4. Character ID permissions ``` ### Points this module is used to create coordinate-based enter/exit areas with radius detection, multiple points can be registered and managed independently all creations are instanced objects every creation will have its own instance and wont be shared with other scripts since its imported to your script when you restart your resource the points will be removed for easy development use these methods below to manage points The unique identifier of the point to check Returns true if the point is active and not deactivated The unique identifier of the point to check Returns true if the player is currently inside the point radius The unique identifier of the point to check Returns true if the player is currently outside the point radius The unique identifier of the point to update New point data to replace the existing point configuration The unique identifier of the point to remove Removes the specified point from the instance The unique identifier of the point to pause Deactivates the specified point without removing it The unique identifier of the point to resume Reactivates a previously paused point Start the point system if not already running, begins monitoring player position Pause the entire point system without destroying it Resume the point system after being paused Destroy the entire point instance and clean up all points Enable visual debug markers for points that have debug enabled register coordinate-based points for enter/exit detection Array of point configurations, each point must have unique id, center coordinates, and radius * id: Unique identifier for the point (string/integer) * center: Point center coordinates (vector3) * radius: Detection radius around center (number) * wait: Check interval in milliseconds (optional, defaults to 500) * debug: Enable visual debug marker (optional, boolean) * deActivate: If true, point starts inactive and must be manually activated (optional, boolean) ```lua theme={null} -- supports multiple points Arguments = { { id = 'bank_entrance', center = vector3(2843.49, 474.49, 64.03), radius = 15.0, wait = 500, debug = true, deActivate = false, } } ``` Function called when player enters any point - receives (point, distance) Function called when player exits any point - receives (point, distance) If true, point system starts automatically after registration other wise use the Start method to start the point system ```lua theme={null} -- Example -- Import the points module local GamePoints = Import 'points' --[[@as POINTS]] local points = GamePoints.Points:Register({ Arguments = { { id = 'bank_entrance', -- unique identifier center = vector3(2843.49, 474.49, 64.03), -- center coordinates radius = 15.0, -- detection radius wait = 500, -- check interval (ms) debug = true, -- show debug marker deActivate = true, -- start active? remove to start active }, { id = 'shop_door', center = vector3(2884.03, 484.19, 66.73), radius = 10.0, wait = 300, debug = true, }, }, OnEnter = function(point, distance) print("Entered point:", point.id, "Distance:", distance) if point.id == 'bank_entrance' then print("Welcome to the bank!") elseif point.id == 'shop_door' then print("Welcome to the shop!") end end, OnExit = function(point, distance) print("Exited point:", point.id, "Distance:", distance) if point.id == 'bank_entrance' then print("Left the bank area") elseif point.id == 'shop_door' then print("Left the shop area") end end }, true) -- Auto-start -- Control methods points:PausePoint('shop_door') -- Pause specific point points:ResumePoint('shop_door') -- Resume specific point points:RemovePoint('bank_entrance') -- Remove specific point -- Check point status local isActive = points:IsPointActive('shop_door') local isInside = points:IsPointInside('shop_door') local isOutside = points:IsPointOutside('shop_door') -- System control points:Pause() -- Pause entire system points:Resume() -- Resume entire system points:Destroy() -- Clean up completely ``` ### PolyZones this module is used to create polygon, circle, or box shaped detection zones with height filtering, debug rendering, and enter/inside/exit callbacks all creations are instanced objects every zone instance is private to the script that imports it and will be removed automatically when the resource restarts use these methods below to register and manage advanced zone shapes Returns the unique identifier assigned to the zone (auto-generated when not provided) Returns the zone type `poly`, `circle`, or `box` Returns true when the zone polling loop is currently running Returns true if the local player is currently inside the zone Replaces the `onEnter` callback (receives zone instance and player coords) Replaces the `onExit` callback (receives zone instance and player coords) Replaces the `onInside` callback that runs every tick while inside Updates polygon points (`vector3` list) and recalculates bounds, available for polygon zones only Updates circle center position Updates circle radius, available for circle zones only Updates box center position Updates box length, available for box zones only Updates box width, available for box zones only Optional new heading in degrees for the box zone Sets the minimum Z (height) allowed before the zone considers the player outside Sets the maximum Z (height) allowed before the zone considers the player outside Enables or disables debug drawing (auto-starts debug loop when the zone is running) Sets polling interval in milliseconds while the player is outside the zone (defaults to 200) Sets polling interval in milliseconds while the player stays inside (defaults to 1) Starts the background thread that evaluates the zone, automatically launches debug rendering when enabled Temporarily stops the zone without clearing callbacks or shape data Restarts a paused zone and resumes detection Disables the zone and clears its configuration (instance should be discarded afterwards) register polygon, circle, or box zones with callbacks and optional auto-start Zone configuration table: * id: Optional string or integer unique identifier (`polyzone_` when omitted) * type: Zone type `poly`, `circle`, or `box` (defaults to `poly`, case-insensitive) * sleep: Interval in milliseconds while outside the zone (default 200) * sleepInside: Interval in milliseconds while inside the zone (default 1) * padding: Extra meters added to the bounding radius for early rejection (default 1.5) * debug: Enable debug drawing for the zone (boolean) * minZ / maxZ: Optional height bounds restricting detection * onEnter(zone, coords): Callback fired when the player enters the zone * onInside(zone, coords): Optional tick callback executed while the player stays inside * onExit(zone, coords): Callback fired when the player leaves the zone * polygon: provide `points` with at least 3 vector3 values and optional `center` * circle: provide `center` vector3 and `radius` number (or `size` table with same values) * box: provide `center` vector3, `length` and `width` numbers, optional `heading` (degrees) or `size` table `{ x, y }` When true the zone starts immediately after registration (defaults to false, call `Start()` manually otherwise) Returns the zone instance so you can control it with the methods above ```lua theme={null} local PolyZones = Import('polyzones').PolyZones local stables = PolyZones:Register({ id = 'valentine_stables', type = 'poly', points = { vector3(-546.83, -600.65, 42.23), vector3(-548.62, -607.16, 42.32), vector3(-554.35, -605.86, 42.31), vector3(-552.20, -599.25, 42.27), vector3(-554.13, -594.14, 42.19), }, minZ = 41.8, maxZ = 45.0, debug = true, onEnter = function(zone, coords) print(('Entered %s at %.2f %.2f'):format(zone:GetId(), coords.x, coords.y)) end, onExit = function(zone) print('Left zone', zone:GetId()) end, }, true) ``` ```lua theme={null} local PolyZones = Import('polyzones').PolyZones local campfire = PolyZones:Register({ id = 'campfire_radius', type = 'circle', center = vector3(-567.97, -594.54, 42.51), radius = 2.5, debug = true, sleepInside = 250, onInside = function(_, coords) print(('Warming up at %.2f %.2f'):format(coords.x, coords.y)) end, onExit = function() print('Leaving the fire') end, }, true) ``` ```lua theme={null} local PolyZones = Import('polyzones').PolyZones local jailCell = PolyZones:Register({ id = 'jail_cell_a', type = 'box', center = vector3(-565.68, -605.77, 42.31), length = 4.0, width = 3.0, heading = 90.0, minZ = 41.5, maxZ = 44.0, }, true) jailCell:SetDebug(true) jailCell:SetTickRates(100, 10) ``` Zone instance returned by `Register` Stops the zone, removes it from the manager, and cleans it up ```lua theme={null} local PolyZones = Import('polyzones').PolyZones local zone = PolyZones:Register({ id = 'temp_zone', type = 'circle', center = vector3(-100.0, 120.0, 40.0), radius = 3.0, }, true) PolyZones:Destroy(zone) ``` ### Events this module is used to register game event listeners that can capture and process native game events with automatic data parsing all creations are instanced objects every creation will have its own instance and wont be shared with other scripts since its imported to your script when you restart your resource the event listeners will be removed for easy development use these methods below to manage event listeners Start the event listener and begin monitoring for the registered event Pause the event listener without destroying the instance Resume the event listener after being paused Destroy the event listener instance and clean up Enable or disable developer mode for debugging events Optional events to ignore when in dev mode (can be event name string, hash) When enabled, logs all events in the group. Use eventsToIgnore to filter out noise. ```lua theme={null} -- Enable dev mode and ignore specific events event:DevMode(true, {"EVENT_PED_CREATED", "EVENT_PED_DESTROYED"}) -- Enable dev mode for all events event:DevMode(true) -- Disable dev mode event:DevMode(false) ``` register a game event listener The game event name (string) or hash (integer) to listen for The event group to monitor: `0` for SCRIPT\_EVENT\_QUEUE\_AI or `1` for SCRIPT\_EVENT\_QUEUE\_NETWORK * **SCRIPT\_EVENT\_QUEUE\_AI (0)**: For AI and NPC related events * **SCRIPT\_EVENT\_QUEUE\_NETWORK (1)**: For network and player related events Function called when the event triggers - receives parsed event data or nothing if event has no data If true, event listener starts automatically after registration, otherwise use Start method ```lua theme={null} -- Example -- Import the events module local Game = Import 'events' --[[@as EVENTS]] -- Register event with automatic data parsing local event = Game.Events:Register('EVENT_PED_CREATED', 0, function(data) print("Ped created with data:", json.encode(data, {indent = true})) end, true) -- Auto-start -- Developer mode for debugging, dont fire this events when in dev mode event:DevMode(true, {"EVENT_PED_CREATED","EVENT_VEHICLE_CREATED"}) -- Enable dev mode, ignore these events -- dev mode enables all events to be triggered -- Clean up event:Destroy() ``` ### DataView this module provides JavaScript-like DataView functionality for handling binary data in Lua with support for various data types and endianness this module is based on gottfriedleibniz's DataView implementation providing efficient binary data manipulation use these methods below to manage binary data Get the underlying binary buffer as a string Get the length of the buffer in bytes Get the current offset position within the buffer Available getter methods for reading different data types: * `GetInt8(offset, endian)` - Read 8-bit signed integer * `GetUint8(offset, endian)` - Read 8-bit unsigned integer * `GetInt16(offset, endian)` - Read 16-bit signed integer * `GetUint16(offset, endian)` - Read 16-bit unsigned integer * `GetInt32(offset, endian)` - Read 32-bit signed integer * `GetUint32(offset, endian)` - Read 32-bit unsigned integer * `GetInt64(offset, endian)` - Read 64-bit signed integer * `GetUint64(offset, endian)` - Read 64-bit unsigned integer * `GetFloat32(offset, endian)` - Read 32-bit float * `GetFloat64(offset, endian)` - Read 64-bit double * `GetString(offset, endian)` - Read null-terminated string * `GetLuaInt(offset, endian)` - Read Lua integer * `GetLuaNum(offset, endian)` - Read Lua number Byte offset from buffer start to read from Endianness: true for big-endian, false/nil for little-endian The read value, or nil if offset is out of bounds * `GetFixedString(offset, length, endian)` - Read fixed-length string * `GetFixedInt(offset, length, endian)` - Read fixed-size signed integer * `GetFixedUint(offset, length, endian)` - Read fixed-size unsigned integer Byte offset from buffer start Number of bytes to read Endianness: true for big-endian, false/nil for little-endian Byte offset to create the sub-view from Create a new DataView that shares the same buffer but with different offset Available setter methods for writing different data types: * `SetInt8(offset, value, endian)` - Write 8-bit signed integer * `SetUint8(offset, value, endian)` - Write 8-bit unsigned integer * `SetInt16(offset, value, endian)` - Write 16-bit signed integer * `SetUint16(offset, value, endian)` - Write 16-bit unsigned integer * `SetInt32(offset, value, endian)` - Write 32-bit signed integer * `SetUint32(offset, value, endian)` - Write 32-bit unsigned integer * `SetInt64(offset, value, endian)` - Write 64-bit signed integer * `SetUint64(offset, value, endian)` - Write 64-bit unsigned integer * `SetFloat32(offset, value, endian)` - Write 32-bit float * `SetFloat64(offset, value, endian)` - Write 64-bit double * `SetString(offset, value, endian)` - Write null-terminated string * `SetLuaInt(offset, value, endian)` - Write Lua integer * `SetLuaNum(offset, value, endian)` - Write Lua number Byte offset from buffer start to write to The value to write Endianness: true for big-endian, false/nil for little-endian Returns self for method chaining * `SetFixedString(offset, length, value, endian)` - Write fixed-length string * `SetFixedInt(offset, length, value, endian)` - Write fixed-size signed integer * `SetFixedUint(offset, length, value, endian)` - Write fixed-size unsigned integer Byte offset from buffer start Number of bytes for the data type The value to write Endianness: true for big-endian, false/nil for little-endian create a new binary buffer Size of the buffer to allocate in bytes Returns a new DataView instance with allocated buffer ```lua theme={null} -- Import the dataview module local Data = Import 'dataview' --[[@as DATAVIEW]] -- Create a 64-byte buffer local buffer = Data.DataView.ArrayBuffer(64) -- Write different data types buffer:SetInt32(0, 42) -- Write integer at offset 0 buffer:SetFloat32(4, 3.14159) -- Write float at offset 4 buffer:SetString(8, "Hello") -- Write string at offset 8 -- Read the data back local intValue = buffer:GetInt32(0) -- 42 local floatValue = buffer:GetFloat32(4) -- 3.14159 local stringValue = buffer:GetString(8) -- "Hello" print("Buffer length:", buffer:ByteLength()) -- 64 print("Values:", intValue, floatValue, stringValue) ``` wrap existing binary data Existing binary data string to wrap Returns a DataView instance wrapping the existing data ```lua theme={null} -- Wrap existing binary data local existingData = string.pack("i4f", 100, 2.718) local wrappedView = Data.DataView.Wrap(existingData) -- Read from wrapped data local intVal = wrappedView:GetInt32(0) -- 100 local floatVal = wrappedView:GetFloat32(4) -- 2.718 ``` create sequential data reader DataView instance to create stream from Returns a DataStream for sequential reading Available DataStream methods (automatically advance offset): * `Int8(endian, align)`, `Uint8(endian, align)` * `Int16(endian, align)`, `Uint16(endian, align)` * `Int32(endian, align)`, `Uint32(endian, align)` * `Int64(endian, align)`, `Uint64(endian, align)` * `Float32(endian, align)`, `Float64(endian, align)` * `String(endian, align)`, `LuaInt(endian, align)`, `LuaNum(endian, align)` ```lua theme={null} -- Create buffer with mixed data local buffer = Data.DataView.ArrayBuffer(32) buffer:SetInt32(0, 123) buffer:SetFloat32(4, 4.56) buffer:SetInt16(8, 789) -- Create stream for sequential reading local stream = Data.DataView.DataStream.New(buffer) -- Read sequentially (offset advances automatically) local int1 = stream:Int32() -- 123, offset now at 4 local float1 = stream:Float32() -- 4.56, offset now at 8 local int2 = stream:Int16() -- 789, offset now at 10 print("Sequential read:", int1, float1, int2) ``` ### Streaming this module provides utility functions for loading various game assets like models, animations, textures, and more with automatic cleanup and timeout handling all functions handle the loading process with proper validation and error handling, preventing common issues with asset streaming use these functions below to load various game assets with automatic cleanup Model name (string) or hash (integer) to load Optional timeout in milliseconds to automatically unload the model and free memory Loads and validates the model, throws error if invalid or fails to load within 5 seconds Texture dictionary name to load Optional timeout in milliseconds to automatically unload the texture dictionary Loads texture dictionary with validation and error handling Particle effect dictionary name to load Optional timeout in milliseconds to automatically remove the particle effect asset Loads particle effect dictionary for use with particle systems Animation dictionary name to load Optional timeout in milliseconds to automatically remove the animation dictionary Loads animation dictionary with existence validation Weapon name (string) or hash (integer) to load Unknown parameter (usually 31) Unknown parameter (usually false) Optional timeout in milliseconds to automatically remove the weapon asset Loads weapon asset with validation Move network definition name to load Optional timeout in milliseconds to automatically remove the network definition Loads move network definition for advanced movement systems Clip set name to load Optional timeout in milliseconds to automatically remove the clip set Loads animation clip set for character movement styles Coordinates where collision should be loaded Loads collision data for terrain at specified coordinates Model name or hash to load collision for Loads collision data for a specific model IPL (Interior Proxy List) name or hash to load Loads IPL for interior or map sections, warns if already loaded Position to load scene around Offset from position Radius to load scene within Unknown parameter (usually 0) Loads world area around entity - use carefully as it can cause crashes with too many MLOs import the streaming module ```lua theme={null} -- Import the streaming module local Assets = Import 'streaming' --[[@as STREAMING]] -- Use any function Assets.Streaming.LoadModel('A_C_BEAR_01') Assets.Streaming.LoadAnimDict('amb@world_human_drinking@coffee@male@idle_a') ``` ### Class this module provides a complete object-oriented programming system for Lua with classes, inheritance, private members, and automatic getters/setters supports both traditional Lua OOP patterns and modern structured approaches with automatic property management was inspired by JavaScript classes use these methods below to create classes with full OOP support Base class to inherit from, or table of initial methods/properties Optional name for the class (used in error messages) Returns a new class that can create instances with :New() ```lua theme={null} -- Import the class module local Lib = Import 'class' --[[@as CLASS]] -- Create a basic class local MyClass = Lib.Class:Create({ constructor = function(self, name) self.name = name end, getName = function(self) return self.name end }, "MyClass") -- Create instance local instance = MyClass:New("Test") print(instance:getName()) -- "Test" ``` * Traditional Lua example ```lua theme={null} local MyClass = Lib.Class:Create({},"MyClass") function MyClass:constructor(name) self.name = name end function MyClass:getName() return self.name end local instance = MyClass:New("Test") print(instance:getName()) -- "Test" ``` Arguments to pass to the constructor Returns a new instance of the class Creates new instances of the class. Supports both table-based and argument-based constructors. ```lua theme={null} -- Table-based constructor local instance1 = MyClass:New({ name = "John", age = 30 }) -- Argument-based constructor local instance2 = MyClass:New("John", 30) ``` Classes can inherit from other classes, gaining access to all parent methods and properties. ```lua theme={null} -- Base class local Entity = Lib.Class:Create({ constructor = function(self, id) self.id = id self.created = os.time() end, getId = function(self) return self.id end, getInfo = function(self) return "Entity " .. self.id end }, "Entity") -- Inherited class local Ped = Lib.Class:Create(Entity, "Ped") function Ped:constructor(id, model) self:super(id) -- Call parent constructor self.model = model end function Ped:getInfo() return "Ped " .. self.id .. " (" .. self.model .. ")" end -- Usage local ped = Ped:New(123, "A_M_M_FARMER_01") print(ped:getInfo()) -- "Ped 123 (A_M_M_FARMER_01)" print(ped:getId()) -- 123 (inherited method) ``` Arguments to pass to parent constructor Calls the parent class constructor Used within a constructor to call the parent class constructor. ```lua theme={null} local Ped = Lib.Class:Create(Entity, "Ped") function Ped:constructor(id, model) self:super(id) -- Call parent constructor self.model = model end ``` Define automatic getters and setters for properties using `get` and `set` tables. ```lua theme={null} local Person = Lib.Class:Create({ constructor = function(self, name, age) self.name = name self.age = age end, -- can be used to organize your code as well just like JS classes get = { name = function(self) return self.name:upper() -- Always return uppercase end, age = function(self) return self.age end, isAdult = function(self) return self.age >= 18 end }, -- can be used to organize your code as well just like JS classes set = { name = function(self, value) if type(value) ~= "string" then error("Name must be a string") end self.name = value end, age = function(self, value) if type(value) ~= "number" or value < 0 then error("Age must be a positive number") end self.age = value end } }) local person = Person:New("john", 25) -- Using getters print(person.name) -- "JOHN" (automatic uppercase) print(person.isAdult) -- true -- Using setters person.name = "jane" -- Validates and stores person.age = 30 -- Validates and stores ``` Members starting with underscore `_` are private and can only be accessed from within the same class. ```lua theme={null} local BankAccount = Lib.Class:Create({ constructor = function(self, accountNumber, initialBalance) self._accountNumber = accountNumber -- Private self._balance = initialBalance -- Private self.accountType = "Checking" -- Public end, -- Public method that accesses private members getBalance = function(self) self:_validateAccess() -- Private method call return self._balance end, deposit = function(self, amount) if amount > 0 then self._balance = self._balance + amount return true end return false end, -- Private method _validateAccess = function(self) print("Validating access to account " .. self._accountNumber) end, -- Private method _calculateInterest = function(self) return self._balance * 0.01 end }, "BankAccount") local account = BankAccount:New("12345", 1000) -- ✅ Public access print(account:getBalance()) -- 1000 account:deposit(500) -- ❌ Private access will error -- print(account._balance) -- ERROR -- account:_validateAccess() -- ERROR ``` Private members are class-specific and cannot be accessed by subclasses. ```lua theme={null} local Vehicle = Lib.Class:Create({ constructor = function(self, model) self._engine = "V8" -- Private to Vehicle self.model = model -- Public end, getEngineInfo = function(self) return "Engine: " .. self._engine -- ✅ Same class access end, _startEngine = function(self) print("Starting " .. self._engine .. " engine") end }) local Car = Lib.Class:Create(Vehicle, "Car") function Car:constructor(model, doors) self:super(model) self.doors = doors -- self._engine = "Modified" -- ❌ Would error - can't access parent private end function Car:tryAccessPrivate() -- ❌ Cannot access parent's private members -- local engine = self._engine -- ERROR -- self:_startEngine() -- ERROR print("Cannot access parent private members") end local car = Car:New("Mustang", 2) print(car:getEngineInfo()) -- ✅ "Engine: V8" (via public method) car:tryAccessPrivate() -- Shows privacy enforcement ``` comprehensive class system example ```lua theme={null} -- Import the class module local Lib = Import 'class' --[[@as CLASS]] -- Base Entity class local Entity = Lib.Class:Create({ constructor = function(self, data) self._id = data.id or 0 -- Private ID self._position = data.pos or vector3(0,0,0) -- Private position self.name = data.name or "Entity" -- Public name self._created = os.time() -- Private creation time end, -- Public methods getId = function(self) return self._id end, getPosition = function(self) return self._position end, setPosition = function(self, pos) self._position = pos self:_onPositionChanged() -- Private method call end, getAge = function(self) return os.time() - self._created end, -- Private methods _onPositionChanged = function(self) print("Entity " .. self._id .. " moved to " .. tostring(self._position)) end, -- Automatic getters/setters get = { displayName = function(self) return self.name .. " (#" .. self._id .. ")" end }, set = { name = function(self, value) if type(value) ~= "string" or #value == 0 then error("Name must be a non-empty string") end self.name = value end } }, "Entity") -- Ped class inheriting from Entity local Ped = Lib.Class:Create(Entity, "Ped") function Ped:constructor(data) self:super(data) -- Call parent constructor self._model = data.model or "A_M_M_FARMER_01" -- Private model self._health = data.health or 100 -- Private health self.faction = data.faction or "Civilian" -- Public faction end function Ped:spawn() local pos = self:getPosition() local handle = CreatePed(joaat(self._model), pos.x, pos.y, pos.z, 0.0, true, false, false, false) self._handle = handle print("Spawned " .. self.displayName .. " at " .. tostring(pos)) return handle end function Ped:damage(amount) self._health = math.max(0, self._health - amount) if self._health <= 0 then self:_onDeath() end end -- Private method function Ped:_onDeath() print(self.displayName .. " has died") if self._handle then DeletePed(self._handle) end end -- Getters for private properties Ped.get.health = function(self) return self._health end Ped.get.model = function(self) return self._model end -- Usage local ped = Ped:New({ id = 123, name = "John Marston", pos = vector3(100, 200, 300), model = "CS_JOHNMARSTON", health = 150, faction = "Van der Linde Gang" }) -- Public interface print(ped.displayName) -- "John Marston (#123)" print("Health:", ped.health) -- 150 (via getter) print("Age:", ped:getAge(), "seconds old") ped:setPosition(vector3(150, 250, 350)) ped:spawn() ped:damage(50) print("Health after damage:", ped.health) -- 100 -- Validation works ped.name = "Arthur Morgan" -- ✅ Valid -- ped.name = "" -- ❌ Would error -- Privacy enforced -- print(ped._health) -- ❌ Would error -- ped:_onDeath() -- ❌ Would error ``` using traditional lua function syntax ```lua theme={null} local Lib = Import 'class' --[[@as CLASS]] -- Create class with traditional Lua methods local Timer = Lib.Class:Create({},"Timer") function Timer:constructor(name, duration) self.name = name or "Timer" self._startTime = nil self._duration = duration or 5000 self._isRunning = false end function Timer:start() self._startTime = GetGameTimer() self._isRunning = true print(self.name .. " started for " .. self._duration .. "ms") end function Timer:stop() self._isRunning = false print(self.name .. " stopped") end function Timer:isExpired() if not self._isRunning or not self._startTime then return false end return (GetGameTimer() - self._startTime) >= self._duration end function Timer:getTimeLeft() if not self._isRunning or not self._startTime then return 0 end local elapsed = GetGameTimer() - self._startTime return math.max(0, self._duration - elapsed) end -- Usage local timer = Timer:New("Countdown", 10000) timer:start() -- Check in a loop or thread CreateThread(function() while not timer:isExpired() do print("Time left:", timer:getTimeLeft() .. "ms") Wait(1000) end print("Timer expired!") timer:stop() end) ``` ### Functions utility classes for control flow, timing, and conditional execution provides Switch-case patterns, repeating intervals, and one-time timeouts with full control over execution state shared between server and client environments use these utilities for advanced control flow and timing operations The value to match against cases creates a switch-case control structure that allows chaining case statements and default handling inspired by JS ```lua theme={null} -- Import the functions module local Lib = Import 'functions' --[[@as FUNCTIONS]] -- Basic switch usage local result = Lib.Switch(playerLevel) :case(1, function(value) return "Beginner" end) :case(2, function(value) return "Intermediate" end) :case(3, function(value) return "Advanced" end) :default(function(value) return "Unknown Level: " .. value end) :execute() print(result) ``` Function to execute repeatedly Delay between executions in milliseconds Arguments to pass to the callback function Whether to start the interval immediately Returns an Interval instance for control creates a repeating interval that executes a function at specified intervals ```lua theme={null} -- Import the functions module local Lib = Import 'functions' --[[@as FUNCTIONS]] -- Create an interval that runs every 5 seconds local healthCheck = Lib.SetInterval(function(self, playerId) local player = GetPlayerPed(playerId) if player and DoesEntityExist(player) then local health = GetEntityHealth(player) print("Player " .. playerId .. " health: " .. health) self:Destroy() -- destroy the interval end end, 5000,{GetPlayerServerId(PlayerId())}, true) ``` Returns true if interval is running, false if paused returns the current state of the interval ```lua theme={null} local isRunning = healthCheck:GetState() print("Interval running: " .. tostring(isRunning)) ``` Pauses the interval execution New arguments to pass to the callback New arguments to pass to the callback ```lua theme={null} healthCheck:Update(newPlayerId, additionalData) ``` Stops and cleans up the interval completely Function to execute after delay Delay before execution in milliseconds Arguments to pass to the callback function Returns a Timeout instance for control creates a one-time delayed execution that can be controlled ```lua theme={null} -- Import the functions module local Lib = Import 'functions' --[[@as FUNCTIONS]] -- Create a timeout that executes after 10 seconds local delayedAction = Lib.SetTimeout(function(message, playerId) print("Delayed message: " .. message) end, 10000, {"Welcome to the server!", PlayerId()}) ``` Returns true if timeout is active, false if paused/executed Pauses the timeout, preventing execution New arguments to pass to the callback accepts update arguments too like the update method New arguments to pass to the callback updates the callback arguments ```lua theme={null} delayedAction:Update("Modified message", differentPlayerId) ``` Cancels and cleans up the timeout completely ### Logger this shared module is used to print formatted logs with timestamps, log levels, optional prefixes and structured context the base console already provides the resource name, so the logger output only adds time, level and your message by default `DEBUG` logs are disabled until you enable them with `SetDebugEnabled(true)` or force them with the `debug` option ```lua theme={null} local Logger = Import('logger').Logger --[[@as LOGGER]] ``` ```text theme={null} [12:34:56] [INFO] message [12:34:56] [WARN] [BANK] message | charId=1 money=250 [12:34:56] [ERROR] something failed ``` Base method used by all other log helpers Supported values are `INFO`, `WARN`, `ERROR` and `DEBUG` Message parts, values are concatenated in order Optional context table appended as `key=value` pairs Optional prefix displayed before the message body Forces a `DEBUG` log even when debug mode is disabled Set to `false` to disable console colors ```lua theme={null} local Logger = Import('logger').Logger --[[@as LOGGER]] Logger:Log('INFO', 'player connected', { charId = 12, source = 4 }, { prefix = 'CHARACTER' }) ``` Shorthand helpers for the supported log levels ```lua theme={null} local Logger = Import('logger').Logger --[[@as LOGGER]] Logger:Info('inventory loaded') Logger:Warn('low ammo', { weapon = 'WEAPON_REPEATER_CARBINE' }) Logger:Error('failed to save character', { charId = 5 }) Logger:SetDebugEnabled(true) Logger:Debug('debug output enabled') ``` Enables or disables debug output globally for this logger instance Set to `true` to allow `DEBUG` logs, `false` to disable them Returns the current debug state `true` if debug logs are enabled, otherwise `false` ```lua theme={null} local Logger = Import('logger').Logger --[[@as LOGGER]] Logger:Info('client logger info output', { side = 'client', ped = PlayerPedId() }, { prefix = 'TEST' }) ``` ```lua theme={null} local Logger = Import('logger').Logger --[[@as LOGGER]] Logger:SetDebugEnabled(true) Logger:Debug('server logger debug output', { side = 'server', source = source }, { prefix = 'TEST' }) ``` ## Exports ### Selector This Selector allows you to select players with a NUI selector that will return the player id that was selected Allow self selection Amount of players to select Distance to select players Allow selection of players in vehicles Allow selection of players on horses The player id that was selected ```lua theme={null} local result = exports.vorp_lib:Select({ allow_self = true, amount_of_players = 4, distance = 8.0, allow_in_vehicle = true, allow_on_horse = true }) ``` ### ProgressBar Allows you to create a progress bar that will be displayed on screen for a specified amount of time Text to display in the progress bar Table with the colors for the progress bar `startColor` and `endColor` are the colors for the text and `backgroundColor` and `fillColor` are the colors for the background and the fill of the progress bar image Duration in `milliseconds` for the progress bar Type of progress bar only `linear` is avaliable for now Table with the position for the progress bar on screen `top` and `left` are the position in `%` for the progress bar Image for the progress bar only `png` is avaliable for now Callback function if you want to use it as async the result of the progress bar `true` or `false` if `false` the progress bar was cancelled ```lua theme={null} local data = { text = 'Some text here', colors = { -- for text startColor = 'white', -- starting color of the text endColor = 'black', -- ending color of the text -- these colors are filters they dont really represent the color that well but its an option if you want to change it -- for background -- https://colorpicker.dev/#21d70d use this website choose hwb and its the first number just add deg to it like this 330deg -- backgroundColor = '0deg', -- Changes grey bar to blue-ish --fillColor = '120deg', -- Changes white bar to green-ish }, duration = 5000, type = 'linear', -- only linear is avaliable for now position = { top = 90, left = 50 }, -- in % for position on the screen image = 'score_timer_extralong', -- only png this is optional you can add your own image , images must be in this script images folder } -- SYNC local result = exports.vorp_lib:progressStart(data) if not result then print('cancelled') else print('completed') end --OR ASYNC exports.vorp_lib:progressStart(data, function(result) if result then print('Progress bar completed') else print('Progress bar cancelled') end end) ``` cancel the progress bar ```lua theme={null} exports.vorp_lib:progressCancel() ``` ### Copy Allows you to send a clipboard copy request from `vorp_lib` NUI. Text to copy to the clipboard ```lua theme={null} exports.vorp_lib:copyToClipBoard("Hello from vorp_lib") ``` ### Density Allows you to inspect or change the population density multipliers handled by `vorp_lib` at runtime. The module keeps a default value and can also apply a temporary override. When a temporary value exists, it is used first. When no temporary value exists, the default value is used. Valid density names are: ```lua theme={null} "AnimalDensity" "HumanDensity" "PedDensity" "VehicleDensity" "ScenarioAnimalDensity" "ScenarioHumanDensity" "ScenarioPedDensity" "ParkedVehicleDensity" "RandomVehicleDensity" ``` Density name. If omitted, the export returns the full multipliers table. Returns either one density entry or the full density table. A single entry contains the configured `value`, and can also contain `temp_value` when a temporary override is active. ```lua theme={null} local allMultipliers = exports.vorp_lib:GetDensityMultipliers() local vehicleDensity = exports.vorp_lib:GetDensityMultipliers("VehicleDensity") print(vehicleDensity.value, vehicleDensity.temp_value) ``` Target player source or -1 for all. One of the valid density names listed above. Density multiplier value. Use values between `0.0` and `1.0`. ```lua theme={null} local target = source exports.vorp_lib:SetDefaultDensityMultipliers(target, "VehicleDensity", 0.2) ``` Target player source or -1 for all. One of the valid density names listed above. Density multiplier value, Use values between `0.0` and `1.0`. Optional time in seconds before the temporary density override is removed automatically. ```lua theme={null} local target = source exports.vorp_lib:SetTemporaryDensityMultipliers(target, "VehicleDensity", 0.2) ``` Target player source or -1 for all. One of the valid density names listed above. ```lua theme={null} local target = source exports.vorp_lib:RemoveTemporayDensityMultipliers(target, "ScenarioHumanDensity") ``` ### Collector Not yet implemented ## Cache Cache system to help reduce the amount of most used natives calls like PlayerPedId CACHE is a Global Client table that contains cached data for `Ped`,`Player`,`ServerID`,`Vehicle`,`Mount`,`Weapon` these are updated every 5 milliseconds `Vehicle`, `Mount` reset to 0 when the player is not in a vehicle or mount `LastVehicle`, `LastMount`, `LastWeapon` keep the previous value when it changes, they are not reset to 0 The cached data ```lua theme={null} local ped = CACHE.Ped -- current player ped id local player = CACHE.Player -- current player id local serverId = CACHE.ServerID -- current player server id local vehicle = CACHE.Vehicle -- current vehicle or 0 if not in a vehicle local mount = CACHE.Mount -- current mounted entity or 0 if not mounted local weapon = CACHE.Weapon -- current held weapon local isDead = CACHE.IsDead -- current player is dead or not local lastVehicle = CACHE.LastVehicle -- last vehicle the player was in local lastMount = CACHE.LastMount -- last mount the player was on local lastWeapon = CACHE.LastWeapon -- last weapon the player held ``` these allow you to have more control over the cache system, by default all are false you must disable the ones you dont need ```lua theme={null} -- at the top of your client file. CACHE.SkipWeapon = true -- no need for weapon cache CACHE.SkipVehicle = true -- no need for vehicle cache CACHE.SkipMount = true -- no need for mount cache CACHE.Wait = 500 -- by default is 500 , you can adjust to your needs ``` register a callback that is called when the player ped changes, the new ped id is passed to the callback The function called with the new ped id when the player ped changes ```lua theme={null} CACHE.OnPedChange(function(pedId) print('ped changed', pedId) end) ``` register a callback that is called when the player dies, relies on the `IsDead` check so `CACHE.SkipIsDead` must stay false The function called when the player dies ```lua theme={null} CACHE.OnPlayerDeath(function() print('player died') end) ``` # menu Source: https://docs.vorp-core.com/api-reference/menu vorp menu is a library that allows you to create menus in game with a rdr2 style. ### GetMenuData on top of your client scripts add this to get the menu data setters and getters The menu data ```lua theme={null} local Menu = exports.vorp_menu:GetMenuData() ``` ### CloseAll Close all menus ```lua theme={null} -- these params are optional -- to not fire event close pass false if nil or true will fire the event close MenuData.CloseAll(showRadar, soundClose, fireEventClose) ``` ### RegisterControls Register custom keyboard, mouse, or wheel controls handled by vorp\_menu's NUI layer. This is useful when you want menu-like input handling outside of an opened menu. Array of controls to listen for. Supported values: * Any browser keyboard key string from `KeyboardEvent.key`, for example `e`, `ArrowUp`, `Enter`, or `Backspace` * `scrollup` * `scrolldown` * `mousepress` Callback fired with the triggered control name. Notes: * Keyboard keys and `mousepress` repeat every frame while held until release. * `scrollup` and `scrolldown` fire once per wheel event. * `mousepress` ignores middle click and returns `mousepress_left` or `mousepress_right` in the callback. * If a menu is open, these menu keys are reserved and will not trigger custom callbacks: `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`, `Enter`, `Escape`, `Backspace`. * Calling `RegisterControls` again replaces previously registered controls in the UI layer. * Call `Menu.UnregisterControls()` when you no longer need the listeners. ```lua theme={null} local Menu = exports.vorp_menu:GetMenuData() Menu.RegisterControls({ "e", "scrollup", "scrolldown", "mousepress" }, function(control) if control == "e" then print("E is being held") elseif control == "scrollup" then print("Scrolled up once") elseif control == "scrolldown" then print("Scrolled down once") elseif control == "mousepress_left" then print("Left mouse button pressed") elseif control == "mousepress_right" then print("Right mouse button pressed") end end) ``` ### UnregisterControls Remove all controls previously registered with `RegisterControls`. ```lua theme={null} local Menu = exports.vorp_menu:GetMenuData() Menu.UnregisterControls() ``` ### Menu Elements Menu elements are the elements that will be displayed in the menu for each element you can use the following params The value of the tab element The label of the tab element The description of the tab element The height of the tab element example `4vh` The position of the label `left` or `center` The text of the footer If true the element will not be selectable, meaning the red square will not be shown If true the element will not be clickable and will be grayed out The image name from vorp\_inventory items folder, for grid menu only ```lua theme={null} local menuElements = { { label = "name", value = "value", desc = "description", itemHeight = "4vh", -- optional labelPos = "left", -- optional footerText = "any text here", -- optional isNotSelectable = true, -- optional image = "image", -- optional skipeOpenEvent = false, -- if true will not fire open event -- optional } } ``` allows to use a slider type of element to select a number , can be floats or integers this is defined by the hop value The value of the tab element The label of the tab element The description of the tab element The type of the tab element must be `slider` The minimum value , if not defined will default to 0 The maximum value , if not defined will default to 100 The hop value , can hop by 1 2 etc, to use floats set the hop to 0.1 etc. ```lua theme={null} local menuElements = { { label = "name", value = 0, desc = "description", type = "slider", -- required min = 0, max = 10, hop = 1 } } ``` allows to use a slider type of element to select a string , from a list of strings The value of the tab element The label of the tab element The description of the tab element The type of the tab element must be `text-slider` The list of strings to select from ```lua theme={null} local menuElements = { { label = "name", value = "value", desc = "description", type = "text-slider", -- required textList = { { label = "skinny", value = "anything you want", }, { label = "fatter", value = "anything you want", } } } } ``` `data.current.textIndex` will return the index of the selected string ```lua theme={null} -- example if data.current.value == "value" and data.current.textIndex then local currentValue = data.current.textList[data.current.textIndex].value end ``` allows to use a slider type in the label of the element to select a number , can be floats or integers this is defined by the hop value works with press key or drag when `cursorEnabled` is true The value The label The description The type must be `label-slider` The minimum value , if not defined will default to 0 The maximum value , if not defined will default to 100 The hop value , can hop by 1 2 etc, to use floats set the hop to 0.1 etc. The attributes of the slider , can be used to style the slider `trackColor` is the color of the track accepts names or hex codes rgba `fillColor` is the color of the fill, only accepts linear-gradient you can choose one color or multiple colors and the direction `thumbColor` is the color of the thumb accepts names or hex codes rgba ```lua theme={null} local menuElements = { { label = "name", value = 0, desc = "description", type = "label-slider", -- required min = 0, max = 10, hop = 1, attributes = { -- optional trackColor = "grey", fillColor = "linear-gradient(90deg, #000, #fff)", thumbColor = "white" } } } ``` allows to create multiple sliders in the description of the element, can use integers or floats The value of the tab element The label of the tab element The description of the tab element The type of the tab element must be `desc-slider` The minimum value , if not defined will default to 0 The maximum value , if not defined will default to 100 The hop value , can hop by 1 2 etc, to use floats set the hop to 0.1 etc. The list of sliders ```lua theme={null} local menuElements = { { label = "name", value = "any", desc = "description", type = "desc-slider", -- required sliders = { { label = "Slider one", value = 0, min = 0, max = 1, hop = 1, color = true, -- custom keys if needed attributes = { trackColor = "red", -- red or #ffff or a multicolor fillColor = "linear-gradient(90deg, red, orange, yellow, green, blue, purple)", -- green or #ffff or a multicolor thumbColor = "grey", -- yellow or #ffff or a multicolor } }, { label = "Slider two", value = 0.0, min = -10.0, max = 10.0, hop = 0.1, comp = true, -- custom keys if needed }, } } } ``` `data.current.sliderIndex` will return the index of the selected slider ```lua theme={null} -- example if data.current.value == "any" and data.current.sliders then local currentValue = data.current.sliders[data.current.sliderIndex].value end ``` allows to create a tick box in the element only accept `unticked` or `ticked` The label of the tab element The description of the tab element to enable it set to true ```lua theme={null} local menuElements = { { label = "name", value = "unticked", -- start unticked or ticked desc = "description", tickBox = true } } ``` `data.current.value` will return the value of the tick box ```lua theme={null} -- example if data.current.tickBox then print(data.current.value) end ``` allows to create multiple tick boxes in the description of the element The value of the tab element The label of the tab element The description of the tab element The type of the element must be `tick-box` The list of tick boxes ```lua theme={null} local menuElements = { { label = "label", desc = "description", value = "value", type = "tick-box", -- required tickBoxes = { { label = "box one", value = "ticked", -- value will change to ticket or unticked }, { label = "box two", value = "unticked", -- value will change to ticket or unticked }, } } } ``` `data.current.tickBoxIndex` will return the index of the tick box we ticked or unticked ```lua theme={null} -- example if data.current.value == "value" and data.current.tickBoxes then local currentValue = data.current.tickBoxes[data.current.tickBoxIndex].value end ``` allows to create a price in the description of the element like RDO The value of the tab element The label of the tab element The description of the tab element The price of the tab element * `amount` is the amount of the price * `icon` is `gold` or `money` only * `text` the label ```lua theme={null} local menuElements = { { label = "label", desc = "description", value = "value", descPrice = { amount = 100.00, icon = "money", text = "Price", } } } ``` ```lua theme={null} -- example if data.current.value == "value" and data.current.descPrice then local currentValue = data.current.descPrice.amount end ``` The title of the menu The subtext of the menu The align of the menu , top-right , top-center , top-left The elements for the menu The last menu function name if you wish to go back to the previous menu this will enable the following code and call a global function ```lua theme={null} if (data.current == "backup") then return _G[data.trigger](parameters,parameters) end ``` sets to all elements to this height `4vh` etc sets the position of the label to all elements * `left` * `center` adds a divider to the footer of the menu to all elements sets the fixed height of the menu, so it doesnt resize depending on elements and description enables the cursor for the menu, key inputs will still work, including for sliders and tick boxes * hover over the element and left click to select element then again left click to act as ENTER, or simply press ENTER * right click to close the menu, or simply press Backspace * scroll wheel to scroll up and down the menu sets the max visible items in the menu hides the radar when the menu opens. to display it again simple pass these params again in these functions ```lua theme={null} function(data, menu) -- to hide the radar and to play the final sound of the menu closing menu.close(hideRadar, soundClose, fireEventClose) -- also available here Menu.CloseAll(hideRadar, soundClose, fireEventClose) end ``` plays the first opening sound of the menu creates a button in the description , useful when you dont have to create a new element for a button creates a button in the description , useful when you dont have to create a new element for a button sets the menu to a grid layout, instead of a list layout use in the menuelements the value `image` to display item images useful for creating shops if `true` will skip the open event by default it will fire the open event, usefull when you open one menu after the other without firing the open event ```lua theme={null} local MenuInfo = { title = "menu title", subtext = "menu sub text", align = "top-right", elements = menuElements, lastmenu = "functionName", itemHeight = "4vh", labelPos = "left", divider = true, fixedHeight = true, enableCursor = true, maxVisibleItems = 6, hideRadar = true, soundOpen = true, confirmButton = { label = "Confirm", value = "confirm" }, cancelButton = { label = "Cancel", value = "cancel" }, isGrid = false, skipOpenEvent = false, } ``` ## Functions update elements ,add ,remove ,get elements runtime this function will add a new element to the current menu elements by order The label of the element The value of the element The description of the element ```lua theme={null} menu.addNewElement({ label = "label", value = "open", desc = "description" }) ``` refresh menu to show new element ```lua theme={null} menu.refresh() ``` find an element by value or index * `data.current.value` is available to use in the menu elements * `data.current.index` is available to use in the menu elements ```lua theme={null} local element = menu.getElementByValue(value) local element = menu.getElementByIndex(index) ``` this function will update a specific `element` variable The `index` of the menu element to update `data.current.index` is available to use in the menu elements The variable of the menu element to update , `label`,`value`,`desc`, any The new value of the menu element to update ```lua theme={null} menu.setElement(index, variable, newValue) ``` refresh menu to show changes ```lua theme={null} menu.refresh() ``` this function will remove a specific element by value or index The value of the element to remove `data.current.value` is available to use in the menu elements The index of the element to update `data.current.index` is available to use in the menu elements stop looking at the first element found can be used when you loop through several elements and remove all indexes ```lua theme={null} menu.removeElementByIndex(index,loop) menu.removeElementByValue(value,loop) ``` refresh menu to show changes ```lua theme={null} menu.refresh() ``` this function will close the current menu show the radar when the menu closes plays the final sound when the menu closes if `true` will fire the close event, this is usefull when you want to final close a menu by default the events are only fire when using the `backspace` or if you dont pass the parameter `nil` , to not fire the event pass `false` ```lua theme={null} menu.close(showRadar, soundClose, fireEventClose) ``` this function will set the title of the current menu The title of the menu ```lua theme={null} menu.setTitle("title") ``` refresh menu to show changes ```lua theme={null} menu.refresh() ``` this function will set the subtext of the current menu The subtext of the menu ```lua theme={null} menu.setSubtext("subtext") ``` refresh menu to show changes ```lua theme={null} menu.refresh() ``` creates an input box to collect text or numbers etc. The type of input, `text`, `number`, `password`, `date` `yesno` is a special type of input that will just create a yes or no button, no input needed The header of the input The placeholder of the input The buttons of the input The max length of the input The pattern of the input * `letters` all Unicode letters and spaces * `numbers` numbers only * `alphanumeric` all Unicode letters and numbers * `no-symbols` letters, numbers, spaces (all languages) * `username` username with international letters * `phone` phone numbers with + for country codes * `email` email with international letters * `money` money format (supports both . and , decimals) * `no-special` no special symbols but allow apostrophes and hyphens ```lua theme={null} -- async function menu.displayInput( { inputType = 'text', header = 'Enter your name', placeholder = 'Type here...', -- not for input type yesno description = 'Are you sure you want to archive this bill?', -- for input type yesno only buttons = { confirm = "Confirm", cancel = "Cancel" }, maxLength = 50, pattern = 'letters', patternMessage = "only letters alowed" }, function(inputValue) -- On submit print("User entered: " .. inputValue) end, function() -- On cancel print("User cancelled pressed ESC") end ) ``` ## Events * close menu event ```lua theme={null} AddEventHandler("vorp:menu:closemenu", function(data) end) ``` * open menu event ```lua theme={null} AddEventHandler("vorp:menu:openmenu", function(data) end) ``` ## Menu Example ```lua theme={null} function OpenMenu() -- close any menu before opening Menu.CloseAll() local menuElements = { { label = "name", value = "value", desc = "description" }, { label = "name", value = 0, desc = "description", type = "slider", min = 0, max = 10, hop = 1 }, { label = "name", value = "value", desc = "description", itemHeight = "4vh" } } Menu.Open("default", GetCurrentResourceName() , "OpenMenu", -- unique namespace will allow the menu to open where you left off { title = "title", subtext = "subtext", align = "top-left", -- top-right , top-center , top-left elements = menuElements, -- elements needed lastmenu = "functionName", -- if you wish to go back to the previous menu , or remove (optional) maxVisibleItems = 6, -- max visible items in the menu hideRadar = true, -- hides the radar soundOpen = true, -- plays the open sound of the menu skipOpenEvent = false, }, function(data, menu) -- submit callback -- triggers when pressing/clicking enter print("current key of MenuElements is " .. data.current.index) print("current value of MenuElements is " .. data.current.value) -- to go back to lastmenu if any if (data.current == "backup") then --(optional) if lastmenu is defined return _G[data.trigger](any,any) -- or the function of the last menu end end, function(data,menu) -- cancel callback THIS IS OPTIONAL -- when menu closes if lastmenu isn't defined menu.close(true, true, true) end, -- do not use the below unless you really need, it causes the menu to spike when you press up and down because the submit callback is doing the same thing. function(data, menu) -- change callback THIS IS OPTIONAL -- if theres no previous menu close menu on backspace press -- is called when scrolling through the elements, also when the type = "slider" is changed i dont know why. end, function(data,menu) -- close callback THIS IS OPTIONAL -- when menu closes if lastmenu isnt defined -- menu.close(showRadar, soundClose, fireEventClose) end) end ``` # metabolism Source: https://docs.vorp-core.com/api-reference/metabolism metabolism api for vorp Client side The available status types are `Metabolism`, `Thirst` and `Hunger`. The key is case insensitive, the first letter is capitalized internally. Value ranges: * `Thirst` and `Hunger` go from `0` to `1000` * `Metabolism` goes from `-10000` to `10000` ## Change metabolism value Adds the given amount to the current value, the result is clamped to the valid range of the status. ```lua theme={null} TriggerEvent('vorpmetabolism:changeValue', 'Metabolism', 9000) ``` ## Set metabolism value Sets the value directly, clamped to the valid range of the status. ```lua theme={null} TriggerEvent('vorpmetabolism:setValue', 'Metabolism', 10000) ``` ## Get metabolism value Returns the current value through the callback, or `nil` if the key is not a valid status. ```lua theme={null} TriggerEvent('vorpmetabolism:getValue', 'Metabolism', function(value) print('metabolism value', value) end) ``` ## Toggle the HUD Shows or hides the metabolism HUD. ```lua theme={null} TriggerEvent('vorpmetabolism:setHud', true) -- false to hide ``` # progressbar Source: https://docs.vorp-core.com/api-reference/progressbar create a progressbar in your scripts Client side Initiate the progress bar ,use it on the top of your script ```lua theme={null} progressbar = exports.vorp_progressbar:initiate() ``` Start your progress UI the message that will be displayed in the progressbar the duration that the progressbar will be displayed in milliseconds the function that will be called when the progressbar is done the theme of the progressbar can be `linear`, `circle`, `innercircle` ```lua theme={null} progressbar.start("Loading Example", 20000, function () print('DONE!!!!') end, 'linear') ``` # Best Practices Source: https://docs.vorp-core.com/bestpractices Learn the best practices for writing code in LUA ## Tables and Arrays When working with `structured data`, use tables with `named keys` for better `performance`, `readability`, and `maintainability` Arrays `are good` for lists of simple values, but tables `are better` for complex structured data *** These are just `examples` to demonstrate faster data retrieval using tables versus arrays
Arrays have their own purpose and aren't inherently bad; they just have different use cases
*** #### Choosing Between Tables and Arrays Tables are `faster` than arrays for data lookups because they use a hash map internally, providing constant time lookups, making them `much more efficient`, especially for `larger datasets`
Arrays are `slower in lookups` due to linear time complexity , as they require looping through `each element` until the value is found `for i` loops are generally faster than `ipairs` or `pairs` *only arrays work with ipairs or for i loops* ```lua Good theme={null} local job = "police" local table = {police = true, doctor = true} local hasJob = table[job] ``` ```lua Bad theme={null} -- the larger the array the slower it gets local array = {"police", "doctor"} local job = "police" local hasJob = false for i = 1, #array do if array[i] == job then hasJob = true break end end ``` *** #### Efficient Data Structuring When working with structured data, use `named keys` in tables to improve `readability`, `clarity`, and `performance`
Named keys allow for `easier understanding` of what each field represents, and they also enable `faster lookups`
Arrays with indexed values are `harder to read and maintain`, and lookups `are slower`, especially as the size of the data grows. ```lua Good theme={null} local table = { {grade = 0, job = "police"}, {grade = 0, job = "doctor"} } local job = "police" local hasJob = false for i = 1, #table do if table[i].job == job then hasJob = true break end end ``` ```lua Bad theme={null} local array = { { 0, "police"}, { 0, "doctor"} } local job = "police" local hasJob = false for i = 1, #array do for j = 1, #array[i] do if array[i][j] == job then hasJob = true break end end if hasJob then break end end ``` # Frequently Asked Questions Source: https://docs.vorp-core.com/faq You can find the answers to frequently asked questions about VORP Core here *** ### How can I translate VORP Scripts? You can choose your own language from the `translation.lua`, `language.lua`, `config.lua` files in VORP Scripts, if you have one, or you can translate your scripts into your own language from the same places. ### How can I translate item name/label/description? You can edit in `items` table in database (It is not recommended to change the names in the `item` column in `items` table) ### How can I give item/weapon/job? You can do in `vorp_admin` or you can use command; `/additems `, `/addweapon `, `/addjob ` ### How can I add new items? `items` table in database ### How can I add images for items in the inventory? You can add any `.png` image to `\resources\[VORP]\[vorp_essentials]\vorp_inventory\html\img\items` location with the name of the item in `items` table in the database ### How do I add food and drinks? In the `vorp_metabolism/config.lua` file, you can add any food, drink or health item you want by looking at the other examples. (Don't forget to add the items you add here to the `item` table in the database) ### How can I turn off the huds that appear on the top right (Cash, Gold, ID etc.)? You can set true `HideMoney`, `HideGold` in `\resources\[VORP]\[vorp_essentials]\vorp_core\config\config.lua` ### How do I prevent everyone from creating 5 characters? You can set the `MaxCharacters` value in `\resources\[VORP]\[vorp_essentials]\vorp_core\config\config.lua` ### How can I set the amount of time the player has to wait before respawning? You can set the `RespawnKeyTime` value in `\resources\[VORP]\[vorp_essentials]\vorp_core\config\config.lua` ### How can I add admin to the server? You can add admin to your server based on the examples in `server.cfg`, `vorp_admin/vorp_perms.cfg` files. In addition, you need to change the content of the `group` column in the `characters` and `users` tables in the database to `admin` ### How can I edit the character height/scale? `scale` in `skinPlayer` in `characters` table in database ### How can I CK character? The easiest way is to go to your database, SHIFT+CTRL+F, paste the player's Steam Hex in the search field and delete the results to CK them. ### How do I change the time/weather? `/time` command or you can use `/weatherui` command to open time/weather management menu ### How can I integrate Discord Rich Presence After creating an application from the [Discord Developer Portal](https://discord.com/developers), you need to upload assets to the application and fill in the required fields(`\resources\[VORP]\[vorp_essentials]\vorp_core\config\config.lua`) according to the application information ### How can I solve 32 player problem? Since this problem is caused by CFX, there is no way to solve it outside of CFX. (Bucket/Instance scripts are not very recommended) #### For general RedM problem [RedM FAQ](https://github.com/Z-eus/RedM-FAQ) #### For Support and more [VORP Core Official Discord Server](https://discord.gg/JjNYMnDKMf) # Introduction Source: https://docs.vorp-core.com/introduction Welcome to the VORP Core API Documentation # VORP Core **The lead Framework** for RedM to create **roleplay servers**, offering you the tools you need to build your **custom server**. *** See updates share and learn with the community The Official VORP Core Organisation ## Meet the developers VORP Core is `actively maintained` by it's developers. Project Manager & Maintainer Project Lead Experienced Developer Assistant Assistant ## Meet the staff VORP Core is `actively supported` by the support team and community Discord Staff Discord Staff # Work space Source: https://docs.vorp-core.com/quickstart Set up your development environment `Download Visual Studio Code` to start coding with ease.
Visual Studio Code is a code editor redefined and optimized for building and debugging.
### VSC Extentions These are some of the most useful extentions for Lua, CFX, VORP Core developers. Install VORP Core VSC extention to help you code faster when developing with VORP Core API. Use Lua sumneko VSC to get intellicence for lua and many other useful features. Use Cfx VSC to get intellicence for Cfx Natives/Functions. The Better Comments extension will help you create more human-friendly comments in your code. Improve highlighting of errors, warnings and other language diagnostics.