Why is a "main" game loop necessary for developing a game?
Asked Answered
A

12

52

I find that most game development requires a main game loop, but I don't know why it's necessary. Couldn't we implement an event listener and respond to every user action? Animations (etc.) could then be played when a event occurs.

What is the purpose of a main game loop?

Absorber answered 2/4, 2010 at 8:12 Comment(2)
Whether you write the main loop or not, it's going to be there. In order to have events, you need some kind of loop somewhere. It might be abstracted from you by your platform.Rexer
Strictly speaking, you do not "need some kind of loop somewhere". True enough that with most modern OS's, there will be loops somewhere, but it is entirely possible, using a 'close to the metal' approach, to construct a game platform in which everything is truly event driven, using interrupts. But even in that (extreme!) situation, there is still a reason to use loops, which is that they are the easiest way to get deterministic behavior from your system, i.e., to ensure that the relative execution rates of input, rendering, bad guys, etc, all stay consistent.Begum
B
84

The argument that you "need a loop because otherwise what calls the event listener" does not hold water. Admittedly on any mainstream OS, you do indeed have such a loop, and event listeners do work that way, but it is entirely possible to make an interrupt driven system that works without any loops of any kind.

But you still would not want to structure a game that way.

The thing that makes a loop the most appealing solution is that your loop becomes what in real-time programming is referred to as a 'cyclic executive'. The idea is that you can make the relative execution rates of the various system activities deterministic with respect to one another. The overall rate of the loop may be controlled by a timer, and that timer may ultimately be an interrupt, but with modern OS's, you will likely see evidence of that interrupt as code that waits for a semaphore (or some other synchronization mechanism) as part of your "main loop".

So why do you want deterministic behavior? Consider the relative rates of processing of your user's inputs and the baddies AIs. If you put everything into a purely event based system, there's no guarantee that the AIs won't get more CPU time than your user, or the other way round, unless you have some control over thread priorities, and even then, you're apt to have difficulty keeping timing consistent.

Put everything in a loop, however, and you guarantee that your AIs time-lines are going to proceed in fixed relationship with respect to your user's time. This is accomplished by making a call out from your loop to give the AIs a timeslice in which to decide what to do, a call out to your user input routines, to poll the input devices to find out how your user wants to behave, and call out to do your rendering.

With such a loop, you have to watch that you are not taking more time processing each pass than actually goes by in real time. If you're trying to cycle your loop at 100Hz, all your loop's processing had better finish up in under 10msec, otherwise your system is going to get jerky. In real-time programming, it's called overrunning your time frame. A good system will let you monitor how close you are to overrunning, and you can then mitigate the processing load however you see fit.

Begum answered 2/4, 2010 at 20:34 Comment(2)
I'd been wondering about this myself, and luckily for all of us, you delivered an excellent answer. Thanks @BegumIntervene
One comment: Going for 100fps in a game loop is what I would consider overkill. 10 milliseconds is not a lot of time. Very few (if any) average PC displays are actually capable of refreshing that fast. For most game logic, updating about 30 times a second is plenty.Cablegram
C
16

An event listener is also dependent on some invocation loop whether you see it or not. Who else is going to call the listener?

Building an explicit game loop gives you absolute control on what's going on so you won't be dependent on whatever some toolkit/event handling library does in its event loop.

Cellophane answered 2/4, 2010 at 8:15 Comment(2)
In the purest sense of event driven programming, you could drive everything using interrupts, so it's not strictly true that there must be a loop. The fundamental problem with events is dealing with the asynchronous nature of event driven programming; even when the events are all derived from timers, it's just much more difficult to juggle asynchronous events and get timing-consistent system behavior.Begum
@JustJeff, yea, for most applications the timing is negligible, but for games consistent timing is everything.Aerosphere
D
7

A game loop (highly simplified is as follows)

initialise
do
     input
     update
     render
loop
clean up

This will happen every frame the game is drawn. So for games that run at 60fps the above is performed sixty times every second.

This means the game runs smoothly, the game stays in sync and the updates/draws per cycle happen frequently enough. Animation is simply a trick of the eye, objects move between locations but when played quickly enough they appear to be travelling between these locations.

If you were to only update on user input, the game would only react when the user was providing input. Other game components such as A.I game objects would not react on their own. A loop is therefore the easiest and best way of updating a game.

Dullard answered 2/4, 2010 at 11:4 Comment(3)
But why don't use separate loops to do different animation?Absorber
There's no need. One game loop is enough.Dullard
@Absorber - what Finglas said is right on. The simplest thing that works is usually the best.Begum
L
6

It's not true that all kind of games require a dedicated main game loop.

Action games need such a loop due to frequent object updates and game input precision.

On the other hand, I implemented a minesweeper game and I used window
messages for the notifications.

