JRS COREДокументация
Справочник API

lib

JRS Lib is a modular scripting library for RedM that simplifies game development by providing reusable, instance-based components with automatic cleanup. Designed specifically for JRS Core Framework, it helps developers write cleaner, more efficient scripts while eliminating common issues like memory leaks and global variable pollution

Note

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.

Warning

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
   shared_script "@jrs_core/lib/import.lua"

Module Import#

Note

Only Lua files can be imported

List of Modules#

modules (client)#
entities (module)#

this module contains methods that allows you to create entities like peds, vehicles, objects, etc

blips (module)#

this module contains methods that allows you to create various types of blips styles and map related stuff

inputs (module)#

this module contains methods that allows you to create input controls

raycast (module)#

this module contains methods that allows you to perform gameplay raycasts from the camera or from an entity

prompts (module)#

this module contains methods that allows you to create prompts

commands (module) (client)#

this module contains methods that allows you to register commands

points (module)#

this module contains methods that allows you to create points enter/exit with debug options

polyzones (module)#

this module contains methods that allows you to create polygon, circle, or box detection zones with callbacks and debug tools

events (module)#

this module contains methods that allows you to register game events

dataview (module)#

this module contains methods that allows you to use dataview in lua

streaming (module)#

this module contains methods that allows you to call to load several game assets like anim dics models etc

modules (server)#
commands (module)#

this module contains methods that allows you to register commands for the server with permissions options and more

modules (shared)#
class (module)#

this module contains methods that allows you to create classes with inheritance and more

functions (module)#

this module contains methods that allows you to use like switch setInterval etc

logger (module)#

this module contains methods that allows you to create formatted logs with time, level, prefix and context data

Importing Modules#

Import#
modulestringrequired

Allows to import any modules from the lib, a list of modules available can be found here

lua
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
Import#
modulestringrequired

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
local module = Import "/filename"
local module = Import "/folder/filename"
Import#
modulestringrequired

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
local module = Import "@script_name/filename"
local module = Import "@script_name/folder/filename"

Import Usage#

Single#
modulestringrequired

The module name to import

lua
local module = Import "module"
Multiple#
modulearrayrequired

The module name to import

lua
local module = Import ({"module", "module2", "module3"})
local prompts = module.Prompts
Mixed#
modulearrayrequired

The module names to import

lua
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

Shared#

This is the baseclass for (peds, vehicles, objects) subclasses you can use these methods bellow or use directly the natives

GetHandle#
returnstring

Get the handle of the entity, this is a unique identifier for the entity

GetModel#
returnstring

Get the model of the entity

GetPosition#
returnvector3

Get the position of the entity

GetHeading#
returnnumber

Get the heading of the entity

GetRotation#
returnvector3

Get the rotation of the entity

GetNetId#
returnnumber

Get the networked id of the entity if the entity created had IsNetworked = true

SetPosition#
vectorvectorrequired

can use vector3 or vector4 to just set heading by passing a table with w {w = 0.0}

Delete#
returnnil

Delete the entity

Ped#
  • 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#

create a ped

Modelintegerrequired

The model of the ped

Posvector3required

The position of the ped

IsNetworkedboolean

if the ped is networked

ScriptHostPedboolean

if the ped is a script host ped

P7boolean

unknown

P8boolean

unknown

Optionstable

these are optional parameters

PlaceOnGround = boolean, OutfitPreset = integer

OnCreatefunction

The function to will be called when the ped is created

OnDeletefunction

The function to will be called when the ped is deleted

lua
    -- 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,
        },
       
            print('Ped created use your own logic here, handle: ', self:GetHandle())
        end,

        netid)
            print('Ped deleted use your own logic here, handle: ', handle, 'netid: ', netid)
        end
    })
    -- methods you can use
   local handle = ped:GetHandle()
   ped:Delete()
Vehicle#
  • 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
Create#
Modelstringrequired

The model of the vehicle

Posvectorrequired

The position for the vehicle

IsNetworkedboolean

if the vehicle is networked

ScriptHostVehboolean

if the vehicle is a script host vehicle

DontAutoCreateDraftAnimalsboolean

create draft animals if true

P8boolean

unknown

Optionstable

PlaceOnGround, Seat = { Ped = ped, Index = -1}

OnCreatefunction

The function to call when the vehicle is created

OnDeletefunction

The function to call when the vehicle is deleted

lua
-- 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
        }
    },
   
        print('Vehicle created use your own logic here, handle: ', self:GetHandle())
    end,

   
        print('Vehicle deleted use your own logic here, handle: ', self:GetHandle())
    end
})

local handle = vehicle:GetHandle()
vehicle:Delete()
Object#
  • 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
Create#
Modelintegerrequired

The model of the object

Posvector3required

The position for the object

IsNetworkedboolean

if the object is networked

ScriptHostObjboolean

if the object is a script host object

Dynamicboolean

if the object is dynamic

Optionstable

PlaceOnGround = boolean, Rot = vector3,Rot.Order = integer, Rot.P5 = boolean

OnCreatefunction

The function will be called when the object is created

OnDeletefunction

The function will be called when the object is deleted

lua
-- 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,
        }
    },

   
        print('Object created use your own logic here, handle: ', self:GetHandle())
    end,

   
        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

Blip#

This is the baseclass for blips, you can use these methods below or use directly the natives

GetHandle#
returninteger

Get the handle of the blip

GetBlipColor#
colorstring|tablerequired

Get the color value's for blip colors, can be a single color string or table of color strings

returninteger

Returns the color value's corresponding to the color name's

lua
    -- 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#
returnnil

Remove/Delete the blip

SetName#
namestringrequired

Set the name/label of the blip

SetCoords#
posvector3required

Set the coordinates for the blip (pos.x, pos.y, pos.z)

SetStyle#
styleinteger|stringrequired

Set the style for the blip, see blip style

SetSprite#
spriteinteger|stringrequired

Set the sprite icon for the blip. see blip sprite

AddModifier#
modifierinteger|stringrequired

Add a modifier for the blip see blip modifier

RemoveModifier#
modifierinteger|stringrequired

Remove a modifier from the blip see blip modifier

AddModifierColor#
colorstring|integerrequired

Add a color modifier for the blip, use the GetBlipColor method to get the color value's if needed

Create#

create a blip

BlipTypestringrequired

The type of blip to create: entity, coords, area, radius each will have specific params

Blipinteger|stringrequired

The blip sprite/hash to use, see blip sprite hash

Entityinteger

Required for 'entity' type - the entity handle to attach the blip to

Posvector3

Required for 'coords', 'area', and 'radius' types - the position for the blip

Scalevector3

Required for 'area' type - the scale dimensions (x, y, z)

Radiusnumber

Required for 'radius' type - the radius size (defaults to 0.5)

P7integer

Optional parameter for 'area' type (defaults to 0)

Optionstable

Optional parameters for blip appearance:

sprite = integer|string, name = string, style = integer|string, modifier = integer|string, color = string

OnCreatefunction

The function that will be called when the blip is created

lua
    -- 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
        },
       
            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

Input#

use these methods below to manage input controls

Destroy#
returnnil

Destroy the input instance and stop all processing

RemoveKey#
keystringrequired

Remove a specific key from multiple inputs or if single input , destroys the input

Pause#
returnnil

Pause the input processing without destroying the instance

Resume#
returnnil

Resume the input processing after being paused

Update#
datatablerequired

Update custom parameters for the input if needed

keystring|integerrequired

Required if using multiple inputs - specifies which input to update

Start#
returnnil

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#

register an input or multiple inputs

inputTypestringrequired

The type of input: Press, Hold, Release

keystring|integerrequired

The key to listen for (e.g., E, W) these are predefined keys, you can use any hash or string controls

callbackfunctionrequired

Function called when input is triggered - receives (instance, customParams)

stateboolean

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
    -- 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

Import#
lua
local Raycast = Import('raycast').Raycast --[[@as RAYCAST]]
Flags#

Available flag names:

  • World
  • Vehicles
  • Peds
  • Ragdolls
  • Objects
  • Pickups
  • Glass
  • Rivers
  • Foliage
  • All
FromCamera#

Cast a ray from the gameplay camera forward

distancenumber

Distance of the raycast, defaults to 10.0

flagsstring

