I'm fairly new to the RBLX lua, so I'm looking for a bit of clarification regarding datastores. I'm trying to put together a script that keeps track of how many times a player has clicked on a specific part, and using this (https://www.robloxdev.com/articles/Saving-Player-Data) article from the roblox dev wiki to help me out.
I've got the proper pieces of the code I need that are featured in that article in a script in my game, but it didn't mention how to increase (IncrementAsync?) values using parts you might find in Workspace (like ClickDetectors), and so far I haven't found any other source that has the information I'm after. If someone could maybe point me in the right direction on where to head to next, it would be greatly appreciated.
Just because your function is connected to an event (like a ClickDetector's MouseClick
event) doesn't mean that the code will run any differently. This works the same as any other code that uses IncrementAsync
, although you might want to use variables outside of the connected function to avoid sending a datastore request on every single click.
An example of using variables outside of the connected function so that you don't need to send constant requests would be:
local clickDetector = workspace.something.clicky local dsService = game:GetService("DataStoreService") local timesClickedDS = dsService:GetDataStore("TimesClicked") -- obviously "TimesClicked" doesn't matter one bit as long as its consistent local playerService = game:GetService("Players") local timesClickedTable = {} clickDetector.MouseClick:Connect(function(player) if timesClickedTable[player.UserId] then -- if there's a value already saved timesClickedTable[player.UserId] = timesClickedTable[player.UserId] + 1 -- increment counter -- maybe something else else timesClickedTable[player.UserId] = 1 -- set to one since clicked once end end) playerService.PlayerRemoving:Connect(function(player) -- when someone quits local pUserId = player.UserId if timesClickedTable[pUserId] then -- check how many times they clicked this session timesClickedDS:IncrementAsync(pUserId, timesClickedTable[pUserId] -- increment it to their saved data end end) playerService.PlayerAdded:Connect(function(player) -- for each player while true do wait(300) -- every 300 seconds if timesClickedTable[player.UserId] then -- if there's any data timesClickedDS:IncrementAsync(player.UserId, timesClickedTable[player.UserId]) -- save it to their datastore end end end)
In this particular example, someone would be able to autoclick to increment the counter a lot more than (probably) intended, as there's no debounce or anything that will change once they've clicked it once.
As I'm pretty sure you've figured out (judging by your question), you can find a lot of information on the wiki page for datastores.
Edit: Since you wanted an answer where the value is available between scripts, you can adapt the original code to use IntValues instead of script-specific variables. This wouldn't require much change, but I'll repost the whole thing edited as the changes are spread throughout the script. Changed lines will be marked with "--***--" above them.
local clickDetector = workspace.something.clicky local dsService = game:GetService("DataStoreService") local timesClickedDS = dsService:GetDataStore("TimesClicked") -- obviously "TimesClicked" doesn't matter one bit as long as its consistent local playerService = game:GetService("Players") local timesClickedTable = {} clickDetector.MouseClick:Connect(function(player) if timesClickedTable[player.UserId] then -- if there's a value already saved --***-- added .Value twice so that it updates value of object rather than replacing the reference to the object in table with a number timesClickedTable[player.UserId].Value = timesClickedTable[player.UserId].Value + 1 -- increment counter -- maybe something else else --***-- next 4 lines are all new to set up IntValue local intValueSetup = Instance.new("IntValue") -- make an IntValue to store data intValueSetup.Name = "timesClicked" -- name it so it's easier to access from other scripts intValueSetup.Value = 1 -- start at 1 because it was 0 and they just clicked --***-- using intValueSetup instead of 1 since it's an object now timesClickedTable[player.UserId] = intValueSetup -- put value in table for later end end) playerService.PlayerRemoving:Connect(function(player) -- when someone quits local pUserId = player.UserId if timesClickedTable[pUserId] then -- check how many times they clicked this session --***-- added .Value to check the IntValue's value rather than saving an object (doesn't work) timesClickedDS:IncrementAsync(pUserId, timesClickedTable[pUserId].Value) -- increment it to their saved data end end) -- in case of server crash or forced manual shutdown playerService.PlayerAdded:Connect(function(player) -- for each player while true do wait(300) -- every 300 seconds if timesClickedTable[player.UserId] then -- if there's any data --***-- added .Value to check the IntValue's value rather than saving an object (doesn't work) timesClickedDS:IncrementAsync(player.UserId, timesClickedTable[player.UserId].Value) -- save it to their datastore end end end)
As you can see, it is largely the same aside from adding .Value
to check the IntValue
's value and extra setup for the IntValue
since it's an object not just a number. If there's any confusion, I'll likely edit the post later.