#multiplayer

1 messages · Page 672 of 1

sinful tree
#

So... if you wanted the actor to be culled at 10000 (or 100m) it would be 100,000,000

rare pulsar
#

Should it not appear though when the clients pawn got closer?

sinful tree
#

Yes it should, but it's not always instantaneous.

#

May take a moment.

rare pulsar
#

alright

rare pulsar
sinful tree
#

Is this in your player controller?

rare pulsar
#

This is for AI, some that the palyer influence some that they dont, its the one they dont influence that dont replicate

sinful tree
#

Is your player set as the owner of the AI when it is spawned?

rare pulsar
#

No

sinful tree
#

Then you can't run Execute on Server events from it.

#

You can do something from your player controller that calls a "Run on Server" rpc on the player controller which the server can then run that event on that particular AI.

rare pulsar
#

the player influence isnt what i was looking at the ones that arent influenced by the player dont replicate their movement

dim flame
#

when you say movement

#

do you mean animation or the movement component or both?

sinful tree
rare pulsar
#

The ai itself I’ll find the exact bp in one min stepped away from my pc

rare pulsar
sinful tree
rare pulsar
sinful tree
#

Are you sure it's actually being called on server and performing the move on the server? Are you sure the move isn't failing? (you can put in some breakpoints and print strings to try it out)

rare pulsar
sinful tree
#

Are these placed or spawned units?

rare pulsar
#

Placed

sinful tree
#

You have the actor replication & the movement component (just realized you don't need the movement component set to replicated) set to replicated? (Check on a placed one as well)

rare pulsar
#

in the bp

#

yup both are set to replicate

pure hearth
#

is this the correct way to play sounds in mp? i tried putting a key to play a sound but it doesn't work

lost inlet
#

that's not enough info to tell if it's correct or not

#

is the owning actor replicated? is the component? what is the UFUNCTION declaration like? what do the MultiCastPlaySoundAtLocation_Implementation function look like?

pure hearth
#

Owning actor is replicated so does the component
Ok the thing is if i remove the check for the Authority role the sound works but

#

it's doubled

#

like when i step for example i hear 2 footsteps

meager spade
#

footsteps should be done via animation and anim notify?

#

and just played locally

#

i wouldnt want to be multicasting footsteps..

pure hearth
#

i want other players to hear it

meager spade
#

and they will hear it..

pure hearth
#

did this and it worked

lost inlet
#

So it’s not entirely unreasonable

meager spade
#

but you would not multicast that over the network

#

local clients can work that stuff out

#

either via CMC or via animations

#

but sending rpc's just for footsteps, is just not something i have heard games do, but 🤷

lost inlet
#

Though as something server authoritative then you’d probably just send a client RPC to those who could potentially hear it

meager spade
#

i mean that is also a solution, and you will be sending less traffic

#

but still, if you can do stuff locally, its even better

#

tbh you would not hear footsteps if someone was that far away (far enough to not be visible/relevant) tho

lost inlet
#

You’d be surprised, though it depends how your footsteps attenuate

meager spade
#

right, but that would really be annoying if i am hearing footsteps of someone 10K away

#

unless i had special hearing skill

#

if that was general gameplay, that would annoy me

lost inlet
#

Yeah but if someone’s upstairs but not rendered then you need to do something that isn’t animation driven

meager spade
#

right i mean sure, but if your detecting footsteps without animations

#

then you can do that same logic client side

#

playing*

sacred flint
#

hello, i'm testing things in multi and currently i'm making a flashlight, everything is good but the problem is when i press f it turns the lamp on or off, so player a has the lamp player b will be able to press the key to turn it off and on how do i do that only the player who has the lamp can turn it on or off

blazing spruce
sacred flint
#

btw my flash light code is on the character body

sinful tree
sacred flint
#

i target my flashlight bp

sinful tree
#

That's the problem.

sacred flint
#

aah fuck

#

so how i can do ?

sinful tree
#

Don't use get actor of class. You probably have a flashlight attached to your character somehow, no?

sacred flint
#

because, it is an item that you can take from the ground

sinful tree
#

Ok, so what you should be doing is storing the reference to the object on the player when they pick it up.

sacred flint
#

Ok, with a cast instead of a get actor?

sinful tree
#

It's not about casting... When you pick it up you're getting the reference to the actor itself.

sacred flint
#

Ok, so please can you direct me to do it, that would be really cool ? ty 🙂

sinful tree
#

Sadly no, because I don't know your full pickup code. You are obviously doing something to pick up that flash light which means you're probably interacting with that Flashlight object in some way, so you have a reference to that object (as I imagine when you press F, that flashlight disappears). That reference is what you want to use rather than "Get actor of class", so store that reference in a variable.

sacred flint
#

Ok right!

#

Thanks for you answer, i keep you informed 🙂

thin stratus
#

Don't use Multicasts for state changes

#

It's wrong

#

Use an OnRep variable

kindred widget
#

But... If you run away, and then turn on your flashlight, you can run around with it on, and no one will see it!

thin stratus
#

😩

#

@blazing spruce @sacred flint

#

Change the Multicast to an OnRep variable

sacred flint
#

@thin stratus with onrep, i can use with actor ?

#

or i need to reference flashlight like say datura

thin stratus
#

The variable should be in the actor itself

#

So yeah you need a reference to the flashlight

sacred flint
#

okok

#

i need to find how

thin stratus
#

But that aside, never use Multicasts for state changes

#

Someone hot joining or being far away from you won't get that call

sacred flint
#

in my case the players will be close all the time

#

but, I will do it with your onrep

thin stratus
#

Doesn't matter

#

It's wrong either way

sacred flint
#

true

#

thanks for the information 🙂

blazing spruce
#

How can i disable clients buttons on the lobby screen when the host presses the start game button? I think i need to use Game State, ive not used the class before but from what i understand that'll be the best place to do it

sinful tree
elfin sail
#

dedicated server not load any map

#

map is included in packaging and set default server map

#

is was working a day ago i am not what i changes make this e=issue

blazing spruce
chrome bay
#

For a bool I wouldn't even bother, just have the UI grab the game state and set the button to either enabled/disabled (via it's tick event)

#

Events are only really worth setting up if the change is going to cause a major UI rebuild or something, since you also have to gracefully handle a case where the gamestate isn't available for event binding too.

blazing spruce
blazing spruce
#

Like this? ive put that on the client screen

still monolith
#

Hey, I've got a mantle / vault system set up through GAS which is working as intended for the most part, there is just an issue when it comes to vaulting through smaller openings e.g. windows. The ability disables collision between the vaulting player and the obstacle, functionally this works, and the player is able to vault through the opening, but over the network this causes some rubberbanding, as I assume not all clients receive the updated collision info in time.

#

Does anyone have any pointers on a solution to the problem, e.g. a setup where clients wouldn't rely on an update from the server to allow movement through such obstacles?

dark edge
still monolith
chrome bay
chrome bay
#

Well 'GameStarted' should presumably also be plugged into "In is Enabled" too

blazing spruce
#

yeah just done that too

#

gotta try it now

round star
#

Sigh. On rep notify means that the replicated variable calls the function attached to it for everyone. No?

blazing spruce
round star
#

I am so freaking confused. The onrep notify function is not being called for clients. The server is updating a variable with on rep notify that changes a material parameter collection scalar..and is only ever called on server. I thought onrep_notify meant it would replicate to clients

bitter oriole
#

Show the code

round star
#

Nevermind I forgot something simple

#

relevancy

lost dune
#

Can someone help me about making a client authoritative position for character movement?

#

I don't care about cheating for the moment

#

This don't work

#

it says there is no server position erros detecting and corrections , but there are

#

character is jittering when moving forward

#

I run play as client and laucnh separate server , with run under one process unchecked

jolly siren
#

What is the engine function that checks if a property has changed on the server in order to replicate?

chrome bay
#

FRepLayout::CompareProperties

#

Then CompareProperties_r, which ultimately just boils down to using the == operator IIRC

#

Oh sorry no, PropertiesAreIdentical() is the real one

eternal canyon
chrome bay
#

RepLayout.cpp

#

You can just type that into any file BTW and then CTRL+G or ALT+F12 etc.

#

Quicker than a find

eternal canyon
#

Dang it discord no bookmarks

#

😢

jolly siren
#

Thank you 🙂

hoary lark
# lost dune

are you running that event on server? I haven't done MP in a while but last time I did it I had to set options in DefaultGame.ini

#

e.g. [/Script/Engine.GameNetworkManager] MAXPOSITIONERRORSQUARED=250000.0f MAXNEARZEROVELOCITYSQUARED=2500.0f ClientAuthorativePosition=true

lost dune
#

thank you i ll try

hoary lark
#