Flag name to use for the shape test, invalid or missing values fallback to World

ignoreEntityinteger

Entity handle to ignore, defaults to PlayerPedId()

options.offsetvector3 | table

Optional offset added to the camera coordinates

options.traceTypeinteger

Shape test trace type, defaults to 7

options.timeoutinteger

Max wait time in milliseconds for the result, defaults to 1000

options.waitinteger

Delay between polling attempts, defaults to 0

returnRAYCAST_RESULT

Returns a result table with hit, coords, normal, entity, material, state, didHit and handle

lua
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
FromEntity#

Cast a ray from an entity forward using its current forward vector

entityintegerrequired

Entity handle to cast from, the entity must exist

distancenumber

Distance of the raycast, defaults to 10.0

flagsstring

Flag name to use for the shape test, invalid or missing values fallback to World

ignoreEntityinteger

Entity handle to ignore, defaults to the provided entity

options.offsetvector3 | table

Optional offset added to the entity coordinates before casting

options.traceTypeinteger

Shape test trace type, defaults to 7

options.timeoutinteger

Max wait time in milliseconds for the result, defaults to 1000

options.waitinteger

Delay between polling attempts, defaults to 0

returnRAYCAST_RESULT

Returns a result table with hit, coords, normal, entity, material, state, didHit and handle

lua
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
RAYCAST_RESULT#

Result fields returned by FromCamera and FromEntity

hitboolean

True when the shape test hit something

stateinteger

Native shape test state

handleinteger

Shape test handle returned by the native

didHitinteger

Raw native hit result

coordsvector3

Hit coordinates

normalvector3

Surface normal

entityinteger

Hit entity handle, or 0 if no entity was hit

materialinteger

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

Prompt#

use these methods below to manage prompts

GetHandle#
keystring|integerrequired

The key identifier of the specific prompt, its whatever you set in the register

returninteger

Get the handle of a specific prompt by key

GetPromptGroup#
keystring|integerrequired

The key identifier of the specific prompt, its whatever you set in the register

returninteger

Get the group ID of a specific prompt

GetGroupLabel#
keystring|integerrequired

The key identifier of the specific prompt, its whatever you set in the register

returnstring

Get the group label of a specific prompt

IsRunning#
returnboolean

Check if the prompt you registered is currently running

SetLabel#
labelstringrequired

New label text for the prompt

keystring|integerrequired

The key identifier of the prompt to update, its whatever you set in the register

SetEnabled#
enabledbooleanrequired

Whether the prompt should be enabled or disabled

keystring|integerrequired

The key identifier of the prompt to update, its whatever you set in the register

SetVisible#
visiblebooleanrequired

Whether the prompt should be visible or hidden

keystring|integerrequired

The key identifier of the prompt to update, its whatever you set in the register

SetMashMode#
mashCountintegerrequired

Number of times the key must be mashed

keystring|integerrequired

The key identifier of the prompt to update, its whatever you set in the register

SetMashIndefinitelyMode#
keystring|integerrequired

The key identifier of the prompt to set to indefinite mash mode, its whatever you set in the register

Start#
returnnil

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#
returnnil

Pause the prompt system without destroying it

Resume#
returnnil

Resume the prompt system after being paused

Remove#
keystringrequired

The key identifier of the specific prompt to remove if multiple, if single will destroy

Destroy#
returnnil

Destroy the entire prompt system

Register#

register prompts

coordsvector3required

The center coordinates where prompts will be active

distancenumber

Activation radius from coords (defaults to 2.0)

labelstringrequired

The group label shown at the top of the prompt group

sleepinteger

Sleep time when not in range (defaults to 700ms)

markertable

Optional marker configuration: type, color = {r,g,b,a}, distance, scale = {x,y,z} can be used for debug as well

promptsarrayrequired

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)

callbackfunctionrequired

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.

stateboolean

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
    -- 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

Command#

use these methods below to manage command controls

Remove#
returnnil

Removes the command and its suggestion from chat

AddSuggestion#
returnnil

Adds command suggestion to chat

RemoveSuggestion#
returnnil

Removes the command suggestion from chat

Pause#
returnnil

Pause the command without removing it (temporarily disables the command)

Resume#
returnnil

