Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why is DataStore not saving the Stats and Tool BoolValues?

Hello!

Problem: DataStore is not saving the Tools of players when they die/leave the game, and is also not saving the Leaderstats when a player leaves and returns. Also, when a player purchases the Tools, it continues to clone infinitely until a player dies, at which point the Tools disappear from the Backpack, but remain inside StarterPack.

There is a Folder inside** StarterPack** named "Inventory" that has BoolValues: HasM9, HasPistol, HasAK, etc.

These BoolValues are turned into True when a Player purchases an item from the Shop: SHOP Script:

--Shop Purchase Script Above
if plr.leaderstats.Points.Value >= amount then 
 	tool:Clone().Parent = plr.Backpack
            tool:Clone().Parent = plr.StarterGear
            plr.leaderstats.Points.Value = plr.leaderstats.Points.Value - amount
			plr.Backpack.Inventory.HasM9.Value = true
	else 
--Shop Purchase Script Below

Inside of ServerScriptStorage I have the following Module Script as my DataStore Script DataStore Script:

https://pastebin.com/AjGkFyi2 (my script goes way past the 10,000 character limit, including it as an external link.)

As a descendant of this Module Script is a short Script:

require(script.Parent)

Now, to ensure that the purchased Tools are given to the player is a Local Script inside StarterPlayer - StarterPlayerScripts named ToolGiverCheck.

ToolGiverCheck Script:

local player = script.Parent.Parent
local rs = game:GetService("ReplicatedStorage")
while wait(1) do
	if player.Backpack.Inventory.HasM9.Value == true then
	    local m9 = rs.M9:Clone()
	    m9.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasPistol.Value == true then
		local pistol = rs.Pistol:Clone()
		pistol.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasM4.Value == true then
		local m4 = rs.M4:Clone()
		m4.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasShotgun.Value == true then
		local shotgun = rs.Shotgun:Clone()
		shotgun.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasSuperball.Value == true then
		local superball = rs.Superball:Clone()
		superball.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasRocketLauncher.Value == true then
		local rocketlauncher = rs.RocketLauncher:Clone()
		rocketlauncher.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasGoldenGun.Value == true then
		local goldengun = rs.GoldenGun:Clone()
		goldengun.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasBombthrower.Value == true then
		local bombthrower = rs.BombThrower:Clone()
		bombthrower.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasAK.Value == true then
		local ak = rs.AK:Clone()
		ak.Parent = player.Backpack
	end
	if player.Backpack.Inventory.HasFireball.Value == true then
		local fireball = rs.Fireball:Clone()
		fireball.Parent = player.Backpack
	end
end

Summarized Question: How do I fix my scripts so that the Player is able to retain their Tools after death, and that their Leaderstats save when they leave/return to the game?

I owe abnotaddable a big thank you for all the help that's been provided so far. :) I know this script is close to being working, just need a bit more help. Thank you so much in advance to everyone who's given/will give assistance.

4 comments

0

I think I know why its infinitely cloning

0

I will do this and make sure that it works with fe as well

1

I have wrote the the data stores, but I had to use pastebin

0

Commented in response to your answer with follow-up questions! :) Thank you again!

1 answer

✓ Accepted answer

Hello again!
I will try to make this question as clear as possible!
Firstly we want to set up our Remote Event. To do this, insert a Folder into Replicated Storage. Name this Folder "Events". Inside of our folder we want to insert a Remote Event. Name this Remote Event "ToolPurchase".
Next, in Server Script Service, we want to insert a Script. Name this script "Event Handler". Inside of our script we want to define a few variables:

--//Get Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--//EventFolder
local Events = ReplicatedStorage:WaitForChild("Events")
--//Events
local ToolPurchase = Events:WaitForChild("Events")

Then we want to create a listener function:

ToolPurchase.OnServerEvent:Connect(function(Player, Tool, Value, Amount)  --When we fire the server (ToolPurchase:FireServer()), three arguments will be passed: The tool name, the value to change and the amount to take away. E.g : ToolPurchase:FireServer("M9", HasM9, amount), the server will do the rest for you, so DO NOT change any of the following code.
	
end)

Then we need to add the tool purchase process

