The BLS folds video game designers into its broader "multimedia artists and animators" category, and the newest numbers there are worth sitting with. Median pay was $99,800 in May 2024, with projected job growth of just 2 percent through 2034, slower than the average for nearly every white-collar occupation the agency tracks. About 5,000 openings a year, mostly from people leaving the field rather than new roles being created. That tells you something about game dev hiring in 2026: the roles that do open are competitive, and studios lean on the interview loop to filter hard, not to check a box.
Most "game developer interview questions" lists online are a paragraph on Unity versus Unreal bolted onto generic LeetCode. That's not what actually separates candidates in a real loop. What separates them is whether they can explain why a fixed timestep keeps physics from breaking on a slow frame, or why a garbage collection spike in C# shows up as a hitch every few seconds instead of a smooth 60fps. Below are 45 questions organized around four things studios actually probe: math and physics, engine and language internals, rendering and performance, and gameplay architecture.
One honest caveat. Engine-specific depth varies a lot by studio size. A 12-person indie team hiring a generalist Unity programmer won't ask half of what a 200-person Unreal studio asks a rendering engineer. I don't have clean data on exactly how that split breaks down by team size, only that it's real, and it's worth asking your recruiter about directly before you over-prep the wrong half of this list.
Game math and physics questions
These show up at a mobile puzzle studio and at a AAA shooter team alike, because every genre needs movement, collision, and some notion of time that doesn't fall apart under a dropped frame.
Easy questions
15Delta time is the elapsed time between the previous frame and the current one. Multiply velocity by delta time (position += velocity * deltaTime) and movement stays consistent whether the game runs at 30fps, 60fps, or 144fps. Skip it and your character sprints on a fast machine and crawls on a slow one, which is exactly the bug that shows up in code review right before a demo.
Dot product tells you how aligned two vectors are, and its sign tells you whether something is in front of or behind another object, which is how you gate an AI's field-of-view check. Cross product gives you a vector perpendicular to both inputs, which is how you compute a surface normal or figure out which side of a line a point falls on. Mixing these up is a common tell that someone memorized formulas without using them.
Dynamic bodies respond to forces, gravity, and collisions automatically, think projectiles or ragdolls. Kinematic bodies are moved by script and affect other objects on contact, but nothing pushes them back, which is exactly what you want for a player controller or a moving platform that shouldn't get knocked around by the physics it's supposed to carry.
Unity's C# scripting and asset store ecosystem make it fast to prototype and strong for 2D, mobile, and indie titles. Unreal's C++ core and Blueprint visual scripting layer, plus built-in Lumen lighting and Nanite geometry, make it the default for AAA 3D titles that need high fidelity and mature multiplayer tooling out of the box. Team size and existing skillset matter as much as the technical fit. A small team full of C# developers will ship faster in Unity even if Unreal's renderer is objectively stronger.
Awake runs once when the object is created, before any Start call, and is where you set up references to other components. Start runs once, after all Awake calls have completed, which matters if one object needs to reference another that was just instantiated. Update runs every rendered frame and is where input and most gameplay logic lives. FixedUpdate runs on a fixed timestep independent of frame rate, which is why physics and Rigidbody manipulation belong there instead of Update.
Structs are value types, copied on assignment and passed to methods by value unless you explicitly pass by reference. Classes are reference types, so assignment copies a reference, not the underlying data. The gotcha that trips people up in interviews: modifying a struct stored inside a List<T> through a foreach loop doesn't change the original, because you're modifying a copy. Structs also avoid heap allocation, which matters for GC pressure in hot paths.
A draw call is a CPU command telling the GPU to render a batch of geometry, and each one carries fixed overhead regardless of how small the object is. Batching objects that share a material, using texture atlases so multiple objects can share one texture bind, and GPU instancing for repeated identical meshes (a forest of the same tree model) all cut draw call count without changing what's on screen.
Frustum culling skips rendering anything outside the camera's view volume, which is cheap and purely geometric. Occlusion culling goes further and skips objects that are inside the frustum but hidden behind something else, a wall, a mountain, which requires more work to determine but pays off heavily in dense scenes where most of what's "visible" by frustum alone is actually blocked from view.
A shader is a small program that runs on the GPU, most commonly a vertex shader that transforms geometry and a fragment shader that computes final pixel color. You reach for a custom one when the built-in shader graph or standard material can't express what you need: a stylized toon outline, a specific post-processing effect, or an optimization where a generic shader is doing more work than your specific use case requires.
Represent behaviors (Idle, Patrol, Chase, Attack) as distinct states, each with its own enter, update, and exit logic, and define the conditions that trigger transitions between them. A switch statement over an enum works fine for simple cases. A dedicated state object per behavior scales better once each state grows its own logic, since it keeps the transition conditions and the per-state behavior from turning into one giant unreadable function.
public enum EnemyState { Idle, Patrol, Chase, Attack }
void UpdateAI()
{
switch (currentState)
{
case EnemyState.Idle:
if (CanSeePlayer()) currentState = EnemyState.Chase;
break;
case EnemyState.Chase:
MoveTowardPlayer();
if (InAttackRange()) currentState = EnemyState.Attack;
else if (!CanSeePlayer()) currentState = EnemyState.Patrol;
break;
case EnemyState.Attack:
PerformAttack();
if (!InAttackRange()) currentState = EnemyState.Chase;
break;
}
}Linearly interpolating toward the target position each frame smooths out sudden movement, but naive Lerp alone can feel laggy or overshoot depending on frame rate if you're not careful with the interpolation factor.
void LateUpdate()
{
Vector3 desiredPosition = target.position + offset;
Vector3 smoothed = Vector3.Lerp(transform.position, desiredPosition, dampening * Time.deltaTime);
transform.position = smoothed;
}More advanced camera rigs add a dead zone (the camera doesn't move until the target leaves a small box), velocity-based look-ahead, and spring-damper systems for a more physical feel. The technique you pick matters far less to interviewers than whether you can explain why teleporting the camera to the target every frame feels wrong in the first place.
A blend tree takes multiple animation clips and blends between them based on one or more continuous parameters, like speed or direction, instead of snapping from one clip to another. A 1D blend tree for locomotion might blend idle, walk, and run based on a speed float, so at 2.3 m/s you get a weighted mix of walk and run rather than a hard cut. A 2D blend tree adds a second axis, commonly used for directional movement where forward, backward, strafe-left, and strafe-right clips blend based on an X/Y input vector.
The problem it solves is popping. Switching clips the instant speed crosses a threshold produces a visible snap in pose and timing every time that threshold is crossed, and it gets worse the more clips you add. Blending smooths that transition and lets you cover a continuous range of speeds with a small set of clips (idle, walk, run, sprint) instead of authoring a separate clip for every speed bucket.
The catch is synchronization. If the walk and run clips aren't phase-matched, meaning foot strikes don't line up at the same normalized time, blending between them makes feet slide or cross unnaturally. Most tools let you mark sync markers or normalize clip length so footfalls line up before weights get mixed, and you still often need additive layers on top for things like aim offsets or lean that a locomotion blend tree alone can't express.
Input buffering means the game remembers a player's button press for a short window, often 100 to 200ms, even if the current animation or state can't consume it yet, and applies it the moment the game becomes able to. Without buffering, a jump pressed two frames before landing gets dropped entirely, forcing the player to time a re-press exactly on the landing frame, which reads as unresponsive even though the timing was only off by a trivial margin.
Fighting games and platformers depend on this because animation-driven states have committed windows, like a landing recovery or attack recovery, where raw input can't be acted on immediately. A buffer queues the last few inputs with timestamps, and when the state machine transitions into an accepting state, it checks the buffer first before falling back to live input. Related is coyote time, giving the player a few frames after leaving a ledge where a jump input still counts, covering the gap between visually still on the platform and physically already falling.
The tuning tradeoff is buffer length versus feel. Too short and it doesn't cover normal human timing variance. Too long and inputs meant for a different action get consumed unintentionally, like a buffered attack firing right after a dodge the player didn't mean to chain into. Most teams land somewhere around 3 to 8 frames at 60fps and tune it per action rather than using one global window.
In a CPU particle system, the main thread or a worker thread updates each particle's position, velocity, color, and lifetime every frame, then uploads the results to the GPU for rendering. That gives full access to gameplay data, so particles can raycast against the world, read game state, or trigger events like a spark that applies damage on contact. The cost is that CPU particle counts are limited, usually into the low thousands before the update loop starts eating into frame budget.
GPU-simulated particles run the simulation in a compute shader, so tens or hundreds of thousands of particles update and render without the CPU doing more than issuing the dispatch. That's what you want for weather, explosions with heavy fill, or environmental effects where particles don't need to make gameplay decisions. The tradeoff is that reading data back from the GPU to check collisions or affect gameplay is expensive and usually a frame or more delayed, so GPU particles typically get simplified collision against a depth buffer or a low-res distance field instead of real physics queries.
In practice most games use both. Gameplay-critical effects that need to know what they hit stay on CPU or a hybrid setup, while pure visual density like rain or debris clouds goes on the GPU system where volume matters more than individual particle behavior.
Middleware separates sound design from code so a sound designer can build the audio behavior, like layering, randomization, ducking, and mix routing, in a visual tool and hook it up to a single event name a programmer calls once, such as PlayEvent(Footstep_Grass). Internally that event can pick from a randomized pool of variations, adjust pitch and volume based on velocity, route through reverb zones, and duck the music bus, all without another line of code once the initial hook exists.
The bigger win is iteration speed. Without middleware, changing how a footstep sounds usually means a code change or reimporting assets and rebuilding. With Wwise or FMOD, sound designers iterate live against a running build, tune parameters, and ship updated sound banks without touching code or doing a full rebuild, which matters on a project where audio content changes daily during a polish pass.
Middleware also handles profiling and memory concerns specific to audio, like streaming versus in-memory playback per platform, voice limiting when 40 explosions go off at once, and per-platform loudness and format handling, none of which teams want to hand-roll per project.
Medium questions
27Quaternions represent 3D rotation with four components (x, y, z, w) and avoid gimbal lock, the situation where two rotation axes align and you lose a degree of freedom. Euler angles are easier to read in an inspector panel, but they break down under compound rotations, which is why engines store rotation as a quaternion internally and only expose Euler angles as a display convenience.
The follow-up worth practicing: explain SLERP (spherical linear interpolation) for smoothly blending between two rotations, versus naive linear interpolation, which distorts rotation speed near the endpoints.
Axis-aligned bounding boxes are cheap and great for UI hit-testing or coarse broad-phase checks, but they get sloppy for rotated objects. Sphere collision is the fastest distance check available and works well for anything roughly round, projectiles, explosion radii, but it's a poor fit for long thin objects. Oriented bounding boxes handle rotation correctly at higher cost, using the separating axis theorem to test for overlap. Most engines run AABB first as a cheap rejection test, then fall back to a precise test only for pairs that pass.
Raycast from the AI to the target and check whether anything on the obstacle layer blocks the ray. The naive version, running this every frame for every enemy, is the part that costs you. Filter to the relevant collision layer only, cache the result for a few frames instead of re-checking constantly, and stagger checks across enemies so they're not all firing rays on the same frame.
Integrate velocity and position each fixed step: apply gravity to vertical velocity, then move the projectile by velocity times delta time. Air resistance, if you bother modeling it, subtracts a force proportional to velocity squared, which is usually overkill for gameplay feel and gets approximated instead.
void FixedUpdate()
{
velocity.y += gravity * Time.fixedDeltaTime;
velocity *= (1f - dragCoefficient * Time.fixedDeltaTime);
transform.position += velocity * Time.fixedDeltaTime;
}Interviewers usually follow up by asking you to predict landing position for an AI aim assist, which just means solving the same integration in reverse to find time-to-impact.
Quadtrees divide 2D space recursively and suit top-down or mostly-flat games. Octrees do the same in 3D and fit open-world or flight games with real vertical variation. Spatial hashing (bucketing objects into a uniform grid by position) is simpler to implement and often faster in practice for evenly distributed objects, though it wastes memory on sparse regions. All three exist to avoid the O(n squared) cost of checking every object against every other object.
Frame rate isn't constant, but physics needs a constant step size to stay deterministic and stable. Running physics at, say, a fixed 50Hz regardless of render frame rate keeps collision response consistent whether the game is rendering at 30fps or 144fps, and it's what makes replays and networked physics reproducible. The render loop then interpolates between the last two physics states to display something smooth in between fixed steps.
Broad-phase quickly rules out pairs of objects that obviously can't be colliding, using cheap bounding volumes and spatial partitioning to cut an O(n squared) problem down to a small candidate list. Narrow-phase then runs precise geometry tests, like the separating axis theorem for convex shapes, only on the pairs that survived broad-phase. Skipping straight to narrow-phase on every pair is the mistake that tanks frame rate in scenes with hundreds of objects.
In ECS, entities are just IDs, components hold data (Position, Health, Renderer), and systems contain the logic that operates on entities matching a component signature. Separating data from behavior lets you pack components in memory contiguously, which is far more cache-friendly than object-oriented GameObjects scattered across the heap. Unity built its Data-Oriented Technology Stack around this specifically to hit large entity counts, thousands of units in an RTS, without the per-object overhead of MonoBehaviours.
Every allocation you make in a hot path, a new list, a boxed struct, a closure capturing a variable, adds pressure that eventually triggers a GC pass, and that pass shows up as a visible hitch on the frame it runs. Object pooling avoids repeated instantiation. Caching arrays instead of allocating new ones every frame helps. Avoiding LINQ in Update loops helps more than people expect, since many LINQ operations allocate enumerators internally.
Pre-allocate a fixed number of objects up front, hand them out on request, and return them to an inactive pool instead of destroying them. It's worth the extra code for anything spawned and destroyed at high frequency: bullets, particle effects, enemy waves. For something instantiated a handful of times per level, plain instantiation is simpler and the complexity isn't worth it.
public class ObjectPool<T> where T : Component
{
private readonly Queue<T> pool = new Queue<T>();
private readonly T prefab;
public ObjectPool(T prefab, int initialSize)
{
this.prefab = prefab;
for (int i = 0; i < initialSize; i++)
{
T obj = GameObject.Instantiate(prefab);
obj.gameObject.SetActive(false);
pool.Enqueue(obj);
}
}
public T Get()
{
T obj = pool.Count > 0 ? pool.Dequeue() : GameObject.Instantiate(prefab);
obj.gameObject.SetActive(true);
return obj;
}
public void Release(T obj)
{
obj.gameObject.SetActive(false);
pool.Enqueue(obj);
}
}UPROPERTY hooks a C++ member variable into Unreal's reflection system, which is how the engine exposes it to the Blueprint editor, the details panel, and its own garbage collector. Without it, a UObject pointer stored as a plain C++ member is invisible to Unreal's garbage collector and can get freed out from under you. Treat it as load-bearing for memory safety, not a cosmetic editor convenience.
Blueprint is fast to iterate on and lets designers tune gameplay without recompiling, which makes it a good fit for UI logic, level-specific triggers, and rapid prototyping. C++ is faster at runtime and better for anything performance-sensitive or reused across many actors, core gameplay systems, AI logic, networked code. Most shipped Unreal titles land on a hybrid: C++ base classes exposing tunable properties, with Blueprint subclasses handling the specific tuning and simple event wiring.
TSharedPtr is Unreal's reference-counted smart pointer for non-UObject C++ types, similar in spirit to std::shared_ptr. The object is freed automatically once the last TSharedPtr referencing it goes out of scope. The bug it prevents is the classic manual delete, use-after-free, or double-free that plagues raw pointer management. TWeakPtr holds a non-owning reference and breaks reference cycles: two objects holding TSharedPtrs to each other would otherwise sit at refcount 1 forever and never get freed.
TSharedPtr<FInventoryItem> Item = MakeShared<FInventoryItem>();
TWeakPtr<FInventoryItem> WeakRef = Item;
if (TSharedPtr<FInventoryItem> Locked = WeakRef.Pin())
{
// Safe to use Locked here; it's null if Item was already freed.
Locked->Use();
}ScriptableObjects hold data independent of any scene instance, which makes them a clean way to store shared configuration, weapon stats, enemy archetypes, item definitions, without duplicating that data across every prefab that uses it. Designers can tune values by editing an asset instead of touching code, and multiple systems can reference the same ScriptableObject without coupling to a specific GameObject in the scene.
Vertex processing transforms vertex positions from model space through world, view, and projection space. Primitive assembly groups vertices into triangles. Rasterization converts those triangles into pixel fragments. Fragment (or pixel) processing runs lighting and texture calculations per fragment. Per-pixel operations like depth testing and blending decide what actually makes it to the screen. Knowing the order matters because it explains why, say, alpha blending has to happen after depth testing against opaque geometry.
Pre-author two or three mesh and texture quality tiers per asset, then switch between them based on distance from camera or projected screen size. The "doesn't pop visibly" part is the actual question. Cross-fading between LOD levels over a short window, or switching at a distance where the change is small enough on screen to go unnoticed, both work better than a hard cut that's obvious the moment it happens.
DXT (or BC) formats are standard on PC and most consoles. PVRTC targets iOS hardware specifically. ETC covers Android's baseline GPU support. ASTC is newer and works across modern mobile and desktop GPUs with better quality-to-size ratios. Picking wrong means either bloated build size or textures that silently decompress to an unsupported fallback format at load time, which is a bug you really don't want to find during certification.
Drop the render resolution drastically. If frame time barely changes, you're CPU-bound, since resolution mostly affects GPU fragment work. If frame time drops a lot, you're GPU-bound. From there, a profiler breaks down where CPU time goes (game logic, physics, rendering submission) or where GPU time goes (vertex, fragment, post-processing), which points you at the actual bottleneck instead of guessing.
Overdraw happens when the GPU shades the same pixel multiple times in one frame, common with stacked transparent particle effects or overlapping UI. Each of those shading passes costs fragment shader time even though only the top layer is visible. Mobile GPUs have far less fragment throughput than desktop, so overdraw that's invisible in the editor on a fast PC becomes an obvious frame drop on a mid-range phone. Most engines have an overdraw visualization mode in their profiler specifically to catch this before it ships.
Unity Profiler and Unreal Insights both give you a timeline of CPU and GPU work per frame, good for answering "where is time going across the whole frame." RenderDoc captures a single frame in detail and lets you step through every draw call, inspect every texture and buffer bound at each stage, which is what you actually need to debug a specific rendering artifact rather than a general slowdown. Interviewers ask this to check you know the difference between profiling for speed and debugging for correctness.
Mobile forces lower polygon counts, aggressive texture compression, and tight thermal budgets since a phone throttles under sustained load in a way a console with active cooling doesn't. Console targets fixed, known hardware, so you optimize for one specific configuration rather than a range. PC has to support scalable settings across wildly different GPUs, which means building quality tiers into the pipeline from day one rather than bolting them on later. VR adds its own constraint on top: dropping below roughly 90fps risks real motion sickness for the player, a much higher price than a rough-looking frame on a flat screen.
A* uses a heuristic (usually straight-line or Manhattan distance to the goal) to guide the search toward the target faster than Dijkstra, which explores uniformly in all directions and guarantees the shortest path but does more work to find it. In practice A* wins almost every time in games because you already know where the goal is. Dijkstra still earns its keep when you need shortest paths from one point to everywhere, like precomputing distances across a whole level.
Publishers raise events, subscribers listen, and neither side needs a direct reference to the other, which is what keeps a health system from needing to know about the UI, the audio system, and the achievement tracker all at once. Where it goes wrong is debuggability: a bug that's "this event fired but nothing happened" is much harder to trace than a direct function call, especially once a project has fifty different event types and no consistent naming convention.
Pick a format based on your actual constraints. Binary is fast and compact but hard to debug by hand. JSON or XML is readable and easy to patch but larger and slower to parse. Beyond format, the real design problems are save versioning (what happens when you add a new field and load an old save file) and corruption handling (what happens when the write gets interrupted mid-save). Studios that skip versioning early almost always regret it the first time they ship a content patch.
The client should never be trusted as the source of truth for anything that matters. Server authority means the server, not the client, decides whether a hit landed, whether a player moved a legal distance, and whether an item was actually picked up. Sanity checks on the server (did this player's position change faster than the max movement speed allows) catch a lot of naive cheats. Beyond that, encrypted communication and dedicated anti-cheat systems that watch for memory tampering handle the more sophisticated attacks that server-side validation alone won't stop.
A slot holds a reference to an item definition plus a quantity, and the inventory itself is a fixed-size or dynamic collection of slots. Making the slot generic over item type (a C# generic class or a C++ template) lets you reuse the same stacking, swapping, and validation logic for weapons, consumables, and crafting materials instead of writing three near-identical systems. The harder part interviewers probe is stack splitting and merging logic when a player drags a partial stack, which is where most naive implementations have off-by-one bugs.
Build a damage-info structure carrying amount, damage type, source, and any active modifiers, rather than passing a raw float around. That structure lets you layer in resistances (fire resistance multiplies fire-type damage by some factor), critical hit multipliers, and damage-over-time application without touching the core combat loop every time a new mechanic gets added. Routing damage through an event, rather than calling TakeDamage directly, also lets UI, achievements, and analytics all react to the same hit without the damage system knowing any of them exist.
Hard questions
10Verlet integration computes the next position from the current and previous positions plus acceleration, without explicitly tracking velocity: x_new = 2 * x - x_old + acceleration * dt^2. It's more numerically stable for constraint-based systems like cloth or rope simulation, because velocity falls out naturally from position history instead of accumulating separately. Euler integration is simpler and cheaper per step, but it drifts and can blow up under stiff constraints, which is why rope and cloth demos almost always use some Verlet variant underneath.
32-bit floats lose precision fast as coordinates grow, which shows up as jittering objects or physics glitches far from the world origin. The common fix is a floating origin: periodically re-center the world so the camera or player sits near (0,0,0), shifting everything else relative to that. Some engines instead switch to double-precision world coordinates and only convert to single precision for rendering, which sidesteps the problem at a memory and bandwidth cost.
Every object of a class with virtual functions carries a hidden vptr pointing to a vtable, a static array of function pointers. Calling a virtual function means dereferencing that pointer and looking up the function, which adds one indirection and a possible cache miss versus a direct call. In a tight loop iterating thousands of entities per frame, that indirection adds up, which is part of why data-oriented and ECS designs avoid virtual dispatch on hot paths in favor of flat data and free functions.
Unreal replicates properties declared with the Replicated specifier automatically from server to clients, with RPCs (remote procedure calls) for one-off events, and it's deeply integrated into the actor lifecycle. Unity's Netcode for GameObjects uses NetworkVariables and RPCs with a similar shape, but it's a newer, more modular package layered on top of GameObjects rather than baked into the engine core the way Unreal's replication graph is. Interviewers mostly want to hear that you understand server authority either way, the client shouldn't be the source of truth for anything that affects other players.
Forward rendering calculates lighting for each object as it's drawn, which gets expensive fast as light count grows since every light touches every object in its range. Deferred rendering splits the work: first pass writes geometry data (position, normal, albedo) into a G-buffer, second pass applies lighting in screen space using that buffer, so lighting cost scales with screen pixels and light count, not with object count times light count. The cost is memory bandwidth for the G-buffer and real difficulty handling transparency, which is why most deferred renderers fall back to a forward pass just for transparent objects.
Client-side prediction lets the local player move immediately based on their own input, without waiting for a server round trip, then reconciles with the server's authoritative state once it arrives, correcting position if the client's prediction was wrong. Interpolation between the last two received server states smooths remote players' movement instead of them snapping between positions. Lag compensation on the server, rewinding hit detection to the state the shooter actually saw, is what makes shooting a moving target feel fair despite the round trip.
A finite state machine works fine until the number of states and transitions grows past a certain point, and a six-phase boss with conditional attack selection inside each phase is usually past that point. Behavior trees compose small reusable nodes (selectors, sequences, conditions) into a tree that's easier to extend without the transition table turning into spaghetti. The honest trade-off: behavior trees take longer to set up for something simple, and I'd argue plenty of teams reach for one when a well-organized FSM would have shipped just as well and faster.
Perlin noise generates a smooth, pseudo-random gradient field by defining a grid of random gradient vectors and interpolating between them at each sample point, producing continuous values instead of the harsh discontinuities of naive per-pixel randomness. For terrain, you sample the noise function at each point of a heightmap grid using world-space coordinates, and the output maps to height. A single octave gives rolling, blob-like terrain. Stacking multiple octaves at increasing frequency and decreasing amplitude, called fractal Brownian motion, adds large landmasses from the low-frequency octaves and rocky small-scale detail from the high-frequency ones layered on top.
Simplex noise, Ken Perlin's later improvement, fixes two specific problems: it scales to higher dimensions with far fewer sample evaluations per point, and it avoids the subtle grid-aligned directional bias that classic Perlin noise shows along the X and Z axes.
The artifacts that actually bite in production are grid-aligned ridges or valleys lining up suspiciously with world axes if you're using classic Perlin without rotation, tiling seams at chunk boundaries if you're sampling from a bounded lookup table instead of a truly continuous function, and repetition at scale, since noise is deterministic and a large open world sampling the same octave frequencies will produce visually similar hill shapes far apart unless you vary the seed per region or add domain warping, offsetting the sample coordinates by another noise function, to break up the regularity.
In lockstep, every client runs the full simulation, and instead of sending state, clients send only inputs to each other, agreeing to advance the simulation frame by frame only once every client has received every other client's input for that frame. Because all clients start from identical state and apply identical inputs in identical order, they end up in identical state, which is why RTS games with hundreds of units use it: sending 'unit 47 move to x,y' is dramatically cheaper than sending position and state for every unit every tick.
Client-server, by contrast, has one authoritative simulation on the server, and clients receive state snapshots or deltas while doing local prediction to hide latency. It tolerates a client falling behind or having a local bug, because the server's state is what counts. A buggy client just looks wrong to itself or gets corrected on the next update.
Desyncs in lockstep are miserable because there's no single correct copy of the game state, every client's local simulation is trusted equally. The moment one client's simulation produces a value even a single float's worth different from the others, often from an uninitialized variable, a hash map iteration order that differs across platforms, a floating-point operation that isn't bit-identical across CPU architectures or optimization levels, or a random number generator consumed in a different order, that difference compounds silently for possibly minutes before it manifests as something visibly wrong, like units standing in different places. Tracking it down means diffing full state snapshots between clients at fixed intervals and bisecting to find the first tick where they diverge, since the actual root cause is almost always earlier than where the divergence becomes visible.
A two-bone IK chain, thigh, shin, foot, takes a target position, usually a raycast hit point on the ground under where the animation's foot would normally be, and solves for the thigh and knee angles that place the foot exactly on that target while respecting a pole vector that constrains which direction the knee bends. The solve is trigonometric: given the fixed bone lengths and the distance from hip to target, you have a triangle with known side lengths, so the interior angles come straight out of the law of cosines, no iteration needed for a two-bone chain, unlike longer chains that need FABRIK or CCD.
In an engine this layers on top of the underlying animation. The base locomotion animation plays normally, a raycast per foot each frame finds the ground height under the animated foot position, and the IK solver adjusts hip height and per-foot position so both feet land on the actual ground instead of the flat plane the animation was authored against. You also blend in a body height offset so the character doesn't look like it's doing the splits on a steep slope, and you weight the IK blend down to zero during states like jumps or attacks where foot planting shouldn't apply.
Where it breaks visibly: fast terrain changes like stairs or a curb can cause foot sliding or snapping if the raycast height changes faster than the IK weight can blend, so most implementations smooth or clamp the height delta per frame. Steep slopes cause knee hyperextension or an awkward flip in knee direction if the target sits outside the reachable radius of thigh plus shin length, which needs clamping the target distance before solving. And if the ground raycast misses, say the foot is over a ledge or gap, you need a fallback, either extending a virtual ground plane or blending IK weight back to zero, or the foot stretches toward whatever the raycast happens to hit far below, producing a visibly broken leg.
One pattern shows up over and over in mock sessions run through LastRoundAI's game-developer track. Candidates nail the first answer on a physics or math question, then stumble the moment an interviewer ties the concept to a real engine constraint. A clean explanation of quaternions is common. Explaining why SLERP interpolation matters for a smooth camera blend at a fixed frame budget is rare, and it's usually the difference between a pass and a maybe.
LastRoundAI's Interview Copilot responds in under 200ms during a live call and covers 50+ languages, including C# and C++, so it can keep pace with an engine-specific follow-up instead of defaulting to a generic coding answer. The Concept Explainer feature gets used most on ECS architecture and deferred rendering, two topics candidates say they understand right up until someone asks them to draw the actual data flow on a whiteboard.
Figure out which quarter of this list actually applies to your interview. A Unity mobile studio and an Unreal AAA rendering team are testing almost different jobs. LastRoundAI's free tier gives you 15 credits a month, reset every month, enough for a couple of full mock sessions across these sections before you'd need the $19/month Starter plan. Both the desktop app and the web app run the same mock sessions; there's no separate native mobile app yet, so plan to prep at a desk rather than on your phone.
For the DSA fundamentals that show up alongside the physics and math questions above, the data structures interview questions guide covers the traversal and complexity questions in more depth. If your loop includes a dedicated system design round, the multiplayer and architecture questions here connect directly to the system design interview questions guide. And for the CS fundamentals overlap on a hybrid engineering role, the software developer interview questions guide is worth a pass too.
LastRoundAI listens to the call and suggests clear, structured answers to questions like the ones above, in real time and invisible on screen share.
LastRound data
What we see on our side
Of 1,393 LastRound sessions configured between January 2025 and July 2026, 8 enabled the coding round. Games interviews lean harder on live problem solving than most, so that number is worth sitting with before you decide talking practice is enough.
Frequently asked questions
What do game developer interviews test most?
Maths, performance and engine familiarity. Expect vectors, matrices and frame-budget reasoning, usually framed around something concrete that was running too slowly.
How much C++ is required?
For most engine and gameplay roles, a lot. Memory management, cache behaviour and avoiding allocations in the frame loop come up regularly.
Do they ask about specific engines?
Usually the one they use, but concepts transfer. Being able to explain a component system or a render pipeline in general terms often satisfies the question.
Is a portfolio or shipped game necessary?
It helps considerably. A small shipped project you can discuss technically tends to outweigh a longer list of unfinished ones.
How this list was built
Worth being straight about where these questions come from, because plenty of pages in this category are not. The set was compiled from a research pass across official documentation, vendor release notes, published engineering writing and public discussion of hiring processes, then cross-checked against the current version of each technology so nothing here describes behaviour that has since changed.
What that means in practice: these are the questions the material supports as reasonable and current for this role, not a transcript of any one company's loop. We have not sat in on your interview and we are not going to claim we have. Treat the list as well-sourced preparation rather than a leaked question bank, and expect your panel to phrase things their own way.
If you spot something out of date, tell us at contact@lastroundai.com and we will fix it.

