I’d like to propose a change to the Group Ally/Enemy Checker code sample which shows how to use GroupService in actual work. The new code sample tackles the following areas:
-
General code improvements, ensuring current standards are used.
-
Fixes on spelling mistakes that could cause erroring or are simply not correct to use.
-
Improved formatting.
local GroupService = game:GetService("GroupService")
local Players = game:GetService("Players")
-- define group id here
local GROUP_ID = 271454
-- utility function for dealing with pages
local function pagesToArray(pages)
local array = {}
while true do
for _, v in ipairs(pages:GetCurrentPage()) do
table.insert(array, v)
end
if pages.IsFinished then
break
end
pages:AdvanceToNextPageAsync()
end
return array
end
-- get lists of allies and enemies
local alliesPages = GroupService:GetAlliesAsync(GROUP_ID)
local enemiesPages = GroupService:GetEnemiesAsync(GROUP_ID)
-- convert to array
local allies = pagesToArray(alliesPages)
local enemies = pagesToArray(enemiesPages)
local function playerAdded(player)
-- check to see if the player is in the group
if player:IsInGroup(GROUP_ID) then
print(player.Name .. " is a member!")
else
local isAlly, isEnemy = false, false
-- check to see if the player is in any ally groups
for _, groupInfo in ipairs(allies) do
local groupId = groupInfo.Id
if player:IsInGroup(groupId) then
isAlly = true
break
end
end
-- check to see if the player is in any enemy groups
for _, groupInfo in ipairs(enemies) do
local groupId = groupInfo.Id
if player:IsInGroup(groupId) then
isEnemy = true
break
end
end
if isAlly and not isEnemy then
print(player.Name .. " is an ally!")
elseif isEnemy and not isAlly then
print(player.Name .. " is an enemy!")
elseif isEnemy and isAlly then
print(player.Name .. " is both an ally and an enemy!")
else
print(player.Name .. " is neither an ally or an enemy!")
end
end
end
-- listen for new players being added
Players.PlayerAdded:Connect(playerAdded)
-- handle players already in game
for _, player in ipairs(Players:GetPlayers()) do
playerAdded(player)
end
The following changes in this code sample were made in comparison to the current sample:
-
Sample is properly formatted. Previous sample was all tabbed by one except for the very first line.
-
All cases of pairs were changed to ipairs. This sample does not work with dictionaries in any scope, so I opted to change the iterator used. The StandardPages returned by GetAllies/EnemiesAsync always return contiguous arrays per page. GetPlayers always returns an array as well.
-
First variable in the for loop of pagesToArray was changed from k to an underscore. This was not consistent with all other for loops which used an underscore for the first variable. I also used value for the second variable because that’s more readable than a single letter and it represents the idea of key-value pairs for pages.
-
Removed the useless conditional check in the for loops intended to set isAlly and isEnemy. When iterating through the allies and enemies arrays, all the elements are guaranteed to exist, it won’t iterate over a nil value. If this was to account for edge cases, then the if check should have been done before trying to index a member item, as that would throw an error. Fixed example, if the edge case conditional is required, available below.
for _, groupInfo in pairs(GROUP_TYPE_TABLE)) do
if groupInfo then
local groupId = groupInfo.Id
if groupId and player:IsInGroup(groupId) then
isGROUPTYPE = true
break
end
end
end