Game Development
Introduction to Game Development
60 FPS is a 16.6 ms budget per frame. In those 16.6 ms the engine must process input, update physics for every object in the scene, recalculate AI, animations, LOD, frustum culling - and submit rendering commands. In an AAA game that means 10,000+ objects. Red Dead Redemption 2 renders one million grass objects in a single frame. Budget: 16.6 ms, non-negotiable. Welcome to game development.
- **Game loop (requestAnimationFrame)**: the same pattern in the browser - React Three Fiber, Three.js, WebGL visualizations; 60 FPS = 16.6 ms budget per frame
- **ECS in Unity DOTS and Overwatch**: Blizzard switched to ECS for 60 Hz server simulation with thousands of objects; Unity DOTS delivers x10-100 performance vs MonoBehaviour
- **LOD (Level of Detail) in AAA**: close-up character - 100K polygons, distant - 100; automatic switching by distance; Red Dead Redemption 2, Cyberpunk 2077
- **Procedural generation in Minecraft and No Man's Sky**: seed → deterministic world; the entire infinite Minecraft world is generated on the fly from a single number
Game Loop
60 FPS = 16.6 ms per frame. 30 FPS = 33 ms. This is not a preference - it is a hard budget. In every 16.6 ms the engine processes input, updates physics, AI, and animations, and draws the scene. Every game - from Pong to Cyberpunk - runs on one principle: the infinite **game loop**, beating like a heart.
The problem with a naive loop: on a powerful machine the ball moves faster than on a weak one, because update() is called more often. In 1999 Quake III Arena worked exactly that way - physics was tied to FPS. The fix: **fixed timestep** - physics updates at a fixed rate (60 Hz = 16.6 ms), rendering runs as fast as possible.
**Fixed timestep** guarantees determinism: the same input produces the same result on any hardware. This is critical for online games (lockstep networking), replay systems, and physics stability.
The alpha parameter in render(alpha) is **interpolation**: physics at 60 Hz, monitor at 144 Hz. Intermediate object positions are drawn between physics frames. The result: smooth visuals with stable physics. That is exactly how Cyberpunk 2077 looks smooth on a 144 Hz monitor without overclocking the physics simulator.
Why does a game loop use a fixed timestep?
Entity-Component-System
How is game code organized? Inheritance (Enemy extends Character extends GameObject) quickly becomes a nightmare: the diamond problem, rigidity, a hierarchy explosion. Blizzard ran into this in Overwatch - 40+ hero types, each with unique abilities. The solution: **Entity-Component-System (ECS)**, where data is separated from logic.
An **Entity** is simply an identifier (a number). A **Component** is a data container with no behavior: Position {x, y}, Health {current, max}, Sprite {texture, frame}. A **System** is a function that processes all entities with a specific set of components.
ECS advantages: **composition over inheritance** (any combination of components), **cache-friendly** (data stored in arrays, not scattered across the heap), **parallelism** (systems operating on different components can run in parallel).
ECS is used by Unity DOTS (x10-100 performance vs MonoBehaviour), Unreal Mass Entity, Bevy (Rust), and Flecs (C/C++). Overwatch (Blizzard) switched to ECS for 60 Hz server simulation with thousands of objects. Even in classic Unity, MonoBehaviour is already a component on a GameObject (entity) - partial ECS without the label.
In the ECS architecture, which part contains behavior logic?
Scene Management
A game consists of screens: main menu, game level, pause, shop, game over screen. Each of these is a **scene**. In an AAA game, a level transition means 2-5 GB of textures and models. Loading it all at once is impossible. The **scene manager** handles resource loading and unloading - that is its core job, not just transition animation.
Scenes come in two flavors: **stack-based** and **replacing**. A push scene (pause) overlays the previous one - when unpaused, the game resumes. A replace scene (menu → game transition) completely replaces the current one - the menu is unloaded from memory.
Loading resources (textures, sounds, models) is the slowest part of any transition. Common solutions: **loading screen** (async loading with a progress bar), **preloading** (load the next level during the current one), **pooling** (reuse objects instead of creating and destroying them).
The scene lifecycle: **onEnter()** - load resources and initialize, **update(dt)** + **render()** - main loop, **onPause()** / **onResume()** - when another scene is pushed or popped, **onExit()** - release resources. Skip onExit and get a memory leak. Cyberpunk 2077 at launch had exactly these leaks on PS4, causing crashes after a few hours.
How does a push scene differ from a replace scene?
Input Handling
Players interact with a game through input devices: keyboard, mouse, gamepad, touchscreen. The input system's job is to abstract specific devices into **actions**, so that game logic is independent of hardware.
There are three types of input events: **pressed** (button just pressed - one frame), **held** (button held down), **released** (button just released - one frame). Movement typically uses held, jumping uses pressed, and firing depends on the weapon type.
| Device | Input Type | Characteristics |
|---|---|---|
| Keyboard | Discrete (0/1) | Multiple simultaneous keys, no analog axes |
| Mouse | Position + buttons | Sub-pixel precision, delta movement, scroll wheel |
| Gamepad | Sticks + buttons + triggers | Analog axes (-1..1), dead zone, rumble |
| Touchscreen | Multi-touch + gestures | No hover, virtual buttons overlap the screen |
**Dead zone** - the area around the center of an analog stick where input is ignored. Without a dead zone, the character "drifts" due to stick imprecision. Typical value: 0.15–0.25 of the full deflection range.
Input is processed at the start of the game loop, before update(). All events for the frame are buffered and handled at once - physics receives a consistent snapshot. In competitive games (Valorant, CS2) input lag is measured in single frames: 1 frame @ 128 Hz server = 7.8 ms. That is exactly why pros play on 240 Hz monitors.
The full game loop picture: processInput() reads devices and maps to actions, update(dt) updates the world with a 16.6 ms fixed timestep, render() draws the result with interpolation. Three steps - the foundation of every game from Tetris to GTA VI. The 16.6 ms budget never goes away.
A game engine is the game itself
An engine is a tool (rendering, physics, input, audio). The game is the gameplay, design, content, narrative, and art built on top of the engine.
Fortnite and PUBG both run on Unreal Engine. Ori and the Blind Forest and Temple Run both run on Unity. The engine does not determine the genre or quality. Minecraft was built without an AAA engine (Java, later C++) and sold 238 million copies. Many of the most successful indie games use custom engines or Godot.
Why is input mapping necessary?
Key Takeaways
- **Game loop** - 16.6 ms per frame at 60 FPS: input → update (fixed timestep) → render; fixed timestep guarantees physics determinism on any hardware
- **ECS** separates Entity (ID) / Component (data) / System (logic); Unity DOTS and Overwatch use ECS for x10-100 performance vs inheritance
- **Scene manager** - scene stack: push (pause on top of the game) and replace (menu → level); onEnter/onExit lifecycle manages resource loading
- **Input mapping** abstracts devices into actions - one codebase works for keyboard, gamepad, and touchscreen
Related Topics
Game development fundamentals connect to many disciplines:
- Game Engines — Unity, Unreal, and Godot implement game loop, ECS, and scene management out of the box
- 2D Rendering — The render() function from the game loop is a discipline in itself: sprites, tilemaps, animations, parallax
Вопросы для размышления
- Why did ECS win out over inheritance in game development? React uses a similar architecture (stateless components + hooks). Is it the same idea?
- What happens without a fixed timestep: Quake III Arena tied physics to FPS, causing specific bugs on fast hardware. What exactly went wrong?
- 16.6 ms frame budget. LOD, frustum culling, draw call batching - rank these by the maximum gain they deliver in modern AAA games.
Связанные уроки
- cg-01 — Computer graphics is the foundation of rendering in games: transformation matrices, shaders, z-buffer
- alg-01-big-o — Algorithms are critical in game dev: collision detection, pathfinding (A*), spatial partitioning
- se-01 — Architectural patterns (Entity-Component-System, Observer, State Machine) are the same as in regular software development
- gd-02 — Understanding engines opens the path to game mechanics and physics
- la-06-transformations