The game I am creating relies on timers for a lot of its mechanics, some of which have fairly low wait times, which can cause slight problems because of how often timers can emit their timeout signal. To add to this, I've also implemented a fast-forward feature using Engine.time_scale, which causes the timers' wait times to be even lower and thus become even more inconsistent. To fix this I can increase the physics tick rate or the fps, the former of which completely kills the game's performance, and the latter seems like it would not be consistent when the game lags (which it definitely can in some circumstances).
I'm looking for advice on this because both solutions seems to bring a wide array of disadvantages. Perhaps there's something I'm missing here that would solve this?
Looking for a solution for timers with low wait time
Donderboor2 fairly low wait times
How low are the wait times?
DaveTheCoder approx 0,03 seconds, with a speed scale of 3 that would then be 0,01
Just out of curiosity, what are you doing with all those timers with that short wait times? And what problems to they cause? How do they become inconsistent?
trizZzle The timers are used for the attacking cooldowns for towers in a tower defense game.
Timers can only emit once per physics frame or rendered frame (as stated in the docs), so wait times are capped by the duration of one of those (depending on the setting of the timer).
I see. Not sure how to handle this using such short timeouts. Never thought about this problem before.
The only thing I can think about right now is to increase timeout so it doesn't drop below frametime, even when speeding up time.
But does that tower have to attack 33x in a second?
trizZzle Well, it doesn't have to attack that fast, but it looks a lot less cool when it doesn't haha
I already tried just making it shoot more at once which works, but it's not quite what I'm looking for. It does seem that is the only option though.
- Edited
Donderboor2 I also have had trouble with timers, the way you have. I have a stamina meter that drains and refills and has a "cooldown" state in my game when exhausted.
When this happens, I find a value I can add in each frame, watch it, and when it hits a level, flip whatever bool I need to allow whatever to happen again. I should mention to incorporate delta
into those calculations for consistency between platforms.
Something like:
var _currentMoveMeter = 0 ## your "cooldown" meter
const _moveMeterTarget = 0.1 ## meter's target level before move can trigger
export var _moveInputNudge = 0.1 ## level that cooldown refills, export to save your sanity in editor for balancing/tweaking
var _canTrigger : bool = true ## this flag determines if move can trigger
func _process(_delta): ## listen if bool is open every frame
if _canTrigger: ## if open, allow move execute
### move logic (likely with an input function so it doesn't trigger each frame)
else: ## if meter empty, bool flips to disable move and cooldown begins
_currentMoveMeter+=_moveInputNudge
if _currentMoveMeter >= _moveMeterTarget: ## when cooldown hits levels, bool flips
_canTrigger = true
_currentMoveMeter = 0 ## reset at end to avoid logic weirdness
SnapCracklins Thanks for the advice. I ended up going for a similar code-based implementation using delta:
`
fire_timer += delta
while fire_timer >= firerate:
Tower.shoot_bullet(projectile, self)
fire_timer -= firerate
`
- Edited
Donderboor2 What's the point of having a 0.01 seconds cooldown? From the player's perspective that's pretty much instantaneous.
xyz Sorry for the late response, but 0.01 is only when the speed is set to 3x. Normally it would be 0.03 sec, a delay which is definitely noticeable