"Argument 1 missing or nil"

That doesn’t focus on saving data?

Oh for data store let me see. Btw do you want to use DataStoreService or DataStore2

data store 2

btw I would recommend learning DataStoreService first tho because it is much easier to understand.

i was going to make that inventory system but i quit because i didn’t know how to use d2

But DataStore2 is nice because it does alot of stuff for you. Here is a dev forum for it

but how is that the same as saving a gui?

If you save something too big in DataStore it might time out. I would rather save the data about the player’s gui data in something more simple like a table that holds the gui inventory items.

Pretty sure you cant even save instances in the Datastore

1 Like

Ya I think so too. To make your scripts as efficient as possible, I would save datatypes that are part of Lua and not from the roblox library.
1 nil

Used to differentiate the value from having some data or no(nil) data.
2 boolean

Includes true and false as values. Generally used for condition checking.
3 number

Represents real(double precision floating point) numbers.
4 string

Represents array of characters.
5 function

Represents a method that is written in C or Lua.
6 userdata

Represents arbitrary C data.
7 thread

Represents independent threads of execution and it is used to implement coroutines.
8 table

Represent ordinary arrays, symbol tables, sets, records, graphs, trees, etc., and implements associative arrays. It can hold any value (except nil).
These are datatypes from Lua that are acceptable
Source from: Lua - Data Types

Hey Slinky can you give yoru full code because i want to try to understand it, and also because you have some things you put down that aren’t variables i can see

--[[Services]]--
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")

local ItemModule = require(game.ReplicatedStorage.ItemModule)
local Items = ItemModule.Items
local PlayerData = require(game.ReplicatedStorage.ClientData)

--[[Constants]]--
--Objects
local plr = game.Players.LocalPlayer
local Mouse = plr:GetMouse()
local Character = plr.Character or plr.ChildAdded:Wait()

--UI
local InventoryGui = script.Parent
local InventorySlotGui = InventoryGui.Slots
local InventorySlotGrid = InventorySlotGui.UIGridLayout

local LeftHandSlot = InventoryGui.LeftHandSlot
local RightHandSlot = InventoryGui.RightHandSlot

local HeadSlot = InventoryGui.HeadSlot
local ChestSlot = InventoryGui.ChestSlot
local LegSlot = InventoryGui.LegSlot
local BootSlot = InventoryGui.BootSlot

local GeneralGui = script.Parent.Parent.Parent.General
local HotBarGui = GeneralGui.HotBar
local HotBarFrame = HotBarGui.Frame

local UIAssets = game.ReplicatedStorage.Assets.UI
local InventorySlotModel = UIAssets.InventorySlot

local UIVariables = game.ReplicatedStorage.Variables.Player.UI

--Events
local Events = game.ReplicatedStorage.Events
local DataEvents = Events.Data
local DataUpdated = DataEvents.DataUpdated
local PlayerAction = Events.PlayerAction

--Non Objects
local StartCanvasSize = InventorySlotGui.CanvasSize
local StartGridSize = InventorySlotGui.Size
local StartGridPos = InventorySlotGui.Position

local CellSizeWeight = UIVariables.CellSizeWeight.Value
local PaddingWeight = UIVariables.PaddingWeight.Value
local CellSize = UIVariables

local InventorySize = #PlayerData.SlotData.Inventory
local RowSize = 4

local ViewSizeX = 0
local ViewSizeY = 0

local SpacingDistance = 1
local Spacing = Vector3.new(SpacingDistance, SpacingDistance, SpacingDistance)
local ItemCameraCFrame = CFrame.new(Spacing)*CFrame.lookAt(Spacing, Vector3.new(0, 0, 0))


--[[Variables]]--
local InventoryFrameSize 

local InventorySlotSize
local InventorySlotPadding

local InventorySlotFrameData = {}
local HotBarSlotFrameData = {}

