Log mappin slot RVAs
This commit is contained in:
@@ -17,11 +17,14 @@ and lane connection probabilities. Live tests have not supported that:
|
||||
- probing the obvious `TrafficSystem_Pathfinding` and
|
||||
`StartPathfinding`/`StopPathfinding` string-xref wrappers did not fire during
|
||||
deliberate world-map route plotting
|
||||
- probing the obvious `RunGPSQuery` and `UpdateGPSQuery` helpers also did not
|
||||
fire during deliberate world-map route plotting
|
||||
|
||||
The stronger current theory is that player GPS route selection goes through a
|
||||
native GPS/mappin query path, with traffic data used by traffic simulation and
|
||||
possibly as an input to cooked GPS data, but not as a live route-cost graph that
|
||||
can be steered by simple resource weighting.
|
||||
native world-map mappin tracking path, which then updates native GPS state
|
||||
downstream. Traffic lane data is still likely used somewhere in the final route
|
||||
line, but the tested `maxSpeed` and lane-exit probability fields are traffic
|
||||
simulation inputs, not the live player-GPS edge-cost knobs.
|
||||
|
||||
## Static GPS Query Candidates
|
||||
|
||||
@@ -50,8 +53,8 @@ the wrapper.
|
||||
`UpdateGPSQueryHelper` appears related but takes a request type and target. Its
|
||||
return value is also used as a success flag.
|
||||
|
||||
The next RED4ext probe should hook these helpers with return-value-preserving
|
||||
signatures, not the registration thunks:
|
||||
These helpers were hooked with return-value-preserving signatures, not the
|
||||
registration thunks:
|
||||
|
||||
```cpp
|
||||
bool RunGPSQueryHelper(void* this_, void* from, void* to, void* debugText,
|
||||
@@ -61,9 +64,50 @@ bool UpdateGPSQueryHelper(void* this_, uint32_t requestType, void* target,
|
||||
```
|
||||
|
||||
These signatures are inferred from the wrapper call sites and Windows x64
|
||||
calling convention. If either helper fires exactly when a map destination is
|
||||
selected, it is a much better path into the actual route computation than the
|
||||
traffic-pathfinding probes.
|
||||
calling convention.
|
||||
|
||||
Live result: neither helper fired when plotting multiple world-map routes. They
|
||||
remain useful static landmarks for GPS-like script APIs, but they are not the
|
||||
world-map destination tracking path being exercised by normal player route
|
||||
selection.
|
||||
|
||||
## Mappin Tracking Handoff
|
||||
|
||||
The current native lead is the script/native mappin tracking path:
|
||||
|
||||
```text
|
||||
TrackMappin string rva: 0x2e82c30
|
||||
TrackMappin registration xref: 0x1843eb8
|
||||
TrackMappin wrapper rva: 0x27c4ab4
|
||||
TrackMappin core rva: 0x27c11d0
|
||||
Mappin system resolver rva: 0x02bb840
|
||||
|
||||
SetMappinTrackingAlternative string rva: 0x2c672e0
|
||||
SetMappinTrackingAlternative registration xref: 0x121c194
|
||||
SetMappinTrackingAlternative wrapper rva: 0x1246794
|
||||
```
|
||||
|
||||
`TrackMappinCore` resolves a native mappin system through `0x02bb840`. The
|
||||
resolver loads an object pointer from `this + 0xa8`, reads the mappin-system
|
||||
type/singleton global at `0x342f138`, and calls vtable slot `0x08` on the
|
||||
object it loaded.
|
||||
|
||||
Once the native mappin system is resolved, `TrackMappinCore` branches on whether
|
||||
the supplied mappin handle is null:
|
||||
|
||||
- non-null tracked mappin: call resolved system vtable slot `0x220`
|
||||
- null tracked mappin: call resolved system vtable slot `0x228`
|
||||
|
||||
That looks exactly like "set tracked mappin" versus "clear tracked mappin". The
|
||||
installed RED4ext probe now resolves this system at runtime, logs the concrete
|
||||
vtable addresses for slots `0x220`, `0x228`, `0x250`, `0x2e0`, `0x368`, and
|
||||
`0x3a8`, and attaches temporary hooks to slots `0x220` and `0x228`. The next
|
||||
in-game route-plotting run should therefore give directly disassemblable RVAs
|
||||
for the concrete mappin-system methods that receive the tracked destination.
|
||||
|
||||
`SetMappinTrackingAlternative` parses two script arguments and calls vtable slot
|
||||
`0x418` on its receiver. It is probably related to alternate tracking behavior,
|
||||
but static disassembly has not yet shown it to be the main route planner.
|
||||
|
||||
## The High-Level Shape
|
||||
|
||||
@@ -78,9 +122,10 @@ navigation tools. They are not the car GPS. The car GPS system type exists as
|
||||
`gamegpsGPSSystem`, but its public RTTI surface does not expose planner methods
|
||||
that a REDscript mod can override.
|
||||
|
||||
That means the practical mod surface is data, not algorithm replacement. The
|
||||
native `gamegpsGPSSystem` likely builds or queries a graph from traffic lane
|
||||
resources, then renders a GPS line from the selected lane path.
|
||||
That means the practical mod surface is not yet settled. The data-only surface
|
||||
has been tested and appears insufficient. The next credible surface is a
|
||||
RED4ext hook in the native mappin/GPS handoff, after the concrete target
|
||||
function has been identified.
|
||||
|
||||
## Relevant Game Types
|
||||
|
||||
@@ -228,8 +273,8 @@ pavement lanes:
|
||||
|
||||
The values are not real-world mph/kph. They are compact game-scale lane speeds.
|
||||
Because highways are already mostly `17` and normal roads are mostly `15`, a
|
||||
large value like `90` would be reckless. The mod currently uses conservative
|
||||
defaults:
|
||||
large value like `90` was expected to be reckless. The first conservative
|
||||
archive used:
|
||||
|
||||
- highway speed target: `25`
|
||||
- road speed floor: `15`
|
||||
@@ -241,15 +286,16 @@ That changes `2,519` lanes:
|
||||
|
||||
It leaves pavement/crosswalk/blocked/disabled lanes alone.
|
||||
|
||||
## What The Mod Actually Does
|
||||
## What The Data Archive Experiment Did
|
||||
|
||||
The mod does not replace the pathfinding algorithm.
|
||||
The data archive experiment did not replace the pathfinding algorithm.
|
||||
|
||||
It edits the traffic graph's lane metadata so the native GPS planner has better
|
||||
cost inputs. If the planner factors `maxSpeed` into traversal cost in the usual
|
||||
way, then a segment with the same physical length but higher `maxSpeed` becomes
|
||||
cheaper. That nudges the native planner toward highways and high-capacity roads
|
||||
without having to hook the planner itself.
|
||||
It edited the traffic graph's lane metadata so the native GPS planner might have
|
||||
better cost inputs. The original hypothesis was that if the planner factored
|
||||
`maxSpeed` into traversal cost in the usual way, then a segment with the same
|
||||
physical length but higher `maxSpeed` would become cheaper. That should have
|
||||
nudged the native planner toward highways and high-capacity roads without
|
||||
hooking the planner itself.
|
||||
|
||||
Conceptually:
|
||||
|
||||
@@ -258,9 +304,9 @@ old cost ~= lane.length / lane.maxSpeed
|
||||
new cost ~= lane.length / patched_lane.maxSpeed
|
||||
```
|
||||
|
||||
The actual game formula is native and not exposed in RTTI, so this is an
|
||||
inference. The inference is supported by the presence of `maxSpeed`, `length`,
|
||||
connectivity data, and GPS-specific lane graph metadata in the same resource.
|
||||
Live testing disproved this as a player-GPS lever. The patched value clearly
|
||||
reached the game because traffic speed changed, but player GPS route choice did
|
||||
not.
|
||||
|
||||
## Why Not Just Write A New A*?
|
||||
|
||||
@@ -330,11 +376,11 @@ per lane. Each row has `inLanes` and `outlanes`. Each outgoing connection
|
||||
contains `laneIndex`, `exitProbabilityCompressed`, `isSharpAngle`,
|
||||
`nextLaneEntryPosition`, and `thisLaneExitPosition`.
|
||||
|
||||
There is still no explicit edge cost field. The current best data-only test is
|
||||
to patch `exitProbabilityCompressed`: strongly favor road/GPSOnly/highway
|
||||
connections that enter or remain on highways, and lower competing non-highway
|
||||
exits. A prepared experimental archive changes 145 outgoing connection
|
||||
probabilities across 136 lanes.
|
||||
There is still no explicit edge cost field. A follow-up data-only test patched
|
||||
`exitProbabilityCompressed`, strongly favoring road/GPSOnly/highway connections
|
||||
that enter or remain on highways and lowering competing non-highway exits. That
|
||||
archive changed 145 outgoing connection probabilities across 136 lanes. It also
|
||||
loaded and ran, but it did not change the tested player GPS routes.
|
||||
|
||||
The Oodle library was not available inside the toolbox, so WolvenKit packed with
|
||||
its Kraken fallback. A vanilla full-resource control archive loaded in game and
|
||||
@@ -349,15 +395,17 @@ instead.
|
||||
|
||||
Better versions of this mod could:
|
||||
|
||||
- build district-specific presets
|
||||
- patch `all.lane_connections` probabilities around ramps and highway exits
|
||||
- inspect `GPSOnly` connector lanes separately
|
||||
- compare route output with probability-only archives enabled
|
||||
- hook the native destination-tracking handoff after the concrete mappin-system
|
||||
method is identified
|
||||
- trace the downstream GPS update that consumes the tracked mappin
|
||||
- locate any native or baked edge-cost data not exposed in RTTI
|
||||
- inspect `GPSOnly` connector lanes if a later native trace proves they are
|
||||
consumed by the player GPS
|
||||
- build district-specific presets if a real data-cost surface is found
|
||||
- generate a diff report of every changed lane with flags, length, speed, and
|
||||
graph component
|
||||
- ship multiple archives: conservative, strong, and experimental
|
||||
- ship multiple archives only if a data patch is proven to affect routing
|
||||
|
||||
The next practical step is in-game route testing between known bad waypoint
|
||||
pairs, especially cases where vanilla GPS exits highways too early or cuts
|
||||
through surface streets.
|
||||
The next practical step is one more in-game route-plotting run with the current
|
||||
RED4ext mappin-system slot probe installed. If it logs concrete slot RVAs, the
|
||||
next static-disassembly target is no longer a guess.
|
||||
|
||||
Reference in New Issue
Block a user