local codes = {"ALPHA"} while wait() do for _, v in pairs(codes) do if codebox.Text == v then print("Code Given") end end end
This work, and it prints when it is supposed to, but how could I make it so the player doesn't just abuse the code and they can only use it once? I was thinking something to do with datastores, but I don't understand datastores really well, and the wikis are kind of useless.
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)
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.