text Untitled 7 views
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