166 lines
5.1 KiB
Markdown
166 lines
5.1 KiB
Markdown
# Compaction Handoff
|
|
|
|
Current date/time context: 2026-06-20/21, local timezone America/Chicago.
|
|
|
|
## Current Installed State
|
|
|
|
- Latest commit: `64ddf7a Trace GPS provider filters`.
|
|
- Installed RED4ext plugin:
|
|
`Cyberpunk 2077/red4ext/plugins/EdgeWeightGPS/EdgeWeightGPS.dll`.
|
|
- Installed build is read-only. It should not alter route behavior.
|
|
- Plugin log is cleared and empty before the next test:
|
|
`Cyberpunk 2077/red4ext/plugins/EdgeWeightGPS/EdgeWeightGPS.log`.
|
|
- Game is cold as of the latest user message.
|
|
|
|
## New Toolbox Tools
|
|
|
|
The Fedora toolbox `2077` now has:
|
|
|
|
- `rizin` 0.7.4
|
|
- `python3-capstone` 5.0.5
|
|
- `python3-pefile` 2024.8.26
|
|
|
|
If adding Python-only tooling, create/use a venv and maintain `requirements.txt`
|
|
instead of one-off pip installs.
|
|
|
|
## Active Probe Configuration
|
|
|
|
In `red4ext/EdgeWeightGPS/src/Main.cpp`:
|
|
|
|
- `kEnableGpsProviderClassPatch = false`
|
|
- `kEnableGpsProviderClassPatchTrace = false`
|
|
- `kEnableGpsTraceHooks = true`
|
|
- `kEnableGpsQueryLifecycleHooks = false`
|
|
- `kEnableGpsLocalSearchHooks = true`
|
|
- `kEnableRouteUiTraceHooks = false`
|
|
|
|
Active hooks:
|
|
|
|
- `GPSSearch 0x44f054`
|
|
- `GPSRouteProducer 0x44cc7c`
|
|
- `GPSEdgeCost 0x44f838`
|
|
- filtered provider filter `0x44ff68`
|
|
- base provider filter `0x450b08`
|
|
|
|
The filter probe records pass/fail totals by GPS point class and by bits in
|
|
`point + 0x10`, tested against provider masks at `+0x108` and `+0x10a`.
|
|
|
|
## Why This Probe Exists
|
|
|
|
Data and behavior patches tested so far:
|
|
|
|
- Traffic `maxSpeed` patches affected NPC freeway speed but not GPS route
|
|
choice.
|
|
- Lane connection probability patches did not change GPS route choice.
|
|
- Global cost-table patch produced weird routing but mostly confirmed we were
|
|
near the solver, not a clean highway preference knob.
|
|
- Provider class override patches fired correctly but produced no perceptible
|
|
route change after preserving vanilla class `14`.
|
|
|
|
Static disassembly clarified the provider split:
|
|
|
|
- Provider vtable slot `+0x08` is an admissibility filter, not cost.
|
|
- Provider vtable slot `+0x10` is geometric edge cost, multiplying distance by
|
|
`provider[0x08 + class * 4]`.
|
|
- We patched only slot `+0x10` inputs. If slot `+0x08` filtering dominates the
|
|
candidate graph, those cost changes can fire and still not visibly steer GPS.
|
|
|
|
## Important Native Findings
|
|
|
|
GPS pipeline landmarks:
|
|
|
|
- shared query submit: `0x70a42c`
|
|
- query dispatch: `0x70a570`
|
|
- route producer: `0x44cc7c`
|
|
- local search loop: `0x44f054`
|
|
- edge cost: `0x44f838`
|
|
- query result fetch: `0x7094b8`
|
|
|
|
The search loop is A*/Dijkstra-like:
|
|
|
|
- initialize/open list with start node
|
|
- pop best node
|
|
- check destination handle
|
|
- traverse adjacent lane handles
|
|
- call provider filter
|
|
- call provider cost
|
|
- update candidate cost/best predecessor
|
|
|
|
Provider details:
|
|
|
|
- Base provider vtable RVA: `0x2ae6120`
|
|
- Filtered provider vtable RVA: `0x2ae60f8`
|
|
- Base provider constructor `0x451158` fills 64 class multipliers with `1.0`
|
|
and sets mask `+0x108` to `0xffff`.
|
|
- Filtered provider constructor `0x44b9b4` changes vtable to `0x2ae60f8`.
|
|
- Filtered provider commonly has class `14 = 0.05`; preserve this unless
|
|
deliberately testing it.
|
|
|
|
Route result records:
|
|
|
|
- `0x7094b8` output records are 0x28-byte route segment records.
|
|
- `h00` in those records matches `worldTrafficLanePersistent.nodeRefHash`.
|
|
- Route records can be joined to `work/raw-segment-json/all.traffic_persistent.json`.
|
|
- The low byte of route-record `u08` is not the same as the search point class.
|
|
|
|
## Next User Test
|
|
|
|
Ask the user to run the usual routine:
|
|
|
|
1. Launch game.
|
|
2. Hit Continue on main menu.
|
|
3. Hit Space to Continue.
|
|
4. Wait for minimap/GPS to settle.
|
|
5. Open map.
|
|
6. Plot the usual three routes plus one custom highway-ish target.
|
|
7. Close game.
|
|
|
|
Ask for timestamps for:
|
|
|
|
- Space-to-Continue
|
|
- map open
|
|
- each route click
|
|
- game cold
|
|
|
|
After the run:
|
|
|
|
1. Archive the log to `logs/EdgeWeightGPS_provider_filter_probe_<time>.log`.
|
|
2. Inspect `GPSSearch result` lines for `filterPassClasses`,
|
|
`filterFailClasses`, `filterPassMaskBits`, and `filterFailMaskBits`.
|
|
3. Compare filter pass/fail classes to `edgeSrcClasses` and route output
|
|
records. The key question is whether the class/mask filter is selecting the
|
|
graph subset before cost weighting can matter.
|
|
|
|
## Useful Commands
|
|
|
|
Build/install:
|
|
|
|
```bash
|
|
toolbox run -c 2077 ./tools/build_red4ext_shim.sh
|
|
toolbox run -c 2077 ./tools/install_red4ext_shim.sh
|
|
```
|
|
|
|
Clear plugin log:
|
|
|
|
```bash
|
|
truncate -s 0 '/var/home/salt/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common/Cyberpunk 2077/red4ext/plugins/EdgeWeightGPS/EdgeWeightGPS.log'
|
|
```
|
|
|
|
Inspect current plugin log:
|
|
|
|
```bash
|
|
tail -n 240 '/var/home/salt/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common/Cyberpunk 2077/red4ext/plugins/EdgeWeightGPS/EdgeWeightGPS.log'
|
|
```
|
|
|
|
Disassemble with rizin in toolbox:
|
|
|
|
```bash
|
|
toolbox run -c 2077 rizin -q -A '/var/home/salt/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common/Cyberpunk 2077/bin/x64/Cyberpunk2077.exe'
|
|
```
|
|
|
|
## Caution
|
|
|
|
- Do not revert user changes or old untracked logs unless explicitly asked.
|
|
- Commit early/often.
|
|
- Do not install Python packages one by one with pip; use `requirements.txt`.
|