EDGEQUEST / DOCS

Quest formats

Status: agreed with the owner on 2026-10-21 (written 2026-10-17 in Q0). What a quest is made of in the game files, how mods add one, and what must agree across files. Checked against the installed game (2.3x with Phantom Liberty) through redcode-mcp (REDbridge 0.10.0, WolvenKit 9.1.0), ArchiveXL’s source and release notes, the community wiki, and two published quest mods (their file sets and behavior only). Anything not checked is marked unverified.

The files

File Count in the game What it is
.quest 734 A quest’s top graph (questQuestResource). The game’s root is base\quest\cyberpunk2077.quest; Phantom Liberty adds ep1\quest\ep1_standalone.quest (and a second file, cyberpunk2077_ep1_standalone.quest)
.questphase 3,838 A phase: a graph of nodes joined socket to socket (questQuestPhaseResource). Phases nest: a phase node points at another phase file
.scene 8,553 A dialogue or cinematic scene (scnSceneResource): actors, a scene graph (sections, choices, hubs, quest nodes inside the scene), the screenplay (lines and choice options)
.journal 2 The journal tree: quests, contacts and phone messages, codex, shards (onscreens), points of interest and more. Root gameJournalRootFolderEntry, nine folders
Onscreens .json per language Short texts by LocKey: journal titles, objectives, text messages (localizationPersistenceOnScreenEntry: primaryKey, secondaryKey, female and male text)
Subtitles .json 3,800 in en-us Spoken-line text by stringId (localizationPersistenceSubtitleEntry)
Voice-over maps voiceovermap.json and _1 per language (32,767 + 30,184 entries in en-us) stringId to the female and male .wem file
Line lengths stringidvariantlengthsreport.json per language stringId to the female and male line length in seconds
Voice .wem 102,158 in en-us Named <speaker>_<quest>_f_<id in hex>.wem
Lip sync .anims per scene and speaker, <language>.lipmap Animation names f_<ID IN HEX> and m_<ID IN HEX>
World data .streamingblock, .streamingsector People, spots, trigger areas and markers a quest refers to by NodeRef

One id ties a spoken line together

Checked on sq030_01_dam_meetup.scene: for 50 of its 59 lines, the line’s locstringId is also the subtitle stringId, the voice-over map stringId and the line-length stringId; the .wem name and both lip-sync names carry the same id in hex. Choice options use the same locstringId to subtitle join (13 of 14). Why 9 lines have no entries is unverified (likely unvoiced or unused lines).

How a mod adds a quest

Through ArchiveXL’s .xl file, without replacing game files. ArchiveXL documents these keys in its source and release notes rather than its README.

Need .xl key Since Notes
Start a new quest quest.phases: path, parent 1.9.0; parent a .quest from 1.15.0 A phase whose parent is a .quest starts once per save, also in existing saves. ArchiveXL remembers that in a fact. Parent cyberpunk2077.quest is a scope covering the base game and Phantom Liberty roots (1.22.0)
Hook into a game phase quest.phases with input, output, intercept 1.9.0 Input and output are node-id paths plus a socket. Conflicts with other mods hooking the same place are possible
Journal entries journal 1.4.0 A partial journal tree, merged by path. Its root id must match the game’s
Texts localization.onscreens 1.x Merged by secondaryKey
Subtitles, voice, lip sync localization.subtitles, vomaps, lipmaps 1.4.3 One file per language. No key for line lengths (Audioware fills that with a script); whether new lines need one is unverified
World data streaming.blocks 1.4.0 A quest sector with trigger areas, spots and markers; communities from 1.17.0
Scenes, facts none   A scene is reached by path from a phase; facts are set and tested by nodes

New voice needs .wem files made with Wwise 2023.1.14 (the wiki calls this version a hard requirement). New lip-sync animation cannot be made from new audio; WolvenKit can copy a game line’s animation. V has no lip sync.

What must agree across files

This is what quest_check will test.

Link Both ends Status
Phase injection .xl path and parent exist; input and output node paths and sockets exist in the parent ArchiveXL source
Phase node and child phase The child’s input and output socket names match the phase node’s sockets Wiki guide
Journal A node’s journal path (realPath, className, fileEntryIndex) points at an entry in a loaded journal Seen in both studied mods
Texts Every LocKey a journal entry uses exists in the onscreens file of each shipped language Seen; wiki
Dialogue Each line and option id has a subtitle entry; voiced lines also a voice-over map entry and lip sync Checked in the game
Scene actors Section events use performer ids (actorId × 256 + 1), lines use actor ids, debug symbols list them Wiki stub, unverified
Facts Same name in every node that sets or tests it; unique per mod; writes to the game’s own facts flagged Seen in a mod
World Every NodeRef a phase or scene uses is registered by a loaded sector; the phase’s prefab ref matches the block’s Seen in a mod
Images imageId and avatar ids exist as TweakDB records Wiki guide, unverified

