local function onTimeChanged(newTime)
local currentTime = math.max(0, newTime)
local minutes = math.floor(currentTime / 60)
local seconds = math.floor(currentTime) % 60
return string.format("%02d:%02d", minutes, seconds)
end
for _, allPotions in pairs(potions:GetChildren()) do
if allPotions:IsA('ImageLabel') then
allPotions.Gems.Activated:Connect(function()
if debounce then return end
debounce = true
if purchasePotion:InvokeServer(allPotions.Name, 'Gems') then
allPotions.Gems.Visible = false
allPotions.Gold.Visible = false
allPotions.Time.Visible = true
allPotions.Desc.Visible = true
end
debounce = false
end)
allPotions.Gold.Activated:Connect(function()
if debounce then return end
debounce = true
if purchasePotion:InvokeServer(allPotions.Name, 'Gold') then
allPotions.Gems.Visible = false
allPotions.Gold.Visible = false
allPotions.Time.Visible = true
allPotions.Desc.Visible = true
spawn(function()
for i = 3600, 0, -1 do
allPotions.Time.Text = onTimeChanged(i)
wait(1)
end
end)
end
debounce = false
end)
end
end
Currently got this. Basic run down, when you click to buy a potion, it checks the server to make you got the required amount for the set Potion, server handles giving you the powers, etc. Now main question I have is how to handle the countdown? Currently I just have the countdown inside the here, running in a spawn() function as to not stop the script from sitting there for an hour doing nothing. The countdown works, I can buy multiple potions, each one with there own countdown clock ticking down.
Question is. should I be doing this countdown timer inside the server? Only reason Iām afraid of doing it in the server is how Iād manage several countdowns at once (As I donāt want to have multiple Events for each potion)
Could I just keep the countdown where it is now, and then when itās done fire an Event to say to the server that the potion has run out, take away there powers? I feel this would definitely be the easiest solution but is it the safest? I donāt see how players could edit the countdown timer in anyway, but then again, I donāt know how to do all that fancy client hacking stuff XD I just donāt want players either giving themselves the potion effects without buying it, or editing the timer, giving them an infinite time
If you want everything to be kept on the server, Iād say that you could utilize Dictionaries and tables. For example,
local players = {
[12345] = { --userid of player here
["Potion1"] = 3600,
["Potion2"] = 3600
}
}
Where you could add the dictionary of potions after a player joins and initiate a countdown using the tables. Not sure if I set up the table correctly but I think you get the general idea
If you want to continue on the client and instead use RemoteEvents, I think itād be possible provided that you put in the usual security measures. The safest option I feel is if you fire the event when it starts, have the server record when timestamp, then fire again when it ends and have the server compare the two timestamps. This way, the client canāt pass in parameters that might be used to exploit it although Iām not sure how efficient this would be. Ultimately, the safer way is still having the server control all the operations.
The problem is more focused on how to get the client to show the countdown. If I have the countdown going on in the server, theres no real way to get it to show on the Client unless I fired a RemoteEvent, but not sure how firing a RemoteEvent every second for an hour would go, especially if say a player has purchased all 6 purchases, itād be going nuts. And then if numbers overlap or whatever
As I said before, as long as you donāt do anything stupid networking-wise, itās safe. Anything stupid in this case would be allowing client to send data instead of just being able to read it.
Think of it as āpermissionsā;
In this case, client should only have read permission.
As long as the server is validating what they are sending, they canāt. They are completely capable of changing the timer, but if your server is keeping itās own timer than thereās no use. Itās the same with the potion, they can always request a potion but the server should invalidate the request.
The timer loop is done on the client, that way the countdown label shows how long it has left. The reason I wanted to avoid server checking was because I wasnt sure how itād work if I have 6 timers all running at the same time, firing the same event every second, 6 times.
It shouldnāt matter all that much as long as you arenāt syncing 24/7. A few remote calls every minute or two shouldnāt be too big on performance. Definitely donāt fire them every second, youāre right that it would become problematic.
To simplify this a lot you can have a table of when each power-up ends, so for eample if you have a certain power-up for 5 minutes then you would save tick() + 300. Then on the server you can loop through all the values every 30 seconds or every minute (or even every second if you wanted) and remove the ones that have expired.
On the client you just ask the server for the end-time value which was originally saved and then the client can caculate locally how much time is remaining and show that on the timer.