-
What do you want to achieve? Keep it simple and clear!
So basically i need to make weapon loadout table for my new FPS game, when i click button it should change [“Primary”] Array to An weapon from GUI and etc, but exact problem what i have no idea how to store it to datastore, in case i need to save it across servers.
-
What is the issue? Include screenshots / videos if possible!
Described in 1
-
What solutions have you tried so far? Did you look for solutions on the Developer Hub? I tryed to use objectValue, but i can’t add arrays there
Datastore code:
local playersService = game:GetService("Players")
local dataStores = game:GetService("DataStoreService")
local dataStore = dataStores:GetDataStore("DataStore")
local protectedCall = pcall
local function onPlayerJoined(player)
local StatsFolder = Instance.new("Folder")
StatsFolder.Parent = player
StatsFolder.Name = "StatsFolder"
local PlrExp = Instance.new("NumberValue")
PlrExp.Parent = StatsFolder
PlrExp.Name = "PlrExp"
local PlrLevel = Instance.new("NumberValue")
PlrLevel.Parent = StatsFolder
PlrLevel.Name = "PlrLevel"
local RequiredExp = Instance.new("NumberValue")
RequiredExp.Parent = StatsFolder
RequiredExp.Name = "RequiredExp"
local success, result = protectedCall(function()
return dataStore:GetAsync("Data_"..player.UserId)
end)
if success then
if result then
if type(result) == "table" then
PlrExp.Value = result[1] or 0
PlrLevel.Value = result[2] or 1
RequiredExp.Value = result[3] or 500
end
end
else
warn(result)
end
end
local function onPlayerLeft(player)
local success, result = protectedCall(function()
return dataStore:SetAsync("Data_"..player.UserId, {player.StatsFolder.PlrExp.Value,player.StatsFolder.PlrLevel.Value,player.StatsFolder.RequiredExp.Value
})
end)
if success then
print(result)
print("Everything success")
else
warn(result)
warn("everything wrong")
end
end
local function onServerClosed()
for _, player in ipairs(playersService:GetPlayers()) do
local success, result = protectedCall(function()
return dataStore:SetAsync("Data_"..player.UserId, {player.StatsFolder.PlrExp.Value,player.StatsFolder.PlrLevel.Value,player.StatsFolder.RequiredExp.Value
})
end)
if success then
print(result)
else
warn(result)
end
end
end
playersService.PlayerAdded:Connect(onPlayerJoined)
playersService.PlayerRemoving:Connect(onPlayerLeft)
game:BindToClose(onServerClosed)
Note: Also i wanna this method be efficient(fast readable by other script)
so to save a table we are just, going to give it a table, call it data, and save it
local plrUserId = "Player_"..plr.UserId
local data = {}
-- set data to whatever you use, for my example its an inventory value
-- data = invhandler:GetInv(plr)
-- which returns a table like such
--[[
inventory = {
Items = {
item1 = {},
item2 = {}
]
}
]]
local Success, Error_Message = pcall(function()
MainDataStore:SetAsync(plrUserId, data)
print("Successfully saved ".. plr.Name.."'s data!")
end)
and for loading, we do generally the same thing
local plrUserId = "Player_".. plr.UserId
local User_Data = nil
local Success, Error_Message = pcall(function()
User_Data = MainDataStore:GetAsync(plrUserId)
end)
if Success == true then
if User_Data == nil then
-- load starter data
else
-- load their saved data
end
print("Successfully loaded ".. plr.Name.."'s data!")
end
Im happy to help with any issues in the reply
but pretty much you just give it a table to save
And in the saving data function in my example its an inventory, you could have a function called “getPlrWeapons” or something which returns a table to save
Weapons = {
Primary = “gun1”,
Secondary = “gun2”
}
etc
1 Like
Well, but there is already DS script, and this is different one, how could i implement them into each other?
EDIT: I just don’t wanna add a tons of script which could be implemented in one, so i won’t get lost in them lol
you mean keep all datastores inside the same script? I normally keep them in seperate scripts as its easier to work on and debug imo, but you could just use a for loop or something of the kind and save each value that you need to
Oh hmm, is this isn’t 2 datastore requests in same moment? On my main DS i save a big table and then get it, it is 1 datastore request, or i’m wrong?
so instead you are trying to save something of the such?
local plrData = {
Weapons = {},
EXP = {},
Level = {}
}
This would work using the way that I described in my first post, just instead of the weapons taking up the entire table add them into the sub-table that holds the weapons
Here is my datasatore script, maybe you didn’t saw it:
local playersService = game:GetService("Players")
local dataStores = game:GetService("DataStoreService")
local dataStore = dataStores:GetDataStore("DataStore")
local protectedCall = pcall
local function onPlayerJoined(player)
local StatsFolder = Instance.new("Folder")
StatsFolder.Parent = player
StatsFolder.Name = "StatsFolder"
local PlrExp = Instance.new("NumberValue")
PlrExp.Parent = StatsFolder
PlrExp.Name = "PlrExp"
local PlrLevel = Instance.new("NumberValue")
PlrLevel.Parent = StatsFolder
PlrLevel.Name = "PlrLevel"
local RequiredExp = Instance.new("NumberValue")
RequiredExp.Parent = StatsFolder
RequiredExp.Name = "RequiredExp"
local PlayerLoadout = {
["Primary"] = {"AK105"},
["Secondary"] = {"Glock19"},
["Knife"] = {"Karambit"}
} -- Here is Loadout table
local success, result = protectedCall(function()
return dataStore:GetAsync("Data_"..player.UserId)
end)
if success then
if result then
if type(result) == "table" then
PlrExp.Value = result[1] or 0
PlrLevel.Value = result[2] or 1
RequiredExp.Value = result[3] or 500
end
end
else
warn(result)
end
end
local function onPlayerLeft(player)
local success, result = protectedCall(function()
return dataStore:SetAsync("Data_"..player.UserId, {player.StatsFolder.PlrExp.Value,player.StatsFolder.PlrLevel.Value,player.StatsFolder.RequiredExp.Value
})
end)
if success then
print(result)
print("Everything success")
else
warn(result)
warn("everything wrong")
end
end
local function onServerClosed()
for _, player in ipairs(playersService:GetPlayers()) do
local success, result = protectedCall(function()
return dataStore:SetAsync("Data_"..player.UserId, {player.StatsFolder.PlrExp.Value,player.StatsFolder.PlrLevel.Value,player.StatsFolder.RequiredExp.Value
})
end)
if success then
print(result)
else
warn(result)
end
end
end
playersService.PlayerAdded:Connect(onPlayerJoined)
playersService.PlayerRemoving:Connect(onPlayerLeft)
game:BindToClose(onServerClosed)
EDIT: I added loadout table to this script exactly.
try changing playerloadout to a playerdata table, and hold all player data inside of that for saves and loads, this way its 1 data save request with 1 table and it saves everything in the same place
backend tables dont seem to be working too well for you, so there is another way. you make a folder under the player called “PlrWeapons” or whatever, add string values “Wep1” and “Wep2” (primary secondary), and save those the exact same way you save the rest of your leaderstats, forgetting the table issue
1 Like
Ughh, i didn’t understand sorry, i’m still new to datastores and tables, i know them a bit bad.
Oh well, i think i will use it, it’s way easier for me to understand, i always have problem with saving table to datastore. Thanks, lemme try it.
1 Like
Well, maybe i did something wrong, but getting loadout name and getting weapon from pack doesn’t seems to work, here scripts:
Local Script which fires server to give loadout:
local Button = script.Parent
local GUI = script.Parent.Parent.Parent
local BlueTeam = game.Teams.BLUE
local Player = game.Players.LocalPlayer
local cc = workspace.CurrentCamera
local mc = workspace.MenuCamera
local Slots = Player.PlayerGui.CustomHotBarGui.Slot
local GameGUI = script.Parent.Parent.Parent.Parent.GameGUI
local GetLoadoutEvent = workspace.RemoteEvents.GetLoadout
Button.MouseButton1Click:Connect(function()
Player.Team = BlueTeam
GUI.Enabled = false
if GameGUI.Enabled == false then
cc.CameraType = Enum.CameraType.Custom
Player.CameraMode = Enum.CameraMode.LockFirstPerson
if workspace:FindFirstChild("Map") then
Player.Character.HumanoidRootPart.CFrame = workspace.Map.BlueSpawn.CFrame
end
for i,slots in ipairs(Slots:GetChildren()) do
slots.Visible = true
end
end
GetLoadoutEvent:FireServer() -- Here event fired
end)
Btw , There is 2 buttons.
Here is server script:
local GetLoadoutEvent = workspace.RemoteEvents.GetLoadout
local Weapons = game.ReplicatedStorage.ImplementedWeapons
GetLoadoutEvent.OnServerEvent:Connect(function(plr)
local Loadout = plr.LoadoutFolder
local PrimaryWeapon = Loadout.Primary
local SecondaryWeapon = Loadout.Secondary
local KnifeType = Loadout.KnifeType
if Weapons:FindFirstChild(tostring(PrimaryWeapon)) then
local PWeapon = Weapons:FindFirstChild(tostring(PrimaryWeapon))
local PWeaponClone = PWeapon:Clone()
PWeaponClone.Parent = plr.Backpack
local PWeaponClone2 = PWeapon:Clone()
PWeaponClone2.Parent = plr.StarterGear
end
if Weapons:FindFirstChild(tostring(SecondaryWeapon)) then
local SWeapon = Weapons:FindFirstChild(tostring(SecondaryWeapon))
local SWeaponClone = SWeapon:Clone()
SWeaponClone.Parent = plr.Backpack
local SWeaponClone2 = SWeapon:Clone()
SWeaponClone2.Parent = plr.StarterGear
end
if Weapons:FindFirstChild(tostring(KnifeType)) then
local Knife = Weapons:FindFirstChild(tostring(KnifeType))
local KnifeClone = Knife:Clone()
KnifeClone.Parent = plr.Backpack
local KnifeClone2 = Knife:Clone()
KnifeClone2.Parent = plr.StarterGear
end
end)
what I meant to do was something like this
game.Players.PlayerAdded:Connect(function(plr)
local weps = Instance.new("Folder")
weps.Name = "Weapons"
weps.Parent = plr
local wep1 = Instance.new("StringValue")
wep1.Name = "Wep1"
wep1.Parent = weps
local wep2 = Instance.new("StringValue")
wep2.Name = "Wep2"
wep2.Parent = weps
end)
I done that, datastore works fine, There is some error with giving loadout to player script
I also tryed use local script, still nothing
Oh well, forgot to add .value at end, now it works. Thank you for help!