Two quest mods studied

  A Judy side quest (Californication, Nexus 7833) Jobs of Night City: Trauma Team (Nexus 7427)
Approach The game’s own quest files A CyberScript datapack: JSON missions run by a CET mod
Files 10: three phases, two scenes, a journal, onscreens, a subtitle file, a world sector 50 JSON scripts, 69 WAV voice lines (Audioware), a vehicle and workspots
How it starts Fills slot 3 of a separate quest framework by the same author (not studied yet) CyberScript’s own triggers
People Reuses Judy’s spawn entries and game animations Spawns NPCs at runtime
Scene A game scene copied and edited CyberScript’s dialogue UI
What to avoid Replaces a whole game subtitle file (conflicts, English only); hand-picked text keys; writes the game’s own facts Depends on a framework that may be broken on the current game (owner)

Saves and live reload

Question What is known Status
Are facts saved? Yes; an unset fact reads 0 Wiki
A new quest after removing and reinstalling the mod ArchiveXL’s start fact stays in the save, so the quest does not start again ArchiveXL source; effect inferred
A save whose running phase file is gone No source Unverified
Reloading archives in a running game RedHotTools reloads archives and asks ArchiveXL to reload; WolvenKit has a hot reload button RedHotTools source
A running phase or scene picking up changes Not documented; reloading then loading an earlier save should work Unverified

Places, map markers and arriving (Q2 study, 2026-10-21)

What a new quest needs to send V somewhere, checked against the game files, the Judy mod and ArchiveXL’s journal source.

