Game Dev
By the end of this lesson you'll understand the heartbeat of every game — the input/update/render loop — and why movement must be scaled by delta time . You'll write a fixed-timestep loop, a small 2D vector struct, and a tiny entity-component world, all as plain console simulations you can run right here.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Think of a game like an animated flip-book . Each page is a frame . To draw the next page you do three things in order: glance at what the player pressed ( input ), nudge every character a little ( update ), then ink the page ( render ). Flip the pages fast enough and still images become motion. The catch: if one artist flips pages twice as fast as another, the characters would race ahead — unless each nudge is sized by how much time the page took . That time-per-page is delta time , and multiplying movement by it is what keeps the game running the same on a slow laptop and a fast desktop.
1. The Game Loop & Delta Time
A game loop is a loop that runs over and over while the game is alive. Each pass — a frame — does three jobs in the same order: input (what did the player press?), update (move everything forward a little), and render (draw it). Because there is no graphics window here, "render" just prints to the console — but the structure is exactly what Unreal and every other engine uses. Read this worked example and run it.
The single most important habit in game code: multiply movement by delta time . delta time ( dt ) is the number of seconds the last frame took. If you instead move by a flat amount per frame, a faster computer renders more frames per second and everything sprints ahead. position += speed * dt turns "pixels per frame" into "pixels per second" so the game behaves identically everywhere. Run this and watch two very different frame rates land on the same answer.
Your turn. The program below makes a falling object accelerate under gravity. Fill in the two blanks marked ___ using the // 👉 hints, then run it and check your output against the expected lines.
2. Fixed Timestep for Stable Physics
Delta time keeps movement consistent, but raw dt wobbles frame to frame — and wobbly physics means jumps and collisions that behave slightly differently every time. The fix is a fixed timestep : always advance the physics by the same step (commonly 1.0 / 60.0 seconds). An accumulator banks each frame's real time and you run as many fixed steps as fit. A long, stuttery frame simply runs more steps to catch up, so the simulation never drifts.
3. A Tiny 2D Vector Struct
Almost everything in a 2D game is an (x, y) pair: a position, a velocity, a direction. Bundling those two numbers into a small Vec2 struct — with + to add and * to scale — makes movement read like the maths you'd write on paper: pos = pos + velocity * dt . The length() (magnitude) of a velocity vector is the object's speed.
4. Entities & the Entity-Component Pattern
An entity is "a thing in the world" — a hero, a slime, a coin. Rather than one enormous class that does everything, the entity-component pattern gives each entity a bag of small components (Position, Velocity, Health), and writes systems — plain functions — that loop over every entity and act on the data they care about. One movement system moves all entities; one render system draws them all. It keeps data together and lets you build behaviour by mixing components instead of deep inheritance.
Now you try. Finish the update step of a side-scrolling ship's game loop — the only blank is the delta-time scaling you learned in Section 1:
Real engines separate how often physics updates from how often the screen draws . Physics runs on the fixed timestep (say 60 updates a second); rendering runs as fast as the monitor refreshes. When the two don't line up, you interpolate : draw the object a fraction alpha of the way between its last and next physics positions, so motion looks buttery even if physics ticked slightly before the frame was drawn.
All four are C++ at heart. The loop you wrote above is the same one they run — they just replace cout with drawing a sprite to a window.
No blanks this time — just a brief and an outline to keep you on track. Build a game loop where a ball climbs, hits a ceiling, and falls back down by flipping its velocity. Run it and check your output against the example in the comments.
Practice quiz
What three jobs does a game loop do every frame, in order?
- render, update, input
- update, render, sleep
- input, update, render
- load, save, draw
Answer: input, update, render. Each frame reads input, updates the world a little, then renders (draws) it.
What is delta time (dt)?
- The number of seconds that passed since the last frame
- The total time the game has run
- The frame rate in frames per second
- A fixed constant of 1/60
Answer: The number of seconds that passed since the last frame. dt is the seconds elapsed since the previous frame; multiplying movement by it makes it frame-rate independent.
Why do you write position += speed * dt instead of position += speed?
- It uses less memory
- dt makes the object move faster
- speed alone causes a compile error
- It turns 'pixels per frame' into 'pixels per second' so movement is identical on any frame rate
Answer: It turns 'pixels per frame' into 'pixels per second' so movement is identical on any frame rate. Scaling by dt makes movement time-based, so a fast PC and a slow PC reach the same position.
What is a fixed timestep used for?
- Drawing the screen as fast as possible
- Advancing the physics by the same step every time for consistent, repeatable physics
- Limiting the game to 30 FPS
- Skipping input on slow frames
Answer: Advancing the physics by the same step every time for consistent, repeatable physics. A fixed timestep updates physics with a constant dt (e.g. 1/60 s), so jumps and collisions behave the same on any hardware.
What role does the accumulator play in a fixed-timestep loop?
- It banks each frame's real time so you can run as many fixed steps as fit
- It counts the total score
- It stores the player's position
- It measures the frame rate
Answer: It banks each frame's real time so you can run as many fixed steps as fit. The accumulator banks leftover time; a long frame simply runs more fixed steps to catch up, so nothing drifts.
What does double dt = 1 / 60; produce, and why?
- 0.016667, the correct value
- A compile error
- 0, because 1 / 60 is integer division
- 60, the frame rate
Answer: 0, because 1 / 60 is integer division. 1 / 60 is integer division yielding 0; write 1.0 / 60.0 so the maths is done in double.
For a Vec2 velocity of (3, 4), what does length() return?
- 7
- 5
- 12
- 3.5
Answer: 5. length() is sqrt(3*3 + 4*4) = sqrt(25) = 5 — the classic 3-4-5 triangle.
In the entity-component pattern, what is a 'system'?
- A single giant Player class
- The operating system
- A type of component
- A function that loops over every entity and acts on the data (components) it needs
Answer: A function that loops over every entity and acts on the data (components) it needs. Systems are plain functions (like a movement or render system) that operate on every entity holding the right components.
What is the 'spiral of death' in a fixed-timestep loop?
- When the player loses all lives
- When each fixed step takes longer than STEP real seconds, so the accumulator never drains and the game freezes
- When dt becomes negative
- When the game runs too fast
Answer: When each fixed step takes longer than STEP real seconds, so the accumulator never drains and the game freezes. If steps can't keep up, the while loop never drains the accumulator; cap the steps per frame or clamp the frame time.
Which library is recommended as the gentlest starting point for a beginner?
- Unreal Engine
- SDL2 only
- raylib or SFML
- Vulkan
Answer: raylib or SFML. raylib and SFML have small APIs that get a window and shapes on screen fast; learn the loop first, then grow into bigger tools.