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

Areas, devices, and hacking

This cookbook page assembles three systems that are often mistaken for one: a world area or device must exist and stream, a questphase must address it through the correct identity, and the player-facing objective and marker must be managed separately. The graph never creates the trigger volume, interaction prompt, controller, hack minigame, or drop-point kiosk that it observes.

world ownership                     quest ownership
streaming block                     questQuestPhaseResource
  -> Quest sector                     -> phasePrefabs root
     -> trigger or device              -> objective / mappin state
     -> nodeData placement              -> action or waiting condition
     -> full child NodeRef              -> local child NodeRef

Use this page after Triggers and areas, Quest prefabs and NodeRefs, and Devices and persistence. It is a cookbook, not a replacement for those ownership chapters.

Vanilla references

These focused base-game resources are useful comparisons. Extract them from your own installation; they are references, not files to copy into the project.

base\quest\main_quests\part1\q108\phases\q108_06b_tower_mainframe.questphase
base\open_world\street_stories\watson\little_china\sts_wat_lch_01\phase\sts_wat_lch_01_phase.questphase
base\open_world\street_stories\watson\little_china\sts_wat_lch_01\phase\sts_wat_lch_01_openworld.questphase
base\open_world\street_stories\watson\little_china\sts_wat_lch_01\phase\sts_wat_lch_01_combat.questphase
base\quest\side_quests\sq021\phases\sq021_randys_room.questphase
base\gameplay\devices\drop_points\drop_point.ent

Resource and asset checklist

Before opening the quest graph, inventory every owner. A blank cell is not a default; it is an unresolved design decision.

ConcernRequired ownerReview evidence
World namespaceQuest-prefab root plus a Quest streaming descriptorLocal root in phasePrefabs; matching full root in the descriptor
AreaworldTriggerAreaNode, AreaShapeOutline.buffer, notifier, and nodeDataFull child NodeRef, transform, bounds, decoded points, height, and questTriggerNotifier_Quest
Objective presentationJournal objective, description, localization, and optional journal mappinFull typed paths, correct fileEntryIndex, and registered localization
World markerUsually a dedicated worldStaticMarkerNode in an AlwaysLoaded sectorFull marker NodeRef and world-space navigation endpoint
DeviceworldDeviceNode or evidence-matched entity placementEntity template, appearance, node-local instanceData, controller, components, slots/workspots, and full NodeRef
Quest-side device accessPrefab dependency plus action and/or conditionExact controller class, action CName, condition function CName, and local target NodeRef
Persisted lookupOnly the evidence-required .devices or .psrep contributionExact NodeRef hash, controller class, merge result, and reload behavior
Plant itemTweakDB item record and inventory ownershipItem ID, grant/pickup owner, quantity, consumption rule, and save behavior
Drop pointExisting live kiosk plus its controller contractExact native NodeRef, walkable approach, reservation item, deposit fact, and separate marker endpoint

phasePrefabs declares a namespace dependency; it does not place the sector. A sector nodeRefs row registers an identity; it does not supply a concrete trigger or device. A visible entity does not prove that its persistent controller bound correctly. These are Observed in vanilla and Structurally validated ownership distinctions, not runtime shortcuts.

Reach and leave areas

Story view

activate reach objective and marker
  -> wait for the intended area relation
  -> succeed reach objective and hide marker
  -> activate leave objective
  -> wait for the outer leave relation
  -> succeed leave objective
  -> optional completion fact or cleanup

The reach and leave waits must be ordered. If an outside-state condition is active before the player enters, it can already be true.

Exact phase payload

The retained player-targeted trigger condition has this focused property contract:

OwnerPropertyMeaning in the inspected shape
questPauseConditionNodeDefinitionconditionHandle to the condition wrapper
questTriggerConditiontriggerAreaRefLocal NodeRef beneath an available quest-prefab root
questTriggerConditionactivatorRefEmpty entity reference in the inspected player form
questTriggerConditionisPlayerActivator1 in the inspected player form
questTriggerConditiontypeEntered, Exited, IsInside, or IsOutside

Observed in vanilla: the cited Q108 phase uses a player-targeted questTriggerCondition with an empty activatorRef, isPlayerActivator: 1, local triggerAreaRef, and IsInside.

Use Entered/Exited for crossings and IsInside/IsOutside for current containment. Lab 3 uses the latter as ordered state waits:

ConditionUse when the story meansReload boundary
EnteredCross from outside to inside after activationLoading already inside may not create a new edge
ExitedCross from inside to outside after activationStarting outside is not a leave event
IsInsideProceed whenever the player is currently insideAlready-inside activation and reload require a retained test
IsOutsideProceed whenever the player is currently outsideMust be activated only after the intended inside step

The world-side area needs an authoritative outline buffer, a quest notifier, a vertical band that intersects the route, and a full NodeRef beneath the same root. Check the player’s Z coordinate when a rooftop trigger never fires.