Resume the command after being paused

Destroy#
returnnil

Completely destroy the command instance and clean up

Start#
addSuggestionboolean

Whether to add chat suggestion when registering the command, use this only on runtime, by default when player selects character suggestion is added automatically

returnnil

Start/activate the command

OnExecute#
callbackfunctionrequired

its called when the command is executed

OnError#
callbackfunction

its called when the command has errors

Register#

register a command

namestringrequired

The command name (without the / prefix)

Suggestiontable

Chat suggestion configuration with Description and Arguments array

Permissionstable

Permission configuration with Ace group settings

OnExecutefunctionrequired

Function called when command executes - receives (args, rawCommand, instance)

OnErrorfunction

Function called on command errors - receives error type string

stateboolean

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
    -- 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
        },

        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,

       
            if errorType == 'missing_arguments' then
                print('Usage: /mycommand <playerId> <amount> [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)
Command#

use these methods below to manage server command controls

Remove#
returnnil

Remove the command, its suggestion from all clients, and ACE permissions

AddSuggestion#
targetintegerrequired

The player source ID to send suggestion to

returnnil

Add command suggestion to specific player's chat

RemoveSuggestion#
targetintegerrequired

The player source ID to remove suggestion from

returnnil

Remove command suggestion from specific player's chat

Pause#
returnnil

Pause the command without removing it (temporarily disable)

Resume#
returnnil

Resume the command after being paused

Destroy#
returnnil

Completely destroy the command instance and clean up

Start#
returnnil

Start/activate the command and register ACE permissions if configured

OnExecute#
callbackfunctionrequired

Set or update the callback function called when command executes

OnError#
callbackfunctionrequired

Set or update the callback function called when command has errors

Register#

register a server command

namestringrequired

The command name (without the / prefix)

Suggestiontable

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
    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" }
        }
    }
Permissionstable

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
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
    },
}
OnExecutefunctionrequired

Function called when command executes - receives (source, args, rawCommand, instance)

OnErrorfunction

Function called on command errors - receives error type string

stateboolean

If true, command starts automatically after registration (defaults to false)

lua
    -- 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
            }
        },

        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,

       
            if errorType == 'missing_arguments' then
                print('Usage: /admincommand <playerId> <amount> [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

Point#

use these methods below to manage points

IsPointActive#
idstring|integerrequired

The unique identifier of the point to check

returnboolean

Returns true if the point is active and not deactivated

IsPointInside#
idstring|integerrequired

The unique identifier of the point to check

returnboolean

Returns true if the player is currently inside the point radius

IsPointOutside#
idstring|integerrequired

The unique identifier of the point to check

returnboolean

Returns true if the player is currently outside the point radius

UpdatePoint#
idstring|integerrequired

The unique identifier of the point to update

datatablerequired

New point data to replace the existing point configuration

RemovePoint#
idstring|integerrequired

The unique identifier of the point to remove

returnnil

Removes the specified point from the instance

PausePoint#
idstring|integerrequired

The unique identifier of the point to pause

returnnil

Deactivates the specified point without removing it

ResumePoint#
idstring|integerrequired

The unique identifier of the point to resume

returnnil

Reactivates a previously paused point

Start#
returnnil

Start the point system if not already running, begins monitoring player position

Pause#
returnnil

Pause the entire point system without destroying it

Resume#
returnnil

Resume the point system after being paused

Destroy#
returnnil

Destroy the entire point instance and clean up all points

DebugPoints#
returnnil

Enable visual debug markers for points that have debug enabled

Register#

register coordinate-based points for enter/exit detection

Argumentsarrayrequired

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
    -- supports multiple points
    Arguments = {
        {
            id = 'bank_entrance',
            center = vector3(2843.49, 474.49, 64.03),
            radius = 15.0,
            wait = 500,
            debug = true,
            deActivate = false,
        }
    }
OnEnterfunctionrequired

Function called when player enters any point - receives (point, distance)

OnExitfunctionrequired

Function called when player exits any point - receives (point, distance)

stateboolean

If true, point system starts automatically after registration other wise use the Start method to start the point system

lua
    -- 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,
            },
        },

        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,

        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

PolyZone#