--[[Functions]]--
local function ScreenSizeChange()
	
	ViewSizeX = Mouse.ViewSizeX
	ViewSizeY = Mouse.ViewSizeY
	
	--Normalizing
	local c = CellSizeWeight + PaddingWeight
	local CellSizeScale = CellSizeWeight/c
	local PaddingScale = PaddingWeight/c
	
	--InventoryGrid
	
	--Acounting for a the bar
	local BarThickness = InventorySlotGui.ScrollBarThickness
	InventorySlotGui.Size = StartGridSize + UDim2.fromOffset(-BarThickness, 0)
	InventorySlotGui.Position = StartGridPos + UDim2.fromOffset(BarThickness, 0)
	
	InventoryFrameSize = InventorySlotGui.AbsoluteSize
	local FrameX = InventoryFrameSize.X - BarThickness --To acount for both sides
	
	InventorySlotSize = FrameX*CellSizeScale/4
	InventorySlotPadding = FrameX*PaddingScale/3
	
	--Setting the Values
	local newSlotSize = UDim2.fromOffset(InventorySlotSize, InventorySlotSize)
	InventorySlotGrid.CellSize =  newSlotSize
	InventorySlotGrid.CellPadding = UDim2.fromOffset(InventorySlotPadding, InventorySlotPadding)
	local AbsoluteContentSize = InventorySlotGrid.AbsoluteContentSize
	InventorySlotGui.CanvasSize = UDim2.fromOffset(AbsoluteContentSize.X, AbsoluteContentSize.Y)
	
	--Setting the Size of the Slots in the Gui above
	LeftHandSlot.Size = newSlotSize
	RightHandSlot.Size = newSlotSize

	HeadSlot.Size = newSlotSize
	ChestSlot.Size = newSlotSize
	LegSlot.Size = newSlotSize
	BootSlot.Size = newSlotSize
end

local function LoadSlot(ItemSlot, SlotFrameData)
	--Setting Variables
	local ItemName = ItemSlot.ItemName
	local IsEmpty = ItemName == ""
	local SlotItemData = Items[ItemName]
	
	local ItemFrame = SlotFrameData.Gui.ItemFrame
	local OldModel = ItemFrame.VP.Camera:FindFirstChild("Model")
	
	--Setting ViewportFrame Model
	if SlotFrameData.ItemName ~= ItemName then
		SlotFrameData.ItemName = ItemName
		
		--Getting Rid of Old Model
		if OldModel then
			OldModel:Destroy()
		end
		
		--Creating new Model
		if not IsEmpty then
			local newModel = SlotItemData.Model:Clone()
			newModel:SetPrimaryPartCFrame(CFrame.fromOrientation(0, 45, 0))
			newModel.Parent = ItemFrame.VP.Camera
		end
	end
	
	--Setting QuanitityLabel
	local ItemQuantity = ItemSlot.Quantity
	if not IsEmpty and SlotItemData.Stackable then
		ItemFrame.Quantity.Visible = true
		if SlotFrameData.Quantity ~= ItemQuantity then
			ItemFrame.Quantity.Text = ItemQuantity
			SlotFrameData.Quantity = ItemQuantity
		end
	else
		ItemFrame.Quantity.Visible = false
	end
end

local function UpdateInventory()
	for i, v in pairs(PlayerData.SlotData.Inventory) do
		LoadSlot(
			PlayerData.SlotData.Inventory[i],
			InventorySlotFrameData[i]
		)
	end
	for i, v in pairs(PlayerData.SlotData.HotBar) do
		LoadSlot(
			PlayerData.SlotData.HotBar[i],
			HotBarSlotFrameData[i]
		)
	end
end

local function OpenInventory(_, UserInputState)
	if not UserInputState or UserInputState ~= Enum.UserInputState.Begin then return end
	if InventoryGui.Parent.Enabled then
		InventoryGui.Parent.Enabled = false
	else
		InventoryGui.Parent.Enabled = true
	end
end

--[[Main]]--
InventoryGui.Parent.Enabled = false

--Setting up size variables
ScreenSizeChange()

for i, v in pairs(PlayerData.SlotData.Inventory) do
	local newSlot = InventorySlotModel:Clone()
	newSlot.Name = i
	newSlot.Parent = InventorySlotGui
	
	InventorySlotFrameData[i] = {
		Index = i,
		Gui = newSlot,
		LastQuantity = 0,
		LastItemName = ""
	}
	
	local RowSlot = (i-1)%4
	local Row = math.floor((i-1)/4)+1
	newSlot.Position = UDim2.fromOffset(
		RowSlot*InventorySlotPadding + RowSlot*InventorySlotSize,--SubFromBoth(SlotSize, -1), 
		Row*InventorySlotPadding + Row*InventorySlotSize
	)
	
	local newSlotCam = Instance.new("Camera")
	newSlotCam.Parent = newSlot.ItemFrame.VP
	newSlot.ItemFrame.VP.CurrentCamera = newSlotCam
	newSlotCam.CFrame = ItemCameraCFrame
	
	--Interaction
	newSlot.MouseButton2Down:Connect(function()
		--Temp
		PlayerAction:FireServer("SwitchPlaces", "Inventory", i, "HotBar", 1)
	end)
end

