FishNet icon indicating copy to clipboard operation
FishNet copied to clipboard

Make tick smoothers multithreaded

Open belplaton opened this issue 1 week ago • 0 comments

Tick Smoothing: execution refactor (single-thread -> jobified)

This PR changes how the existing tick smoothing runs: from per-object, main-thread execution to a centralized jobified pipeline in TickSmoothingManager. The core smoothing idea remains the same; the implementation/dispatch model is different.

Key differences (before vs after)

  • Before: each TickSmootherController subscribed to TimeManager and ran smoothing on the main thread.
    After: the controller only Register/Unregisters; all event wiring (OnUpdate/OnPreTick/OnPostTick, RTT, prediction replay) and execution are handled in TickSmoothingManager.

  • Before: per-object state lived in controller/smoother instances.
    After: state is stored in the manager as indexed Native/SoA containers (masks like canSmooth/useOwner/objectReconciling/..., realtime interpolation/multipliers, move-rates, snapshots, and a per-index TickTransformProperties queue).

  • Multithreading approach: work is expressed as explicit job chains with JobHandle dependencies (no per-object main-thread loops).

    • Transform work uses IJobParallelForTransform over TransformAccessArray (_graphicalTaa, _targetTaa, _trackerTaa).
    • Non-transform work uses IJobParallelFor with batching (ComputeBatchSize based on JobsUtility.JobWorkerCount).
  • Dispatch pattern: “payload + executeMask”. Jobs populate payload arrays (move, discard, set rates, snap, teleport, enqueue/clear, replay modify), and subsequent jobs apply only entries where executeMask != 0.

  • Tick buffer: the per-object tick buffer is now job-friendly via StripedRingQueue<TickTransformProperties> (one ring queue per index/stripe). Queue trimming (limits + required headroom over interpolation) is performed in DiscardExcessive... as part of job chains.

Phase breakdown (job chains)

  • OnPreTick

    • Update fast masks on main thread
    • PreTickMarkJob → discard → teleport (and queue clear) → PreTickCaptureGraphicalJobComplete()
  • OnPostTick

    • CaptureLocalTargetJobPostTickCaptureTrackerJobPostTickJob (produces snap/enqueue payloads)
    • discard → snap → add/enqueue → Complete()
  • OnUpdate

    • UpdateJob (move payload) → MoveToTargetJob (moves graphical; may trigger set rates/multiplier/clear) → Complete()
  • RTT / prediction replay

    • Separate job chains update realtime interpolation and perform ModifyTransformProperties after prediction replay.

Additional changes

  • Added MovementSettings.UseLocalSpace to select local/world space for position/rotation smoothing.
  • Updated .asmdef dependencies for Jobs/Burst/Mathematics/Collections.

belplaton avatar Dec 17 '25 18:12 belplaton