I had mine set up with semi-client authority, the client would still get corrected for major errors. I never extensively tested it but seemed to work for the most part

tropic snow
#

So in order to fix client rubber banding when it comes to rpc calls in bp and when packet losses are introduced is to do it in c++?

lost inlet
#

well the CMC's prediction stuff isn't exposed to C++ nor would it expose to BP very well

#

I would only really use BP for very simple replication stuff to begin with

hazy magnet
#

Hi everyone, I hope your day is going well. I have encountered a huge problem in my game and I needed help. I wanted to know if there is a way to transfer the authority over to a client. In my game you can open rooms and people can join it just like Among Us. This works fine but when the person that opened the room quits, all the clients also get kicked out. I wanted to know if I can transfer the ownership of the room to another client. I am also looking for a only blueprint route. Thank you all (:

lost inlet
#

that's usually called host migration

bitter oriole
#

It also won't be a Blueprint only route

#

Or even an easy C++ route for that matter

meager spade
#

For a game like that, you want dedicated servers

#

UE4 has no host migration as mentioned above, so quitting host will be an issue. I am not aware of anything released or in the wild for host migration though, and like stranger said, this will be a lot of c++ work.

#

If its something you need, you might have to pay a contracted network and game engineer, to help you achieve this, likely by modifying the engine.

bitter oriole
meager spade
#

yeah but its not in the wild, it was done bespoke

bitter oriole
#

Yup

lost inlet
#

there was a marketplace result for it, but y'know... marketplace

meager spade
#

we were thinking of doing it for RS2, but our game is not competitive and host leaving, sure annoys players, but they don't loose anything from it

#

as its a co-op PvE

hollow eagle
#

SoT probably had a pretty easy time all things considered - quests and progress are almost exclusively tracked by items in your inventory and player profile data, so there's probably no complex script state that needs to be migrated. Everything else is just copying player and item positions.

#

I'd guess the most complex part was the actual server scaling solution that had to decide when to migrate servers.

#

I wouldn't be surprised if servers get marked as "cannot be migrated" if a more complex world event happens just so they don't have to deal with it.

harsh lintel
#

I have an spectator pawn, and I'm replicating a variable so the player that is spectating can "see" from the spectated player's point of view, but the spectator's camera is no very smooth this way

#

any advice

#

?

twin juniper
#

Is it possible for someone to do a tutorial, mordhau combat ?

hazy magnet
#

So in short since there is no such thing as host migration, I have a huge problem that cannot be solved unless I hire someone?

lost inlet
#

you would have to implement it, which will be difficult with a BP-only approach

unkempt tiger
#

Any ideas on why ever since changing engines (to 4.27) my custom pawn network code is unplayably laggy in PIE sessions (while working swimmingly in 4.26 and in packaged 4.27 builds)?

#

Is there maybe some new config setting to acknowledge, or anything like that?

twin juniper
#

hello guys, im using a child actor component on an actor. The game is running on a dedicated server. The child component actor is attached to a socket but only the server actually attach the actor to the socket, on the clients the actor does not follow it

sweet pelican
#

Hey there, dont have much experience with networking and was just getting started with a basic networked game. At the moment Im storing game rules like "can the player jump" or "can the player swap to first person" in the gamemode, and then in the players code, getting a reference to the gamemode and calling for that information to check if its allowed before completing the action. But now that I've started networking I found out the hard way that the gamemode is only on the server, so this method doesnt work and crashes the game. I know usually to do something like this, youd send a message from the client to the server and have the server handle the action instead, especially with things that arent already replicated like player movement. But with something like jumping, wouldnt this method just make the game feel gross and laggy? I was just wondering if there was a better convention for handling things like this or a better place to store game rules that is accessible to clients but not editable still. I was considering just shipping those game rules to the clients on spawn, but then realized that would defeat the purpose of them, as the clients could just change those values to cheat. Searching around online I saw something about an AWorldSettings that can be called from the world but have no idea how to use it.

sinful tree
# sweet pelican Hey there, dont have much experience with networking and was just getting starte...

In multiplayer the Game Mode is meant to contain anything that the clients aren't supposed to know about or have any access to change. It's not so much about defining the rules of everything in the game, but just the rules of the game - like a character needs 30 points to win, or the flag needs to be captured. It can be used to define that "players cannot jump" in this particular game mode but then that should probably be a static rule of that particular game mode, not something that would change based upon conditions of the player.

Any character rules you set up, should be in the characters. Since basic movement & jumping replication is covered by the character movement component you can do these things without relying on replicating the movement to the server so long as you're using the CMC's "Add Movement Input" and "Jump" nodes. The server will playback the moves automatically based on what it knows about the character and correct the position of the player if necessary.

So if you did have a rule where "players cannot jump" in the game mode, then on the server's begin play of the character, you can set and replicate a boolean on the character that will prevent them from jumping, including modifying the character movement component completely preventing them from jumping on the server's copy. If someone was malicious and wanted to try and force themselves to jump, then it may look a bit silly on their end as they attempt to jump and fail, but it won't look like that for anyone else.

#

Everything that is specifically related to the gameplay and it's rules should be executed on the server. You can do client side prediction, but if the client is wrong, you need some way of rewinding what was done on the client which is fairly difficult to do. You also have the option of doing "fake" things on the client and just letting the server do it when it receives the commands to do so. The other option you have is looking into the #gameplay-ability-system which can do prediction and rewind for you.

sweet pelican
# sinful tree In multiplayer the Game Mode is meant to contain anything that the clients aren'...

Thanks for the response! Clears it up but still a little unsure of one bit

At the moment I have keybinds to swap between first/third person and whatnot, that check if its allowed by the gamemode first too
I could do a similar thing where the sever's copy of the player sets a bool for that rule and replicates it across to the client
But then couldnt someone alter that bool and it would simply just replicate back to the server and bypass it?
Or is there a way to make that bool only editable by the server?

sinful tree
#

No - replication is only one way, from server to client. If you have a replicated variable set on server, that's what the client should be at as well. I say should because there's is no way you can guarantee what values a client has on their machine, so you can only go by what values you have on the server.

There has to be a little bit of leeway to what you need to enforce and realize that cheater's are going to cheat and you will probably have to use other means beside server authoritative design to try and enforce what rules you want enforced (like anti-cheat engines). Like, I'd understand that certain players must be in first person view to say, shoot a sniper rifle, but does it really harm the game if they aren't on the client? The only thing you should probably be passing to the server is that the player wants to shoot - not necessarily the target they're aiming at. That's usually done server side based on the values the server knows of the client, so on your RPC to the server to shoot, you'd have to enforce what you know about the client based on the replicated variables you sent to them, like if they are alive, if they have ammo, if they are in first person view, etc.

sweet pelican
#

Ohhh that makes so much more sense now
I interpreted replicated variables as a kinda two way street... I assumed that the client could also update them, and that info would be sent back to the server
So if the client did try to update a replicated variable, theres nothing stopping it from changing client side, but the server wouldnt be updated by it?

sinful tree
#

Correct.

#

And there's no way without external anti-cheat engines to ensure that a value on the client isn't changed by the client themselves maliciously. So they can make it "look" like they have 100% health on their end by manipulating the game's memory, but the server knows they only have 10% health, so the next shot will kill them despite what it shows on the client.

sweet pelican
#

Awesome, thanks for the help man, appreciate it!

peak sentinel
#

Anyone knows if UT's projectile predicting stuff would work with homing projectiles?

void nest
#

Hello. Does anyone know how to fully fix the well known (but sadly not very well documented) problem of pawns getting auto destroyed by the engine when a player using them disconnects?
For our multiplayer game we have written an override (with the documentation regarding this issue we found) to not have pawns be deleted by the controller. This fixed the issue partially. Meaning, pawns no longer get auto-destroyed when a player leaves the server. BUT, they still do when a player is force disconnected. Say due to a connection error. How can one completely disable the auto destruction of pawns?

#

Kind of weird that this is so heavily enforced from within the engine. I get that it's an obvious optimisation thing. But I can think of so many cases where you don't want this at all. Mainly, possessable vehicles that can also be used by other players in multiplayer games. Why is there no option to disable this?

#

I bet there is a good reason for this. Would love to know what the reason is though.

nova wasp
#

earlier jambax was discussing something similar about storing the player's data

kindred widget
#

There's a few places where Pawn is destroyed for connection things. PlayerController's PawnLeavingGame is one. KickPlayer from GameSession is another.

void nest
#

I completely understand the auto destruction for player pawns. But vehicles really should never be auto-destroyed. As other players should be able to use them when the vehicle is empty because of a player leaving.

#

@kindred widget the player controller destroy we have fixed. It's the other one we should probably also have a look at then

kindred widget
#

Judging from general code, it would seem that most important calls use a true for the bnetforce on Destroy. Overriding that in your vehicles, and only calling super if that is true could also work. Not sure what side effects that may have.

#

Could be worth a test. 🤷‍♂️

rose prawn
#

What can be the reason for GetOwner returning null on client? I spawn the actor on server, set the owner in spawn node, all the variables inside the spawned actor are also replicated but GetOwner returns null on client.

#

Where should I look at?

#

My variables works properly, they are all replicated. Only problem is the owner.

kindred widget
#

Where/when are you checking owner and what is the owner?

rose prawn
#

The owner is the character. I'm checking the owner in BeginPlay after Switch Authority macro (remote output)

kindred widget
#

That can run before Owner pointer has a chance to replicate.

rose prawn
#

I added delay node to just make sure of that

#

But it's still not replicated

kindred widget
#

Odd. You are saying you set the owner from the blueprint exposed pin for Owner?

rose prawn
#

Yes. It was working yesterday, I'm not sure what changes caused the problem. I will revert everything back and test it again.

#

But seeing variables are replicated but the owner is not is weird.

kindred widget
#

Maybe try to forcibly call SetOwner after the spawn code. I rarely, and I've seen quite a few other people having issues with inputting it as a parameter.

rose prawn
#

Should I do that inside the spawned actor?

kindred widget
#

Where ever you're spawning it. Just drag off of the return value of the SpawnActor node and call SetOwner.

rose prawn
#

Yeah, still no luck.

peak sentinel
#

Also put a breakpoint to setowner function in AActor

#

See if param is valid

rose prawn
#

Are you talking about this?

peak sentinel
#

C++ implementation of SetOwner

#

But yeah, from BP, param seems to be valid too

rose prawn
#

I could just create another variable for the owner and it would probably work as my other variables are replicated but this problem is really weird

peak sentinel
#

Where is spawn happening? In which class

kindred widget
#

It's almost.. Unreal.

rose prawn
#

It happens in Gameplay Ability.

peak sentinel
#

GAS?

rose prawn
#

Yes.

peak sentinel
#

GAS has its own spawn actor for gameplay task

rose prawn
#

Ok let me try it, I'll be back

peak sentinel
#

Generally in GAS you should not use things require "ownership" logic, root motion and spawning logic will not work in abilities

#

GAS have replacement for them

rose prawn
#

Yeah still no luck, I will remove saved/Intermediate/binaries etc. recompile and try it again

#

if it doesn't work revert back to older version

peak sentinel
grand kestrel
#

@rose prawn@kindred widget When my character has a playerstate + controller (or wont have one) + have begun play, they send each other an RPC to say they're initialized, only after they're initialized both locally and remotely does anything whatsoever actually happen, until then character is hidden/no collision/movement disabled - this also prevents initial replication of playerstate/controller racing against whatever I'm actually trying to do

peak sentinel
#

saved/Intermediate/binaries
Usually those folders are related with blueprint assets and source code

#

Not with the logic itself in your code

rose prawn
grand kestrel
#

Don't use delays for that, what if latency exceeds delay in form of connection delay / lag spike in real world scenario

#

You're creating an edge case that fails

#

This is the plugin I use and modify per-project, you can either use it and modify as required or use as reference

#

That one checks for Phy's voxel world to be initialized which you'll likely want to remove

#

Or use his awesome plugin 😛

#

Anyway that gives you OnInit functions to replace BeginPlay

#

Which guarantees pawn/character has been fully setup and replicated once

rose prawn
#

Thanks, I'll test it right after I fix the problem. 🙂 I was using While Loop with Delay macro that I created which was checking if some of the variables are initialized but this might solve that problem too.

grand kestrel
#

Another thing I like to do is use a playercameramanager that fades in using OnInit()

#

And starts faded out

#

Looks pro

grand kestrel
#

The sad reality is pawns don't have proper initialization events

#

My plugin is just a simple way to give them what they need

#

It's the #1 thing that catches out people new (or new-ish) to multiplayer

#

The plugin is pretty simple, you could use interface and multicast delegates so you don't need custom classes if you make your own solution

rose prawn
#

Thanks, looking forward to replace my bandaids with them then. 😄

thin stratus
#

That being said

#

I recall the SpawnActor node for GAs being shit

#

We made our own in The Ascent, cause it was lacking multiple things

#

It's not exactly like the standard SpawnActor node, for god-knows what reason

rose prawn
#

I reverted my project back and now it works, so something is broking it but I'm not sure what is the cause. In the working one, I still use ability system and spawn actor node.

#

So it should be something else

thin stratus
#

Well you def have bandaid shit in your project, reading what you wrote above

#

But that aside I just wanted to share what I recalled about the spawn actor task

grand kestrel
#

(via GAS I mean)

peak sentinel
#

Probably many things are actor based since GAS involved thinkmanny

#

I'm wondered too

thin stratus
#

Uff, lots of things, nothing I can list

#

But the gist of it was that the node doesn't have all things that normal one has

#

I think it even lacks an Owner and Instigator Pin

#

And back in whatever UE4 version we had it was also not using the SPawnRotation iirc

rose prawn
#

Thanks for sharing and answering people 🙂 I will make some changes then.

thin stratus
#

Yeah Now I recall

#

So you have the AbilityTask for spawning an Actor

#

And it takes a TargetData

#

But as far as I found out, it only returns "EndPoint" or "HitLocation", which both are vectors, not transforms

#

So it just swallows the rotation and scale you might pass in

#

And it indeed doesn't have an Instigator and Owner pin

#

But i can't recall if they set that by hand somewhere down the line, cause those nodes are hacked as sh*t

thin stratus
#

Cause designer wanted lots of bullets, and 4 player coop was killing it

peak sentinel
#

Out of curiosity, why The Ascent went with GAS this heavily? Why did you guys preferred it?

thin stratus
#

I joined them after they already decided that. Don't know the answer

grand kestrel
thin stratus
#

I assume because they heard about it and after looking into it found it a good fit for their RPG style game, specially since it does a lot replication and prediction for you

#

Which it was

#

I'm happy I learned to use GAS :P

grand kestrel
#

You can pass custom structs FYI, but I guess you know that already

thin stratus
#

Yeah

#

Either way, the SpawnActor AbilityTask is weird >.>

grand kestrel
#

Was handy for my vaulting system because it let me serialize (compress) all the vectors specific to that system the way I wanted and not pass anything unnecessary like a full hit result

#

Yeah I'd just make my own, good to know in advance so I don't have to figure it out though 😄

thin stratus
#

Yeah you can go crazy with custom structs and serialization

#

We actually never needed to modify the EffectContext

grand kestrel
#

Have you seen my vaulting plugin yet btw

thin stratus
#

We were lucky enough to have all the data available

grand kestrel
#

It's unbeatable 😛

thin stratus
#

I have not

grand kestrel
#

Hmm I can't post it here can I? Should I DM you?

thin stratus
#

DM

#

Already quite off topic

bitter oriole
thin stratus
#

^ correct

#

And it was perfect. I was able to make all of the abilities in a month or so.
And iteration for rebalancing was also quick

grand kestrel
thin stratus
#

Yeah

#

But it's a matter of scaling. The setup takes a bit, specifically the amount of custom nodes you will create

#

And custom functions and variables to make everything perfect

peak sentinel
#

I started to use it a month ago, even now I don't really understand many things about it. Probably my top reason to avoid it is GAS being declarative

thin stratus
#

After that it scales nicely, but if you barely need the scaling part, then GAS is too much and you should just do something simpler

grand kestrel
#

Yup

#

I've built full prediction/rewind and even if GAS doesn't have rewind nothing stops me taking a prediction key and stealing CMC snapshot

#

It's pretty much perfect once you've got it setup

thin stratus
#

Yeah I set it up 2 1/2 times by now. Currently moving most of it into an internal plugin

grand kestrel
#

Makes sense

thin stratus
#

(since our company does a lot of contract work, I don't want to reinvent the wheel every time)

grand kestrel
#

It's the same thing every time for the most part

#

No reason not to

thin stratus
#

I'll leave it at that

grand kestrel
#

Ah yeah

rose prawn
#

I found out the problem

#

I forgot to call Super in GetLifetimeReplicatedProps function

#

So owner variable wasn't replicated

nova wasp
#

I kinda wish that there was some reflection thing to yell at you if you forget super

#

half the time I'm not 100% sure if I have to call super

bitter oriole
#

It's generally safe to always do it everywhere

rose prawn
#

Yeah, luckly before I revert back for no reason I backup the project so I don't have to spend 5 extra hours for the same thing. 😄

#

I noticed that by luck but forgeting small things takes huge time so it would be nice to notified about super.

sour plover
#

I don’t think it would be very useful to have the build system yell at you for lack of a Super::. It has no idea if it’s accidental; sometimes you do want to omit the parent method call on purpose

rose prawn
#

Yeah probably, it could be very annoying to notified too.

peak sentinel
#

BeginPlay yells at you literally

#

But no other function afaik

bitter oriole
#

The same problem occurs with warnings on switch/case with some compilers offering a warning when no break is present

#

In that case a "fallthrough" comment disables the warning

#

Same thing could be done for Super

#

(And I think omitting Super on purpose is rarer than omitting break on purpose)

rose prawn
#

I guess it would %99 of the time would be required to call super.

#

Since Owner and Instigator variables are pretty basic and needs to be replicated properly.

peak sentinel
#

I liked the idea of Stranger, as an alternative to 'debug' forgotten Super::'s we might have a boolean on build.cs

#

And UHT can yell at us if we set it to true

nova wasp
#

I'm sure everyone is excited at the prospect of more reflection macros

#

I guess it's all already there in beginplay except it doesn't get used

grand kestrel
#

You should only specifically not call it to avoid parent logic

sour plover
#

The warnings on switch/case were put there probably because they can be a hint to the programmer that they’re using the language’s syntax wrong. Super:: calls are more like an outcome of a certain architectural choice, specific to UE4 but not necessarily to other types of software. So, two very different things, I guess.
If I wanted to put such an enforcement in place, I would probably go for the optional macro, like @nova wasp suggested. Kinda like the pragma optimize thing.

grand kestrel
#

Don't forget you can call Super::Super::Thing(); to bypass direct parent logic only on that topic

#

Also did you know there is a ThisClass macro typedef so the examples showing you how to bind or say, DOREPLIFETIME(ThisClass, MyProp), never tell you that

blazing spruce
sinful tree
#

Realized, if you're hosting the game then you're running as a listen server so what I said wouldn't apply.... But your boolean does need to be set as a replicated variable.

blazing spruce
sacred flint
#

@thin stratus hi, can i call with you 5 minutes i have a question about notify?

thin stratus
#

No, sorry, I'm working atm. Just post your question here and someone (or me if I find 5 seconds) will help you.

sacred flint
#

No worries, but impossible to explain the problem here (too big here)

winged badger
#

that is unlikely, just simplify it

sacred flint
#

@winged badger @thin stratus
Basically:
I have a door system with a key.
When the client takes a key he can open the door but the server doesn't know that the client has taken the key.

If the server takes the key and the client takes the key, if the client opens the door then everything works perfectly

#

I tried to simplify as much as possible

#

characters bp

winged badger
#

client taking a key needs to happen by client location a key for interaction locally

sacred flint
#

bp door

#

notify door open

winged badger
#

then sending a Server RPC in order for server to execute the interaction

sacred flint
#

that my code ! 🙂

winged badger
#

and then server replicates the interaction results back to client

#

your problem is server not knowing a key (pun intended) gameplay state

sacred flint
#

@winged badger game instance u mean?

winged badger
#

this has nothing to do with game isntance

sacred flint
#

Can we see this in voice I would like to understand ? would be good i think !

winged badger
#

nope 😄

sacred flint
#

Otherwise I'll look again on my side no worrie..

#

Okay !

#

so

#

Just direct me I have to do this or in the pictures I sent you

#

i think in notify i need to do something

winged badger
#

all interactions need to happen server side

#

client picking up the key needs to happen server side

#

and client interacting with the door also needs to happen server side

sacred flint
#

actually this is what I do to open the door (i think)

winged badger
#

door then replicates its state Open

sacred flint
#

have to create a game state instance to store? or no need

winged badger
#

and OnRep_Open would cause client to rotate door or whatnot into an opet state

dark edge
# sacred flint <@!352507850980851712> <@!94211915902889984> Basically: I have a door system wi...

On pawn, make a replicated variable bHasKey or whatever.

On door, have replicated variable bIsOpen or whatever.

Do the key pickup (setting bHasKey = true) on the server so it can replicate out (for UI showing whether or not you have the key or other uses)

Do the Interact or AttemptOpenDoor server side. On Interact, if the interacting Pawns bHasKey is true, set bIsOpen on the door to true.

On the repnotify for bIsOpen, do the actual opening animation, play sound, etc.

#

In my project, the RPC from client to server occurs in the interaction phase.

Button Input -> Run on server event -> Interact with actor

rose prawn
#

Also don't ping or DM random people.

amber raft
#

is there a way to apply live link in multiplayer?

prisma fiber
#

why scalar parameters of materials refuse to replicate? I set whole actor and mesh "replicates" to true

#

If I play it without server event being involved everything works fine but scalar parameters are not replicated

dark edge
#

That is, replicate the random float and apply it on repnotify

prisma fiber
#

so only one scalar parameter of 1 materials of mesh is changed

cinder quartz
#

you change same variable multiple times in a single frame, so server only replicates the most recent change. you need to use an array or 12 different floats

prisma fiber
kindred widget
prisma fiber
# kindred widget What exactly are you trying to do?

ok
so
1)every mesh has 4 materials (actually 6 but the rest 2 are not affected here)
2)every material has 3 scalar parameters (1 for each of RGB values). every parameter called like IndexOfMaterial.IndexOfparameter so the third parameter of the second material will be named 2.3
my solution without replication is: "for 4" > "for 3" > append strings (first loop index + . + second loop index) > "set scalar parameter value on materials" with this name of parameter and random float

pretty complicated so here is a screenshot:

dark edge
prisma fiber
dark edge
#

Either generate an array of random floats and replicate it, or use streams and just replicate the seed.

#

Either way, in the repnotify of the array or stream seed, that's where you'd apply it to the materials.

kindred widget
#

Also. For simplicity, it can be much easier to pass colors as a vector.

dark edge
#

If you need it to be extensible, use streams. Streams are just seeded random number generators, so the output of Random float will be the same on all machines.

#

Like how if you type the same seed in in Minecraft you randomly generate the same world as somebody else

prisma fiber
prisma fiber
dark edge
#

Exactly the same way, just use a vector parameter instead. Google how to use them, you can figure it out. That's not a very good attitude to game Dev, you won't get very far if you just give up whenever you don't already know how to do something

kindred widget
#

I meant pass one vector instead of three floats in the replication. But yeah. Adriel makes a good point. A single integer that can set this up locally would be best.

thin stratus
#

Any chance there are known problems with setting the RelativeLocation of the Mesh of a Character on Server and Client?
It just doesn't seem to work for simulated clients (even though it calls with the same correct value on both).

#

Trying to wrap my head around why. Thought about replication itself having an issue here, cause relative location is replicated, but limiting it to auth doesn't fix it either

dark edge
#

You think it might be a weird character thing where the CMC or character class is overriding?

