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

Lab 2: Signal Race

Lab 2 turns a single linear quest into two independently observable routes. It uses an immediate selector, two fact-listening Pause Conditions, two realtime Pause Conditions, a nested Boolean AND, and an XOR-typed convergence without relying on an untested cancellation claim.

RecordValue
Structural validation date2026-08-09
Runtime test dateNot yet recorded

Structurally validated: both checkpoints round-trip with WolvenKit 8.19.0. Follow the test guide for timing, parallel waits, re-entry, and reload.

Follow Author Signal Race in WolvenKit to build the graph from the start checkpoint. Use Test both Signal Race routes to keep the canonical and source-edited candidates, saves, and logs separate.

What the lab demonstrates

The canonical project sets cqa002_test_mode to 2 and takes the stable route:

entry -> completed guard -> test_mode = 2 -> activate quest/objectives
  -> immediate selector chooses False
  -> wait 120 realtime seconds -> signal_stop = 1
  -> waiting AND observes signal_stop > 0 AND test_mode == 2
  -> optional objective succeeds -> XOR-shaped convergence
  -> required objective succeeds -> completed = 1 -> quest succeeds

A controlled source edit changes only node 11 from exact value 2 to 1:

entry -> completed guard -> test_mode = 1 -> activate quest/objectives
  -> immediate selector chooses True
  -> wait 30 realtime seconds -> signal_failed = 1
  -> failure listener continues
  -> optional objective fails -> XOR-shaped convergence
  -> required objective succeeds -> completed = 1 -> quest succeeds

Only the selected writer delay starts in either candidate. The other monitor is still a lifecycle obligation, but its reserved fact has no writer in that variant. The lab therefore does not need to claim that XOR cancels a losing timer. Phase-exit cleanup and arbitrary external fact writes remain Experimental.

Prerequisites and downloads

Complete Lab 1 and read:

Use Cyberpunk 2077 2.31a, WolvenKit 8.19.0, ArchiveXL 1.27.0, RED4ext 1.30.0, and redscript 0.5.31.

Do not install the two checkpoints together. They register the same depot paths. Use separate untouched pre-Lab-2 saves for the mode-2 and mode-1 runtime variants; all five tutorial facts and the journal lifecycle are save-backed.

Resource model

ResourceDepot pathOwns
Root questphasemod\cqa\cqa002\phases\cqa002.questphaseGuard, selector, monitors, delays, fact writes, journal operations, convergence, termination
Journalmod\cqa\cqa002\journal\cqa002.journalQuest, phase, required objective, optional objective
Onscreen localizationmod\cqa\cqa002\localization\en-us\onscreens\cqa002.jsonThree English strings used by the journal
ArchiveXL registrationCQA_Lab02_SignalRace.archive.xlRoot attachment plus journal/localization merges

The start checkpoint supplies the same journal and localization content as the completed checkpoint. Its questphase has only Input 0, terminating Output 1, and one ordinary edge. This makes it an executable authoring baseline, not an empty folder or a hidden generator input.

Journal and localization contract

quests
└── minor_quest
    └── cqa002                              gameJournalQuest
        └── cqa002_01                       gameJournalQuestPhase
            ├── cqa002_01_obj_wait          required objective
            └── cqa002_01_obj_stable        optional objective
Journal entryKeyEnglish text
cqa002 titlecqa_cqa002_titleSignal Race
cqa002_01_obj_wait descriptioncqa_cqa002_objective_waitWait for the signal test to resolve.
cqa002_01_obj_stable descriptioncqa_cqa002_objective_stableKeep the signal stable.

The stable journal objective has optional: 1. The corresponding questphase journal-node payloads retain their normal type.optional: 0; do not copy the journal entry’s optional flag into that unrelated node field. Every typed path uses fileEntryIndex: 2 because cqa002 is the containing gameJournalQuest at path component two.

Exact questphase

The completed graph has 21 nodes and 22 edges. Compare its IDs, socket names, and connections with your WolvenKit graph.

