[SOLVED] Players Inventory won't save (or maybe load)? (Datestores problem)

Overview

I am trying to make a Battle Royale-themed swording fighting game. There have been some issues saving the players swords (or loading in the swords. I am unsure what the problem is.)

Important facts:

  • DataStores are enabled with testing in Roblox Studio

  • No output Errors

  • The game has been thoroughly tested and not one time has the players swords shown on the GUI when rejoining the game

Very Detailed Pictures describing the problem


When I am in the game and I purchase the sword.

I leave the game, go back in and all of my data is missing.
bandicam%202019-04-17%2017-16-56-840
When I purchase a sword the sword goes into my inventory. When I re-join the game, the sword is no longer in the inventory. (Rainbow sword is an example.)

Code that is related to the supposed issue

I’m sorry for the incorrect formatting. Formatting on the Dev forum is very difficult. Anyways, here is a script in ServerScriptService which saves the players data.

game.Players.PlayerAdded:Connect(function(player)

playersLeft = playersLeft + 1

-- Other code here not useful to the swords PM if you need to know what I scripted here

-- Data Stores

local player_data

local weaponsData

local equippedData

pcall(function()

player_data = dataStores:GetAsync(player.UserId.."-Bucks") --12787687-Bucks

end)

pcall(function()

weaponsData = dataStores:GetAsync(player.UserId.."-Weps") --12787687-Bucks

end)

pcall(function()

equippedData = dataStores:GetAsync(player.UserId.."-EquippedValue") --12787687-Bucks

end)

if player_data ~= nil then

-- Player Has saved , load it in

bucks.Value = player_data

else

-- New Player

bucks.Value = defaultCash

end

if weaponsData then

for _, weapon in pairs(weaponsData) do

if game.ServerStorage.Items:FindFirstChild(weapon) then

local weaponClone = game.ServerStorage.Items[weapon]:Clone()

weaponClone.Parent = inventory

print(weapon.." loaded in!")

end

end

if equippedData then

equipped.Value = equippedData

player:WaitForChild("PlayerGui")

game.ReplicatedStorage.SendEquipped:FireClient(player,equippedData)

end

else

print("No weapons Data")

end

end)

local bindableEvent = Instance.new("BindableEvent")

game.Players.PlayerRemoving:Connect(function(player)

pcall(function()

dataStores:SetAsync(player.UserId.."-Bucks",player.leaderstats.Bucks.Value)

end)

pcall(function()

local weapons = game.ServerStorage.PlayerData[player.Name].Inventory:GetChildern()

local weaponsTable = {}

for _, v in pairs(weapons) do

table.insert(weaponsTable,v.Name)

end

dataStores:SetAsync(player.UserId.."-Weps",weaponsTable)

if game.ServerStorage.PlayerData[player.Name].Equipped.Value ~= nil then

local equippedVal = game.ServerStorage.PlayerData[player.Name].Equipped

dataStores:SetAsync(player.UserId.."-EquippedValue",equippedVal.Value)

end

end)

print("Saved Weapons and Bucks")

playersLeft = playersLeft - 1

bindableEvent:Fire()

end)

game:BindToClose(function()

-- This will be triggered upon shutdown

while playersLeft > 0 do

bindableEvent.Event:Wait()

end

end)

If the datastores are working properly then below I will put when the script when the swords are put in the shop UI.

I learned most of the datastores and how to save the swords from and @Alvin_Blox tutorial:

I understand If I may be asking for a lot, but this problem has been an issue for over a month so I thought this was the right time to ask the community for help. If it seems cheezy that I am using a tutorial please keep in mind that I am still learning Lua and this tutorial has helped a lot.

If you need more scripts or need to see the game yourself please DM me.

3 Likes

There is no errors since the data store requests are being done in a function that is being called in protected mode. Hint: your functions you are passing to pcall.

pcall returns false as first return value if the function you give it is called and there is an error during run time.

The second return, is the error message.

Here is an example to demonstrate this:

local success, err = pcall(function()
    return 2 + true; --// you can't add booleans
end);

print(success, err); --> false    attempt to perform arithmetic on a boolean value.

The data store requests are probably failing, you just need to get the specific error.

In your specific case, you can write something like this:

local success, data = pcall(dataStores.GetAsync, dataStores, player.UserId .. "-Bucks");
--// a:b(c) is syntactic sugar for a.b(a, c). So this is how this works.

If pcall returns true as first return value, this means the function was called successfully without any errors. So everything else after success is the returns of the function, if any.

Also for the data stores themselves, you can use a single data store for saving all the data.

Like you can have a table with a Weapons field, which will be a table of all the names of the weapons the player has, another field which is Bucks, which is the bucks they have, i don’t know exactly what EquippedValue is, but you can do the same for that as well.

Here is a small example

local playerData = {
    Bucks = 25,
    Weapons = {"Classic", "Mega", "Ultra"} --// just some random names
};

local success, err = pcall(dataStore.SetAsync, dataStore, player.UserId .. "-Data", playerData);
print(not success and err or "Data successfully saved!");

also I don’t encourage you to watch that tutorial, it has bad coding practices

2 Likes

What’s your code and the game?


This is probably not it. I have a few other ideas of interpreting your example but I’m not sure which is correct.

104: Cannot store Instance in data store. Data stores can only accept valid UTF-8 characters.

You are trying to save an instance into a data store. You cannot do this. You can, as an alternative, save the name of the object, rather than the object itself.

local weapons = game.ServerStorage.PlayerData[player.Name].Inventory:GetChildern()

local weaponsTable = {}

The children of the inventory are string values. Do I need the name of the string values instead? Seems strange because that’s what I did.

for _, v in pairs(weapons) do

table.insert(weaponsTable,v.Name)

end

What is EquippedValue supposed to be? Could that be the problem? Can you paste some code where you work with EquippedValue?

@incapaxx I scrolling through my code and I believe this is the error.

    if game.ServerStorage.PlayerData[player.Name].Equipped.Value ~= nil then
       local equippedVal = game.ServerStorage.PlayerData[player.Name].Equipped
       dataStores:SetAsync(player.UserId.."EquippedValue",equippedVal.Value)
        end
    end)

EquippedValue is knowing whether or not a sword was equipped, and also the ItemViewPort in the bottom left corner.

^ Obove me is the “Equipped” ItemViewPort

You can maybe save a table (or array) with all informations about…

{56, true, false, false, true,...}

The first value would be the money and the rest is “Did I have this object?”

--The first arry is to explain what the value is for
{Buck, FireSword, SwordOfRedEpicness, RainbowSword, BendySword,...}
{  56,      true,              false,        false,       true,...}

--Also you can save table of arrays!
{{1,2},{3,4}}