Save, Store and Refer to Purchased and Equipped Tools

First of all, good morning…
For some time now I’ve been working on a small project, a round-based game. For this I’m planning to design a shop, which can only be accessed from the lobby. In this shop, players can buy and equip weapons, and when the round starts, the shop closes and each player is given the weapon they had previously equiped.
But I’m facing a problem and a small mental block. The truth is that I’m quite inexperienced, and I can’t think of a way to save the weapons that players buy, so that they don’t get deleted when they leave the game.

  1. WHAT I WANT TO ACHIEVE:
    Basically, my idea was that when buying a weapon, something like a value is saved in the Player instance of each player, when equipping the weapon, the game checks if the player has previously purchased the weapon, if so, then the name of the weapon, or any way to identify it, is placed in a value (called “CurrentWeapon”) in the Player instance of the player.

  2. WHAT IS THE ISSUE?
    Now coming to the problem, I don’t know how I can make the system to know what weapons the player has bought, and to be able to refer to the weapons that the player has bought when he wants to equip a weapon.

  3. What solutions have you tried so far?
    My first idea was to create a boolValue for each weapon, inside a folder called PurchasedWeapons, in the Player instance, but a part of me thinks that doing this can be quite complicated and perhaps heavy for the game.

For the moment I have only created the IntValue called CurrentWeapon in the Player, and to refer to x weapon, I have placed it in the ToolTip of each one a number, if the CurrentWeapon number matches the ToolTip number, then I give x weapon to the player.

If you want to save data between games such as joining and leaving. Use Datastores, they can save data between game sessions. there is several tutorials on how to do this on youtube. but i will give a brief rundown.

local DatastoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")

local Scope = DatastoreService:GetDataStore("Playerdata") -- This is the datastore where everything will be saved

Players.PlayerAdded:Connect(function(Player)
	local Success, ErrorMessage = pcall(function()
		local Data = Scope:GetAsync(Player.UserId) -- You should always use the user id because the player cannot change it
		
		--Change all of your values in the folder here
	end)
	if ErrorMessage then
		warn(ErrorMessage)
	end
end)

Players.PlayerRemoving:Connect(function(Player)
	local Success, ErrorMessage = pcall(function()
		local Data = {} -- since datastores cant save instances we can use a table/dictionary to save them
		
		Data.ExampleData = Player.Userdata.OwnedGun.Value
		
		Scope:SetAsync(Player.UserId, Data) -- the first value is the Key or the user id, and the second is the data you want to save
	end)
	if ErrorMessage then warn(ErrorMessage) end
end)

ohnestly the most basic kind of datastores, but it works for what I think you want to achive.

Hope this helps!

Yes, I have heard about datastores, the truth is I have not read much about their operation but I more or less understand it, but my question is not that exactly, my problem is how can I store the weapons that the player has purchased, in an accessible way and from which I can easily refer to it to identify whether or not the player has purchased a weapon, I am sorry if I was not very clear in my initial message. Do you think it is a good idea to create a folder in the Player and place a boolvalue inside it to know if the player has bought a weapon or not? Do you think that saving so many boolvalues with datastore could be very heavy?

I would probably get the data from the datastore and cache it in a module so other scripts can access it. This’ll work if you’re identifying if a weapon is bought or not on the server. For saving the weapon, if it doesn’t have unique attributes like enchantments and it’s just a regular tool then I’d save them as strings in a table.

Example:


local WeaponsData = {
  "Mace", 
  "Sword", 
 .... 
}

if you want to save your data when people join and then they leave you can use DataStoreService this is basically your games memory, where it stores each players information permanently

game.Players.PlayerAdded:Connect(function(player)
    local playerData
    local success, errorMessage = pcall(function()
        playerData = playerWeaponsDataStore:GetAsync(player.UserId)
    end)
    if success then
        if playerData then
            player:SetAttribute("PurchasedWeapons", playerData)
        else
            player:SetAttribute("PurchasedWeapons", {})
        end
    else
        warn("Failed to load player data: " .. errorMessage)
    end
end)


function buyWeapon(player, weaponName)
    local purchasedWeapons = player:GetAttribute("PurchasedWeapons") or {}
    table.insert(purchasedWeapons, weaponName)
    player:SetAttribute("PurchasedWeapons", purchasedWeapons)

    local success, errorMessage = pcall(function()
        playerWeaponsDataStore:SetAsync(player.UserId, purchasedWeapons)
    end)
    if not success then
        warn("Failed to save player data: " .. errorMessage)
    end
end


1 Like

I see, I don’t know why but I had the idea that saving tables in datastore was not possible, now looking at it this way I have an idea of ​​how to do it.
Right now I’m away from my PC, but when I have time I’ll try it.
Thanks :slight_smile:

1 Like

No problem! If you need anymore help just ask :slight_smile: