How to make weapon loadout table

  1. 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.
  2. What is the issue? Include screenshots / videos if possible!
    Described in 1
  3. 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!