I have a fundamental #GameDev question that has been bugging me for ages.

I've tried developing my own games, but I always felt like I was missing something fundamental about #programming logic and everything I did felt "wrong" and inefficient.

Here goes.

At the most basic level, games run as endless loops, right? Every frame, something happens. The program goes through the same loop over and over again until something causes it to exit.

For example, in a simple Asteroids-like shoot-em-up, the game goes through the list of obstacles every frame and sets their position downward a bit. They therefore appear to be coming towards you over time.

But games are obviously complex and interactive, and therefore don't just do the same thing every frame. The game needs different things to happen each iteration of the loop, based on what's going on in the game.

For example, the Asteroids obstacle needs to be removed from the game once it exits the screen, or once it overlaps with the player.

The only way I know to check whether something happened is to add a conditional to the game loop. Every single frame, the game checks for every single obstacle whether its position is outside the boundaries, and if so, removes it.

A computer can't just "keep in mind" to watch for a certain event to make something happen, it needs to explicitly be reminded to check every frame.

Even if something is supposed to happen only every minute, you still need to count a number up every frame until you reach a minute's equivalent amount of frames, and then the counter gets reset to zero and the event happens.

I understand all this works.

But what I don't understand is the following:
This seems extremely wasteful and inefficient, right?

I understand that a computer can calculate and compare a bazillion things a second, and that this is perfectly fine for something as simple as Asteroids.

But what about more complex games?

  • Do Mario jump-and-run games genuinely check whether Mario touches the goal post every single frame of the game?
  • Does GTA V check every single frame whether the player is in a mission, and if so, which one they're in?
  • Do games like #Minecraft check every single frame, for every single animal, whether they're currently on fire?
  • Do games check every single frame whether they're paused, in a menu, or running?

If this is genuinely what's going on, how the hell do complex games even run? When I play Minecraft, does the computer really, 120 times a second, for every single animal in the world, check whether they're currently poisoned? And then also checks whether the game is paused, whether there is mouse input, whether it's raining, whether music is playing, whether a block state has changed, and so on and so on?!

What about something like #BindingOfIsaac? Does it really check every single frame for every one of the thousands of possible items and whether the player has them equipped?

I mean, I'm sure it's abstracted a bit in that the game adds an "event hook" or something whenever you pick up a new item, but underneath all that, surely the game still has to check every frame for every possible hook whether it is active or not?

If I finally understood the answer to this question, I'd understand way more about game development.

@lianna the answer is probably much longer than you question. 😀 But technically, yes. Everything needs to be check/updated every frame. Events, positions, physics, collisions,... However, there are tons of optimizations to quickly eliminate things that don't need checked.

Sometimes there is some preprocessing done when the game is built. For example, the OG Doom used binary space partitioning (bsp) trees precalculated as part of the game data. The game would walk the nodes in the tree with...

@lianna ...each node effectively eliminating half the level from being checked. It's not really used anymore but it's just one of the optimizations I understand 😀. Writing game engines is hard!

@lianna I'll take a shot at offering some intuition. Let's take Doom as an example. Every frame the game needs to render the weapon I currently have selected, and maybe it needs to shoot if I pressed Ctrl or switch weapons if I pressed a different number. So it needs to check input every frame, that's a given.

But the fact that Doom can *store* which weapon I currently have selected means that it doesn't have to check, each frame, "is the shotgun selected? if so render the shotgun. is the rocket launcher selected? if so render the rocket launcher", which seems to be what you're concerned about. It can just say "render the current weapon" and have a reference already prepared for what sprite actually needs to get drawn onto the screen to make that happen. That reference only needs to change if I press a number key to change weapons.

Similarly for your GTA V mission example I'd imagine that somewhere there's some "current mission" variable, and sure, maybe that variable needs to get checked every frame to determine whether to render some mission-related UI at all, but it doesn't need to get compared against every possible mission; it can just point at all the data for the current mission at once. Then the lookup to grab all that data only has to happen once, when the mission changes (and with good choice of data structures I wouldn't think that lookup has to be particularly expensive either).