Marker ownership

Activate and clear the journal mappin on explicit graph edges. Do not assume a trigger or device NodeRef is also a useful marker anchor. A marker intended to exist before a Quest sector streams normally needs its own AlwaysLoaded owner. The retained direct-device mappin failure is documented in NodeRefs, streaming, and placement.

Experimental: whether a new native device can serve directly as a journal mappin target must be tested for that exact cross-world identity. A separate marker is a controlled design, not a universal engine requirement.

Meeting areas are a lifecycle, not one radius

A contact meeting normally separates broad setup from the final engagement:

request community activation
  -> wait for CharacterSpawned
  -> V enters the broad setup area
  -> optional checkpoint
  -> start scene at a scene marker
  -> the running scene owns any narrower engage/awareness gate
  -> receive a named scene exit
  -> delay cleanup until no scene or AI owner remains
BoundaryOwnerWhat it may establish
Streaming/setupQuest sector, community area, and broad trigger after readinessThe world and contact have time to become available before scene start
ReadinessSpawn Manager action plus CharacterSpawned conditionThe named community entry exists before scene acquisition
EngagementNarrow trigger or interaction owned by the running sceneThe player deliberately reaches the presentation point after scene setup
Scene originscnWorldMarker and scene start nodeScene transform and actor acquisition context
CleanupNamed scene exit, later delay/area, and community deactivationA reviewable lifetime after presentation ends

For actor readiness and scene startup, follow Activation, readiness, and acquisition and Scene entry, exit, and quest handoff.

The native device contract

A quest action and a quest condition are consumers of a device that already exists:

worldDeviceNode
  -> entityTemplate (.ent)
     -> interaction/controller/scanner/workspot components
  -> node-local instanceData RedPackage, when required
  -> stable full NodeRef

questphase
  -> optional questInteractiveObjectManagerNodeDefinition
  -> questPauseConditionNodeDefinition
     -> questObjectCondition
        -> questDevice_ConditionType

The structurally validated focused properties are:

Node or payloadDecisive properties
questInteractiveObjectManagerNodeDefinitiontype: questDeviceManager_NodeType
questDeviceManager_NodeTypeParamsdeviceAction, deviceControllerClass, objectRef, actionProperties, slotName
questPauseConditionNodeDefinitioncondition: questObjectCondition
questDevice_ConditionTypedeviceConditionFunction, deviceControllerClass, functionParameters, objectRef

Keep four meanings separate:

  • Observed in vanilla: the entity template and bound instance package own available interaction, controller, scanner, slot, and workspot behavior.
  • Structurally validated: a device-manager node can send one named action, and a pause condition can wait on one named controller function.
  • Runtime-proven: only the exact action/function/device combinations named in the evidence table have retained in-game results.
  • Experimental: substituting a controller class, action, condition function, device template, or NodeRef creates a new runtime claim.

Player-driven versus quest-driven operation

Use a command node only when the quest itself should send an action. If the player must select a prompt, the graph should normally expose that interaction through the device asset and wait on its resulting controller state or fact. Sending the same action before the wait can complete or retrigger the device without player input.

Structurally validated: the retained generated device shape can omit the action node and connect presentation directly to the device condition.

Experimental: that omission does not prove a particular device exposes a prompt. Prompt availability still belongs to its template, instance package, TweakDB interaction record, slots/workspots, controller state, and placement.

Four bounded device recipes

Interact with a device

Use this smallest topology when one controller function is the completion signal:

objective Active
  -> optional description and marker Active
  -> optional device-manager action
  -> wait questDevice_ConditionType
  -> objective Succeeded
  -> marker Inactive
  -> optional success fact

Structurally validated: this is the exact generated research shape. It does not synthesize the device, controller, prompt, animation, or the state transition consumed by deviceConditionFunction.

Hack an access point

An access-point recipe has two additional owners: the access-point entity must provide the personal-link/minigame behavior, and its placement must leave a usable entry and exit workspot. The quest may enable the device first, but the player-driven route should wait for the native result rather than fire the same operation twice.

Experimental: a generic access-point tutorial remains incomplete until a mod-owned device passes approach, connection, minigame, success, cancel, disconnect, reload, and replay cases on the pinned stack.

Plant or upload an item

The reduced plant topology is:

OrderNative nodeRequired binding
1questJournalNodeDefinitionObjective Active
2questInteractiveObjectManagerNodeDefinitionDevice, controller class, action
3questPauseConditionNodeDefinitionSame device/controller plus completion function
4questItemManagerNodeDefinitionLocal-player item removal
5questJournalNodeDefinitionObjective Succeeded
6questFactsDBManagerNodeDefinitionExact completion fact

Observed in vanilla: comparable plant-item structures occur in sts_std_arr_05_openworld.questphase and the cited Q108 mainframe phase.

