This only runs once: when the server script starts. Meaning after everyone loads in, they’re going to have the exact same ‘random’ plot.
You shouldn’t update a data store right after the value changes, that’s the fastest way to fill your data store queues. You should save the player’s data when the leave/get disconnected
You should be using protected calls because DataStore:GetAsync() and DataStore:SetAsync() can both fail and break your script
Can’t you just use 1 data store and save a table into it?
This. Also (this is just a small note) using Instance.new()'s second parenting parameter isn’t recommended. It’s been proven to cause significant latency. Parent your objects at the end rather then right after calling Instance.new()
-- services here
local dss = game:GetService("DataStoreService")
local serverStorage = game:GetService("ServerStorage")
local players = game:GetService("Players")
-- data stores
local ds1 = dss:GetDataStore("GemSaveSystem")
local ds2 = dss:GetDataStore("CashSaveSystem")
local ds3 = dss:GetDataStore("jb")
local Plots = workspace.Plots -- using the "workspace" global is much faster
local PlotsInUse = workspace.PlotsInUse
local StarterHouse = serverStorage:WaitForChild("Houses").StarterHouse:Clone()
-- uses "WaitForChild" because the "Houses" instance could possibly not load
local DFChildren = Plots:GetChildren() -- Returns a table
local function SetAsync(dataStore, key, value)
local success, err = pcall(function()
dataStore:SetAsync(key, value)
end)
if not success then
warn(err) -- like the GetAsync function, tell you why something fails
end
end
players.PlayerAdded:Connect(function(plr) -- not exactly sure why you had 2 player arguments
-- "connect" is deprecated, you should use the PascalCase API
local random = DFChildren[math.random(1, #DFChildren)]
-- as Toidit said, don't use the parent argument
local folder = Instance.new("Folder")
folder.Name = "leaderstats"
folder.Parent = plr
local gems = Instance.new("IntValue")
gems.Name = "House"
gems.Parent = folder
local cash = Instance.new("IntValue")
cash.Name = "Cash"
cash.Parent = folder
local jb = Instance.new("IntValue")
jb.Name = "jb"
jb.Parent = folder
local function GetAsync(dataStore, key)
local success, err = pcall(function() -- this is a protected call
return dataStore:GetAsync(key)
end)
if not success then
warn(err) -- in case it fails, tell you why
err = nil
end
return err
end
gems.Value = GetAsync(ds1, plr.UserId) or 0
cash.Value = GetAsync(ds2, plr.UserId) or 0
jb.Value = GetAsync(ds3, plr.UserId) or 0
if folder.jb.Value == 0 then
print("Never Joined Before")
folder.House.Value = 1
folder.Cash.Value = 10000
folder.jb.Value = 1
else
print("Joined Before")
end
if folder.House.Value == 1 then
StarterHouse.Parent = workspace
StarterHouse:SetPrimaryPartCFrame(random.CFrame)
random.Parent = PlotsInUse
end
end)
local function PlayerRemoving(player)
-- function for when the player leaves
local ls = player:WaitForChild("leaderstats")
local cash = ls.Cash
local jb = ls.jb
local gems = ls.House
-- save everything
SetAsync(ds1, plr.UserId, gems.Value)
SetAsync(ds2, plr.UserId, cash.Value)
SetAsync(ds3, plr.UserId, jb.Value)
end
players.PlayerRemoving:Connect(PlayerRemoving) -- detect if a player leaves
game:BindToClose(function()
-- this saves everyone's data incase the server closes unexpectedly
for _, plr in pairs(players:GetPlayers()) do
PlayerRemoving(plr)
end
end)
P.S. You should test data stores in a live server, not studio