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
Can you include the script for the CurrencyManager
aye aye capt
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
This may cause UpdateAsync to be called again as new data is being set.
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.
thanks for your help!