DataStore and Events
A DataStore would be the easiest way to make sure that players only redeem codes once. However, they can only be accessed by ServerScripts, so when working with LocalScripts (as I assume you are with you GUIs) you'll need a RemoteEvent in order for cross-scope communication.
In addition, this could be made much more efficient if we use an event that fires when a code is entered, rather than using a while loop that is constantly using resources. A variety of different events could be used, such as FocusLost or maybe MouseButton1Down on a GuiButton.
So what you need to do is create a DataStore for each player that holds a Boolean value of whether of not each code has already been redeemed. Then when the player enters a code in a TextBox and fires the event you choose (I used FocusLost), you can invoke the server with the RemoteEvent and check to see whether of not the code has been used or not.
In this example I give the player it's on scope so I can better organize the data store. See this wiki page as I think the diagram really helps to visualize what I'm doing.
Server Script
local DataStoreService = game:GetService("DataStoreService")
local RemoteEvent = Instance.new("RemoteEvent", game.ReplicatedStorage.RemoteEvent)
local Codes = {}
game.Players.PlayerAdded:connect(function(player)
local DataStore = DataStoreService:GetDataStore("Codes", player.Name)
for _, code in next, Codes do
local value = DataStore:GetAsync(code)
if value == nil then
DataStore:SetAsync(code, false)
end
end
end)
RemoteEvent.OnServerEvent:connect(function(player, text)
for _, code in next, Codes do
local value = DataStore:GetAsync(code)
if value then
DataStore:SetAsync(code, true)
print("Code Given")
end
end
end)
Local Script
local DataStoreService = game:GetService("DataStoreService")
local RemoteEvent = game.ReplicatedStorage.RemoteEvent
codebox.FocusLost:connect(function(enterPressed)
if enterPressed then
RemoteEvent:FireServer(codebox.Text)
end
end)
Additional Note
The method GetAsync has a 10 second delay from the actual value stored on the Roblox servers, so It might be best to limit how often you can redeem a code to at least a minimum of 10 seconds. This can be done with a simple debounce.
Example:
local CanRedeem = true
codebox.FocusLost:connect(function(enterPressed)
if enterPressed and CanRedeem then
CanRedeem = false
RemoteEvent:FireServer(codebox.Text)
wait(10)
CanRedeem = true
end
end)
However you might want to tell the user via a GUI when the can and can't redeem.
1 comment
make a debounce that uses a value saved from a data store. This way you can constantly get back this value when you need to and once its false and/or true it will stay that way and they cant use again