Structurally validated: the reduced template uses questAddRemoveItem_NodeTypeParams with nodeType: RemoveAll, a concrete item TweakDBID, the local-player universal reference, silent removal, and no notification. Those exact removal choices are fixture properties, not universal plant semantics.

Deliver to a drop point

A drop point is a live device and a separate navigation target. The retained delivery shape first proves the selected item is present, then sends a ReserveItemToThisDropPoint event to the kiosk and waits for the engine-owned deposit fact.

Event-manager propertyRetained value or binding
managerNameDropPointManager
componentNamecontroller
PSClassNameDropPointControllerPS
objectRefExact native drop-point entity reference
eventReserveItemToThisDropPoint with the item TweakDBID

The reservation event does not create the kiosk, add the item, choose a safe location, or place a useful quest marker. Inspect base\gameplay\devices\drop_points\drop_point.ent; its UI_Interaction, poi_mappin, roleMappin, and main_slot/navQuery offsets are distinct in the retained vanilla template.

Keep the device as the deposit target and place a separate navigation marker at a walkable approach point when the device origin produces a poor GPS route.

Author in WolvenKit

The exact editor layout changes between WolvenKit builds, but the native resource order is stable enough to review deliberately:

  1. Start from a mod-owned project and copy the completed Lab 3 or Lab 5 checkpoint into a new experiment; never edit an installed lab in place.
  2. Add the Quest descriptor and mod-owned sector resources. Declare one quest-prefab root and register every full child NodeRef under it.
  3. For an area, create the trigger node, placement, notifier, and authoritative outline. Reopen and decode the outline after saving.
  4. For a custom device, select an evidence-matched .ent, then author the smallest node-local package or registry contribution required by that comparison. Do not copy a whole unrelated RedPackage.
  5. In the questphase, add the objective and marker state nodes before adding the trigger or device condition. Use an action node only if the quest owns that action.
  6. Bind every local NodeRef to the root that the phase can actually resolve. For an external child, follow the parent/child ownership arrangement proved by its selected reference rather than duplicating roots by habit.
  7. Add explicit success, marker cleanup, inventory mutation, fact, and community cleanup edges. Do not treat an activation node’s Out as proof that the player completed the activity.
  8. Save, reopen, serialize, and inspect the concrete node classes, non-null handles, socket connections, NodeRefs, item IDs, and controller CName values.
  9. Pack only mod-owned resources and ArchiveXL registrations. Extract the archive and compare its payload inventory with the intended project.

The Lab 3 and Lab 5 downloads remain the executable references for world and meeting ownership. This page does not claim that either download contains a custom device, plant interaction, or drop-point recipe.

Clean-save acceptance matrix

Use one untouched save made before the candidate existed, then make separate named child saves. Do not overwrite the only clean control.

CaseWhat it distinguishes
Start outside the areaPremature state-condition or objective activation
Cross the boundary normallyTrigger geometry, notifier, activator, and graph order
Load before crossingRestoration before an edge or state change
Load already inside while the wait is activeEntered versus IsInside behavior for this exact graph
Leave through two directions and elevationsOutline, height, bounds, and real site geometry
Approach the device before and after its sector streamsVisibility versus controller and interaction readiness
Cancel or disconnect mid-hackController recovery and objective non-completion
Complete once, then reloadDuplicate action, reward, item mutation, and marker prevention
Stream away and returnDevice, marker, and community reacquisition
Reinstall against an old saveSave-backed fact, journal, trigger, and persistent-device contamination
Remove the mod and load a disposable copyCleanup/isolation only; never risk the sole clean control

For each test, note the starting save, player position and Z, selected interaction, result fact, inventory change, journal state, and relevant logs.

Troubleshooting

SymptomInspect first
Objective appears but area never completesTrigger notifier, local/full NodeRef chain, activator fields, condition type, outline buffer, and player Z
Leave completes immediatelyGraph order and an already-true IsOutside condition
Meeting starts before the contact existsCommunity activation, CharacterSpawned, broad setup order, and scene acquisition
Marker routes to the wrong placeDedicated marker transform and navigation endpoint; do not assume the trigger/device root is walkable
Device renders but has no expected promptEntity template, interaction component, controller binding, workspot/slot, instance-package CRUIDs, and initial state
Quest cannot find a visible devicePrefab dependency, local/full NodeRef context, controller class, and evidence-required .devices registration
Hack completes before player inputA quest action was sent before a player-driven condition wait
Plant succeeds but item remainsItem TweakDBID, local-player reference, remove mode, quantity, and branch actually reached
Drop point has no deposit choiceReservation event, exact item ownership, native kiosk reference, controller class, and deposit fact
Old files, prompts, or device state returnSave-backed device identity; use a fresh NodeRef or a pre-stream clean save
A packed candidate loads but behaves incorrectlyTreat serialization and runtime validity separately; inspect the producer of the waited state

Continue with Items, shards, files, and scans for inventory and readable-content ownership, and Workspots and interactions for placement and interaction assets.