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

How to call function in different Service for Data Stores?

Asked by 5 years ago

I'm trying to create a small game and try to learn Lua by creating a problem I want in my game and trying to code them. I wanted to create Data storage. I used the Roblox tutorial https://developer.roblox.com/en-us/articles/Saving-Player-Data.

I understand all the lines except for this.

    -- Function that other scripts can call to change a player's stats
    function PlayerInfo:ChangeStat(player, statName, value)
        local playerUserId = "Player_" .. player.UserId
        assert(typeof(sessionData[playerUserId][statName]) == typeof(value), "ChangeStat error: types do not match")
        if typeof(sessionData[playerUserId][statName]) == "number" then
            sessionData[playerUserId][statName] = sessionData[playerUserId][statName] + value
        else
            sessionData[playerUserId][statName] = value
        end
    end

To my understanding that a function that given the player, stat name, and value will save the value if it's a number and if a string will save value as the name of the string. If this is correct how would I go about calling this code from a different script attached to a part?

For Instance, I created a small sphere and added particle effects to represent experience orbs, Once the player comes in contact I was going to create a hit function that destroys the orb and updates the player's experience using and UpdateAsync.

How would I go calling the function or am I just supposed to return values and it saves it. I really want to understand more than anything. I tried to look at Roblox Studio Base games and other videos online. The Roblox Studio Line runner game almost had what I was looking for , but I believe it's different because it just creates a clone of the script.

Additionally, am I going about data stores the correct way I saw some other videos online of people creating folders and saving values into those folders would that be more efficient then how I'm going about this currently? Any help is greatly appreciated

One last thing I noticed most people put files into ServerScriptService or ServerStorage. At the start of the tutorial, it instructs you to make a ModuleScript and put it in the ServerStorage. Everyone seems to put it in the ServerScriptService which I believe ran as soon as the game is launched. I was reading up on ModuleScript and has stated on the Roblox Wiki

A ModuleScript is a type of Lua source container that runs once and must return exactly one value. This value is then returned by a call to require given the ModuleScript as the only argument. ModuleScripts run once and only once per Lua environment and return the exact same value for subsequent calls to require.

Is this only supposed to actually return a single value? I know this is meant to used functions over and over, but any help on that would be awesome as well.

If you made it this far Thank you just for reading this! Once again all help welcomed and will be greatly appreciated!!

Full Code :

-- Set up table to return to any script that requires this module script
    local PlayerInfo = {}

    --new variable for the data store in the same ModuleScript and call GetDataStore() to open a new PlayerData data store
    local DataStoreService = game:GetService("DataStoreService")
    local playerData = DataStoreService:GetDataStore("PlayerData")

    -- Table to hold player information for the current session
    local sessionData = {}

    local AUTOSAVE_INTERVAL = 60

    -- Function that other scripts can call to change a player's stats
    function PlayerInfo:ChangeStat(player, statName, value)
        local playerUserId = "Player_" .. player.UserId
        assert(typeof(sessionData[playerUserId][statName]) == typeof(value), "ChangeStat error: types do not match")
        if typeof(sessionData[playerUserId][statName]) == "number" then
            sessionData[playerUserId][statName] = sessionData[playerUserId][statName] + value
        else
            sessionData[playerUserId][statName] = value
        end
    end

    -- Function to add player to the "sessionData" table
    local function setupPlayerData(player)
        local playerUserId = "Player_" .. player.UserId
        local success, data = pcall(function()
            return playerData:GetAsync(playerUserId) --GetASync() checks if holding any data
        end)

        if success then 
            if data then
            --Data exists for this player
            sessionData[playerUserId] = data
            else 
            --Data store is working, but no current saved data for this player
            sessionData[playerUserId] = {Gold=0, Experience=0}
            end
        else
            warn("Cannot access data store for player!")
        end
    end

    -- Function to Save player Data
    local function savePlayerData(playerUserId)
        if sessionData[playerUserId] then
            local tries = 0
            local success
            repeat
                tries = tries + 1
                success = pcall(function()
                    playerData:SetAsync(playerUserId, sessionData[playerUserId])
                end)
            until tries == 3 or success
            if not success then 
                warn("Cannot save data for the player!")
            end
        end
    end

    -- Function to save player data on exit
    local function saveOnExit(player)
        local playerUserId = "Player_" .. player.UserId
        savePlayerData(playerUserId) 
    end
        -- Function to save player's data
    local function savePlayerData(playerUserId)
        if sessionData[playerUserId] then
            playerData:SetAsync(playerUserId, sessionData[playerUserId])
        end
    end

    -- Function to save player data on exit
    local function saveOnExit(player)
        local playerUserId = "Player_" .. player.UserId
        savePlayerData(playerUserId)
    end

    -- Function to Autosave every X(AUTOSAVE_INTERVAL variable defined above) mins
    local function autoSave()
        while wait(AUTOSAVE_INTERVAL) do 
            for playerUserId, data in pairs (sessionData) do
                savePlayerData(playerUserId)
            end
        end
    end

    -- Once player is spawned starts running "autoSave()" function
    spawn(autoSave)

    -- Connect "setupPlayerData()" function to "PlayerAdded" event (PlayerAdded when Human Joins Server)
    game.Players.PlayerAdded:Connect(setupPlayerData)

    -- Connect "saveOnExit()" function to "PlayerRemoving" event (PLayerRemoving is when a Human is leaving the Server)
    game.Players.PlayerRemoving:Connect(saveOnExit)

    return PlayerInfo
0
Yeah this is too much information. Attention spans only get shorter and shorter, there is no way anyone will read that wall of text. incapaz 195 — 5y
1
Basically I just want to know how to call first function to read/update the value there in a different script outside the current service Froxtyy 4 — 5y

Answer this question