# 2077 Edge Weight Mod

Experimental Cyberpunk 2077 GPS route-weighting mod tooling.

## Feasibility

Cyberpunk exposes a native `gamegpsGPSSystem`, but the current public RTTI dump does
not expose script-callable methods for replacing or overriding the GPS planner. The
useful surfaces are generated traffic resources:

- `worldTrafficPersistentResource.data.lanes`
- `worldTrafficLanePersistent.length`
- `worldTrafficLanePersistent.maxSpeed`
- `worldTrafficLanePersistent.flags`
- `worldTrafficLanePersistent.playerGPSInfo`
- `worldTrafficPersistentLaneConnectionsResource.data`
- `worldTrafficConnectivityOutLane.exitProbabilityCompressed`
- `worldTrafficConnectivityOutLane.isSharpAngle`
- `worldTrafficLanePersistentFlags.Highway`
- `worldTrafficLanePersistentFlags.GPSOnly`

The in-game GPS path is computed natively over generated traffic graph data. A
full replacement planner would require native hooks or patching the game
executable. A feasible REDmod-style mod has to patch generated graph resources
and test which fields the native planner actually consumes.

## Current Implementation

Current active work is a RED4ext shim under `red4ext/EdgeWeightGPS`. It has
confirmed the world-map GPS route path runs through the native async traffic
route pipeline, not the script-facing `RunGPSQuery`/`UpdateGPSQuery` helpers.
The shim can log the query lifecycle, async traffic result handoff, and route
postprocess stages.

A later spatial edge-cost prototype hooked the native local GPS edge-cost
callback at `0x44f838` and successfully changed thousands of candidate edge
costs in live route-producer calls. A controlled in-game inversion test still
produced byte-identical final `GPSQueryResultFetch` route records before and
after flipping highway weights from nearly free to extremely expensive. Treat
that hook as a useful local-search diagnostic, not the final player GPS
weighting surface.

An experimental traffic candidate scorer hook at RVA `0x8d46cc` proved the game
does consult traffic lane flags while selecting route/projection candidates:
highway, road, and pavement flags were visible live and the hook changed their
scores. That detour currently crashes during load, so it is disabled by default
in source and disabled in the local game install as `EdgeWeightGPS.dll.disabled`.
It should be treated as evidence and an RE lead, not a playable mod.

The older data-only tooling remains in the repo for reference:

This repo currently contains WolvenKit-export patchers:

```bash
python3 tools/patch_traffic_lanes.py exported-json-dir patched-json-dir
python3 tools/patch_lane_connections.py all.traffic_persistent.json all.lane_connections.json patched.lane_connections.json
```

`patch_traffic_lanes.py` recursively scans WolvenKit JSON exports for `lanes`
arrays that look like `worldTrafficLanePersistent` data and applies configurable
speed weighting:

- highways get boosted toward a preferred GPS speed in the game's lane scale
- regular roads keep a moderate speed floor
- pavement, crosswalk, and disabled traffic lanes are left alone
- optional non-highway speed caps can make highways more attractive

In-game testing disproved `maxSpeed` as the main GPS routing lever: even highway
speed `120` did not change GPS routes, although freeway traffic visibly moved
faster. Treat speed patches as traffic simulation experiments, not route
weighting.

`patch_lane_connections.py` patches `all.lane_connections` by raising
highway-enter/stay edge probabilities and lowering competing non-highway exits.
That candidate loaded in game, but live testing did not show a GPS routing
change.

After patching, deserialize the JSON back into CR2W and pack the resulting
resources into an archive.

The toolbox now has WolvenKit CLI installed:

```bash
toolbox run --container 2077 bash -lc '$HOME/.dotnet/tools/cp77tools --help'
```

See [docs/tooling.md](docs/tooling.md) for the end-to-end archive build flow.
See [docs/traffic-system-debrief.md](docs/traffic-system-debrief.md) for the
detailed feasibility and traffic graph notes.

## Status

A conservative speed archive, an aggressive speed archive, and a connection
probability archive were built from the local Flatpak Steam Phantom Liberty
install. All `zz_edge` archives are currently disabled in the game folder.

The RED4ext plugin is also currently disabled for normal play:

```text
Cyberpunk 2077/red4ext/plugins/EdgeWeightGPS/EdgeWeightGPS.dll.disabled
```

```text
Cyberpunk 2077/archive/pc/mod/zz_edge_weight_gps_highway_probability.archive.disabled
```

Build outputs are ignored by git. Experimental archives and RED4ext DLL builds
should be enabled one at a time and tested from a cold boot.
