Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Can anyone help me fix this difficult datastore bug?

Asked by
St_vnC 330 Moderation Voter
5 years ago

I have problems with my RPG datastore here's save/Load data part of the script :

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local DataStore = DataStoreService:GetDataStore('Data')

-- Settings
local StarterData = {
    MaxChar = 5;
    LStats = {
        Lvl = 1;
        XP = 0;
        Coins = 0;
    };

    savedStats = {
        Mana = 50;
        Health = 100;
        Class = "Adventurer";
        CharName = "Name";
        CurrentPlace = 0;
        CurrentPos = Vector3.new(0,0,0)
    };
    Stats = {
        HitChance = 0;
        CritChance = 0;
        Attack = 0;
        MagicAttack = 0;
        Defense = 0;
        MagicDefense = 0;
        Dodge = 0;
    };
    StatPts = {
        Strength = 5;
        Intelligence = 5;
        Dexterity = 5;
        Agility = 5;
        Vitality = 5;
    };
    Char = {
        HairStyle = "Default";
        HairColor = Color3.new(0,0,0);
        Gender = "Boy";
        SkinColor = BrickColor.new("Light orange").Color;
        Mustache = "None";
        Eye = "Default";
        EyeColor = Color3.new(0.1,0.05,0)
    };
    Inventory = {       
        MaxSlots = 50;
        SlotSample = {
            Item = "Rock";
            Type = "Equipments";
            EquipType = "Weapons";
            WeaponType = "None";
            Stackable = false;
            Stack = 0;
        };
        EquipmentSlotSample = {
            Item = "Rock";
            WeaponType = "None";
        }
    };
};
local playersavetable = {};
local AUTO_SAVE_INTERVAL = 180;

-- Functions

local function loadData(Player)
    local Data
    local s,e pcall(function()
        Data = DataStore:GetAsync('UserId:'..Player.UserId)
    end)

    if s then
        print('Loading '.. Player.Name .."'s data was successful!")
    else
        print('Something went wrong!')
    end

    if Data then
        for num,Slot in pairs(Player.Slots:GetChildren()) do
            for name, value in pairs(Data) do
                if not Slot.leaderstats:FindFirstChild(name) then return end
                Slot.leaderstats[name].Value = value
            end
            for name, value in pairs(Data) do
                if not Slot.StatPts:FindFirstChild(name) then return end
                Slot.StatPts[name].Value = value
            end
            for name, value in pairs(Data) do
                if not Slot.savedStats:FindFirstChild(name) then return end
                Slot.savedStats[name].Value = value
            end
            for name, value in pairs(Data) do
                if not Slot.Char:FindFirstChild(name) then return end
                Slot.Char[name].Value = value
            end
        end 
        for _, Folder in pairs(Player.Slots["Slot"..CurrentSlot.Value]:GetChildren()) do
            for _,Stat in pairs(Folder:GetChildren()) do
                Player[Folder.Name][Stat.Name].Value = Stat.Value
            end
        end
        print('Data has been loaded')
    else
        print(Player.Name ..'has no data! Generating new data.')
    end

end

local function saveData(Player)
    if RunService:IsStudio() then return end
    local Data = {}
    -- Transfers char Current Data to current char slot.
        local Slot = Player.CurrentSlot.Value
        local Current_Slot = "Slot"..Slot
        for _,stat in pairs(Player.Slots[Current_Slot].leaderstats:GetChildren()) do
            stat.Value = Player[stat.Parent.Name][stat.Name].Value
        end
        for _,stat in pairs(Player.Slots[Current_Slot].StatPts:GetChildren()) do
            stat.Value = Player[stat.Parent.Name][stat.Name].Value
        end
        for _,stat in pairs(Player.Slots[Current_Slot].savedStats:GetChildren()) do
            stat.Value = Player[stat.Parent.Name][stat.Name].Value
        end
        for _,stat in pairs(Player.Slots[Current_Slot].Stats:GetChildren()) do
            stat.Value = Player[stat.Parent.Name][stat.Name].Value
        end
    for i,v in pairs(Player.Slots:GetChildren()) do
        for _,stat in pairs(v.leaderstats:GetChildren()) do
            Data[stat.Name] = stat.Value
        end
        for _,stat in pairs(v.StatPts:GetChildren()) do
            Data[stat.Name] = stat.Value
        end
        for _,stat in pairs(v.savedStats:GetChildren()) do
            Data[stat.Name] = stat.Value
        end
        for _,stat in pairs(v.Stats:GetChildren()) do
            Data[stat.Name] = stat.Value
        end
    end
    local s,e pcall(function()
         DataStore:SetAsync('UserId:'..Player.UserId, Data)
    end)
    if s then
        print('Success')
    else
        warn('Failed to save '.. Player.Name.. "'s data.")
    end
