# Cyberpunk 2077 Traffic/GPS System Debrief This is based on the public NativeDB RTTI dump, WolvenKit exports from the local Steam install, and the generated `all.traffic_persistent` resource from the Phantom Liberty archive. ## The High-Level Shape Cyberpunk appears to split "navigation" into at least two major domains: - pedestrian/NPC navigation over navmesh resources - vehicle/GPS routing over generated traffic lane resources The public script/native type dump exposes `worldNavigationScriptInterface` and `AINavigationSystem` methods for navmesh path queries, but those are character navigation tools. They are not the car GPS. The car GPS system type exists as `gamegpsGPSSystem`, but its public RTTI surface does not expose planner methods that a REDscript mod can override. That means the practical mod surface is data, not algorithm replacement. The native `gamegpsGPSSystem` likely builds or queries a graph from traffic lane resources, then renders a GPS line from the selected lane path. ## Relevant Game Types The useful RTTI types are: - `gamegpsGPSSystem` - `gamegpsSettings` - `worldTrafficPersistentResource` - `worldTrafficPersistentData` - `worldTrafficLanePersistent` - `worldTrafficLanePlayerGPSInfo` - `worldTrafficLanePersistentFlags` `gamegpsSettings` contains display/refresh settings: - `lineEffectOnFoot` - `lineEffectVehicle` - `fixedPathOffset` - `fixedPortalMappinOffset` - `pathRefreshTimeInterval` - `lastPlayerNavmeshPositionRefreshTimeIntervalSecs` - `maxPathDisplayLength` Those affect GPS presentation and refresh behavior, not edge selection. `worldTrafficPersistentResource` is the key resource type. Its root chunk has `data: worldTrafficPersistentData`, which has: - `lanes: array` - `neighborGroups: array>` Each lane has the actual graph metadata: - `outLanes` - `inLanes` - `outline` - `accumulatedLengths` - `crowdCreationInfo` - `maxSpeed` - `deadEndStart` - `length` - `width` - `area` - `flags` - `subGraphId` - `playerGPSInfo` - `neighborGroupIndex` - `nodeRefHash` - `laneNumber` - `seqNumber` - `isReversed` - `roadMaterials` - `polygon` `playerGPSInfo` contains: - `subGraphId` - `stronglyConnectedComponentId` That strongly suggests the GPS planner has a precomputed connectivity graph and uses connected-component/subgraph metadata to reject impossible paths quickly. ## Resource Location In this install, the important resource is: ```text base\worlds\03_night_city\sectors\_generated\traffic\all.traffic_persistent ``` It exists in both the basegame Night City archive and the Phantom Liberty Night City archive. For a Phantom Liberty install, the EP1 archive version should win: ```text archive/pc/ep1/ep1_1_nightcity.archive ``` WolvenKit can extract, serialize, deserialize, and pack this resource on Linux through `wolvenkit.cli` 8.18.1. ## Lane Flags `worldTrafficLanePersistentFlags`: ```text FromRoadSpline = 1 Bidirectional = 2 PatrolRoute = 4 Pavement = 8 Road = 16 Intersection = 32 NeverDeadEnd = 64 TrafficDisabled = 128 CrossWalk = 256 GPSOnly = 512 ShowDebug = 1024 Blockade = 2048 Yield = 4096 NoAIDriving = 8192 Highway = 16384 NoAutodrive = 32768 ``` The important flags for GPS weighting are `Road`, `Intersection`, `GPSOnly`, and `Highway`. The important flags to avoid touching are `Pavement`, `CrossWalk`, `TrafficDisabled`, and `Blockade`. ## Observed Lane Distribution The local EP1 `all.traffic_persistent` resource contains `33,952` lanes when extracted from the archive's raw compressed segment. Observed `maxSpeed` distribution: ```text all lanes: 1: 12852 15: 12107 10: 5859 17: 3027 14: 96 8: 8 9: 2 4: 1 highway lanes: 17: 2700 15: 164 1: 2 road lanes: 15: 11943 10: 671 17: 327 14: 96 8: 4 pavement lanes: 1: 12848 10: 5188 8: 4 9: 2 4: 1 ``` The values are not real-world mph/kph. They are compact game-scale lane speeds. Because highways are already mostly `17` and normal roads are mostly `15`, a large value like `90` would be reckless. The mod currently uses conservative defaults: - highway speed target: `25` - road speed floor: `15` That changes `2,519` lanes: - `2,429` highway boosts - `90` road floor boosts It leaves pavement/crosswalk/blocked/disabled lanes alone. ## What The Mod Actually Does The mod does not replace the pathfinding algorithm. It edits the traffic graph's lane metadata so the native GPS planner has better cost inputs. If the planner factors `maxSpeed` into traversal cost in the usual way, then a segment with the same physical length but higher `maxSpeed` becomes cheaper. That nudges the native planner toward highways and high-capacity roads without having to hook the planner itself. Conceptually: ```text old cost ~= lane.length / lane.maxSpeed new cost ~= lane.length / patched_lane.maxSpeed ``` The actual game formula is native and not exposed in RTTI, so this is an inference. The inference is supported by the presence of `maxSpeed`, `length`, connectivity data, and GPS-specific lane graph metadata in the same resource. ## Why Not Just Write A New A*? A standalone A* is easy. Integrating it into Cyberpunk's GPS is the hard part. The game already has: - traffic lane connectivity - lane polygons/outlines - player lane matching - destination lane matching - dynamic refresh - minimap/world map rendering - quest mappin target integration - portal/entrance handling - route line effects The script-facing `gamegpsGPSSystem` type does not expose hooks for replacing that pipeline. A custom planner would still need a way to feed its result back into the GPS renderer and route-following systems. Without native RED4ext hooks, that is much riskier than patching the resource data the existing pipeline already consumes. ## Packaging Flow The working flow is: 1. Read the archive index and extract the exact compressed segment for resource hash `3419764573789342681`. 2. Decompress that KARK segment with WolvenKit CLI's Oodle command. 3. Serialize the CR2W resource to JSON. 4. Patch lane `maxSpeed` values. 5. Deserialize the patched JSON back to CR2W. 6. Put the CR2W back under the original resource path. 7. Pack an archive. 8. Place the archive in `archive/pc/mod`. Do not use plain `cp77tools extract` for this resource. In this install, WolvenKit CLI extracted a `9,984,106` byte CR2W, while the stock archive segment declares and decompresses to `10,673,648` bytes. A vanilla control archive built from the smaller extraction crashed during load. A vanilla control archive built from the raw segment reached the game and the GPS worked normally. The generated archive currently contains exactly: ```text base\worlds\03_night_city\sectors\_generated\traffic\all.traffic_persistent ``` ## Risks And Unknowns The main unknown is the native GPS cost formula. If it ignores `maxSpeed`, this patch will not meaningfully change routes. If it uses speed but with caps or category penalties, the effect may be subtle. If it uses `maxSpeed` for both GPS and traffic simulation, the patch may also affect some traffic behavior on highways. The Oodle library was not available inside the toolbox, so WolvenKit packed with its Kraken fallback. A vanilla full-resource control archive loaded in game and GPS worked normally, so the earlier crash was caused by bad extracted data rather than the Kraken-packed archive container. The patch targets the EP1 traffic resource because Phantom Liberty is installed. On a non-PL install, the basegame archive resource would need to be patched instead. ## Future Improvements Better versions of this mod could: - build district-specific presets - increase highway speed to `22`, `25`, or `30` based on playtesting - lower intersection penalties only where highway ramps are misclassified - inspect `lane_connections` to identify ramp/arterial topology - patch `GPSOnly` connector lanes separately - generate a diff report of every changed lane with flags, length, speed, and graph component - ship multiple archives: conservative, strong, and experimental The next practical step is in-game route testing between known bad waypoint pairs, especially cases where vanilla GPS exits highways too early or cuts through surface streets.