How would I make this looting system?

My goal is to make a looting system, that is fair for all players. I want every player to get different loot that can’t be claimed by any other player and only them.

Let’s say an enemy NPC died, and dropped loot. How would I distribute loot to every player that won’t get stolen by others? If I do it on client, wouldn’t it get exploited??

The easy way to do that is just pass the items to the players directly after NPC has died, without dropping any loot.
That makes it fair for everyone.

…i want them to directly drop on the floor though, then have it despawn after a few minutes ( i know how ), so the player can pick up what they want and what they don’t want

Alr, another solution, Prioritize the loop before it drops.
For example after NPC dies, make an avatar icon or player name appear above the loot.

The third solution is.
Make drop for each player unique (using remotes and local scripts) and then verify if player really can get that item on server

1 Like

Create a “Loots” folder in the ReplicatedStorage, and in server side, create a new folder inside it for each player (with playerAdded).

Players.PlayerAdded:Connect(function(Player)
    local NewFolder = instance.new("Folder")
    NewFolder.Parent = ReplicatedStorage.Loots
    NewFolder.Name = Player.Name
end)

When the NPC dies, do the loot randomization for each players in server side, and add a value into the player loot folder in the replicated storage.

Humanoid.Died:Connect(function()
    for _, Player in Players:GetPlayers() do
        local RandomCoins = math.random(1, 100)
        local RandomItem = LootTable[math.random(1, #LootTable)]

        local NewCoinsValue = instance.new("IntValue")
        local NewItemValue = instance.new("StringValue")

        NewCoinsValue.Value = RandomCoins 
        NewCoinsValue.Name = "Coins"
        NewCoinsValue.Parent = ReplicatedStorage.Loots:FindFirstChild(Player.Name)

        NewItemValue.Value = RandomItem
        NewItemValue.Name = "Item"
        NewItemValue.Parent = ReplicatedStorage.Loots:FindFirstChild(Player.Name)
    end
end)

Now in client side, use ChildAdded to detect when new loots are added into your player folder and drop them onto the map, then each time your collecting the loots, destroy them and FireServer().

Receive the event in server side, check if the loot value exist in the folder, if it does not exist do nothing, if it exist delete the value and give them the loot.

Client Side

local MyLootFolder = ReplicatedStorage.Loots:FindFirstChild(LocalPlayer.Name)

MyLootFolder.ChildAdded:Connect(function(LootValue)
    --Go to storage > drop loot on the map

    --Do whatever you need to collect the loot (touched / proxi...)
    Loot.Touched:Connect(function()
        Loot:Destroy()
        RemoteEvent:FireServer(LootValue)
    end
end)

Server Side

Remote.OnServerEvent:Connect(function(Player, LootValue)
    local LootFolder = ReplicatedStorage.Loots:FindFirstChild(Player.Name)

    if LootFolder[LootValue] then
        --Give loot to Player
        LootValue:Destroy()
    end

    --example
    if LootFolder[LootValue] and LootValue.Name == "Coins" then
        Player.leaderstats.Coins.Value += LootValue.Value
        LootValue:Destroy()
    end

     if LootFolder[LootValue] and LootValue.Name == "Item" then
        local Clone = ItemsStorage:FindFirstChild(LootValue.Value):Clone()
        Clone.Parent = Backpack
        LootValue:Destroy()
    end
end)
1 Like

ill try this in a bit, ill let you know if it works, thanks!

1 Like