GET_ACTIVE_PLAYERS: the replacement for player loops

Originally published at: https://cookbook.fivem.net/2019/06/29/get_active_players-the-replacement-for-player-loops/

Just a quick hint: when writing new client-side scripts in Lua/JS (C# already has the Players list doing exactly this), you can loop through players by using the GET_ACTIVE_PLAYERS native. See below for an example of before/after: Before… for i = 0, 255 do if NetworkIsPlayerActive(i) then local ped = GetPlayerPed(i) – do stuff end…

9 Likes

is this still on canary channel?

1 Like

The code after is actually wrong and wont work, you are getting index from the loop and not the player it self, the code needs to be like this

for i,player in ipairs(GetActivePlayers()) do
    local ped = GetPlayerPed(player)
    -- do stuff
end
2 Likes

Thanks, tiny oversight when writing in a blog composer without testing.

Should be fixed now.

What if it’s done this way? Will this behave normally for OneSync?

local xPlayers = ESX.GetPlayers()
    for i=1, #xPlayers, 1 
        do
        local xPlayer = ESX.GetPlayerFromId(xPlayers[i])
        if xPlayer.job.name == 'police' then
            TriggerClientEvent('esx:showNotification', xPlayers[i], _U('robbery_complete_at'))
            TriggerClientEvent('esx_atmholdup:killblip', xPlayers[i])
        end
    end

I’m guessing #ESX.GetPlayers() will probably just return the length of a table which loops to 255, checks if it is a player and then inserts the int to the table. But, something like the following should work fine…

for _, i in ipairs(GetActivePlayers()) do
   local xPlayer = ESX.GetPlayerFromId(xPlayers[i])
...

From ESX’s wiki

.

"This function returns an array of all online players ID’s.

You can use this to access each players data."

ESX.GetPlayers Example

local xPlayers = ESX.GetPlayers()

for i=1, #xPlayers, 1 do

  local xPlayer = ESX.GetPlayerFromId(xPlayers[i])

  if xPlayer.getName() == "Gepetto" then

    xPlayer.addMoney(100)

    TriggerClientEvent('esx:showNotification', xPlayer.source, "Blablabla...")

  end

end

I am still learning a lot when it comes to coding and I’ve learned the most by trial&error methods :upside_down_face: I don’t wanna touch anything that isn’t broken.

You should change the loop inside the ESX.Game.GetPlayers() function to the GetActivePlayers().

Go into the es_extended/client/functions.lua and have a look at it there. The wiki shows how to use it’s functions, not the code of the functions themselves.
:kiss:

do you mean ESX.Game.GetPlayers() ?

@FiveM_Indonesia
Yes, my post is updated to reflect.
:kiss:

General Comment for anyone else
As of two days ago, The es_extended resource was updated on github.

If you or anyone else is uncertain about what to do, just redownload it again.

If anyone would like to learn about it, the commit change is Here.

The red shows what it used to be.
The green shows what it is now using the new native.

Lets keep all keep this thread clean from specific questions about a specific resource(s) and put it on the track of how to use the new native.

It’d be great if we could get something like this for server-side too :slight_smile:

I wonder, what is the difference between your solution and “just” setting max player in config to 128?

This seems to be working just fine for our players so far…

Teach me, Senpai!

Aside from any further benefits of not having to go back in and change it again if you decided to change slot count.

Think of it in another manner.
In the OP

Rather than calling the native NetworkIsPlayerActive x amount of times in the loop.
“x” being your slot count

It calls the new native once, returning only active players anyway.
Providing you an index of players that existed at the time of the calling.

So rather than your computer asking the server, “hey, does this player exist?” 128 times.

It just asks, “yo, can i get that index again?”

At least, this is what I have taken from it.
I could be slightly wrong in some aspects.

1 Like

GetPlayers()?

This would of been so nice to know a long time ago… Lol