Lilley answered 2/4, 2010 at 8:22 Comment(4)
But surely the game loop is then just Windows' own loop which you don't have any control over.Hypoxia
The point is that somehow, your program has to be notified whenever the user presses a button, moves or clicks with the mouse, or makes an input through any other peripheral device. That is, someone somewhere has to poll either the input devices directly or an input buffer (filled by the hardware) in order to discover when new user input has arrived. Either the operating system does this for you in another thread, and raises an event which your game program subscribes to, or your game manages its own polling loop. If it doesn't, a loop is still there, namely that of the OS.Morbidity
@stakx, of course there is always a loop behind the scenes. Is that the actual point of the question? Anyway, my point is that games don't have to explicitly maintain such a loop always.Lilley
D: "Is that the actual point of the question?" Only the OP could tell. Depending on what platform or framework he is programming against, it might be necessary for him to provide a main loop, or such a one might already be in the framework. I don't know whether or not he is aware of the fact that there always is, as it must be, a main event loop somewhere.Morbidity
H
4

It's because current operating systems aren't fully event based. Even though things are often represented as events, you'll still have to create a loop where you wait for the next event and process it indefinitely (as an example the Windows event loop). Unix signals are probably the closest thing you get to events on an OS level, but they're not really efficient enough for things like this.

Hovey answered 2/4, 2010 at 8:17 Comment(0)
G
4

In practical terms, as other people have indicated, a loop is needed.

However, your idea is theoretically sound. You don't need a loop. You need event-based operations.

At a simple level, you can conceptualize the CPU to have a several timers;

  • one fires on the rising edge of 60Hz and calls the blitting code.
  • Another might be ticking at 60kHz and be rendering the latest updates of the objects in the game world to the blitter buffer.
  • Another might be ticking at 10kHz and be taking input from the user. (pretty high resolution, lol)
  • Another might be the game 'heartbeat' and ticks at 60MHz; AI and physics might operate at heartbeat time.

Of course these timers can be tuned.

Practically, what would be happening is your would be (somewhat elided) like this:

void int_handler1();
//...
int main() 
{ 
  //install interrupt handlers
  //configure settings
  while(1);
}
Geometric answered 2/4, 2010 at 20:51 Comment(2)
+1 Yep, you can do it that way. The thing is, what happens when one of these happens to be running when the timer for another one goes off? It gets messy! You need logic to make sure nothing misses its turn. Unless you somehow synchronize the timers so it doesn't happen, tricky to do. Easily accomplished with one loop, driven by one timer, which explicitly gives each component an appropriate amount of attention per timer tick. Which is the motivation for using the loop, which is what the OP seemed to be asking about.Begum
Oh, I'm not saying that this is the most wonderful approach. I'm just pointing out that it could be done in an event-based fashion. Of course implementing true events is fairly tricky and generates the entire class of problems associated with real-time operating systems as compared with non-real-time. :)Geometric
E
3

The nature of games is that they're typically simulations, and are not just reacting based on external events but on internal processes as well. You could represent these internal processes by recurring events instead of polling, but they're practically equivalent:

schedule(updateEvent, 33ms)

function updateEvent:
    for monster in game:
        monster.update()
    render()

vs:

while 1:
    for monster in game:
        monster.update()
    wait(33ms)
    render()

Interestingly, pyglet implements the event-based method instead of the more traditional loop. And while this works well a lot of the time, sometimes it causes performance problems or unpredictable behaviour caused by the clock resolution, vsync, etc. The loop is more predictable and easier to understand (unless you come from an exclusively web programming background, perhaps).

Eudemonism answered 3/4, 2010 at 15:3 Comment(0)
S
2

Any program that can just sit there indefinitely and respond to user's input needs some kind of loop. Otherwise it will just reach the end of program and will exit.

Simpleton answered 2/4, 2010 at 9:47 Comment(0)
B
2

The main loop calls the event listener. If you are lucky enough to have an event-driven operating system or window manager, the event loop resides there. Otherwise, you write a main loop to mediate the "impedance mismatch" between an system-call interfaces that is based on I/O, poll, or select, and a traditional event-driven application.

P.S. Since you tagged your question with functional-programming, you might want to check out Functional Reactive Programming, which does a great job connecting high-level abstractions to low-level, event-based implementations.

Bumpy answered 2/4, 2010 at 10:48 Comment(0)
O
2

A game needs to run in real-time, so it works best if it is running on one CPU/core continuously. An event-driven application will typically yield the CPU to another thread when there is no event in the queue. There may be a considerable wait before the CPU switches back to your process. In a game, this would mean brief stalls and jittery animation.

Oddson answered 2/4, 2010 at 19:55 Comment(0)
N
1

Two reasons -

Even event driven systems usually need a loop of some kind that reads events from a queue of some kind and dispatches them to a handler so you end up with an event loop in windows for example anyway and might was well extend it.

For the purposes of animation you'd need to handle some kind of even for every frame of the animation. You could certainly do this with a timer or some kind of idle event, but you'd probably end up creating those in some kind of loop anyway so it's just easier to use the loop directly.

I've seen systems that do handle it all using events, they have a frame listener that listens to an event dispatched at the start of each frame. They still have a tiny game loop internally but it does little more than handle windowing system events, and create frame events,

Nicholle answered 2/4, 2010 at 8:24 Comment(0)
L
0

There are many benefits of making a strict and deterministic game loop such as better glitch recreation. Another one is your game is more likely to become a speedrun game (if you designed it to be competitive). Many gamers rely on their muscle memory so deterministic output is important for strategy. Also using TAS (Tool Asisted Speedrun) becomes easier since the program outputs the same thing when given the same inputs.

Lancashire answered 11/12, 2023 at 19:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.