thin stratus
#

Yeah, something something

dark edge
#

I think the CMC does some weird stuff with mesh transform for smoothing

#

That would be on simulated clients only too so that might be a direction to look in.

#

Maybe it caches relative transform at begin play or something.

chrome bay
#

yeah it gets it from the CDO

thin stratus
#

s<ojlkjsak<lgjlökag

dark edge
chrome bay
#

but yeah they use the relative loc/rot for the smoothing

thin stratus
#

Why the f does that stop me from just setting it runtime

#

I can't be the only one that sets the mesh location runtime, or?

#

:D

dark edge
#

Is it just me or is Character just a pile of intertwined spaghet

thin stratus
#

It's all of us

chrome bay
#

yep 😄

kindred widget
#

Character class is absolutely fantastic... For a beginner, who just wants to make a UT clone.

thin stratus
#

Let's not go there and focus on the problem at hand. mine, the one where I can't set the rel location.

#

;_;

prisma fiber
thin stratus
#

CacheInitialMeshOffset(Mesh->GetRelativeLocation(), Mesh->GetRelativeRotation());

#

It's this, isn't it

#

BPCallable. FOR ONCE, something is exposed

#

I shall report back

#

NAILED IT

#

This fixes it, calling it right after changing the rel loc, same frame.

#

Don't know if that's the correct way, spent enough time on this..

kindred widget
#

If it works, it's correct enough. 😄

thin stratus
kindred widget
#

Add the array index to the stream for a different float each iteration.

thin stratus
#

Somewhere it has to do it anyway, so if there is no node then do it manually

prisma fiber
thin stratus
#

Yes and no

#

Each call should generate a new one

#

But if you do the same thing again

#

you get the same

#

That's the idea of the stream

dark edge
thin stratus
#

If you generate 10 numbers with a stream and seed, you get 10 different numbers

#

If you restart teh stream and do it again, you get 10 different numbers, but the same 10 numbers from last time

#

