Building Ability System on Mover Plugin and NPP

I’m trying to use the latest Mover plugin with Network Prediction Plugin as its backend, but I am not sure how to build a compatible ability system with it. It seems like there are multiple ways to do so:

  1. There is a MockFlyingAbilityComponent example in the NP Extras plugin, but the show case ability is movement related, so it inherited the NP component which implenments NP related functions like ProduceInput, FinalizeFrame etc.. Its InputCmd is derived from the corresponding InputCmd, so it contains all the input variables needed for handling movement. If I code my ability component like this, it would be coupled with the movement component.
  2. Build my own ability component like GAS:
    a. I can add the player input to InputCmd in MoverComponent, then pass to the SyncState (which isn’t ideal as the NPP indicated). Get the input from SyncState if it is controlled by player, and from AI if it is not. This will require the ability system do the rollback itself.
    b. Implement ability component inside NPP, this would require extra InputCmd and SyncState to be set up. AI controlled actors with ability should all be managed by NPP, this can cause lots of overhead because NPP constantly checks ProduceInput every tick. Binding more than one ProduceInput on one character causes more overhead on NPP tick for player controlled characters. Also, ticking order between Mover, ability system and other world actor would be messy, since AI and most other module of the engine ticks after NPP.

I really want to explore more with NPP and its reliable network rollback system, but it is way too complicated for me if I want to build any gameplay codes besides the movement system. I am sincerely appreciated if anyone shares more idea on this topic.

2 Likes

Hey @ZxMapleLiu,

I see you posted in Jul 2025, but if your still stuck. Here is some guidence for you and others stumbling in here! :slight_smile:

Building a predicted ability system on top of Mover / NPP can be overwhelming at first with NPP structures ticks and state buffers, but you actually don’t need a separate NPP component or heavy architecture for it.

IMPORTANT - Think of it as a onion! xD

Here are three core principles on how you can integrate an ability system cleanly without coupling it too tightly to Mover:

1. Bit-Packed Ability Flags in InputCmd

Instead of spinning up a second UNetworkPredictionComponent (which adds overhead and complicates execution order), pass lightweight ability triggers directly through your movement model’s FAetherInputCmd (or your custom Mover input cmd).

By using bit-packing in NetSerialize, sending ability inputs adds practically zero network bandwidth overhead.

// Example: Bit-packed ability triggers in InputCmd
uint32 ActiveAbilityBits = 0; 

void NetSerialize(const FNetSerializeParams& P)
{
    // Serialize 8/16 bits for ability inputs only if active
    P.Ar.SerializeBits(&ActiveAbilityBits, 8);
}

2. Run Ability Logic inside the Simulation Step

Keep your state predicted by evaluating the input flags inside your simulation tick (e.g., in a dedicated sub-simulation step or simulation helper).

  • State Data: Store ability cooldowns, active states, or resource costs inside your SyncState or AuxState.
  • Execution: During SimulationTick, read the InputCmd flags, update the SyncState (e.g., set bIsCasting = true), and apply any resulting movement or state changes deterministically.
  • This ensures that if a rollback/reconciliation occurs, NPP automatically rewinds and re-simulates the ability state seamlessly along with movement.

3. Use NetSimCue for Visuals & Audio

Never trigger visual effects, sounds, or animations directly inside the simulation tick, as rollbacks will cause them to re-trigger or play multiple times. Instead, invoke a NetSimCue (via Output.CueDispatch). NPP handles cue dispatching safely so FX only execute once on the local client when the frame is finalized.


I’ve implemented a similar NPP-backed movement and simulation architecture in my framework Aether and in my other projects:
[GitHub Repo /Aether NPP/6DOF C++ Deep Dive]
These are more deep dives into the C++ architecture to setup npp :slight_smile: If you have any follow-up questions or want to dig deeper into the C++ implementation, just let me know, happy to help!

Promise I won’t bite! :smiling_face_with_sunglasses: