Add RED4ext release packaging

This commit is contained in:
2026-06-27 04:20:40 -05:00
parent c725e7ebc3
commit 83cf10495e
6 changed files with 188 additions and 96 deletions
+125 -96
View File
@@ -1,108 +1,137 @@
# 2077 Edge Weight Mod
# EdgeWeightGPS
Experimental Cyberpunk 2077 GPS route-weighting mod tooling.
Cyberpunk 2077 RED4ext plugin that improves player GPS routing by penalizing
short-segment churn in the native GPS solver. The current validated default
pushes the GPS toward smoother, higher-momentum driving corridors without
globally forcing every route onto highways.
## Feasibility
## Current Status
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:
Working prototype, validated in-game.
- `worldTrafficPersistentResource.data.lanes`
- `worldTrafficLanePersistent.length`
- `worldTrafficLanePersistent.maxSpeed`
- `worldTrafficLanePersistent.flags`
- `worldTrafficLanePersistent.playerGPSInfo`
- `worldTrafficPersistentLaneConnectionsResource.data`
- `worldTrafficConnectivityOutLane.exitProbabilityCompressed`
- `worldTrafficConnectivityOutLane.isSharpAngle`
- `worldTrafficLanePersistentFlags.Highway`
- `worldTrafficLanePersistentFlags.GPSOnly`
- Route scoring patch: enabled.
- Live tuning file: enabled.
- Current default fixed-edge penalty: `80.0`.
- Highway multiplier: neutral `1.0`; the earlier highway-speed/class
experiments are not part of the playable default.
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:
The active package is a RED4ext plugin only:
```text
Cyberpunk 2077/red4ext/plugins/EdgeWeightGPS/EdgeWeightGPS.dll.disabled
red4ext/plugins/EdgeWeightGPS/EdgeWeightGPS.dll
red4ext/plugins/EdgeWeightGPS/momentum_weights.bin
red4ext/plugins/EdgeWeightGPS/solver_weights.bin
```
## What It Patches
Reverse engineering found the player GPS route search loop around the native
solver relaxation cluster. The useful patch surface is not the script-facing
`RunGPSQuery`/`UpdateGPSQuery` helpers and not the generated traffic
`maxSpeed` fields. The playable hook patches the two ordinary adjacency
expansion sites feeding the native relax/update routine at `0x40ba58`.
The plugin adds a nonnegative fixed cost to ordinary edge expansion. In
practice, this makes many tiny street segments and repeated 90-degree
stair-steps less attractive, while still allowing local roads when they are the
right path.
## Validation Summary
The default `80.0` penalty was selected after live A/B testing:
- `0.0`: vanilla behavior; visibly stair-stepped in highlighted routes.
- `40.0`: partial improvement, but still missed useful smoother corridors.
- `80.0`: best observed result; selected smoother high-speed corridors and
passed drive testing.
- `160.0`: too high; caused bad hairpins/local access and one fallback-style
route.
Drive validation at `80.0`:
- The Dogtown route used a smoother highway corridor and drove cleanly at high
speed.
- Live minimap recalculation still worked after a deliberate detour.
- Claire/Westbrook route also drove cleanly; one blind hill/ramp surprise was
driver unfamiliarity, not a route failure.
See [docs/gps-momentum-field-tests.md](docs/gps-momentum-field-tests.md) for
the detailed test notes, screenshots, and log references.
## Build
Build in the Fedora toolbox:
```bash
toolbox run -c 2077 ./tools/build_red4ext_shim.sh
```
This writes:
```text
Cyberpunk 2077/archive/pc/mod/zz_edge_weight_gps_highway_probability.archive.disabled
build/red4ext/EdgeWeightGPS-mingw64/EdgeWeightGPS.dll
```
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.
## Install Locally
Only install while the game is cold.
```bash
toolbox run -c 2077 ./tools/install_red4ext_shim.sh
```
The install script builds the DLL, installs it into the Flatpak Steam Cyberpunk
2077 folder, and writes the validated defaults:
- `momentum_weights.bin = 80.0`
- `solver_weights.bin = 1.0`
Override the game directory with `CYBERPUNK2077_GAME_DIR` if needed.
## Package
Create a redistributable RED4ext zip:
```bash
toolbox run -c 2077 ./tools/package_red4ext_mod.sh
```
The package is written under `dist/` and contains the `red4ext/` folder layout
expected by the game.
## Live Tuning
`momentum_weights.bin` is a single little-endian float32 and is hot-reloaded
every 500 ms while the game is running.
Useful presets:
```bash
python3 tools/write_momentum_weights.py vanilla # 0.0
python3 tools/write_momentum_weights.py default # 80.0
python3 tools/write_momentum_weights.py overstrong # 160.0, known too high
```
`solver_weights.bin` is still present for older highway multiplier experiments,
but the playable default keeps it neutral:
```bash
python3 tools/write_solver_weights.py vanilla # 1.0
```
## Repository Notes
This repository also contains older experiments and reverse-engineering tools:
- REDmod/archive traffic resource patchers.
- Traffic lane and connection probability patchers.
- Static disassembly helpers.
- RED4ext logging probes.
Those tools are retained because they explain the route-finding system and
document failed approaches, but they are not part of the current playable
package. The important debriefs are:
- [docs/traffic-system-debrief.md](docs/traffic-system-debrief.md)
- [docs/red4ext-logging-shim.md](docs/red4ext-logging-shim.md)
- [docs/gps-routing-research.md](docs/gps-routing-research.md)