Question Finding Status
Where a map marker’s position comes from base\worlds\03_night_city\_compiled\default\03_night_city.mappins (gameMappinResource): 4,337 compiled positions, plus 41 GPS and 5 multi-position entries. Each is keyed by the journal path’s hash (Murmur3, seed 0x5EEDBA5E, of the full path), not by a NodeRef. 4,266 of them match a journal path in the game, so every game marker has a known name, quest and world position Checked in the game
A new quest’s marker Has no compiled position. ArchiveXL fills it in when the game asks, from the NodeRef in reference: that node’s transform plus offset. ArchiveXL’s source also reads “no NodeRef: offset is the world position”, but in the game a marker with no NodeRef shows at the world’s origin: the game never asks ArchiveXL (no “Cooked mappin” line in its log), and ArchiveXL has already cleared the offset. The game’s own static markers all stand on a node (3,257 compiled, 44 without a node and without a compiled position) In-game test 2026-10-22 (ArchiveXL 1.27.4)
What EDGEquest does A place is a game map marker. The quest index keeps each marker’s NodeRef and offset (#mq055_mp_megabuilding_apartment, 0 0 0.5 at V’s door); the new marker uses both. The marker showed at V’s door, with its GPS route, so ArchiveXL resolves the node while V is far away (it reads the node’s transform from the world’s static data) In-game test 2, 2026-10-22
V’s distance to a node (questDistanceComparison) questObjectDistance: a questUniversalRef with refLocalPlayer 1, and nodeRef2, compared with a questValueDistance: 2,130 uses with V, 399 to a node a marker also uses. The ones looked at measure to entities (the vehicle offers’ _mp nodes are worldEntityNodes: the cars); the rest are unchecked. V’s door marker node is in no quest sector: a map spot with no entity. V within 10 m of it never fired. Not used In-game test 2, 2026-10-22; the world sectors
How game quests wait for V at a place V inside a trigger area: questTriggerCondition with isPlayerActivator 1, type IsInside (or Entered), triggerAreaRef the area’s NodeRef. mq055 shows the door marker, then waits until V is inside #mq055_tr_megabuilding_apartment. The Judy mod does the same with its own area The game, the Judy mod
Where trigger areas live In quest prefab sectors (quest_*.streamingsector: 2,404 in Night City, 381 in Dogtown, 2 in the main menu). A node’s path names its prefabs: $/.../#mq000_pr_apartment/#mq000_tr_vs_apartment. Such a sector is loaded only while a running phase lists the prefab in phasePrefabs (questQuestPrefabEntry). 10,221 trigger areas; game phases list the outer prefab (503 aliases) or an inner one (541). Game 2.5 through REDbridge 0.11.0 (2026-10-27): a sector’s node entries (worldCompiledNodeInstanceSetupInfo) no longer carry the path, only globalNodeId.hash: FNV-1a 64 of the full path with every # left out. The streaming block’s descriptor names the sector’s prefab (questPrefabNodeRef, $/.../#mq000_pr_apartment), and a trigger node’s debugName gives its alias ({mq000_tr_vs_apartment}; copies {mws_wat_03_tr_start_}_003 for #mws_wat_03_tr_start_003, though some real aliases keep a doubled _). The hash checks a name only for a node right in its prefab (7,733 of 12,310). 10,795 areas; 5,702 of the 5,723 that game phases wait in are found. Where no phase lists a prefab on the path, the index gives the sector’s own prefab (inferred: it is what loads the sector) The game’s world
What EDGEquest does to arrive Waits until V is inside the place’s trigger area, and lists the area’s prefab in the phase’s phasePrefabs, as the Judy mod lists #dlc6_apart_judy_apartment. The area is the place’s area:, or the one the game’s own quest waits in after showing that marker (2,417 of the 4,266 markers have one). The template uses V’s apartment quest’s #mq000_tr_vs_apartment (prefab #mq000_pr_apartment, which also holds a stash scene object) rather than the romance quest’s (its prefab also holds a bottle) Q2 test 3
GPS distance to a marker (questMappinGPSComparison) Needs no node, only the marker. The game uses it only at 1,000 m and more (courier timers). It did not fire at 10 m in test 1, though the marker there was at the origin, so the test was not fair to it. Not used In-game test 2026-10-22
Subtitles through ArchiveXL An .xl localization: subtitles: entry is loaded as a subtitle map (localizationPersistenceSubtitleMap: entries of subtitleFile and subtitleGroup), like the game’s base\localization\en-us\subtitles\subtitles.json (3,538 entries, group quest for quest scenes, files named after their scene). A file of lines listed there directly fails to load (“Resource … failed to load” in ArchiveXL’s log). Game scenes keep only db_db text in locStore; the text players see comes from the subtitle files In-game test 2026-10-22, ArchiveXL source, the game
Game NodeRefs from a quest’s own prefab A phase lists its world prefabs (phasePrefabs, for example #mq026_pr_smuggler); its trigger areas and spots live there. They are in quest prefab sectors (above). Whether another phase listing the prefab brings them in while their own quest is not running is unverified Q2 test 3
The Judy mod’s places Its own sector, added through streaming.blocks: a trigger area, two AI spots and a static marker, NodeRefs under a game prefab’s path. Its markers point at those NodeRefs with a 0.5 m height offset Seen in the mod
fileEntryIndex in a journal path The position in the path of the entry that owns the file: the quest (quests/minor_quest/mq026_conspiracy/... is 2; the Judy mod’s quests/main_quest/prologue/nq_californication is 3) or the contact (contacts/judy/... is 1). Default -1 Seen in the game and a mod
A scene’s place sceneLocation is a scnWorldMarker: a NodeRef (5,036 scene nodes in the game) or a tag. The tag around_player (156 uses) plays the scene wherever V is, so a scene with V alone or a phone call needs no place Checked in the game

The smallest scenes (Q2 study, 2026-10-21)

A scan of the game’s 4,627 .scene files (4 failed to read): 102 have V as the only actor, 96 of them with a choice. The smallest with lines and a choice is mq017_streetkid_chicken_test.scene (2 lines, 4 options); the smallest phone call is courier_sandbox_holocall_ambush.scene (5 lines). What a scene with V alone holds:

Part Content
Actors playerActors: one scnPlayerActorDef, findInContext, contextual name Player, record Character.Player_Puppet_Base. actors is empty
Graph scnStartNode → scnSectionNode (dialogue line events) → scnChoiceNode → … → scnEndNode. Node ids are small numbers; an output socket is (name, ordinal), and a choice’s option i leaves from socket (0, i)
Lines A section’s scnDialogLineEvent has screenplayLineId, startTime and duration in ms, voParams (Vo_Context_Quest, Vo_Expression_Spoken). A screenplay item’s id is its place in its own list: line k is k*256+1, option k is k*256+2 (all 9,591 lines and 1,897 options in 141 sampled quest scenes, 2026-10-22). The game finds an item by that id: in-game test 3 numbered lines and options with one shared counter, so the options pointed past the end of their list; the choice showed no text and choosing it crashed the game
Text screenplayStore lines and options point at a locstringId; locStore maps it per locale (db_db, en_us, …) to a variant and its text
Performers debugSymbols lists each performer: V’s #player is performer id 1 for actor id 0, so performer = actorId × 256 + 1 holds
Entry and exit entryPoints Start 0 and exitPoints End 0, which become the phase’s scene node sockets. A scene branches its quest by its exits: each exit point names an scnEndNode, and the quest’s scene node has an output socket of the same name. 375 of 392 scene nodes in 300 side and minor quest phases have several outputs (2026-10-23); mq000_03_secret_room.scene has exits try_get_inside, whats_this, dont_believe and End 3. End nodes are Terminating or NonTerminating. EDGEquest makes a go_<beat> exit per beat a choice goes on to
Other Empty workspots, props, effects; an interruptionScenarios default; resouresReferences lists the lip sync anim set; sceneCategoryTag (minorQuests, other, …)
A phone call The caller is a scnActorDef (spawnSet); their lines have isHolocallSpeaker 1 and Vo_Expression_Phone. How the phase opens the call and shows the caller’s portrait is the next study

Choice options

How the game marks an option, from 2,722 options in 579 sampled scenes and the game’s scripts (questCondition.swift, rpgManager.swift), 2026-10-29, game 2.5:

Part Content
Colour scnChoiceNodeOption.type is a gameinteractionsChoiceTypeWrapper whose properties are bits of gameinteractionsChoiceType: QuestImportant 1 (yellow), Blueline 256, Pay 512 (AlreadyRead 2 is set by the engine as an option is chosen). 1,433 options had 1, 1,147 had 0, 72 had 257, 68 had 256
Blue tag bluelineCondition: a questStatsCondition with questLifePath_ConditionType (LifePath_ScriptConditionType, lifePathId LifePaths.Corporate, .Nomad, .StreetKid) or questBuild_ConditionType (Build_ScriptConditionType: buildId PlayerBuilds.Solo (Body), .Netrunner (Intelligence), .Techie (Technical Ability), .Reflexes, .Cool; difficulty an EGameplayChallengeLevel; comparisonType CO_GreaterEq, or CO_Lesser for the option shown to V below it; questAssignment a content assignment whose power level picks the number from the attribute_checks curves); or a questPaymentCondition with PaymentFixedAmount_ScriptConditionType (payAmount) or PaymentBalanced_ScriptConditionType (difficulty, questAssignment), payWhenSucceded 1 takes the money. Both entityRefs are a questUniversalRef with refLocalPlayer 1. The dialogue UI shows a failed blueline with its fail background
Showing it questCondition hides an option when false: 489 options, mostly fact tests. Some lifepath options repeat the lifepath test there (sq012_07a_conclusions.scene)
Other iconTagIds (ChoiceCaptionParts.SitIcon, JackInIcon, …) for action options; isSingleChoice (157); timedParams (timed choices, rare); gameplayAction (Interactions.Inspect)

EDGEquest writes yellow from the story (worked out or main:), a lifepath as both blueline and quest condition, a check with DeviceContentAssignment.Autoscaling (power level Character.ScaleToPlayerLevel), a payment with Pay set too. Unverified until in-game test 8: that another lifepath’s option is hidden, that a failed check or payment shows locked, and that paying takes the money.

Music and sound in quests (Q4 study, 2026-10-24)

A sample of 300 of the 3,837 quest phases and 150 of the 4,627 scenes, read through REDbridge on game 2.31:

Where Class Fields Seen
Phase questAudioNodeDefinition, type questAudioEventNodeType event, isMusic, musicEvents, events, switches, params, objectRef, isPlayer, emitter 143 nodes in 36 phases
Phase type questAudioMixNodeType mixSignpost 144
Phase types questAudioSwitchNodeType (switch, isMusic), questAudioMusicSyncNodeType   2 and 1
Scene scnAudioEvent audioEventName, emitterName, ambientUniqueName, performer in 24 of the 150 scenes

Music is posted as cue events per quest: mus_q001_v_meets_dex_01_START_intro_dialogue_choice, ..._02_take_the_chip to ..._05_STOP_end_silent; mus_q104_drone_flight_01_START and _02_STOP. Sound events are names such as sa_airdrop_package_land; scene events are mostly a performer’s foley (q004_sc_06_v_stands_up). The two switches seen set radio_station. Unverified: whether a cue plays well outside its quest, and what the mix signposts do.

Tools that already edit quests

WolvenKit edits .questphase and .scene as node graphs (since 8.12.1, reworked in 8.17.0): add and connect nodes, a scene editor with a timeline, dialogue import from JSON (9.0.0), copying game lip sync. It has no undo yet. Whether it opens .quest as a graph is unverified. EDGEquest’s place next to it: the story layer, checks across files, and assistants; raw graph editing stays in WolvenKit and REDcode’s CR2W editor.

Sources and credits

ArchiveXL by psiberx (source, release notes, QuestBaseScope.xl); WolvenKit and its wiki; the Cyberpunk 2077 modding wiki (quest guides on facts, sockets, text messages, holocalls, Johnny scenes, custom voice lines, lip sync, shards, communities, NodeRefs); RedHotTools by psiberx; Audioware docs; the authors of the two studied mods.