You are viewing a potentially older version of this package. View all versions.
Drastic-ClientPredictedProjectiles-3.0.3 icon

ClientPredictedProjectiles

Clients own every projectile they fire: instant prediction, full local simulation, and the shooter's copy does all hit detection (impacts, explosions, piercing) which the host applies. No snap-back, instant impacts. All players need it.

By Drastic
Date uploaded 19 hours ago
Version 3.0.3
Download link Drastic-ClientPredictedProjectiles-3.0.3.zip
Downloads 50
Dependency string Drastic-ClientPredictedProjectiles-3.0.3

This mod requires the following mods to function

bbepis-BepInExPack-5.4.2121 icon
bbepis-BepInExPack

Unified BepInEx all-in-one modding pack - plugin framework, detour library

Preferred version: 5.4.2121

README

ClientPredictedProjectiles

Gives multiplayer clients full ownership of the projectiles they fire, for every projectile in the game (vanilla, DLC and modded survivors), so they feel as responsive as they do for the host.

In vanilla, every projectile a client fires is simulated and hit-checked by the host. The client only sees a "dumb" local preview that can't hit anything and doesn't home, stick or explode. As a result:

  • projectiles appear late, or not at all, until the host's copy arrives (many have no preview at all),
  • rockets visibly fly through the enemy they hit and explode a moment later,
  • homing, sticky and boomerang projectiles fly in a straight line, then snap to where the host has them,
  • the projectile visual snaps backwards when the host's copy arrives,
  • explosions and impact sounds play one full ping after the hit,
  • the host's copy starts behind (the game even calculates how far behind, then never uses the value).

What this mod changes about projectiles

