Document GPS probe handoff
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
# 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`.
|
||||
Reference in New Issue
Block a user