"Add Movement Input" for client's character executed on server

Hey. I am trying to create a simple CO-OP game to learn how networking and multiplayer works in UE5.

I started with Thrid Person Project and duplicated ThridPersonCharacter which I adjusted for Synty Polygon Characters. I also removed almost everything from event graph because I thought that this stuff won’t be needed.

Firstly in my Character blueprint I added Mapping Context to Enhanced Input subsystem, but only for local controllers because other players does not need to know what keys we use.

Next in character I created method that applies “Add Movement Input” based on given world location under the mouse cursor.

I execute this method in event that have replication “Run on server” + reliable field checked.

And finally, this event is executed when owner hit the mouse button.

The problem now is, that when I click mouse button in “server” window it works, character is moving and I can see it in server window and also client window. However when I hit mouse button in “client” window nothing happens, client’s character is in the same place for both windows. Event is executed on the server, because print node shows “Server: Hello”. Maybe it is also worth to mention that when I switch SR_MoveCharacter event to “Not replicate”, it is working fine.

So the question is what did I do wrong here, that moving client’s character on server is not working?

From what I understand, we should send request to move character on server side in order to have a one source of truth of players position. Correct me please if I missunderstood something.

Additional question: How logic for controlling character should be splitted in multiplayer game? Should we for example leave in character blueprint only methods and events that apply effects on it, and input handling move to player controller? I will appreciate any tips.




Character movement is already designed under the hood to handle player movement locally and replicate to server and other clients. So for the client character it expects input from the client not from the server. You are not supposed to to replication yourself there, it’s all done internally.

Traditionally it was all handled in PlayerController, but now Enhanced Input and Mapping Contexts encourage you to bind pawn-specific mappings to pawns. I’d say just split with common sense. Anything related to the pawn/character/vehicle (such as movement) goes there, while more general bindings go to player controller (eg. scoreboard, pause menu..)

Thanks for the response.

After reading your comment I found article in docs “Networked Movement in the Character Movement Component” and it describes in details how it networking works in component. I do not know how I could miss that, sorry.

I believe now that I should only worry about movement replication when I would like to create my own custom movement component, however in article mentioned above, there is a whole process described how it should be handled.

And thanks for the tips about splitting logic. Initially I wanted to put input events in PlayerController, but it made relation Character<–>Player Controller more tight. I will try to split next components and logic with common sense as you said, but it is always a good practice to ask about good practices and correct patterns :slight_smile: (And it might save you from refactoring huge blueprints at some point)