use these methods below to register and manage advanced zone shapes

GetId#
returnstring|integer

Returns the unique identifier assigned to the zone (auto-generated when not provided)

GetType#
returnstring

Returns the zone type poly, circle, or box

IsRunning#
returnboolean

Returns true when the zone polling loop is currently running

IsInside#
returnboolean

Returns true if the local player is currently inside the zone

SetCallbacks#
cbEnterfunction

Replaces the onEnter callback (receives zone instance and player coords)

cbExitfunction

Replaces the onExit callback (receives zone instance and player coords)

cbInsidefunction

Replaces the onInside callback that runs every tick while inside

UpdatePolygon#
pointsarray

Updates polygon points (vector3 list) and recalculates bounds, available for polygon zones only

UpdateCircle#
centervector3

Updates circle center position

radiusnumber

Updates circle radius, available for circle zones only

UpdateBox#
centervector3

Updates box center position

lengthnumber

Updates box length, available for box zones only

widthnumber

Updates box width, available for box zones only

headingnumber

Optional new heading in degrees for the box zone

SetHeight#
minZnumber

Sets the minimum Z (height) allowed before the zone considers the player outside

maxZnumber

Sets the maximum Z (height) allowed before the zone considers the player outside

SetDebug#
enabledboolean

Enables or disables debug drawing (auto-starts debug loop when the zone is running)

SetTickRates#
outsideMsnumber

Sets polling interval in milliseconds while the player is outside the zone (defaults to 200)

insideMsnumber

Sets polling interval in milliseconds while the player stays inside (defaults to 1)

Start#
returnnil

Starts the background thread that evaluates the zone, automatically launches debug rendering when enabled

Pause#
returnnil

Temporarily stops the zone without clearing callbacks or shape data

Resume#
returnnil

Restarts a paused zone and resumes detection

Destroy#
returnnil

Disables the zone and clears its configuration (instance should be discarded afterwards)

Register#

register polygon, circle, or box zones with callbacks and optional auto-start

datatablerequired

Zone configuration table:

  • id: Optional string or integer unique identifier (polyzone_<timestamp> 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 }
stateboolean

When true the zone starts immediately after registration (defaults to false, call Start() manually otherwise)

returnPolyZone

Returns the zone instance so you can control it with the methods above

lua
    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,
        coords)
            print(('Entered %s at %.2f %.2f'):format(zone:GetId(), coords.x, coords.y))
        end,
       
            print('Left zone', zone:GetId())
        end,
    }, true)
lua
    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,
        coords)
            print(('Warming up at %.2f %.2f'):format(coords.x, coords.y))
        end,
       
            print('Leaving the fire')
        end,
    }, true)
lua
    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)
Destroy#
instancePolyZone

Zone instance returned by Register

returnnil

Stops the zone, removes it from the manager, and cleans it up

lua
    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

Event#

use these methods below to manage event listeners

Start#
returnnil

Start the event listener and begin monitoring for the registered event

Pause#
returnnil

Pause the event listener without destroying the instance

Resume#
returnnil

Resume the event listener after being paused

Destroy#
returnnil

Destroy the event listener instance and clean up

DevMode#
enabledbooleanrequired

Enable or disable developer mode for debugging events

eventsToIgnorestring|array

Optional events to ignore when in dev mode (can be event name string, hash)

returnnil

When enabled, logs all events in the group. Use eventsToIgnore to filter out noise.

lua
    -- 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#

register a game event listener

eventNamestring|integerrequired

The game event name (string) or hash (integer) to listen for

groupintegerrequired

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
callbackfunctionrequired

Function called when the event triggers - receives parsed event data or nothing if event has no data

stateboolean

If true, event listener starts automatically after registration, otherwise use Start method

lua
    -- 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

DataView#

use these methods below to manage binary data

Buffer#
returnstring

Get the underlying binary buffer as a string

ByteLength#
returninteger

Get the length of the buffer in bytes

ByteOffset#
returninteger

Get the current offset position within the buffer

Data Type Getters#

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
offsetintegerrequired

Byte offset from buffer start to read from

endianboolean

Endianness: true for big-endian, false/nil for little-endian

returnnumber|string|nil

The read value, or nil if offset is out of bounds

