6.2 KiB
Ordinary local camera observation
ERR_OrdinaryLookObserver.c is an opt-in read-only companion to the ordinary input observer, excluded from Workbench builds. It adds no timer, input, camera, actor, menu or action mutation. The 183944 ordinary Chat run passes native compilation, actual camera response/return and subsequent keyboard delivery, with zero captured errors and verified cleanup. Response was 1.935°, return error 0.149°, over 2101 ms of native samples. The earlier 183353 review corrected a checker timing assumption without changing that run's failed verdict. Policy tests alone do not establish native mouse response.
Enable -errOrdinaryLookObserve <nonce> only alongside the identical -errOrdinaryInputObserve <nonce> and ordinary Core/Chat selection. It also requires a local server in RplMode.None, a non-console process, and a canonical active PRISON participant. The existing observer supplies the original clock start and sample index, so no new observation lifetime is created.
Integration
After the existing observer increments m_Samples and validates the ordinary SAMPLE (without changing its schedule), invoke:
ERR_OrdinaryLookObserver.Sample(m_Mode, m_World, m_Controller, m_Actor,
m_Nonce, m_Start, m_Samples, now);
There is no additional cleanup callback. One process-wide attempt pins the original mode, world, controller, actor, roster life/account and player camera. It stops permanently on context loss, menu opening, changed explicit opt-in, clock/sample violation or invalid pose. When the main observer stops calling it, it performs no work. Restarting a mode cannot adopt another camera under the old attempt.
Exact native API basis
Installed vanilla sources used:
scripts/Game/generated/Player/PlayerController.c:GetPlayerCamera()returns the controller'sPlayerCamera.scripts/Game/generated/Camera/CameraBase.c:22:GetWorldCameraTransform(out vector mat[4])is documented as the current camera world transformation. Its forward basis[2]and position[3]supply the actual view; the body is not used as a view approximation.scripts/Game/generated/ChimeraGame.c:27andgenerated/Camera/CameraManager.c:19: the active manager'sCurrentCamera()must equal the exact pinned controller camera, before and after native reads.- Actor
GetTransform()[2]provides the separately logged body facing. Thebodyposition comes from the exact pinned actor’sGetOrigin(), matching the ordinary INPUT and GATE observers. Camera position still comes from the native camera transform[3]. Neither camera transform application nor setters are called.
All entity/world/controller/roster bindings are rechecked per sample. Any top menu blocks observation, including inventory. The camera's world must match the original world. Basis lengths must be finite and within 0.5–2 before normalization; all emitted vector components and native turn inputs must be finite and bounded. Indices must be contiguous from 1, at most 450, with a monotonic real clock still less than 45 seconds from the original input-observer start. Pose sampling may miss short-lived input deltas between ticks; measured view response remains necessary.
Log contract
The first valid sample emits one basis declaration followed by the sample:
ERR LOOK OBSERVE: run=N sample=1 real=T BASIS native-player-camera-world-transform
ERR LOOK OBSERVE: run=N sample=1 real=T SAMPLE direction=<x,y,z> camera=<x,y,z> body=<x,y,z> bodyForward=<x,y,z> turn=<right,up,0>
direction and bodyForward are normalized. camera and body are distinct world positions. turn contains native CharacterTurnRight and CharacterTurnUp values; it does not assert that a helper sent input. Nonce/index/real clock match the corresponding ordinary input SAMPLE. No account identifier is logged.
On invalidation, exactly one terminal record is emitted:
ERR LOOK OBSERVE: run=N sample=I real=T CANCELLED menu-opened
Other reasons are explicit-scope-lost, original-binding-changed, sample-or-clock-bound, native-camera-or-player-context-lost and invalid-native-pose. No sample follows cancellation. The main input observer continues independently. Thus normal inventory opening after the completed look proof may legitimately cancel look telemetry; proof verification must examine only the agreed interval before the first W movement, not treat later menu cancellation as failure of an already-observed look response.
The external helper must require fresh stable native baseline samples, actual direction change after its bounded positive relative input, and a fresh return near baseline after its negative input. It must independently retain the existing stationary-body, private-display/window/focus ownership and input-release checks. This utility issues no authorization to send input and claims no gameplay, escape, multiplayer or performance qualification.
Logical body-position correction (native rerun pending)
The ordinary approach run whose session started 2026-09-19 19:07:07 refused its live join at sample 180 after normal forward input: actor transform translation and actor GetOrigin() differed by approximately (0.04, -0.001, -0.03) metres, just beyond the existing 0.05m cross-API check. INPUT and GATE, which both use GetOrigin(), agreed. This establishes a telemetry API mismatch; it does not establish a teleport or a completed approach. Preserve that run’s failed result.
The staged correction logs body from the same pinned actor’s GetOrigin() instead of GetTransform()[3]. Body-facing [2], actual camera position/direction, identity checks, finite-value guards, original observation lifetime and all validation tolerances remain unchanged. A focused actual-method test deliberately gives the transform and logical origin different translations, verifies the emitted body equals only GetOrigin(), and verifies facing and view still use their original native sources. A nonfinite logical origin refuses the sample. This source/test correction requires a new ordinary native run before qualification; it changes no gameplay state or input.