So I want everything to save onto a table:
I am new to scripting would the best way to save a players inventory be through a folder or a table?
and how would I go about saving the players item stats, so say for example they upgraded there sword and now it does more damage how would i get it save the stats of the weapon?
You should use data store with module script as well, for an example you should create “Damage” value and put it in data store also and re-script your weapones with dmg function, also don’t forget use game:BindToClose() if you want save your data even if you’re able shutdown the servers. Example: Damage = 10 – starter dmg, when they upgrading something you should add up value to dmg for an example: Damage.Value = Damage.Value +or*(upg value). The best way to save plrs inv is table for sure, pretty easy use and understand it.
game:BindToClose(function()
for i, p in pairs(Players:GetChildren()) do
saveData(p)
end
end)
This is what I have for bindToClose, but would I require a module script in the datastore script or would i get the datastore in the module script.
You should get the datastore in module script for sure, since you’re saving table values so it will work pretty good. For an example:
function saveStats(player)
local default_player_save_table = player_saves_DSS:GetAsync(player.UserId) or nil
player_saves_DSS:SetAsync(player.UserId, default_player_save_table)
So in a module script I would have a function called UpgradeWeapon(weapon, player)
and inside I would get the upgrade value and just added it to the weapon and save that weapon.
If this is the case how would It get added back if the player leaves and joins back, because since this is a table I would make a for loop that loops a folder with weapons and then surely the weapon would be a default one right? Unless I have to save each stat of a weapon separately. I’m confused
Yeah you should add values such as like: "Weapones{default} and if they upgading it then you need add it to table in player stat, so you also need add a function “UpgradeWeapon” and every weapon has dmg.Value so they can use it well. If you’re talking about joins and back with their old weapon, then you should use: “EquippedWeapon” value like: “EquippedWeapon = default” so people would always use it before he will upgrade/equip other sword as well.
–testing
local player_save_table = {
['EquippedSword'] = Default,
['Damage"] = 10,
So a player joined they were new and had enough to upgrade their sword, they go to upgrade and lets say there current sword damage is 10 and when they upgrade it will be 12 and now they leave, and then when they join back they should have that weapon with the 12 damage. I am still a bit confused sorry.
Of course they will have that sword with damage if you used the “EquippedSword” value since when people joining. It will auto give to them their weapon with damage. For an example you can make a table for swords with damage such like: "Default sword = 10-- dmg’, “Advanced Sword = 12” and etc.
equipped_Sword.Value = player_save_table['EquippedSword']
equipped_Damage.Value = player_save_table['EquippedDamage']
local equippedSword = player:FindFirstChild('EquippedSword')
local sword_clone = swords:FindFirstChild(store_tables['SwordsList'][equippedSword.Value]
['Name']):Clone()
local welds = Instance.new('Folder', sword_clone)
welds.Name = 'Welds'
I recommend using the Datastore2 module for this. You can use Datastore2.Combine(“Inventory”, “Gold”, “Armour”, “Potions”, “Weapons”) to put them all into one easy to use datastore (named inventory). also Datastore2 is extremely unlikely to have any issues like data loss, and is faster when handling with multiple datastores.
I made an inventory with a system like this. see below
local HttpService = game:GetService("HttpService")
local players = game:GetService("Players")
local Datastore2 = require(1936396537) -- get datastore2 module
Datastore2.Combine("Inventory", "Gold", "Armour", "Potions", "Weapons")
players.PlayerAdded:Connect(function(player)
local Inventory = Instance.new("Folder", player); Inventory.name = "Inventory"
local playerGold = Instance.new("IntValue", Inventory); playerGold.Name = "Gold"
local playerArmour = Instance.new("StringValue", Inventory); playerArmour .Name = "Armour"
local playerPotions = Instance.new("StringValue", Inventory); playerPotions .Name = "Potions"
local playerWeapons = Instance.new("StringValue", Inventory); playerWeapons .Name = "Weapons"
local goldStore = Datastore2("Gold", player); local goldStoreData = goldStore:Get()
local armourStore = Datastore2("Armour", player); local armourStoreData= armourStore({})
local potionsStore = Datastore2("Potions", player); local potionsStoreData = potionsStore({})
local weaponsStore= Datastore2("Weapons", player); local weaponsStoreData = weaponsStore({})
playerArmour.Value = HttpService:JSONEncode(armourStoreData) -- turning your items into a JSON table. we don't need to do this for gold as gold is a number and wont have multiple items inside
armourStore:OnUpdate(function(decodedData)
playerArmour.Value = HttpService:JSONEncode(decodedData) -- encode newly updated data
end)
playerPotions.Value = HttpService:JSONEncode(potionStoreData)
potionStore:OnUpdate(function(decodedData)
playerPotions.Value = HttpService:JSONEncode(decodedData) -- encode newly updated data
end)
playerWeapons.Value = HttpService:JSONEncode(weaponsStoreData)
weaponsStore:OnUpdate(function(decodedData)
playerWeapons.Value = HttpService:JSONEncode(decodedData) -- encode newly updated data
end)
my apologies if this looks complicated or if its not optimised too well. i have a bad habit of accidentally making things harder for myself. however this should do exactly what you’re looking for.
if you need anything explained please say so and i’ll do the best i can
So if someone was to get a sword, how would it add it.
local equippedSword = player:FindFirstChild('EquippedSword')
local sword_clone = swords:FindFirstChild(store_tables['SwordsList'][equippedSword.Value]
['Name']):Clone()
local welds = Instance.new('Folder', sword_clone)
welds.Name = 'Welds'
It’s simple you should check player’s weapon value and give them via :Clone().
a RemoteEvent
can be used for this.
inside, for example a sword on the floor, you can use a local script to see if a player touches it or if you want to make it a bit more advanced, see if a player is looking at it and picking it up with a keybind (usually E or F). have a script in server script storage that looks for when this event is fired and when it is run a function.
this is what im working on right now; RoScrolls - Early Testing - Roblox
just a test place right now but this is the inventory system of mine so far. it looks for a stringvalue named ObjectType inside of the part and if it finds it, it will look inside its children for another stringvalue called “ItemType” which contains what category of item it is.
here’s the remote event
-- Local script
local item = script.Parent
local player = game.Players.LocalPlayer
local pickupItemEvent = game:GetService("ReplicatedStorage").PATH TO YOUR EVENT HERE
script.Parent.Touched:Connect(function(hit)
if (hit.Parent:FindFirstChildOfClass("Humanoid") and hit.Parent:FindFirstChild("Head")) then
pickupItemEvent:FireServer(script.Parent) -- we do not need to include player because player is given by default.
end
end)
Now inside a script in server script service
local HttpService = game:GetService("HttpService")
local Datastore2 = require(1936396537)
local pickupServerEvent = game:GetService("ReplicatedStorage").PATH TO YOUR EVENT HERE
function itemPickedUp(player, item)
local ItemName = item.Name -- the item added to the inventory will be the name of the part.
if item:FindFirstChild("ItemType") then
local ItemType = item.ItemType.Value
local InventoryStore = Datastore2(ItemType, player)
InventoryStore:Update(function(CurrentInventory)
if (CurrentInventory[ItemName]) then
local tempNum = CurrentInventory[ItemName]
CurrentInventory[ItemName] = CurrentInventory[ItemName] + 1
print("Added "..item.ItemType.Value.." '"..item.Name.."' (x1)")
item:Destroy()
else
CurrentInventory[ItemName] = 1
print("Added "..item.ItemType.Value.." '"..item.Name.."' (x1)")
item:Destroy()
end
print("New amount: "..CurrentInventory[ItemName].."\n")
return CurrentInventory
end)
end
end
pickupItemEvent.OnServerEvent:Connect(itemPickedUp)
(if this helped can you set it as the question solution? )