If you change the seed, you get different 10 numbers

dark edge
#

Can a stream itself be replicated or do you replicate the seed and generate stream locally?

thin stratus
#

You replicate the seed

#

I mean, you can probably also replicate the stream somehow

#

Depends on how urgent it is for them to stay in sync

dark edge
#

Streams just a struct right? I bet it just had a seed and number of times accessed and methods to generate vectors floats etc.

thin stratus
#

Yeah you can probably replicate teh seed and the times it is used or so

dark edge
#

Although yeah you don't want the number of times accessed to be replicated LOL

thin stratus
#

But either way, you could always somehow miss a package

prisma fiber
thin stratus
#

Depends on what is in that struct

#

If the struct params aren't marked as UPROPERTIES; they won't replicate

#

private:

// Holds the initial seed.
int32 InitialSeed;

// Holds the current seed. This should be an uint32 so that any shift to obtain top bits
// is a logical shift, rather than an arithmetic shift (which smears down the negative bit).
mutable uint32 Seed;
#

They aren't

#

So no, you can't replicate that thing

kindred widget
#

You don't need to replicate anything more than a single integer.

thin stratus
#

Yes and no or?

#

I mean, you can replicate the initial Seed

#

As a single integer

#

But if the client calls the random function differently often, it's out of sync

#

So the current seed is also interesting

kindred widget
#

The stream is always the same from the seed integer. All you need is a randomizing function that runs off of that.

dark edge
#

Just replicate the seed and make sure you access in same order everywhere.

prisma fiber
#

where is the reason of making separate "stream" variable when int is fine too? 🤔
you can even break stream into int and nothing else will appear

dark edge
#

It's basically like a seed for seeds

prisma fiber
#

I mean
why dont just accept seed in "stream" nodes?

dark edge
#

You use the seed to make the stream then use stream to make the random numbers.

#

Think of a stream like a list of infinite random numbers, that if you make it with the same seed, will be the same list everywhere

#

So you replicate the seed, that lets every client have the same list of millions of random numbers, and then you just start using them to set your colors.

kindred widget
#

@prisma fiber It's pretty much as easy as something like this.

dark edge
#

With your approach you don't even need streams then, just add seeds together.

prisma fiber
kindred widget
#

Once is server, other is client's Onrep

dark edge
#

Onreps run on server in Blueprint

kindred widget
#

Right. I always forget that.

dark edge
#

I'm pretty sure it can be much simpler, sec

prisma fiber
sage isle
#

This should have been fairly simple but I am struggling, I wanted to pass in a variable and change the characters coloring based on if that variable is true or not. It works on the client so it appears changed to the owning client but to everything is its unchanged and I cant seem to get this.

#

I tried running the event on the server and as a multicast but had the same results, anyone got any ideas?

dark edge
#

Client passes Red to server.
Server sets MyColor=red
Repnotify on MyColor actually changes the mesh or whatever

narrow vigil
#

hey folks, is there any kind of obvious 'checkboxes' or something that i gotta check to get bone rotation/movement replicated properly online?

#

i've got a 'look at' thing going on in my vehicle, and the rotation values are set to be reliable

#

it all works nicely standalone, but this shit glitches out the moment i jump in a lcient

#

set to update on tick in the pawn

dark edge
narrow vigil
#

the look at itself isnt reliable

#

i'm only using two floats

#

that i break out

#

which are reliable

#

pitch and yaw, which i also use to drive the anim bp

dark edge
#

Nothing that's sent every frame should be reliable

narrow vigil
#

yeah i'm aware, i can throw it in a timer no problem

dark edge
#

Yeah that should not be reliable. I would sink one thing, an aim Direction

#

No just send it every tick unreliable.

narrow vigil
#

but i figured if it doesnt even work on tick

#

alright

dark edge
#

On tick
Calculate aim direction (rotation or vector)
Send to server Unreliable

In animation
Read Aim direction
Move bones etc.

narrow vigil
#

though it remains glitched out as heck

#

yes that's what it's doing right now

dark edge
#

So what you have right now

narrow vigil
#

on tick: do raycast, find point, set as 'target' then rotate turret to target

#

is run on server unrelaible

#

'target' is replicated

jaunty onyx
#

Is GasShooter compatible with UE5EA ?

narrow vigil
#

as well as 'current' rotation values of turret

narrow vigil
dark edge
narrow vigil
#

oh youre right i only ticked it for debug

#

which made no difference

dark edge
#

So when you say it glitching around, is it just kind of wiggling around? Maybe try smoothing the actual replicated value to derive the value you want to use to drive your animations.

narrow vigil
#

it's an interpolated valu

#

and only the final value is sent to server

#

as well as the anim bp

dark edge
#

Yeah replicate the raw value, but interpolate towards it everywhere so the animations can be really smooth

#

RInterpTo

narrow vigil
#

hmmmmmmmmmmm

dark edge
#

Just constantly interpolate AimDirectionSmoothed towards AimDirectionReplicated

narrow vigil
#

that almost sounds like it makes sense

#

:D

#

gimme a sec to set up

dark edge
#

Show an example of how bad it's glitching out. Are you sure you have your net update frequency high enough?

narrow vigil
#

video is above

#

should be nice smooth rotation

dark edge
#

That looks like something's being send really slowly or updated back to default between replications or something. I would back up and just replicate one rotation. Do it in the pawn.

narrow vigil
#

yeah right and this is just in my own editor playing on a simulated client

#

it's like it's got massive packet loss or something

dark edge
#

I'm using the exact setup I laid out before and it works perfectly as butter smooth. And I'm not doing any smoothing

#

All I do is send a rotation to the server, have it replicate back out, use it in my animations

narrow vigil
#

hmm do you send ROTATION

#

or floats

#

and should that make any difference

#

well that's another path to try if this doesnt work

dark edge
#

I send one rotation

#

I call it aim rotation

narrow vigil
#

i think that solved it

#

yup

#

it just REALLY didnt like sending the interpolated value to server

#

thanks amigo

#

still doesnt sync

#

but at least it isn't actively exploding

meager spade
#

why are you replicating mouse pitch?

#

@narrow vigil ?

#

oh for the gun turret

#

i normally would do this locally, then send the server what i did, server can then do the same, and simulated proxies can just interpolate using some exponential lerp.

#

bit like how the CMC works, but simpler

dark edge
#

Exactly what I said but in a more compact form lol

prisma fiber
kindred widget
#

You're setting it on Beginplay.

#

Beginplay runs locally for every machine.

prisma fiber
kindred widget
#

Only do it on authority.

#

I usually prefer explicit IsServer checks, but in most cases Authority works fine.

prisma fiber
kindred widget
#

Yep.

#

You'll find in a lot of cases that networking can often run a ton of OnReps long before Beginplay is called.

prisma fiber
#

I hope at some point I'll be better with replication...
thanks for your help tho, now materials are the same on both clients

#

<@&213101288538374145> ban
discord gift scammer

dark edge
prisma fiber
green delta
#

i think i am slightly off somewhere.
It works on the server.
The client can do its thing.
But the server cannot see the client's.

I'm trying to set movement rotation.
E_setTurnRotation is not replicated and set on Tick.
C_SetTurnRotation is run on server.
S_SetTurnRotation is multicast.
SetTurnRotation is not replicated and it sets the rotation of the character.

kindred widget
#

Where are you setting the rotation value? Is that only locally set?

kindred widget
#

My initial assumption is that clients need to send that to server, and it should replicate ignoring owner.

#

Then I think the rest of your stuff will work.

#

Out of curiosity though. If this is nothing more than a right/left movement. It could be replicated as a bool, and the rotation could be created locally on all. Optimization stuff though.

green delta
#

whether bool or not, i will use that value as a desired rotation and it's only 1 of 2. might as well use it numerically rather than boolean and add an extra layer, no?

#

i'm not sure i follow what you mean by the clients need to send that to server, it is replicated, so not sure what else to do

kindred widget
#

I was more considering net code. Bool is 1 byte. I think the smallest rotator is 2 when perfectly compressed under best circumstances. Though it's usually about 4.3 bytes on average.

green delta
#

oh i see, could optimize later

kindred widget
#

But what I mean is that your controls are running locally. You're replicating, but your clients aren't telling your server what to replicate. They'll need to set their own local state, then RPC the rotation to the server so that it can replicate it to others.

#

Or if you want server authority, skip the local state set, and just do an RPC straight off of controls, and let server replicate back to all. That'll end up slightly laggy for the owner though.

green delta
kindred widget
#

Are your other clients or server seeing client rotation now?

green delta
#

yup but now i am wondering if my logic is too complex for something so simple

#

i input movement, then i send the info to server and then i do an RPC call

kindred widget
#