for i, v in pairs(PlayerData.SlotData.HotBar) do
	local newSlot = InventorySlotModel:Clone()
	newSlot.Name = i
	newSlot.Parent = HotBarFrame

	HotBarSlotFrameData[i] = {
		Index = i,
		Gui = newSlot,
		LastQuantity = 0,
		LastItemName = ""
	}
	
	local RowSlot = i-3
	
	newSlot.Size = UDim2.new(.15, 0, .15, 0)
	newSlot.Position = UDim2.new(.5 + .2*RowSlot, 0, .5, 0)

	local newSlotCam = Instance.new("Camera")
	newSlotCam.Parent = newSlot.ItemFrame.VP
	newSlot.ItemFrame.VP.CurrentCamera = newSlotCam
	newSlotCam.CFrame = ItemCameraCFrame
end

ContextActionService:BindAction("InventoryToggle", OpenInventory, false, Enum.KeyCode.Q)
RunService:BindToRenderStep("CheckSize", 199, function()
	if Mouse.ViewSizeX ~= ViewSizeX or Mouse.ViewSizeY ~= ViewSizeY then
		ScreenSizeChange()
	end
end)

UpdateInventory()
DataUpdated.Event:Connect(function()
	UpdateInventory()
end)

just the variables if thats fine? with the loadslot function and update

--[[Services]]--
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")

local ItemModule = require(game.ReplicatedStorage.ItemModule)
local Items = ItemModule.Items
local PlayerData = require(game.ReplicatedStorage.ClientData)

--[[Constants]]--
--Objects
local plr = game.Players.LocalPlayer
local Mouse = plr:GetMouse()
local Character = plr.Character or plr.ChildAdded:Wait()

--UI
local InventoryGui = script.Parent
local InventorySlotGui = InventoryGui.Slots
local InventorySlotGrid = InventorySlotGui.UIGridLayout

local LeftHandSlot = InventoryGui.LeftHandSlot
local RightHandSlot = InventoryGui.RightHandSlot

local HeadSlot = InventoryGui.HeadSlot
local ChestSlot = InventoryGui.ChestSlot
local LegSlot = InventoryGui.LegSlot
local BootSlot = InventoryGui.BootSlot

local GeneralGui = script.Parent.Parent.Parent.General
local HotBarGui = GeneralGui.HotBar
local HotBarFrame = HotBarGui.Frame

local UIAssets = game.ReplicatedStorage.Assets.UI
local InventorySlotModel = UIAssets.InventorySlot

local UIVariables = game.ReplicatedStorage.Variables.Player.UI

--Events
local Events = game.ReplicatedStorage.Events
local DataEvents = Events.Data
local DataUpdated = DataEvents.DataUpdated
local PlayerAction = Events.PlayerAction

--Non Objects
local StartCanvasSize = InventorySlotGui.CanvasSize
local StartGridSize = InventorySlotGui.Size
local StartGridPos = InventorySlotGui.Position

local CellSizeWeight = UIVariables.CellSizeWeight.Value
local PaddingWeight = UIVariables.PaddingWeight.Value
local CellSize = UIVariables

local InventorySize = #PlayerData.SlotData.Inventory
local RowSize = 4

local ViewSizeX = 0
local ViewSizeY = 0

local SpacingDistance = 1
local Spacing = Vector3.new(SpacingDistance, SpacingDistance, SpacingDistance)
local ItemCameraCFrame = CFrame.new(Spacing)*CFrame.lookAt(Spacing, Vector3.new(0, 0, 0))


--[[Variables]]--
local InventoryFrameSize 

local InventorySlotSize
local InventorySlotPadding

local InventorySlotFrameData = {}
local HotBarSlotFrameData = {}
1 Like

Hey uh sorry to ask but what is “SlotFrameData”?

I use it to tell what data is displayed in each slot so i can compare it to the new data and make changes as needed

How does the script know what it is?

You should probably just attempt to make your own system instead of examining mine. Trial and error will help you learn way better than analyzing my scripts

yes, im making a script right now I was just wondering what it was since i use your script for reference

local function LoadData(Armor, ArmorData)
	
	local template = game.StarterGui.MainGui.InventoryHolder.Inventory.Templates.Template
	local newTemplate = template:Clone()
	local ArmorName = armormodule.armors.Name
	
	local Viewport = game.StarterGui.MainGui.InventoryHolder.Inventory.Templates.Template.ViewportFrame
	local OldArmor = Viewport:FindFirstChild("Model")
	local ArmorModule = require(game.ReplicatedStorage:WaitForChild("ArmorHandler"))
	local Armor = ArmorModule.armors
	local plr = game.Players.LocalPlayer
	local IsEmpty = ArmorName == ""
	local char = plr.Character or plr.ChildAdded:Wait() 
	
	

	
end

Its used to make the process of updating the gui a tiny bit more efficient. I would not bother trying to understand what it does when you don’t have a working system yet