Skip to content

Frequently Asked Questions

Jared Taylor edited this page Oct 31, 2024 · 2 revisions

Why is such an elaborate solution needed, can't I simply replicate the max speed?

ACharacter & UCharacterMovementComponent have built-in client-side prediction to provide what feels like latency-free movement, yet with server authority to prevent hacking/cheating.

If you replicate anything that the character's predicted movement uses, this will happen outside of the prediction framework and result in considerable desync. It may appear to work in testing, but until you introduce latency, you won't see the actual result.

This solution introduces the abilities and stamina into the prediction framework so that it doesn't desync.

What is client-side prediction?

This is a complex topic beyond the scope of this readme. Here are some resources:

Client-side prediction with server authority is considered the gold standard, however it comes with downsides; it is vastly more complex to develop, takes considerably more time to develop, and has high processing costs so for larger games such as battle royales or high player-count shooters it can become incredibly prohibitive for a server to process the prediction of so many players.

Why is the ACharacter class required for RPCs? Can't you just replicate the UCharacterMovementComponent?

Replication routes through the AActor class, even for UActorComponent, these components send an additional uint8 that identifies which component is replicating. By manually routing through the ACharacter class we forego the bandwidth cost of the additional uint8. It is an optimization that the engine establishes the standard for.

Why are there multiple UCharacterMovementComponent and ACharacter?

Developers who use this plugin need to fork it and change the inheritance so the abilities they want are present in their project's resulting ACharacter, thus they do not end up with abilities that their project does not require. There may be a link branch that has all abilties linked together for you but it is not always up to date, if this is the case, you can still use it as an example.

Why isn't PrepMoveFor and SetMoveFor being used for Stamina?

Corrections occur in UCharacterMovementComponent::ClientHandleMoveResponse and the information is sent in FStaminaMoveResponseDataContainer::ServerFillResponseData.

PrepMoveFor and SetMoveFor will actually undo the correction.

A paraphrased explanation of why by Cedric 'eXi':

Let's say the server corrects it to 5 and your move still has the old value of 50. Your saved moves will continue sprinting longer and cause another correction. Instead of running out of stamina you will probably have enough to keep sprinting and then send a new server move with a location that the server can't reach. The boolean (bStaminaDrained) also comes from the server. Doesn't sound right to override it with the saved move, and for saving it into the saved move, the InitialPosition function should be enough. That's what epic does, at least for the values that are used in CombineWith.

Why should CharacterMovementComponent handle Stamina instead of GAS Attributes?

The CharacterMovementComponent has its own ecosystem for prediction. Performing any form of external action that modifies data which the CMC uses to predict movement may result in corrections.

Furthermore, not following the whole setup for concepts like SavedMoves also removes the ability of the CMC to reconcile whatever was predicted after a corrected move.

There are also restrictions on GAS side that limit the ability to predict properly, such as GEs not allowing Stacks and Removal to be predicted.

As a general note, the game that spawned this plugin tried every available method to implement Stamina via GAS and was unable to have it working correctly in a networked environment. This is the only method that worked. There are no known or published solutions to achieve GAS-based Stamina. Inadequate and limited results could be achieved, but nothing that is sufficient for this game, and likely not sufficient for most games.

Clone this wiki locally