Checking for players in game who aren't your friend

Can anyone tell me if this would work? I can’t test since I don’t have any to join my game / and this can’t be tested using server clients :confused:

It should go through all the players in the game, if the player isn’t yourself, then it continues to then check if said player is in your friends list. If that player isn’t your friend, then it will finally print this players name, and then move on to to the next player.

for i, allPlayers in pairs(Players:GetPlayers()) do
	if allPlayers.Name ~= Player.Name then
		for i, yourFriends in pairs(Players:GetFriendsAsync(Player.UserId)) do
			if allPlayers.Name ~= yourFriends then
			    print(allPlayers.Name)
			end
		end
	end
end

Problem with this is, I’m not sure is since I have 2 for loops running, if the print would print multiple times for the same player. It should only print once and move on, so then at the end it will have printed all the players in game who aren’t my friends.

1 Like

https://developer.roblox.com/en-us/api-reference/function/Player/IsFriendsWith

https://developer.roblox.com/en-us/api-reference/function/Player/GetFriendsOnline

https://developer.roblox.com/en-us/api-reference/function/Players/GetFriendsAsync

Take a look at these if you haven’t already, I’m pretty sure they provide sufficient information for you to figure out how to achieve what you want

1 Like

Hard to tell since I’m on mobile, but this could get messy very quickly. Have you had a look at Player.IsFriendsWith instead? This will you a lot of trouble.

Your current operation:

  1. Iterate through each player. Check if the iterated player isn’t the same as the requesting player.
  2. Iterate through the player’s friends list. You now need to check if the requester isn’t on the target’s friends list.

This obviously pretty inefficient, so using IsFriendsWith, you can cut that down entirely and stay within the scope of the game.

for _, yourPlayer in pairs(Players:GetPlayers()) do
    if not (yourPlayer.Name == myPlayer.Name) and not (yourPlayer:IsFriendsWith(myPlayer.UserId)) then
        print(yourPlayer, "is not my friend!")
    end
end

This one cuts down loop and size by half.

  1. Iterate through each player.
  2. Check that the iterated player is not the same as the requesting player, then if they’re friends. If both are false, the other player is not friends with the requesting player.
2 Likes

I personally wouldn’t recommend using either of the last two unless you have a use case that involves friends regardless of presence. That includes creating a Join Friends window or similar.

Given the nature of the thread in wanting to check players on the current instance and if they aren’t friends, iterating through each player and using IsFriendsWith is the best course of action here. Simple and efficient, minus any potential caching (I do not believe it caches though).

The other two would present unnecessary overhead and a slight reinventing of the wheel for existing methods of checking status between two users.

Alternatively to this, you could get a list of the Player’s friends once with GetFriendsAsync instead of having to make API calls for each player.

    local Players = game:GetService("Players")
    local player = game.Players.Whoever
    local playerFriends = Players:GetFriendsAsync(player.UserId)

    local function findFriend(friends, name)
        for i,plr in pairs(friends) do
            if plr.Username == name then
                return i
            end
        end
        return false
    end

    for _, plr in pairs(Players:GetPlayers()) do
        if not findFriend(playerFriends, plr.Name) then
            print('This is not my friend')
        end
    end
2 Likes

Not a good idea. Friends can change over the course of a session. If you cache the player’s friends once per session, you become unable to accommodate for any new friends a player adds.

This also goes back to the drawing board of using two loops and using a function that isn’t presence-dependent, which presents unnecessary overhead. OP only wants to check status between two players in an instance.

That is true, though an added friend in the current session could just be added to the cache.

If you’re willing to refresh the variable every so often? Sure. At that point though, unless the function call takes enough time to be noticeable, you might as well not cache. That brings us back to the code seen in the OP.

There’s far less involvement and little to no overhead by performing a direct check to player relationships over the iterated players.

I completely agree, it just becomes extremely inefficient if it is extensively used in which cause it’s probably better to limit the API calls. If it’s just a few checks every so often I think that the OP and your code would be the way to go :slightly_smiling_face: