The problem is: the table which contains all the user data won’t save anything most of the time and it won’t warn any error.
I’m kind of new to Roblox programming so i’m very open minded for every advise possible. I’m going to try to be as clear as possible to explain the context of the code, i started by coding a “custom service” (basically a folder that stores events) through a ModuleScript that is located in ReplicatedFirst, that ModuleScript also creates all the intvalues that will be used to store data like money, level, exp etc. The inventory system is also structured around intvalues, each of those corresponds to a slot in the inventory, so if there’s an item inside a inventory slot, the intvalue that corresponds to that slot will have a number inside. This part will be explained a bit better soon.
Then i made all the basic stuff for data storage like bindable events to save and load data, and made remote events to store and withdraw items server sidedly to the inventory.
For everyone reading the code, the “syncd” variable may be confusing but it is basically what i said before, “syncd” is the intvalue that corresponds to the slot interacted.
How the inventory system works
-
To store an item
The code will check if inside the tool there’s an intvalue named “ID”, if there is, the tool is deleted from your hand, the ID’s parent (tool) name appears on the slot you clicked and the value of ‘syncd’ is mirrored to the ID of the tool you had in hands. -
To withdraw an item
There’s a folder in ReplicatedStorage named Items, there are located all the items that can be used in the game. The script will look through every descendant named “ID” of the items folder and it will compare if the value of the ID is the same as syncd. Remember, syncd is the intvalue instance that corresponds to the slot interacted with.
Video showing it doesn’t always save the data:
I have tried doing a more dynamic inventory like, only creating values on the player’s inventory data when an item is stored, but i couldn’t make that work either.
Any questions please comment
Module Script code:
local DataStoreService = game:GetService("DataStoreService")
local database = DataStoreService:GetDataStore("database")
local sessionData = {}
local service = Instance.new("Folder") -- creates the custom service
service.Name = "DataStorage"
service.Parent = game.ReplicatedStorage
local DataLoad = Instance.new("BindableEvent") -- creates DataLoad bindEvent
DataLoad.Name = "DataLoad"
DataLoad.Parent = service
local DataSave = Instance.new("BindableEvent") -- creates DataSave bindEvent
DataSave.Name = "DataSave"
DataSave.Parent = service
local itemStore = Instance.new("RemoteEvent") -- creates itemStore remoteEvent
itemStore.Name = "itemStored"
itemStore.Parent = service
local itemWithdraw = Instance.new("RemoteEvent") -- creates itemWithdraw remoteEvent
itemWithdraw.Name = "itemWithdraw"
itemWithdraw.Parent = service
-- dataLoad event set up
DataLoad.Event:Connect(function(player, userid)
-- default data
local dataFolder = Instance.new("Folder")
dataFolder.Name = "PlayerData"
local Money = Instance.new("IntValue")
Money.Name = "Money"
Money.Parent = dataFolder
local Level = Instance.new("IntValue")
Level.Name = "Level"
Level.Parent = dataFolder
local EXP = Instance.new("IntValue")
EXP.Name = "EXP"
EXP.Parent = dataFolder
local StatPoints = Instance.new("IntValue")
StatPoints.Name = "StatPoints"
StatPoints.Parent = dataFolder
local Sword = Instance.new("IntValue")
Sword.Name = "Sword"
Sword.Parent = dataFolder
local Fruit = Instance.new("IntValue")
Fruit.Name = "Fruit"
Fruit.Parent = dataFolder
local Inventory = Instance.new("Folder")
Inventory.Name = "Inventory"
Inventory.Parent = dataFolder
local counter = 0
repeat
counter += 1
local slot = Instance.new("IntValue") -- creates 25 intvalues which are for every slot of the inventory
slot.Name = "Slot"..counter
slot.Parent = Inventory
until counter == 25
-------------------------------------------------------
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData = pcall(function()
return database:GetAsync(userid)
end)
attempt += 1
if not success then
warn(playerData)
task.wait(3)
end
until success or attempt == 5
if success then
print(player, "was connected to database")
if not playerData then
print("Assigning default data")
playerData = {
["Money"] = 0,
["Level"] = 1,
["EXP"] = 0,
["StatPoints"] = 0,
["Sword"] = 0,
["Fruit"] = 0,
["Inventory"] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}
end
sessionData[userid] = playerData
else
warn("Unable to get data for player", player)
player:Kick("Unable to load your data. Try again later.")
end
---------------------------------------------------------
Money.Value = sessionData[userid].Money
Money.Changed:Connect(function()
sessionData[userid].Money = Money.Value
end)
Level.Value = sessionData[userid].Level
Level.Changed:Connect(function()
sessionData[userid].Level = Level.Value
end)
EXP.Value = sessionData[userid].EXP
EXP.Changed:Connect(function()
sessionData[userid].EXP = EXP.Value
end)
StatPoints.Value = sessionData[userid].StatPoints
StatPoints.Changed:Connect(function()
sessionData[userid].StatPoints = StatPoints.Value
end)
Sword.Value = sessionData[userid].Sword
Sword.Changed:Connect(function()
sessionData[userid].Sword = Sword.Value
end)
Fruit.Value = sessionData[userid].Fruit
Fruit.Changed:Connect(function()
sessionData[userid].Fruit = Fruit.Value
end)
for i, v in pairs(Inventory:GetChildren()) do -- Inventory:Getchildren() = 25 intvalues, which are the custom inventory slots
print(sessionData[userid].Inventory[i])
v.Value = sessionData[userid].Inventory[i]
v.Changed:Connect(function()
sessionData[userid].Inventory[i] = v.Value
print(sessionData[userid].Inventory)
end)
end
dataFolder.Parent = player
end)
-- dataSave event setup
DataSave.Event:Connect(function(player, userid)
if sessionData[userid] then
local success = nil
local errorMsg = nil
local attempt = 1
repeat
success, errorMsg = pcall(function()
database:SetAsync(userid, sessionData[userid])
end)
attempt += 1
if not success then
warn(errorMsg)
task.wait(3)
end
until success or attempt == 5
if success then
print("Data saved for", player)
else
warn("Failed to save data for", player)
end
end
end)
itemStore.OnServerEvent:Connect(function(player, syncd) -- itemStore event setup
local tool = player.Character:FindFirstChildWhichIsA("Tool")
syncd.Value = tool.ID.Value
tool:Destroy()
end)
local ToolsStorage = game.ReplicatedStorage:WaitForChild("Items")
local toolDescen = ToolsStorage:GetDescendants()
itemWithdraw.OnServerEvent:Connect(function(player, syncd) -- itemWithdraw event setup
for i, v in pairs(toolDescen) do
if v.Name == "ID" and v.Value == syncd.Value then
local clone = v.Parent:Clone()
clone.Parent = player.Backpack
end
end
syncd.Value = 0
end)
-- ignore below
local module = {}
return module