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.
- ✗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
- →How would you support branching quests with mutually exclusive objective paths?
- →How would you persist quest progress through your save system?
Key classes
UQuestDataAsset— quest definition:id, text, an ordered array ofFObjectiveDef, rewards, prerequisites.FObjectiveDef— aUSTRUCT: objective type (kill/collect/reach), target tag, required count.UQuestComponent— aUActorComponentonPlayerState: active quests, per-objective progress, history.UQuestSubsystem— an event bus: gameplay systems post events here, components subscribe.FQuestProgress— a runtime-stateUSTRUCT: questid, objective index, counters.
Data model
A quest is data: one execution engine reads a UQuestDataAsset. An objective is described by a type and a tag, not code. Progress (FQuestProgress) is separate from the definition, which lets it be serialized into a save.
Data flow
- A gameplay event (kill, pickup) → the system posts an
FGameplayEventtoUQuestSubsystem. - The subsystem dispatches the event to subscribed
UQuestComponents. - The component matches the event against the current
FObjectiveDefand increments a counter. - Objective complete → advance to the next; all objectives complete → the server grants rewards.
FQuestProgressreplicates and the UI updates via anOnQuestUpdateddelegate.
Replication considerations
UQuestComponent lives on PlayerState, FQuestProgress is Replicated. All objective checks and reward grants happen on the server. The client only displays replicated progress. The event bus runs server-only; the UI updates through OnRep.
Designer-facing config
Each quest is a UQuestDataAsset asset; objectives are assembled from reusable FObjectiveDef in the editor. Text comes from localization tables. Rewards reference UItemDataAsset. The designer builds content with no code.
Trade-offs
- Linear objective array vs. a graph: an array is simple, a graph is needed for branching — it complicates the UI and the save.
- Event bus vs. direct calls: a bus decouples systems and scales, but adds indirection when debugging.