Saving Tools With Profile Service

The title is exactly how it looks. How would I go about saving tools with ProfileService? I tried many things and they don’t seem to work and I’m very frustrated with it.

What type of saving are you trying to do?
What tools are you trying to save?
What is ProfileService?

I wasn’t trying to be specific because I have a lot to say, but decided that I don’t want to overflow with information. But here goes:

Ok so I have a shop where you purchase bats. When the player has enough Gold it’s supposed to save the tool name in a table. Here is the code I have tried:

local Template = {
	Gold = 250,
	Emeralds = 0,
	Kills = 0,
	Level = 1,
	XP = 100,
	MaxXP = 100,
	Bats = {}
}

So this code will save the “Bats” table.

Next I will check if the player has enough stats:

function module.CheckBatInfoForPurchase(plr, Toolname, price, spd, dmg)
	local data = module:Get(plr)

	if plr then
		for i, v in pairs(module.BatInfo) do
			
			if v.batName == Toolname and v.Price == tonumber(price) and v.attackRate == tonumber(spd) and v.Damage == tonumber(dmg) then
				print("Joe mama")
				Toolname = v.batName
				price = v.Price
				spd = v.attackRate
				dmg = v.Damage

				if plr.leaderstats.Gold.Value >= price then
					local bat = getBat(Toolname)
					plr.leaderstats.Gold.Value -= price
					table.insert(data.Bats, Toolname) -- This causes the error
					print(data.Bats)
				end
			end
		end
	end
end

Error:

ServerScriptService.ServerModules.MainModule:406: invalid argument #1 to 'insert' (table expected, got number)

As you can see “data.Bats” will return an int value and not a table, but originally in the “Template” I put a table.

Have you tried printing data?
Printing tables will only work if you turn off log mode in the output window.

Yes. Data will print all of the stats and for some reason the “Bats” table is just a straight int value not a table.

Can I see the module:Get() function?

function module:Get(plr)
	local profile = Profiles[plr]
	
	if profile then
		return profile.Data
	end
end

The profiles table is just a table of all the players data. and Profiles[plr] retrieves all the data in the "Template" table

Print every time you use the table and see where it turns into an int

Wait scratch that. It turns to int when joining as well.

print(profile.Data.Bats)

This will return “0”

One more thing when printing “profile.Data” it will return this:

{
                    ["Bats"] = 0,
                    ["Emeralds"] = 0,
                    ["Gold"] = 4991000,
                    ["Kills"] = 0,
                    ["Level"] = 1,
                    ["MaxXP"] = 100,
                    ["XP"] = 100
                 }

As you can see “Bats” is no longer a table and is now an int value. I hate this so much and I’m so confused.

This is pretty weird, tables turning into ints, what method are you using to store the table? Are you using instances like NumberValue and StringValue?

also, what is ProfileService? I have never heard of it and knowing about it might help solve the problem

Ok basically I’m storing any values inside a table then updating the value every time its changed. For example the “Teplate” Table:

local Template = {
	Gold = 250,
	Emeralds = 0,
	Kills = 0,
	Level = 1,
	XP = 100,
	MaxXP = 100,
	Bats = {}
}

These values will be sent to every player in a form of a folder, and then it will save. I thought since “Bats” was a table it will just save.

So you said the values will be sent in a folder?
Here is a possible way to store bats as a table:
image

Yeah Im currently attempting this as well. When a player buys a bat Im gonna parent a string value into the plr. After that I checked BatsFolder.ChildAdded then inserted the child’s name into the “Bats” table. I don’t know how to save things inside a table though.

finally, something I can write a script for!

function getDataTable(folder)
	local out = {}
	for _, p in pairs(folder:GetChildren()) do
		if p:isA("Folder") then
			out[p.Name] = getDataTable(p)
		else
			out[p.Name] = p.Value
		end
	end
	return out
end

function setDataTable(table) -- untested
	local out = Instance.new("Folder")
	for i, v in pairs(table) do
		if typeof(v) == "table" then
			local newFolder = setDataTable(v)
			newFolder.Name = i
			newFolder.Parent = out
		elseif typeof(v) == "string" then
			local newValue = Instance.new("StringValue")
			newValue.Name = i
			newValue.Value = v
			newValue.Parent = out
		elseif typeof(v) == "number" then
			local newValue = Instance.new("NumberValue")
			newValue.Name = i
			newValue.Value = v
			newValue.Parent = out
		end
	end
	return out
end

outputs:

{
   ["Bats"] = {
      ["bat1"] = "Papier-mâché bat",
      ["bat2"] = "baseball bat",
      ["bat3"] = "big bat"
   },
   ["Emeralds"] = 0,
   ["Gold"] = 0,
   ["Kills"] = 0,
   ["Level"] = 0,
   ["MaxXP"] = 0,
   ["XP"] = 0
}

No this isn’t my problem. My problem is saving tools with the data given. When a player joins I want to take the data from the “Bats” table and make a string value out of it. Here is my attempt, but the values inside the table will not save.

local BatsFolder = Instance.new("Folder", plr)
			BatsFolder.Name = "BatsFolder"

			Profiles[plr] = profile
			
			BatsFolder.ChildAdded:Connect(function(child)
				table.insert(profile.Data.Bats, child.Name)
			end)
			
			for i, v in pairs(profile.Data.Bats) do
				local str = Instance.new("StringValue", BatsFolder)
				str.Name = v
			end

That’s because when you add the string values, they are named “StringValue” by default. Set the name before the parent, then they will save.

Write a failsafe.

if typeof(data.Bats) ~= 'table' then
data.Bats = {};
end

Nevermind I got it to work. Eventually I just rewrote my code to make it cleaner and it worked. I just kept the same code and it worked… Weird, but it works. I just stored a table in the Template called “Bats” and then inserted the string value into the table when they buy a bat. It saves when they join back too.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.