Maybe. Depending on your movement, this could also be derived from actor's last moving direction. Wouldn't even need networking. That's assuming that you can't run backwards though.

green delta
#

it's meant to make quick sideways turns

#

otherwise lightly tapping makes the character face the X axis

#

I will end up making this into CPP later

#

ty 🙂

rancid flame
#

I'm not entirely sure how Replicated works with nested stuff:
If I have an UActorComponent subclass with a Replicated property, do I also need to mark the UActorComponent itself as Replicated within its parent AActor?

dark edge
#

Yes.

#

And the parrot after itself has to be replicated

#

Parrot actor f****** Google text-to-speech

#

Parent actor

blazing spruce
#

Hey, If i wanted to make custom console commands do they have to be in the Level BP?

rancid flame
blazing spruce
rancid flame
blazing spruce
obsidian cargo
#

It looks like a common pattern with UE4 multiplayer is as follows: ```void AReplicatedCharacter::AttemptToDoThing()
{
if (CanDoThing())
{
if (!HasAuthority()) // Running on client
{
Server_DoThing();
}
else // Running on server
{
DoThing(); // Either spawn a replicated actor or modify replicated properties
}
}
}

// This is declared with UFUNCTION(Server)
void AReplicatedCharacter::Server_DoThing_Implementation()
{
DoThing();
}```

#

Is this correct?

#

Is there a common naming convention for "DoThing" type methods that should only be invoked by the server?

chrome bay
#

Nothing specific - it's usually a pattern for when you want some code to run on a server/listen server, but if the player is a client ask the server to do it for them.

obsidian cargo
#

Does the client need to ask the server to change replicated properties?

chrome bay
#

Yep always

#

Well, a client can change their local value - but then they'll be out of sync and the server won't know they changed it

obsidian cargo
#

Ok I thought so

#

Oh wait, I get my confusion

#

The CMC handles the server RPCs for you

#

So it only looks like it is run just on the client

chrome bay
#

yeah, internally it does a lot of processing before it sends RPC's off

obsidian cargo
chrome bay
#

It would yeah

obsidian cargo
#

That's where "rubberbanding" would occur

chrome bay
#

Rubber-banding is slightly different in CMC's case because it's not actually replicating any properties to the owner, just telling it when they got something wrong

#

But CMC is a very specialised code path

obsidian cargo
#

Ok that makes sense! Thanks for helping me double check my understanding.

#

I've read a LOT about network replication in general, but don't have any practical experience with it.

#

It seems UE4's implementation keeps things quite simple

#

Though I am also trying to understand how FFastArraySerializer works

#

I assume based on above, that the server would need to actually add / remove / modify the TArray

chrome bay
#

It's kind of a black box tbh, really it's reserved for when you have large arrays with lots of items

obsidian cargo
#

But I am not sure if I need the OnRep calls for it

chrome bay
#

Built-in TArray replication is actually surprisingly efficient

obsidian cargo
#

Because it has its own special callbacks on the structure

#

For my first dip into multiplayer... I'm replicating terrain destruction in the form of voxel removal!

#

Gotta start with the simple things! lol

#

I'm just planning on adding an entry to a FFastArraySerializer for each voxel removal operation, and in the PostReplicatedAdd call I'm doing the actual voxel removal

chrome bay
#

I tend to use the internal PostReplicatexxx functions just for transient states, then use the OnRep to push out updates to the game. Sort of depends on the use-case though.

#

But I would heed caution on adopting FFastArraySerializer before testing whether or not it's actually much cheaper

obsidian cargo
#

Is the OnRep called for all 3 PostReplicate types?

chrome bay
#

No just once

obsidian cargo
#

I mean, if you add, remove, or modify, it is always called?

#

Oh wait, I think I get it now

chrome bay
#

Well actually, potentially several times if you have any UObjects inside that are resolved

#

And ofc those Add/Remove/Modify funcs are only called client-side

obsidian cargo
#

If I were just marking a TArray as replicated, the OnRep would always get called for each TArray modification

chrome bay
#

No it would get called once per-update

#

So if you added 10 items in one go, it'd be called once when that replicates.

obsidian cargo
#

I'm not sure how the engine would know to replicate changes to the item's data

chrome bay
#

It tracks them internally

obsidian cargo
#

Wouldn't each of the properties on the items need to be marked as replicated?

chrome bay
#

For standard UPROPERTY serialization the engine creates a shadow copy of all the variables, and compares them

#

Depends

#

USTRUCT() properties are automatically replicated by default

#

You have to explicitly mark them as NotReplicated

obsidian cargo
#

I have TArray<int32> MyNums. Marked as replicated.

#

If I then say MyNums[0] = 5, would the OnRep_MyNums fire?

chrome bay
#

it would yeah

#

any received change to that property will cause the OnRep to fire

obsidian cargo
#

But would it be up to the client to discover what changed?

chrome bay
#

Yeah, but it knows

#

I.e. it's automatic

obsidian cargo
#

I mean lets say each of the elements represents something on the UI

#

I would need to have the client loop through all elements and update the UI

#

Because the OnRep call wouldn't tell me which element changed

chrome bay
#

Typically yes, but there's also another thing you can do

obsidian cargo
#

I could have some non-replicated book keeping to help with it

chrome bay
#

void OnRep_MyArray(const TArray<int32>& PreviousValue)

obsidian cargo
#

IE, track the last known item count

chrome bay
#

^

#

The engine can optionally pass the previous value into the OnRep callback too

obsidian cargo
chrome bay
#

So whenever it's changed, you can compare to the last value if you need to

obsidian cargo
#

I see, so at the least you wouldn't need to do the bookkeeping manually

chrome bay
#

That doesn't actually work for FFastArraySerializer though, as the engine doesn't keep a shadow-state for it

obsidian cargo
#

So THIS is why they say FFastArraySerializer is more for large arrays

#

You wouldn't want to copy arrays with thousands of elements

chrome bay
#

FFastArraySerializer is for large arrays with large items that replicate atomically

#

For pretty much everything else, I've found TArray to be way cheaper

obsidian cargo
#

Ah that's really slick

#

Is there a good way to know if a TArray was replicated because it just changed, or because it just became relevant?

#

IE the reason for the replication

chrome bay
#

The nice thing about TArray's built-in replication is that it can send individual properties of internal items, so if you have an array of structs, and you change one property of one struct, only that property is sent.

obsidian cargo
#

For my use case, I need to play a particle effect if the TArray just had an append

chrome bay
#

Whereas with FFastArraySerializer, the entire item is sent along with a hefty header identifying it

obsidian cargo
#

But I would NOT want to play the effect if a player is late joining or entering a new area with old modifications

chrome bay
#

For FX you typically just spawn them locally

obsidian cargo
#

Right... Through a multicast I presume

#

Unfortunately I don't think that will work for me

chrome bay
#

What you can do to get around that is compare the actors' CreationTime property to UWorld::TimeSeconds, and skip doing anything if they are the same

#

I do that for our weapon muzzle flashes etc.

obsidian cargo
#

The particle effect has to be fed the number and color of voxels removed. Typically represented by a texture that is 64x64 or 128 x128

#

I really don't want to pass that around since it can be computed locally

#

But only at time of execution

#

Is there some kind of "time since start" variable that would be consistent between client and server?

chrome bay
#

There's not, but you can do what I mentioned so that the client skips doing something if the actor replicating it was created in the same frame

obsidian cargo
#

Alternatively, I could have my array elements have a "just spawned" bool of some sort that is true on initial add, and then changed to false some amount of time later (like 1/4 second)

obsidian cargo
chrome bay
obsidian cargo
#

That's a really good idea. I'll have to think about how I can use it.

#

Oh I see it in your code!

#

That's actually pretty simple

chrome bay
#

We drive muzzle flashes from a replicating counter, so when players walk back into relevancy range, they don't start triggering FX

obsidian cargo
#

Yeah I read about the burst counter a bit

#

I need to practice a bit to get a handle on exactly how that works

chrome bay
#

You can use multicasts too, but we prefer variables because the engine can prioritise them and we prefer to leave the unreliable buffer free for other things

obsidian cargo
#

Yeah that makes sense

chrome bay
#

Generally means we're sending much less data overall

obsidian cargo
#

It's cheaper to include the variable replicate with the next packet

#

Than to create a special RPC just for something visual

chrome bay
#

Yeah, and if a weapon fires like 10 shots before it's next update it doesn't send 10 RPCs.. just one var packet

obsidian cargo
#

So just thinking about that bIsOpenChannelPacket check you have above

#

The rep call will always be right after the spawn?

chrome bay
#

Yeah, the actor is spawned, then replicated properties read-in, then it "begins play"

obsidian cargo
#

