Hey,
I need help with the Friend Referral System. What I want is that when a player invites someone to the game, and the invited player plays for at least 10 minutes, the inviter receives a tool as a reward that they keep permanently.
I feel like I’m close to accomplishing this, but I’m not sure what I’m missing, since it’s not working.
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local DataStoreService = game:GetService("DataStoreService")
local rewardToolName = "ReferralRewardTool"
local requiredPlayTime = 10
local referralStore = DataStoreService:GetDataStore("ReferralRewardStatus")
local pendingStore = DataStoreService:GetDataStore("PendingReferralRewards")
local referredPlayers = {}
local function tryDeliverReward(player)
local userId = player.UserId
local success, shouldGive = pcall(function()
return pendingStore:GetAsync(tostring(userId))
end)
if success and shouldGive then
local tool = ServerStorage:FindFirstChild(rewardToolName)
if tool then
local clone = tool:Clone()
clone.Parent = player:WaitForChild("Backpack")
print("[REFERRAL] Delivered queued reward to", player.Name)
else
warn("[REFERRAL] Tool not found in ServerStorage:", rewardToolName)
end
pcall(function()
pendingStore:RemoveAsync(tostring(userId))
end)
end
end
Players.PlayerAdded:Connect(function(player)
tryDeliverReward(player)
local success, joinData = pcall(function()
return player:GetJoinData()
end)
if not success or not joinData then
warn("[REFERRAL] Failed to get join data for", player.Name)
return
end
local inviterId = joinData.ReferrerUserId
if inviterId then
referredPlayers[player.UserId] = {
InviterId = inviterId,
JoinedAt = tick()
}
print(("[REFERRAL] %s was invited by UserId %d"):format(player.Name, inviterId))
end
end)
Players.PlayerRemoving:Connect(function(player)
local ref = referredPlayers[player.UserId]
if not ref then return end
local timePlayed = tick() - ref.JoinedAt
print(("[REFERRAL] %s played for %d seconds (needed %d)"):format(player.Name, timePlayed, requiredPlayTime))
if timePlayed >= requiredPlayTime then
local inviterId = ref.InviterId
local success, alreadyRewarded = pcall(function()
return referralStore:GetAsync(tostring(inviterId))
end)
if success and not alreadyRewarded then
local inviter = Players:GetPlayerByUserId(inviterId)
local tool = ServerStorage:FindFirstChild(rewardToolName)
if tool then
if inviter then
local clone = tool:Clone()
clone.Parent = inviter:WaitForChild("Backpack")
print("[REFERRAL] Gave reward to online inviter:", inviter.Name)
else
pcall(function()
pendingStore:SetAsync(tostring(inviterId), true)
end)
print("[REFERRAL] Inviter offline — queued reward for UserId", inviterId)
end
pcall(function()
referralStore:SetAsync(tostring(inviterId), true)
end)
else
warn("[REFERRAL] Reward tool not found in ServerStorage!")
end
else
print("[REFERRAL] Inviter already rewarded or failed to read status.")
end
end
referredPlayers[player.UserId] = nil
end)