ToolPurchase.OnServerEvent:Connect(function(Player, Tool, Value, Amount)
	local Clone = ReplicatedStorage:FindFirstChild(Tool):Clone() --Find the tool and Clone it
	if not(Player:WaitForChild("Backpack"):FindFirstChild(Tool)) then --If they do not have the tool
		Clone.Parent = Player:WaitForChild("Backpack") --Clone it to the PLAYERS BACKPACK (NOTE: Players do not have a "StarterPack", and StarterPack intended
		--Use is to clone the tools inside to EVERY player when they die/join. So you must use Player.Backpack)
		Player.leaderstats.Points.Value = Player.leaderstats.Points.Value  - Amount --Subtract money from the player
		Value = true --Set the value to true
	else
		print(Player .. " Already Owns: " .. Tool) --If they already have the tool
	end
end)

The whole script should be:

--//Get Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--//EventFolder
local Events = ReplicatedStorage:WaitForChild("Events")
--//Events
local ToolPurchase = Events:WaitForChild("Events")

ToolPurchase.OnServerEvent:Connect(function(Player, Tool, Value, Amount)
	local Clone = ReplicatedStorage:FindFirstChild(Tool):Clone()
	if not(Player:WaitForChild("Backpack"):FindFirstChild(Tool)) then
		Clone.Parent = Player:WaitForChild("Backpack")
		Player.leaderstats.Points.Value = Player.leaderstats.Points.Value  - Amount
		Value = true
	else
		print(Player .. " Already Owns: " .. Tool)
	end
end)

Note: You should not change any of the above code.
Next, assuming your "Shop purchase Script" is a local script and inside of a gui, We can do the following code (Note: It is much more efficient to have one local script, that control lots of GUIs, than lots of local script that only control one GUI.)
In our script:

--//Get Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
--//EventFolder
local Events = ReplicatedStorage:WaitForChild("Events")
--//Events
local ToolPurchase = Events:WaitForChild("Events")
--//Guis
local ScreenGui = script.Parent
local m9button = ScreenGui:WaitForChild("m9button") --change this to wherever the button is located
m9button.MouseButton1Click:Connect(function()
	local amount = 100
	if Player.leaderstats.Points.Value >= amount then
		ToolPurchase:FireServer("M9", Player.Backpack.Inventory.HasM9.Value, amount)
	end
end)

Then inside of our ToolGiverCheck(Remove previous code):

local player = game:GetService("Players").LocalPlayer
local rs = game:GetService("ReplicatedStorage")

player.CharacterAdded:Connect(function(character) --When the character is loaded
	if player.Backpack.Inventory.HasM9.Value == true then
      	  local m9 = rs.M9:Clone()
      	  m9.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasPistol.Value == true then
        local pistol = rs.Pistol:Clone()
        pistol.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasM4.Value == true then
        local m4 = rs.M4:Clone()
        m4.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasShotgun.Value == true then
        local shotgun = rs.Shotgun:Clone()
        shotgun.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasSuperball.Value == true then
        local superball = rs.Superball:Clone()
        superball.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasRocketLauncher.Value == true then
        local rocketlauncher = rs.RocketLauncher:Clone()
        rocketlauncher.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasGoldenGun.Value == true then
        local goldengun = rs.GoldenGun:Clone()
        goldengun.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasBombthrower.Value == true then
        local bombthrower = rs.BombThrower:Clone()
        bombthrower.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasAK.Value == true then
        local ak = rs.AK:Clone()
        ak.Parent = player.Backpack
    end
    if player.Backpack.Inventory.HasFireball.Value == true then
        local fireball = rs.Fireball:Clone()
        fireball.Parent = player.Backpack
    end
end)

And thats it for the tool purchase! You do not need to change any of the code (apart from paths to objects, e.g game.Workspace.Part).
For the DataStore I am going to focus on the player added function. Which goes like this:

https://pastebin.com/KaGvy1Y8

Im not going to write the whole thing, but I will show you how it should be wrote (again, but working).

https://pastebin.com/pymZ49MU

