[Solved] Difference between an input listener and "always"

Kajitii

  • Posts: 184
In terms of computer resources taken, what's the difference between an input listener and a block of "always" code that does something when a key a pressed?  A pic for those confused by what I mean has been included.

Related, more specific question: how often do the listener and "always" code run?  Every frame?  Even faster?  Whenever a star goes supernova?

« Last Edit: June 10, 2012, 12:40:43 am by Kajitii »

Ryusui

  • Posts: 827
"Always" code runs every frame. Not sure about listeners.
In the event of a firestorm, the salad bar will remain open.

captaincomic

  • *
  • Posts: 6108
The listener will only run once whenever the key is pressed, but I'm not sure how much performance cost it is to "listen" to a key press. It's probably similar to one "if key was pressed" in always, which will be negligible anyway in most situations.

Kajitii

  • Posts: 184
"Always" code runs every frame.

This is apparently not true.  I was experimenting with counters for delayed control responses.  I took it to the test, and triggered the "if" condition for 10 seconds (using an analog "handy" clock).  On average, the FlxG counter counted up to 10 seconds, while the other counter counted about 16 seconds.  Interestingly enough, if I printed the statement everytime the FlxG counter changed value, it would appear to lag, but I'm going to disregard it xD

I also did the test while artificially lowering the fps.  The results are the same.

EDIT:  Oops forgot the attachment!

« Last Edit: June 09, 2012, 04:50:33 pm by Kajitii »

hansbe

  • Posts: 262
I have been wondering myself how it works. If rendering a frame would be dropped first, while updated is still executed if there is time. But of course at some point when things slow down enough it must skip update events as well.

Justin

  • *
  • Posts: 4716
Always runs 100 times a second (this is not a frame. This is an update "step")
When drawing runs, ideally, at 60 times a second. This is your framerate.

When the processor can't handle the game at 100 steps and 60 frames a second, the game continues to run 100 steps a second, but the framerate slows down. You can think of this as "frameskip".

When the framerate goes below 30, the game also begins to slow down (less than 100 update steps per second). Update events are never skipped.


In other words, saying that "always" run every frame isn't completely correct. The number of updates per second isn't the same as the number of frames drawn per second.

As for the question regarding performance, there might be a slight overhead to using a listener rather than the "if" block, but it would be negligible enough that I would never avoid using the listener for performance purposes. From a design perspective, using an "if" in always is pretty much the same as using a listener event.

« Last Edit: June 09, 2012, 09:27:03 pm by Justin »
For Live Support: Join our discord server and ping me @justin.
I'm most often available between 10am and 10pm Japan time. (GMT+9)

Kajitii

  • Posts: 184
That's a pretty good explanation Justin.  But I have to wonder, for curiosity's sake, what exactly is the computer doing when using a listener compared to the "if" in always?

Justin

  • *
  • Posts: 4716
Eh, a little too lazy to dig into it much now, but it's something like this.

Your behavior:

event: when x is pressed
event: when y is pressed

Another behavior:

event: when x is pressed
always: if y is pressed

How the engine processes it

init:
- Add a "when pressed" listener to x.
- Add a "when pressed" listener to y.
- Add a "when pressed" listener to x.

Game loop:
-run "update" for every active behavior in the game
 - When it gets to "if <y is pressed>" it checks if the key "y" has just been pressed.
. . .
-for each key that has listeners (just two: x and y)
 - if the key was pressed/released, call every listening function (x has two listeners, y has one)


I wasn't really thinking of it too much earlier, so I take back what I said. There is a slight difference to the listeners and the if condition in always. When it's a condition in always, then it's run together with all the behaviors other code. On the other hand, if it's a listener, all of the listeners are thrown into a single global registry, and they're all run one after the other whenever the keystate changes.

If you have 20 behaviors who all listen for "x", then all 20 of those listeners will be run one after the other once x is pressed.
For Live Support: Join our discord server and ping me @justin.
I'm most often available between 10am and 10pm Japan time. (GMT+9)

Kajitii

  • Posts: 184
Coolbeans, thanks for the insight.

froz

  • Posts: 250
Quote
Always runs 100 times a second (this is not a frame. This is an update "step")
When drawing runs, ideally, at 60 times a second. This is your framerate.

When the processor can't handle the game at 100 steps and 60 frames a second, the game continues to run 100 steps a second, but the framerate slows down. You can think of this as "frameskip".

When the framerate goes below 30, the game also begins to slow down (less than 100 update steps per second). Update events are never skipped.

Thank you for this information. Stencylpedia says something else or at least it is misleading. I hope someone could change it to simply state that update runs 100 times per second and drawing runs at framerate speed. Currently it says update runs every frame and drawing usually too.

http://www.stencyl.com/help/view/events-reference/

By the way, does time counter count time or update ticks? I mean, will I get always the same result if I manually count to 100 in update event and when I use block "do after 1 second", even if the game would lag? Or is the time counter always counting in real time, so in case of lag, counting via update could be slower?

hansbe

  • Posts: 262
Very useful information. Thanks, Justin!

Re, the last question: I'm pretty sure the time counter uses system time. It might a bit late for a single call, but then the next call would have a smaller delta.

Justin

  • *
  • Posts: 4716
Using the do after/do every uses timers that are updated along with the engine. So if the game is lagging, the timer blocks will also take longer. But the timers won't be run at a different "game time" even if the game is slow.
For Live Support: Join our discord server and ping me @justin.
I'm most often available between 10am and 10pm Japan time. (GMT+9)

captaincomic

  • *
  • Posts: 6108
Yeah, thanks, Justin! I didn't know that either. :)
That's very important information and I also think this should go into Stencylpedia. I always thought that "always" and "when drawing" would happen every frame/step. If you put some logic in "when drawing" and expect it to happen every step, this could lead to some hard-to-find bugs.

Kajitii

  • Posts: 184
Using the do after/do every uses timers that are updated along with the engine. So if the game is lagging, the timer blocks will also take longer. But the timers won't be run at a different "game time" even if the game is slow.

Confirmed.  I use a "do every x seconds" block for my guy when he's running, and there's never been any hiccups despite what I do to my game.  It's all smooooth as butter.