Torso: the TWIST goes LIVE -- electrical watchdog chain, centered crosshair, coherent controls (task #57/#58)
The MadCat torso twists, the view turns with it, and targeting follows. Three reconstruction fronts closed: THE ELECTRICAL WATCHDOG CHAIN (why the torso never powered up): - PowerWatcher::UpdateWatch reconstructed (@004b181c, the REAL registered Performance -- PTR @0050f5fc; Ghidra missed the fn start): the watchdog MIRRORS the watched subsystem's electrical level (+0x278), brownout downgrade when gen output <= minVoltage% x rated. @004b1804 relabeled ResetToInitialState (slot 10) -- the old "Simulation" tag was wrong. - The factory watcher-CONNECT pass reconstructed (vtable slot +0x38, @004aee2c/@004b1a40 byte-identical, recovered from raw exe bytes): watchedLink.Add(roster[watchedSubsystem]) on the master node. Was the SubProxy::Start() no-op -- every watchdog sat at 0 forever. - MinVoltageScale = 0.01 (a 10-byte x87 literal @0x4b1924; was 1.0f = permanent brownout) and PowerWatcher's Derivation chains its REAL base HeatWatcher (the HeatableSubsystem stand-in broke IsDerivedFrom for the whole Torso/Searchlight/ThermalSight family). - KB correction swept: derivation tag 0x50e604 = HEATWATCHER (not "HeatSink"); the btl4gaug heat-widget gate now tests it via the BTIsHeatWatcher bridge. THE CROSSHAIR (task #58 forensics, 6-agent workflow + live probes): - The VIEW is TORSO-MOUNTED: jointtorso -> jointeye -> siteeyepoint in every twist-capable .SKL; the camera + canopy ride the same hinge subtree through HingeRenderable's live matrix-stack compose -- ALREADY WORKING in the port. The crosshair stays screen-centered (center IS the boresight); the twist reads on the tape carets/compass/radar. - The real bug was the port's gBTAimX = tan(twist) slew (the falsified "body-mounted view" model): the camera already carried the twist, so the crosshair counter-slid to hull-forward and the fire ray with it. Deleted; the pick ray inherits the twist from the yawing eye basis. - Two instrumentation traps documented (chase-eye-as-default-camera, BT_FORCE_TORSO clobbering real joints -> the hook now only fills unresolved ones); an over-correcting explicit eye compose was added on those false readings and retired the same day. CONTROLS + REPLICATION: - Q/E spring-center on release (the axis is a twist-RATE demand; the old hold-deflection model drifted forever); X also zeroes the axis and pulses the authentic torso Recenter (@004b6918). M cycles control mode via the real CycleControlMode body. - Torso update-record DIRECTION fixed: engine truth is Write=serialize / Read=apply; @004b6a78 is the READ (was mislabeled Write) and the missing WRITE @004b6a1c recovered from raw disasm (recordLength 0x1C, twist/vel/rate at +0x10/14/18) -- kills the replicant's 0xCDCDCDCD -140-degree ghost twist. - Marching-ghost desync: 4 Standing-case guards zero stale reverse cycleSpeed (negative cadence passed the <= ZeroSpeed stop gate). - Kill credit rerouted to the OBSERVED killer (lastInflictingID -> killer's player link) -- kills count, target K/D populates. KB: subsystems.md (watcher chain), multiplayer.md (record direction), combat-damage.md + gauges-hud.md + cockpit-view.md (torso-mounted view re-correction), decomp-reference.md (new addresses + tag fix), open-questions.md (dead capability-roster loops 2-4, snapshot CD read). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
065c114590
commit
02cdfd6576
@@ -237,6 +237,30 @@ engine/port member. Wire sizes verified live (0x14/0x20/0x2c/0x78). Key mechan
|
||||
A TU-local stub type forced the `BTMapperSpeedDemandRaw(void*)` bridge (mech.cpp carries a local
|
||||
`struct MechControlsMapper` recon stub — typed cross-TU signatures mangle differently).
|
||||
|
||||
## Subsystem update-record DIRECTION + the Torso pair (task #57, 2026-07-13) [T0/T1]
|
||||
|
||||
**Engine semantics [T0 SIMULATE.cpp:270-297]: `WriteUpdateRecord(record, model)` PRODUCES the
|
||||
outgoing record from the object (master serialize; base sets `recordLength=sizeof`, stream
|
||||
advances by `recordLength` — variable-length records are the mechanism); `ReadUpdateRecord(record)`
|
||||
APPLIES the record into the object (replicant).** The names read backwards — do not flip them.
|
||||
Base fns in every subsystem vtable: slot 6 = 41bd34 (Read/apply), slot 7 = 41c500 (Write/produce,
|
||||
3 args).
|
||||
|
||||
- **Torso pair:** slot 6 `@004b6a78` = `ReadUpdateRecord` (apply: lastUpdateTime clock stamp +
|
||||
twistAtUpdate/twistVelocity/twistRate ← record +0x10/14/18). Slot 7 `@004b6a1c` =
|
||||
`WriteUpdateRecord` — **Ghidra missed the function start**; raw-disasm recovery: chains base,
|
||||
sets `recordLength=0x1C`, writes currentTwist/twistVelocity/twistRate → +0x10/14/18, snapshots
|
||||
`twistAtUpdate = currentTwist`.
|
||||
- **The bug this fixed:** the old recon had the APPLY body on the WRITE virtual (and no Write at
|
||||
all) — the master consumed its own uninitialized stream buffer (0xCDCDCDCD → twistAtUpdate =
|
||||
−4.316e8) and never serialized twist; the replicant MadCat pinned at −140° (the "torso ghost
|
||||
twist"). With the pair correct the replicant tracks `targetTwist = twistAtUpdate +
|
||||
twistRate·elapsed` cleanly (cur=0 when master still). [T2 live]
|
||||
- **Residual (authentic):** the initial full-state snapshot record does NOT carry the torso
|
||||
extras; the replicant's blind +0x10 read can pick up 0xCD fill ONCE at spawn. The binary does
|
||||
the same read; the twist clamp contains it (on the fixed-torso BLH it pins to ±0.01° —
|
||||
invisible). First real twist record overwrites it.
|
||||
|
||||
## Remaining (P6 phase 4 / Phase 7)
|
||||
The pod-LAN config (real IPs, bare-IP pilot entries); update-record velocity sourced from the body-channel
|
||||
projection (above). See [[open-questions]]. [T3]
|
||||
|
||||
Reference in New Issue
Block a user