@lianna The answers to your questions are generally not a simple yes or no answer, but I will try to give a very broad idea. On a very basic level: Yes, the game will check all the information per frame. If you start to write a simple game, that is a good way to get going and understand what's going on. BUT, in the specifics a lot is going on and it depends on many factors. A few examples:
@lianna A game would try to avoid checking collisions of every object with all others. For that reason, space is divided into distinct regions and other heuristics are used to avoid testing too many pairs. This also extends to something like "did we touch the goal". We could react to a collision with the goal based on the optimizations, no need to check every frame.
@lianna In something like Isaac, you would not check all cominations, but instead have a "bullet" or somilar abstraction that is composed of all current powerups. This structure knows how to fire tears and calculate damage based on its state.
So in general, it is a big mixture of: Test what is needed per frame, try to react to specific things detected, couple state with its own behaviour and also try to avoid computations as much as you can
@lianna Sorry for the multiple posts, but I would suggest: Don't worry too much about it in the beginning! Just follow some tutorials and gain experience, this will lead you do understanding. A bit of programming fundamentals are also helpful, as this will help you judge whether something is inefficient or if there are different ways to organize and operate on data

@lianna Yes it does all those check every frame. But not always the way you describe them. For example, in Binding of Isaac it wouldn't go

"Do I have item 1?"
"Do I have item 2?"
etc..

Instead it loops through a list of equipped items

"What Item is in slot 1? Do that effect"
"What Item is in slot 2? Do that effect"
"What Item is in slot 3? Do that effect"

Some older games do certain checks only periodically, not every frame. Like the famous Super Mario Framerule
https://www.youtube.com/watch?v=RV6Dtn4hgwg

The Biggest Lie in Mario Speedrunning

YouTube

@lianna Short answer: No, not everything has to be checked every frame. Longer answer: In general, only things that are contextually relevant need to be checked every frame, and the rest can be checked as needed. Typically the physics engine and input polling needs to run every frame, but Minecraft doesn't update the state of the entire world every frame, it updates a certain area around the player, and most of that area is static blocks that don't need much processing. Things like weather changes that only change occasionally can be put on a timer and only checked when the timer expires (the timer is updated every frame, but that's a cheap operation).

You already hinted at one optimization: Setting up event-driven callbacks for some things. Instead of testing for every eventuality every frame, you have infrequent occurrences generate an event or signal when they occur, and push them into a queue. Then your game can get by on checking whether the event queue has anything in it, and only processing when it does.

@lianna look for the "listener" concept, I think it's what you're missing
@lianna
This is a really good set of questions. Yes, games do check a lot of things every frame, but not as many as you might think. Games will keep dynamic lists (arrays) of things in memory that are active at that point in time, then check through each of those every frame. You may notice on older games, when more than a certain number of enemies are on screen at the same time, the game will slow down.

@lianna
Each of your questions might deserve its own answer.

In Super Mario Bros, The game level is a two dimensional array of block definitions and at any given frame, Mario is overlapping only a few of these blocks, so the game will look at each of those blocks only and if one of those happens to be a flagpole, then it will trigger the end of the level code

@lianna
There are a number of data structures and algorithms which allow the game to only have to check a few things each frame. For complex 3D games, there are structures called trees that make it so you can easily only check items in a certain area without looking at every item in the game.
A lot of Computer Science is just figuring out efficient data structures and algorithms to make computing more efficient.
@lianna
Any CS book on data structures and algorithms would provide a lot of tools for effectively processing data in efficient ways. A lot of games programming books will show how to adapt these algorithms directly in games. Reading game source code can be informative.
Short answer: dynamic arrays, tree structures, clever algorithms.

@lianna
So, let's start with the easiest things to answer:
- Yes, games check every single frame (or tick) whether they are paused, in a menu, or whatever - same goes for GTA and its missions. It is effectively one or two simple checks, which is beyond negligible compared to displaying all that stuff on the screen.
- Games like Minecraft check various things related to mobs (including whether they are on fire) every single simulation tick... but here is the trick - the entire world isn't simulated at once, only stuff within a certain radius of the player. Mobs are usually despawned outside that radius (or a slightly bigger one) if they aren't set to be persistent, like Minecraft dogs.
- TBoI, assuming it is coded in a sane way, mostly doesn't do anything that isn't related to the currently held items. That being said if you go overboard with a completely rigged game you can end up crashing the game - though usually it is less about overwhelming the PC, but more about some unexpected edge case interaction between these items.
- Mario is a complex thing to talk about, because if we are going to talk about old-ass NES hardware, things were way more complicated back then. Generally though the trick from the Minecraft is still used here - only process things that are in the simulation range, which in case of SMB1 is basically limited to a very tiny bit more than you see on your screen.
- Event hooks are a way to do the opposite of checking things each frame. You are basically making an object ask nicely another object that if something happens the first object will tell the second object to do something. And if there are multiple objects hooked? The first object will just tell each other object that registered the hook in order.

Feel free if you have more questions or if I might have explained something poorly - hard to go into understandable detail even with the 2k character limit