I mean would you ever get a very small non-zero value there?

chrome bay
#

Not ever fortunately

obsidian cargo
#

Oh fantastic

chrome bay
#

When an actor channel opens, it contains all of it's latest state

obsidian cargo
#

Epic really did a good job keeping the edge cases for replication smooth

#

I've worked professionally with Unity for over 8 years, and there is so much muddying your code to handle edge cases they don't deal with properly

chrome bay
#

yeah I'm heavily biased but IMO UE's networking stuff is really great

#

some occasional "gotchas" but for the most part, it's up to scratch

obsidian cargo
#

It's why I'm switching over to UE. UE's architecture is fantastic. So much closer to how I like to approach problems.

#

It's super complicated at first, but as you learn it, all the complexity has good basis

#

Well most of it

#

I still hate UE_LOG... lol

chrome bay
#

Some stuff could definitely do with a trim-down but the nice thing about UE is that it's networking layer is very foundational

#

It's not something that they kind of plonked ontop later

obsidian cargo
#

Is there a common naming convention for methods that should only be called on the server?

#

Methods that are not set to replicate, etc

chrome bay
#

I don't think so. I use Server_## Client_## Multi_## etc.

obsidian cargo
#

Right, those prefixes make sense for RPCs

#

This is really cool.

#

I wasn't sure I wanted to try to get my game working on multiplayer. But I see now that blueprint can be largely unaware that it is running on a replicated environment.

chrome bay
#

If anything it's probably better if Blueprint has nothing to do with any multiplayer at all 😄

obsidian cargo
#

Yeah... I prefer to put a lot of things in C++ before blueprint.

tacit sage
#

Hi, I have server and two clients. How can I trigger function on the client that other client connected to the game and also when client disconnects?

I have tried multicast RPC in GameMode on PostLoing with unique network player id, but sometimes it happens that playerstates are not replicated to client yet.
I found that in UWorld is NotifyAcceptedConnection - looks fine, but there is no disconnection function.
And Playercontroller get only info about itself after established connection.

Do you have any ideas how to approach this?

obsidian cargo
#

But I am embracing blueprints

chrome bay
#

Blueprint networking has some shockingly stupid "gotches" that make little sense

#

Like OnReps not really being OnReps which still grinds me

#

But it also doesn't really have even half the flexibility of CPP networking

obsidian cargo
#

What differs with the blueprint OnReps?

chrome bay
#

Stupidly the Blueprints ones are called whenever the property changes, both on client and server

#

So they aren't really "OnRep", they're more "OnChanged"

obsidian cargo
#

Oh

#

I'm glad you told me that

chrome bay
#

But they fire on all connections incl the server, which is equally stupid

obsidian cargo
#

That could get super confusing

chrome bay
#

And I can't really fathom why Epic chose to have BP behave differently to CPP

#

But it's probably a legacy decision that they're too committed to to fix now

obsidian cargo
#

Yeah it was probably a legacy decision where two departments didn't talk to each other

chrome bay
#

But yeh generally speaking anything involving networking I stay well clear of BP

obsidian cargo
#

Noted

#

I'm using GAS

chrome bay
#

Just expose the relevant nodes if needed and let CPP handle it

obsidian cargo
#

So I'm already planning on doing a lot of foundational work in CPP to expose functionality to blueprint

chrome bay
#

Yeah a lot of that is hidden away

obsidian cargo
#

I've spent the last 3 weeks learning about GAS, and replication

#

As well as tweaking my game code as I learn things

chrome bay
#

But generally I think GAS is designed so that BP doesn't have to worry about networking so much

obsidian cargo
#

That is what I've noticed

#

It is what put me on the path to learn replication

#

It would be easier to learn one thing at once

#

And then apply it

#

But the replication seemed like low hanging fruit

chrome bay
#

My advice would be learn networking/replication outside of GAS

#

Even with a simple test project with some UI buttons and some print strings

obsidian cargo
#

That is what I started doing yesterday actually

chrome bay
#

Just so GAS doesn't muddy it up

obsidian cargo
#

I have a multiplayer project with no GAS

#

It's just stupid logging and spawning junk at this point

#

But it's where I came up with the TryDoThing template above

chrome bay
#

And OFC you can't use GAS for everything so sometimes you may need it anyways

obsidian cargo
#

Right

#

Though the gameplay tags seem to be oh-so-versatile

chrome bay
#

Tags are frikkin amazing

#

Genuinely revolutionary for me

obsidian cargo
#

There is a lot of brilliant engineering that went into GAS

#

So many of my JR engineers make crazy stuipid FSMs in gameplay design. GAS does away with all that.

ember vine
#

@chilly mason but is getting the ping going to be good enough for that specific multicast ? im trying to handle instances when that specific packet might have got there slower than what the ping states

#

afaik the ping doesnt update that often ?

#

but currently i do alot of network extrapolation based off the ping

chilly mason
#

not familiar with ue4 netcode

ember vine
#

"does anyone know if a way to find out how long it took for a multicast to reach a client, im thinking about measuring the server world time, passing that through and comparing it to the clients but doesnt seem to be like a good way to do this" was original question

chrome bay
obsidian cargo
#

Your ping is the time it takes to send a message and get a response

chrome bay
#

@ember vine ping is really the only way. Server World Time won't help much because server/client don't have any sync'd clocks

#

But it'll never be perfect, it's literally impossible to know how long it took really

ember vine
#

surely theres some way to atleast slighty increase the accuracy

chrome bay
#

noop, you're staring down the barrel of an age-old physics problem

ember vine
#

what if i try syncing the world time clocks at the start and go off there ?

chrome bay
#

They'll slowly go out of sync

obsidian cargo
#

Are you worried about packets arriving out of order?

#

Or is there another concern with time sensitivity?

ember vine
#

yeah pretty much, im trying to "rollback" an unsynced state into roughly where it is on the server

#

i use ping for this kind of stuff currently but im wondering if there is a way to achieve more accuracy

#

especially for people with unstable connections

obsidian cargo
#

You are rolling the client back to the server?

ember vine
#

a server multicast/repnotify would come into the client and the client would adjust

chrome bay
#

Instead of using ping you can repeatedly bounce packets to and from the server to get a more accurate clock you can control

#

Again it won't be 100% perfect, but it'll probably update more often than the ping

obsidian cargo
#

Are you talking about a heartbeat?

ember vine
#

im not sure what is meant by a heartbeat, but yeah essentially like something jambax is saying, im looking for a more accurate way to extrapolate rather than just using ping

#

when i test with unstable connections there is the potential to desync so im trying to have fallback logic to resync

chrome bay
#

Essentially all you do is save a timestamp, send a packet to server, and the server sends one back

#

Compare the time from send->receive and there's your RTT

obsidian cargo
#

Heart beat / keep alive. Periodic message sent just to keep a connection alive / gauge the health of the connection.

chrome bay
#

But here's the rub.. RTT is never guaranteed to be symmetrical

ember vine
#

in that case, is there a way i can just get the ping to update more aggressively? right now i feel like current UE ping is pretty slow on the update

chrome bay
#

And unfortunately that latter part is an unsolvable problem

ember vine
#

i see

#

i understand that i cant fix the internet as a whole but just trying to seek ways i can achieve as much accuracy as possible

chrome bay
#

APlayerState::ExactPing should be reasonably accurate

obsidian cargo
#

Can't you change network frame rate on the server?

#

Or is this something different?

ember vine
#

something different

chrome bay
#

ExactPing should be updated everytime you receive a packet

#

Check UNetConnection::ReadPacketInfo

#

Right at the bottom

ember vine
#

its basically like, client 1 performs X action server request which then multicasts

client 2 is running some predictive logic but due to him being laggy now needs to be rollbacked into another state

#

if i exactping inside a repnotify would that give me what i need then ?

chrome bay
#

Theoretically yeah

#

It's more of an "average" ping, but is updated each time you get a packet

#

But you can always override APlayerController:UpdatePing and store the incoming 'ping' value somewhere for the latest measured ping for that frame

ember vine
#

i see, but there is also some discrepancy between client/server update rate and the client frames correct? so is there a possibility i grab it too early from there ?

#

well i guess if i did it in a repnotify that wouldnt be the case

#

hmm

#

ok thanks guys, very insightful! will try this

#

my only question is whats the point in ExactPingV2 thonk

chrome bay
#

no idea 😄

#

Nobody seems to know either 😄

#

Seems to be two different methods of keeping track of the average ping

ember vine
#

LUL i see

chrome bay
#

What an unbelievable PITA that InitializeComponent() is called before replicated properties are read in. F

#

I take it back UE netcode sux

violet sentinel
chrome bay
#