Fixed Size Getters#
  • 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
offsetintegerrequired

Byte offset from buffer start

lengthintegerrequired

Number of bytes to read

endianboolean

Endianness: true for big-endian, false/nil for little-endian

SubView#
offsetintegerrequired

Byte offset to create the sub-view from

returnDataView

Create a new DataView that shares the same buffer but with different offset

Data Type Setters#

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
offsetintegerrequired

Byte offset from buffer start to write to

valuenumber|stringrequired

The value to write

endianboolean

Endianness: true for big-endian, false/nil for little-endian

returnDataView

Returns self for method chaining

Fixed Size Setters#
  • 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
offsetintegerrequired

Byte offset from buffer start

lengthintegerrequired

Number of bytes for the data type

valuenumber|stringrequired

The value to write

endianboolean

Endianness: true for big-endian, false/nil for little-endian

ArrayBuffer#

create a new binary buffer

lengthintegerrequired

Size of the buffer to allocate in bytes

returnDataView

Returns a new DataView instance with allocated buffer

lua
    -- 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#

wrap existing binary data

binaryDatastringrequired

Existing binary data string to wrap

returnDataView

Returns a DataView instance wrapping the existing data

lua
    -- 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
DataStream#

create sequential data reader

dataViewDataViewrequired

DataView instance to create stream from

returnDataStream

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
    -- 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

Asset Loading#

use these functions below to load various game assets with automatic cleanup

LoadModel#
modelstring|integerrequired

Model name (string) or hash (integer) to load

timeoutinteger

Optional timeout in milliseconds to automatically unload the model and free memory

returnnil

Loads and validates the model, throws error if invalid or fails to load within 5 seconds

LoadTextureDict#
dictstringrequired

Texture dictionary name to load

timeoutinteger

Optional timeout in milliseconds to automatically unload the texture dictionary

returnnil

Loads texture dictionary with validation and error handling

LoadParticleFx#
dictstringrequired

Particle effect dictionary name to load

timeoutinteger

Optional timeout in milliseconds to automatically remove the particle effect asset

returnnil

Loads particle effect dictionary for use with particle systems

LoadAnimDict#
dictstringrequired

Animation dictionary name to load

timeoutinteger

Optional timeout in milliseconds to automatically remove the animation dictionary

returnnil

Loads animation dictionary with existence validation

LoadWeaponAsset#
weaponstring|integerrequired

Weapon name (string) or hash (integer) to load

p1integerrequired

Unknown parameter (usually 31)

p2booleanrequired

Unknown parameter (usually false)

timeoutinteger

Optional timeout in milliseconds to automatically remove the weapon asset

returnnil

Loads weapon asset with validation

LoadMoveNetworkDef#
netDefstringrequired

Move network definition name to load

timeoutinteger

Optional timeout in milliseconds to automatically remove the network definition

returnnil

Loads move network definition for advanced movement systems

LoadClipSet#
clipSetstringrequired

Clip set name to load

timeoutinteger

Optional timeout in milliseconds to automatically remove the clip set

returnnil

Loads animation clip set for character movement styles

RequestCollisionAtCoord#
coordsvector3required

Coordinates where collision should be loaded

returnnil

Loads collision data for terrain at specified coordinates

RequestCollisionForModel#
modelstring|integerrequired

Model name or hash to load collision for

returnnil

Loads collision data for a specific model

RequestIpl#
iplstring|integerrequired

IPL (Interior Proxy List) name or hash to load

returnnil

Loads IPL for interior or map sections, warns if already loaded

LoadScene#
posvector3required

Position to load scene around

offsetvector3required

Offset from position

radiusnumberrequired

Radius to load scene within

p7integerrequired

Unknown parameter (usually 0)

returnnil

Loads world area around entity - use carefully as it can cause crashes with too many MLOs

Import#

import the streaming module

       
lua
    -- 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

OOP System#

use these methods below to create classes with full OOP support

Create#
basetable|class

Base class to inherit from, or table of initial methods/properties

classNamestring

Optional name for the class (used in error messages)

returnclass

Returns a new class that can create instances with :New()

lua
    -- 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
 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"
New#
...any

Arguments to pass to the constructor

