Hi there! I have two scripts. One awards a player with currency every 5 seconds,

local currencymanager = require (game.ServerStorage.CurrencyManager)

while wait(5) do 
	for _, player in ipairs(game.Players:GetPlayers()) do
		currencymanager:Deposit(player.UserId,1)
		local balance = currencymanager:GetBalance(player.UserId)
		game.ReplicatedStorage.CurrencyEvents.UpdateCurrencyDisplay:FireClient(player,balance)
		print("given a diamond" .. balance)
	end
end

And the other script allows a player to collect a physical piece of the currency off the ground and add it to their balance.

local currencymanager = require (game.ServerStorage.CurrencyManager)
local sound = script.Parent:FindFirstChild("Sound")
local waittime = 5 -- Time Between each hit
local amnt = 1 --how much you get for it
local db = false --the debounce

function onTouched(part)
    if not db then
        db = true --Turn on debounce
        local thisplr = game.Players:GetPlayerFromCharacter(part.Parent)
        if thisplr then
			currencymanager:Deposit(thisplr.UserId,amnt)
			local balance = currencymanager:GetBalance(thisplr.UserId)
			game.ReplicatedStorage.CurrencyEvents.UpdateCurrencyDisplay:FireClient(thisplr,balance)
            sound:Play();
        	end
        end
        script.Parent.Transparency = 1
        wait(waittime)
        script.Parent.Transparency = 0 
        db = false 
    end

script.Parent.Touched:connect(onTouched)

However, these two scripts are clashing with each other, and will only accept one at once. For instance, Sometimes I cannot pick up the currency as the other script is adding to the amount. Or if I pick up currency, it stops the first script for some time (the script that gives currency over time) before it works again. I am guessing I need something other than "wait", but I'm just not quite sure what! Any ideas?

Thanks a ton!

currency manager:

local CurrencyManager = {}

-- Services
local DataStoreService = game:GetService("DataStoreService")

-- Variables
local timeZoneOffset = -8 * 60 * 60
local dailyLoginBonus = 20
local initialFunds = 100

-- Constants
local DATASTORE_RETRIES = 5

-- Private Variables
local playerDataStore = DataStoreService:GetDataStore("PlayerData")

-- Private Functions

local function dataStoreRetry( dataStoreFunction )
    local tries = 0
    local success = true
	local message = ""
    local data = nil

    repeat
        tries = tries + 1
        success, message = pcall( function() data = dataStoreFunction() end )
        if not success then wait(1) end
    until tries == DATASTORE_RETRIES or success
    if not success then
        error( 'Could not access DataStore! You should warn players that their data might not get saved! :: ERROR MSG -> "' .. message .. '"' )
    end

    return success, data
end

local function batchTransactions( playerID, transactions, deposit )
    local balance = 0

    -- Get sum of all transactions
    local total = 0

    for i = 1, #transactions do
        if deposit then
            total = total + transactions[i]
        else
            total = total - transactions[i]
        end
    end

    local enoughMoney = true
    local success = dataStoreRetry( function()
        playerDataStore:UpdateAsync( playerID, function( oldData )
            -- Check if player has enough funds to cover transaction
            if oldData.Currency + total >= 0 then
                oldData.Currency = oldData.Currency + total
            else
                enoughMoney = false
            end

            balance = oldData.Currency
            return oldData
        end)
        return true
    end)

    return success, balance, enoughMoney
end

-- Setters

-- Set time zone for server
function CurrencyManager:SetTimeZoneOffsetHours( offset )
    timeZoneOffset = offset * 60 * 60
end

-- Set amount to award players when they log in for the first time each day
function CurrencyManager:SetDailyLoginBonus( bonus )
    dailyLoginBonus = bonus
end

-- Set the initial amount of currency a new player gets when they first join the server
function CurrencyManager:SetInitialFunds( initial )
    initialFunds = initial
end

-- Public Functions

-- Store that a player owns an asset in game
function CurrencyManager:GiveAsset( playerID, assetID )
    local success = dataStoreRetry( function()
        local assetPurchaseHistory = DataStoreService:GetDataStore( playerID, "AssetPurchaseHistory" )
        assetPurchaseHistory:SetAsync( assetID, true )
    end)

    return success
