Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Conditions and gates

A condition answers a question about game state. A gate decides when that question is asked and what execution signal leaves afterward. Keeping those jobs separate is the foundation of reliable quest control flow.

“Continue when the player has arrived” can mean at least three different things:

  • sample the arrival state now and choose True or False;
  • hold this execution path until the arrival state is fulfilled;
  • combine arrival with other predicates before either of those graph nodes acts.

Those are different native resource shapes. A visually similar graph can therefore have different runtime behavior.

Three layers, three questions

Trace a gate from the outside in:

execution signal
      |
      v
graph node: evaluate now or wait?
      |
      v
condition object: which state is being tested?
      |
      v
leaf payloads and Boolean composition

Then trace outward again through named sockets. The three layers answer different questions:

LayerNative examplesQuestion
Evaluation schedulequestConditionNodeDefinition, questPauseConditionNodeDefinitionIs the predicate sampled on entry, or does this path wait?
PredicatequestFactsDBCondition, questTriggerCondition, questJournalConditionWhat piece of game state counts as fulfilled?
Predicate compositionquestLogicalCondition containing child conditionsMust all, any, or some other combination of child predicates be fulfilled?

Graph-level logical nodes are a fourth, separate concern: they receive execution signals through sockets. A questLogicalCondition does not merge graph edges, and a graph-level AND or XOR does not inspect facts by itself. Using the same English words for both layers is convenient, but the serialized types reveal which contract actually applies.

Choose the native shape from the behavior

Intended behaviorStarting shapeEssential caution
Decide between two routes using current stateImmediate condition nodeFalse is an output route, not a request to wait
Continue this route after a predicate is fulfilledPause condition nodeDo not assume how it polls, saves, cancels, or re-arms
Require several state predicates togetherLogical condition tree beneath either nodeThis combines truth values, not execution signals
Prevent a one-shot effect from running againImmediate fact guard plus an explicit persistent fact writeThe save may already contain either value
Watch for failure while other work continuesA separately activated waiting pathStarting a listener does not define how it is stopped
Accept one of several arriving graph signalsGraph topology, not a nested condition treeWinner, cancellation, and tie behavior require their own evidence

The table is a design router, not a copy-paste recipe. Every row still needs an explicit entry edge, exit edge, lifecycle owner, and evidence plan.

Read this section in order

ChapterQuestion it answers
Immediate branches and waiting gatesWhen does a condition run, and which sockets continue the graph?
Condition payloadsHow do fact, trigger, distance, journal, and time predicates represent state?
Boolean condition treesHow are leaf predicates nested under AND or OR, and why is there no generic NOT recipe?
Signal flowHow do graph-level AND, XOR, Hub, and Switch shapes route execution signals?
Delays and persistenceWhich clock and save-state questions must a delayed route answer?
Parallel monitors and cancellationHow can a side listener remain harmless or be explicitly cut?
Condition-family catalogWhich additional native condition families were observed, and what still needs research?
Lab 2: Signal RaceHow do immediate selection, parallel waits, a Boolean AND, and XOR-shaped convergence fit in one project?
Author Signal RaceWhich native properties and 22 socket edges reproduce the supplied graph?
Test both routesHow are two source variants, clean saves, hashes, logs, and outcomes kept distinct?

Start with the node schedule. A perfectly authored fact comparison still behaves incorrectly if it sits under the wrong surrounding graph node.

Inspect vanilla conditions

Use a disposable WolvenKit project for vanilla research:

  1. In the Asset Browser, locate the exact depot path named by a chapter.
  2. Open it without adding it to a distributable project, or add it only to a separate local inspection project.
  3. Record the graph-local node ID, concrete node class, condition payload, socket names, and focused connected edges.
  4. Record the game version, WolvenKit version, extraction date, and optionally a local hash.
  5. Keep the extracted .questphase and any complete CR2W-JSON serialization out of the book and downloadable examples.

Use the depot path to locate a reference. Adapt only the fields you need; vanilla facts, NodeRefs, and journal paths belong to the original quest.

State is not an event sequence

Many predicates describe state: a fact has a value, a journal entry has a state, or an actor is inside an area. Even when a payload enum contains words such as Entered or Exited, the enum name alone does not establish its exact edge timing, persistence, or replay behavior.

Ordered behavior comes from explicit execution edges:

wait for A
  -> wait for B
  -> perform C

Putting A and B in one AND tree asks whether both predicates are fulfilled for one condition evaluation. It does not record that A happened first. Starting two waiters in parallel likewise does not establish which will emit first or whether the losing path will stop.

Test timing-dependent behavior

When your quest depends on timing, test pause, loading, time skip, fast travel, and save/load. For parallel signals, test both arrival orders and simultaneous arrival. For reusable waits, test interruption and re-entry.