returninstance

Returns a new instance of the class

Creates new instances of the class. Supports both table-based and argument-based constructors.

lua
    -- Table-based constructor
    local instance1 = MyClass:New({
        name = "John",
        age = 30
    })

    -- Argument-based constructor
    local instance2 = MyClass:New("John", 30)
Class Inheritance#

Classes can inherit from other classes, gaining access to all parent methods and properties.

lua
    -- 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)
super#
...any

Arguments to pass to parent constructor

returnnil

Calls the parent class constructor

Used within a constructor to call the parent class constructor.

lua
    local Ped = Lib.Class:Create(Entity, "Ped")
    function Ped:constructor(id, model)
        self:super(id) -- Call parent constructor
        self.model = model
    end
Automatic Properties#

Define automatic getters and setters for properties using get and set tables.

lua
    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
Private Properties & Methods#

Members starting with underscore _ are private and can only be accessed from within the same class.

lua
    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
Inheritance & Privacy#

Private members are class-specific and cannot be accessed by subclasses.

lua
    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
Complete Example#

comprehensive class system example

       
lua
    -- 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
Traditional Lua Style#

using traditional lua function syntax

       
lua
    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

Switch#

use these utilities for advanced control flow and timing operations

valueany

The value to match against cases

creates a switch-case control structure that allows chaining case statements and default handling inspired by JS

lua
     -- 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)
SetInterval#
callbackfunctionrequired

Function to execute repeatedly

delayintegerrequired

Delay between executions in milliseconds

customArgstable

Arguments to pass to the callback function

startboolean

Whether to start the interval immediately

returnIntervalrequired

Returns an Interval instance for control

creates a repeating interval that executes a function at specified intervals

lua
    -- 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)
GetState#
returnboolean

Returns true if interval is running, false if paused

returns the current state of the interval

lua
    local isRunning = healthCheck:GetState()
    print("Interval running: " .. tostring(isRunning))
Pause#
returnnil

Pauses the interval execution

Resume#
...any

New arguments to pass to the callback

Update#
...any

New arguments to pass to the callback

lua
    healthCheck:Update(newPlayerId, additionalData)
Destroy#
returnnil

Stops and cleans up the interval completely

SetTimeout#
callbackfunctionrequired

Function to execute after delay

delayintegerrequired

Delay before execution in milliseconds

customArgstable

Arguments to pass to the callback function

returnTimeoutrequired

Returns a Timeout instance for control

creates a one-time delayed execution that can be controlled

lua
    -- 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()})
GetState#
returnboolean

Returns true if timeout is active, false if paused/executed

Pause#
returnnil

Pauses the timeout, preventing execution

Resume#
...any

New arguments to pass to the callback accepts update arguments too like the update method

Update#
...any

New arguments to pass to the callback

updates the callback arguments

lua
    delayedAction:Update("Modified message", differentPlayerId)
Destroy#
returnnil

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

Import#
lua
local Logger = Import('logger').Logger --[[@as LOGGER]]
Output Format#
text
[12:34:56] [INFO] message
[12:34:56] [WARN] [BANK] message | charId=1 money=250
[12:34:56] [ERROR] something failed
Log#

Base method used by all other log helpers

levelstringrequired

Supported values are INFO, WARN, ERROR and DEBUG

...any

Message parts, values are concatenated in order

contexttable

Optional context table appended as key=value pairs

options.prefixstring

Optional prefix displayed before the message body

options.debugboolean

Forces a DEBUG log even when debug mode is disabled

options.colorizeboolean

Set to false to disable console colors

lua
local Logger = Import('logger').Logger --[[@as LOGGER]]

Logger:Log('INFO', 'player connected', {
    charId = 12,
    source = 4
}, {
    prefix = 'CHARACTER'
})
Info / Warn / Error / Debug#

Shorthand helpers for the supported log levels

lua
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')
SetDebugEnabled#

Enables or disables debug output globally for this logger instance

enabledbooleanrequired

Set to true to allow DEBUG logs, false to disable them

GetDebugEnabled#

Returns the current debug state

returnboolean

true if debug logs are enabled, otherwise false

Client Example#
lua
local Logger = Import('logger').Logger --[[@as LOGGER]]