IDRED node typeDecisive payloadPurpose
0questInputNodeDefinitioninterface In1Enter from the registered root
1questOutputNodeDefinitionTerminating, interface Out1End completed and bypass routes
10questConditionNodeDefinitioncqa002_completed Equal 0Branch immediately around a completed save
11questFactsDBManagerNodeDefinitionset cqa002_test_mode exactly 2Select the canonical variant; edit only this value for failure testing
12questJournalNodeDefinitionquest pathActivate and track Signal Race
13questJournalNodeDefinitionrequired-objective pathActivate the required objective
14questJournalNodeDefinitionoptional-objective pathActivate the optional objective and fan out its Out
15questPauseConditionNodeDefinitioncqa002_signal_failed Greater 0Wait for the failure result
16questPauseConditionNodeDefinitionAND of stop fact and mode 2Wait for the canonical stable result
17questConditionNodeDefinitioncqa002_test_mode Equal 1Choose one writer branch immediately
18questPauseConditionNodeDefinition30-second realtime delayDelay the edited failure writer
19questFactsDBManagerNodeDefinitionset cqa002_signal_failed exactly 1Fulfil the failure listener
20questPauseConditionNodeDefinition120-second realtime delayDelay the canonical stable writer and leave time for a mid-flow save
21questFactsDBManagerNodeDefinitionset cqa002_signal_stop exactly 1Fulfil the stable AND listener
22questJournalNodeDefinitionoptional objective, Failed inputRecord optional failure
23questJournalNodeDefinitionoptional objective, Succeeded inputRecord optional success
24questFactsDBManagerNodeDefinitionset cqa002_signal_succeeded exactly 1Persist the stable-route outcome
25questLogicalXorNodeDefinitiontwo inputs, one outputConverge the mutually exclusive outcome routes
26questJournalNodeDefinitionrequired objective, Succeeded inputComplete the required objective
27questFactsDBManagerNodeDefinitionset cqa002_completed exactly 1Persist the one-shot completion guard
28questJournalNodeDefinitionquest path, Succeeded inputComplete Signal Race

Every supplied node has one job; no node is a magic template. In particular, ID 16 owns a Boolean condition tree, while ID 25 combines graph signals. They use similar logical vocabulary at different resource layers.

Exact edge contract

SourceDestinationMeaning
0.Out10.InEnter guard
10.False1.InCompleted save bypass
10.True11.InFirst-run variant setup
11.Out12.ActiveActivate quest
12.Out13.ActiveActivate required objective
13.Out14.ActiveActivate optional objective
14.Out15.InArm failure listener
14.Out16.InArm stable listener
14.Out17.InEvaluate selector now
17.True18.InEdited mode: start failure delay
18.Out19.InWrite failure fact
17.False20.InCanonical mode: start stable delay
20.Out21.InWrite stop fact
15.Out22.FailedFail optional objective
22.Out25.In1Failure outcome reaches convergence
16.Out23.SucceededSucceed optional objective
23.Out24.InRecord stable success
24.Out25.In2Stable outcome reaches convergence
25.Out126.SucceededComplete required objective
26.Out27.InWrite completion fact
27.Out28.SucceededComplete quest
28.Out1.InTerminate successful route

The three edges from 14.Out are three connections on one ordinary socket. There is no Hub. The two edges into Output 1.In also share one destination socket; socket count is not connection count.

Fact ownership

FactWriterReaderPurpose
cqa002_test_mode1116, 17Select and constrain the test variant
cqa002_signal_failed1915Failure monitor result
cqa002_signal_stop2116Stable monitor stop signal
cqa002_signal_succeeded24retained evidence/extension pointRecord stable optional success
cqa002_completed2710Bypass completed saves

These names are reserved to Lab 2. Do not use console writes or another mod to drive them during canonical acceptance; doing so changes which producer owns the result.

Common failure modes

SymptomCheck firstBoundary
Signal Race never appearsConfirm the .archive and .archive.xl names, all three registered depot paths, and the ArchiveXL/RED4ext logsRegistration or lookup failure; the graph has not yet been exercised
Both routes appear, or the wrong route winsConfirm node 11 is exact mode 2 for canonical or exact mode 1 for the edited candidate, and that only 17.True -> 18 and 17.False -> 20 existA dirty save or extra writer invalidates route attribution
Optional objective never resolvesCheck the matching writer fact, its listener comparison, the delay payload, and the listener’s journal-state socketDo not infer XOR or cleanup behavior before the route reaches convergence
Quest completes twice after reloadVerify the 27 -> 28 order, node 10 completed guard, and a truly untouched versus completed saveA console fact reset is diagnosis, not clean-save evidence
Graph looks right but validation failsCompare node IDs, RED types, socket names, resolved edges, and decisive payloads—not canvas placement or handle IDsLayout is not serialized behavior

Lab sequence: All labs · Next: Author Signal Race in WolvenKit.