#multiplayer

1 messages · Page 208 of 1

keen adder
#

Ohhh. So I should prob check for ownership and stuff

#

That makes sense

quasi tide
#

It could be that you're running in single process mode (which can make some stuff screwy) as well

hoary timber
#

friends, I'm using SetViewTargetWithBlend() function on another class, in a first person multiplayer game, but once the transition happens, I can see my players multiplayer mesh, The mesh on Character Blueprint is marked as Owner No See. Since the function it's Player Controller target, it seems like due to that the player controller doesnt own my character anymore? any way to geet that working?

So basically, I use an interface to interact with a class, through interface I pass Player Controller reference, and from that class I use the SetViewTargetWithBlend, should have this been done differently?

keen adder
quasi tide
#

It would be in your project settings, not there.

#

If you haven't touched it, then yeah, you're in Single Process mode.

keen adder
#

Yeah I see it here, it even mentions it'll have more issues lol

#

I'll google what those issues may be

#

Thanks for your help man

#

Oh! Probably issues with statics and stuff

#

multi-instance loads pretty fast, so it's no biggie

quasi tide
#

To be honest - I mostly run things in SP mode just because it is faster to start up.

keen adder
#

Haven't run into any issues?

quasi tide
#

Whenever something is screwy, that's the only time I turn it off to confirm it.

#

Not really. Nothing outside of the ordinary to be honest.

keen adder
#

I immediately found one in multi-instance. The non-active client runs at 2fps lol

#

I'm sure there's a setting somewhere to disable the low fps on loss of focus, but I'll stick with SP for now, thanks broski

kindred widget
#

Not really. OnRep is just an extra function called when the variable arrives on client.

hoary timber
keen adder
#

Hey dude, sorry to summon you again, I put my log on ReceivePossess, and now the server posesses both, but the client still has nothing

#