I have something similar but I have a really obscure setup for this particular comp.. I really need some function that's called post construction script and post replicated properties being read in.. but unless I manually do that from the owning actors' PostInitComps I'm stuck

#

And can't use BeginPlay because it's stoopid

#

Nearly found a way around it but doesn't look like there's anyway to see whether a component is due a property update even when looking deep into the actor channel

eager jolt
#

on my game when you shoot someone it triggers an event that "kills" them my problem is I cannot get a blood screen to show up on the dead players screen

#

here is my blood screen code

#

how can i attach the correct owning player to the one who is supposed to be dying?

short arrow
#

Client should have a way of knowing it's dead on its own, and then setting up the logic for that blood widget itself.

eager jolt
#

thats what i said

#

but some guy the other day got me to re-write the code

#

and make it so only the server decides whos dead

short arrow
#

Server should decide who's dead, but the server shouldn't be running widgets for the client

eager jolt
#

do you mean like this?

#

just remembered theres a client side test for death

#

where should i attach this?

#

i feel event tick is a bit of a waste

short arrow
#

Do you have a replicated health variable maybe?

eager jolt
#

no just "is dead" yes/no

short arrow
#

Okay, one method you can use is to make the is dead variable a rep notify

eager jolt
#

ahhh yes

short arrow
#

Inside of the repnotify you'll put that code. Or an event that calls this code

eager jolt
#

thanks 🙂

short arrow
#

did you get it working? there may or may not have been a step I forgot to mention

eager jolt
#

yh it works pretty good 🙂

#

i did have to put a branch inside the rep notify

#

to test if "is dead" was true again

short arrow
#

yeah that's what I was missing

#

my bad, glad you caught it

eager jolt
#

🙂

proven kayak
#

so, subsystems are amazing, but as they are uobject derived, they don't replicate (by default). is there any problem with having the game state, or game instance, add subsystems to its ReplicateSubobjects override? my intuition tells me this would probably work, but i wanted to ask first if there is a more obvious way to implement replicating singletons

chrome bay
#

They aren't sub-objects so it won't work

#

ReplicateSubobjects() only works when the sub-objects' "Outer" is the actor, and when it is indeed a sub-object.

#

If you need replicated properties for a subsystem then usually the best practice is to spawn a replicated actor to manage it

proven kayak
#

game instance subsystems dont have the game instance as an outer?

twin juniper
#

hey, im developing an app for phones that can live stream video from a computer, that is on a diffrent wifi network, money no issue

meager spade
#

@proven kayak yes they do, but GameInstance does not replicate nor can it be replicated.

#

Subsystems are not meant to be replicated

#

if you need to replicate, use an actor.

proven kayak
#

got it. thanks! totally spaced that GI dont replicate

lament minnow
#

question, how can i get which client is making an multicast rpc call to a function?

hollow eagle
#

clients can't call multicast RPCs

#

only the server can

lament minnow
#

ah, I missed that, thanks.

twin juniper
nova wasp
#

I feel like that isn't really an unreal related problem

sweet pelican
#

Visual studio isnt liking RPC implementation functions, wont let me compile

#

Any ideas on how to fix?

lost inlet
#

That’s an intellisense error

#

You can explicitly declare that function to help it out I guess but won’t cause errors

#

Look at the output log for actual errors

sweet pelican
#

so
virtual void ServerRPC_SpawnBomb_Implementation()
or smth?

twin juniper
lost inlet
#

Though check the output log for the error

#

Ignore the error log entirely, or at least set it to “build only”

sweet pelican
#

ah ok ty

sinful tree
twin juniper
#

I asked in general and got nothing

dark edge
pure elm
#

Guys I have a problem

#

I want 4 people to have a shared world

#

Which they could play

#

But its a long term game I'm developing

#

So I don't want the world to disappear when they stop playing

#

Furthermore, I want any one of the 4 players join the world, at any time, even alone; How can I achieve that????

#

Pls help, networking is new for me

winged badger
#

you don't

#

even with dedicated servers, physics will start breaking down due to lost precision in float timestamps after 3 days

hollow eagle
#

It's not a networking issue, it's a services one. You would have to write a system to store world state when no one is playing, then either automatically launch a dedicated server or make the data available for local play when a player logs in.
None of this is even remotely trivial, and there are no out of the box solutions. This is not the sort of task that I'd even remotely recommend to a beginner. There aren't even any good starting points to point you towards - you could look at dedicated server and user management platforms like playfab but there's still a lot of custom services work it'd require.
I suggest coming up with something simpler to start that contains some of your idea and slowly work towards learning what you need.

pure elm
#

Ty!

#

I'm not quite sure, what a dedicated server is, 😅 , could you elaborate?

hollow eagle
#

Dedicated servers, as they apply to unreal, are a specific type of build that is meant to host a multiplayer game without the server itself acting as a player - as opposed to a listen server where an actual player is running the server from the same process as they're playing the game in.
The fact that you've asked that question makes it seem like you're well in over your head for this type of project. If you haven't already, learn unreal and build something single player first. If you've done that, learn to build a simple multiplayer game and move forward from there.

pure elm
#

Since that is too hard for me, could I have one player as a host, to save the world data, and to have him running the game for other players to play?

hollow eagle
#

That would be a listen server, yes.

winged badger
#

saving the world state is also far from trivial

pure elm
#

And I have been making single player games for over two years now, trying to make a multiplayer game rn

pure elm
#

Other than the players PCs?

hollow eagle
#

Generally yes, this would be running on something you as the developer control.

winged badger
#

physical computer != dedicated server instance

#

the hosting services generally have a single computer run many instances of the game

pure elm
#

You're hurting my brain 😅

winged badger
#

if i need 2 physical CPU cores and 4GB or RAM to run a dedicated server

#

and i have 16 cores with 32GB of RAM

#

i can run 8 games simultaneously

#

which is what dedicated servers generally do

pure elm
#

Ooh ok

#

I think I'll just try to make a listen server and just tell the players to cope with it he he

winged badger
#

you do not have to have a separate PC to run it while developing

#

it does need to have enough resources to run a server instance + client instance though

#

also, players are spoiled brats and they don't do coping

pure elm
#

Thanks for explaining! Apperantly I will need a lot of time to learn mp :D

pure elm
#

I think I'll just try to find out how playfab works for now

#

And try to put it into my game

winged badger
#

its too early to integrate playfab

#

first you need to figure out if the game is even fun

dark edge
pure elm
#

OK, thank you for the advice!

#

BTW, does playfab require me to have a bought steam page?

winged badger
#

it shouldn't, but playfab is not free

pure elm
#

😞 any other services that I can use that are free? If there are?

#

Btw will steam do?

winged badger
#

steam doesn't offer servers

#

first step - listen server + saving and restoring the world

#

then you can move to the next thing, but nothing will work without the step 1

pure elm
winged badger
#

no

#

that is why its first step

#

you only need 2 computers

pure elm
#

Thanks for the advice man, this is soo important to me!

rustic kraken
#

Hello i have an array of a structure which stores players email(for now) what i am trying to do is everytime a player joins the session their em,ail will get added

#

but the problem is, only emails on the server side are getting added

#

for eaxample if this is a server player then his email is getting added and saved but when the client jo9ins the array changes from his side but not from server side

#

i am calling the event on the ss on server and set the array variable to replicate

#

shouldnt that work? what am i lacking?

#

ty

kindred widget
#

If I'm not mistaken, you need to remove everything to the right of the Add node, and don't call Add on the client.

#

You simply want to send the client's email to the server. Add a new struct to the array on the server. This will change it and flag it for replication on the server. Now everyone should be up to date.

rustic kraken
#

Hey @kindred widget thanks for the quick response, ok so now what happens is, when the server player joins,

#

the array length gets 1

#

but again when the client joins, instead of the array length being 2, it remains 1

#

Code:

kindred widget
#

What class is this in?

rustic kraken
kindred widget
#

Ah. Yeah, that would be your reason I assume if this is a singleton.

#

Clients cannot RPC through anything they don't own.

rustic kraken
#

so what type of class do you prefer? @kindred widget

kindred widget
#

For something like login? Most likely your controller class. Makes most sense since it's basically the player's identity and also the root of their ability to RPC.

#

Although. To be fair, PlayerState wouldn't be a terrible idea either. Specially if you just wanted to update that one playerstate. Then you wouldn't even need the struct, you could just get the connected players and get the email from it.

rustic kraken
#

ok lemme try

rustic kraken
kindred widget
#

Ah. Fair. But yeah. Controller or PlayerState are decent choices for the player to use to send their email from.

rustic kraken
#

used controller @kindred widget

kindred widget
#

What have you done?

rustic kraken
kindred widget
#

Where is your print?

rustic kraken
kindred widget
#

The struct is replicated?