Ok, so my data store script isn’t functioning as I want it to. I can’t figure out why. Here’s my script:
-- Server Script
-- Get the DataStoreService and create a DataStore
local DataStoreService = game:GetService("DataStoreService")
local datastore = DataStoreService:GetDataStore("PlayerInvenDatastores")
-- Define default data for various inventories
local defaulttable = require(script:WaitForChild("DefaultData"))
game.Players.PlayerAdded:Connect(function(plr: Player)
-- Get the local player
local hasappliedstarterdata = false
-- Create a folder to store player inventory data
local plrInven = Instance.new("Folder")
plrInven.Name = "PlayerInven"
plrInven.Parent = plr
local blockinvensaving = Instance.new("BoolValue")
blockinvensaving.Value = true
blockinvensaving.Name = "BlockInvenSaving"
blockinvensaving.Parent = plrInven
local SavePlrDataFromServerScripts = Instance.new("BindableEvent")
SavePlrDataFromServerScripts.Name = "SaveDataEvent"
SavePlrDataFromServerScripts.Parent = plrInven
-- Material Slots
local materialinven = Instance.new("Folder", plrInven)
materialinven.Name = "Materials"
local numberofMaterialSlots = 150
local materialdataslots = {}
for i = 1, numberofMaterialSlots do
local currentSlot = Instance.new("StringValue", materialinven)
currentSlot.Name = "Slot" .. tostring(i)
materialdataslots["Slot" .. tostring(i)] = currentSlot
local amount = Instance.new("IntValue", currentSlot)
amount.Name = "Amount"
end
-- Melee Slots
local meleeinven = Instance.new("Folder", plrInven)
meleeinven.Name = "Melee"
local numberofMeleeSlots = 10
local meleedataslots = {}
for i = 1, numberofMeleeSlots do
local currentSlot = Instance.new("StringValue", meleeinven)
currentSlot.Name = "Slot" .. tostring(i)
meleedataslots["Slot" .. tostring(i)] = currentSlot
end
-- Head Armor Slots
local hArmorInven = Instance.new("Folder", plrInven)
hArmorInven.Name = "HeadArmor"
local numberofHeadArmorSlots = 3
local harmordataslots = {}
for i = 1, numberofHeadArmorSlots do
local currentSlot = Instance.new("StringValue", hArmorInven)
currentSlot.Name = "Slot" .. tostring(i)
harmordataslots["Slot" .. tostring(i)] = currentSlot
end
-- Middle Armor Slots
local mArmorInven = Instance.new("Folder", plrInven)
mArmorInven.Name = "MiddleArmor"
local numberofMiddleArmorSlots = 3
local marmordataslots = {}
for i = 1, numberofMiddleArmorSlots do
local currentSlot = Instance.new("StringValue", mArmorInven)
currentSlot.Name = "Slot" .. tostring(i)
marmordataslots["Slot" .. tostring(i)] = currentSlot
end
-- Leg Armor Slots
local lArmorInven = Instance.new("Folder", plrInven)
lArmorInven.Name = "LegArmor"
local numberofLegArmorSlots = 3
local larmordataslots = {}
for i = 1, numberofLegArmorSlots do
local currentSlot = Instance.new("StringValue", lArmorInven)
currentSlot.Name = "Slot" .. tostring(i)
larmordataslots["Slot" .. tostring(i)] = currentSlot
end
-- Ranged Slots
local rangedinven = Instance.new("Folder", plrInven)
rangedinven.Name = "Ranged"
local numberofRangedSlots = 10
local rangeddataslots = {}
for i = 1, numberofRangedSlots do
local currentSlot = Instance.new("StringValue", rangedinven)
currentSlot.Name = "Slot" .. tostring(i)
rangeddataslots["Slot" .. tostring(i)] = currentSlot
end
-- Arrows
local arrows = Instance.new("StringValue", rangedinven)
arrows.Name = "Arrows"
local arrowAmount = Instance.new("IntValue", arrows)
arrowAmount.Name = "Amount"
rangeddataslots["Arrows"] = arrows
-- Magic Slots
local magicinven = Instance.new("Folder", plrInven)
magicinven.Name = "Magic"
local numberofMagicSlots = 10
local magicdataslots = {}
for i = 1, numberofMagicSlots do
local currentSlot = Instance.new("StringValue", magicinven)
currentSlot.Name = "Slot" .. tostring(i)
magicdataslots["Slot" .. tostring(i)] = currentSlot
end
-- Mana
local Mana = Instance.new("StringValue", magicinven)
Mana.Name = "Mana"
local manaAmount = Instance.new("IntValue", Mana)
manaAmount.Name = "Amount"
magicdataslots["Mana"] = Mana
-- Quest Slots
local completedquests = Instance.new("Folder", plrInven)
completedquests.Name = "Quests"
local questslots = {}
local numberofQuestSlots = 150
for i = 1, numberofQuestSlots do
local currentSlot = Instance.new("StringValue", completedquests)
currentSlot.Name = "Slot" .. tostring(i)
questslots["Slot" .. tostring(i)] = currentSlot
local rewards = Instance.new("StringValue", currentSlot)
rewards.Name = "Rewards"
local identifier = Instance.new("NumberValue", currentSlot)
identifier.Name = "Identifier"
end
-- Player Stats
local plrstats = Instance.new("Folder", plrInven)
plrstats.Name = "Stats"
local temperature = Instance.new("NumberValue", plrstats)
temperature.Name = "Temperature"
local stealth = Instance.new("NumberValue", plrstats)
stealth.Name = "Stealth"
local money = Instance.new("IntValue", plrstats)
money.Name = "Money"
-- Function to get data for all inventories
function GetDataForAll()
local materialdata = {}
local meleedata = {}
local rangeddata = {}
local magicdata = {}
local questdata = {}
local headarmordata = {}
local middlearmordata = {}
local legarmordata = {}
-- Get materials data
for i = 1, numberofMaterialSlots do
local currentSlot = materialdataslots["Slot" .. tostring(i)]
materialdata["Slot" .. tostring(i) .. "Name"] = currentSlot.Value
local amount = currentSlot:FindFirstChild("Amount")
if amount then
materialdata["Slot" .. tostring(i) .. "Amount"] = amount.Value
else
materialdata["Slot" .. tostring(i) .. "Amount"] = 0
end
end
-- Get melee data
for i = 1, numberofMeleeSlots do
local data = meleedataslots["Slot" .. tostring(i)].Value
meleedata["Slot" .. tostring(i)] = data
end
-- Get ranged data
for i = 1, numberofRangedSlots do
local data = rangeddataslots["Slot" .. tostring(i)].Value
rangeddata["Slot" .. tostring(i)] = data
end
-- Get magic data
for i = 1, numberofMagicSlots do
local data = magicdataslots["Slot" .. tostring(i)].Value
magicdata["Slot" .. tostring(i)] = data
end
magicdata["Mana"] = manaAmount.Value
-- Get quest data
for i = 1, numberofQuestSlots do
local currentSlot = questslots["Slot" .. tostring(i)]
questdata["Slot" .. tostring(i)] = currentSlot.Value
local identifier = currentSlot:FindFirstChild("Identifier")
if identifier then
questdata["Slot" .. tostring(i) .. "Identifier"] = identifier.Value
else
questdata["Slot" .. tostring(i) .. "Identifier"] = 0
end
local rewards = currentSlot:FindFirstChild("Rewards")
if rewards then
questdata["Slot" .. tostring(i) .. "Rewards"] = rewards.Value
else
questdata["Slot" .. tostring(i) .. "Rewards"] = ""
end
end
-- Get head armor data
for i = 1, numberofHeadArmorSlots do
local data = harmordataslots["Slot" .. tostring(i)].Value
headarmordata["Slot" .. tostring(i)] = data
end
-- Get middle armor data
for i = 1, numberofMiddleArmorSlots do
local data = marmordataslots["Slot" .. tostring(i)].Value
middlearmordata["Slot" .. tostring(i)] = data
end
-- Get leg armor data
for i = 1, numberofLegArmorSlots do
local data = larmordataslots["Slot" .. tostring(i)].Value
legarmordata["Slot" .. tostring(i)] = data
end
return materialdata, meleedata, rangeddata, magicdata, questdata, headarmordata, middlearmordata, legarmordata, money.Value
end
local tabletoget
-- Function to apply saved data from server
function ApplySavedData()
local id = game.PrivateServerId .. plr.UserId
local success, data = pcall(function()
return datastore:GetAsync(id)
end)
if success then
if data then
--print("Retrieved data for player " .. player.Name)
tabletoget = data
else
--print("No data found for player " .. player.Name .. ", sending default data.")
tabletoget = defaulttable
end
else
warn("Failed to retrieve data for player " .. player.Name .. ": " .. data)
-- Optionally, send default data in case of error
tabletoget = defaulttable
end
print("Applying saved data to "..plr.Name..".")
local materialsfrom = tabletoget["Materials"]
local meleefrom = tabletoget["Melee"]
local rangedfrom = tabletoget["Ranged"]
local magicfrom = tabletoget["Magic"]
local questsfrom = tabletoget["Quests"]
local headfrom = tabletoget["Head"]
local middlefrom = tabletoget["Middle"]
local lowfrom = tabletoget["Low"]
local moneyfrom = tabletoget["Money"]
-- Apply money
money.Value = moneyfrom
-- Apply mana
manaAmount.Value = magicfrom["Mana"]
-- Apply materials data
for i = 1, numberofMaterialSlots do
local materialSlot = materialdataslots["Slot" .. tostring(i)]
materialSlot.Value = materialsfrom["Slot" .. tostring(i) .. "Name"]
local amount = materialSlot:FindFirstChild("Amount")
if amount then
amount.Value = materialsfrom["Slot" .. tostring(i) .. "Amount"]
end
end
-- Apply melee data
for i = 1, numberofMeleeSlots do
local meleeSlot = meleedataslots["Slot" .. tostring(i)]
meleeSlot.Value = meleefrom["Slot" .. tostring(i)]
end
-- Apply ranged data
for i = 1, numberofRangedSlots do
local rangedSlot = rangeddataslots["Slot" .. tostring(i)]
rangedSlot.Value = rangedfrom["Slot" .. tostring(i)]
end
-- Apply magic data
for i = 1, numberofMagicSlots do
local magicSlot = magicdataslots["Slot" .. tostring(i)]
magicSlot.Value = magicfrom["Slot" .. tostring(i)]
end
-- Apply quest data
for i = 1, numberofQuestSlots do
local questSlot = questslots["Slot" .. tostring(i)]
questSlot.Value = questsfrom["Slot" .. tostring(i)]
local identifier = questSlot:FindFirstChild("Identifier")
if identifier then
identifier.Value = questsfrom["Slot" .. tostring(i) .. "Identifier"]
end
local rewards = questSlot:FindFirstChild("Rewards")
if rewards then
rewards.Value = questsfrom["Slot" .. tostring(i) .. "Rewards"]
end
end
-- Apply head armor data
for i = 1, numberofHeadArmorSlots do
local headArmorSlot = harmordataslots["Slot" .. tostring(i)]
headArmorSlot.Value = headfrom["Slot" .. tostring(i)]
end
-- Apply middle armor data
for i = 1, numberofMiddleArmorSlots do
local middleArmorSlot = marmordataslots["Slot" .. tostring(i)]
middleArmorSlot.Value = middlefrom["Slot" .. tostring(i)]
end
-- Apply leg armor data
for i = 1, numberofLegArmorSlots do
local legArmorSlot = larmordataslots["Slot" .. tostring(i)]
legArmorSlot.Value = lowfrom["Slot" .. tostring(i)]
end
if not hasappliedstarterdata then
blockinvensaving.Value = false
hasappliedstarterdata = not hasappliedstarterdata
end
end
-- Apply saved data on start
ApplySavedData()
print("Waiting for signal")
game.ReplicatedStorage:WaitForChild("AllowToSaveData").OnServerEvent:Wait()
blockinvensaving.Value = false
print("Signal")
local function SaveData(data)
local id = game.PrivateServerId .. plr.UserId
-- Save data with error handling
local success, err = pcall(function()
datastore:SetAsync(id, data)
end)
if not success then
warn("Failed to save data for player " .. plr.Name .. ": " .. err)
end
print("Saving data to datastore for "..plr.Name..".")
end
-- Function to save data when properties change
local function onValueChanged()
if blockinvensaving.Value then
return
end
print("getting data")
local materialdata, meleedata, rangeddata, magicdata, questdata, headarmordata, middlearmordata, legarmordata, moneyValue = GetDataForAll()
SaveData({materialdata, meleedata, rangeddata, magicdata, questdata, headarmordata, middlearmordata, legarmordata, moneyValue})
end
-- Connect value changed events to save data
SavePlrDataFromServerScripts.Event:Connect(onValueChanged)
money:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
manaAmount:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
arrowAmount:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
-- For materials
for i = 1, numberofMaterialSlots do
local currentMaterialSlot = materialdataslots["Slot" .. tostring(i)]
print(currentMaterialSlot)
local amount = currentMaterialSlot:FindFirstChild("Amount")
if amount then
amount:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
currentMaterialSlot:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
-- For quests
for i = 1, numberofQuestSlots do
local currentQuestSlot = questslots["Slot" .. tostring(i)]
currentQuestSlot:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
local identifier = currentQuestSlot:FindFirstChild("Identifier")
if identifier then
identifier:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
local rewards = currentQuestSlot:FindFirstChild("Rewards")
if rewards then
rewards:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
end
-- For melee slots
for i = 1, numberofMeleeSlots do
local currentMeleeSlot = meleedataslots["Slot" .. tostring(i)]
currentMeleeSlot:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
-- For ranged slots
for i = 1, numberofRangedSlots do
local currentRangedSlot = rangeddataslots["Slot" .. tostring(i)]
currentRangedSlot:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
-- For magic slots
for i = 1, numberofMagicSlots do
local currentMagicSlot = magicdataslots["Slot" .. tostring(i)]
currentMagicSlot:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
-- For head armor slots
for i = 1, numberofHeadArmorSlots do
local currentHeadArmorSlot = harmordataslots["Slot" .. tostring(i)]
currentHeadArmorSlot:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
-- For middle armor slots
for i = 1, numberofMiddleArmorSlots do
local currentMiddleArmorSlot = marmordataslots["Slot" .. tostring(i)]
currentMiddleArmorSlot:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
-- For leg armor slots
for i = 1, numberofLegArmorSlots do
local currentLegArmorSlot = larmordataslots["Slot" .. tostring(i)]
currentLegArmorSlot:GetPropertyChangedSignal("Value"):Connect(onValueChanged)
end
end)
And then there is the module script for default data.
local materialsdef = {}
local meleedef = {}
local rangeddef = {}
local magicdef = {}
local questsdef = {}
local headdef = {}
local middledef = {}
local lowdef = {}
local moneydef = 0
-- Initialize default materials and quests data
for i = 1, 150 do
materialsdef["Slot" .. tostring(i) .. "Name"] = ""
materialsdef["Slot" .. tostring(i) .. "Amount"] = 0
questsdef["Slot" .. tostring(i)] = ""
questsdef["Slot" .. tostring(i) .. "Identifier"] = 0
questsdef["Slot" .. tostring(i) .. "Rewards"] = ""
end
-- Initialize default melee, ranged, and magic data
for i = 1, 10 do
meleedef["Slot" .. tostring(i)] = ""
rangeddef["Slot" .. tostring(i)] = ""
magicdef["Slot" .. tostring(i)] = ""
end
magicdef["Mana"] = 50
-- Initialize default armor data
for i = 1, 3 do
headdef["Slot" .. tostring(i)] = ""
middledef["Slot" .. tostring(i)] = ""
lowdef["Slot" .. tostring(i)] = ""
end
-- Combine all default data into one table
local defaulttable = {}
defaulttable["Materials"] = materialsdef
defaulttable["Melee"] = meleedef
defaulttable["Ranged"] = rangeddef
defaulttable["Magic"] = magicdef
defaulttable["Quests"] = questsdef
defaulttable["Head"] = headdef
defaulttable["Middle"] = middledef
defaulttable["Low"] = lowdef
defaulttable["Money"] = moneydef
return defaulttable
You can set up exactly what I have here if you paste the first code into a script in ServerScriptService and the second chunk of code into a module script parented under the first one named “DefaultData”.
Thanks for your time!