When the host has the mod, for every projectile a modded client fires:

  1. Every projectile is predicted. Projectiles that vanilla never shows early now appear the instant you fire. For those, the host keeps network authority exactly as in vanilla. The client pairs its copy with the host's copy itself, so the host doesn't show up as a second projectile.

  2. Your copy runs the projectile's full behaviour locally. Logic the game only runs on the host (homing and target finding, sticking, boomerang returns, fuses, lifetimes, detonations, child projectiles) also runs on your copy, so it behaves correctly on your screen immediately. This works for modded projectiles too.

  3. Your copy does all of the hit detection. It decides:

    • what the projectile collides with (enemies, walls, bounces, triggers),
    • who is inside each explosion radius,
    • who each piercing, single-target or damage-zone hitbox touches.

    This is checked against enemies where you see them, at the moment it happens on your screen. Each result is sent to the host tagged with the projectile's age. Your copy never deals damage, heals, procs items, applies DoTs, fires orbs or spawns anything for real, and nothing else it does is sent over the network. Its effects and sounds play only on your machine.

  4. The host's copy replays your timeline. The host spawns its copy a small buffer (default 0.06 s) after your shot arrives. Your reports for every moment are then already waiting when its copy gets there:

    • your impacts are applied at the spot you saw, with your projectile's speed after the hit;
    • at each explosion or overlap attack, the host's own detection is swapped for your hit list.

    Hits are re-applied relative to where each enemy currently is on the host. Everything that follows (damage, crits, procs, DoTs, debuffs, the projectile's own on-hit behaviour) still runs through the normal game code on the host, so the host keeps authority over the results. Item procs that make their own explosions are never fed your hit list.

  5. Only shots your game confirms are client-decided. Right after you fire, your game tells the host it is simulating that shot. Shots it isn't simulating (local simulation off or turned off for that projectile type, passenger projectiles) stay fully host-decided, so a projectile can never end up with nobody detecting its hits. The host's copy ignores its own physics hits while it is in sync with yours. It only takes over (vanilla behaviour, and your visual blends to its copy) if one of your reports fails the sanity checks. Those checks allow for distance, projectile speed, enemy speed and ping. It also takes over if you disconnect or stop simulating that projectile.

  6. Fast-forward for the rest. Projectiles you don't simulate (passenger projectiles, or when local simulation is off) are instead fast-forwarded on the host by your one-way latency. This uses a collision sweep and also advances fuse and lifetime timers.

  7. The host doesn't echo your own effects back to you. Effects your projectile's own code creates (explosions, impacts, hit sparks, expiry effects, its sounds) aren't sent back, because you already played them. Damage numbers and proc effects still come from the host.

  8. Your projectile's visual follows your local path instead of snapping back to the host copy. It blends smoothly to the host's path only if the two genuinely disagree, or if the host rejected one of your impacts.

  9. Projectiles you didn't fire (enemies' and other players') are drawn where the host currently has them, not one ping behind, so what you dodge is what the host simulates. This is purely visual and is never drawn through walls.

Exception: projectiles that carry a passenger (VehicleSeat, ones that move your own character) keep vanilla prediction and don't run locally, because a second copy would grab your own character. They still get fast-forward and smoothed visuals.

Self-healing: if some projectile's code fails when run locally (for example a mod component that assumes it is on the host), the mod logs it once. After three failures it turns local simulation off for that projectile type for the rest of the session and tells the host.

Compatibility

  • Everyone should install it, but nothing breaks if someone doesn't. Clients and host shake hands when joining:
    • with a vanilla host, a modded client is 100% vanilla, apart from the purely visual item 9;
    • vanilla clients in a modded host's lobby play vanilla;
    • all modded clients get everything.
  • Doesn't add itself to the network mod list, so it doesn't block anyone from joining.
  • Only dependency: BepInExPack. No R2API or HookGenPatcher.
  • The host behaves exactly like vanilla for everything except client-fired projectiles.
  • Designed alongside these mods:
    • AttackDirectionFix: its visual offset still applies.
    • ItemQualities: local explosions run the real code, so its explosion radius changes apply.
    • PizzaClientLagFix, MiscFixes, RiskyFixes.
  • A vanilla host logs a single harmless Unknown message ID 21437 line when a modded client joins.

Configuration

BepInEx/config/daz.ClientPredictedProjectiles.cfg

  • [Host] settings only matter on the host: client-owned impacts, fast-forward and its cap, impact hold time, distance tolerance.
  • [Client] settings only matter on the player's own machine: predict all, simulate locally, predicted visuals, correction blend time, showing other projectiles where the host has them.
  • [Advanced]
    • Excluded Projectiles leaves specific projectiles completely vanilla.
    • Log Projectile Report lists how every projectile is handled.
    • Verbose Logging logs every impact report, rejection and sandbox block.

Limitations

  • Hitscan (bullets) and melee are already client-authoritative in vanilla, so they're unchanged.
  • Client-side detection covers the game's explosion (BlastAttack) and hitbox (OverlapAttack) systems, which is what nearly all projectiles use. A projectile that searches for targets some other way (homing lightning beams, a mod that calls damage directly) still has that part decided by the host.
  • Because the host replays your projectile a small buffer later, other players see it about that much later than you do. Item 9 on their machines makes up most of that.
  • Orb attacks (e.g. Huntress arrows) are created by the host and aren't projectiles, so they aren't changed.
  • Damage numbers and on-hit item procs still come from the host, one ping after the hit.
  • All players should run the same version (the handshake rejects mismatched versions, which then play vanilla).

CHANGELOG

Changelog

3.0.3

  • Compatible with mods that update projectile visuals once per frame instead of every physics step (e.g. RiskOfFrames): the visual hooks step aside when the update is deferred, and the "where the host has it" extrapolation measures real elapsed time. No protocol change (works with 3.0.2).

3.0.2

  • Fixed: prediction ids are reused by the game, so a new shot's early hit reports could be applied to the previous shot that used the same id (or stale reports could leak into the next shot). Every simulated shot now has a unique serial on its confirmation and on all its reports.
  • Fixed: late overlap hits applied after the projectile was gone were checked against the wrong position. Each attack's position and size are now recorded when it happens.
  • Fixed: late-applied hits could echo hit sparks back to the shooter.
  • Protocol v5: all players must update.

3.0.1

  • Fixed: a shot the client predicts but doesn't simulate (e.g. Predict All Projectiles off, or simulation turned off for that projectile type) could never hit anything. The client now confirms each shot it simulates, and unconfirmed shots are fully host-decided.
  • Fixed: an explosion whose hit report arrived just after the host copy detonated lost its damage. Late reports now still apply for up to 1 s after the projectile is gone.
  • Fixed: item procs that make their own explosions (e.g. Brilliant Behemoth) could reuse the projectile's injected hit list. (Found in verification.)
  • Going over the per-projectile report limit now hands the projectile to the host instead of silently dropping reports.
  • Protocol v4: all players must update.

3.0.0

  • The shooter's own copy now does all hit detection: collisions, explosion radius hits and piercing, overlap and damage-zone hits, against enemies where the shooter sees them. The host swaps its own detection for the shooter's hit lists, so damage, procs, DoTs and debuffs still run through normal host code.
  • The host replays client-simulated projectiles on the shooter's timeline (spawned a small, configurable buffer later), so reports are always on time. Its copy's own collisions are ignored while in sync, and the wait-and-guess impact hold is gone.
  • Late reports are still applied to the attack they belong to; early ones (point-blank) are held until the host copy exists.
  • Item procs that make their own explosions are never fed the projectile's hit list.
  • Hit sparks from client-detected hits are no longer echoed back to the shooter.
  • New host setting Client Report Buffer Seconds. Fast-forward now only applies to projectiles the client doesn't simulate.
  • Protocol v3: all players must update.

2.0.0

  • Covers every projectile, vanilla and modded, instead of only simple ones.
  • Every projectile a client fires is predicted, including ones vanilla never predicts. The client pairs them with the host's copy itself, so the host keeps network authority.
  • Predicted copies run the projectile's full host-side behaviour locally in a sandbox (homing, sticking, boomerangs, fuses, detonations, children). Damage, procs, spawning and all network traffic from the sandbox are blocked; effects and sounds play locally.
  • Every impact (not just the last one) is client-owned and replayed on the host, including bounce velocity.
  • The host pins its copy while it waits for the client's report, so a held impact happens where it happened.
  • The host no longer echoes back any effect or sound produced by a client-simulated projectile's own code.
  • New: other players' and enemies' projectiles are drawn where the host currently has them.
  • Self-healing: projectile types that fail when simulated locally fall back to plain prediction.
  • Protocol v2: all players must update.

1.0.0

  • Initial release: client-owned impacts for simple projectiles, host fast-forward, predicted visuals with reconciliation, instant local impact effects.