Trust model notes
Evidence level for everything below: static-analysis image (analysis_with_filtered_partial_unwind.exe) plus the older restored image; virtualized dispatch not removed; capstone/pefile reading only; no runtime observation.
From the hit-registration teammate (round 23 B)
bClientPredictivedefaults to true: the nativeFWDProjectileStatsconstructor stores 1 (0x699E212). The 17 explicit cooked values are all false (rockets, artillery, missiles, drone). Every other round omits the field and so defaults to true (9mm, 5.45, 5.56, 7.62 variants, .50 Cal, 12g, buckshot, arrows and others).- Hit handler
0x6B73E90branches on net mode (3 = client, derived from0x3CAB0A0GetNetMode). On a client, a projectile with the flag set and a local controller forwards itsFWDProjectileHitDataviaServer_ValidateClientHit(sender0x69E86F0, call sites0x6B740D9,0x6B74D6E) and does not build damage itself. On the server it builds damage via0x6B725B0and0x6B717C0, skipping when!IsServerOwned && !controllerIsLocal && bClientPredictive(0x6B74251-0x6B74271). So for a remote client’s predictive bullet the server’s own simulation does not apply damage. Server_ValidateClientHitimplementation (vtable slot0x500ofUWDProjectileProxyComponent=0x6B74770) looks like a 17-byte leaf that only freesHitData.CustomHitResults(+0x100) and returns; exec thunk0x69E93E0copies the 0x238-byte record from the wire. CAVEAT: the bytes at0x6B74761-0x6B7476Flook like prologue fragments and0x6B74781onward decodes as nonsense; identical in both images. May be a protection-layer artifact. Treat as unconfirmed.- No consumer found for
ValidClientProjectileHitData(inst+0x2F8) orbFailedHitValidation(inst+0x310) in0x6B00000-0x6BD0000,0x6F20000-0x6F50000,0x76C0000-0x76E2000.Client_ValidateClientHit_Response(0x6B72370) only walks a global listener list. - Client-supplied fields, if the server accepts the forwarded record: the
FHitResult(impact point, bone, component, physical material),ImpactVelocity,SimulationData(elapsed time, seed, hit count, history bitmaps),ProjectileOrigin(feeds distance falloff). - No lag compensation found:
AutoProxyFixedTickInfoandFromToPctare initialised to -1 in0x6F353F0; no writer, no rewind code.
From the spread teammate (round 23 A)
- For a single bullet the client draws the random cone direction (fresh CRT
rand()per shot), rounds it to 16-bit pitch/yaw, and sends it in a 0x28-byte record (Server_FireProjectile0x6B97900); the server re-runs the shared executor0x6B93610with seed -1 and does not redraw. For shotguns the record carries the pellet seed (Server_FireBuckshotProjectile0x6B97820). No check of the received direction against the cone was found in0x6B97900,0x6B97820or0x6B93610. Whether the server limits it elsewhere (for example in hit validation) is open.
What would confirm or refute
- Runtime test with a forged hit on a predictive projectile, and whether the server re-simulates from the seed. NOT to be run against the live game (Elytra kernel-level anti-cheat; terms of service). Only an owned, isolated, permitted setup would be acceptable.
- Devirtualizing or reading the true body of
0x6B74770(item 3 may be a stub artifact). - A search for any server-side use of the received direction/hit record beyond the three scanned ranges.
Where the public docs stand
The public pages (pipelines/Wardogs_HitRegistration_v1.md, pipelines/Wardogs_WeaponSpread_v1.md) were scrubbed of items 1-7: they name the RPC pair (already visible in the public SDK dump) and the fire-record layout, and say server-side handling is not documented.
Smoke authority, round 26 A (2026-10-23, static analysis only, unconfirmed)
Verdict: smoke volume geometry and sight blocking are CLIENT-SIDE; the server never builds a smoke volume. Nothing server-side reads smoke.
- Volume actor
AWDSmokeGrenadeVFXActor(ctor0x869C200) has nobReplicatesstore and noGetLifetimeReplicatedProps;SmokeVolume/Pawnscarry no Net flag.BP_SmokeGrenadeVFX.SetupcallsSetPointsonly for non-signal smokes (SmokeType != 1: White, Black), building the sphere-trace point list locally and pushing it to Niagara. - Volume is registered via
0x869BED0intoUWDSightBlockerSubsystem(0x6F4B100class getter). ItsShouldCreateSubsystem(vtable slot 86,0x6F4FDC0) returns false on a dedicated server (0x45C4DC0), so smoke registration does nothing there. Subsystem exists for listen server, standalone, client. - The explode cue that spawns the VFX actor is suppressed on a dedicated server (
UWDGameplayCueManagerslot 930x4C55DB0returns true when net mode == 1, unless a global byte overrides it; override not resolved). AWDSmokeGrenadeAfterEffect(B_WorldSmokeGrenade_*, ctor0x869BFF0) IS server-spawned and replicated (or [actor+0x63],0x10):OwnerEntityTag(+0x2C0) and a server-time float (+0x2C8), probably InitialOnly. Spawned inAWDSmokeGrenadeAuth_Explode (slot 237,0x869C640) behind Role==Authority; non-authority computes a late-join start offset from GameState server time.- Only consumer of the registered volume: aim-assist target manager (
0x6D820B0, via eligibility override0x6D81EB0) via query0x6F4E2D0. This is local-controller aim assist, so smoke affects only the local client’s target acquisition.Pawnslist (UpdatePawnsInBoundingBox0x869E420,UpdatePawnsInSmoke0x869F600) has no native caller; result discarded at0x869F765. - No smoke GameplayEffect or stealth/status tag in cooked data. Only tags: GameplayCue.SmokeGrenade.Explode, GameplayCue.Vehicle.Countermeasures.Smoke, ID.Item.SmokeGrenade., Audio..
-
Throw/fuse (partial, not completed in round 26 A): B_Action_ThrowExplosive_C.ThrowOrExplodeExplosiveruns only when IsDedicatedServerIsStandalone and takes launch params from the server’s GetActorEyesViewPoint;StartFuseTimer(0x6CAF200) is Authority-only and its handler calls Auth_Explode. So the server owns throw and fuse. - Implication: a modified client skipping the volume or blocker registration would only change that client’s aim assist and visuals. Smoke is not a server authority concern in the sense of hiding players from server-side checks.
- Open: GC_SmokeGrenade_Explode BP not dumped; trace channel TraceTypeQuery11 mapping; AfterEffect dormancy/NetUpdate (
0x3AA4150,0x3AA3C40,0x3AA3A50); map tracker registration0x53FFBF0; other BPs calling UpdatePawnsIn*. Round 26 B covers throw path and LOS.
Smoke authority, round 26 B (throw path and LOS; static analysis only, unconfirmed)
Confirms and extends round 26 A. Verdict: throw, fuse and explosion are SERVER-authoritative; the smoke cloud as experienced is built locally on each machine; smoke changes no server-side gameplay outcome.
-
No Server/Client RPC exists for throw, fuse or explode. Origin = server pawn GetActorEyesViewPoint+ throw offset; velocity = throw curve + serverGetVelocityinfluence; fuse = serverBaseFuseTime(smoke 3.0) and timer. Client contributes only input timing and its normal view rotation.B_Action_ThrowExplosivespawns only if IsDedicatedServerIsStandalone (deferred spawn -> InitializeForThrow-> finish ->OnThrowRelease0x6CABE60);AWDGrenade::OnThrowRelease(0x6CAF180) callsStartFuseTimer(0x6CAF200, Authority-only; callback0x6CAE0C0-> explode virtual slot 237). No client fuse timer. - Replicated on
AWDExplosive(0x6CAA4D0, push-model):ThrowInfo(+0x318),ExplosionInfo(+0x340),ExplosiveAttachData, instigator PlayerState. Smoke/grenade classes add no Net fields. Clients simulate canister physics locally; explosion cue gated byExplosionCueTimeoutTolerance. - Explode virtual
0x6CA80E0(server only) builds blast/damage via0x6CA8D20, which returns early when NetMode==Client. Smoke override0x869C640(Authority) spawnsB_WorldSmokeGrenade_*(AfterEffect, InitialLifeSpan 175 s), copies velocities, sets OwnerEntityTag.Multicast_ExplodeInstantaneous(reliable multicast, thunk0x6CAD0C0) exists; callers on the smoke path not traced. - AfterEffect
BeginPlay(0x869CA10) runs everywhere: server stores world time; clients compute start offset and run local cueGameplayCue.SmokeGrenade.Explode; server also registersTrackers.Type.SmokeGrenade(UI map tracker, call0x1453FFBF0). The cue presumably spawnsBP_SmokeGrenadeVFX, which runs local traces and registers a local sight blocker (inferred from SDK; cue BP not dumped). - Sight blocker (
UWDSightBlockerSubsystem): query0x6F4E2D0has exactly one caller (0x6D821E1, aim-assist target manager virtual slot 1610x6D820A0, threshold +0xE0 default 100). No AI perception, spotting, minimap, damage or hit-registration consumer. Producers: smoke VFX actor andAWDSmokeTrailBlockerActor(vehicle countermeasure smoke, 12 s, size 750; segments registered via0x76A2FA0). - Smoke trace channel =
ETraceTypeQuery10, derived (UE ini ordering) asVisibilityNoPawn(ECC_GameTraceChannel16); reading of Block-by-default for profiles is an inference. Cloud shaped by local traces only. No smoke GE/tag affecting stealth/visibility/lock inDefaultGameplayTags.ini. GameStateOverrideAimAssistStrengthMultiplier(Net) exists, so aim-assist strength is a server-replicated setting. - Not determined: whether vehicle missile lock-on/homing consults smoke (no native caller in vehicle code, vehicle smoke is a separate system with
Server_FireSmoke); dedicated-server cue suppression override byte; GC_SmokeGrenade_Explode contents; AI sight traces. - Runtime test (offline or self-hosted only, never the live game; Elytra): server logs of Role/ThrownServerTime/ExplodeServerTime; replication debug of grenade and AfterEffect; dedicated-server run to confirm no cue/VFX/blocker; aim-assist with local smoke altered; vehicle lock-on versus vehicle smoke.