[Help] Modifying Server Side Created Blips

Hey! Does anyone know how can I change a server side created blip’s scale or color ? Currently, I am creating a bunch of blips on a server script, and pass the blip handle to the clients when done creating the blips, but when trying to set the scale of the blips or anything else, I’m getting this error:

[     90859] [    GTAProcess]             MainThrd/ __Lua_InvokeNative: execution failed: Error executing native 0xd38744167b2fa257 at address FiveM_GTAProcess.exe+17A83E.
[     90859] [    GTAProcess]             MainThrd/ ^1SCRIPT ERROR: Execution of native d38744167b2fa257 in script host failed: Error executing native 0xd38744167b2fa257 at address FiveM_GTAProcess.exe+17A83E.^7
[     90859] [    GTAProcess]             MainThrd/ ^3> SetBlipScale^7 (^5SetBlipScale.lua^7:3)

This is my server code:

local spawn_peds_first_connection = false
local finished_spawning = false

local grocery_locations = exports['ptct-grocery-store']:GetGroceryLocations()
local weapon_locations = exports['ptct-weapon-store']:GetWeaponLocations()
local barber_locations =
    exports['ptct-stores-blips-spawns']:GetBarberLocations()
local clothing_locations =
    exports['ptct-stores-blips-spawns']:GetClothingLocations()

local clothing_blips = {}
local weapon_blips = {}
local grocery_blips = {}
local barber_blips = {}

-----------------------------------------------------------
------------------------ Functions ------------------------
-----------------------------------------------------------
function SpawnClothingBlips()
    for k, v in ipairs(clothing_locations) do
        Citizen.Wait(0)

        local blip = AddBlipForCoord(v.x, v.y, v.z)
        SetBlipSprite(blip, 73)

        table.insert(clothing_blips,
                     {['blip'] = blip, ['x'] = v.x, ['y'] = v.y, ['z'] = v.z})
    end

end

function SpawnWeaponBlips()
    for k, v in ipairs(weapon_locations) do
        Citizen.Wait(0)

        local blip = AddBlipForCoord(v.x, v.y, v.z)
        SetBlipSprite(blip, v.id)

        table.insert(weapon_blips,
                     {['blip'] = blip, ['x'] = v.x, ['y'] = v.y, ['z'] = v.z})
    end
end

function SpawnGroceryBlips()
    for k, v in ipairs(grocery_locations) do
        Citizen.Wait(0)

        local blip = AddBlipForCoord(v.x, v.y, v.z)
        SetBlipSprite(blip, 52)

        table.insert(grocery_blips,
                     {['blip'] = blip, ['x'] = v.x, ['y'] = v.y, ['z'] = v.z})
    end
end

function SpawnBarberBlips()
    for k, v in ipairs(barber_locations) do
        Citizen.Wait(0)

        local blip = AddBlipForCoord(v.x, v.y, v.z)
        SetBlipSprite(blip, 71)

        table.insert(barber_blips,
                     {['blip'] = blip, ['x'] = v.x, ['y'] = v.y, ['z'] = v.z})
    end
end

function CreateBlipsThread()
    Citizen.CreateThread(function()
        while not spawn_peds_first_connection do Citizen.Wait(0) end

        SpawnClothingBlips()
        SpawnWeaponBlips()
        SpawnGroceryBlips()
        SpawnBarberBlips()

        finished_spawning = true
    end)
end

function CreateBilpSpawnedEventThread(target)
    Citizen.CreateThread(function()
        while not finished_spawning do Citizen.Wait(0) end

        TriggerClientEvent('ptct-stores-blips-spawns:blipsSpawned', target,
                           clothing_blips, weapon_blips, grocery_blips,
                           barber_blips)
    end)
end

function ClearBlips()
    clothing_blips = {}
    weapon_blips = {}
    grocery_blips = {}
    barber_blips = {}

    finished_spawning = false
    spawn_peds_first_connection = true
end
-----------------------------------------------------------
------------------------ Threads --------------------------
-----------------------------------------------------------
CreateBlipsThread()

