I want to create a tree system in which the player can activate a proximity prompt on the tree and have objects fall out from it; those objects will be collectibles (e.g. apples and oranges) only on the specific client that activated the tree.
Right now I do all the math and cooldowns on the server when the tree is activated:
-- self.Instance is the tree.
local Prompt = self.Instance.PrimaryPart.Prompt.ShakePrompt
self._Trove:Add(Prompt.Triggered:Connect(function(Player)
if not self.PlayersCooldown[Player] then
self.PlayersCooldown[Player] = os.time() - self.CooldownTime
end
if os.time() - self.PlayersCooldown[Player] >= self.CooldownTime then
self.ItemData[Player.Name] = {}
local RandomAmount = self.Random:NextInteger(1, 3)
for _ = 1, RandomAmount do
table.insert(self.ItemData[Player.Name], self:RollCollectable())
end
print(self.ItemData) -- {dmksa123 = {[1] = Orange, [2] = Apple}}
Generate:FireClient(Player, self.ItemData[Player.Name], self.Instance.PrimaryPart.CFrame)
self.PlayersCooldown[Player] = os.time()
end
end))
However, on the client, I want to generate the objects/collectibles. The problem I am facing is that I have no way to prevent duplication of the object by exploiters.
self._Trove:Connect(Generate.OnClientEvent, function(ItemData: {}, TreeCFrame: CFrame)
for _, Item in ItemData do
if self.Instance.Name == Item then
local ClonedObject = self.Instance:Clone()
ClonedObject.Parent = workspace
ClonedObject:PivotTo(TreeCFrame * CFrame.new(math.random(1, 3), 3, math.random(1, 3)))
end
end
end)
I want the client to send information back to the server that removes the collectible from their ItemData (as shown in the module).
The solution I was thinking about was just to send back a client → server RemoteEvent to remove the objects from their ItemData and check if the object is in the data still.
Basically, I desire to know if this is the best way to handle this or if there is a better way.