Function Replication

Hey everyone,
I’m looking for some advice on how to properly structure replication in a project that wasn’t originally built with multiplayer in mind.

A while back I tried adding replication to a different game project and ended up shelving it due to how tedious it was—felt like I had to rewrite entire systems just to make things sync properly.

Now, I’ve got a first-person shooter I’ve been working on casually in my free time. I’ve recently decided to make it multiplayer, which I know is kind of backwards—ideally, multiplayer should be planned from the beginning. But here I am, and it’s too late to start over.

So, my main question is: How would you go about retrofitting a singleplayer-focused project to support multiplayer in Unreal Engine?

To give a specific example:
Let’s say I have a weapon with an OnFire function that gets called whenever the gun shoots. In singleplayer, this is super clean and self-contained:

But once I start replicating this, things get messy. Logic ends up split between Server, Multicast, and Client RPCs, and I lose the clarity of a centralized function. Everything feels scattered across the replication flowchart and harder to maintain.

I’m wondering how others approach this—
Is it possible to still keep most of the firing logic inside OnFire, and just call it from RPCs (like Server_OnFire, Multicast_OnFire, etc.), branching internally for authority checks? Would this also work correctly for listen servers, where the host is both a server and a client?

Would love to hear how you all handle organization and structure for multiplayer in projects that didn’t originally plan for it.
Any best practices or examples are appreciated.

1 Like

Multiplayer is basically understanding the 3 proxies and writing specific code for each.
Autonomous (client), Simulated and Server (authority).

Identifying Client, Sim, Server upfront is key. Once you can determine the role of a character the flow logic handling is easy.

In the character class you’d implement a function that sets an Enum identifier for role.


Key note…
Servers do not play audio or visual FX. Servers do not render anything. So you write your code based on that.


Never use (index) nodes in multiplayer.


Here’s a post that goes in to detail about multiplayer shooting. Regardless the title of the post, this is not a Gameplay Ability approach.

Okay, thankyou for your response and for all the multiplayer related help i have seen from you on the forums :slight_smile:

How do i avoid running visual FX assuming i might be using a listen server or a dedicated server in the future?

Would your example of setting the player’s proxy role be redundant due to Unreal’s default methods for checking roles? Or is it just a more convenient way of going about it?

Do you have any idea why my Integer Rep Notify is not being called for client’s?
For equipping a weapon slot, I set said integer from a Server RPC and on rep notify i set the newly equipped weapon, its visibility, etc. Unfortunately it seems as if it’s only replicating on the server (I’m running a print string inside the on rep function and it always prefixes with server but never the client). I was and still am under the impression a rep notify when updated on the server, automatically calls the On Rep function for all clients? Maybe it’s a Unreal bug?




Mines a convenient approach. Check a single variable vs the Branch conditional chain.

The posted setup is for dedicated server. A Listen server setup would need to consider the hosting client. The enum would add a “Host” option. (Host, Server, Client, Sim)

No clue based on what you’re showing. Are you running 2 instances in PIE? If only one in Listen server mode you’ll get just server.

Switch Has Authority works different on Listen Servers because the host is also the server.
Autonomous Proxy, And Authority, And Network Authority.

That switch isn’t necessary after Equip Weapon Slot.

Yes, in BP the OnRep function is immediately called on the Server after setting the variable. In C++ you have to call it directly.

e.g. Set variable → OnRep Function

I am running the net mode ‘Play as Client’ with two players running in PIE on UE5.5.4. I also switch between client and Listen Server to ensure my setup works for both but its only running for the server on both net modes :confused:

If i run the function that sets the variable on a multicast, it actually does rep notify the clients but obviously that just makes the rep notify redundant. Really confused, maybe unreal is bugging out unfortunately.

Oh my god, apparently RepNotify doesn’t get called if the value of the variable doesn’t actually change from its previous value. My SelectedIndex was 0 by default, and it was set to 0 again (since the player didn’t have a weapon yet). As a result, the RepNotify didn’t trigger on the client. Is this normal behavior? Feels a bit odd, but I guess that was the issue?

That’s normal expected behavior. No Change, No replication.

Options…

  1. Change your Slot type to an Enum.
    (None, Slot 1, Slot 2, Slot 3 etc.) Default to None/Unequipped.

  2. Compare the passed slot index to the current slot index variable. If the same, add an arbitrary value then set the variable, then immediately set it to the correct value.

e.g. Passing 0, Default is 0 … 0+25 → Set Slot Index(25) → Set Slot Index (0)

The value is then Technically changing on the server therefore marking the property dirty for replication.

Probably could get away with having the selected index being -1 for unequipped, this was driving me crazy i figured it would fire the on rep event regardless. Thank’s for the help :slight_smile:

1 Like

-1 would work. Enumerators work better long term. Just have to remember to always reset to unequipped state and also compare on the client before RPC’ing the server.

If Current state == State I want to transition to, do nothing, else RPC server.

Save yourself some bandwidth and not saturate the network.

Good idea, network optimization is definitely something i need to be warry of as general game optimization is something i care a lot about. Would Enum’s actually be worth it? Currently i am using a integer because i don’t have to make a new Enum slot if i spontaneously decide to let the player have more than two weapons.

I love Enums. Typically you fully scope your game before developing. Adding new slots means refactoring inventory. So an added enum entry isn’t a tall order.

I run the same chain logic on client actions before RPC’ing the server. Essentially On Input → Can I do this (Macro/Function), If Yes, do local stuff → RPC server to “TRY”. Server does its own “Can I do this”.

Something like…

Oh yeah they are awesome, I’m under the impression they are also a byte each, so they would be 4x cheaper than a int32 which could be great, also adding a new Enum to the list isn’t difficult at all you are right. As far as scoping out the game before developing goes, I’m more so making a FPS system with a basic idea of how i would like it to operate and code just about anything in a way that its as easy as possible to tweak. I’m thinking i would be willing to do a enumerator like you are but to get my equipped weapon, i get a copy of my weapons / dual wielded weapons array and I’m unsure if the byte to integer conversion makes the usage of the byte (enum) redundant. Not to mention it’s more of a Halo eques game rather than something like quake/half life where weapon slots = med kits, grenades, weapons, etc.

Sorry if this is a dumb question, but wouldn’t you want to run checks like can equip on the server directly as opposed to locally to make cheating more difficult? Especially if its a very quick to execute operation?

You do it on both.
Client does it so it doesn’t waste an RPC for the server to just say No. Consider Key spamming. 100 back to back rpc’s that get ignored.

Server does it to prevent cheating and it is the one that actually equips (Attaches, changes character state etc).

Firing a weapon goes through the same flow. Client checks if it can (has weapon, weapon has ammo etc) → RPC server. Server checks if it can (has weapon, weapon has ammo etc) → fires auth shot.

Oh okay, thats very very good to know, i’m under the impression that server RPC’s are extremely valuable due to server’s/listen server’s needing alot more aggressive optimization than typical game logic. As a result i will definitely try to be as careful about calling RPC’s as possible lol.