#7DRL Day 2 — What’s a Game Loop?

Brad M
3 min readMar 7, 2021

The plan yesterday was to create a few buildings, plunk them on the map, then move straight on to map generation. However, in the course of getting some things working, I ran into an issue — my main game loop was pretty raggedy.

Buildings worked correctly, generating and moving resources between themselves, but none of it would render on-screen the way I expected. This led me to do some research into game loops in my copy of Game Programming Patterns, and also to think about how order of operations plays into automation games.

What’s a Game Loop

I had a very naïve understanding that the speed of your in-game simulation shouldn’t be tied to the displayed frame rate of your game. This is what causes old DOS games to run at a billion frames per second, and that intrinsically made sense to me. However, that was about all I knew. At the start of the day yesterday, I had two separate methods running on disconnected setInterval() loops — one to update the simulation, update(), and one to update the screen, render().

I highly recommend you pick up a copy of Game Programming Patterns if you intend on doing any indie dev, but the web version is available for free. I decided to go with a simple fixed time step with synchronization, since there aren’t high requirements for frame rate or simulation rate in an automation-roguelite game.

It turned out not to solve my root problem, which had more to do with order of operations than the game loop itself. So, for today we’re going to leave it alone. If anything, I’m going to look into any Javascript libraries that will let me easily extract a game & render loop to plug my code into.

Order of Operations

A miner and conveyor belts from the game Factorio.

Picture a basic assembly line in any old Factorio/Satisfactory-type game. On one side, a miner pulling up iron. A loader arm moves the raw iron out of the miner’s inventory and places it on a conveyor belt, and the conveyor belt moves it a few squares to the east. If we were to run this system for a few seconds, we know generally what to expect.

As of now, however, the order in which the buildings get to act has an impact on the simulation. The problem I was seeing was that my conveyor belts were each taking their actions in the same order as the belt.

  1. We begin a single tick of the simulation…
  2. Belt 1 moves its inventory to Belt 2…
  3. Belt 2 moves its inventory to Belt 3…
  4. Belt 3 moves its inventory to Belt 4…
  5. …we end the simulation tick and render the results to the player.

This behavior means that instead of a resource moving one unit per turn, it zoomed through the entire belt line in one turn! Certainly efficient, but not necessarily good for gameplay.

Solution

I’d love to put this to bed and jump into some more roguelite-y things today, but without this, we don’t really have a simulation, much less a game. Here’s what we’re going to try today:

Ensure a fixed OoO always takes place. Buildings that generate resources first, then those that consume them, then loaders, then conveyor belts. Within a conveyor belt, ensure the last segment of the belt works first, and the first segment comes last.

If we do this backwards operation of a conveyor belt, we should get something closer to what we want:

  1. We begin a single tick of the simulation…
  2. Belt 4 has no inventory and does nothing
  3. Belt 3 has no inventory and does nothing
  4. Belt 2 has no inventory and does nothing
  5. Belt 1 moves its inventory to Belt 2
  6. …and we end the update() and render the results

This results in one resource moving one tile per tick, which is much more in-line with the simulation results we want.

Thanks

Thanks for reading! As a reminder, I’m working on this game for the next 6 days as part of 7DRL, the 7-day roguelike challenge. You can follow my progress on Twitter, where I’ll be sharing more thoughts about the process and a link to the project when it’s done!

--

--

Brad M

Software engineer, indie game dev, lifelong student.