Money counter keeps going over wallet limit

I have this game that involves collecting money over time. They can use the money to spawn units to protect their base, upgrade wallet, etc. My problem is that the amount of money keeps going over the maximum they are supposed to have. Also, for some reason the money increases irregularly, almost as if there are 2 timers going on at once.

Here is the code that controls the incrementation:

local function increaseMoney() if moneyCount == moneyWallet then else moneyCount = moneyCount + 10 moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) end end local moneyCounterTimer = timer.performWithDelay(increasePerTime, increaseMoney, 0) local function upgradeUpdate() increasePerTime = increasePerTime - 10 moneyLVL = moneyLVL + 1 moneyCount = moneyCount - costToUpgrade costToUpgrade = costToUpgrade + 100 moneyWallet = moneyWallet + 335 end local function upgradeMoney(event) if event.phase == "began" then if moneyCount == costToUpgrade or moneyCount \> costToUpgrade then if moneyLVL \< 8 then upgradeUpdate() upgradeText.text = "Upgrade: \nLevel " .. tostring(moneyLVL) costUpgradeText.text = "$" .. tostring(costToUpgrade) moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) timer.cancel(moneyCounterTimer) local moneyCounterTimer = timer.performWithDelay(increasePerTime, increaseMoney, 0) end if moneyLVL == 8 then upgradeText.text = "Upgrade: \nMAX " upgradeText.fontSize = 15 costUpgradeText.text = "" end else print("Insufficient Funds") end end end upgradeCapEfi:addEventListener("touch", upgradeMoney)

Any help would be great! Plus, I added a video for your convenience.

https://youtu.be/Sc52e2NX7ow

  1. You are not checking whether adding 10 will take you over the moneyWallet, you only check whether your moneyCount is exactly the same as moneyWallet. 

For example, if moneyCount is 499 and moneyWallet is 500, it will still add 10 and you’ll end up with 509, 519, 529 etc.

  1. When you reset the moneyCounterTimer in upgradeMoney, you need to remove the ‘local’. Otherwise you are creating a timer which is local to that instance of upgradeMoney, and will lose that reference as soon as the function finishes. The next time it runs, it tries to cancel ‘moneyCounterTimer’ but this is referring to the old timer initialised near the top that was already cancelled, so will not cancel anything.

Wow, thanks for the explanation! I will need to try this.

This solved everything except for one problem:

https://youtu.be/WY8NqJQJBiw

Here is the current code: 

local function increaseMoney() if moneyCount == moneyWallet then elseif moneyCount \> moneyWallet then moneyCount = moneyWallet else moneyCount = moneyCount + 23 moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) end end local moneyCounterTimer = timer.performWithDelay(increasePerTime, increaseMoney, 0) local function upgradeUpdate() increasePerTime = increasePerTime - 10 moneyLVL = moneyLVL + 1 moneyCount = moneyCount - costToUpgrade costToUpgrade = costToUpgrade + 100 moneyWallet = moneyWallet + 335 end local function upgradeMoney(event) if event.phase == "began" then if moneyCount == costToUpgrade or moneyCount \> costToUpgrade then if moneyLVL \< 8 then upgradeUpdate() upgradeText.text = "Upgrade: \nLevel " .. tostring(moneyLVL) costUpgradeText.text = "$" .. tostring(costToUpgrade) moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) timer.cancel(moneyCounterTimer) moneyCounterTimer = timer.performWithDelay(increasePerTime, increaseMoney, 0) end if moneyLVL == 8 then upgradeText.text = "Upgrade: \nMAX " upgradeText.fontSize = 15 costUpgradeText.text = "" end else print("Insufficient Funds") end end end upgradeCapEfi:addEventListener("touch", upgradeMoney)

This code has issues: 

local function increaseMoney() if moneyCount == moneyWallet then elseif --\<----- not usually done this way moneyCount \> moneyWallet then moneyCount = moneyWallet --\<----- Note this line else moneyCount = moneyCount + 23 moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) end end

Usually you would not code like this. Instead you would do:

if moneyCount \<= moneyWallet then &nbsp; &nbsp; &nbsp;moneyCount = moneyCount + 23 &nbsp; &nbsp; &nbsp;... end