-----------------------------------------------------------
------------------------ Events ---------------------------
-----------------------------------------------------------
RegisterNetEvent('playerSpawnedFirst')
AddEventHandler('playerSpawnedFirst', function()
    spawn_peds_first_connection = true
    CreateBilpSpawnedEventThread(source)
end)

AddEventHandler('onResourceStart', function(resourceName)
    if GetCurrentResourceName() ~= resourceName then return end

    if GetNumPlayerIndices() > 0 then
        ClearBlips()
        CreateBlipsThread()
        CreateBilpSpawnedEventThread(-1)
    end
end)

and this is my client code:

-----------------------------------------------------------
------------------------ Functions ------------------------
-----------------------------------------------------------
function HandleClothingBlips(clothing_blips)
    for k, v in ipairs(clothing_blips) do
        Citizen.Wait(0)
        local blip = v.blip
        SetBlipScale(blip, 0.8)
        SetBlipDisplay(blip, 4)
        SetBlipAsShortRange(blip, true)

        BeginTextCommandSetBlipName("STRING")
        AddTextComponentString("Clothing Store")
        EndTextCommandSetBlipName(blip)
    end
end

function HandleWeaponBlips(weapon_blips)
    for k, v in ipairs(weapon_blips) do
        Citizen.Wait(0)
        local blip = v.blip
        SetBlipScale(blip, 0.8)
        SetBlipDisplay(blip, 4)
        SetBlipAsShortRange(blip, true)

        BeginTextCommandSetBlipName("STRING")
        AddTextComponentString("Hunter Firearms")
        EndTextCommandSetBlipName(blip)
    end
end

function HandleGroceryBlips(grocery_blips)
    for k, v in ipairs(grocery_blips) do
        Citizen.Wait(0)
        local blip = v.blip
        SetBlipScale(blip, 0.8)
        SetBlipDisplay(blip, 4)
        SetBlipAsShortRange(blip, true)

        BeginTextCommandSetBlipName("STRING")
        AddTextComponentString("Grocery Store")
        EndTextCommandSetBlipName(blip)
    end
end

function HandleBarberBlips(barber_blips)
    for k, v in ipairs(barber_blips) do
        Citizen.Wait(0)
        local blip = v.blip
        SetBlipScale(blip, 0.8)
        SetBlipDisplay(blip, 4)
        SetBlipAsShortRange(blip, true)

        BeginTextCommandSetBlipName("STRING")
        AddTextComponentString("Barber")
        EndTextCommandSetBlipName(blip)
    end
end

-----------------------------------------------------------
------------------------ Events ---------------------------
-----------------------------------------------------------
RegisterNetEvent('ptct-stores-blips-spawns:blipsSpawned')
AddEventHandler('ptct-stores-blips-spawns:blipsSpawned',
                function(clothing_blips, weapon_blips, grocery_blips,
                         barber_blips)
    Citizen.CreateThread(function()
        HandleClothingBlips(clothing_blips)
        HandleWeaponBlips(weapon_blips)
        HandleGroceryBlips(grocery_blips)
        HandleBarberBlips(barber_blips)
    end)
end)

Thanks!!

I feel like you’re overcomplicating this script by alot. Why not do a function that on playerspawn loads a bunch of blips within a for loop taking the blips from a cfg file?

Thanks for the response! I read in the docs (here to be specific: OneSync - Cfx.re Docs (fivem.net)) that for best practice I should create entities and such on the server. I saw there is a “AddBlipForCoord” function for server scripts but as for the scale and color there is no supported function, so I thought that was the best way to create the blip from the server and still be able to change its scale and color. But after second thought, I think you are right, and it is a bit overcomplicated, so I might just create them client side to begin with.

You are correct. That is the best practice for things like that. I 100% agree with that.

But with blips we are still missing quite a lot functionality on server side. The server side natives are enough to create e.g. blips for players that everyone can see. Or just POIs on the map.
And you cannot change things like the color or only display a blip to certain players (e.g. job or mission related). They will always be active for all players.

Blips don’t break anything or are a “security” risk for the server (unlike compared to a client being able to spam hundreds of entities that impact other players experience).
They are usually client side only and show POIs (like shops or places for jobs). There is not really a problem with using them on client side. Especially if you rely on all the additional functions.