game.Players:GetPlayers() doesnt get all players?

Im trying to make a gun that shows bullets for everyone when shot by using FireClient on every player except for the shooter himself. I tested this out with my friends and his gun showed bullets on my side. However, when i shoot my gun my friend doesnt see my bullet. Here’s my code:

wep.FireForServer.OnServerEvent:Connect(function(p, direction)
	local shoot = Instance.new("Animation")
	shoot.AnimationId = glockshoot
	local shootanim = character.Humanoid:LoadAnimation(shoot)
	shootanim.Priority = Enum.AnimationPriority.Action
	shootanim:Play()
	spawn(function()
		handle.Shoot:Play()
		handle.BulletSpawn.Smoke.Enabled = true
		handle.Light.Enabled = true
		wait(0.05)
		handle.BulletSpawn.Smoke.Enabled = false
		handle.Light.Enabled = false
	end)
	for i,v in pairs(game.Players:GetPlayers()) do -- iterating every player in the game
		print(v.Name)
		if v.Name == p.Name then return end -- returns if it is the shooter
		game.ReplicatedStorage.GunShot:FireClient(v, p.Character, direction, handle.BulletSpawn.WorldPosition, handle.Trail) -- a local script in StarterPlayerScripts will pick this up and fire the bullet
	end
end)

When my friend shot his gun, the output showed both our names. However, when I shot my gun, only my name showed up. It couldnt be because of the return line because the print command was before it. The tables then turned when we rejoined and this time my friend was the first to join. I couldnt see his bullets, but he could see mine. Why doesnt it go through every player for the first player that joined the game? The local script that picks up the function is in every players StarterPlayerScripts. Is there a solution to this or do I have to remake everything?

3 Likes

Using return in a loop has the same effect that using a break in it would have. Once you return, no code will be executed after the line.
For example:

for _, num in pairs({1,2,3,4}) do
    print(num)
    if num == 3 then return end
end
print("Done")

--[[ Output:
1
2
3
]]

The output stops at 3 since the loop stops as soon as num == 3, no further code is ran – not even print(“Done”)

This matters since though the print line is before the return line, no further code is executed and hence no further prints are seen. Instead you should wrap the whole body of the for block in an if condition, without returning!

for _, player in pairs(game.Players:GetPlayers()) do
    if not player == p then -- You can also compare the instances instead of their names
        -- Fire remote
    end
end

This might have worked for your friend and not for you as the players in the table are alphabetically ordered (I think). So your loop terminated too early while your friend’s did not. No clue why this would reverse if the accounts used stay the same but the solution is wrapping the body, not returning.


P.S. Please indent your code, it can do wonders in productivity.

2 Likes

Make sure to format your code when showing it on the forums, this makes it much easier to read your code and possibly help.

Here’s how:
```
Code here
```

1 Like

Thanks! It works like intended! I will indent my code next time, Im still new to the DevForum!

1 Like

pairs loops are not guaranteed to run in any specific order. Use ipairs (which only works for arrays) if you want them to run in order based on index. You can use table.sort if an array isn’t ordered the way you want. Source: PiL

The pairs function, which iterates over all elements in a table, is similar, except that the iterator function is the next function…

The call next(t, k) , where k is a key of the table t , returns a next key in the table, in an arbitrary order.

2 Likes