But if you want it to completely fill to the value of moneyWallet then you would do

moneyCount = moneyCount + 23 if moneyCount \> moneyWallet then &nbsp; &nbsp; &nbsp; moneyCount = moneyWallet end

assuming moneyWallet is the maximum you want to clamp to.

Now for the line I noted. That’s an assignment operation not a conditional test. The value of moneyWallet will be assigned to moneyCount and since the value isn’t nil or false, it will evaluate to true with regards to the conditional test.

Rob

I just realized what was wrong, I never set the new value or moneyCount to the text object.

Now it works.

local function increaseMoney() moneyCount = moneyCount + 23 moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) if moneyCount \> moneyWallet then moneyCount = moneyWallet moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) end end

Thanks @Rob Miracle, @nick_sherman.

  1. You are not checking whether adding 10 will take you over the moneyWallet, you only check whether your moneyCount is exactly the same as moneyWallet. 

For example, if moneyCount is 499 and moneyWallet is 500, it will still add 10 and you’ll end up with 509, 519, 529 etc.

  1. When you reset the moneyCounterTimer in upgradeMoney, you need to remove the ‘local’. Otherwise you are creating a timer which is local to that instance of upgradeMoney, and will lose that reference as soon as the function finishes. The next time it runs, it tries to cancel ‘moneyCounterTimer’ but this is referring to the old timer initialised near the top that was already cancelled, so will not cancel anything.

Wow, thanks for the explanation! I will need to try this.

This solved everything except for one problem:

https://youtu.be/WY8NqJQJBiw

Here is the current code: 

local function increaseMoney() if moneyCount == moneyWallet then elseif moneyCount \> moneyWallet then moneyCount = moneyWallet else moneyCount = moneyCount + 23 moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) end end local moneyCounterTimer = timer.performWithDelay(increasePerTime, increaseMoney, 0) local function upgradeUpdate() increasePerTime = increasePerTime - 10 moneyLVL = moneyLVL + 1 moneyCount = moneyCount - costToUpgrade costToUpgrade = costToUpgrade + 100 moneyWallet = moneyWallet + 335 end local function upgradeMoney(event) if event.phase == "began" then if moneyCount == costToUpgrade or moneyCount \> costToUpgrade then if moneyLVL \< 8 then upgradeUpdate() upgradeText.text = "Upgrade: \nLevel " .. tostring(moneyLVL) costUpgradeText.text = "$" .. tostring(costToUpgrade) moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) timer.cancel(moneyCounterTimer) moneyCounterTimer = timer.performWithDelay(increasePerTime, increaseMoney, 0) end if moneyLVL == 8 then upgradeText.text = "Upgrade: \nMAX " upgradeText.fontSize = 15 costUpgradeText.text = "" end else print("Insufficient Funds") end end end upgradeCapEfi:addEventListener("touch", upgradeMoney)

This code has issues: 

local function increaseMoney() if moneyCount == moneyWallet then elseif --\<----- not usually done this way moneyCount \> moneyWallet then moneyCount = moneyWallet --\<----- Note this line else moneyCount = moneyCount + 23 moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) end end

Usually you would not code like this. Instead you would do:

if moneyCount \<= moneyWallet then &nbsp; &nbsp; &nbsp;moneyCount = moneyCount + 23 &nbsp; &nbsp; &nbsp;... end

But if you want it to completely fill to the value of moneyWallet then you would do

moneyCount = moneyCount + 23 if moneyCount \> moneyWallet then &nbsp; &nbsp; &nbsp; moneyCount = moneyWallet end

assuming moneyWallet is the maximum you want to clamp to.

Now for the line I noted. That’s an assignment operation not a conditional test. The value of moneyWallet will be assigned to moneyCount and since the value isn’t nil or false, it will evaluate to true with regards to the conditional test.

Rob

I just realized what was wrong, I never set the new value or moneyCount to the text object.

Now it works.

local function increaseMoney() moneyCount = moneyCount + 23 moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) if moneyCount \> moneyWallet then moneyCount = moneyWallet moneyText.text = tostring(moneyCount) .. " / " .. tostring(moneyWallet) end end

Thanks @Rob Miracle, @nick_sherman.