Save every bool value with the same named located in a players gui

Screenshot 2022-09-21 113919

Hello, so i need to make a script that saves every bool value named “Ifequipped” thats located in the gui highlighted in blue.

if you decide to make the script for me, please tell me how you did it so that i can understand the base of it and know how to do it on my own next time.

Thanks!

Insert a LocalScript into the GUI. Use a for loop and loop through all the UI’s descendants by doing script.Parent:GetDescendants(). After that, check if v.Name is equal (==) to “Ifequipped”. If it is, insert it into a table that contains all the BoolValue’s values and send that table over a remote event to a ServerScript in ServerScriptService. Then you can save that data using DataStoreService and :SaveAsync() with the key being the player’s UserId, and then the data being saved being the table of BoolValues sent over the remote event.

I’m not gonna write an entire data saving system for you because that’s not what this category is for, I’m just providing you my thought process on how I would go about doing this.

Things to learn: DataStoreService, Remote Events, Loops.

If you have any questions on any part of this logic, feel free to ask and I’ll explain it best I can.

Alright, ill make the local script then check back with you!

Screenshot 2022-09-21 115758

Ok! im pretty new to this so correct me if im wrong, i tried my best

local data = {}

for i, v in pairs(script.Parent:GetDescendants()) do
	if v:IsA("BoolValue") then
		if v.Name == "IfEquipped" then
			table.insert(data, v.Value)
		end
	end
end

Now, the datastore script is what im going to need the most help on because im not that experienced with datastore. All i really know how to do is get the datastore script from the internet and change the script to fit my values

Your LocalScript looks great, you just need to use a RemoteEvent to send that table over to a ServerScript, because we can’t access DataStores on a LocalScript.

Would I would do here is create a RemoteEvent in ReplicatedStorage and then call :FireSever() for that event in your LocalScript. Inside your Serverscript, you’ll have to get the DataStoreService (I’m assuming you know how to get Services), and then create a new DataStore using by doing local BoolValueData = DataStoreService:GetDataStore(“BoolValueData”)
That should create a new DataStore for you to use. Inside your remote event, use a pcall function (pcall(function()end)) and inside of it, I would do BoolValueData:SetAsync(player.UserId, data). player.UserId should be whatever player was passed through the remote event automatically, and then data will be that data table you passed.

Also, like you said, go through tutorials and look at their code since what I explained above is very basic, and for a better and safer system you’ll need to add more to it.

1 Like

This is what i was able to do based off of what i understood in your message

ServerScript:

local BoolValueData = DataStoreService:GetDataStore("BoolValueData")

game.ReplicatedStorage.BoolValueSave.OnServerEvent:Connect(function(player, data)
	pcall(function()
		BoolValueData:SetAsync(player.UserId, data)
	end)
end)

LocalScript:

local data = {}

for i, v in pairs(script.Parent:GetDescendants()) do
	if v:IsA("BoolValue") then
		if v.Name == "IfEquipped" then
			game.ReplicatedStorage.BoolValueSave:FireServer(data)
			table.insert(data, v.Value)
		end
	end
end

Yep looks good. You should have every BoolValue saved now in your datastore. You can use a print statement after calling :SetAsync() just to be sure your data was saved, and then also print out data to make sure it’s being passed over the remote event correctly. Other than that, your basic saving system should be good now, you just have to load that data back up when you want.

Alright, so to be sure the part i just scripted saves all the value when the player leaves correct?

or is that part setting the data when the player joins the game?

The part you just scripted will save the values of every BoolValue in that GUI frame every time that remote event is called.

So if i want it to fire when the player leaves the game will this work?

local data = {}

game.Players.PlayerRemoving:Connect(function()
	for i, v in pairs(script.Parent:GetDescendants()) do
		if v:IsA("BoolValue") then
			if v.Name == "IfEquipped" then
				game.ReplicatedStorage.BoolValueSave:FireServer(data)
				table.insert(data, v.Value)
			end
		end
	end
end)

Yeah it should work if you format it like that.

Except you should put your :FireServer() call outside of the for loop.

Sorry I didn’t catch that at first.

Ok, Im going to put it below the for loop. Then for the player adding so it sets the data when the player joins again i should just do the same thing with a new remote event and just use GetAsync this time?

Pretty much, except remember you can’t access DataStores on LocalScripts, which means you’ll have to use a PlayerAdded event on the server, create a variable called “data” or something and assign it to BoolValueData:GetAsync(player.UserId) or {}. The reason why we do “or {}” is because if a new player joins, they aren’t going to have any data, so we need to just give them a blank table.

After you get the data, you could probably just use the same remote event, except fire it to the client that just joined the game by doing RemoteEvent:FireClient(player, data). This will send over the player’s boolvalue data from the datastore.

The only downside to this (and why I suggest doing your own research on DataStores and tables) is that you will probably have to manually assign each BoolValue value in the table you received in the LocalScript, to the corresponding BoolValue located in the GUI.

If you made your table into a dictionary with each Index in the dictionary being a unique name for each BoolValue, you could just loop through the data with a for loop, but I’m not gonna discuss that because I think it might be bit too advanced and I wouldn’t be able to explain it well.

Anyways, in your LocalScript, you can do RemoteEvent.OnClientEvent:Connect(function(data) to receive the data, then do what I said above and set each BoolValue’s value to the corresponding data value in your data table.

For example, to set Isequipped1’s value, you could do Isequipped1.Value = data[1]. data[1] represents whatever value is in the first index of your data table, so if the first value in the table is false, Isequipped1’s value would be set to false.

This is kind of long and hard to explain, so if you need elaboration on certain parts, feel free to ask or look it up on the internet.

Also, I’d like to note that you should add a check in your LocalScript onclientevent that checks if data is == to {}. If so, the player has no data so you should just set every BoolValue to a default one (most likely false).

Well this is dissapointing becuase im going to have at least more than 50 of those values in different guis and i dont want to have them assigned individually because that will take to much space. I could have done them individually without help but i wanted to know if theres a way to save all of them all together.

Yeah i dont think this is going to work out with my system because the bool value is for if the ability is equipped or not and i cant change the value to something thats not corresponding with my system else that will mess the entire thing up. Maybe if i got a regular datastore script from the internet we could use something like this a scripter gave me on a similar topic a while ago

local folder -- folder containing bool values
local dsService = game:GetService("DataStoreService")
local dataStore = dsService:GetDataStore("global")

local data = {} --stores all bool values
for i, v in pairs(folder:GetChildren())
    if v:IsA("BoolValue") then
        if v.Name == "IfEquipped" then
            table.insert(data, v.Value) -- insert bool to the "data" table
        end
    end
end

dataStore:UpdateAsync("key_userId", function(oldValue)
    local newValue = data or oldValue
    return newValue -- send bool table to data store
end)

The problem is i didnt and still dont know how to add or implement it into the datastore script that is most used for most datastores.

I think you could still make this work. What you could do is loop through your folder of BoolValues, then assign each BoolValue a value from the data table. For example:

for i, v in ipairs(FolderOfBoolValues:GetChildren()) do
     v.Value = data[i]
end

This will set each boolvalue’s value to the same BoolValue that you saved for it, you just have to make sure the order of the BoolValues in the GUI are the same when you save the data, and then when you load it. Put the for loop above in your OnClientEvent I discussed in my previous post.