A source-available Unreal Engine plugin for non-linear, branching quest systems. SimpleQuest is built on a directed acyclic graph of quest steps with a typed publish/subscribe event bus, giving designers the freedom to craft questlines that feel alive rather than scripted. Currently free for non-commercial use, an upcoming MIT licensed free-use release is planned following a future funding milestone.
This version is for Unreal Engine 5.6.
See CHANGELOG.md for version history.
The
devbranch contains a ground-up rewrite of SimpleQuest and introduces SimpleCore, a new foundational plugin. Everything below describes work that is feature-complete ondevand targeting a pre-release in the near future. Themainbranch still reflects the older class-based system described in the rest of this README.
SimpleQuest now sits on top of SimpleCore, a standalone plugin providing general-purpose game infrastructure that any system can use — not just quests.
- Hierarchical Tag Router — A signal bus where subscribing to a parent gameplay tag receives events from all descendant tags. Designed to complement (not replace) Epic's GameplayMessageRouter. Decoupled from actors — any system can publish or subscribe.
- World State Subsystem — A persistent, queryable fact store keyed by gameplay tags with integer counts. Boundary-transition broadcasting, bulk operations, and fact-added/removed events. Think GAS tag counting without the ability system coupling.
The headline feature. Quest authoring moves from data arrays to a full node-based graph editor inside the Unreal editor.
- Recursive graph model — Quests and steps can nest to any depth in any combination. No fixed "questline > quest > step" hierarchy — the graph structure is whatever the design requires.
- Named outcomes — Nodes resolve with designer-authored outcome tags (not binary success/failure). A combat step can complete with
Victory,Retreat, orNegotiated, and downstream wiring routes each outcome independently. - Prerequisite combinators — AND, OR, and NOT operator nodes wire into any content node's prerequisite input. Prerequisites can gate activation, gate progression, or defer completion depending on the gate mode.
- Deactivation system — Nodes can be externally deactivated, blocked, and unblocked. Deactivation cascades, block/clear utility nodes, and group signal nodes enable complex quest state machines.
- Linked questline nodes — Reference external questline graph assets inline. The compiler inlines the linked graph's wiring with bidirectional tag resolution and dual-tag (contextual + standalone) support.
- Live editing feedback — Step nodes display objective class, target actors/classes, watching givers and targets from loaded levels, gate mode, reward class, and named outcomes at a glance. Expand for full detail. Red border when configuration is incomplete.
- Multi-pass compiler — Compiles the full graph tree into flat runtime data with clickable error and warning messages that navigate directly to the offending node.
- Tag rename propagation — Rename a node, recompile, and all quest components in loaded levels are automatically updated. No broken references.
The runtime has been rebuilt from scratch around gameplay tags and UObject instances.
- Tag-addressed, instance-based — Every quest node is a
UObjectinstance addressed by gameplay tag. No class-per-quest, no struct arrays. The subsystem, components, and signal bus all route by tag. - Pull-based prerequisite activation — Deferred activation subscribes to world state changes per prerequisite leaf tag. When all conditions are met, the node activates. No polling, no ticking.
- Component catch-up — Givers, watchers, and targets that register after quest events have already fired (streaming, late spawn, join-in-progress) receive the current state immediately on registration.
- Outcome-filtered watchers — Watcher components can filter which outcomes they respond to. Empty filter = all outcomes (backward compatible).
The graph and runtime are feature-complete. Remaining work before the first external testing round:
- Stale pin preservation (prevent silent wire breakage on node config changes)
- Stale tag cleanup on compilation
- Self-loop connection rule tightening
- Packaged build tag registration
- Logging pass and readability pass for external contributors
- Non-linear quest graph -- Quest steps form a DAG with bidirectional prerequisite and next-step edges. Multiple steps can be active simultaneously, branches can converge, and completing one path can permanently close or re-enable another.
- Typed publish/subscribe event bus -- Channels keyed by
(UObject*, EventType)pairs guarantee that events are structurally unreachable by unintended subscribers. No conditional filtering required at any call site. - Blueprint/C++ parity -- All objectives, rewards, and components are fully accessible from Blueprint. Core systems are implemented in C++ with
BlueprintNativeEventoverride points throughout. - Late-registration state replay -- Components that register after quest events have already fired receive the current in-flight state automatically. Safe for streaming levels, dynamically spawned actors, and multiplayer join-in-progress scenarios.
- Editor-time validation -- Asset validation via
IAssetRegistrydetects duplicate Quest IDs across the entire project at cook time. Runtime collision detection provides a second pass on load. - Extensible without forking -- Subclass
UQuestManagerSubsystemand inject it via project settings to add custom orchestration logic without modifying plugin source. - Save-ready by design -- Each quest asset carries a stable
QuestIDproperty intended as a save key. Compatible withUSaveGameout of the box. - CoreRedirects included --
Config/DefaultSimpleQuest.inimaintains backward compatibility when classes or properties are renamed.
- Unreal Engine 5.6 or later
- Visual Studio 2022 (Windows) or Xcode (Mac) with C++20 support enabled
- Copy the
SimpleQuestfolder into your project'sPlugins/directory. - Right-click your
.uprojectfile and select Generate Visual Studio project files. - Open the solution and build the Development Editor target.
- Enable the plugin in Edit > Plugins if it is not already active.
To use SimpleQuest as a source dependency in another plugin, add "SimpleQuest" to your .uplugin or Build.cs dependencies.
(Soon to be replaced with visual graph questline authoring)
Right-click in the Content Browser, select Blueprint Class, and choose Quest as the class. Open the asset and assign a unique Quest ID.
Each FQuestStep in the Steps array carries:
- ObjectiveClass -- the
UQuestObjectivesubclass to instantiate when this step activates - PrerequisiteStepIDs -- indices of steps that must complete before this one activates
- NextStepIDs -- indices of steps to unlock when this one completes
- TargetActors / TargetClass -- optional actor references passed to the objective on activation
Steps with no prerequisites activate immediately when the quest starts. Steps with prerequisites activate the moment all of their prerequisites are satisfied, without any polling.
UQuestManagerSubsystem* QuestManager = GetGameInstance()->GetSubsystem<UQuestManagerSubsystem>();
QuestManager->StartQuest(UMyQuest::StaticClass());From Blueprint, call Start Quest on the Quest Manager Subsystem node and pass your quest class.
| Component | Attach to | Purpose |
|---|---|---|
UQuestPlayerComponent |
Player Pawn or PlayerState | Tracks the local player's quest state |
UQuestGiverComponent |
NPC Actor | Offers and activates quests on interaction |
UQuestTargetComponent |
Enemy, item, or location Actor | Responds to trigger, kill, and interact events |
UQuestWatcherComponent |
Any Actor | Receives lifecycle events for one or more quests |
UQuest (data asset)
└─ UQuestManagerSubsystem.StartQuest()
└─ Activates FQuestSteps with no unmet prerequisites
└─ Instantiates UQuestObjective per step
└─ Notifies registered UQuestTargetComponents
via UQuestSignalSubsystem
└─ Player interaction calls
QuestManagerSubsystem.CountQuestElement()
└─ Objective.TryCompleteObjective()
└─ Unlocks next steps,
ends quest, or
starts next quest
Steps within a quest form a directed acyclic graph. The broader quest network supports cycles to enable replayability and conditional re-activation.
The orchestration hub. Maintains maps of registered givers and watchers, validates prerequisites, progresses steps, and publishes lifecycle events. Scoped to the GameInstance so quest state persists across level transitions.
A typed pub/sub event bus. Channels are keyed by (UObject*, UScriptStruct*) pairs. Subscribers capture weak object pointers and are silently dropped on broadcast if the subscriber has been garbage collected. C++20 derived_from concept constraints enforce type safety at compile time.
Subclass UQuestObjective and override TryCompleteObjective. The subsystem calls this each time CountQuestElement is invoked for the relevant step.
UCLASS(Blueprintable)
class UMyObjective : public UQuestObjective
{
GENERATED_BODY()
public:
virtual bool TryCompleteObjective() override
{
return CurrentElements >= MaxElements;
}
};Override SetObjectiveTarget to receive the target actor assigned in the step definition.
Subclass UQuestReward and implement your reward grant logic. Assign the class to the RewardClass field on any FQuestStep.
Subclass UQuestManagerSubsystem and register it in Project Settings > SimpleQuest via UGameInstanceSubsystemInitializer. Use this to add analytics hooks, custom prerequisite logic, or save system integration without touching plugin source.
Log verbosity -- SimpleQuest logs under the LogSimpleQuest category. Set verbosity in DefaultEngine.ini:
[Core.Log]
LogSimpleQuest=VerboseLog statements at VeryVerbose are stripped entirely in Shipping builds.
CoreRedirects -- When renaming any public class or property, add a redirect to Config/DefaultSimpleQuest.ini to avoid breaking existing consumers.
| Quarter | Deliverable | Status |
|---|---|---|
| Visual graph editor + SimpleCore foundation | Feature-complete — in pre-release testing | |
| Q3 2026 | Save/Load system — USaveGame integration with mid-step state handling |
Planned |
| Q3 2026 | Multiplayer replication — server-authoritative quest state with join-in-progress support | Planned |
| Q4 2026 | GAS integration module — GameplayTag identifiers, GameplayEffect rewards, Gameplay Event triggers | Planned |
| Q1 2027 | Expanded objective library — timed, escort, collection, and conversation objectives | Planned |
| Q1 2027 | Example project and full API documentation | Planned |
Community feedback is welcome and valuable at this stage. If you encounter a bug, a compatibility issue, or have a feature request, please open an issue with the engine version and a description of the problem or suggestion.
Code contributions via pull request are not being accepted during the current pre-release phase while licensing terms are being finalized. This will be revisited ahead of the first public release. Watch the repository for updates.
For bug reports, include the engine version, a minimal reproduction case, and any relevant output from the LogSimpleQuest log category.
SimpleQuest is licensed under Polyform Noncommercial 1.0.0. It is free to use, modify, and distribute for any non-commercial purpose. Commercial use requires a separate license.
The project is planned to relicense to MIT upon a future funding milestone, at which point it will be free for all uses without restriction. Commercial licensing terms will be announced separately ahead of that transition.

