Custom missions

To create a custom mission, whether single-player or multiplayer, you first need to understand which files are required and how to edit/use them properly.

1

Create a basic config template

Locate the config/missions.lua file and create a basic template (example bellow)

    {
        label = 'Custom Mission Example',
        description = 'Your Custom Mission Example description for gang-activities.',
        icon = 'assets/avatars/male_5.png',
        reward = 100,
        xpReward = 50,
        difficulty = 'easy',
        required_level = 1,
        mission = 'custom_mission_exemple',
        endMissionRespawn = false,
        respawnRandomPos = {
            vector3(-57.509113311768, -1079.9354248047, 26.964902877808),
            vector3(377.14935302734, -1306.2001953125, 33.484718322754),
            vector3(-823.34063720703, -1094.5144042969, 11.145439147949),

        },
        blip = { -- set blip = nil so you don't activate the blip menu
            id = 119,
            color = 4,
            scale = 0.6,
            coords = true,

            name = 'Custom Mission Blip'
        },
        tasks = {
            [1] = {
                info = 'Custom singleplayer mission task 1',
                completeFunction = function(tasksArgs)
                    local arg1 = tasksArgs[1]


                    return false;
                end,
            },
        }
    },

Note: In order to create a high quality mission script you need to add more data in this mission table, such as random mission locations/ rewards / tasks etc.

2

Create the server-side file for your mission.

Navigate to server/custom/missions/singleplayer/ or server/custom/missions/multiplayer/ and use the default template located there.

---@type string unique and same as client side
local missionId <const> = 'custom_mission_exemple';

---comment
---@param playerSource integer
---@param missionData table
---@return table?nil, table?nil
local missionFunction = function(playerSource, missionData)
    if not missionData then return print('ERROR: MissionData is nil') end;

    local extraData = {};
    local entities = {};

    -- custom singleplayer missions for server side;
    -- insert all the entities in entities table with table.insert(entities, {entityData}), so after the mission is finished/failed or resource is restarted the entities will be deleted
    -- extraData need to contain all the entities informations created in server side such as: networkId, weaponName for npc enemy, extra mission data such as selected location/house etc
    -- even if you are not using extraData and entities make sure to let it an empty table, = {}
    -- make sure to set entities in virtual world if the missionData.setVirtualWorld = true;
    -- example:

    local npc; -- npc entity after you create it;

    local playerIdentifier = Framework.GetPlayerIdentifier(playerSource);

    if missionData.setVirtualWorld then
        local bucketId = 100 + playerSource;
        SetEntityRoutingBucket(npc, bucketId);
    end

    return extraData, entities;
end

-- be sure to add this code line if you want to crete the mission;

-- exports['axr_gang-activities']:insertSingleMission(missionId, missionFunction);

Note: safe this file and rename it to a desire label. Also you need to create custom code lines in order to work, such as CreateVehicle, CreatePed, custom threads etc.

3

Create the client-side file for your mission.

Navigate to client/custom/missions/singleplayer/ or client/custom/missions/multiplayer/ and use the default template located there.

Note: safe this file and rename it to a desire label. Also you need to create custom code lines in order to work, such as CreateVehicle, CreatePed, custom threads etc.

---@type string unique and same as server side
local missionId <const> = 'custom_mission_exemple';

---comment
---@param missionData table
---@param extraData table
local missionFunction = function(missionData, extraData)
    if not missionData then return end; 
    if not extraData then return end;

    -- custom singleplayer missions for client side;
    -- use missionData and extraData from server side to take control of entities/ set multiple blips and make your mission as you want

    inMissions = true -- need to set inMissions = true before creating mission overlay

    -- create blip with createMissionBlip function

    local blip;
    local blipSetter = vector3(1834.9813232422,-1922.0208740234,149.18962097168); -- blip setter need to be entity or vector3 coord, set forEntity = true or coords = true in config/missions.lua for your mission as you want;
    if missionData.blip then
        blip = createMissionBlip(missionData.blip, blipSetter)
    end


    -- create and show mission overlay code:

    local missionDataCopy = overlayFunctions.createMissionCopy(missionData);
    overlayFunctions.createMissionOverlay(missionDataCopy);
    overlayFunctions.createOverlaytoogleThread();



    Citizen.CreateThread(function()
        ---@type table
        local playerTempStats = {}
        local condition = true;
        local waiter = 1000;

        local failed = false;
        local failed_condition = false;
        local taskParameter1, taskParameter2;
        local condition_made_kill = false;
        while condition do
            Citizen.Wait(waiter);

            -- add verification for mission tasks,
            ---@taskParameter1 any value you want (the logic for completing the task is made in config/missions.lua)
            ---@taskParameter2 any value you want (the logic for completing the task is made in config/missions.lua)
            ---@params count = mission tasks count

            overlayFunctions.checkCompletedTasks(missionData, { taskParameter1, taskParameter2, });

            if condition_made_kill then -- example to update player kills statistics. For more information check our documentation
                playerTempStats['missions_kills'] = {
                    addValue = true,
                    value = 1
                }
            end

            ---@type boolean -- set failed_condition for your custom mission
            if failed_condition then
                failed = true;
            end

            -- break the mission and notify the player for failing it
            if failed then
                -- Notify(fail_message, notify_type)
                break;
            end
        end

        -- delete blips after mission failed/completed

        if blip and missionData.blip then
            RemoveBlip(blip)
        end

        inMissions = false -- be sure to set inMissions = false after mission failed/completed

        -- respawn random player after failed/completed, coords can be added/edited in config/missions.lua

        if missionData.endMissionRespawn then
            respawnPlayerFromMission(missionData.respawnRandomPos, missionData.success)
        end

        -- destroy mission overlay;
        overlayFunctions.destroyMissionOverlay();

        -- be sure to add this TriggerServerEvent to update player statistics and give reward if missionData.success = true;

        TriggerServerEvent('axr_gang-activities:finishMission', missionData, playerTempStats)
    end)
end

-- be sure to add this code line if you want to crete the mission;

-- exports['axr_gang-activities']:insertSingleMission(missionId, missionFunction);
4

Sync the logic between these files.

Now that you have created all three files, you need to implement the logic that will make the code behave like a mission.

Recommendation:

  • Store all mission data such as coordinates, rewards, ped/vehicle/prop codes inside the mission’s config table.

  • Create entities on the server-side.

  • Add entities to the global entities table using table.insert(entities, entity).

  • Return all necessary mission information inside the extraData table so it can be used later on the client-side.

  • On the client-side, ensure that entity control is assigned to a single client.

  • Use boolean parameters for tasks, or apply simple checks inside the task’s completeFunction.

  • Follow the existing templates to avoid issues with blip creation, mission overlay handling (start/stop), etc.

  • Use logical expressions to detect whether the mission has failed or not.

  • At the end of the mission, make sure to remove temporary blips, destroy the mission overlay, and clean up client-side entities. (On the server-side, entities are automatically removed.)

Last updated

Was this helpful?