Add live-tunable GPS solver highway weight

This commit is contained in:
2026-06-26 23:33:20 -05:00
parent 3fa723c3cc
commit 92287bd8e1
12 changed files with 363 additions and 43 deletions
+46 -11
View File
@@ -2,6 +2,41 @@
Current date/time context: 2026-06-26, local timezone America/Chicago.
## 2026-06-26 Confirmed Solver-Cost Patch
- We have unequivocally found the player GPS route-cost lever.
- The crashing RED4ext detour on `0x40bb40` has been replaced by an inline
patch at the road-tail block `0x40bb98`. The patch preserves vanilla
`node+0x93` behavior, checks `node+0x88 & 0x4000` for `Highway`, and then
multiplies highway lane cost by a tunable float.
- This inline patch avoids the register-clobber crash from the C++ detour.
Static disassembly showed the optimized caller reusing volatile state after
calling the tiny vanilla multiplier helper.
- The proof build used highway multiplier `0.35` and visibly changed player
map routes. It also caused over-aggressive behavior, including a bad custom
pin hairpin around the city-center roundabout, proving the hook is real but
that `0.35` is too low.
- The vanilla A/B build disabled only the inline multiplier patch and restored
obviously different route choices. User confirmed the custom pin returned to
the straight city-center roundabout route, while the `0.35` build took the
wrong hairpin.
- Current installed build enables the inline patch with default highway
multiplier `0.80` and polls
`red4ext/plugins/EdgeWeightGPS/solver_weights.bin` every 500 ms. The file is
exactly one little-endian float32 highway multiplier.
- The inline patch is deliberately broad across the vanilla road-tail branch:
reaching `0x40bb98` already means vanilla selected road-style modes `0/2/4`,
so we do not hard-gate on `solver+0xc4 == 2`. This avoids creating a manual
drive/autodrive disparity. Pedestrian mode `1` uses a different vanilla
branch and is not changed by this road-tail patch.
- Preset writer:
`tools/write_solver_weights.py`. Preset binaries live in
`presets/solver_weights/`: `vanilla`, `mild`, `default`, `strong`,
`proof-highway-cheap`, and `highway-expensive`.
- Evidence logs:
`logs/EdgeWeightGPS_inline_highway035_changed_routes_1449.log` and
`logs/EdgeWeightGPS_vanilla_ab_2120.log`.
## 2026-06-26 Static Update
- Installed RED4ext state is safe: the game plugin directory contains
@@ -110,19 +145,19 @@ Important caveat:
- Older DLLs are preserved disabled as:
`Cyberpunk 2077/red4ext/plugins/EdgeWeightGPS/EdgeWeightGPS.dll.disabled`
and `EdgeWeightGPS.dd1423b.dll.disabled`.
- Source defaults now enable the full async solver multiplier hook:
`kEnableGpsMultiplierHooks = true`.
- The current behavior patch is deliberately narrow and diagnostic:
`DetourGpsNodeMultiplier` hooks native `0x40bb40`, applies only when
`job+0xc4 == 2` (driving route mode), reads lane/node flags from
`node+0x88`, and multiplies vanilla node edge cost by highway `0.35`,
GPSOnly `1.10`, pavement `1.25`, and all other flags `1.0`.
- `0x40bb00` auxiliary/reverse multiplier is hooked only for signature logging;
it is not patched yet.
- Source defaults enable the inline road-tail patch:
`kEnableGpsNodeMultiplierInlinePatch = true`.
- Source defaults do not enable the old full-function detour:
`kEnableGpsMultiplierHooks = false`.
- Current behavior patch is the inline `0x40bb98` code-cave patch. It preserves
vanilla road cost except for highway lanes, whose cost is multiplied by the
current `solver_weights.bin` float. Installed default is `0.80`.
- `solver_weights.bin` lives beside the DLL and is hot-polled every 500 ms.
- The plugin log was truncated immediately before installing this build.
- Latest archived test log:
`logs/EdgeWeightGPS_spatial_inversion_no_route_change_1845.log`.
- Game is cold as of the latest user message.
`logs/EdgeWeightGPS_vanilla_ab_2120.log`.
- A cold restart is required after installing a new DLL; changing
`solver_weights.bin` after that is hot-reloaded.
## 2026-06-26 Full Async Solver Findings