Logger:Info('client logger info output', {
    side = 'client',
    ped = PlayerPedId()
}, {
    prefix = 'TEST'
})
Server Example#
lua
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

Select#
allow_selfboolean

Allow self selection

amount_of_playersinteger

Amount of players to select

distancenumber

Distance to select players

allow_in_vehicleboolean

Allow selection of players in vehicles

allow_on_horseboolean

Allow selection of players on horses

playeridinteger

The player id that was selected

lua
local result <const> = exports.jrs_core: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

Start#
textstringrequired

Text to display in the progress bar

colorstablerequired

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

durationintegerrequired

Duration in milliseconds for the progress bar

typestringrequired

Type of progress bar only linear is avaliable for now

positiontablerequired

Table with the position for the progress bar on screen top and left are the position in % for the progress bar

imagestring

Image for the progress bar only png is avaliable for now

callbackfunction

Callback function if you want to use it as async

returnboolean

the result of the progress bar true or false if false the progress bar was cancelled

lua
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.jrs_core:progressStart(data)
if not result then
    print('cancelled')
else
    print('completed')
end

--OR ASYNC
exports.jrs_core:progressStart(data, function(result)
    if result then
        print('Progress bar completed')
    else
        print('Progress bar cancelled')
    end
end)
Cancel#

cancel the progress bar

lua
    exports.jrs_core:progressCancel()

Copy#

Allows you to send a clipboard copy request from jrs_core NUI.

copyToClipBoard#
textstringrequired

Text to copy to the clipboard

lua
exports.jrs_core:copyToClipBoard("Hello from jrs_core")

Density#

Allows you to inspect or change the population density multipliers handled by jrs_core 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
"AnimalDensity"
"HumanDensity"
"PedDensity"
"VehicleDensity"
"ScenarioAnimalDensity"
"ScenarioHumanDensity"
"ScenarioPedDensity"
"ParkedVehicleDensity"
"RandomVehicleDensity"
GetDensityMultipliers#
namestring

Density name. If omitted, the export returns the full multipliers table.

returntable

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
local allMultipliers = exports.jrs_core:GetDensityMultipliers()

local vehicleDensity = exports.jrs_core:GetDensityMultipliers("VehicleDensity")
print(vehicleDensity.value, vehicleDensity.temp_value)
SetDefaultDensityMultipliers#
sourceintegerrequired

Target player source or -1 for all.

namestringrequired

One of the valid density names listed above.

valuenumberrequired

Density multiplier value. Use values between 0.0 and 1.0.

lua
local target <const> = source
exports.jrs_core:SetDefaultDensityMultipliers(target, "VehicleDensity", 0.2)
SetTemporaryDensityMultipliers#
sourceintegerrequired

Target player source or -1 for all.

namestringrequired

One of the valid density names listed above.

valuenumberrequired

Density multiplier value, Use values between 0.0 and 1.0.

timerinteger

Optional time in seconds before the temporary density override is removed automatically.

lua
local target <const> = source
exports.jrs_core:SetTemporaryDensityMultipliers(target, "VehicleDensity", 0.2)
RemoveTemporayDensityMultipliers#
sourceintegerrequired

Target player source or -1 for all.

namestringrequired

One of the valid density names listed above.

lua
local target <const> = source
exports.jrs_core:RemoveTemporayDensityMultipliers(target, "ScenarioHumanDensity")

Collector#

Not yet implemented

Cache#

Cache system to help reduce the amount of most used natives calls like PlayerPedId

CACHE#

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

returnany

The cached data

lua
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
CACHE#

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
-- 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
OnPedChange#

register a callback that is called when the player ped changes, the new ped id is passed to the callback

callbackfunctionrequired

The function called with the new ped id when the player ped changes

lua
CACHE.OnPedChange(function(pedId)
    print('ped changed', pedId)
end)
OnPlayerDeath#

register a callback that is called when the player dies, relies on the IsDead check so CACHE.SkipIsDead must stay false

callbackfunctionrequired

The function called when the player dies

lua
CACHE.OnPlayerDeath(function()
    print('player died')
end)
JRS Core · Бесплатный фреймворк RedM с открытым кодом · JRS TEAM