AAA Interview Questions
Commonly asked questions are highlighted.
Gameplay Programmer
Builds and codes game mechanics (like movement, combat, AI) to make the game play well.
C++ and Language Fundamentals
What are the differences between pointers and references?
References are aliases to existing variables. They share the same address as existing variables. Cannot be null or reassigned after binding, and are automatically dereferenced.
Pointers are used for dynamic memory and optional ownership, while references are better for guaranteed access and ownership doesn’t change.
Use a reference for stack-allocated objects you don’t own, and a pointer for heap-allocated or optional objects you may manage or replace.
What are the storage specifiers in C++?
M.A.R.S.E.
- mutable: Allows modification of class members declared as const.
- auto: Compiler automatically infers the type.
- register: Hints compiler to store the variable in a CPU register if possible. (rarely used as modern compilers optimise automatically).
- static: In a function it retains value between function calls. In a class or outside a function, it makes the variable or method have a local scope.
- extern: Tells the compiler that the actual definition of the variable or function is elsewhere and it should link to it later during the linking phase. e.g. global values.
Each specifier controls the scope, lifetime, and visibility of variables. They allow programmers to manage memory usage, optimize performance, and handle variable accessibility efficiently.
What does mutable mean?
Use mutable for variables that logically don’t affect the object’s state but need to be changed in const methods, like caches or counters as they dont change the logical behaviour. Also can be used in lazy evaluation.
What is the rule of five in C++?
used when managing a classes resources, you need to explicitly define:
- Copy constructor: creates a new object as a copy of existing object
- Copy assignment operator: copies contents from one existing object to another existing object
- Move constructor: transfers resources from a temporary object to a new object
- Move assignment operator: transfers resources from a temporary object to an existing object
- Destructor: release resources and clean up when destroyed
This ensures safe copy/move semantics and prevents resource leaks or shallow copies.
What is the difference between Win32 and Win64?
Pointer size: 4 bytes on Win32 and 8 bytes on Win64.
Max addressable memory: ~4 GB on Win32 and 16EB (theoretical) on Win64
What is a template?
In C++, templates are a compile-time feature that allows you to write generic code that works with any data type or class type.
Templates are more flexible because they can be used for:
- Functions
- Classes
- Specializations (e.g., to change behavior for specific types)
Templates are resolved at compile time, meaning the code is generated for each type you use with the template.
C# does not have templates, but it provides generics, which give you similar functionality with compile-time type safety. They are limited to type parameters and some constraints.
What is the difference between C# and C++?
C++ has manual memory management using new, delete, pointers. Compiled to machine code. Good for systems-level programming.
C# has automatic garbage collection and compiles to an intermediate language.. Good for applications.
What are smart pointers and when would you use unique_ptr vs shared_ptr?
unique_ptr: sole ownership, cannot be copied. Use for strict ownership semantics.
shared_ptr: reference-counted shared ownership. Use when multiple owners are required.
Explain virtual functions and v-tables.
Virtual functions enable runtime polymorphism.
A v-table is a lookup table maintained per class that stores addresses of overridden functions.
When you call a virtual function on a base pointer, the call is dispatched through the v-table to the appropriate derived class’s function.
What’s the difference between a struct and a class in C++?
Technically identical except:
struct members are public by default.
class members are private by default.
Conventionally, use struct for plain data (PODs) and class for encapsulated logic or behavior.
What is the difference between Stack and Heap memory allocation?
Stack is for temporary, short-lived data such as local variables and function calls that exist only during that function’s execution.
Heap is for longer-lived, dynamically allocated data that needs to persist across multiple frames or have flexible lifetime and size.
Stack
- Managed automatically by the compiler.
- Fixed size, allocated at compile time (e.g., for auto variables).
- Fast allocation/deallocation (LIFO order).
- Limited size (typically a few MB).
- Used for local variables, function calls, and parameters.
- Memory freed when scope ends (e.g., function exits).
Heap:
- Managed manually (via new, delete) or by smart pointers.
- Dynamic size, allocated at runtime..
- Slower allocation/deallocation (due to memory management).
- Larger size (limited by system memory).
- Used for objects with unpredictable lifetime or large data.
- Memory persists until explicitly freed or program ends.
| Description | Stack | Heap |
| Lifetime | Memory Freed when scope ends | Memory persists until explicitly freed or program ends |
| Size | Limited size, allocated at compile time | Dynamic size, allocated in runtime |
| Managed | automatically | manually |
| Used | local variables, function calls, paramaters | large data, unpredictable liftetime |
| Speed | Fast allocation/deallocation | Slower allocation/deallocation |
What are common C++ data types and their typical sizes?
| Type | Description | Typical Size |
| char | Character or small integer | 1 byte |
| bool | Boolean value | 1 byte |
| short | Short integer | 2 bytes |
| int | Standard integer | 4 bytes |
| long | Long integer | 4 bytes |
| float | Single-precision float | 4 bytes |
| double | Double-precision float | 8 bytes |
| void* | Generic pointer | 8 bytes |
| Function ptr | Function address (like any ptr) | 8 bytes |
What are atomic operations?
This is crucial in multithreaded programming (like in Unreal or any C++ system) to prevent data races and corruption when multiple threads read/write the same variable.
Examples in Unreal:
FThreadSafeCounter, FThreadSafeBool
TAtomic
General Unreal
What are common Unreal C++ data types and their typical sizes?
| Type | Description | Typical Size |
| FName | Hashed name identifier | 12 bytes* |
| FString | Managed string (TArray<TCHAR>) | 16–24 bytes* |
| FText | Localizable text | ~24–32 bytes* |
| FVector | 3 float struct | 12 bytes |
| FTransform | Translation, Rotation, Scale Struct | 48 bytes |
Sizes marked with * (like FString, FName, etc.) are dependent on compiler padding and internal allocations.
What does Transient mean?
Definition: A Transient object or property is not serialized, meaning it:
- Won’t be saved to disk
- Won’t be loaded from disk
- Won’t persist between editor sessions
Common Use: Temporary runtime data like caches, temp states, or intermediate calculations.
What are 5 storage containers in Unreal?
- TArray: Dynamic. indexed by integers
- TMap: Key-value pair storage. Keys must be hashable.
- TSet: Unordered collection of unique items, unique elements
- TQueue: FIFO (First In, First Out). e.g. task scheduling
- TCircularQueue: Fixed-size circular buffer e.g. history tracking
Performance and Optimization
What is the Unreal Garbage Collector?
Unreal Engine’s GC is a memory management system that:
- Automatically tracks and frees unused UObjects.
- Prevents memory leaks by removing objects that are no longer referenced.
It is not C++ standard garbage collection — it only works with UObjects, not raw pointers or standard C++ objects.
You must use NewObject<> to create and UPROPERTY() to reference them.
How would you identify and fix a performance bottleneck in gameplay code?
Analyze call stacks, CPU time, memory usage.
Look for:
- Excessive Tick() usage
- Expensive allocations
- Unnecessary branching or locking
Optimize by:
- Avoiding allocations in critical paths
- Caching computations
- Using data-oriented structures
- Defer or batch work
How do you avoid memory fragmentation?
Avoid frequent small heap allocations. Use memory pools, arenas, or object pools for frequently allocated/deallocated objects.
Prefer stack or frame allocators for transient gameplay data.
Minimize dynamic allocations, especially in per-frame code.
Describe some different smart pointers in Unreal
TSharedPtr: Owns an object with shared ownership; deletes it when the last TSharedPtr or TSharedRef goes away; can be null.
TSharedRef: Like TSharedPtr but always non-null; guarantees a valid referenced object.
TWeakPtr: Non-owning reference to an object managed by TSharedPtr; can become null anytime; can be promoted temporarily to TSharedPtr for safe access.
TUniquePtr: Sole owner of an object; exclusive ownership with no sharing allowed; deletes the object when it goes out of scope; cannot be copied, only moved.
TStrongObjectPtr maintains a strong refernece to a UObject and stops it being garbage collected when in scope.
Multithreading and Concurrency
How would you ensure thread safety?
- Mutexes and locks for shared data
- Atomic variables for lightweight sync
- Task graphs or job systems (e.g., Unreal’s FAsyncTask, FGraphEventRef)
- Design strategies like read-copy-update, thread-local storage, and minimizing shared state.
Describe cache coherency and how it affects performance in games.
Use synchronization, atomic operations, and careful memory layout to maintain cache coherency and ensure correctness and performance in its multithreaded environment.
Poor spatial locality (scattered memory access) or false sharing (multiple threads writing to same cache line) breaks coherency.
Optimize by:
- Using SoA (Structure of Arrays) over AoS (Array of Structures)
- Aligning data to cache lines
- Avoiding shared writes in multithreaded code
How would you handle gameplay code that needs to update in both the main and worker threads?
Separate data and logic: worker threads compute; main thread applies.
Use double buffering or command queues to marshal data between threads safely.
Schedule deterministic points (e.g., Tick) where changes can be applied atomically.
Ensure thread-safe APIs and use synchronization barriers when merging results.
Math and 3D Programming
Explain how quaternions work and why they are preferred over Euler angles.
Quaternions represent rotation as a 4D unit vector (x, y, z, w) with no gimbal lock.
Efficient for smooth interpolation (slerp) and composition.
Avoid cumulative drift and discontinuities present in Euler angles.
How would you interpolate between two transforms?
Use a combination of:
- LERP for translation (FMath::Lerp)
- SLERP for rotation (Unreal: FQuat::Slerp)
- LERP or blend for scale
Apply all three to construct a smooth blended transform.
What is a transform matrix?
| R11 R12 R13 Tx | ← Rotation + Translation (X)
| R21 R22 R23 Ty | ← Rotation + Translation (Y)
| R31 R32 R33 Tz | ← Rotation + Translation (Z)
| 0 0 0 1 | ← Homogeneous coordinate row
Top-left 3×3 = Rotation and Scale
Rightmost column (Tx, Ty, Tz) = Translation (position)
Bottom row = Required for matrix math to work in 3D with homogeneous coordinates.
How would you perform a raycast in 3D space?
Define ray: origin O and direction D (normalized).
Check for intersections with geometry using:
- Bounding volumes (AABB, Sphere)
- Mesh triangles (Möller–Trumbore algorithm)
Use engine API (e.g., LineTraceSingleByChannel() in Unreal) for optimized collision.
What is a matrix?
A matrix is a 2D grid of numbers.
Unreal’s FMatrix is 4×4 and often used for 3d transform.
FMatrix::M[RowIndex][ColumnIndex]
Operations:
- Addition / Subtraction
- Multiplication (by scalar or another matrix)
- Transpose (flipping rows and columns)
- Determinant (used for matrix inversion and solving equations)
- Inverse (used to reverse transformations)
- Transform vectors (common in 3D graphics)
Apply all three to construct a smooth blended transform.
What does gimbal lock mean?
Technical Artist
Bridges art and code by creating tools, writing shaders, and optimizing visuals to make the game look and run well.
General
How do you balance visual quality with performance?
Establish visual benchmarks early (target polycount, texture sizes, shader complexity).
Use:
- LODs (Level of Detail) for meshes and materials.
- Texture streaming and compression.
- Shader variants (fallbacks for lower-end devices).
- Texture atlases
- Baked lighting
Profile regularly using tools (e.g., Unreal’s GPU Profiler or Unity Profiler).
Collaborate with art and engineering to find creative compromises that retain impact while cutting cost.
Describe a time you had to bridge communication between departments.
Example1:
Artists exported characters with naming errors that broke the animation pipeline.
Wrote a Python tool for Maya that:
- Validated naming conventions.
- Warned about hierarchy and pivot issues.
- Automatically exported clean FBX files.
Shaders & Materials
What is the difference between Deferred and Forward Rendering?
Deferred Rendering:
- Geometry is drawn first, storing data like normals, albedo, and depth in G-Buffers.
- Lighting is calculated in a separate pass using G-Buffer data.
- Pros: Efficient with many lights, better for dynamic lighting.
- Cons: Poor transparency support, higher memory usage.
Forward Rendering:
- Lighting is calculated per object during drawing.
- Pros: Better for transparent objects, lower memory usage.
- Cons: Performance drops with many lights.
Deferred Rendering is the default in Unreal Engine and is optimised for high-end visuals and dynamic lighting. Forward rendering could be useful for mobile or VR.
What is overdraw, and how do you detect/fix it?
Overdraw = multiple transparent pixels drawn on top of each other (alpha blending).
Detected using:
- Unreal: Shader Complexity view or Overdraw view.
- Unity: Scene View > Overdraw.
Solutions:
- Minimize transparent layers.
- Use dithered alpha or masked blending when possible.
- Optimize UI layout and decal usage.
Explain the PBR workflow and commonly used maps.
PBR (Physically-Based Rendering) simulates real-world material responses to light.
Common maps include:
- Albedo (base color without lighting).
- Metallic (0 = dielectric, 1 = metal).
- Roughness (surface smoothness).
- Normal map (adds surface detail without geometry).
- AO (Ambient Occlusion) (self-shadowing).
Ensures consistency across lighting environments.
How would you create a stylized water shader?
Key elements:
- Scrolling normal maps for fake movement.
- Vertex displacement for ripples and waves.
- Depth-based color blending (deep = dark blue, shallow = light teal).
- Fresnel effect for edge highlights.
Optional: Use masking or noise textures for foam effects near shorelines.
Tools & Pipeline
Describe a tool you built for artists.
- Validated names and hierarchy.
- Ensured correct export settings.
- Exported to FBX with correct scale/pivot.
- Resulted in fewer in-engine errors and faster exports.
What tools do you use to build pipelines from DCC to engine?
DCC: Maya, Blender, Houdini.
Scripts in:
- Python (Maya, Blender).
- MEL for older Maya tasks.
- Unreal Python/Blueprint Tools or Unity Editor scripts.
Can include:
- Auto FBX exports.
- Animation bake-down tools.
- Batch renaming/naming validation.
When should you use Nvidia Nsight?
- GPU Performance Profiling
- Advanced CUDA/Compute Debugging
- GPU Trace and Timeline Analysis
- Overdraw and Performance Analysis
- Nvidia-Specific Hardware Features
- Debugging at the Kernel Level
How would you validate a rig before it’s exported?
- Skeleton structure matches naming template.
- No rogue scale transforms.
- Max joint count within engine limits.
- Skin weights are normalized and clean.
Automated via Maya scripts or Unreal’s Control Rig tools.
What tools have you used to profile and debug performance in Unreal Engine?
- Unreal Insights – primary tool for CPU/GPU profiling and frame analysis.
- Stat Commands – (stat unit, stat fps, etc.) for quick in-game metrics.
- GPU Visualizer (profilegpu) – visual breakdown of GPU rendering cost.
- RenderDoc – frame capture and analysis at the GPU level (great for draw calls, overdraw).
- Intel GPA / Nvidia Nsight – deep GPU profiling, especially for platform-specific optimization.
- Visual Logger – for tracking gameplay data like AI movement and events over time.
When should you use Renderdoc?
- Frame-Level Debugging
- Draw Call and Shader Debugging
- Overdraw and Performance Analysis
- Cross-Platform GPU Debugging
Scripting & Automation
What scripting languages have you used and for what?
Python: Primary language for pipeline tools (naming, exporting, rig cleanup).
MEL: For legacy Maya automation.
C#: Used in Unity for editor tooling and runtime debugging.
HLSL/GLSL: For custom shader development.
Blueprints: For prototyping logic inside Unreal Engine.
How would you clean up a scene via script?
Remove unused nodes, materials, and constraints.
Fix naming with regex or predefined rules.
Freeze transforms and delete history.
Optionally, reparent or organize into export groups.
Example of automating a repetitive task:
Script:
- Removed construction history.
- Applied transforms.
- Exported with scene-based naming.
- Packaged into folders.
Saved days of work over project lifetime.
Graphics
What is the difference between UAV (Unordered Access View) and SRV (Shader Resource View)
SRV is read-only, typically used for textures and buffers accessed by shaders without modification. E.g. Texture for texture sampling.
What are the different types of graphics passes, and what are their purposes?
- Geometry Pass: Collects data from the scene (e.g., geometry, normals, albedo, depth) and stores it in G-buffers for later use in lighting and post-processing.
- Lighting Pass: Computes the lighting based on the data stored in the G-buffers, including calculating light contributions from multiple light sources.
- Shadow Pass: Renders shadow maps from the perspective of light sources to determine areas affected by shadows.
- Post-Processing Pass: Applies visual effects to the final image (e.g., bloom, tone mapping, depth of field, color grading).
- Final Pass (Render Pass): Combines all previous passes into the final output image, often involving anti-aliasing, blending, and the final screen-space output.
Optimization & Performance
How do you profile GPU/material performance?
Unreal: GPU Profiler, Material Complexity view.
Unity: Frame Debugger, GPU Usage breakdown.
Check:
- Shader instruction count.
- Texture sampling complexity.
- Overdraw and blend modes.
Use Material Instances instead of unique shaders for performance.
How would you fix texture streaming issues?
Confirm mipmaps are generated.
Adjust engine’s streaming pool size.
Use LOD bias or forced mip levels if needed.
Check UV scaling to ensure textures aren’t too low-res on large meshes.
What are draw calls and how do you reduce them?
Fewer draw calls = better performance.
Techniques to reduce:
- Batching (static/dynamic).
- Instancing (for repeated assets).
- Texture atlases (combine multiple textures).
- Merging small meshes into one where appropriate.
How do you create and manage LODs?
Tools: Maya LOD groups, Blender decimate modifier, Simplygon.
Naming: Use consistent suffixes (e.g., _LOD0, _LOD1).
Import as LOD groups in Unreal/Unity.
Test in-engine for pop-in and visual quality loss.
Rigging & Animation
How would you rig a character for facial animation?
Combine with joints for jaw, eyelids, and lips (if real-time performance matters).
Support with:
- Pose space deformers.
- Driven keys or animation curves.
Validate in-engine with facial capture or baked animation.
Describe a modular rigging system you’ve created.
- Each module = leg, spine, arm, face, etc.
- Script auto-connects parts into one rig.
- GUI interface for toggling features (e.g., FK/IK switches).
Scales to multiple characters easily.
How would you debug a character that doesn’t retarget animations correctly?
- Bone hierarchy and naming.
- A-pose or T-pose consistency.
- Retargeting settings in Unreal (IK Retargeter or Retarget Manager).
In Unity, inspect Avatar setup and Humanoid mapping.
Look for scale issues or flipped joints.
Animation Programmer
Core Technical Questions
What is the difference between forward kinematics and inverse kinematics?
Inverse Kinematics (IK) works backward from a desired end position (e.g., a hand touching a surface) to compute the necessary joint rotations.
FK is often used for working with spines and arms.
IK is ideal for gameplay interactions like foot placement or hand alignment when you know the exact rotation and orientation.
| Feature | FK | IK |
| Control flow | Parent->Child | End effector -> solver -> joints |
| Foot placement | Difficult | Easy and precise |
| Best use | Arms, spine, Expressive animations | Legs, feet, grounded interaction |
| Common In | Keyframe Animation | Real-time foot IK, procedural animations |
How would you optimize an animation system for memory and CPU usage?
Stream animations instead of loading all into memory.
Only evaluate bones required for rendering (LOD-based skeleton masking).
Avoid updating animations for off-screen or far-away characters.
Reuse common animation sets via retargeting.
Explain how root motion works and how it interacts with gameplay logic.
It can be extracted and applied to the character controller to preserve animation-authored movement.
Syncing with gameplay is tricky — you need to balance authorial control with in-game responsiveness (e.g., interrupting a roll to dodge).
Common approach: use root motion for special cases (e.g., melee attacks), and in-place motion with procedural control for general movement.
What is control rig?
- Controls; Drive bone chains.
- Bones; Extra bones for specific rigging behaviour such as IK-chain or dummy bones.
- Nulls; Containers to collect, group and transform other rig elements.
What is an animation slot?
Allow you to insert one-off animations into the anim graph at specific areas.
How would you implement a foot IK system for uneven terrain?
- Perform a downward raycast from each foot to find ground contact points.
- Adjust the foot bone position and orientation to align with the surface normal.
- Blend the IK offsets with the original animation using a smooth curve.
- Adjust the pelvis position to prevent stretching.
- Optionally apply a spring-damper filter to smooth motion across frames.
What are animation state machines, and when are they not enough?
Use blend trees or rule-based systems (e.g., motion matching, behavior trees) when:
- Transition conditions get too complex.
- You need responsiveness beyond discrete states.
- Animation sets are large and data-driven (e.g., 500+ mocap clips).
What is retargeting?
Allows for sharing animations between characters that use different Skeleton assets (as long as they share a similar Bone Hierarchy) and use a shared asset called a Rig to pass animation data from one Skeleton to the other.
Only the bone’s translation is retargeted. The bone’s rotation always comes from the animation data.
How does retargeting work?
Animations are bound to a skeleton asset. A skeleton asset is a list of bone names, hierarchy data and initial proportions from the original skeletal mesh.
Retargeting Modes:
- Animation – Bone Translation comes from the animation data, unchanged.
Example: Root Bone, IK Bones, weapon bones - Skeleton – Bone Translation comes from the Target Skeleton’s bind pose.
Example: all other bones - AnimationScaled – Bone translation comes from the animation data, but is scaled by the Skeleton’s proportions. This is the ratio between the bone length of the Target Skeleton (the skeleton the animation is being played on), and the Source Skeleton (the skeleton the animation was authored for).
Example: pelvis so it sits at the right height
What is the difference between Root, Joint, Bone, Effector and Sockets?
- Root: The top-level transform that controls the entire skeleton’s position and rotation.
- Joint: A pivot point where bones connect and rotate.
- Bone: A virtual segment between joints that deforms the mesh.
- Effector: A target point used in inverse kinematics to position limbs.
- Socket: Named attachment point on a bone.
What is a solver?
A solver is an algorithm that automatically calculates the positions and rotations of joints to satisfy a specific goal or constraint — like placing a hand on a wall or keeping a foot on the ground.
| Solve Type | Description | Example Use |
| Two-Bone IK | Solves a 3-joint chain (e.g. hip -> Knee -> ankle) | Leg/arm placement |
| FABRIK | Forward And Backward Reaching. Iteratively positions joints to reach the effector using forward-backward passes | More natural, stretchy limbs |
| CCD IK | Cyclic Coordinate Descent. Rotate joints incrementally to reach the goal | Lightweight, fast real-time IK |
| Full-body IK | Solves across the entire skeleton, preserving body balance, and constraints. | Motion matching, VR, procedural posing |
Advanced/Behavioral Questions
Describe a system you built or helped optimize for animation in a past project.
When I joined Different Tales they were still in preproduction so had cut a lot of corners. They had a gigantic animation graph with logic-dependent abilities, locomotion and more. There was a lot of branching for different characters. I build an animation catalogue and querying tool so that montages could be looked up and ran on specific slots. This freed a lot of memory from the animation blueprint. Also introduced animation LODS.
How do you debug animation issues in a large codebase?
Log and inspect state transitions, blend weights, and input parameters.
Isolate animation graph inputs from gameplay code.
Use assertions and validation for bone hierarchy consistency and missing assets.
What are the challenges of integrating animation systems with physics?
Solution: Use ragdoll only when needed, or blend procedural animation with constraints (e.g., spring bones or joint limits).
Keep tight synchronization between physics and animation update steps (fixed vs variable timestep issues).
Apply post-physics animation blending or animation-driven physics constraints to bridge gaps.
How do you ensure high performance for animation on consoles (e.g., PS5 or Xbox Series X)?
Batch animation updates using multi-threaded job systems.
Use sparse updates for LOD characters (e.g., update only every N frames).
Keep per-frame memory allocations minimal — use pool allocators.
Minimize cache misses by linearizing memory layout of bone transforms.
Gameplay Integration
How would you synchronize animation and gameplay events (e.g., attack hit frames)?
What’s the best way to interrupt and blend out of an animation (e.g., cancel an attack)?
How do you handle animation-driven movement in a multiplayer game?
What are the 3Cs?
- Character: How the player character moves (locomotion, transitions, responsiveness)
- Camera: How the camera follows or frames the character, camera smoothing, collision
- Controls: Inputs and their responsiveness, combo systems
Systems and Architecture
How would you design a modular animation system for NPCs with different skeletons?
How would you support additive animations (e.g., breathing, aiming)?
What is motion matching?
Full-body ik is helpful here as it redefines the selected pose to make it more physically correct.
Describe how you'd implement a runtime blend space.
Describe how you'd retarget animations for different skeletons
With a rig you can match up bones to the target. An automapping feature gets a best match on naming convention and bone position.
How Are End Effectors Handled With Retargeting
To address props you could create a separate chain of bones (hand ik bones) that follow the hands in the original animation and then retarget only the body and the arms and not the hand ik bones.
Having a separate chain of bones allows you to switch smoothly between FK and IK.
Math and Technical Depth
How do you interpolate between two quaternions?
How would you implement a look-at system for the head and eyes?
What’s a retargeting matrix and why is it needed?
Optimization and Tools
What are animation LODs and how do they work?
- Lowering keyframe resolution.
- Updating fewer bones.
- Switching to simplified animations or frozen poses.
Selection is based on screen size, distance, or performance metrics.
What challenges arise with animation compression, and how do you address them?
- Visual artifacts from aggressive keyframe reduction.
- Mismatched root motion deltas.
You address them with per-bone error thresholds, quaternion compression (e.g., fixed-point), and choosing the right codec (e.g., ACL in Unreal).
How would you profile animation CPU cost?
Collaboration & Pipeline
How do you support animators working in Maya or Blender with custom rig tools?
What’s your approach to debugging animation bugs reported by designers or QA?
Core AI Concepts
Explain the difference between Behavior Trees and Utility AI. When would you use one over the other?
Utility AI scores actions dynamically based on environmental and internal stimuli, enabling emergent behavior.
- Use BTs for clear, structured decisions (e.g., patrol → chase → attack).
- Use Utility AI when decisions must be fluid, like choosing between fleeing, healing, or attacking based on health, threat, and ammo.
How do you avoid decision thrashing in Utility AI?
- Add hysteresis (threshold buffer before switching).
- Use cooldowns or inertia scores to delay frequent changes.
- Apply blending or smoothing functions (e.g., exponential decay) to inputs.
What is hierarchical planning and how is it used in games?
Used to manage complexity and allow reusability (e.g., “Attack Enemy” → “Equip Weapon” → “Chase” → “Attack”).
What is GOAP and how does it differ from traditional BTs or FSMs?
It differs by being goal-driven, rather than following a hardcoded decision path like BTs or FSMs.
Useful in sandbox or simulation-heavy games (e.g., AI villagers or survival NPCs).
What are the trade-offs between Utility AI, FSMs, and GOAP?
- FSMs: Fast, easy to implement, but scale poorly.
- Utility AI: Adaptive and dynamic, but hard to debug and tune.
- GOAP: Highly flexible and goal-driven, but expensive and harder to implement.
Use Utility or GOAP when behavior needs to be emergent or priority-based; use FSMs for tight, deterministic control.
How do you design an AI system for sandbox gameplay (e.g., emergent NPC behavior)?
- Use event-driven architecture or GOAP.
- Implement needs-based decision systems (e.g., hunger, safety).
- Define affordances in the environment.
- Drive actions through agent memory, perception, and social graphs.
Explain the difference between polling and event-driven systems in AI.
- Polling: AI constantly checks conditions (e.g., “is player visible?”).
- Event-driven: AI reacts to events (e.g., “player spotted” → pushed into queue).
Event-driven systems are usually more performant and responsive in large-scale simulations.
Navigation Systems
How would you handle dynamic obstacle avoidance for multiple AI agents in UE5?
- Use Dynamic Nav Mesh Updates with bDynamicObstacle enabled on moving actors.
- Use Navigation Modifiers for non-static updates (e.g., falling platforms).
- For crowd agents, use MassAI plugin or Detour Crowd Manager.
- Implement Reciprocal Velocity Obstacles (RVO) or Flow Field AI for large groups.
What is the difference between AIController::MoveTo and using a NavMeshPath directly?
Using NavMeshPath gives finer control:
- Manually query UNavigationSystemV1::FindPathToLocationSynchronously
- Update or prune paths dynamically
- Integrate with crowd systems or avoidant steering.
Unreal AI Integration
How would you set up a custom pathfinding solution in Unreal Engine that extends or replaces A*?
- Subclass UNavigationQueryFilter or implement a custom NavData type.
- Modify or override the ANavigationData::FindPath or extend FRecastQueryFilter for heuristics.
- Use ProjectPointToNavigation, FindPathToLocationSynchronously, or FPathFindingQuery with your new filter.
- Optionally, plug into the EQS system for higher-level decision integration.
Explain how NavAreas and NavFilters work.
NavFilters can be applied to pathfinding requests to include/exclude NavAreas or adjust traversal cost.
You define filters in C++ or Blueprint and assign them via AIController or movement commands.
Describe how a blackboard system works.
Helps decouple decision-making from data gathering.
Advanced AI Architectures
How would you design a scalable AI architecture for 200+ agents in a UE5 open-world game?
- Use State Trees (UE5) for CPU-efficient logic.
- Leverage Zone-based LOD AI — only full AI tick when near the player.
- Defer planning logic to Gameplay Tasks or Async Tasks.
- Use MassEntity (ECS) for logic batching and scalable agent handling.
- Offload high-cost logic like GOAP planning to a central planner or use blackboard-driven event models.
How do you design an extensible AI system?
- Favor data-driven design: behaviors defined in JSON, XML, or ECS data.
- Use component-based architecture: behavior modules (e.g., PerceptionComponent, TaskComponent).
- Avoid deep inheritance — use composition.
What are affordances in AI, and how would you implement them in Unreal?
In Unreal:
- Annotate actors with gameplay tags or custom interfaces.
- Query world affordances via line-of-sight, sphere overlaps, or EQS.
- Have agents interpret these affordances based on internal needs (e.g., low health → search for cover).
How would you design a sensory system for an NPC?
- Separate vision, hearing, and other senses into modular components.
- Use raycasting, spatial queries, or sound event broadcast.
- Integrate with blackboard or memory system to inform decision-making.
- Include memory decay and stimulus confidence levels.
Debugging & Optimization
How do you debug complex AI behavior in Unreal?
- Use AIDebugger (press apostrophe) to view perception, movement, BTs, and blackboards.
- Log with UE_LOG or use Gameplay Debugger categories.
- Use Profiler for tick costs and NavMesh Visualizer to inspect paths and agents.
- Integrate Editor Utility Widgets for live agent inspection in large simulations.
A designer says an NPC isn’t reacting correctly. How do you debug this?
- Reproduce the scenario in a debug environment.
- Inspect decision history (e.g., logs, visual tools).
- Check sensory input — is the AI perceiving correctly?
- Validate decision logic and cooldowns.
- Use logging, breakpoints, or visual debuggers (e.g., custom behaviour visualizers).
How do you optimize AI behavior in large-scale environments?
- Tick throttling via SetActorTickInterval, PrimaryActorTick.bCanEverTick = false.
- Use Level Streaming and AI LODs.
- Replace full BT/GOAP with simpler FSMs for distant agents.
- Reduce sensory frequency (AIPerceptionComponent::SetSensingInterval).
- Offload utility scoring or EQS queries to async jobs or frame budget scheduling.