Doelen en voortgang
Gevorderd Laatst bijgewerkt 9 jul 2026
Op deze pagina
Alles tussen “accepteren” en “inleveren” staat hier beschreven: hoe doelen worden bijgeschreven, hoe voorwaarden content afschermen, hoe effecten de state veranderen en hoe quests aan elkaar geketend worden.
Doelen
Een bij te houden doel leeft binnen een stap. De stap gebruikt een generieke id (Goal,
Deliver), terwijl de concrete soort in objective.type staat, zodat je die soort kunt wijzigen
zonder iets opnieuw te sleutelen:
- id: Goal
objective:
type: Kill
target: MyGame.Enemy.Wolf # GameplayTag, MUST be registered
count: 3
location: MyGame.Area.Farm # optional area gate
desc: "Kill the wolves near the farm"
next: Deliver
| Type | Betekenis | Hoe het meetelt |
|---|---|---|
Kill | dood N getagde vijanden | jouw doodscode meldt een Kill-event |
Collect | verzamel N getagde items | jouw pickup-code meldt een Collect-event |
Reach | bereik een getagde plek | een Reach-event, of CompleteObjective vanuit een trigger |
TalkTo | praat met iemand | automatisch: een gesprek beginnen telt mee |
Deliver | terugrapporteren aan de questgever | wordt vervuld door het inleveren zelf |
Custom | al het andere | jouw game meldt Custom + je eigen tag |
Twee handige eigenschappen:
TalkToricht zich op een speaker key, niet op een tag (target: Mary, dezelfde key als inspeakers:en op het Cast-tabblad). Elk gesprek met die NPC telt het doel alleen mee voor de pratende speler, en alleen zolang het doel actief is; met de NPC praten voordat je de quest accepteert telt dus terecht niets mee.Deliverblokkeert het inleveren nooit. Het bestaat zodat de tracker een regel “ga terugrapporteren” toont, en wordt automatisch afgevinkt zodra de quest ingeleverd wordt.
Meetellen vanuit je game is één aanroep (Blueprint of C++), server-authoritative en idempotent per
EventSourceId:
Comp->ReportObjectiveEvent(Instigator, EQuestwrightObjectiveEventType::Kill,
MatchTags, LocationTags, EventSourceId);
Tags worden hiërarchisch vergeleken: een doel met target: Enemy.Wolf telt ook mee bij een
event met de tag Enemy.Wolf.Alpha, dus je hoeft niet elk subtype op te sommen.

GameplayTags: de ene cruciale regel
Elke waarde van target, location, require/grant bij een keuze, tag in een voorwaarde en
grant_tag in een effect is een GameplayTag die al geregistreerd moet zijn in je project;
anders lost hij op tot een ongeldige tag en wordt hij stilzwijgend genegeerd. Dit is oorzaak
nummer 1 van “mijn doel telt nooit mee”. Registreren kan op twee manieren:
- Native in C++ (voorkeur voor tags die meegaan naar release):
UE_DEFINE_GAMEPLAY_TAG_COMMENT(...). - Project Settings → Project → GameplayTags (schrijft naar
Config/DefaultGameplayTags.ini).
Gebruik een hiërarchie met punten (MyGame.Enemy.Wolf, MyGame.Area.Farm), dan werkt
hiërarchisch matchen vanzelf. De enige uitzondering: een TalkTo-target is een speaker key, geen
tag.
Voorwaarden
Voorwaarden schermen de beschikbaarheid van een quest af (available_when) en de toegang tot een
stap (require). Atomaire soorten:
| Vorm | Betekenis |
|---|---|
{ quest: <QuestId>, state: <state> } | een andere quest verkeert in een state (available, active, completed, failed, declined) |
{ objective: <ObjId>, state: <state> } | een doel is active / complete / failed / inactive |
{ flag: <Name>, equals: <Value> } | een questvariabele van deze playthrough is gelijk aan een waarde |
{ tag: <GameplayTag> } | de speler bezit een gameplay tag |
{ item: <ItemId>, min: <N> } | de inventory bevat ≥ N van een item (via jouw inventory-provider) |
{ attribute: <AttrId>, min: <N> } | een stat is ≥ N (via jouw stat-provider) |
Samengesteld: { all: [...] } (EN), { any: [...] } (OF), { not: <cond> }.
available_when:
all:
- { quest: Region.Intro, state: completed }
- { not: { flag: Betrayed, equals: "true" } }
Effecten (on_end:)
Worden toegepast zodra een scène wordt verlaten:
on_end:
quest: accept # accept | complete | decline | fail | turnin
set: { RewardTier: Negotiated } # write flags, read back by flag conditions
grant_tag: Region.MetBran # grant gameplay tag(s) to the player
grant_quest: Region.FollowUp # auto-accept follow-up quest(s)
Een inleverscène eindigt doorgaans met on_end: { quest: turnin } plus end: completed.
Vertakken op keuzes van de speler
Wil je dat de questgever reageert op een eerdere keuze, zet dan een flag op het moment van die
keuze en schrijf vervolgens twee inleverstappen: die met de flag-voorwaarde eerst, de
vangnetstap als laatste. De routering van de questgever kiest de eerste inleverstap waarvan
require slaagt:
- id: Haggle
scene: { ... }
on_end: { quest: accept, set: { RewardTier: Negotiated } }
- id: DeliverHaggled # specific branch; keep it before the catch-all
require:
all:
- { objective: Goal, state: complete }
- { flag: RewardTier, equals: Negotiated }
scene: { ... }
on_end: { quest: turnin }
end: completed
- id: Deliver # default branch, carries the tracked objective
require: { objective: Goal, state: complete }
objective: { type: Deliver, count: 1, desc: "Report back" }
scene: { ... }
on_end: { quest: turnin }
end: completed
De meegeleverde demoquest gebruikt precies dit patroon (afdingen leidt tot een andere uitbetalingsscène).
Questketens
Een keten is niet meer dan data; er is geen apart asset:
available_when: { quest: A, state: completed }bij quest B (voorwaarde vooraf), en/ofon_end: { grant_quest: B }bij quest A (het vervolg automatisch accepteren).
priority bepaalt de volgorde van meerdere quests die één questgever aanbiedt (hoger eerst). De
New Chain-UI van de Studio schrijft deze waarden voor je weg met drag & drop; met de hand
schrijven is gelijkwaardig. De validatie vangt cycli in ketens en losse verwijzingen naar quests
of doelen op.
Barks
Sfeerbarks (barks:) klinken boven het hoofd van de questgever op een willekeurige timer; idle
barks (idle_barks:) klinken bij interactie wanneer de questgever niets meer te bieden heeft.
Beide gaan door dezelfde voice-over- en gezichtspipeline, in de stem van de questgever:
barks:
interval: [8, 16]
lines:
- "Wolves howling again..."
- { text: "After dark, nobody sets foot in the yard.", weight: 2 }
idle_barks:
lines:
- "Rest easy. The farm's safe, thanks to you."
Beloningen
rewards:
base:
currency: 20
xp: 50
items:
- { def: SmokedMeat, count: 1 }
currency, xp en items worden bij het inleveren vastgelegd; jouw game deelt de daadwerkelijke
goederen uit via het koppelvlak van de inventory-provider (zie
Runtime-integratie).