You'll notice I have only done it for the first three. Do this for the rest of them, but make sure that When setting the value (e.g: val = false), make sure it is the right kind of value. e.g boolvalues must use false and true. int values must use numbers
EDITS:
https://pastebin.com/PDRrRrsR --Global death script
When I was looking at your place, you did what I said not to which was to create multiple local scripts and not jsut one. its okay to have 1 or 2 but not like 17!! xd
Also, the reason its not saving is because the values are not actually being changed on purchase.
https://pastebin.com/YPiic4aq --here's what the purchase should actually look like
also the event handler:
https://pastebin.com/zrNteZxS
also your heal pad script I fixed:
https://pastebin.com/AiX7LzCA
I also noticed that when you die I get the error "roblox needs to quit! we're sorry!" error, so make sure to save and publish before you test!
--every time I try to fix it roblox studio crashes

22 comments

0

Excellent!!! :D Thank you again good sir, I eagerly await your followup!

0

Thank you so much for this! I've done as you've graciously advised. I'm getting an error right off though when loading the ToolDataStore script: 22:52:53.464 - Module code did not return exactly one value 22:52:53.465 - Requested module experienced an error while loading 22:52:53.465 - Stack Begin 22:52:53.465 - Script 'ServerScriptService.ToolsDataStore.Script', Line 1 22:52:53.466 - Stack End

0

^ after getting that error, leaderstats doesn't load, and everything else doesn't work. o.o I still have the descendant script with the line: require(script.Parent) - which appears to be what the stack end is referring to. I'm not sure why it would say "Module code did not return exactly one value" though...

0

Also getting this when I try to make a purchase: 23:34:30.920 - Infinite yield possible on 'ReplicatedStorage.Events:WaitForChild("Events")'

1

1st reason is that that is ONLY the player added function. you need to add the player removed function and the auto save at the end of the script (leave plr remove and autosave unchanged) then put return module at the bottom

1

2nd reason is my mistake. it should be : local ToolPurchase = Events:WaitForChild ("ToolPurchase")

1

you need learn variables.

0

Had a big ol' dose of stupid I did not noticing the PlayerRemoved part wasn't in the DataStore. XD; Thank you so much. I went and added the rest, made the proper edits. I also redid my entire Shop Gui system to be more efficient as you recommended. I previously had a Local Script for every single item, instead of one Local Script for everything. Definitely prefer that after doing that.

0

The only problem is that its still not saving the Stats/Tools when a player Respawns or Leaves the game, its all gone. I really appreciate all the help you've shown me so far, and hoped you could take one last look at my game. I uploaded the .lua file here: https://ufile.io/muovx

0

My only thought is the Global Death Script may be preventing it saving properly. Its a Script under Workspace, and its required for the MainRounds script to work properly, but it does get an error, here's the script and the error line: https://pastebin.com/d6Z9ch2v I think this might be the final stumbling block...if so, it means I can finally get my game back online. T_T Thanks to your help.

0

(I went ahead and Accepted the answer here, I'm grateful for all your help, and you've provided all the answers needed that should make this thing work.)

0

Ignore that first upload link, this one is the correct one: https://ufile.io/pg3me Sorry about that, made a quick change, that had no impact on the rest.

1

Global death script should not be the problem, will look at the place later

0

hopefully this should now work

0

Hello good sir! :D Many thanks as always. ...you mean 17 local scripts is too many? XD I've updated the scripts as you've provided. Many thanks for the Global Death Script and Heal pad fixes!! I've made the edits, saved and published, the ToolsDataStore is printing properly, it says the stats were saved,but when the player dies, the Tools are still gone, and when the player leaves,the Stats reset.

0

Were you able to get it to save when you tried it? :/ I re-uploaded the file - https://ufile.io/0sc8l Is there something I'm missing here? >.<

0

...could it be that the datastore name isn't long/unique enough? Would that make a difference? o.o

1

no lol

0

Well darn. Any idea what's wrong with it? XD

1

Have you got API Access enabled?

1

ok, sice I really cba to make any more code for you (I litterally have gone WAY past how much anyone would EVER help you) i don't want to write anymore

0

I do have it. You're absolutely correct, you have gone far above and beyond what anyone else would have, and I thank you for that. I'm grateful for your time and kindness. :) I won't ask anymore. Thank you again for all the assistance. I hope I can one day do the same.

This discussion is preserved as it was. New answers, comments, and votes are closed.