end

-- Check if a player owns an asset in game
function CurrencyManager:HasAsset( playerID, assetID )
    local found = false
    local success = dataStoreRetry( function()
        local assetPurchaseHistory = DataStoreService:GetDataStore( playerID, "AssetPurchaseHistory" )
        found = assetPurchaseHistory:getAsync( assetID )
    end)

    return found
end

-- Deposit a table of transactions for a given player
function CurrencyManager:DepositBatch( playerID, deposits )
    return batchTransactions( playerID, deposits, true )
end

-- Deposit an amount of currency to a player
function CurrencyManager:Deposit( playerID, amount )
    return batchTransactions( playerID, {amount}, true )
end

-- Withdraws a table of transactions for a player
function CurrencyManager:WithdrawBatch( playerID, withdrawals )
    return batchTransactions( playerID, withdrawals, false )
end

-- Withdraws an amount of currency from a player
function CurrencyManager:Withdraw( playerID, amount )
    return batchTransactions( playerID, {amount}, false )
end

-- Sets up the datastore for when a new player joins the server
function CurrencyManager:InitializePlayer( playerID )
    local success = dataStoreRetry( function()
        playerDataStore:UpdateAsync(
			playerID, 
			function( oldData )
	            if not oldData or oldData == {} then
	                oldData = {}
	                oldData.Currency = initialFunds
	                oldData.LastLoginReward = 0
	                return oldData
	            end
        end)
    end)
    return success
end

-- Check the current balance of a player
function CurrencyManager:GetBalance( playerID )
    local balance = 0
    local success = dataStoreRetry( function()
        local playerData = playerDataStore:GetAsync( playerID )
        balance = playerData.Currency
        return true
    end)

    return balance
end

-- Check if product purchase has been handled
function CurrencyManager:PurchaseHandled( playerID, purchaseID )
    local purchased = false
    local success = dataStoreRetry( function()
        local playerPurchaseHistory = DataStoreService:GetDataStore( playerID, "PurchaseHistory" )
        purchased = playerPurchaseHistory:GetAsync( purchaseID )
    end)

    return success, purchased
end

-- Handle product purchase to buy with Robux
function CurrencyManager:HandleRobuxPurchase( assetID, receiptInfo )
    local balance = 0
	local amount = 0
    local success = dataStoreRetry( function()
        local playerPurchaseHistory = DataStoreService:GetDataStore( receiptInfo.PlayerId, "PurchaseHistory" )

        -- First attempt to grant asset
        local batchSuccess = false
        batchSuccess, balance = batchTransactions( receiptInfo.PlayerId, {amount}, true )
        if not batchSuccess then
            return false
        end

        -- Asset awarded, record transaction
        playerPurchaseHistory:SetAsync( receiptInfo.PurchaseId, tick() )
        return true
    end)

    return success, balance
end

-- Check if player has logged in today
function CurrencyManager:CheckDailyLogin( playerID )
    local todayThreshold = math.floor( (tick() + timeZoneOffset ) / ( 24 * 60 * 60 ) )
	print( "Got threshold - " .. todayThreshold )

    local success = dataStoreRetry( function()
        playerDataStore:UpdateAsync( playerID, function( oldData )
            if oldData.LastLoginReward < todayThreshold then
                oldData.LastLoginReward = todayThreshold
                oldData.Currency = oldData.Currency + dailyLoginBonus
                return oldData
            end
        end)

        return true
    end)

    return success
end


return CurrencyManager

6 comments

1

Can you include the script for the CurrencyManager

1

aye aye capt

1

The first thing I can see is that you are setting the same key too often, You can only set data to the same key once every 6 seconds (you have the loop on 5) see http://wiki.roblox.com/index.php?title=Data_store#Per_Place_Limit

1

This may cause UpdateAsync to be called again as new data is being set.

1

I would store the players currency in a script as a variable so it can be accessed at all times but save the players data every minute.

1

thanks for your help!