Any other thoughts on how the client can get ahold of it's pawn? It has a playercontroller, I can see, it just doesn't seem to posess it
(It's always nullptr)

queen escarp
toxic grove
queen escarp
#

this is called in game mode ive confirmed all players holds 2 controllers but its only fiering on 1 oif them :/ ?

cobalt notch
daring gorge
#

i was going through @fathom aspen s multiplayer tips/ tricks and he mentions how cpp includes something called replication graph, custom network serialization for types, fast array replication(i understand this), virtual methods. can anyone give me an example of where id use these methods? like real life applications

modest crater
# daring gorge i was going through <@393501253184913418> s multiplayer tips/ tricks and he ment...

A custom replication graph - almost never unless you really need someting custom since unreal supports the defalt replication graph and iris

Custom Serialization - I use it all the time, you just need to specify some type traits templated on your struct type and then you can implement whatever the trait expects (DW if this doesnt make sense, you wont need to care about it until you actually start writing network code you intend to keep, not just mess around with and learn), unreal supports most serialization out of the box without much effort from you

FastArray - Sometimes, depends on if you have lots of data that changes an even needs a fast array setup, again same concept as above where it is a nice optimization but it changes nothing about the general concept of you just learning, I would ignore these until you need them.

Virtuals - nothing to do with networking at all and the entire engine relies on them (mike acton laughing at us rn). This sounds like you should do some learncpp.com

daring gorge
vivid seal
modest crater
#

I know, I use them I just already said a lot

daring gorge
vivid seal
#

off the top of my head, things like equipped ability slots, you can have UI elements that update for each slot individually, and when a new ability is set in a slot (a fast array item) the UI can just bind to that specific slot instead of having to figure out what in the array changed and which widget needs to update

#

but there's probably a lot of use cases, you can use it for initializing individual elements on the client side as they're added to the array

fossil spoke
#

The point being is that its much more convenient to use, than just replicating a regular TArray and manually parsing all elements that changed in the OnRep

#

Im not entirely sure what the performance differences are between regular TArray replication and FastArray replication.

daring gorge
#

so in a fast array only the element that got init or addded gets replicated and not the entire array when the change is made?

fossil spoke
#

I almost feel like the Fast Array callbacks should be native to TArray replication as well.

#

But I guess thats specific to networking and since TArray is a generic container, its not really appropriate in all cases.

vivid seal
modest crater
fossil spoke
#

Yeah there is likely CPU optimizations in there, given that it stores deltas

daring gorge
fossil spoke
#

How well that translates across the size of the array im not sure.

modest crater
#

wdym likely, there is. That is a massive benefit to using them, not just index callback behaviour

fossil spoke
#

Id expect it to be more performant for high counts

fossil spoke
daring gorge
#

im just making sure what i write in my project makes more sense and is the right method, however im slowly realising that this whatever i coded 2 years ago watching a bunch of youtube is stupid and ill go over it again so why not do it properly and know whats proper

#

if not just know more🤷‍♂️

#

also lets say it being a generic shooter project i often fail to see how/where i can use concepts in my project but yeah examples help understand better!

modest crater
fossil spoke
#

Generally speaking, as you progress through a problem, you find different solutions that you weren't aware of before. These solutions are also going to be useful for other problems. As you understand a solution through its usage, you end up being able to identify its usefulness to solve other problems.

#

Knowing how to solve a particular problem, or at the very least, what tools (concepts, patterns, etc) you can use, becomes easier as you gain more experience.

daring gorge
#

i dont have any problems as of now however i wouldnt want any in the future either

daring gorge
fossil spoke
#

Sure, if thats how you learn best. Personally, thats not how I learn.

#

Typically I will come across a problem, not know the best way to approach solving it. Research the issue and come up with something I think might work. Find out what elements of that solution exist already. Learn those and apply them.

#

If that solution isn't efficient enough or has flaws, rinse and repeat the earlier steps.

#

I cant just pick up a 1000 page book on all the inner workings of C++ or networking and just absorb all that information to be able to recall the appropriate parts when faced with a problem.

#

Which is what I feel like you are suggesting

daring gorge
#

ive recently figured that my knowledge of networking isnt sufficiant to just keep going on my project and ive been way too long at this project to keep changing its code everytime i realise ive done something the wrong way or that theres a better way, i love practical way of learning too but i cant keep using my time on my project and keep going at it forever so i wanna clear my knowledge of the basics before i make the bigger mistakes which ofcourse i can fix with your method..

#

also i have recently took upon myself to write things down because it is indeed been helping me more

daring gorge
#

howver itd be good to know incase i run into a problem that hey i mightve thought of this before, mightve either written it down, if nothing it atleast reinforces the idea like "hey youve actually talked about this before and you didnt know when this could be used but now youre using it"

viscid tapir
#

Hey! I'm working on a MOBA-style game (similar to LoL, DotA) and I'm trying to implement Click-To-Move functionality. Right now, I'm using SimpleMoveToLocation for movement but it doesn't seem to work on the client at all.

Does anyone know if there’s something built-in (maybe in the CharacterMovementComponent or nav system) that could help with predicting and replicating click-to-move movements in networked games?

I'm not very familiar with the navigation system, so any pointers would be great!

marble gazelle
cursive steeple
viscid tapir
#

Ok thank you!

meager spade
#

We do predicted movement

#

You can enable navmesh on client

#

Then you can move on navmesh

#

This is how we do it in red solstice 2 do player has instant click to move.movement

tardy fossil
#

all net channels go through the netdriver right? like if i'm using the steam net driver with their relay stuff, a custom net channel should work normally right

coral badger
#

Does anyone know whether Client target builds (not just Game) can still function as Listener Clients?

lost inlet
#

The point of the client target is to get rid of listen servers

#

That's the difference between client and game

wicked whale
#

Hello everyone. I'm a relative beginner when it comes to Unreal Engine and most of my learning come from youtube tutorials/udemy courses. I was able to learn a lot and make excellent progress, but one topic I'm struggling a lot with is multiplayer/network. While I do understand how it works at a code level and how to use it (how to replicate properties and subobjects, net roles, net modes, relevancy, RPC calls, etc), I feel like I'm missing the basic understanding of how to design gameplay features for a multiplayer game.

Does anybody have good advice, or maybe know of a good course or youtube channel where I can learn about multiplayer - but again, not how to do it, but how to design gameplay for multiplayer? For example, while I know exactly how to write the C++ code I need to implement replication, and even custom serialization, I often struggle with basic decisions such as "should this happen on the client or in the server? or in both?" and therefore I feel like I could benefit a lot from learning more about the network mindset itself than learning how to implement specific parts of it.

opal pulsar
#

Does anyone know the CMC moves for AI?

#

doing something custom and I am wondering how I am going to handle sending the clients the updates of the velocity on the pawns. The only way I can think is multicast but thats dumb right? lots of AI would saturate the bandwidth

#

Hence asking how the CMC handles it

modest crater
#

check OnRep_ReplicatedBasedMovement

latent heart
#

Just to check, if an actor has a reference to another actor that's replicated... that reference can get replicated before the other actor right? So it might have its onrep called before that other actor gets sent?

modest crater
#

Yep, that little fun one made me re write my weapon inventory system to use structs and a single source to replicate it (the manager component) (I like it now anyway, super cheap and all data is atomic so it worked out)

But yeah, not really a way to add dependencies either without a custom replication graph afaik too

latent heart
#

My friend is just experiencing the joy of this for the first time with an inventory system 😄

coral badger
lost inlet
#

nothing? ?listen will just be ignored

#

all the server code is removed

coral badger
#

So, you just open a map in single player.

lost inlet
#

yes

coral badger
#

Aight

charred sapphire
#

Hi!

I'm trying to implement a multiplayer-compatible pause menu into my little learning project.
**Is there a delegate that clients can subscribe to, that notifies them that the GameMode has paused the game? **

I'm trying to figure out a (nice) way that clients can listen to this happening, without the GameMode having to cycle through each and every player on my end.

keen adder
#

Heya guys, When testing with 2 pawns, only the owning clients should have IsLocallyControlled() == true right?

coral badger
#

I'm attempting to connect to a server with a Game target client (not Client target) and I'm getting an error that I have not seen before:
[2024.09.06-13.00.45:451][686]LogNet: UNetConnection::SendCloseReason:
[2024.09.06-13.00.45:451][686]LogNet: - Result=MissingLevelPackage, ErrorContext="/Memory/CSSAVBJBQS041BN9UEJ4VUIOQ/Memory/CSSAVBJBQS041BN9UEJ4VUIOQ"
This is on the server.
Does this mean that there are assets on the server that are not there on the client or the other way around?

keen adder
#

Server should only have true on it's own pawn right?

charred sapphire
#

Yeah.

#

It can get weird in the first few ticks after BeginPlay though.

#
Epic Developer Community Forums

Late-ish comment and it might not apply to how/when you’re using it, but I just had this problem my project too. In my case, I have a radar collision capsule on my player. Whenever an object overlaps this capsule, it checks if that pawn is locally controlled and then does some checks to see if they should be added to an array to be displayed on...

coral badger
latent heart
#

I think there is a delegate.

#

Totally forgotten where it is, though.

keen adder
#

So what event is supposed to be used to set everything up?

charred sapphire
#
/** Pawn has been possessed, so changing state to NAME_Playing. Start it walking and begin playing with it. */
    ENGINE_API virtual void BeginPlayingState(); ```

In PlayerController
#

That's what I use most of time, personally.

keen adder
#

BeginPlayingState ?

charred sapphire
#

Yeah. That's where I set up UI, assign delegates, etc.

keen adder
#

Is that even an official event from APawn?

charred sapphire
#

idk what you mean by "official event"

keen adder
#

Ah sorry lol. I'm doing this part through blueprints but it doesn't seem to be exposed, so if it's C++ only I'll have to manually expose it

charred sapphire
#

it's not exposed to blueprints by default, yea

keen adder
#

But you're saying online stuff works by the time this event is called?
Because I'm seeing all kinds of crazy stuff in begin play

charred sapphire
#

.h

    void BlueprintBeginPlayingState(); ```

.cpp

void ACPlayerController::BeginPlayingState()
{
Super::BeginPlayingState();

BlueprintBeginPlayingState();

}

keen adder
#

Like, every pawn thinks it's "LocallyControlled", PlayerController doesn't even run at all on clients, etc.

charred sapphire
#

That's what I've been using personally and it works. I've had my fair share of headaches with BeginPlay unfortunately.

#

It... lies... so... many...times

#

This one seems solid.

keen adder
#

Awesome, I'll go implement that now

keen adder
#

Also searching online it seems like BeginPlayingState is empty, so Super might not even be nessecary 😮

charred sapphire
#

You are right, it's just called by ChangeState

#

I wouldn't remove it regardless, personally. If they decide to add functionality to it later on

keen adder
#

Yeah good call. Also, do you know if that event is on every actor or just PlayerController?

charred sapphire
#

This whole methodology does not work with Spectator type Pawns though. Be aware.

#

Only possessed, playing pawns

keen adder
#

Ah shit

#

Check this out, 2 pawns spawn in

#

Why does the server claim ownership of both lol

#

Just trying to get off the ground here and unreal is not doing anything it's supposed to

keen adder
# keen adder

Sorry to keep bothering you, but do you have any magic for APawns as well? Their begin play also lies

charred sapphire
keen adder
#

I see okay, I'll try your method and if it works, drive the pawns from there. Thanks man!

lost inlet
#

also what's with the "PlayerControllers don't run on clients" remark

#

they run on owning clients

#

also to make that debug output less confusing, it should at least include the name

keen adder
lost inlet
#

GetNameSafe

keen adder
#

Or no sorry

#

Log(GetControlledPawn())
Gives

Server: Pawn
Client: nullptr```
#

That's what it was

lost inlet
#

yeah I don't know what your custom Log function does

keen adder
#

But I'm finding out that BeginPlay just doesn't give enough time to properly register everything

lost inlet
#

since this is just printing a class name

keen adder
#

It prints to the screen

lost inlet
#

yeah, how?

#

I can't see your screen

keen adder
lost inlet
#

the code

keen adder
#

Also this is from BeginPlay on the Pawns

lost inlet
#

super secret Log method

keen adder
#

Bro chill lol

#

GEngine->AddOnScreenDebugMessage

lost inlet
#

yes, how does it convert the pointer you pass to a string

#

like getting blood from a stone

keen adder
#

I think you're focusing on the wrong thing here

lament cloak
#

Hey so with Iris I get this error followed by a check() failure, on the server when I try calling AddReplicatedSubObject() immediately after spawning its owner actor.

LogIrisBridge: Error: ActorReplicationBridge(1)::BeginInstantiateFromRemote Failed to find Outer [NetRefHandle (Id=596):(RepSystemId=?)]NOT_IN_CACHE for dynamic subobject

After banging my head a bit I decided to just throw a timer on it to test. If I call AddReplicatedSubObject() one second after spawning the actor, it's fine.

BeginPlay() seems to be too early.

Is there another hook sometime after BeginPlay() that it's safe to call AddReplicatedSubObject() from? I dont like setting arbitrary delays

lost inlet
#

super secret proprietary log function it is

#

but if it looks like Actor->GetClass()->GetName(), then yeah

#

that'll explain it

keen adder
#

My point is that the BeginPlay doesn't seem to properly register online functionality correctly

#

Nevermind my pseudo code logs trying to explain the situation

lost inlet
#

BeginPlay on a client is called when the client knows about the game state

#

or whenever the initial bunch about an actor is received after that

keen adder
#

Yeah, Augmentum mentioned BeginPlayingState which I'm about to try for the PC

lost inlet
#

NotifyControllerChanged on the pawn side exists on client and server and is called when posession changes

keen adder
#

Is NotifyControllerChanged the correct one to use for registering a client pawn properly?

lost inlet
#

Which on the client will either be nullptr or a valid local controller

#

define "registering a client pawn properly"

keen adder
#

I put in a 1 second delay and all the LocalController() stuff works well

#

But right on BeginPlay I get all kinds of bogus values

lost inlet
#

yes, because BeginPlay will still use whatever values in the initial bunch

#

the PC can also replicate AFTER the pawn

#

OnRep_Controller calls NotifyControllerChanged

keen adder
#

Right yeah that explains things

#

I tried controller changed and got like, 7 print messages from 2 players

#

1 sec

#

This is on just 2 pawns spawning in lol

lost inlet
#

well this output is pretty useless without any actual context

keen adder
#

Oh, just trying to set initial values -- bind controls, etc.

lost inlet
#

and what does the callstack look like when you add a breakpoint?

keen adder
#

I'm just doing this stuff in blueprint atm for quick turnaround speeds

lost inlet
#

not sure why you don't bind controls in SetupPlayerInputComponent though

#

well in BP for controls you just use IAs as an actual node

keen adder
#

Isn't that in the character class?

#

Atm I had PlayerController setting up the IAs on BeginPlay

#

I don't see where the SetupPlayerInputComponent event is

lost inlet
#

that'll be SetupInputComponent on the PC

#

but in BP, IAs are still nodes with exec pins on the player controller

keen adder
#

Yeah and that's the issue, Server PlayerController thinks it owns both pawns, and the Client one thinks it owns nothing lol

#

So I was trying to find an event for when the PC has that stuff properly initialized

#

Justt trying to expose BeginPlayingState now

verbal vapor
#

How do I get the character's root component of a player who actually initiated the input action?

#

So I can actually send to everyone whos root component the sound will be attached to?

#

GameState has the data, right?

#

Or not?

#

I am about to test this out

#

i hope that works kappa

lost inlet
#

what am I even looking at

keen adder
verbal vapor
#

This kind of works for all other people

#

except the one who initiates it

#

so i guess i will play it locally for the initiator

#

or something

charred sapphire
#

so do not use it blindly

lost inlet
#

so the input will always come from the local player

#

input actions are not networked

verbal vapor
#

look

#

when i press 1

#

the sound attaches to myself

#

then i replicate that piece of information to all other clients

#

thats the goal

#

at least

#

right now it works for all other clients (the sound is coming from direction of a player who initiated it)

#

but for the one who initiated it, it plays on other people

#

xD

#

even though i got the player controller

#

so it should be local to the guy who initiated it right

#

so multicast will point to the guy who initiated it

#

and only him

lost inlet
#

I don't know why this wasn't your first thing to test if the sound is supposed to come from this/self

verbal vapor
#

i have done that already

#

and you know what's happening?

lost inlet
#

RPCs are called within the context of this actor they are called from

verbal vapor
#

it attaches to every character

#

except the one that is supposed to attach

#

by character i mean capsules

lost inlet
#

???

verbal vapor
#

yeah

#

xd

lost inlet
#

what PIE mode

#

play as client?

verbal vapor
#

I am using steam sessions

#

2 accounts

lost inlet
#

that is irrelevant for testing in editor

verbal vapor
#

i am not testing in editor

#

since u cant test steam in editor anyway

lost inlet
#

what a pointlessly inefficient workflow

charred sapphire
#

dude

#

be nicer

#

holy hell

lost inlet
#

since unreal networking is nothing to do with steam

charred sapphire
#

you are straight up hostile to others

verbal vapor
#

? XD

dark parcel
#

I suppose it's kinda hard to test sound tho

#

in PiE

#

normally I just print string

lost inlet
#

it's hard to do it even in packaged

lost inlet
#

unless the world enhanced input subsystem is enabled, then it's very unlikely that you're going to be triggering input for anyone but yourself. but that shouldn't apply to pawns (which includes characters)

#

the multicast here will also be called in context of the actor, not just for every pawn in the scene

#

this is why testing in PIE will actually come in handy, you can add breakpoints

verbal vapor
#

I will literally make it 10th time and tell you what's going on

lost inlet
#

well yeah, the timeline here is input key released -> send RPC (nothing happens on client) -> server calls multicast -> the server and each client spawns the sound

verbal vapor
#

Yeah

#

that's correct

#

I have tested multicasting player location for example and it works fine

#

But I cannot multicast the root component of a character

lost inlet
#

well you wouldn't need to anyway

verbal vapor
#

And I am doing yoga trying to retrieve that

lost inlet
#

the client already knows what the root component is

verbal vapor
#

Yeah I wouldn't need but I do since the bp ^ is not working

lost inlet
#

which in a character should be the capsule component

verbal vapor
#

i know it makes sense right

#

but it doesnt work

lost inlet
#

so what's the testing setup here? 2 clients connected to the server dedicated server?

#

or one of them is a listen server?

verbal vapor
#

one of them is a listen server

#

but with this setup it's not supposed to be an issue

#

since listen server is a server and a client

#

this flow should work correctly

lost inlet
#

the only difference is a listen server won't use networking for server calls

#

since it is the server

#

is there any difference in behaviour regardless of who performs the action?

#

uh, regarding

verbal vapor
#

This stuff attaches sound to everyone else except the one who initiated it

#

¯_(ツ)_/¯

lost inlet
#

so if the 1st client performs the action, the 2nd client will see (or hear it) as intended? and vice versa?

verbal vapor
#

When client A initiates the input action, the client B and rest of the clients, will have attached sound on their pawn (and they can hear it)

#

This stuff is mostly working.

#

This works for every client as supposed

#

Except the caller.

lost inlet
#

wait, so the intention is for every client to hear it coming from themselves?

verbal vapor
#

No

#

XD

#

WHEN I PRESS 1

#

I WILL HEAR IT

#

AND I WANT EVERY OTHER CLIENT TO HEAR IT BUT FROM ME

#

AND ONLY ME

#

but the root component as you previously suggested doesnt work as supposed

lost inlet
#

that's what the original thing you showed should do though? the thing you said was "mostly working" will make it come from the local player's pawn

verbal vapor
#

yes

#

as i said it's mostly working

#

but when i fire this up

#

the local player hear it from other player

#

not from himself

#

XD

#

this is fucked up i promise

lost inlet
#

"not from himself" means that it doesn't play at all or that it plays from the wrong source?

verbal vapor
#

Client A initiates sound
Client B, C and the rest hear it from the right source (client A)
But Client A hears it from Client B

magic vessel
#

Is Client B the listen server?

verbal vapor
#

Hold on

magic vessel
#

Or rather, which client is hosting?

lost inlet
#

It didn't sound like there was much difference. But I suppose there is a test you can do, from the input action, you can have a Has Authority branch, and just call the multicast if authority

#

but I'm pretty sure a listen server host will just call server RPCs locally without networking

verbal vapor
#

i mean, as i said before, when i was using get actor location for example, it successfully multicasted it

#

from A to B

#

B to A

#

no problem

#

let me package it really quick

#

Okay so

#

A is a client and when he's pressing 1 the sound attaches to B, so it's wrong here

#

But B hears it from A so it's correct

#

And B is the host

magic vessel
#

Okay, then it's somehow not receiving the multicast?

verbal vapor
#

It's receiving it

#

For sure

#

But somehow the component is wrong

#

How? I dont know

lost inlet
#

well it has to receive it because the sound is from the multicast only

verbal vapor
#

yes

lost inlet
#

I'm not sure how likely it is the root component is wrong, you would have greater problems than this sound if this was the case

#

like movement being broken

#

but you could even debug print the location of the component if you want to check that

#

I'd throw the display name of the pawn into that debug print though

verbal vapor
#

So here is the thing...
Client A attaches it to itself but client A hears it from other clients not himself, while the rest of the clients hears it from the right source
Client B attaches it to itself but client B hear it from other clients not himself, while the rest of the clients hears it from the right source

magic vessel
#

Is this code running on the player controller or pawn? Or somewhere else?

lost inlet
#

I assumed the pawn because of the target in the nodes

lost inlet
#

a character is a pawn for ref

verbal vapor
#

yeah u can call it that way

#

since it's based on pawn

#

and pawn is an actor

lost inlet
#

though I am a little curious about your input mapping implementation here. the listen server host will have a valid controller for all players in the session, so I was wondering if anything else was happening in addition to the adding of that IMC

magic vessel
#

Currently loading up my project to see if I can figure this out

#

Seems to work fine

#

Add in a draw debug box, to visualise which component is being used

#

Might be the enhanced input as sswires mentioned

lost inlet
#

It's a bit of an odd place to enable an IMC in BeginPlay, since there's even a chance the controller isn't set on the client yet. But if you've somehow enabled input on all pawns as the host, then I can imagine that causing some weirdness

#

Enabling an IMC on its own isn't going to do that, and a localplayer doesn't exist for remote players anyway

verbal vapor
magic vessel
#

But the IMC mapping is marked as cosmetic only? So the host wouldn't be able to do anything anyway

magic vessel
verbal vapor
#

Yeah I have the IMC setup from the template third person gamemode

lost inlet
#

Well it needs this, which is a local player subsystem. no local player for remote players

#

Here I was wondering what was hiding above in the Then 1

verbal vapor
lost inlet
#

the "Then 1"

#

it's out of the frame in the screenshot

magic vessel
verbal vapor
magic vessel
lost inlet
#

hmmm I would remove anything to "fix" audio to rule it out

verbal vapor
#

i can test it out without it

lost inlet
#

though it's just attenuation so I doubt it affects panning

#

unless you have something else for that

verbal vapor
#

i meaaaan

#

the thing is

#

it's nothing wrong with panning or attenuation

#

since the source is for sure at different pawn

lost inlet
#

well add the suggested debugging

#

so you can at least visualise the problem

magic vessel
# verbal vapor

Looking at that, why are the rotation values going into a location override?

#

Haven't used that function before, so might be a red herring

lost inlet
#

yeah get the debug box in there and maybe a print string so you know which actor the multicast came from

#

like everything in that screenshot looks good to me

#

it is pretty simple afterall

verbal vapor
#

hold on

#

let's run it then

magic vessel
#

I'd increase the thickness and duration

lost inlet
#

well you'll need to connect the exec

#

and probably an easier to see line colour than black

verbal vapor
#

packaging, uno momento

#

u said my workflow is shit, 2 days ago i was packaging, uploading (for 15 minutes at least each build) and asking friends to come test steam sessions

#

💀

#

now what i have this is supreme workflow to me

#

fuuuuck

#

it was because of the sequence thing

magic vessel
verbal vapor
#

this works correctly now

verbal vapor
magic vessel
#

xD

#

All been there

#

Hours of debugging for a simple fix

verbal vapor
#

simple fix -> getting rid of a feature that broke everything

#

thanks for help

#

So I have plugged in the sequence 1

#

And it's spawning the sound where it is supposed to be

#

But the sound comes from the other character

magic vessel
#

If I had to guess I'd say it's the GetPlayerController that is doing that

#

I'd add in a IsLocallyControlled branch before

verbal vapor
#

right

magic vessel
#

I need to go now for a few hours, if that doesn't work then I'll have a look when I get back 🙂

verbal vapor
#

thanks

#

or maybe i will just delete the player controller

#

and it's gonna end up as ref to 'self'

#

ah no nvm

#

it doesnt work like that :-D

#

yeah well it doesnt work :-D

dark parcel
#

use is locally controlled node

verbal vapor
#

i will test this out xD

lost inlet
#

I think the original train of thought was probably more appropriate

#

but if the possessing player controller is local

#

rather than GetPlayerController(0)

verbal vapor
#

🫡

#

is it?

#

hold on XD

#

the attenuation override doesnt work now

#

like the whole fix

#

ah gotcha

#

so it's still broken

#

xD

#

so let's test this one out then

#

nah this one brings the old problem back

#

oh maybe i am retarded

#

am i supposed to use local player controller?

#

yeah well i am not retarded then

#

🫡

lost inlet
dark parcel
#

stop using get player controller with index?

lost inlet
#

uh

#

GetControlledPawn

#

just replace with GetController

#

check if it's a local controller

dark parcel
#

can't you just use is locally controlled right away

#

it's in player controller

lost inlet
#

oh yeah, so imagine that with one more red squiggled node

#

though BeginPlay checking the controller can be sketchy. there's no guarantee it'll be reliably set by this point

#

ReceiveControllerChanged in BP is more reliable

verbal vapor
#

i dont have such thing

#

as get controlled pawn

lost inlet
verbal vapor
#

my friend

lost inlet
#

cast it to player controller then?

verbal vapor
#

XD

#

yeah u see i have used this before

lost inlet
verbal vapor
#

ok my friend

lost inlet
#

player controller is a child class of controller

#

AI controllers also exist

verbal vapor
#

XD

lost inlet
#

well I've tried to be patient enough

#

though I doubt you're intentionally being obtuse

verbal vapor
#

is that intelligent way of saying i am stupid

lost inlet
#

SetAudioListenerAttenuationOverride is a player controller function

#

so you need to give that the cast result as the target

#

IsLocallyControlled is a pawn function, so "self" is sufficient here

hoary spear
#

Try to always work in context when you can, when using references

#

Especially for less experienced people it helps a lot

dark parcel
#

if you don't know how to use references maybe steer away from multiplayer

verbal vapor
#

X D

#

keep yapping

#

if u dont know how to ride a bicycle, dont ride it

#

fam acting like sitting on a problem for couple of hours will make you better each minute

keen adder
#

Hey so, seems like a common problem:

When I run my game, the Server can't see the clients movements, what's the issue?

#

Looks like it works fine in the content examples without any additional changes

#

Is there a checkbox somewhere I need to click to make the clients movements authoritative?

verbal vapor
#

If you're using default template i.e (third person), it's replicating client character movement by default.

#

And that's what's supposed to be enabled by default.

keen adder
#

Oh no I'm using Pawns, not characters

#

But the Client can see all movements, however the Server only sees itsef move, it doesn't see the client move

#

I wonder if there's something I'm missing, or if both working is some behavior built into the Character class that I don't have with Pawn

verbal vapor
lost inlet
#

CMC assumes character too

#

so I guess you're rolling your own movement?

verbal vapor
#

@lost inlet yes this fix the issue

lost inlet
#

the first two nodes on the left are pretty superfluous

#

"target is pawn", you're already a pawn

#

though the first node not entirely, that has to feed into the cast only

#

just unnecessary for IsLocallyControlled

dark parcel
charred sapphire
#

Dumb question:

Should calling, a GetGameState from the Client during PostInitComponents result in a nullptr exception? I thought it was a safe call.

Works perfectly fine on the ListenServer, but DelegateAccessHandler starts screaming at me during runtime on the Client.

I mainly wanna start listening to a delegate at this point. 🧐

Here is the piece of code, nothing special:
(I know the variable is useless for the time being but it helps me debug this)

void ACPlayerController::PostInitializeComponents()
{
    Super::PostInitializeComponents();

    LogOnScreen(GetWorld(), FString::Printf(TEXT("Starting to listen to delegate.")));
    ACGameStateBase* GameState = Cast<ACGameStateBase>(GetWorld()->GetGameState());
    GameState->OnGamePauseStateChanged.AddDynamic(this, &ACPlayerController::OnGamePauseStateChanged);
}
fossil merlin
#

[Q] Anyone have experience with replicated AnimNotifies? When I test my game in PIE, everything fires as it should, but in Standalone Game (as client) or in built game (with dedicated server) they rarely seem to fire. Any ideas what would cause this behavior? I've tested it with a simple Print String node to validate and they are indeed just failing to fire consistently. Currently running 5.4.2

lost inlet
#

The only reliable place you'll get a game state on a client is in BeginPlay

verbal vapor
#

@lost inlet my man

dark parcel
#

like what to replicate?

verbal vapor
#

this just works too

dark parcel
#

the animation will play on both machines

verbal vapor
lost inlet
# verbal vapor

While it's a lot simpler, it can be problematic on listen server if you don't check if it's locally controlled

keen adder
fossil merlin
lost inlet
#

it's likely to be a problem

dark parcel
keen adder
#

I thought so too, but the server replicates perfectly onto the client

#

So.. 🤷‍♂️

dark parcel
verbal vapor
dark parcel
#

the anim notify will be called in respect of each machine

fossil merlin
dark parcel
#

but which one you want to use is up to your design

#

show code / anims

lost inlet
#

It is the server

#

CMC does that and prediction

sharp hamlet
#

hello, what seems to be wrong in this? this is a code to get the number of connected clients.

keen adder
#

Aight, makes sense. I'll prob suck it up and buy a plugin anyway, I hear CMC on it's own is a disaster once lag/packet loss is factored in

lost inlet
#

Not really, CMC is pretty well battletested

#

It's just annoying to modify

dark parcel
lost inlet
dark parcel
#

to get the number of joining players you can use Game Mode Post Login

sharp hamlet
dark parcel
#

wait 1 second repeat endlessly = addresses late joiners?

#

Use Game Mode post login to track incoming player

dark parcel
#

but yea like sswires also says, widget don't replicate

#

don't bother calling RPC there

lost inlet
#

if you need to replicate state about the game, well there's an appropriately named concept of a game state actor

sharp hamlet
#

no, my POV was to check the no. of connected players every 1s. so ig i have to get the data from Gamemode only? a bit confused

lost inlet
#

though I think this already tracks the number of players anyway

#

since there's an array of player states within it

#

clients also don't know about any player controllers except their own

sharp hamlet
lost inlet
#

it is not sarcasm

dark parcel
lost inlet
#

widgets are not replicated

sharp hamlet
#

so get data from GM instead of the RPC?

dark parcel
#

for easy mode, just get the player array and update that on tick

lost inlet
#

game modes do not replicate

#

they only exist on the server

verbal vapor
lost inlet
#

yes within the context of a pawn

verbal vapor
#

so what is this get local player controller for

#

to troll people?

lost inlet
#

no

sharp hamlet
#

thanks sswires and coldsummers, trying it

lost inlet
#

but it's kinda discouraged for multiplayer stuff since most of the time it's not doing the thing you think you mean by it

lost inlet
#

GetPlayerController(0) will just mean the first player controller, and on a client, this will just be the local controller

#

even more complicated if you want split screen, since then there are 2 player controllers locally

sharp hamlet
#

hey, so its completely futile to use the "get num player controllers" in WBP?

lost inlet
#

yes since on a client that'll be returning 1 most of the time

dark parcel
#

is that even a real node? 0o

#

i mean if it come with stock ue

#

never seen it

lost inlet
#

assuming it is but I don't know

#

but safe to assume it's just counting controllers, which will be 1 unless you have splitscreen

sharp hamlet
dark parcel
#

For easy mode ,

On Tick -> Get Game State -> Get Player array -> Get Length

charred sapphire
#

Sorry to chime in again, but at the risk of looking like a fool, I'd like some help with this: https://gist.github.com/rolandsarosy/69165a64594643490b5b2c862bfc5ee8

This is a GameState child, that I made for the following reason: **I wanted to create a multiplayer-compatible game paused/resumed delegate to show and hide a "pause menu" widget. **

The ListenServer and Clients can all attempt to pause the game (PlayerController has a Server method that calls the GM's SetPause/ClearPause functions) and unpause the game (from either the Widget or by keybind).

I can go into more detail on how these bits work (I can even push the git commit if that helps) but that's not my main issue.

I've been battling with replication for the past few months pretty extensively, but in this case, I just don't know why the OnRep does not get called for the Client always. It's weird, I think everything is in place though, but as the video too shows, the game pauses (handled by the GM) but the OnRep() function only gets called on the server.

Shouldn't it get called on the client too? I just really don't know at this point where I'm fucking up.

Gist

GameState changes for a multiplayer-compatible pause-unpause delegate - CGameStateBase.cpp

#

According to my little whiteboard here, the GameState exists everywhere too...

dark parcel
#

Game states exist in every machine but its not owned by clients, so calling server RPC there as client will not do anything, incase you are doing that

charred sapphire
#

I don't think I am?

dark parcel
#

well I wouldn't know

#

anyway I heard from reputable person here, pausing in mp kinda a shit show

#

maybe consider changing global time dialation to very small number

#

instead pausing the game compeltly

charred sapphire
#
bool ACGameModeBase::SetPause(APlayerController* PC, FCanUnpause CanUnpauseDelegate)
{
    const bool bCouldPause = Super::SetPause(PC, CanUnpauseDelegate);

    ACGameStateBase* GameStateBase = Cast<ACGameStateBase>(GameState);
    GameStateBase->ChangeGamePausedState(bCouldPause);

    if (!bCouldPause) UE_LOG(LogTemp, Error, TEXT("GameMode was unable to pause the game."))
    
    return bCouldPause;
    
}

I'm overriding the GameMode's SetPause (and CLearPause) function too, that calls the GameState's ChangeGamePausedState, which changes the variable, which should launch the OnRep everywhere.

#

It's all running on the server too, since only the GM starts this whole ordeal

dark parcel
#

what is being OnRep? curious

charred sapphire
#

uuuh, it's in the GitHub gist, lemme copy it here too

#
void ACGameStateBase::ChangeGamePausedState(const bool bShouldBePaused)
{ 
    if (!ensure(HasAuthority())) return; // Should only be called by the server.
    
    bIsGamePaused = bShouldBePaused;
    OnRep_IsGamePaused(); // OnRep_Foo() functions don't trigger automatically on the server. Clients will ignore the double call of the function as they already have the correct state set.
}

void ACGameStateBase::OnRep_IsGamePaused() const
{
    LogOnScreen(GetWorld(), FString::Printf(TEXT("OnRep for IsGamePaused triggered.")));
    OnGamePauseStateChanged.Broadcast(bIsGamePaused);
}
#

but again, the Gist has both .h and .cpp files there so it's easier to understand

dark parcel
#

is this Tom Looman tutorial? have you try asking in his discord?

charred sapphire
#

he has absolutely no discord for his course

#

this is not strictly related to that though

#

i've been making it better and improving, refactoring stuff for a while

dark parcel
#

I have no idea sorry, if bIsGamePaused is marked as repnotify I do reckon OnRep should be called

charred sapphire
#

yeah, i do reckon too, i'm going crazy

#

i appreciate your help though, really

dark parcel
#

don't lose hope if exi is around you can probably ask him

#

most of the wise elders are not around atm

charred sapphire
#

funniest thing is, in like... 1 out of every 30 "pausings", it works

#

that's what's most puzzling to me

latent heart
charred sapphire
#

lmao, yeah, it probably would be

#

it's been there for the past 4 months, so i'm pretty sure it soaked right into the whiteboard though

#

i can recite that thing in my dreams too

latent heart
#

You can remove stuck on marker by writing over it with erasable marker.

#

(or actual cleaning fluid)

#

You can remove non-erasable marker the same way.

charred sapphire
#

yeah yeah yeah, i'm just joking

hoary spear
#

sounds like this should just work really

charred sapphire
#

yes 😦

hoary spear
#

testing locally ?

charred sapphire
#

DebugGame, and:

hoary spear
#

single process ?

charred sapphire
#

uuuh, i'm sorry i'm not quite sure what you mean by that 😦

#

could you elaborate please?

hoary spear
#

Advanced Settings-> Run as single process should be toggleable

#

Run under One Process

charred sapphire
#

thanks! lemme check

#

Yes, it is toggled.

#

Lemme check it untoggled.

#

oh i see what it does now, that's kinda cool

#

nop, same behaviour 😦

i didn't work like... 7 times, worked the 8th and does not work once more

#

i'd be more convinced of my own failings if it didn't work... ever

but the fact that sometimes it does, is what makes this really weird

#

might just try a multicast instead of working with OnReps

hoary spear
#

testing it here, it acts strange atm

charred sapphire
#

Oh you could reproduce the issue?

#

I really appreciate the help you put into this.

hoary spear
#

works fine here

charred sapphire
#

Crap.

hoary spear
#

just for testing GS got this

#

replication settings

#

basically same functions as you got , setting the bool from the function input , replifetime for the bool, using OnRep function, calling OnRep on server aswell

charred sapphire
#

That does look similar to my solution. All this above is in GS?

hoary spear
#

yeah

#

I just skipped all the checks etc

charred sapphire
#

yeah, reasonable

hoary spear
#
void AMyGameState::SetGamePaused(bool bShouldBePaused)
{
    bGameIsPaused = bShouldBePaused;
    OnRep_GameIsPaused();
}
charred sapphire
#

Lemme see if the GS BP settings match.

#

Yeah those seem like all the default settings, which is what I have on my end too.

charred sapphire
#

May I ask, what engine version are you using in this example?

keen adder
#

So, odd question: NetMulticast sends an RPC to server + all clients right?

latent heart
#

No

keen adder
#
UFUNCTION(NetMulticast)
void MulticastFunction(){
    DisplayMsg("MulticastFunction");
}```
Meaning when calling this function, I should see "MulticastFunction" displayed for all clients
latent heart
#

NetMulticast can only run on the server and it sends it to all other clients.

#

(other clients in the case of a listen server where the server is also a "client")

#

You can only send single-target server rpcs from a client.

#

If you try to net multicast from a client, it will just execute locally.

keen adder
#

Right, Client -> Server -> Multicast

#

But, when I call multicast from the server, I get this

#

Shouldn't it also display "Client: MulticastFunction"

#

Oh shit no, I'm actually calling it from the server's client

#

That is, the host's machine. Not the server

#

Man is there any way to show a warning form calling that from a client?

latent heart
#

if (GetWorld()->GetNetMode() == NM_Client) { UE_LOG(LogTemp, Error, TEXT("CLIENT MULTICAST!"); }

keen adder
#

Where would that be put though, in the multicast function?

#

Or the function calling it?

latent heart
#

In the caller, I guess.

#

Because the implementation is expected to be on the client.

keen adder
#

Ah, yeah im just worried about when I forget to check for client, and then wonder why it doesn't work lol

#

But hey, I've got some other unexpected behavior

#
UFUNCTION(Server)
void Multicast_Server(){
    Multicast_Clients();
}
UFUNCTION(NetMulticast)
void Multicast_Clients(){
    Print("MulticastFunction");
}```
#

Looks good right? Call server -> Multicast

#

This works well on the client (Prints the msg on Server+Client)

#

but the listenserver only executes it locally (Prints on Server only)

#

Any idea what I'm doing wrong here?

keen adder
# latent heart In the caller, I guess.

Heya, really sorry to summon ya back if you don't mind 1 last piece of help
Calling a UFUNCTION(Server) on the server client seems to call it on it's client and not the actual server, so it just runs locally. You know the right way to call this?

latent heart
#

A cllient doesn't mean "another computer"

#

It means "not hosting the game"

#

UFUNCTION(Server) will execute locally on a server and will be sent to the server from a client - if called on a client-owner actor.

keen adder
#

I assumed the listen server has both the server and client as 2 separate entities on 1 machine?

latent heart
#

No

#

They are the same entity.

keen adder
#

So the host still needs to call to the server before a multicast

#

Ah, so why does the host fail the multicast?

latent heart
#

Do you ahve any other clients?

keen adder
#

Either calling the multicast directly, or from server first. It only runs on itself

latent heart
#

Multicast isn't sent to itself on a listen server.

#

(I think)

keen adder
#

This is from Client -> (Server -> Multicast)

river shore
#

Hello guys!
So I am having this problem when I am trying to do an Interaction system. I am calling an interface in an Actor Component attached to the character and then exit the event on a door. Inside the door, I want to call an event to the server (RPC) but for some weird reason it wouldn´t exc on the server

void ABaseDoor::OnInteract(UObject* HitObject, UPrimitiveComponent* HitComponent, APlayerController* PlayerController)
{
    if(PlayerController->IsLocalController())
    {
        if (GetOwner() != PlayerController)
        {
            SetOwner(PlayerController);
        }
        //Set bIsOpen depending on Client or Server
        if(HasAuthority())
        {
            bIsOpen = !bIsOpen;
            OpenDoor();
        }
        else
        {
            bIsOpen = !bIsOpen;
            OpenDoor();
            Server_SetIsOpen();
        }
    }
}

_________________________________________________
h.
    UFUNCTION(Reliable, Server, WithValidation)
    void Server_SetIsOpen();
    void Server_SetIsOpen_Implementation();
    bool Server_SetIsOpen_Validate();

Any Ideas?

keen adder
#

And this is from the Server -> (Multicast) or Server ->(Server->Multicast)

latent heart
#

Player State, Player Controller, Pawn usually.

keen adder
#

Can't get the server to properly multicast to any other clients

latent heart
#

Then on the server you forward that event back to the door.

river shore
latent heart
river shore
keen adder
# latent heart Show all the _actual_ code you're using?
UFUNCTION(Server)
void Multicast_Server(){
    Multicast_Clients();
}
UFUNCTION(NetMulticast)
void Multicast_Clients(){
    Print("MulticastFunction");
}```
Just this. Calling Multicast_Server on the client works, but calling either on the Server runs locally only
latent heart
keen adder
#

Oh no, this is angelscript -- all that is automatically baked in lol

#

However it works perfectly from the Client side

latent heart
#

Then go ask the angelscript guys why it doesn't work 🙂

keen adder
#

so it can't be anything like that

keen adder
#

and it will properly RPC to all clients? Nothing needed in between?

latent heart
#

The server is the only one that can NetMulticast.

#

(correctly)

keen adder
#

So there's some strange behavior that sort of interferes with that logic

#
    UFUNCTION(Server)
    void Multicast_Server(){
        Print(GetLocalPlayer());
        Multicast_Clients();
    }
    UFUNCTION(NetMulticast)
    void Multicast_Clients(){
        RepPrint("MulticastFunction");
    }
#

If I stick GetLocalPlayer in the server function

#

It should print the servers localplayer, no matter where it's called right?

latent heart
#

Correct

keen adder
#

But calling it from the client shows nullptr

latent heart
#

Go ask the angelscript guys why it doesn't work.

keen adder
#

But from the server shows it's localplayer, and it does not multicast lol

#

lol alright

latent heart
#

This would work perfectly in straight c++.

#

Or even BP.

keen adder
#

Oh man, that's a good point. I'll try in both to compare!

#

They created "It Takes Two" in angelscript, which has perfect online so I figured it should work correctly

#

but you're right none of that really makes sense

latent heart
#

You may have incorrect specifiers.

keen adder
#

Maybe, yeah. anyway thanks man! I'll try out BP to double check 🙂

charred sapphire
# hoary spear 5.4.4

Thanks. I've observed that it works properly before the Client's Controller has gained Posession of the Pawn, but does not work after. I'll see what I can do with this information.

keen adder
latent heart
#

What are you calling these methods on ?

#

Your local PlayerController?

keen adder
#

Yup!

#

Just an empty project to get all the RPC functionality going

latent heart
#

That may be the issue.

#

The player controller isn't replicated to all clients, only the owning client.

#

So running a multicast on a PC will only notify the owning client.

keen adder
#

Oh, shit

#

Yeah that checks out, because the client PC IS on the server, but not the reverse

latent heart
#

👍

keen adder
#

I'll move it to the Pawn class real quick

#

Bruh

keen adder
latent heart
#

Wizard*

keen adder
#

Thankyou very much lol

#

Yes* Me right now:

charred sapphire
#

@hoary spear , @dark parcel

Thank you for all the help. In the end, I could not figure out why OnReps did not work most of the time, it's one of my most puzzling issues since starting to work with multiplayer. Probably was something inside some internal function which decided when to call OnRep() or not, I truly don't know.

In the end, I gave up because I suck, and wrote a simple multicast RPC, since most of this logic could only ever be called from the server anyways. This means I don't have a variable "holding" the flag whether the game is paused or not, only a transient event shows this to Players currently on.

I guess this could be an issue in cases where someone joins late and the game is paused at that moment, since OnReps get called immediately and this is just a transient event.

(This is not a real game just a study project so, whatever.)

This is my end result, and I really, truly appreciate all your help.

vapid gazelle
#

Hey gang, could use a little help. Is it normal for the server to not be sending updates to the clients about the server player's position unless the server player is actively doing something, such as running around or rotating the character?

Problem: have a character ability to hold themselves floating in mid-air (sets velocity to 0 on the component movement, and sets the gravity to 0) and I notice that as long as the server player using this ability keeps moving their mouse, the client sees them floating in mid-air exactly where you would expect, but the instant the server player stops doing anything, the client sees the server player fall down to the ground, effectively predicting it having normal gravity.

It looks like gravity scale isn't replicated server->client, which I suppose makes sense by looking at the implementation which has no replication declared:

/** Custom gravity scale. Gravity is multiplied by this amount for the character. */
UPROPERTY(Category="Character Movement (General Settings)", EditAnywhere, BlueprintReadWrite)
float GravityScale;

However my understanding is that the character movement component is also somewhat special, and doesn't quite use the same replication pathways that I'm used to?

I'm trying to grok if I should manually replicate GravityScale to clients, or if this is the wrong paradigm and I should re-think how I'm doing this altogether? I might be going against how this was meant to be implemented and replicated

nova wasp
#

They get replicated position+velocity along with crouching/movement mode and then simulate some parts of it locally

latent heart
#

It's prbably not replicating the gravity change.

vapid gazelle
#

Is it normal for the server to not replicate the position / rotation of the server player to clients if there has been no input to indicate it would have changed? It seems like it's trying to optimize not sending that information over the network if it thinks there's nothing to report.

nova wasp
#

Yes, why would they send things when nothing changes?

#

The issue is your simulation is doing different things on each side

vapid gazelle
#

Fair enough.

nova wasp
#

A movement mode could help here I suppose

latent heart
#

Or jsut a replicated state change. OnRep -> set gravity based on state.

nova wasp
#

Yeah, that's probably easier

burnt coral
#

Lets say a player leaves the online session and has 500 cash, 100 health, and etc etc.. And I want to save their information so its the same when they load back in.. Same for the location.. Would this get stored in the PlayerState?

#

Or where would I save player data at?

latent heart
#

The player state will be lost after a while.

magic vessel
#

Could use the Player Save Subsystem from EOS?

#

Save it from the server details (never trust the client with this info) and then you should be able to load it back in without the client being able to manipulate it

burnt coral
latent heart
#

Game instance?

#

The trick is then getting the right player id from the reconnecting player.

#

Using their steam or eos id is a good bet.

shadow aurora
#

So I've got this ability that is intended to deal damage to enemies when they've traveled a certain distance. I'm currently tracking that using OnCharacterMovementUpdated, but it's causing some major issues. For some reason the total distance traveled that I'm tracking is vastly different between uses despite using 2D vector distances and knowing that I am absolutely traveling the same distance each time.

Anyone know if there's anything I can do to get an actually consistent and real distance to track? I'm imagining this has something to do with client/server corrections during movement?

hoary spear
#

isnt that sub-sampling?

magic vessel
shadow aurora
keen adder
#

Is it possible for a client to replicate it's variable to the server?

#

I've got a var with OnRep, Server->Client works, but Client->Server does not trigger at all

lost inlet
#

You send an RPC

keen adder
#

Right, so OnRep variables are Server->Client only?

kindred widget
#

Replication in general is server to client only.

keen adder
#

Ah, so to properly use OnRep vars Id have to do

Client RPC to Server, then Server OnRep Var?

kindred widget
#

You ServerRPC to the server. First word defines the machine the RPC is being sent to. But generally yes.

keen adder
kindred widget
#

Not in C++.

keen adder
#

I'm RPCing the server, it's Sending OnRep back to all clients except itself lol

#

So the server needs to run the same code in the OnRep?

#

Since it doesn't OnRep itself

lusty kelp
#

what about unity mutiplayer tho, i got it all figure out!!!

#

all you guys saying are false

#

not to be mean

lusty kelp
#

just saying that unity have a backend where as unreal u got to do extra work

#

what most people are here giving people wrong advice while keeping what they learn to themselves

kindred widget
#

Kind of wild accusations. I'm not sure what you think people are keeping to themselves. There are dozens of forums and many more blogs that have networking guides and techniques to things.

lusty kelp
#

bro bro not to chip nobody ears off but unity and unreal i learnt but switch over tto unity and vila

#

i had a mutiplayer in like an hour

kindred widget
#

I'm happy for you and your Unity. You can have multiplayer in Unreal in about.. well, no time at all. You literally install it and run a map in PIE as listenserver with 2 players.

lusty kelp
#

LOL

#

its more complex then that

kindred widget
#

Oh, were there extra conditions? You didn't really specify. You simply said "i had a mutiplayer in like an hour". Two characters running around and seeing each other move is multiplayer.

lusty kelp
#

yes but hole punching u got to do in order for people to connect across the globe

#

or atleast do port forward

#

some altho take port forward away

#

so the only option is to rent or create or hole punch

kindred widget
#

You have to manage that yourself in Unity? That sucks. I'm sorry for you. Unreal's online subsystems do that for you mostly.

lusty kelp
#

no i got a mutiplayer up

lament flax
#

how much performance does it take to serialized all data for a struct suign NetSerialize ?

lusty kelp
#

enough to screw in a lightbuilb lol

lament flax
lusty kelp
#

no i do unity ty

kindred widget
#

He's a troll. Don't take him too seriously. I'm just bored.

lusty kelp
#

and who calling a troll boy

lament flax
#

if you like Unity so much why bothering UE here

lusty kelp
#

um freedom of speech

kindred widget
#

Freedom of speech protects you from being put in a firing line for saying that your governmental leaders suck. It doesn't actually allow you to say anything you like, anywhere you want.

lament flax
#

reminds me people insulting people then saying "where is my freedom of speech"

lusty kelp
#

how many voices are in ur head

lament flax
kindred widget
vapid gazelle
lusty kelp
#

talking about this my Gs

lament flax
lusty kelp
#

its a unity mp

lament flax
#

and ?

lusty kelp
#

and what

kindred widget
lament flax
lament flax
#

but this will come with time

lusty kelp
#

i show you that to show you proof

lament flax
#

proof of what

dusty quartz
#

Hey, I'm creating a multiplayer card game and I have created a state machine component on the game state to mange state changes (mostly phases of the game). I have a function I'm calling on the component where a state changes called "on begin state". On my base match state UObject bp, I want to call an event on all connected clients to play a widget animation (To show the new phase name). What is the best way to replicate this change to all clients ? Basically my question is, how can I replicate an event from the game state to all connected clients ? I tried using a multicast but for some reason the animation only plays on the server and not on the client.

lament flax
#

i get an issue where if i run the commented line, the PostReplicatedChange event wont be called on client, even tho the Amount changed aswell as the Item ptr

void USLBaseInventoryComponent::Internal_SetAmount(FSLFastInventorySlot& Slot, int32 Amount)
{
    Slot.SetAmount(Amount);
    
    if (Amount <= 0 && IsValid(Slot.GetItem()))
    {

    Slot.SetItem(nullptr); // if we run this, the fast array item wont call its PostReplicatedChange method on client
        Slot.SetItem(InventorySlots.Items[0].GetItem()); // this would work (because InventorySlots.Items[0].GetItem() will return a not nullptr ptr)
    }
    
    InventorySlots.MarkItemDirty(Slot);
    OnPostReplicatedChange(Slot);
}

// FA Item

UPROPERTY() TObjectPtr<USLItem> Item = nullptr;

void FSLFastInventorySlot::SetItem(USLItem* NewItem)
{
    Item = NewItem;
}
bool FSLFastInventorySlot::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
{
    Ar << SlotIndex;
    Ar << Item;
    Ar << Amount;
    Ar << MaxStackableAmount;
    Ar << CachedItemTag;
    
    bOutSuccess = true;
    return true;
}

after some testing the issue only happens when changing the Item property to null

ashen plume
#

ive been working through a custom cmc in c++, and saw that this is being called by phys custom, but theres is actually zero documentation on using it

kindred widget
lament flax
#

The weird thing for me is it breaks when setting the member Item to nullptr (or maybe any other value)

elfin creek
thin stratus
#

A multicast should work fine too if called inside the GameState or the Component (if marked as replicated).

verbal vapor
#

did the guy really come here to shit on people using UE

clever hound
#

Do I need to set the mesh component to be replicated if I want to set the **visibility **of the mesh via OnRep function? It doesn't seem to work without setting the whole component to be replicated

lament flax
#

no you dont need to

#

but the class (i assume actor) where you have your visibility onrep needs to be set to replicated

clever hound
# lament flax but the class (i assume actor) where you have your visibility onrep needs to be ...

The bools are the replicated variables which should fire the OnRep.


void AVRPlayerCharacter::OnRep_SkinStateChange()
{
    ArmsSkinMesh->SetVisibility(bShowArmsSkin);
    NeckSkinMesh->SetVisibility(bShowNeckSkin);
    TorsoSkinMesh->SetVisibility(bShowTorsoSkin);

    if(OwnedCharacterDisplay)
    {
        OwnedCharacterDisplay->ArmsSkin->SetVisibility(bShowArmsSkin);
        OwnedCharacterDisplay->NeckSkin->SetVisibility(bShowNeckSkin);
        OwnedCharacterDisplay->TorsoSkin->SetVisibility(bShowTorsoSkin);
    }
}```
#

Then I set the bool on ServerRPC

lament flax
#

show what is SkinStateChange

#

also, are you using a listen server ?

#

also, apart if you are doign some custome net serialization, each bool will replicate randomly on their own

#

so when you run OnRep_SkinStateChange, some bools might not be updated

clever hound
clever hound
lament flax
lament flax
clever hound
lament flax
#

okay so your server is a dedicated one

clever hound
# lament flax what property calls that ?
void AClothingBase::EquipClothing(AVRPlayerCharacter* Player)
{
    if (HasAuthority())
    {
        if (Hat)
        {
            Player->HatItemData = InventoryItemData;
            Player->RepNotifyHatMesh = InventoryItemData.DisplayMesh;
            Player->OwnedCharacterDisplay->RepNotifyHatMesh = InventoryItemData.DisplayMesh;
            
            Player->bShowNeckSkin = bNeedNeckSkin;
        }```
And then there is ```Player->OnRep_SkinStateChange();``` bellow that
Is that what you mean
#

That is in AClothingBase

lament flax
#

this isnt how OnRep function should be used

#

you usually bind them to a property, when you change the property on server it will call the OnRep on client (depending on your replication settings)

clever hound
#
        bool bShowNeckSkin = false;
    UPROPERTY(ReplicatedUsing = OnRep_SkinStateChange)
        bool bShowArmsSkin = false;
    UPROPERTY(ReplicatedUsing = OnRep_SkinStateChange)
        bool bShowTorsoSkin = false;```
it does
lament flax
#

so there is not variable SkinStateChange

#

you should rename it (the function)

lament flax
clever hound
#

Ahhh

clever hound
#

Ok so I should set seperate OnRep function for each of the bools

lament flax
#

you should do the following:


    UPROPERTY(ReplicatedUsing = OnRep_bShowNeckSkin)
        bool bShowNeckSkin = false;
    UPROPERTY(ReplicatedUsing = OnRep_bShowArmsSkin )
        bool bShowArmsSkin = false;
    UPROPERTY(ReplicatedUsing = OnRep_bShowTorsoSkin )
        bool bShowTorsoSkin = false;

void AVRPlayerCharacter::OnRep_bShowNeckSkin()
{
    NeckSkinMesh->SetVisibility(bShowNeckSkin);
    if(OwnedCharacterDisplay)
    {
        OwnedCharacterDisplay->NeckSkin->SetVisibility(bShowNeckSkin);
    }
}
void AVRPlayerCharacter::OnRep_bShowArmsSkin ()
{
    ArmsSkinMesh->SetVisibility(bShowArmsSkin);
    if(OwnedCharacterDisplay)
    {
        OwnedCharacterDisplay->ArmsSkin->SetVisibility(bShowArmsSkin);
    }
}
void AVRPlayerCharacter::OnRep_bShowTorsoSkin ()
{
    TorsoSkinMesh->SetVisibility(bShowTorsoSkin);
    if(OwnedCharacterDisplay)
    {
        OwnedCharacterDisplay->TorsoSkin->SetVisibility(bShowTorsoSkin);
    }
}
clever hound
#

I just tried to make it cleaner by doing it with 1 function

#

But nvm then

lament flax
#

yeah thats not how it works

keen adder
#

Heya, so I noticed my OnRep vars in my Movement component happen instantly
(Switching animations and stuff)

#

But my OnRep vars in my PlayerStats (switching items the player is carrying) take about 0.5-1 seconds from server->client

#

Is there a legit reason for this? The code in both is nearly identical

upbeat basin
#

If I want my actor to receive function calls on server from any client at any time, I am forced to have a server RPC on any of my locally owned actor which calls the desired function on desired object, right?

#

It feels like a bit of an overhead to be required to implement a new server RPC each time I need to send something to server over an actor that clients doesn't have ownership over it

#

Am I missing something that can be a workaround for this? Like for the reverse, I sometimes use multicast RPC with a pawn or playerstate parameter to check locally controlled state to simulate sending a client RPC without having ownership over an actor

#

It's not an issue to do actor on client->state/controller/pawn->actor on server but it feels like the mediator actor is gaining unnecessary dependency due to this

hoary spear
#

Actor on client -> controller -> actor on server ?

#

Ah nvm slashes between

#

I sorta had the same issue, but dont really have a super way of solving it

#

Ended via via via, to ensure everyone knew what they needed, and server got the memo

#

Helps that my initial interaction is server sided (for now)

#

I kinda dont wanna update ownership all the time either

gilded vapor
#

Like clients are only connecting to the server bit other clients, so unless you wanted an actual P2P system you’d still be tripping from client to server to other client

#

—-
For a lot of systems you seldom need to multicast an rpc, usually just server RPCs and use replicated variables to keep everything in sync

upbeat basin
upbeat basin
gilded vapor
keen adder
upbeat basin
gilded vapor
gilded vapor
upbeat basin
gilded vapor
keen adder
#

Yeah, awesome. I set it to 10/s and it looks instant already. 😄

upbeat basin
# gilded vapor because if you were allowed to call an RPC from any actor (by default) that woul...

I mean, for this specific case, I'm trying to implement a QTE, very similar to generator repairing in dead by daylight. Multiple players can interact so I can't set an owner to the actor. But players need to send their input for server to check if they succeed or failed. Right now my only option is sending the time offset the input is pressed over player controller server RPC to the actor player is interacting with. I still can't understand how would it differ for this case to let players send that float value directly with the interacted actor instead of using player controller as the mediator

gilded vapor
#

but there are good reasons why this isn't the default behavior~~

#

If you need design suggestion

I would make an interface for interactible actors. And the player-controller will be responsible for calling ServerInteract which takes an AActor (that implements the interface) and an FInstancedStruct that represents an abstract payload the interactible can use for parameters

#

(This eliminates having to rewrite the replication code for each interactible and still supports different parameters)

upbeat basin
#

Well for the sake of stating it, I'm against interaction interfaces, I prefer components for that logic. And interaction part is kind of out of my question. But thanks anyways for your answers

gilded vapor
bold shell
#

I am using GameState for an array of pictures that most server and client can see. it half works but the client just shows black. on the client GS they show up as unknown

thin stratus
thin stratus
#

At least not directly like that.

#

You'd need to take the photo on everyone individually, so replicating the action of the taken the photo, or you need to replicate the byte array that represents the photo, which is probably not a thing in Blueprint.

lament flax
#

Cedric do you know if NetSerialize handles giving nullptr to the archive ?

thin stratus
#

wdym

lament flax
#

i got an issue, and its linked to the fact to give nullptr for an archive

thin stratus
bold shell
lament flax
#

i also tried with a rw ptr instead of a TObjectPtr

thin stratus
weary badge
#

Hey everyone, I'm trying to create a prottype for a multiplayer, but I'm already stuck pretty early.
For some reason when I spawn and possess the characters, the client's character works just fine, but the server's character is unable to move.

  • The movement is the base movement of the ThirdPerson Template (Enhanced Input Action) Also doesn't trigger a print.
  • The Attack Input I created works on both client and server

The picture is basically all I've done so far...
I wouldn't mind sharing the screen in a discord call.

quaint rain
#

I’d like to get a sense of how many players my server can support.

I have quite a bit of logic on my player controller.

At a high-level, how would I go about simulating player activity?

#

For context: all of my player and NPC movement is server-side AI controlled. Controller sends RPCs and lets the player issue movement/action commands to server pawns.

lament flax
#

you are saying that you send inputs with RPCs to the server ? and that the server will run the movement logic ? (suc as Add Yaw input) ?

quaint rain
#

Server uses ai move to

lament flax
#

you said player

#

AI runs on server so its fine

quaint rain
#

Server-Ai controlled pawn, player issues commands to ai controller which issues commands to pawn.

lament flax
#

wdym with "player issues commands "

#

i need mroe context here

#

are we talking about movement inputs ? (wasd)

quaint rain
#

Haha, sorry. I’m not so familiar with exact terminology.

It’s a click-to-move RTS style movement. Player controller gets location on click, sends a command to the pawn, pawn ai controller uses “move to” to go to the location.

Pawn actor is owned by server and will persist while player is offline.

#

No WASD

lament flax
#

ah i see

quaint rain
#

I can spawn about 300 of the pawns before the navigation system fails.

But I’m wanting to get a sense of how “heavy” a player controller is. Can I get 20, 40, 100 connections?

lament flax
#

so each player has some pawns to control ?

quaint rain
#

Yeah, each player gets 1-3 pawns

lament flax
#

to simulate that i wont do some random clicks and actions multiplied by the number of players

#

so you need to make a sort of Editor AI only bot to simulate events like a player would do

quaint rain
#

Since I have so much logic tied to the PC, is there a way to recycle that logic without having to re-write the PC?

Is it possible to manually spawn 50 PC, or do they require an active player connection?

PC=player controller

lament flax
#

you can launch a game with as many player you want

#

the issue is how do you want to simulate 50 player playing

weary badge
#

@lament flax couldn't you just loop a timer on event that launches player inputs

lament flax
#

yeah, some random timers with random actions

weary badge
#

yh select on random int

deft onyx
#

Does anyone know if it is possible to do peer-to-peer multiplayer on current consoles or are their any limitations/restrictions to the networking on PS5, XSX or Switch? Or does console network has to be client-to-server?

kindred widget
torn zinc
#

Trying my hand at some multiplayer. How exactly can i just allow the client to do whatever and make sure it has authority to do so, disregarding cheating etc?

kindred widget
torn zinc
#

Yeah

kindred widget
#

Then the same way you would do it with anti-cheat. Client tells server what it wants done. Server does it. The only difference is that you don't care about validations.

torn zinc
#

Oh, was hoping for something simpler old_man_yells_at_unreal

kindred widget
#

I'm not sure what would be simpler. Server has to tell everyone what is happening. So it has to do it. You aren't going to get much simpler unless you cut out multiplayer.

torn zinc
#

Fair enough

static owl
#

Hi everyone! Im new here. I was just wondering if anyone had the time later to help me understand some replication?

Im literally jus trying to get a door safe to open on the server and client from an interaction key!

Would really appreciate some help by jumping into a call and sharing my screen later if possible!! Thanks

daring gorge
#

hi everyone, im facing a weird issue where my attach actor to actor isnt setting the right rotation on client?, i basically want to attach a player character to a boat. the boat consists of a child actor component that stores sockets of "seats". when a button is pressed it runs a server event that launches a line trace which if hits a boat disbales collision on capsule and then runs a "interact" interface, this in boat calls a server RPC which runs the seat func from the chair component. my issue is that i want the player to face the forward axis of the boat, this happens on the server but not when i play as a client. anything im missing?

daring gorge
#

ive fixed it! it was quite stupid, the client never knew of the attachment

quiet yarrow
#

Anyone know how to replicate Timelines?

sinful tree
quiet yarrow
#

lmao

#

why was that hidden

torn zinc
#

Trying to rotate my character, but it's not letting me. I thought this was the right way, to replicate to server then multicast? Or am i missing something

#

Nvm, it works. I messed up, however, it is a bit laggy

#

But seems like making it reliable solves it.

dark parcel
#

Don't use multicast

#

You simply need to replicate the rotation variable

#

Have owning controller set the rotation on server with server rpc

#

For proxies, they can interpolate to the I coming rotation on tick

#

That's it

torn zinc
#

Aaah. I didn't understand this tho: For proxies, they can interpolate to the I coming rotation on tick

dark parcel
#

Are you aware of network roles?

#

If not run through the pinned materials

#

Proxies are the other characters that I don't control in my machine

#

Btw tip number 1 just avoid multicast on anything stateful it will never work

torn zinc
#

Ah ok, yeah i am somewhat familiar with it, just didn't know that's what proxies meant

#

Ok, good tip, thanks 😄

dark parcel
#

Does other played need to see the same thing? Yes? Then multicast has no place in it

#

As they can get dropped and straight don't run on late joiners because they are not in the game yet

#

Then there's relevancy too

torn zinc
#

Ok, makes sense

#

Oh yeah much better, smooth now

quiet yarrow
#

Anyone know why this "springyness" happens when I use constraints or how to turn it off? I think its causing jittery physics in multiplayer

#

I messed with a few settings now and nothing seems to change it

torn zinc
#

There is a setting on the constraint for bounce. I just turned off my computer and dont remeber what it was called

quiet yarrow
#

only thing I could find was this:

#

and I have it at 0

#

im new to constraints. Maybe I need to have it setup different

static owl
#

I am not understanding why the safe door will not open for the client (Also the client cannot open it for the server either).

This was apart of a Computer system that can open the safe that i download from unreal, but it was not made for multiplayer, so I am trying to implement that.

The code is a little rough, but basically As i have it now: The SERVER OPEN near the E key press runs on SERVER. Then near the print text node, Open Door Success is ran, and the OPEN variable is set to true.

Then, Open Door Success is multicast, which runs Opens Door which is multicast as well.

dark parcel
#

@static owl daily reminder don't use multicast on stateful behavior

#

Does everyone need to see the same stage for the door? Yes? Don't use multicast

dark edge
#

The general form is this simple.

Input -> run on server event
run on server event -> set a variable (replicated, repnotify)
OnRep_Variable -> change stuff based on the variable

static owl
dark parcel
#

❌ to multicast for stateful behavior, read what Adriel says on how you should go forward,
if you can't do that. Try to sync a simple boolean value accross players first before you tackle your door again.
❌ to handle inputs in the BP_Safe or the door

plucky pewter
#

Huh...So it seems that suddenly I can't change gameplay tags at run time?
I have a gameplay tag container.
By default it starts empty.
And depending on some stuff the value of that tag container is going to be Team.A or Team.B?
I don't know what has happened because I thought I had been setting it at runtime before....?

bold shell
plucky pewter
#

Any solutions you guys use for separating teams in a general context?

dark parcel
# bold shell would it be as simple as setting the custom even that takes the picture to multi...

Multicast is just server telling all the clients to run the function, so if done properly it will work but the gotchas here since latency exist, each players may not see the same photos (Picture pawns and your own controlled character walking around).
Since lag exist, the time where the function gets called varies respective to each machines.

Also any late joiners, will not take the photo so really the only viable solution is most likely to write implementation to replicate textures or send the data over the network then have the receiver reconstruct the image from the byte