You could create a datastore (I’m not going to explain datastores entirely). You could have a table of players, each time a player joins, pull that table from the datastore and check the amount of values, then if the value is under 100, add the player to the table. If it’s over 100, just leave it alone.
This is inefficient, and there may be a better way, but most likely you can leave this system in place for a little bit, and then once the table fills up, remove it form the game and just store the player’s names/userID’s somewhere so that you could give them rewards in the future (or whatever you plan to do)
local dss = game:GetService("DataStoreService")
local pls = game:GetService("Players")
local list = dss:GetDataStore("balls")
local playerAdd = function(player)
local data = list:GetAsync("List") or {}
if (((#data) < 100) and (not (table.find(data, player.UserId)))) {
data[#data+1] = player.UserID -- storing the userid
repeat local suc = pcall(function()list:SetAsync("List", data)end) task.wait() until suc
}
end
table.foreach(pls:GetPlayers(),function(i,v)playerAdd(v)end)
pls.PlayerAdded:Connect(playerAdd)