end

I always have problems saving data(outside of studio) it keeps printing the error message when I see no errors. I'm pretty sure I didn't exceed the DataStore budget limit, you can check if I'm wrong tho. This DataStore system is based on Mystifine's system https://www.youtube.com/watch?v=at9Yhjt572c

1 answer

Log in to vote
0
Answered by 5 years ago

Ok, lets try it

Firs Step : We need to know how to acces to the DataStoreService and how it works! So lets see how we can get the service!

local ds = game:GetService("DataStoreService")
--> This is all! Is a service of the Instance "game" so you can get it with `GetService()`

That's how we get the DataStoreService in one simple line of code!

Second Step : Second, we need to know how to use correctly the DataStore so we have to make another variable that contains the data of the currency or etc we want to Store on the service!

local ds = game:GetService("DataStoreService")
local moneyDs = ds:GetDataStore("moneyData") 
--[[
    This is all! The service "DataStore" have a function to get the Data already stored in
    so we called with the function "GetDataStore"
]]

That's how we create a variable with the data we want to save. So lets make now a leaderstats functional with the SaveData

Third Step : Enjoy coding! You always have to enjoy what are you doing! Play some music while you script or even you can play a game before to be relaxed!

Lets get into code!

local ds1 = game:GetService("DataStoreService")
local moneyDs = ds1:GetDataStore("moneyData")
local ds2 = game:GetService("DataStoreService")
local xpDs = ds2:GetDataStore("xpData")
local ds3 = game:GetService("DataStoreService")
local lvlDs = ds3:GetDataStore("levelData")
local ds4 = game:GetService("DataStoreService")
local rxpDs = ds4:GetDataStore("requiredxpData")

game.Players.PlayerAdded:Connect(function(plr)
    local folder = Instance.new("Folder", plr)
    folder.Name = "leaderstats"

    local money = Instance.new("IntValue", folder)
    money.Name = "Money"
    money.Value = moneyDs:GetAsync(plr.UserId) or 0 
    --> If the player is new and doesn't have data stored will get the value 0
    money.Changed:Connect(function()
        moneyDs:SetAsync(plr.UserId, money.Value)
        -->When the player get some monye then inmediately will store!
    end)

    local xp = Instance.new("IntValue", folder)
    xp.Name = "XP"
    xp.Value = xpDs:GetAsync(plr.UserId) or 0   
    xp.Changed:Connect(function()
        xpDs:SetAsync(plr.UserId, xp.Vaue) -->The same like on the money
    end)

    local rxp = Instance,new("IntValue", folder)
    rxp.Name = "RequiredXP
    rxp.Value = rxpDs:GetAsync(plr.UserId) or 100 --> Put your required xp for the first level
    rxp.Changed:Connect(function()
        rxpDs:SetAsync(plr.UserId, rxp.Value)
    end)

    local level = Instance.new("IntValue", folder)
    level.Name = "Level"
    level.Value = lvlDs:GetAsync(plr.UserId) or 0
    level.Changed:Connect(function()
        lvlDs:SetAsync(plr.UserId, level.Value)
    end)

    if xp.Value >= rxp.Value then
        xp.Value = xp.Value - rxp.Value
        rxp.Value + 1000 --> This will require for the next level
        level.Value = level.Value + 1 -->Give one level to the player
    elseif xp.Value <= rxp.Value then
        print("You don't have enough experience! Get more to level up!")
    end
end)

game.Players.PlayerRemoving:Connect(function(plr)
    moneyDs:SetAsync(plr.UserId, plr.leaderstats.Money.Value)
    xpDs:SetAsync(plr.UserId, plr.leaderstats.XP.Value)
    lvlDs:SetAsync(plr.UserId, plr.leaderstats.Level.Value)
    --> We are saving all the values!
end)

local warnMessage = "The code is incorrect"
pcall(warnMessage)

That's how we use the DataStore correctly and easy. I write all the code here on scriptinghelpers so that's the why I don't answer faster.

I hope my answer already solve your question! If its like that please accept my answer. That will help me a lot!

Keep scripting!

0
That’s great but I don’t want to copy and paste. Also I want to know what’s wrong in my code St_vnC 330 — 5y
0
Ok, I'll explain you on Discord. Foxy_Developer 111 — 5y
0
But later, I'll check the advanced DataStore function. And I'll try to explain you how it works. Cya Foxy_Developer 111 — 5y
Ad

Answer this question