Sector nodes and placement
A placed sector object is not represented by one array entry. In the compact
mod-owned arrangement used for the lab, its type lives in nodes[], its
transform and streaming metadata live in nodeData, and its addressable
identity is registered in nodeRefs. Cooked vanilla sectors show that these
collections are not universally parallel, so review their explicit
relationships before assuming a marker or trigger is complete.
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\worlds\03_night_city\_compiled\default\quest_606b61008df2ba6f.streamingsector
base\worlds\03_night_city\_compiled\default\always_loaded_0.streamingsector
base\worlds\03_night_city\_compiled\default\exterior_-18_28_0_0.streamingsector
base\worlds\03_night_city\_compiled\default\bd21168eed6c6d62.streamingsector_inplace
The placement triad
| Sector structure | Responsibility |
|---|---|
nodes[index] | Concrete node object and type-specific properties, such as a trigger’s outline and notifiers |
nodeData.Data[*] | Placement and cooked metadata; compact authored sectors use NodeIndex to associate a local concrete node |
nodeRefs[] | Registered NodeRef identities that other resources can address |
A focused conceptual excerpt of that compact shape looks like this:
nodes[3]
$type: worldTriggerAreaNode
...type-specific properties...
nodeData.Data[*]
NodeIndex: 3
Position: Vector4(...)
Orientation: Quaternion(...)
Scale: Vector3(...)
Pivot: Vector3(...)
Bounds: Box(...)
QuestPrefabRefHash: $/mod/.../#root/#trigger
nodeRefs[]
$/mod/.../#root/#trigger
This is a property-focused explanation, not a complete serialized resource. The actual CR2W also contains cooked and versioned data that should be preserved through a supported editor rather than recreated from an abbreviated excerpt.
Do not assume the arrays are parallel
In the compact mod-owned shape and the focused vanilla Quest-sector sample,
NodeIndex associates a placement record with a concrete node. Do not infer
that association from the placement row’s position. More importantly, do not
assume every cooked sector keeps the addressed concrete node in the same
local nodes[] array. nodeRefs[] is a registration set, not a guaranteed
one-for-one mirror of either collection.
The focused vanilla Quest-sector extract happens to contain 21 concrete
nodes, 21 placement records, and 21 registered NodeRefs. Its NodeIndex
values are 0 through 20, and its 21 non-zero QuestPrefabRefHash values
match the registered NodeRef set. A focused vanilla AlwaysLoaded extract has
no local concrete nodes, four placement records, and 32 registered NodeRefs;
its placement indices are 3269, 3273, 3277, and 3291. Those two
arrangements are Observed in vanilla. Separately, a retained mod-owned
comparison has six nodes and four registered references and is
Structurally validated in its prior arrangement. Together they show why
equal counts and local array indices in one file are not schema rules.
Transform and bounds
The retained worldNodeData shape includes:
Positionas aVector4;Orientationas a quaternion;Scale,Pivot, andBounds;NodeIndexandQuestPrefabRefHash;CookedPrefabData,MaxStreamingDistance, andUkHash1;- fields exposed by WolvenKit as
UkFloat1andUk10throughUk14.
QuestPrefabRefHash is exposed as a NodeRef string in WolvenKit JSON despite
its name. Use the field’s observed serialized type and value; do not replace
it with a numeric hash because the property name contains “Hash.”
The Uk* names mark an evidence boundary. Their exact meanings are not
established here. Earlier research treated UkFloat1 as a
streaming-range-like value, but that hypothesis is not enough to rename or
explain the field as a universal engine contract. Preserve values from a
known-good, mod-owned seed or an editor-created resource, and isolate changes.
As an authoring approximation, one world coordinate unit is often treated as roughly one metre. That is Experimental for player-facing distance: HUD rounding, navigation routes, collision, slopes, and vertical geometry can all make the experienced distance differ. Calibrate the actual site in game.
Concrete nodes own behavior-specific data
The sector’s concrete node carries properties unique to its type. The focused
vanilla Quest-sector extract includes 11 worldAISpotNode objects, six
worldTriggerAreaNode objects, three worldSplineNode objects, and one
worldVehicleForbiddenAreaNode. Its trigger nodes include area outlines and
quest trigger notifiers. That inventory is Observed in vanilla only for
the focused extract; it is not a complete catalogue of sector node types.
The later triggers chapter will explain AreaShapeOutline, outline height,
points, and questTriggerNotifier_Quest. The later markers chapter will
separate marker placement from journal map-pin
presentation. Type-specific data belongs on the concrete node while placement and identity remain separate.
Inplace resources are another ownership layer
worldStreamingSector can carry localInplaceResource and
externInplaceResource. An external entry can softly reference a
.streamingsector_inplace, whose worldStreamingSectorInplaceContent owns an
inplaceResources[] collection. In the retained serialized view, the embedded
CR2W bodies themselves are represented in top-level Data.EmbeddedFiles.
Observed in vanilla: the retained
exterior_-18_28_0_0.streamingsector references
bd21168eed6c6d62.streamingsector_inplace. That inplace resource has 45
inplaceResources references: 31 .ent, eight .mesh, and six .xbm. Its
top-level Data.EmbeddedFiles has 43 bodies: 31 entEntityTemplate, six
CMesh, and six CBitmapTexture. The unequal counts are another reason not
to infer array pairing without inspecting the actual handles and paths.
Do not confuse that sector-level resource with a node-local
worldEntityNode.instanceData, which can resolve through
entEntityInstanceData to a RedPackage. They are different owners even when
found during the same world investigation. Questphase inplacePhases is a
third, unrelated property domain; a shared word in the name does not make
these resources interchangeable. These observations are an ownership clue,
not permission to copy the extracted resources.
Placement review procedure
Use WolvenKit’s resource and property views so cooked structures remain under editor control. For each mod-owned addressable node:
- Inspect the concrete
nodes[]object and explain every behavior-specific property the example supplies. - In the compact mod-owned sector, find the placement record whose
NodeIndexis authored to associate with that object. - Verify position, orientation, scale, pivot, and bounds against the intended site.
- Verify
QuestPrefabRefHashis the intended full child NodeRef. - Confirm
nodeRefs[]registers that identity when another resource must address it. - Review local and external inplace-resource ownership independently.
- Save and round-trip the resource, then re-open it and repeat the checks.
- Pack, inspect the archive paths, confirm block registration, and test the node in game from controlled saves.
Do not use a shortened text excerpt as an import template. The downloadable Lab 3 project must contain complete mod-owned resources, and its authoring reference must account for every supplied node and resource.
Boundary Check placement contract
Structurally validated: the canonical resource places the checkpoint
marker at (-1000.02, 1497.2208, 8.3). The reach trigger uses a 25-unit radius,
16 outline points, height 12, and base Z 2.3. The leave trigger uses a
110-unit radius, 20 outline points, height 16, and base Z 0.3. Its finite
padded block box encloses both areas and the intended approach.
After changing the trigger geometry, regenerate and inspect
AreaShapeOutline.buffer together with points and height. Test approach
from several directions, foot crossings, fast travel, streaming return, and
reload before and between the boundaries.
Common failures
| Symptom | Inspect |
|---|---|
| A different concrete node receives the transform | The authored nodeData.NodeIndex association; never rely on placement row order alone |
| Quest lookup fails for one placed node | Full QuestPrefabRefHash, nodeRefs[], descriptor root, and questphase local path |
| Area appears offset or rotated | Position, quaternion orientation, pivot, scale, outline-local points, and Z coverage |
| Behavior changes near the site edge | Descriptor box, node bounds, streaming-distance fields, and test approach direction |
| An entity node exists but a referenced template is missing | Check the separate external/local inplace-resource layer and exact depot path |
| Editor save succeeds but runtime behavior is absent | Round-trip structure, archive contents, ArchiveXL registration, external resources, and runtime logs are separate gates |
| Old saves disagree with clean tests | Saved facts, journal state, checkpoints, and persistent world/device state may survive the archive edit |
For Lab 3 acceptance, use a save created before any version of the quest was installed. Derive separate saves before the reach crossing and after reach has succeeded while the player remains inside the outer leave area. A static placement edit may appear after a new process while the quest still follows old saved facts or journal state; neither observation diagnoses the other. The persistent-state chapter defines that boundary.