SCREECHVR V20: MOVEMENT + BEHAVIOR DETECTION Date: 2026-10-30 Scope: Read-only audit of locomotion, player/hand pose, collision, Tag/Infection, and Photon code plus V18/V19 context. No code or production changes. SUMMARY ScreechVR uses client-run Gorilla locomotion and Photon relays owner-controlled state. PUN 2 without a dedicated game server cannot prove a client’s position, tracking data, collision, reach, or tag claim is honest. A client/Worker can collect evidence and flag anomalies, but movement rules are detection signals, not prevention or ban proof. No numeric movement threshold is justified from source alone: locomotion settings vary by prefab/scene and include speed boosts; normal traces and latency/tracking behavior have not been measured. Use only explicit source invariants where applicable, then calibrate statistical rules from representative sessions. Human review; no permanent auto-bans. 1. RELEVANT SOURCE AND TRUST BOUNDARIES - `! Screech VR/Screech VR/Assets/Scripts/NewGorillaLocomotionScripts/Player.cs` (`GorillaLocomotion.Player.Update`, `StoreVelocities`, `CurrentMaxArmLength`): locomotion is calculated locally from tracked hands/head and collision/sphere casts. Root velocity is derived from position delta / `Time.deltaTime`, with history average; jump impulse is gated by `velocityLimit` and clamped by `maxJumpSpeed` on that client. This is client-side code and can be modified. - Serialized source values: `Assets/Resources/GorillaPrefab.prefab` and `Assets/Prefabs/PhysicRig.prefab` show `maxArmLength=1.5` and `velocityLimit=0.4`. `Player.cs` declares `maxJumpSpeed`, `jumpMultiplier`, `velocityHistorySize`; inspect active prefab/scene overrides before any numeric threshold. `Assets/Scripts/Speed_Boost.cs` sets `maxJumpSpeed` to 15f when boosted and 6.5f when restored, proving one global speed limit would be wrong. - `Assets/Scripts/PhotonVRPlayer.cs` copies local head/hand transforms into the network player representation. No validation is present in this script. The actual sync chain is configured on PhotonView/prefab; do not assume this class itself serializes all transforms. Owner-supplied pose is not server-verified. - `Assets/Scripts/PVP_Player.cs` has `OnPhotonSerializeView` for PVP player state; source-side stream ownership is a Photon controller gate, not a check of legal position or health outcomes. - `Assets/Scripts/GrabbableObj.cs` serializes object position/rotation/velocity; grabbing requests ownership and release transfers it to MasterClient. Those values remain owner-influenced. `AIWanderFollowV2.cs` serializes AI position/ following state from its PhotonView owner. - `Assets/Scripts/Gamemode/TagPlayer.cs`: serialized `touchRadius=0.15f`; `CheckTouch`/`TryTagWithHand` uses `Physics.OverlapSphere(hand.position, touchRadius)`. Local overlap invokes `TagManager.AttemptTag`. - `Assets/Scripts/Gamemode/TagManager.cs`: accepts the local overlap result and sends Tag/Infection state RPCs. There is no authoritative collision/range validation; several RPC handlers lack sender authorization (see V18 report). - Related physics/network code includes `NetworkAi.cs`, `PhotonVRManager.cs`, `PVP_Gun.cs`, `PVP_ROCKET.cs`, `BulletBehavior.cs`, `BulletTrailSync.cs`, `DamagePlayer.cs`, and `WeldGun.cs`. PUN ownership and `IsMine` decide which client writes or interacts; they do not make gameplay outcomes server-truth. 2. DETECTION RULES (PROPOSED; thresholds require measured baselines) For every rule, collect only when the player is authenticated and in a valid session. Each record should include server receive time, sender actor/PlayFab identity binding, scene/mode, source view, sequence, position/pose sample age, Photon RTT/loss if available, client frame delta, tracking-valid flags if exposed, and relevant serialized configuration/version. Do not trust client timestamps as the sole clock. Minimize and retain data only as needed for review. M-01: Sustained root-speed/acceleration anomaly - Inputs: owner root positions at receiver-observed times; derived delta/time; actual active `maxJumpSpeed`, `velocityLimit`, boost/mode state if available; collision/hand contact, frame delta, network age/RTT. - Logic: compute speed/acceleration from multiple fresh samples. Flag only a sustained residual outside empirically measured legitimate envelope for that scene, mode and active movement modifier; separately identify impossible serialized values (NaN/Infinity/out-of-world bounds). Do not use a universal multiplier or take source `maxJumpSpeed` as a complete speed cap: arm-swing displacement and boosts affect movement. - Confidence: low for speed/acceleration alone; medium only when repeated, independent signals agree and samples are fresh. Invalid numeric values are high-confidence malformed input, not proof of cheating. - False positives: legal boosts, jumps, wall pushes, frame stalls, tracking reacquisition, collision resolution, packet batching/jitter and stale snapshots. - Server validation: PUN has none. A backend can flag based on received samples; authoritative prevention requires server-simulated movement/collision. - Response: evidence flag + human review; optionally ignore/reconcile a single malformed snapshot client-side. Never permanent auto-ban. M-02: Teleport/discontinuous displacement - Inputs: sequential positions and receive timestamps, sample gaps, ownership, scene transition/respawn/teleport events and network delay. - Logic: detect a displacement inconsistent with the measured maximum legitimate displacement over that actual elapsed time, excluding known scene loads, respawn, transitions and gaps. Derive envelope from clean captures across modes; do not invent a meters-per-second cutoff now. Flag only repeated discontinuities in fresh samples. - Confidence: low/medium; high only for structurally invalid coordinates or repeated impossible jumps without transition/tracking explanation. - False positives: lost/recovered tracking, low frame rate, long packet gaps, scene/level transitions, respawn, network reconnect, spawn correction. - Server validation: no authoritative position source under PUN. Server can compare claimed samples and flag; cannot know which claim is true. - Response: flag with before/after trace and gap/RTT; human review. M-03: Invalid pose/velocity values - Inputs: root/head/hand positions, rotations, rigidbody velocities, timestamp, stream age and serialization fields. - Logic: reject/flag non-finite values, invalid quaternion norm, impossible encoding/range, or stale/reordered sequence. Derive reasonable world bounds from actual level geometry/spawn bounds before use; no arbitrary global bounds. A stale/out-of-order sample should be discarded, not counted as movement. - Confidence: high for NaN/Infinity or malformed serialization; low for unusual but finite pose without context. - False positives: serialization precision, zero/invalid tracking pose during headset/controller loss, initialization before rig setup. - Server validation: validate schema/ranges at a backend ingestion point, but current Worker has no pose endpoint and PUN Cloud does not inspect game values. - Response: discard malformed sample, record minimal flag; no ban. M-04: Hand reach / controller-pose extension - Inputs: hand and head world positions, hand offsets, active prefab `maxArmLength`, `CurrentMaxArmLength`, tracking validity, sample freshness. - Logic: source locomotion clamps hand-derived positions to `maxArmLength` (serialized 1.5 in identified prefabs). Compare remote hand-head distance to actual active configured limit plus tolerance measured from clean network samples. Flag repeated beyond-limit samples only when tracking valid/fresh. Never assume all scenes/prefabs use 1.5 without checking overrides. - Confidence: medium for repeated violations under valid tracking; low for one sample or missing tracking metadata. - False positives: tracking loss/reacquisition, head/hand transform origin differences, latency, rig initialization, legitimate arm-length overrides. - Server validation: no; the sender controls its own pose. Receiver-side consistency filters can suppress obvious outliers but are bypassable by an owner-modified client. - Response: flag repeated violations; keep legitimate reach responsive. M-05: Interaction-distance / reach abuse - Inputs: hand pose, target collider/position, object bounds, configured `touchRadius`/interaction range and active gameplay mode. - Logic: for Tag specifically, compare submitted target to hand pose using actual `TagPlayer.touchRadius` 0.15f and collision geometry, with empirically measured network tolerance. Reject repeated state requests targeting an actor not within a valid fresh hand overlap, not in room, self, already tagged, frozen, or outside allowed mode/cooldown. For other interactions, inventory each script’s serialized range; do not borrow Tag’s radius as universal range. - Confidence: low/medium under client pose claims; higher for impossible target IDs/state transitions that conflict with room membership or canonical round state. - False positives: stale victim pose, differing collider/hand origin, lag, interpolation, controller tracking glitches, crowded overlaps. - Server validation: backend cannot reconstruct true physical overlap from client claims. MasterClient coordination may reduce accidental conflicts but remains client-authoritative. Dedicated simulation needed to prevent spoofed reach. - Response: deny invalid transition where safely possible, flag repeated attempts. M-06: Invalid Tag/Infection transition - Inputs: requester actor, target actor, mode, current round-state sequence, tagger/infected/frozen state, cooldown, pose sample age and claimed overlap. - Logic: accept only legal state transitions in an ordered round state; validate requester is authorized tagger, target is active/non-self, state permits tag, transition not already applied, and sequence is newer. Keep tag actions idempotent by transition ID. Compare pose distance with configured touchRadius but regard it as supporting evidence only. - Confidence: medium for impossible state/actor/cooldown conflicts; low for distance-only claims. Source confirms current client RPC flow lacks strong sender checks; exact remote exploit depends on accessible PhotonView/runtime. - False positives: late join, simultaneous tags, master migration, stale local infection maps (TagManager state is client-local), network reordering. - Server validation: PUN clients can coordinate via MasterClient/room properties, but that is not trusted. Reconcile canonical sequence on migration; flag only. - Response: idempotent reject/reconcile and human-reviewed flag for repeated abuse. Preserve touch radius and infection mechanics. M-07: Replay/duplicate action abuse - Inputs: action type, actor, Photon view, sequence/transition ID, current round state, receive timestamps, buffer/cached event status. - Logic: use monotonically increasing per-actor/session sequence and idempotency key for meaningful state changes; reject duplicate/stale IDs and illegal repeated transitions. Use set-state instead of toggle RPCs; do not buffer high-frequency movement/transient actions. This detects transport/application duplication, not a malicious client generating fresh IDs. - Confidence: medium when a duplicate transition violates canonical state; low when duplicate is benign retry or ordinary packet behavior. - False positives: legitimate retry after lost response, late join buffered state, reconnect/rejoin, simultaneous clients. - Server validation: receiver/master can enforce consistency only; a malicious actor may send fresh authorized-looking requests. Backend heartbeat not proof. - Response: deduplicate silently, flag persistent patterns; no ban from one repeat. M-08: Latency/tracking-quality qualifier (do not label as cheat rule) - Inputs: Photon RTT/loss/jitter where exposed, sample age/sequence gaps, local frame delta, tracking validity/state, reconnect and scene-load markers. - Logic: downgrade or suppress M-01 through M-07 confidence when data is stale, tracking invalid, frame delta spikes, or network quality is poor. Keep an “insufficient evidence” state rather than increasing risk. - Confidence: it is a data-quality measure, not a cheat detection. - False positives: reported network metrics can themselves be client-influenced; missing tracking telemetry may mean unknown, not invalid. - Server validation: Worker can timestamp receipt and observe request gaps; PUN can expose client/peer stats but does not make them authoritative. - Response: collect minimal diagnostics and human-review context; never punish. 3. IMPLEMENTATION REALITY / SAFE BASELINE - Do not publish numerical speed/acceleration/teleport thresholds yet. Source provides movement parameters, not a complete bound on root displacement under all wall pushes, jumps, boosts, scene variants, frame rates and tracking states. - First establish baseline with opt-in staging traces from normal players, all movement modifiers, each level/mode, normal network conditions and induced lag/tracking interruptions. Capture source-owner and remote-observer views. Compute per-mode distributions and tune conservative thresholds with a false- positive review. Record the exact prefab/scene config and software version. - Under PUN 2, plausible movement and hits can be forged by the owning client. PhotonMessageInfo.Sender/PhotonView ownership can validate which actor sent a message, not the truth of that actor’s position. MasterClient is also a player. - Endpoint/backend telemetry can check malformed schemas, sequence ordering, session identity, impossible state transitions, and repeated anomalies. It cannot securely reconstruct real collisions, controller tracking, or gorilla locomotion from untrusted client reports. - Store flags with session, rule/version, timestamps, mode, data-quality context, and concise samples; limit retention and access. Aggregate corroborating rules; human reviewer records disposition. No automatic permanent bans from movement heuristics. If competitive prevention is required, move the relevant simulation to an authoritative server rather than overclaiming client telemetry. 4. REGRESSION / CALIBRATION PLAN Staging only: 1. Capture ordinary locomotion: arm swings, jumps, wall pushes, crouch/turn, boosts, collisions, all seven levels and Tag/Infection/PVP contexts. 2. Capture tracking/controller loss, recovery, low FPS, packet loss/jitter, reconnect, scene transition and respawn; verify rules lower confidence and do not flag normal sessions as confirmed cheating. 3. Inject synthetic impossible/non-finite pose, stale/out-of-order sequence, repeated tag transition, self-tag, wrong target, excessive hand reach and duplicate action; ensure only the appropriate flag/reject is produced. 4. Verify tag radius from active prefab/config is 0.15f where applicable and arm-length value from the active rig; test overrides and Speed_Boost values (6.5/15f) without global false positives. 5. Compare owner and remote-observer traces with RTT/sample age; never treat a single client-reported position as server truth. 6. Confirm all legitimate Tag/Infection, movement, hand interactions, welding, physics objects, PVP, voice, level transitions and rejoin continue working. 7. Review flagged clean traces before enabling any enforcement; verify no automatic permanent ban path exists. OFFICIAL PHOTON DOCUMENTATION - PUN synchronization and `OnPhotonSerializeView`: https://doc.photonengine.com/pun/current/gameplay/synchronization-and-state - PhotonView ownership & control: https://doc.photonengine.com/pun/current/gameplay/ownershipandcontrol - PUN RPCs and RaiseEvent: https://doc.photonengine.com/pun/current/gameplay/rpcsandraiseevent - PUN Master Client / host migration: https://doc.photonengine.com/pun/current/gameplay/hostmigration No code or production changes. This focused report supplements V18/V19 and does not claim authoritative anti-cheat under PUN Cloud. END OF REPORT