Hello, I was trying to create an inventory system as a table in a modulescript inside each player and now I am trying to make the table save everytime the player leaves and rejoins but it isn’t working.
local ds = game:GetService("DataStoreService")
local datastore = ds:GetDataStore("SaveData")
local HttpService = game:GetService("HttpService")
game.Players.PlayerAdded:Connect(function(plr)
local InvModule = plr:WaitForChild("PlayerGui"):WaitForChild("Interfaces"):WaitForChild("InventoryUI"):WaitForChild("ScrollingFrame"):WaitForChild("InventoryModule")
local Inv = require(InvModule)
Inv = datastore:SetAsync("SaveData"..plr.UserId, Inv)
end)
game.Players.PlayerRemoving:Connect(function(plr)
local InvModule = plr:WaitForChild("PlayerGui"):WaitForChild("Interfaces"):WaitForChild("InventoryUI"):WaitForChild("ScrollingFrame"):WaitForChild("InventoryModule")
local Inv = require(InvModule)
pcall(function()
datastore:GetAsync("SaveData"..plr.UserId, Inv)
end)
end)
There is a button that adds an item to the table as well, but I think this is working fine
local Inv = script.Parent.Parent.InventoryUI.ScrollingFrame.Inventory
local itemValue = script.Parent.ItemValue.Value
local InvModule = require(script.Parent.Parent.InventoryUI.ScrollingFrame.InventoryModule)
script.Parent.MouseButton1Up:Connect(function()
if
true
then
if not InvModule[itemValue] then
InvModule[itemValue] = 1
else
InvModule[itemValue] += 1
end
print(InvModule)
end
end)
The first thing I can come up with is the fact that ModuleScripts do not replicate between the client and the server. If you want your changes to the module script to save then you must make the changes on the server side with a server script.
You can make a remote event that fires when you click the button on the client. Then on the server side, you can listen for when that event fires and then make the changes to the module script there.
Note that this with no additional safety checks will be very vulnerable to exploiters, since they can run client-side code.
Are you trying to change the data within the ModuleScript itself, and not the Datastore? If so, you cannot change anything within a ModuleScript inside of the game.
I’ve a saving tools in backpack and Player Datastore you can use it if you would like.
local DataStoreService = game:GetService("DataStoreService")
local ToolsDataStore = DataStoreService:GetDataStore("ToolsDataStore")
function PlayerJoined(Player)
local Success, KeyInfo
local ToolData
if ToolData ~= nil then
for i, data in ipairs(ToolData) do
local PlayerOwnsTool = Player.Character:FindFirstChild(data[1]) or Player.Backpack:FindFirstChild(data[1])
if ShopItems:FindFirstChild(data[1]) and PlayerOwnsTool == nil then
local ItemClone = ShopItems[data[1]]:Clone()
ItemClone.Handle.Quantity.Value = data[2]
ItemClone.Parent = Player.Backpack
elseif ShopItems:FindFirstChild(data[1]) and PlayerOwnsTool then
PlayerOwnsTool.Handle.Quantity.Value = data[2]
end
end
end
end
function PlayerLeft(Player)
local ToolTable = {}
for i,v in pairs(Player.Backpack:GetChildren()) do
table.insert(ToolTable,{v.Name, v.Handle.Quantity.Value})
end
if ToolTable ~= nil then
local Success, errorMessage = pcall(function()
ToolsDataStore:SetAsync(Player.UserId, ToolTable)
end)
if errorMessage then
warn(errorMessage)
end
end
end
game.Players.PlayerAdded:Connect(PlayerJoined)
game.Players.PlayerRemoving:Connect(PlayerLeft)
No, server scripts can’t listen for input from your keyboard, mouse, ui or gamepad. I would like to point out when you require a module script it returns the value you set to return in the module script with return. In this case it returns a table but that table is not being edited in the module script. You are editing the table returned which will only apply to that server script. No other server script will see those changes.
You are saving the data when the player joins, and getting the data when they leave.
Also, you are saving all the data with a single key, which means that (if im right) everyone will have shared inventories. (nvm about this part, i just read the script again, and i am stupid)
local Inv = script.Parent.Parent.InventoryUI.ScrollingFrame.Inventory
local itemValue = script.Parent.ItemValue.Value
local InvModule = require(script.Parent.Parent.InventoryUI.ScrollingFrame.InventoryModule)
script.Parent.MouseButton1Up:Connect(function()
game.Workspace.GiveItem:FireServer(itemValue,script.Parent.Parent.InventoryUI.ScrollingFrame.InventoryModule)
end)
Serverscript:
script.Parent.OnServerEvent:Connect(function(plr,itemValue,InvModule2)
local InvModule = require(InvModule2)
if not InvModule[itemValue] then
InvModule[itemValue] = 1
print("new item is "..itemValue)
else
InvModule[itemValue] += 1
print("added item "..itemValue)
end
print(InvModule)
end)
DataStore Script:
local ds = game:GetService("DataStoreService")
local datastore = ds:GetDataStore("SaveData")
local HttpService = game:GetService("HttpService")
game.Players.PlayerAdded:Connect(function(plr)
local InvModule = plr:WaitForChild("PlayerGui"):WaitForChild("Interfaces"):WaitForChild("InventoryUI"):WaitForChild("ScrollingFrame"):WaitForChild("InventoryModule")
local Inv = require(InvModule)
Inv = datastore:GetAsync("SaveData"..plr.UserId, Inv)
end)
game.Players.PlayerRemoving:Connect(function(plr)
local InvModule = plr:WaitForChild("PlayerGui"):WaitForChild("Interfaces"):WaitForChild("InventoryUI"):WaitForChild("ScrollingFrame"):WaitForChild("InventoryModule")
local Inv = require(InvModule)
pcall(function()
datastore:SetAsync("SaveData"..plr.UserId, Inv)
end)
end)
It prints out the stuff in the table, but when i leave and rejoin, it doesn’t save it
This doesn’t go anywhere, this is not setting the module script to return the data. This is setting the “Inv” variable to the data saved. I’d find another way to store, edit, and save data. For example you could store the table as a JSON string in an attribute or string value. That’s what I’ve done with one of my most recent games.
If you want to go for the JSON string method you could read into HttpService. It has functions to convert a table into a JSON string and vice versa.