Hello developers!
I recently ran into an issue with my code that I need help with. I wrote a script to save and load a players base for my game, the datastore saves by taking each of the children inside the player’s folder inside workspace (the folder contains each part of the players base) and saving it in a array. When it loads, it goes one by one through the array, checking if the name of the part contains “GRASS”, if so, then it creates the part with instances and sets its parent to the players folder. Just by reading what I said, some experienced developer out there reading this might be facepalming right now. One issue with this is when the player joins and leaves before the base can even load, all the progress is gone because the array is going to have player data, but its also going to be empty. I know that there is a way better way to what I’m doing. Like most newbie scripters, not the biggest knowledge on datastores. Not asking for anyone to write a script for me, but a guided explanation to solve my issue. Thank you.
Code –
-- Parent is ServerScriptService
local newplayer = ""
local distance = 0
local base = {}
local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("tybtojjbgbtgb")
local function onPlayerJoin(player) -- Runs when players join
-- Creates a folder for the base
newplayer = player.Name
local folder = Instance.new("Folder")
folder.Name = player.Name.. "'s Base"
folder.Parent = workspace
local playerUserId = "Player_" .. player.UserId --Gets player ID
local data = playerData:GetAsync(playerUserId) --Checks if player has stored data
if data then
-- Data exists for this player
base = data
else
-- Data store is working, but no current data for this player
base = {
GRASS1 = {0,0,0},
GRASS2 = {0,0,8},
GRASS3 = {0,0,-8},
GRASS4 = {8,0,0},
GRASS5 = {-8,0,0},
GRASS6 = {8,0,8},
GRASS7 = {8,0,-8},
GRASS8 = {-8,0,-8},
GRASS9 = {-8,0,8}
}
end
repeat wait() until player.Character
wait()
-- Loads in last saved base when player joins
--creation
local basepart = Instance.new("Part")
local basepartdesign = Instance.new("Decal")
basepartdesign.Face = Enum.NormalId.Top
basepartdesign.Texture = "http://www.roblox.com/asset/?id=9475664047"
basepartdesign.Transparency = 0.5
basepartdesign.Parent = basepart
basepart.Size = Vector3.new(800,0.1,800)
basepart.Anchored = true
basepart.Position = player.RespawnLocation.Position
basepart.Transparency = 1
basepart.CanCollide = false
basepart.Name = "BASEPART"
basepart.Parent = workspace:WaitForChild(newplayer.. "'s Base")
for key, value in pairs(base) do
local create = Instance.new("Part")
local decoration = Instance.new("Decal")
local clicked = Instance.new("ClickDetector")
local effect = workspace.BaseFunctions.EditLand:Clone()
decoration.Face = Enum.NormalId.Top
decoration.Texture = "http://www.roblox.com/asset/?id=19886465"
decoration.Transparency = 0.5
decoration.Name = "design"
decoration.Parent = create
clicked.CursorIcon = "http://www.roblox.com/asset/?id=9423559062"
clicked.MaxActivationDistance = 50
clicked.Parent = create
effect.Disabled = false
effect.Parent = clicked
if key:match("GRASS") then -- Checks for grass type
create.Material = Enum.Material.Grass
create.Size = Vector3.new(8,1,8)
create.BrickColor = BrickColor.new("Parsley green")
create.Anchored = true
create.Position = Vector3.new(table.unpack(value))
create.Position = Vector3.new(create.Position.X+player.RespawnLocation.Position.X,create.Position.Y,create.Position.Z)
create.Name = key
create.Parent = workspace:WaitForChild(newplayer.. "'s Base")
end
end
end
local function onPlayerExit(player) --Runs when players exit
local success, err = pcall(function()
local playerUserId = "Player_" .. player.UserId
local children = workspace[player.Name.. "'s Base"]:GetChildren()
local savebase = {}
for i = 1, #children do
savebase[children[i].Name] = {children[i].position.X-player.RespawnLocation.Position.X, 0, children[i].position.Z}
end
playerData:SetAsync(playerUserId, savebase) --Saves player data
end)
if not success then
warn('Could not save data!')
end
workspace:WaitForChild(player.Name.. "'s Base"):Destroy()
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)