in reply to Infinite LOOP and reading from STDIN

Your program blocks waiting for user input, and we can take advantage of that for a simpler answer to timed events.

All you need is to store a timestamp for the last time doHeartbeat has been run and compare it to the current time before updating it. You now know how many seconds have elapsed since you last "looked at" the player's status, so you handle healing and mana recharge by "catching up" to the events that "transpired" while the program was waiting for input.

As an example, suppose that a player normally gains 1 mana every minute. The doHeartbeat procedure would then subtract the stored timestamp from time, divide by 60 seconds to a minute, multiply by 1 mana per minute, and add the result to the player's mana pool. (You have to track fractional mana, but you do not have to display it.)

With the code you have shown, doHeartbeat is executed once for each command the user gives. You might also want to fix the "doHeatbeat" typo. :-)

Lastly, using $_ and making the loop while(<STDIN>) will cause the program to exit if STDIN reaches EOF, rather than needing Control-C.