Help with datastore

  1. What do you want to achieve? i want the game to save the number of studs walked

  2. What is the issue? it isn’t my area of expertise

  3. What solutions have you tried so far? everything, youtube, dev forums

local OldPosition = {}
local TotalStudsWalked = {}
game.Players.PlayerAdded:Connect(function(Player)
	local Board = Instance.new("Folder")
	Board.Name = "leaderstats"
	Board.Parent = Player
	local Traveled = Instance.new("IntValue", Board)
	Traveled.Name = "Studs"
end)
game.Players.PlayerRemoving:Connect(function(Player)
end)
while wait do
	for i,Player in pairs(game.Players:GetPlayers()) do
		if Player.Character then
			local Humanoid = Player.Character:FindFirstChildOfClass("Humanoid")
			if Humanoid.MoveDirection.Magnitude > 0 then
				if OldPosition[Player.UserId] then
					local newDistanceTravelled = (Humanoid.RootPart.Position - OldPosition[Player.UserId]).Magnitude
					TotalStudsWalked[Player.UserId] = TotalStudsWalked[Player.UserId] + newDistanceTravelled
					Player:WaitForChild("leaderstats").Studs.Value = Player.leaderstats.Studs.Value + (newDistanceTravelled / 1)
					OldPosition[Player.UserId] = Humanoid.RootPart.Position
				else
					TotalStudsWalked[Player.UserId] = 0
					OldPosition[Player.UserId] = Humanoid.RootPart.Position
				end
			end
		end
	end
	wait(0.1)
end
1 Like

To save the value use

DatastoreService:GetDataStore(youDataStore):SetAsync("a random key" , amountHeWalked)

And to load it use

DatastoreService:GetDataStore(youDataStore):GetAsync("a random key")

Its better to use Datastore2 (a module script) as its way more secure and no data loss will occur

2 Likes

I believe that is a typo, there.

1 Like

I know i missed the r but i just left it, he will change it to his Datastore name.

1 Like

I meant you missed the A in :GetAsync

2 Likes

If you need any help with dataStore2 feel free to dm me Msix29#7740

Lmao im sry

Ccccchhhhhhaaaaaarrrrsss

1 Like

Many people make the mistake by using too many datastores at once. Its better when creating one whole table for everything:

--Vars and Services
local DataStore = game:GetService("DataStoreService"):GetDataStore("MainDatastore")

--Functions
function formatData(player)

	local data = {}

	local YourFolder = player:WaitForChild("leaderstats")
	local steps = {}

	for i,piece in pairs(YourFolder:GetChildren()) do
		table.insert(steps, piece.Value)
	end

	table.insert(data, steps)
	return data
end

function saveData(player)
	local Key = "Player_"..player.UserId
	local stuffToSave = formatData(player)

	local succes, err = pcall(function()

		if stuffToSave then
			DataStore:SetAsync(Key, stuffToSave)
		end

	end)

	if err then
		warn('WARNING: COULD NOT SAVE PLAYER DATA: '..err)
	end
end

function loadData(player)
	--CREATING FOLDERS
	local Key = "Player_"..player.UserId

	local Board = Instance.new("Folder")
	Board.Name = "leaderstats"
	Board.Parent = player
	local Traveled = Instance.new("IntValue", Board)
	Traveled.Name = "Studs"
------------------------------------------------------------
	
	--GETTING PLAYER DATA
	local sucess, err = pcall(function()
		local data = DataStore:GetAsync(Key)
		if data then
			if data[1] then
				Traveled.Value = data[1][1] -- The first section of the folder, first value: FreeSkips
			else
				Traveled.Value = 0
			end
		else  -- if data doesn't exist         
			Traveled.Value = 0
		end
	end)

	if err then
		warn('WARNING: COULD NOT LOAD PLAYER DATA: '..err)
	end

end

function onServerShutdown()
	if game:GetService("RunService"):IsStudio() then
		wait(2)
	else
		for _, player in pairs(game.Players:GetPlayers()) do
			local finished = Instance.new("BindableEvent")

			saveData(player) --It's easier to use the previous saveData function on each player than it is to write new code

			finished.Event:Wait()
		end		
	end
end


--Binding Events
game:BindToClose(onServerShutdown)
game.Players.PlayerAdded:Connect(loadData)
game.Players.PlayerRemoving:Connect(saveData)



--



local OldPosition = {}
local TotalStudsWalked = {}
game.Players.PlayerAdded:Connect(function(Player)
	local Board = Player:WaitForChild("leaderstats")
	local Traveled = Board:FindFirstChild("Studs")
end)

while wait(0.1) do
	for i,Player in pairs(game.Players:GetPlayers()) do
		if Player.Character then
			local Humanoid = Player.Character:FindFirstChildOfClass("Humanoid")
			if Humanoid.MoveDirection.Magnitude > 0 then
				if OldPosition[Player.UserId] then
					local newDistanceTravelled = (Humanoid.RootPart.Position - OldPosition[Player.UserId]).Magnitude
					TotalStudsWalked[Player.UserId] = TotalStudsWalked[Player.UserId] + newDistanceTravelled
					Player:WaitForChild("leaderstats").Studs.Value = Player.leaderstats.Studs.Value + (newDistanceTravelled / 1)
					OldPosition[Player.UserId] = Humanoid.RootPart.Position
				else
					TotalStudsWalked[Player.UserId] = 0
					OldPosition[Player.UserId] = Humanoid.RootPart.Position
				end
			end
		end
	end
end

finished + fixed your script, everything should work as far as you progress and everything wil save. the function you made is at the end of the script so if it wasn’t finished that just change it :slight_smile:
Hope this helps (took me some time to make)

2 Likes

thank you, you have my gratitude

local Game = game
local Players = Game:GetService("Players")
local RunService = Game:GetService("RunService")

local Data = {}

local function OnPlayerAdded(Player)
	Data[Player] = Vector3.new(0, 0, 0)

	local Leaderstats = Instance.new("Folder")
	Leaderstats.Name = "leaderstats"

	local Studs = Instance.new("NumberValue")
	Studs.Name = "Studs"
	Studs.Parent = Leaderstats
	
	Leaderstats.Parent = Player
end

local function OnPlayerRemoving(Player)
	Data[Player] = nil
end

local function OnHeartbeat()
	for _, Player in ipairs(Players:GetPlayers()) do
		local Character = Player.Character
		if not Character then continue end
		local Position = Character:GetPivot().Position
		local Distance = (Data[Player] - Position).Magnitude
		if Distance == 0 then continue end
		Data[Player] = Position
		local Leaderstats = Player:FindFirstChild("leaderstats")
		if not Leaderstats then continue end
		local Studs = Leaderstats:FindFirstChild("Studs")
		if not Studs then continue end
		Studs.Value += Distance
	end
end

Players.PlayerAdded:Connect(OnPlayerAdded)
Players.PlayerRemoving:Connect(OnPlayerRemoving)
RunService.Heartbeat:Connect(OnHeartbeat)
1 Like

not sure if you’ll reply because this thread is very old but, the “studs meter” breaks once someone dies, how do I fix this?

What do you mean with studs meter? Is it the datastore or the script, which adds the studs? Maybe check for the output for errors :slight_smile:

The data store is fine, it’s the script adding the studs,
image
this is the error I am getting

Use the script of Forummers post, i tested it and it worked. The only error tho is that it adds studs if you jump

1 Like