System Design
Designing gameplay systems in Unreal Engine — inventory, combat, abilities, quests, save/load, multiplayer, and large-project structure.
17 questions
JuniorTheoryVery commonWhat is the actor-component model and why prefer composition?
What is the actor-component model and why prefer composition?
An AActor is a container that gains behavior from attached UActorComponents — health, inventory, and movement each live in their own component. Composition lets unrelated actors reuse a component instead of inheriting one giant base class.
Common mistakes
- ✗Putting every feature in one bloated base class instead of separate components
- ✗Confusing a UActorComponent with a child AActor — components are much lighter
- ✗Thinking composition means duplicating logic rather than reusing one component
Follow-up questions
- →When would you still use inheritance instead of a component?
- →How do components communicate with their owning actor?
JuniorTheoryVery commonWhat is game state management and where does state live?
What is game state management and where does state live?
State management decides which object owns each piece of data. In Unreal, match-wide state goes on AGameState, per-player persistent data on APlayerState, transient input on the PlayerController, and the pawn holds only its physical world state.
Common mistakes
- ✗Storing persistent data on the Pawn, which is destroyed on death and respawn
- ✗Using global variables instead of giving each value a clear owning class
- ✗Confusing per-player state (PlayerState) with match-wide state (GameState)
Follow-up questions
- →Why should score live on PlayerState rather than the Pawn?
- →What is the difference between PlayerState and PlayerController state?
SeniorDesignVery commonDesign a Diablo-style action-RPG combat system in Unreal Engine for online co-op. Players have many abilities with cooldowns, costs, and per-level scaling; enemies have health, resistances, and crit interactions; and designers must tune every number — ability damage, resistances, scaling curves — without a programmer recompiling the game. Damage must flow through a single mitigation pipeline so crits, elemental resistances, and damage-over-time compose consistently. The session is multiplayer, so health, kills, and damage must be resolved authoritatively on the server and must not be forgeable by a client, while combat still has to feel responsive (hits and damage numbers should appear without waiting on a round-trip). Describe how abilities, stats, and the damage pipeline are structured, where authority lives, and the trade-offs of your approach.
Design a Diablo-style action-RPG combat system in Unreal Engine for online co-op. Players have many abilities with cooldowns, costs, and per-level scaling; enemies have health, resistances, and crit interactions; and designers must tune every number — ability damage, resistances, scaling curves — without a programmer recompiling the game. Damage must flow through a single mitigation pipeline so crits, elemental resistances, and damage-over-time compose consistently. The session is multiplayer, so health, kills, and damage must be resolved authoritatively on the server and must not be forgeable by a client, while combat still has to feel responsive (hits and damage numbers should appear without waiting on a round-trip). Describe how abilities, stats, and the damage pipeline are structured, where authority lives, and the trade-offs of your approach.
Drive everything server-authoritatively: abilities as data-driven objects, a stat component for health, and a damage pipeline applying FDamageEvent through mitigation. The server resolves hits and death; clients only predict cosmetics.
Common mistakes
- ✗Trusting client-reported damage or health, which opens the game to trivial cheating
- ✗Hard-coding ability numbers in C++ instead of exposing them in data for designers
- ✗Applying damage in client overlap events instead of resolving hits on the server
Follow-up questions
- →How would you make damage numbers feel responsive despite server-authoritative resolution?
- →How would you structure crit, elemental resistances, and damage-over-time in the pipeline?
JuniorTheoryCommonHow do you design data-driven items using DataAssets and DataTables in Unreal?
How do you design data-driven items using DataAssets and DataTables in Unreal?
Define each item once as data, not code. Use a DataAsset for complex items with nested data and asset references, a DataTable for many flat rows edited in bulk. Gameplay references the definition; instances store only mutable state.
Common mistakes
- ✗Thinking a
DataAssetrequires C++ subclassing per item the way a code class would - ✗Using a
DataTablefor items with nested structs and asset references where aDataAssetfits better - ✗Copying the full definition into each instance instead of referencing one shared asset
Follow-up questions
- →When would you choose a
PrimaryDataAssetand the Asset Manager over a plainDataAsset? - →How do you keep item icons and meshes from loading until an item is actually used?
MiddleDesignCommonDesign a general interaction system for a multiplayer Unreal Engine game with many kinds of interactable objects — doors, pickups, levers, triggers — and more types added over the project's life. The player should be able to focus the object they are looking at, see a context prompt for it, and act on it. New interactable types must be addable without editing the player's interaction code (no growing per-type branch the player has to know about). The session is networked, so the actual effect of an interaction (a door opening, an item being consumed) must be authoritative on the server and not decided by the client, while the focus detection and prompt can be local to the acting player. Describe how the player discovers and talks to interactables generically, how an interaction is requested and executed, where authority lives, and the trade-offs of your approach.
Design a general interaction system for a multiplayer Unreal Engine game with many kinds of interactable objects — doors, pickups, levers, triggers — and more types added over the project's life. The player should be able to focus the object they are looking at, see a context prompt for it, and act on it. New interactable types must be addable without editing the player's interaction code (no growing per-type branch the player has to know about). The session is networked, so the actual effect of an interaction (a door opening, an item being consumed) must be authoritative on the server and not decided by the client, while the focus detection and prompt can be local to the acting player. Describe how the player discovers and talks to interactables generically, how an interaction is requested and executed, where authority lives, and the trade-offs of your approach.
Define a common IInteractable interface with an Interact(Instigator) method; doors and pickups implement it. The player runs a trace to find the focused interactable, calls a Server RPC, and the server executes the interaction authoritatively.
Common mistakes
- ✗Casting to each concrete class instead of using a shared interface
- ✗Executing interactions on the client and only replicating the result
- ✗Polling distance every Tick instead of tracing on input
Follow-up questions
- →How would you show an interaction prompt only for the locally focused object?
- →How would you handle an interaction that takes time, like a hold-to-open door?
MiddleDesignCommonDesign an inventory system for a multiplayer Unreal Engine game. Players carry many items — stackable consumables and unique stateful items (durability, ammo) — and designers must define new item types without a programmer or a recompile. The same item type appears in many inventories, so item definitions should be shared rather than duplicated per copy. Inventory contents must be authoritative on the server and not trustable from the client (a client must not be able to grant itself items). The inventory UI must update when items are added, removed, or moved without polling every frame, and the system should scale to large inventories without re-sending the whole contents on every small change. Describe where inventory state and item definitions live, how the UI stays in sync, where authority lives, and the trade-offs of your approach.
Design an inventory system for a multiplayer Unreal Engine game. Players carry many items — stackable consumables and unique stateful items (durability, ammo) — and designers must define new item types without a programmer or a recompile. The same item type appears in many inventories, so item definitions should be shared rather than duplicated per copy. Inventory contents must be authoritative on the server and not trustable from the client (a client must not be able to grant itself items). The inventory UI must update when items are added, removed, or moved without polling every frame, and the system should scale to large inventories without re-sending the whole contents on every small change. Describe where inventory state and item definitions live, how the UI stays in sync, where authority lives, and the trade-offs of your approach.
Put an UInventoryComponent on the owner holding an array of item entries; describe items as UItemDataAsset and reference them by id. Replicate the entry array server-side; the UI binds to a change delegate so adding or moving items rebuilds slots.
Common mistakes
- ✗Spawning a full Actor per item instead of referencing a lightweight shared DataAsset definition
- ✗Polling the inventory every tick from the UI instead of binding to a change delegate
- ✗Putting inventory state on the client and trusting it, instead of replicating from the server
Follow-up questions
- →How would you handle item stacking and split/merge operations across slots?
- →Why use a
FastArraySerializerfor the entry array instead of a plain replicatedTArray?
MiddleDesignCommonDesign a modular character stats system in Unreal Engine for an RPG where stats (health, strength, speed, resistances) are constantly modified by equipment and timed effects. Many buffs and debuffs stack, expire, and overlap — additive and multiplicative — and removing one buff must restore exactly its contribution without corrupting the base value or other modifiers. Designers must be able to add new stats and define item/effect modifiers without rewriting the system. Gameplay and UI must react when a stat changes without polling every frame, and the current value must be cheap to recompute (not rescanned the world every tick). In multiplayer the authoritative values come from the server. Describe how you represent a stat and its modifiers, how the final value is derived and kept consistent as buffs stack and expire, how consumers are notified, and the trade-offs of your approach.
Design a modular character stats system in Unreal Engine for an RPG where stats (health, strength, speed, resistances) are constantly modified by equipment and timed effects. Many buffs and debuffs stack, expire, and overlap — additive and multiplicative — and removing one buff must restore exactly its contribution without corrupting the base value or other modifiers. Designers must be able to add new stats and define item/effect modifiers without rewriting the system. Gameplay and UI must react when a stat changes without polling every frame, and the current value must be cheap to recompute (not rescanned the world every tick). In multiplayer the authoritative values come from the server. Describe how you represent a stat and its modifiers, how the final value is derived and kept consistent as buffs stack and expire, how consumers are notified, and the trade-offs of your approach.
Use a UStatComponent holding each stat as a base value plus a list of modifiers; the current value is computed from base and active modifiers. Items and effects add or remove modifiers, and the component broadcasts a delegate on change.
Common mistakes
- ✗Mutating the final stat value directly so the base value is lost when buffs stack or expire
- ✗Sharing stats in a global singleton instead of a per-character component
- ✗Recomputing stats every Tick instead of recalculating only when a modifier changes
Follow-up questions
- →How would you order additive vs. multiplicative modifiers when computing the final value?
- →How would you handle a stat like health where current value differs from max value?
MiddleDesignCommonDesign a player respawn system for a multiplayer Unreal Engine match. When a player dies, after a delay they should come back at an appropriate spawn point with a clean character — no leftover state from the previous life. Persistent data such as score, team, and stats must survive death and carry across to the new life rather than being lost with the dead body. The respawn must be authoritative on the server: the client must not decide on its own when or where it respawns or spawn its own character. The respawn timer should be visible to clients counting down, and the new character must appear correctly for all clients. Describe what is disposable versus persistent across a life, who performs the respawn and spawn-point choice, where persistent state lives, and the trade-offs of your approach.
Design a player respawn system for a multiplayer Unreal Engine match. When a player dies, after a delay they should come back at an appropriate spawn point with a clean character — no leftover state from the previous life. Persistent data such as score, team, and stats must survive death and carry across to the new life rather than being lost with the dead body. The respawn must be authoritative on the server: the client must not decide on its own when or where it respawns or spawn its own character. The respawn timer should be visible to clients counting down, and the new character must appear correctly for all clients. Describe what is disposable versus persistent across a life, who performs the respawn and spawn-point choice, where persistent state lives, and the trade-offs of your approach.
Handle respawn in the GameMode server-side: on death the old Pawn is destroyed while the PlayerController survives, then after a delay the GameMode picks a PlayerStart and spawns a new Pawn to possess. Persistent state lives on PlayerState.
Common mistakes
- ✗Reusing the dead Pawn instead of destroying it and spawning a fresh one
- ✗Letting the client spawn or place its own Pawn instead of the server
GameMode - ✗Storing persistent data on the
Pawn, which is lost when it is destroyed
Follow-up questions
- →How would you choose a spawn point that avoids enemies and other players?
- →How would you implement a respawn timer that all clients see counting down?
MiddleDesignCommonDesign a save/load architecture for an Unreal Engine game with persistent world state — player progress, inventory, and dynamically spawned actors that must come back on load. Many independent systems each own a slice of savable state, so each must contribute to and restore from the save without one monolithic save routine knowing all their internals. The format must survive across game builds and platforms (it must not break when classes change between versions), so live object memory and raw pointers cannot just be dumped — you need a stable representation that rebuilds live objects on load. Saving must be explicit and durable to disk, not assumed to persist in memory. In multiplayer only the authoritative side persists state. Describe what you store versus what you rebuild, how independent systems plug in, how you keep the save robust across versions, and the trade-offs of your approach.
Design a save/load architecture for an Unreal Engine game with persistent world state — player progress, inventory, and dynamically spawned actors that must come back on load. Many independent systems each own a slice of savable state, so each must contribute to and restore from the save without one monolithic save routine knowing all their internals. The format must survive across game builds and platforms (it must not break when classes change between versions), so live object memory and raw pointers cannot just be dumped — you need a stable representation that rebuilds live objects on load. Saving must be explicit and durable to disk, not assumed to persist in memory. In multiplayer only the authoritative side persists state. Describe what you store versus what you rebuild, how independent systems plug in, how you keep the save robust across versions, and the trade-offs of your approach.
Use a USaveGame subclass as a plain data container, serialized via UGameplayStatics::SaveGameToSlot. Each savable system writes its state into the object on save and restores it on load; never serialize live Actors directly — store ids and rebuild.
Common mistakes
- ✗Trying to serialize live Actor pointers instead of storing ids and rebuilding on load
- ✗Using raw
memcpyof structs, which breaks across builds and platforms - ✗Assuming in-memory state persists without explicitly writing to a save slot
Follow-up questions
- →How would you save and restore dynamically spawned Actors and their world transforms?
- →How would you handle a save written by an older version of the game?
MiddleDesignCommonDesign the enter/exit system for drivable vehicles in a multiplayer Unreal Engine game. A player on foot can walk up to a vehicle, get in, drive it, and later get out at a sensible exit position. While driving, the player's input must control the vehicle rather than the character, and the on-foot character must not be lost — its inventory and state have to survive the trip so the same character resumes on exit. The session is networked, so who controls what must be authoritative and consistent for all clients, and a client must not be able to grant itself control of a vehicle. Driving and on-foot movement should both replicate smoothly. Describe how you model the player, character, and vehicle, how control transfers on enter and exit, what happens to the character while driving, where authority lives, and the trade-offs of your approach.
Design the enter/exit system for drivable vehicles in a multiplayer Unreal Engine game. A player on foot can walk up to a vehicle, get in, drive it, and later get out at a sensible exit position. While driving, the player's input must control the vehicle rather than the character, and the on-foot character must not be lost — its inventory and state have to survive the trip so the same character resumes on exit. The session is networked, so who controls what must be authoritative and consistent for all clients, and a client must not be able to grant itself control of a vehicle. Driving and on-foot movement should both replicate smoothly. Describe how you model the player, character, and vehicle, how control transfers on enter and exit, what happens to the character while driving, where authority lives, and the trade-offs of your approach.
Make the vehicle its own APawn; on enter the server calls Controller->Possess(Vehicle) and hides the character Pawn. On exit it re-possesses the character and teleports it to an exit point. The server is authoritative over every Possess call.
Common mistakes
- ✗Calling
Possesson the client instead of the server, breaking authority - ✗Attaching the character to the vehicle instead of swapping the possessed Pawn
- ✗Destroying or replacing the player's
Controllerinstead of re-possessing
Follow-up questions
- →How would you handle multiple seats — driver plus passengers — in one vehicle?
- →What happens to the character Pawn while the player is driving, and why?
MiddleDesignCommonDesign the weapon system for a competitive multiplayer shooter in Unreal Engine. The game ships with dozens of guns — hitscan rifles, projectile launchers, different fire rates, damage, spread, and magazine sizes — and designers must be able to add and balance new weapons without a programmer or a recompile. Two players holding the same gun must track independent ammo and reload state. Shooting must feel instantly responsive on the firing client, yet hits and kills must be authoritative and not trustable from the client (cheaters must not be able to fake damage). Describe how you would structure the weapon logic, where weapon definitions live, how firing state is owned, and how shots, hits, and cosmetic feedback are split between client and server. State the trade-offs of your structure.
Design the weapon system for a competitive multiplayer shooter in Unreal Engine. The game ships with dozens of guns — hitscan rifles, projectile launchers, different fire rates, damage, spread, and magazine sizes — and designers must be able to add and balance new weapons without a programmer or a recompile. Two players holding the same gun must track independent ammo and reload state. Shooting must feel instantly responsive on the firing client, yet hits and kills must be authoritative and not trustable from the client (cheaters must not be able to fake damage). Describe how you would structure the weapon logic, where weapon definitions live, how firing state is owned, and how shots, hits, and cosmetic feedback are split between client and server. State the trade-offs of your structure.
Make the weapon a UWeaponComponent (or attached Actor) driven by a UWeaponDataAsset for fire rate, damage, and ammo. The component owns firing state; the server validates shots and applies hits, while clients predict muzzle VFX and recoil.
Common mistakes
- ✗Hard-coding weapon stats in C++ subclasses instead of a shared data-driven definition
- ✗Trusting client-reported hits, letting players fake kills
- ✗Using a spawned projectile Actor for hitscan weapons where a line trace suffices
Follow-up questions
- →How would you handle weapon switching and keep ammo state per weapon?
- →How do hitscan and projectile weapons differ in their replication needs?
SeniorDesignCommonDesign a custom ability system for a multiplayer Unreal Engine game without using the ability-system plugin GAS. Characters have many abilities with cooldowns, resource costs, tags, and timed effects (buffs, debuffs, damage-over-time), and designers must be able to author and tune abilities and effects without a programmer recompiling per skill. Ability logic must be reusable across character types rather than welded to one character class. The session is networked, so activation, cost, and cooldown must be validated authoritatively on the server and a client must not be able to fire an ability or apply an effect on its own authority — yet the UI should still feel responsive (cooldowns can be predicted locally with rollback). Describe how you model abilities and timed effects, where activation is resolved, how effects are applied and managed, and what your custom system gives up versus a ready-made framework.
Design a custom ability system for a multiplayer Unreal Engine game without using the ability-system plugin GAS. Characters have many abilities with cooldowns, resource costs, tags, and timed effects (buffs, debuffs, damage-over-time), and designers must be able to author and tune abilities and effects without a programmer recompiling per skill. Ability logic must be reusable across character types rather than welded to one character class. The session is networked, so activation, cost, and cooldown must be validated authoritatively on the server and a client must not be able to fire an ability or apply an effect on its own authority — yet the UI should still feel responsive (cooldowns can be predicted locally with rollback). Describe how you model abilities and timed effects, where activation is resolved, how effects are applied and managed, and what your custom system gives up versus a ready-made framework.
Model each ability as a UAbility object spawned from a UAbilityDataAsset, owned by a UAbilityComponent that tracks cooldowns and resources. The server activates and resolves abilities; effects are timed structs applied to a stat component.
Common mistakes
- ✗Activating abilities client-side without server validation of cost and cooldown
- ✗Coupling ability logic to one character class instead of a reusable component
- ✗Applying timed effects with raw timers scattered everywhere instead of one effect manager
Follow-up questions
- →How would you implement stacking and refreshing of timed effects?
- →What does your custom system lose compared to GAS, and when is that acceptable?
SeniorDesignCommonDesign a quest system for a multiplayer RPG in Unreal Engine. The game has hundreds of quests with ordered objectives (kill N, collect X, reach a place), and designers must author whole quests and objectives without a programmer recompiling per quest. Many unrelated gameplay systems — combat, pickups, exploration — must be able to advance objectives without each one knowing about specific quests or being hard-wired to them. Quest progress and completion must be authoritative on the server, not decided by the client UI, and progress must be serializable so it can persist through a save. Each player tracks their own quests and progress, and the UI updates from progress changes rather than polling. Describe how quests and objectives are represented, how gameplay events advance objectives without tight coupling, where authority and progress live, and the trade-offs of your approach.
Design a quest system for a multiplayer RPG in Unreal Engine. The game has hundreds of quests with ordered objectives (kill N, collect X, reach a place), and designers must author whole quests and objectives without a programmer recompiling per quest. Many unrelated gameplay systems — combat, pickups, exploration — must be able to advance objectives without each one knowing about specific quests or being hard-wired to them. Quest progress and completion must be authoritative on the server, not decided by the client UI, and progress must be serializable so it can persist through a save. Each player tracks their own quests and progress, and the UI updates from progress changes rather than polling. Describe how quests and objectives are represented, how gameplay events advance objectives without tight coupling, where authority and progress live, and the trade-offs of your approach.
Describe quests as UQuestDataAsset with ordered objective definitions; a UQuestComponent tracks active quests and progress. Gameplay systems broadcast events the quest manager listens to, advancing objectives and resolving rewards server-side.
Common mistakes
- ✗Hard-coding quest logic per quest instead of a data-driven objective model
- ✗Coupling gameplay systems directly to quests instead of an event bus
- ✗Tracking quest progress and completion on the client instead of the server
Follow-up questions
- →How would you support branching quests with mutually exclusive objective paths?
- →How would you persist quest progress through your save system?
SeniorDesignCommonDesign the team logic for a team-based multiplayer mode in Unreal Engine — two or more teams, friendly fire disabled within a team, per-team score, and team-colored nameplates. The server must assign and balance teams; a client must never be able to decide on its own who is an ally or report kills it considers valid. Every client needs to read every player's team so it can color nameplates and run friend/foe checks, so each player's team affiliation must be visible to all clients. A player's team must survive their character dying and respawning, and survive a disconnect/rejoin so they return to the same side. Describe where you store team affiliation and per-team score, who assigns teams, how friend/foe and friendly-fire are resolved, and the trade-offs of your approach.
Design the team logic for a team-based multiplayer mode in Unreal Engine — two or more teams, friendly fire disabled within a team, per-team score, and team-colored nameplates. The server must assign and balance teams; a client must never be able to decide on its own who is an ally or report kills it considers valid. Every client needs to read every player's team so it can color nameplates and run friend/foe checks, so each player's team affiliation must be visible to all clients. A player's team must survive their character dying and respawning, and survive a disconnect/rejoin so they return to the same side. Describe where you store team affiliation and per-team score, who assigns teams, how friend/foe and friendly-fire are resolved, and the trade-offs of your approach.
Store a replicated TeamId on each PlayerState; the GameMode assigns teams server-side. Use GenericTeamId for friend/foe checks, keep per-team scores on GameState, and gate damage and objectives through the server's team comparison.
Common mistakes
- ✗Storing team on a non-replicated or client-only object so other clients can't read it
- ✗Letting clients decide friend/foe instead of the server-authoritative team comparison
- ✗Assigning teams outside the GameMode, breaking balance and rejoin logic
Follow-up questions
- →How would you handle a player rejoining and being placed back on their original team?
- →How would you implement team-only chat and team-colored nameplates?
SeniorTheoryOccasionalHow do you migrate Marketplace assets into a project cleanly in Unreal Engine?
How do you migrate Marketplace assets into a project cleanly in Unreal Engine?
Add the content to a clean throwaway project first, then use the Migrate tool to copy only what you need into a dedicated top-level folder. Audit references, fix redirectors, and never let third-party assets scatter through your own folders.
Common mistakes
- ✗Adding a pack directly to the main project, scattering third-party assets among your own
- ✗Copying
.uassetfiles in the OS file explorer, which breaks references and redirectors - ✗Migrating whole demo packs instead of only the assets actually used
Follow-up questions
- →What is a redirector and how do you clean them up after moving assets?
- →How would you use the Reference Viewer and Size Map before migrating a pack?
SeniorTheoryOccasionalHow do you handle versioning of save data across game updates in Unreal?
How do you handle versioning of save data across game updates in Unreal?
Store a version number in the USaveGame and run migration steps on load that upgrade old data field by field. Avoid raw binary blobs; UE's tagged property serialization keeps a save loadable even when new fields are added with sensible defaults.
Common mistakes
- ✗Relying on raw binary serialization, which breaks the moment a struct layout changes
- ✗Assuming the engine package version handles game-specific save migration for you
- ✗Skipping a version field, leaving no way to know which migration steps to run
Follow-up questions
- →How would you migrate a save when a field's meaning changes, not just its presence?
- →How does UE's
FArchivecustom version system help with serialized struct changes?
SeniorTheoryOccasionalHow do you structure plugins and modules in a large Unreal Engine project?
How do you structure plugins and modules in a large Unreal Engine project?
Split code into focused modules with explicit dependencies declared in .Build.cs; group reusable features into plugins. Keep editor-only code in separate editor modules and enforce a one-way dependency graph so low-level modules never need gameplay.
Common mistakes
- ✗Putting all code in one game module, making it a slow-to-compile monolith
- ✗Allowing circular module dependencies, which the build system actually rejects
- ✗Shipping editor-only code in a runtime module instead of a separate editor module
Follow-up questions
- →What is the difference between
PublicDependencyModuleNamesandPrivateDependencyModuleNames? - →When should a feature be its own plugin instead of just another module?