Javascript game engine - is constant setInterval going to be A Bad Thing?
-
Fucking around with doing some javascript game programming because raisins.
Starting with just simulating a bouncing ball. If this was something like MonoGame, there'd be a game loop that ticked every (some time interval), and you use the OnTick event to do physics and movement and collision detection and stuff.
I was thinking of doing something like this:
var FramesPerSecond = 24 var TickCallBacks = $.Callbacks; // in document ready have all objects register a tick callback setInterval(DoTicks, 1000 / FramesPerSecond); function DoTicks() { TickCallBacks.fire(); }
Is having a game loop in Javascript a bad thing? I /thought/ setInterval was non-blocking, but who the fuck knows with Javascript.
-
setInterval is non-blocking, that should be fine as long as DoTicks doesn't take too much time to execute.
-
@Lorne-Kates What would be the alternative?
You're going to have to measure the time of the "tick" (or run it faster than your framerate), same as C#, because setInterval is a pretty loose timer and it'll undoubtedly skip frames if left to its own devices.
I'm not entirely sure what you mean by non-blocking, but keep in mind:
- Only one chunk of JavaScript can run at a time (there's no, zero, nada, parallelization. Not even in Node.JS, you need processes to do that.)
- The browser generally won't update the DOM/screen until your JavaScript function gives up control. This varies by browser, but you should assume no drawing will happen until your JS gives up control.
EDIT: I forgot about WebWorkers, I think there is a little parallelization you can do in this marvelous magical world that wasn't available back when I was working in this junk.
So far the games I've seen in JS have been very simple boring JRPG-style shitfests, like Bermuda and Unhack.
-
@Lorne-Kates You should be using requestAnimationFrame, if it is available.
-
@blakeyrat said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
I'm not entirely sure what you mean by non-blocking,
The time that setInterval is waiting to fire, it isn't just chomping up 100% CPU and preventing anything else from happening.
but keep in mind:
{nod nod} Good advice.
-
@mott555 said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
setInterval is non-blocking, that should be fine as long as DoTicks doesn't take too much time to execute.
I'm hoping to keep it fairly simple. Move the ball based on velocity + gravity, check for collision with a few objects and/or wall. Score as needed.
-
@Lorne-Kates said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
The time that setInterval is waiting to fire, it isn't just chomping up 100% CPU and preventing anything else from happening.
Of course not, what would be the point of it existing if it did? Might as well use a busy-loop.
But it's also not a very precise timer. You'd be better off being able to run your game logic in framerate/2 time so you could fire off your timer fast enough to ensure you're not skipping frames.
-
Did you get tired of War?
-
@blakeyrat if it is in browser it is best to use Request Animation Frame and then fallback to setInterval if that isn't available in browser.
-
@lucas1 I would agree with that but I am a geezer who did not until this thread know that "Request Animation Frame" existed.
-
@boomzilla said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
Did you get tired of War?
I'm planning a re-write of that now that I know slightly more about creating not-completely-fucky cardgame engines.
-
@lucas1 said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
@Lorne-Kates You should be using requestAnimationFrame, if it is available.
It's 2016, and using a game loop is still a best practice, exactly as it was 20+ years ago? Cool.
-
@Groaner As opposed to what?
-
requestAnimationFrame is going to fire really fast when the window has focus and really slow when it doesn't, so be warned that you probably shouldn't do something like physics simulation in that.
-
@Groaner Yes and no. Request Animation frame makes sure you draw at the right time, it basically vsync but for browsers, and it makes animations a lot smoother.
Apparently linking to MDN telling you how you should do it properly is a WTF.
-
All functions in Javascript are blocking, when they're actually running. The exception is web workers, which are still blocking but run in a different thread.
When an interval or timeout is set, though, the actual wait time isn't blocking. So no, you're not hogging the CPU any more than necessary there. Just don't rely on it being exactly 1000 / FramesPerSecond between each time the function runs, and you should be pretty much fine.
@ben_lubar said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
requestAnimationFrame is going to fire really fast when the window has focus and really slow when it doesn't, so be warned that you probably shouldn't do something like physics simulation in that.
Your physics simulation should figure out how much time elapsed since the last time it was called and do its work accordingly.
The setInterval version probably should too, because the interval isn't that precise. It's going to vary. Especially if something else suddenly wants to hog the CPU.
-
@anotherusername also, to accurately figure out the elapsed time, look at performance.now(). It returns a DOMHighResTimeStamp and it's much more accurate than using the difference between two Date objects. It also won't be affected if the system clock is changed, either manually or by synchronizing it with an internet time source.
-
@blakeyrat said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
@Groaner As opposed to what?
I dunno, a collection of fancy-schmancy event handlers that fire whenever the renderer is about to render the next frame, or when two physics objects collide, or upon receiving a remote procedure call, to be run concurrently over a dozen worker threads?
Unity tries to get developers into that mindset by making them work through
Update()
and event handlers on GameObjects. The Ogre samples suggest that work should be done inframeRenderingQueued()
. While event-driven APIs are nice, working with a simple, single-threaded game loop is quite comforting and familiar.
-
@anotherusername said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
Your physics simulation should figure out how much time elapsed since the last time it was called and do its work accordingly.
And that's a whole topic on its own. I'll just leave this here...
-
@Groaner You'd do that for a lot of things, but some things really are time-based, and need to happen regularly. Other things may trigger off that, but you've got to have a loop in there somewhere.
EDIT: Unless it's turn-based or a card game, in which case it could potentially be entirely event based.
-
@Magus said in Javascript game engine - is constant setInterval going to be A Bad Thing?:
@Groaner You'd do that for a lot of things, but some things really are time-based, and need to happen regularly. Other things may trigger off that, but you've got to have a loop in there somewhere.
EDIT: Unless it's turn-based or a card game, in which case it could potentially be entirely event based.
Yeah, it also makes things much easier when you don't have to account for race conditions between different subsystems.
The project I'm currently working on is almost completely single-threaded (some subsystems have worker threads), and practically every subsystem has an
update()
method that gets called every frame which fires all the event handlers. Event-driven, but in a deterministic and single-threaded manner - the best of both worlds.
-
The few JS games I've played and bothered to peek at the source use setTimeout. If something gets fucked up and your setInterval function throws an uncaught error it still tries to execute again and again, spamming you with errors. If you set up a good setTimeout loop though, it will stop at that first error.
Of course there are ways to stop an interval
ifwhen things go tits up, but it's less headache IMO to just use setTimeout.I've not tried requestAnimationFrame but looking at that MDN article it's more or less the same as setTimeout except you have no direct control over how long it delays.
-
javascript anything is a bad idea