What is the best way to save a player dictionary?

I need to save a dictionary with player Inventory info.

local dictionary = {
Apple = {
Name = “myApple”;
Color = ”White”
}

Book = {
Name = “Book”
Color = “Black”
}
}

How do i save this info and retrieve back when player join? Should i use Module Script to do that?

1 Like

you can do this with DataStoreService

use GetAsync when they join to get data at their key (userid), and save that to a table and modify it as you need while they are in-game.
When they leave save their data with SetAsync and set their inventory data to their key (their userid)

2 Likes

Assuming that the dictionary that you sent is the player’s inventory, I would have a module script with the information for the items instead. Then store in the inventory for example id1 which could be apple.

2 Likes

i’d personally add a folder in your player and name it Inventory
then insert BrickColorValues for each item

Example:

local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("Inventory")

function addItem(player, item, color)
   local inv = player.Inventory
   local val = Instance.new("BrickColorValue")
   val.Name = item
   val.Value = color
end

function removeItem(player, item)
   local inv = player.Inventory
   local val = inv[item]
   if val then
      val = nil
   end
end

game.Players.PlayerAdded:Connect(function(player)
   local inventory = Instance.new("Folder")
   inventory.Name = "Inventory"
   inventory.Parent = player

   local inv
   local success, err = pcall(function()
      inv = game:GetService("HttpService"):JSONDecode(ds:GetAsync("Player_"..player.UserId))
   end)

   if success then
      for _, v in inv do
         local value = Instance.new("BrickColorValue")
         value.Name = v.Name
         value.Value = v.Value
         value.Parent = inventory
      end
   end
end)

game.Players.PlayerRemoving:Connect(function(player)
   pcall(function()
      ds:SetAsync("Player_"..player.UserId, game:GetService("HttpService"):JSONEncode(player.Inventory:GetChildren()))
   end)
end)

game:GetService("ReplicatedStorage"):WaitForChild("AddItem"):Connect(addItem)
game:GetService("ReplicatedStorage"):WaitForChild("RemoveItem"):Connect(removeItem)

game:BindToClose(function()
   task.wait(5)
end)
2 Likes

If you need it to save whenever a player leaves and load whenever the player joins, you need DataStoreService.
The functions you will need are GetAsync() and SetAsync(), but because you can not save tables inside of Roblox Datastores you need to first convert the dictionary to a string, by using httpService and its functions JSONEncode (Table to String) and JSONDecode (String to Table).

Example:

local httpService = game:GetService("HttpService")
local DSS = game:GetService("DataStoreService")
local Datastore = DSS:GetDatastore("PlayerDS")
local players = game:GetService("Players")

players.PlayerAdded:Connect(function(plr)
	local success, data = pcall(function() -- Iniates pcall(), yielding the code inside in case it errors
		return Datastore:GetAsync(plr.UserId) -- returns saved data
	end)
	
	if success and data then -- If there was no problem with getting the data (success) and the player has existent data 
		data = httpService:JSONDecode(data) -- JSON to Table
		
		-- Do what you need to do with the data
	end
end)

players.PlayerRemoving:Connect(function(plr)
	local dict = {["Apple"] = 1; ["Name"] = "Apple";} -- dictionary which needs to be saved
	dict = httpService:JSONEncode(dict) -- Table to JSON
	
	local success, errorMessage = pcall(function()
		Datastore:SetAsync(plr.UserId, dict) -- Saves data to Datastores
	end)
	
	if not success then -- There was a problem with saving the data
		warn(errorMessage) -- prints the associated errorMessage
	end
end)
2 Likes

Honestly, Roblox datastores give you 4MB of space per key. Each character is 1 byte and the data is stored as a JSON-encoded string. So you can calculate how much data a key is using with the following code:

local HttpService = game:GetService("HttpService")

local data = { --example
	Coins = 50,
	Diamonds = 30,
	Gems = 100,
	Inventory = {}
}

local space = 2^22
local size = HttpService:JSONEncode(data):len()
local percent = size/space*100

print("Data takes "..percent.."% amount of space!")

The above code should print 0.0012% for the example used. Most of the time if you don’t plan to make complex systems that store huge amounts of data(eg complex player builds) you only need a few bytes.

The point I’m trying to make is that if you save simple player data, don’t bother making compressions or converting things from one form to another, this will just waste time and complicate things for no reason. Just save the dictionary as it is and if you worry about other more important datastore problems(like data corruption) you should use a known datastore module that handles such scenarios, so you don’t need to reinvent the wheel.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.