#multiplayer

1 messages ยท Page 673 of 1

kindred widget
#

Er. Array.

rustic kraken
#

yeah

kindred widget
#

Remove the Number print you have, and print whether the RPC is running. Print if the client is trying to send it and print if the server is running it.

rustic kraken
#

and whats RPC i am new to multiplayer

kindred widget
#

RPC is RemoteProcedureCall. Your Server event.

rustic kraken
#

oh

#

like this? @kindred widget

kindred widget
#

Yeah. Also one when your client tries to send that message.

rustic kraken
#

yes both gets called

#

this one too

kindred widget
#

How many times?

#

And what event are you running this on?

rustic kraken
#

and the other on the on player join

kindred widget
#

Make sure your logic for this on beginplay is behind a branch for IsLocalController

rustic kraken
kindred widget
#

Show me what you have so far?

rustic kraken
rustic kraken
#

@kindred widget

kindred widget
#

Move the IsLocallyControlled check before anything else on Beginplay.

rustic kraken
rustic kraken
kindred widget
#

How many players are you playing as, and with what setting?

rustic kraken
#

ONE AS LISTEN SERVER

#

oops sry for the caps

#

and the other one as client

kindred widget
#

Did you stop the prints for your other actor from earlier?

rustic kraken
#

yes

#

i am currently printing from the controller

kindred widget
#

Then I'm unsure. What you're currently doing should work. RPC from local controller's beginplay, add email. Should add one email per connected client including the host.

low helm
#

I have a simple problem which is deceptively difficult to solve.

I want to attach turret-actors to vehicles in a multiplayer game. You'd think this would be easy. So far, it's a nightmare. I've tried an "ATTACHMENT" variable on the turrets which points to the vehicle, and ONREP attaches it for all clients. This works, but only intermittently, seemingly because of unreliable netculling between them.

winged badger
#

set car as the turrets owner

#

have it use the car's relevancy

#

attachment is replicated by default

low helm
#

woh

#

that might work

low helm
#

you madman

#

in all my years, I've never had a reason to set an actor as owner over another

red sand
#

Hi there, I just need some small pointers as I am doing networking part for the first time and trying it out.

In which class should Authentication, Matchmaking, and all the networking part be handled in?
should it all be done in Game Instance or do they need to be done in different class? if so, can someone explain em to me?

low helm
#

Game instance is totally non replicated

#

But clients can save data there

#

GameMode GameState PlayerState PlayerController, those 4 will make the most sense to perform most of your networking logic

red sand
low helm
#

It's common to put some connection logic in the Main Menu widgets, maybe this isn't like.....the greatest idea. It's still probably better than putting it on your GameInstance, cause then it's always loaded.

chrome quest
#

I have a question on replication. I have an array of UObjects. The array is marked as replicated but for some reason the contents are not. When I get an element from the array, it is valid on the server but invalid on the client. The array length is updated on the client whenever I add or remove from the array.
Could someone enlighten me a bit more on array replication please?

chrome bay
#

The objects themselves must also be replicated somehow

chrome quest
chrome quest
chrome bay
#

Well they need to be replicated as well as the array

chrome quest
chrome bay
#

You can only refer to a UObject through replication if it's either a) stably named or b) created via replication, as the sub-object of an actor

chrome quest
chrome bay
#

Essentially something the client can refer to via a path

#

E.g. like an asset

chrome quest
#

Ahh, I see.

#

Unfortunately, there's no way for my UObject to be a subobject. Its immediately added to the array as soon as it is created

chrome bay
#

But it must have an outer of some kind?

#

The only way to replicate a subobject is via an actor, there's no workaround

#

These are UObjects that you are creating with NewObject presumably?

chrome bay
#

Yeah, so they'd need to be created using an actor as the outer, and that actor implementing ReplicateSubObjects for them

chrome quest
#

I'm reading through the blog now, and I'm seeing an almost exact solution to my problem. Its for the inventory also

chrome quest
#

@chrome bay , you aren't using RPCs anywhere right? for creating and destroying

sage isle
#

Im having an issue with the thing im working on, I was trying to swap characters when I hit a certain key and it works fine, but when testing on the second player it started giving this warning
LogNet: Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor Character_C_2. Function ChangeModel will not be processed.
And then it gave that warning everytime even when I went back to the first player, anyone know what this means?

chrome bay
chrome quest
#

For the actor component implementation, we replicate subobjects in the actor component class but using the parent actor of the component as the outer. Correct?

chrome bay
#

yeah

#

If you use the component it tends to break things because client-side, they are always created using the actor as the outer

dark edge
#

What's the point of item as UObject vs item as UStruct?

chrome quest
chrome bay
chrome quest
#

Also, I have some Inheritance stuff too.

chrome bay
#

But yeah for most inventory, you'd just use a struct or something most likely

#

My actual implementation doesn't replicate the objects now, they're created deterministically at each end and stably named

#

Which is naiiice

chrome quest
#

True. That was my initial implementation. But due to some design decisions and the variety of use cases of a slot. For example, character body parts are inventory slots in themselves.

chrome bay
#

Yeah, it has limited application tbh but can be useful. The only reason I really need to rep anything is because the slots are initialized from tables, and may have different layouts etc.

#

99% of the time though, a struct or actor comp is fine

kindred widget
#

On a side note to UObject replication. I noticed there some form of crazy slowdown when replicating a bunch of UObjects. As in about maybe 300 max. But only when testing in PIE with multiple windows. I read somewhere that it has something to do with some insane logging or something but could never find out what that meant or if there's a way to disable it?

chrome bay
#

Hmm nothing I've noticed

chrome quest
chrome bay
#

In BP it automatically converts the "Return" value to the same class as the input class

#

So it's just a convenience thing to avoid an extra Cast node in BP

chrome quest
#

Oh? That's nice.

chrome bay
#

tbh so many meta attributes aren't documented, they're like gold when you find them

chrome quest
#

lol. True that

kindred widget
#

My favorite isn't even a meta. I HATE pure blueprint nodes that return Arrays most times, because they're usually getters that do a bunch of looping... Which when properly marked in C++ are marked const.. which are automatically pure nodes in blueprint even when marked BlueprintCallable. You have to explicitly mark them (BlueprintCallable, BlueprintPure=false) to get them to be an actual non pure node.

pure elm
#

Quick question; If I have several players, I would need several save files, right?

kindred widget
#

Depends on what you're saving.

#

Depends on game style.

#

If you're talking like.. ARK server. One save file saves everything. Or at least mostly everything, they save some data in separate files.

#

Where as at work, everyone saves all of their own stuff locally. So.. technically multiple save files, but it's all done locally on client so they only have their one file.

#

True that.

pure elm
#

Kk, thanks

obsidian cargo
#

What would the OnRep method signature for this look like? Is there a complete list of valid OnRep signatures somewhere? The only one I know of is const T& to get access to the previous value.

chrome bay
#

Yeah the same

obsidian cargo
#

Oh it's just OnRep_Array(const Array& previous)?

chrome bay
#

You may not know which property was sent but you can compare to find out

#

yeah

obsidian cargo
#

So I have to compare each of the elements to determine changes

chrome bay
#

yeah

obsidian cargo
#

Awesome

#

So far as I've seen this replication stuff is pretty simple

#

It's a little odd that RPCs have to go on owner actors only

#

Could be easy to end up with spaghetti actors with all the RPCs

#

Is most of the complexity dealing with race conditions, throughput, and deployment issues?

chrome bay
#

Generally it's to avoid cheats and encourage a decent architecture, i.e. a client can't just ask the server to do something on an actor it doesn't own

obsidian cargo
#

Oh I can see that

chrome bay
#

The concept of "ownership" allows you to restrict what items a client might be able to influence

obsidian cargo
#

So far my validation methods are "return true"

chrome bay
#

yeah tbh most of the time they are ๐Ÿ˜„

#

If that Validate func returns false, the sender is immediately kicked

obsidian cargo
#

In my case, I'm working on destructible terrain (through voxels). It would be nice to put the RPCs on the voxels themselves, but they will have to live on the pawns.

chrome bay
#

Well it depends

obsidian cargo
#

Thus a little bit of creep towards "spaghetti" actors

#

The pawns themselves shouldn't care they live in voxel based worlds

chrome bay
#

you may instead have a general "voxel interaction" component that handles the RPC's, that can live on the controller

obsidian cargo
#

A component that is added to the actors?

#

That is a really good idea

chrome bay
#

Yeah or the controller. It's a common approach for "interaction" systems for e.g.

obsidian cargo
#

I'm really big on single responsibility / single purpose in software design

chrome bay
#

I.e imagine a scenario where a crate can be opened by lots of players, they can't all own it, so the solution is to build a general-purpose "interact" system that sends an RPC, and passes the crate as the "target" of the interaction

obsidian cargo
#

That's really clever

chrome bay
#

And either the pawn or controller would have one of those comps

obsidian cargo
#

It gets around the limitations of ownership

chrome bay
#

yeah

obsidian cargo
#

But doesn't pollute actors that shouldn't care about interaction

chrome bay
#

Exactly

obsidian cargo
#

How would time sensitive details like melee attack combos be typically handled?

#

IE games like Dark Souls or Monster Hunter

#

Where you have to press the attack button at specific points of the animation

#

Due to latency, you can't be too strict on enforcing it

chrome bay
#

Hard to say, something like that might be determined entirely client side

#

But if you wanted to validate it, you would need some tolerance

obsidian cargo
#

I was thinking of adding some very crude validation

#

Attack 2 has to happen within 1.5 seconds of attack 1

#

The animation is closer to 0.75

chrome bay
#

someone may have done a validated combo attack with GAS

obsidian cargo
#

But would give plenty of leeway for latency, without giving a blank check on spamming the more powerful attack of the combo

#

(for cheaters I mean)

#

It's similar to the cooldown latency problem

chrome bay
#

yeah pretty much

obsidian cargo
#

Where else can I expect to see complexity with multiplayer in UE?

#

I've done a bit of dev ops for teams, so I'm not too concerned about services and dedicated servers, etc.

#

For my game I'm completely removing match making from the equation by keeping it LAN style play

#

Listen servers only

chrome bay
#

Anything involving client prediction is finicky usually

obsidian cargo
#

Oh ok. That is good to keep in mind.

chrome bay
#

Epics advice is to "predict as little as possible"

#

Assuming you can anyway

#

GAS tries to build it in as a fundamental concept

obsidian cargo
#

Right. I've already decided it is impossible to predict my terrain destruction

chrome bay
#

Anything physics-based is inherently a bitch

obsidian cargo
#

I'm working towards a slower paced combat style that won't be hurt by the latency

#

Ok that makes sense, the purpose of chaos is to make things deterministic

chrome bay
#

Other than that it's just the obscure race conditions that only present themselves 3/10 times in a real world situation

#

But you kind of learn to code around them as you go and find them

obsidian cargo
#

Awesome

chrome bay
#

Then it becomes second nature

obsidian cargo
#

It sounds like UE4 has solved the real complexity for us

#

I'm super familiar with the pitfalls of cross-platform serialization

#

Haven't done "replication between simultaneously running simulations"

chrome bay
#

yeah cross platform problems you don't really need to pay any mind to

obsidian cargo
#

But I have dealt with versioning, asset distribution, etc.

chrome bay
#

I mean the backend side of things can still be a pig at times

obsidian cargo
#

Is there a built in solution to validate the server and client is running the same game version?

#

I've had to build things in the past to allow any version of client to connect to the server to retrieve data. Super PITA

chrome bay
#

yeah that's built in

#

with checksums etc.

obsidian cargo
#

Saying client and server has to be the same version solves a huge list of problems

#

Thanks for the help! I've gone from "this all sounds terrifying and complicated" to "I've worked with much worse, this is going to be awesome"

chrome bay
#

I won't say it's entirely free of headaches but it's pretty good ๐Ÿ˜„

autumn glen
#

Quick question about replication - currently I'm using "get base aim rotation" as it's replicated by default; using it for my animation BPs head movement.
I've disabled all the "use controller rotation yaw / pitch / roll" options, but with the yaw option disabled it doesn't replicate.
I need it disabled as otherwise it makes the head turn too much and the body move along with the yaw rotation.

Any easier way to fix this other than creating another variable to replicate instead or something?

meager spade
#

turn on your cmc to use Control rotation

#

if you don't want to use control rotation, then yaw will not replicate.

autumn glen
#

cmc?

#

So best way is to just use controller rotation yaw and fix the unwanted body / head rotation

meager spade
#

CharacterMovementComponent

#

i counter rotate the body

#

and this is what i achieve

#

this all animation blueprint magic ๐Ÿ˜›

chrome quest
#

@chrome bay , thanks again for the help. I've gotten round to implementing the code example and it works perfectly well.
I only hope I'm not making a mistake replicating the entire inventory.๐Ÿ˜…

obsidian cargo
#

Total magic level stuff there

meager spade
#

capsule always rotates, i just counter rotate the root bone

#

then when it hits threshold, i bring the root bone back with a curve

obsidian cargo
#

Here I am building with legos and @meager spade is busy carving a Michelangelo

winged badger
#

with a lego chisel

#

๐Ÿ˜„

obsidian cargo
#

OnRep isn't called on the listen server, yet a lot of the logic in OnRep also needs to happen on the listen server. Is it safe to directly call OnRep on a listen server in response to its own changes?

#

Doing so is not going to be 1:1 the same as how it happens on the client

#

Because the client resolves OnRep as an aggregated delta against multiple changes

#

So if the server has multiple changes in a single frame that invalidate themselves, calling OnRep directly on each change will give a different answer than the client receives (potentially no OnRep calls)

winged badger
#

i find that approach.... impractical

#

generally, i'd make a SetWhateverImReplicating function

#

that i'd call on server, and from OnRep

#

i prefer my breakpoints not hitting inside OnRep functions on server

chrome bay
#

Does anybody have a workaround for replicated properties in an actor component not being set at component register/initialization time? Annoyingly the owning actor is fully initialized and runs postinitcomps before any default subobject props are read in

#

Grasping at straws atm, trying to see if there's a way to grab any "pending" value from the net driver/actor channel or something but coming up empty handed

#

If the component is spawned dynamically or the actor was placed in the world, it's not a problem - it's only actors which are spawned on the fly and their default comps ๐Ÿ˜ฆ

slim matrix
#

whats a good way to replicate weapon sounds like right now i use a multicast to replicate my guns sound every time it fires but if there is lag it may cause all the sounds to bunch up and bee off sync to the gun

obsidian cargo
obsidian cargo
#

Oh wait, those might not help

#

You'll need a "cooldown" for the SFX

winged badger
#

@chrome bay for us, its usually OnReps that fail

#

and doing RepNotify_Always usually fixes it

slim matrix
chrome bay
#

Start a timer on the client to automatically simulate FX when it thinks the weapon is firing

#

Works fine so long as you have a fixed fire rate

#

Even multicasts/properties won't arrive at a fixed interval

winged badger
#

we did have a scenario where actor responsible for procedural map sync did not replicate its initial data if host changed any settings before people joined his lobby

obsidian cargo
#

When does PostInitializeComponent happen in relation to replication?

winged badger
#

on fucking release day

chrome bay
#

๐Ÿ˜„

#

I've got a really obscure setup, but essentially what I've found is that the actors construction script runs before sub-object properties are read in

obsidian cargo
#

Nice job QA!

chrome bay
#

But only if the actor is spawned

slim matrix
#

so would i send a rpc i tell it to play the sound every number of seconds before i tell it to stop?

winged badger
#

our QA is lowest bidder that the publisher found

#

and they are worth every penny that way

chrome bay
#

The only way I can get around it is move the property to the actor table throw

obsidian cargo
winged badger
#

releasing a DLC tomorrow

#

engaged our own + community testers

#

last 2 weeks

#

im under constant fucking ambush by a barrage of critical bugs

#

that our QA did not find

obsidian cargo
#

Are you the Senior on the project?

winged badger
#

lead programmer

obsidian cargo
#

Yeah, that's just the job description

#

But you have my sympathies non-the-less

#

I left the game industry for 3 years hoping it would be better

#

It wasn't

#

And the job was boring to boot

winged badger
#

mine is everything but boring

#

not boring enough

#

@chrome bay not on both client and server

#

with deferred spawn, construction script on server runs only after you call FinishSpawning

slim matrix
#

instead of sending a multicast when ever the gun fires could i instead trigger the sound when ever the gun fire animation plays on the client

winged badger
#

on client it waits for OnReps to call BeginPlay, but runs construction immediately

obsidian cargo
#

Basically BurstCounter > 0 means play the effect. Or something similar.

#

I haven't studied out Burst Counter enough to talk about the nuances

#

There's a lot of documentation on the concept around the web though

slim matrix
#

ive looked it up but all i find is doing it for c++ in UE

obsidian cargo
#

It has several advantages over RPC, but I don't intuitively understand the system well enough to articulate them

#

Oh right.. it is more a c++ thing

#

Sorry I assumed C++

mighty garnet
#

Say I have 10000 static actors (buildings) in my level, and ONLY their visibility and collision settings need to be kept in sync between server and client (and only ONCE, basically from "Alive" to "Dead") -- what's the most efficient way to keep the state in sync?

Does this actor need to be replicated or should I just maintain a replicated TArray of "destroyed" objects in the game state that clients can access to manage their own state? Im not sure how much server overhead is associated with having that many actors to check for changes on every network update

winged badger
#

i think Jambax's blogging career started and ended with burst counters ๐Ÿ˜„

#

@mighty garnet are they net addressable by default?

#

say, placed on the level

mighty garnet
#

yep they're placed in the map

winged badger
#

then a fastarray

mighty garnet
#

ooo whats that

obsidian cargo
#

It's really cool, but not well documented

winged badger
#

it is well documented

#

just not where you'd expect

obsidian cargo
#

Fair enough

winged badger
#

docs are in NetSerialization.h header

obsidian cargo
#

I searched google

obsidian cargo
winged badger
#

header is litearlly more then half comments

obsidian cargo
#

Most the info I found on Google was actually WRONG, so I was a bit confused

winged badger
#

even has a #if 0 example of implementaiton in it

mighty garnet
obsidian cargo
#

Helpful tip: Add an Owner pointer to your container and use that to chain out your rep events

winged badger
#

and never ever make it a UPROP

#

TWeakObjectPtr

obsidian cargo
#

Oh you mean don't make the owner a UPROP

winged badger
#

you do not want to know what shit inherited blueprints put in there

obsidian cargo
#

Doesn't the container need to be a UPROP to replicate?

winged badger
#

when serialization kicks in

#

like CDO of the native base class

obsidian cargo
#

OMG

#

I finally get why C++ needs to use weak pointers

#

I'm a single man team not working with designers atm

winged badger
#

you don't need to replicate the Owner

#

each instance can set it on the fastarray

obsidian cargo
#

Right, you need UPROP on the container reference inside the owner, so the fast array can be replicated

#

But you don't need UPROP on the owner reference in the container

winged badger
#

yes

#

and TWeakObjectPtr prevents any dangling pointers

#

so its quite adequate

obsidian cargo
#

Also, even though you mark the fast array as replicated, and do DOREPLIFETIME, it doesn't look like the OnRep function call even needs to be declared for the fast array

#

At least in my (limited) testing it seemed the OnRep function was ignored

winged badger
#

if you do

#

that OnRep will fire after every individual per item callback

obsidian cargo
#

Does it need the const T& method signature?

#

I wasn't getting OnRep to fire yesterday when experimenting with fast arrays

winged badger
#

it doesn't

obsidian cargo
#

But I did have all the internal rep functions

#

I'll have to do more testing it seems

#

I want to understand the full lifecycle on these fast arrays

#

They seem very useful, but potentially just complicated enough to bite you.

winged badger
#

read the NetSerialization.h for start

#

i expanded on the concept

mighty garnet
#

does it explain this bit about container ownership because Im lost on that lol

winged badger
#

i am using network managers

obsidian cargo
#

Not really

winged badger
#

to replicate 2000+ interactable actors

#

with 4-16 managers

obsidian cargo
#

In my (dirty) test code I have this:

#
USTRUCT()
struct FExampleFastSerializedArray : public FFastArraySerializer
{
    GENERATED_BODY()
    UPROPERTY()
    TArray<FExampleSerializedItem> Items;    /** Step 3: You MUST have a TArray named Items of the struct you made in step 1. */

    AMultiplayerCharacter* Owner;
// SNIP```
#

Just above SNIP I have my owner reference

#

For production use, I intend to put an interface pointer instead

#

Or you can use a weak pointer

#

In my AMultiplayerCharacter's constructor:

#

Then in the optional replicate calls I did something like this to call out to the owner:

#
{
    InArraySerializer.Owner->OnReplicateRemove(/*Pass whatever details you need to the owner*/);
}
#

This is the replicate call on the individual item

#

You'll note the container comes in, which in turn has a reference to the owner

#

OnReplicateRemove is a function I defined on the owner in order to do game logic

mighty garnet
#

oh super helpful thanks -- what's the purpose of using Owner rather than just defining OnReplicateRemove inside FExampleSerializedItem?

obsidian cargo
#

It's to make it easier to pass game logic outside the array

#

As it stands, the OnReplicateRemove is only going to know what FExampleSerializedItem knows

#

Which is perfectly fine for a lot of uses

#

But if you need to modify something like UI based on the changes to the element, it can be helpful to chain the event to your actor

mighty garnet
#

ok so your character here will have some context that the item doesn't, right...

obsidian cargo
#

In your case, your FExampleSerializedItem will probably know about your level placed actors, so you might not benefit from the owner pointer

#

Exactly

mighty garnet
#

Ok and last question, just so I can argue intelligently with my coworker -- what's the benefit of this approach over the default actor property replication in my case?

#

I understand it will be more efficient but exactly how or why?

obsidian cargo
#

I'm still learning how this works

#

But for me, the advantage of FastArray is that it is easier to tell an item has been added, removed, or changed

#

Applying UPROPERTY(Replicates) directly to a TArray gives you a copy of the array prior to the change

#

It is up to you to determine in what ways the array has changed

mighty garnet
#

right that makes sense

#

and what about just checking Replicates on the actor, so my actors will just have their visibility and collision automatically synced to the clients?

#

that's easiest implementation-wise but I assume much less performant

#

I don't know enough about the replication graph to say why

obsidian cargo
#

I'm no where near the experience level to speak on topics of performance

#

I've been learning about replication for about 2 or 3 days at this point

mighty garnet
#

Ok well that makes two of us haha

obsidian cargo
#

(UE4 replication that is, I know a great deal about serialization as a general topic)

obsidian cargo
#

In matters of optimization, I generally end up implementing multiple approaches and measuring to see which is better

mighty garnet
#

yeah good call

#

in this case I feel like it might be knowable beforehand whether or not the vanilla replication system will be efficient or not, but maybe I'll just have to try it and see what happens

slim matrix
#

dose UE replicate linetraces to all clients when fired on the server cuz if i do a raycast on the server everyone sees it

obsidian cargo
slim matrix
#

im only firing it from the server

#

also if i have a print string after they raycast it also says its from the server

#

seems clients only see the debuig line any of the code that the linetraces dose is all running on the server

#

so clients only see the debug line

rancid flame
#

Does this make sense? This is inside an actor. "Remote" in this case would be when this code is executed on a client that does not own this actor, right? So wouldn't "Rotate Server" never execute?

sinful tree
meager spade
#

AMultiplayerCharacter* Owner; raw pointer? yuck

#

i use a TWeak in my FastArraySerializer to hold the onwer

pallid mesa
#

mhm

peak sentinel
#

Do you guys get those errors too?

peak sentinel
#

Location, Rotation and Velocity is replicated via OnRep inside the engine if you are replicating the actor and enabled bReplicateMovement on actor settings

#

So if there isn't anything intentional, you dont have to multicast

#

Server can just set the rotation

obsidian cargo
empty dove
#

How do I get all PlayerContoller on Client side? I want to know the location of other players on client side

empty dove
#

Ok. So I will have to get all the Pawns inside the level. Maybe by using the method UGamePlayStatics::GetAllActorsOfClass. Is there any other method, because in this method Client's own Pawn will be included in the list. I only want others locations.

obsidian cargo
#

It's tough for me to say what without knowing how often you need to know about the other players' pawns

#

You definitely don't want to overuse GetAllActorsOfClass

#

But I don't know if your design needs to worry about players leaving / joining

dark edge
#

Not sure on that tho. I know theres a replicated array of all PlayerStates but I don't know if that has the pawns.

short arrow
rancid flame
#

I'm having a tough time getting my brain around authority vs server vs client and what to check for this particular situation:
I have 2 players and they have laser particle systems.
I don't want to spawn the particle systems on the server (I can't anyway, particle systems don't work on servers).
When playing multiplayer I can use "Is Server" and if false, try to create the particle system.
But when playing standalone "Is Server" is returning true.
What should I be using?

peak sentinel
#

Because in standalone you are authority

rancid flame
peak sentinel
#

ShooterGame seems to be just spawning them normally. I'm not working with dedicated servers so I dont know what kind of checks you need to do during emitter spawning, but what they're doing on ShooterGame is they spawn an "ExplosionEffect" actor from server and during beginplay they spawn particles

#

Probably that dedicated server checks happening internally in the engine

#

You can check for GetNetMode() != NM_DedicatedServer

#

This will return true if you're only a client or listen server local player

twilit sequoia
meager spade
#

I mean particles wont spawn on DedicatedServer

#

but you can just check if (GetNetMode() != NM_DedicatedServer)

#

but SpawnEmitter does this check anyway ``` if (FApp::CanEverRender() && World && !World->IsNetMode(NM_DedicatedServer))

kindred widget
#

@rancid flame IsServer will return false in only one place, if you're a client connected to a server. IsServer returns true if called on an object on the machine of the Listenserver, DedicatedServer, or Standalone(Singleplayer).

Authority on the other hand can be true on clients. Authority is simply true of this actor was originally spawned on this machine. Clients return this true for locally created actors, and false for things that have been replicated to them. A Server should return this true for anything.

In most situations, you don't need to check for some things. "Most" code is meant to be portable for Listenserver and Dedicated server, so as to not cause specific coding for the two. Spawning Sounds, or Particles for instance should be able to be called on both. Most of these things have code that specifically checks if net mode is dedicated server to keep it from running. Kismet blueprint calls do this for most "cosmetic" effects like sounds and particles.

blazing spruce
#

Hi, are all these warnings normal when finding a session?

#

Has it got anything to do with the fact im still using the 480 app ID?

elfin sail
#

hi spawn an actor on server , but i cant see it on client

#

its replicates , always relevant , net load on client

pallid mesa
worldly escarp
elfin sail
#

I started server from bat file

elfin sail
#

just not showing the static meshes

worldly escarp
elfin sail
#

yes working now

#

need replicates all the child static meshes also

worldly escarp
#

๐Ÿ‘Œ

gray orchid
#

hay im new to multiplayer dose anyone know how to make a match making system like fortnite or splitgate?

bitter oriole
#

Use a matchmaking service, like Steam's, GOG's, EOS, your own

twin juniper
#

hey guys, i have a function that is running on server, at some point in the funcion i call a multicast for playing a montage. the montage does not play if im using a dedicated server

#

it play instead if i use listener servers

#

there is some weird checkbox somewhere in the character that does this? im asking because i recently found an enum under skeletal mesh-optimization that doesnt update bone positions if they are not rendered by the server

obsidian cargo
#

When using PIE it looks like all GEngine->AddOnScreenDebugMessage calls appear in all windows. I'm making that call inside if (GetLocalRole() == ROLE_Authority) and the message is also appearing on all my client windows. Is this a settings thing, or is there a different logging method I should be using for testing multiplayer?

rancid flame
#

Is there a standard way to get the index of a player connected to a server? I just want to know like, "this player joined first so they're 0, this player joined 2nd so they're 1"

violet sentinel
rancid flame
violet sentinel
#

if assume they join in sequence can look at their position in GameState::PlayersArray

#

and from player state get controller (owner)

rancid flame
#

ohhhhh that's way better than what I was going to do lol

violet sentinel
#

Game mode spawns bunch of system actors during init and sets them in game state
Game state has replicated array variable of system actors
On clients array often contains nulls for a long period of time since actors did not replicate yet
Currently looping the array in tick and until no nulls present i defer the game start but that sometimes takes several seconds
Is it possible to make sure that when game state replicates first time the system actors get replicated as well ?

#

there is FGlobalActorReplicationInfoMap::AddDependentActor but i assume it is only for RepGraph use

rose egret
#

@violet sentinel I guess there is something named UniqueId or PlayerId in PlayerState

violet sentinel
violet sentinel
#

maybe was too complex

#

i'm currently making own

violet sentinel
#

tldr: instead of engine comparing values you mark the property as dirty for it to replicate to client

#

in some cases saves time for rarely modified variables or arrays

#

?

#

all you can is mark, replication happen when engine decides

bitter oriole
#

Correct

violet sentinel
#

engine checks every NetUpdateInterval / NetUpdateFrequency

#

normal: always check, always send if modified
push: always check, send if marked as dirty

#

i think nowadays everyone is using fast, but it drives intellisense crazy

#

left one autocompletes fine

#

I have a map of key to value but only some values may replicate so i decided to try if this way would work

USTRUCT()
struct FMyActorRepData {
    UPROPERTY(NotReplicated) TMap<FName, Actor*>  AllTools;
    UPROPERTY(Replicated) TArray<Actor*> ReplicatedTools;
}
UCLASS()
class AMyActor {
    UPROPERTY(Replicated) FMyActorRepData Data;
}

do i need custom NetSerialize in this case? and would just writing array to archive suffice (array is set once on launch and does not change during game)

#

you need the bIsPushBased setting, and it present only when you set params

#

doesnt do anything

lost inlet
#

yes, you have to explicitly opt properties into push model

obsidian cargo
#

This push model is awesome! I'm so glad you were discussing this!

#

Is it "costly" to have a lot of actors marked with bReplicates = true, but no properties marked to replicate?

#

I'm looking at PushModel.h right now

#

There is some mention of Dormancy in PushModel.h as well

#

The descriptions in PushModel.h make it sound like the properties won't be replicated at all if you don't mark them as dirty

#

Which is exactly what you would want for properties that replicate very rarely. You want to notify when they are relevant.

#

But then it says ``` * Behind the scenes, Push Model does very simple book keeping, and will forward these dirty notifications on to the

  • networking systems as necessary. The next time an object is replicated, we can simply check a few flags to determine
  • whether or not a given property is dirty.``` So it sounds like the actors are still periodically checked.
#

I'd like to know this as well

#

I'm starting to replicate a destructible environment. Most of my replication will happen on level start, then most of the actors will be largely quiet in regards to replication.

#

Is Dormancy different than Push Model?

#

Again from PushModel.h: ``` * With Dormancy (see ActorChannel.h, NetDriver.h, NetConnection.h), we again go up a step and handle changes at the Actor

  • level. Devs can decide whether or not a given Actor supports Dormancy, and at what dormant level an actor starts at
  • (i.e., whether it's considered initially "active" in the game, or "inactive" in the game). When an Actor becomes Active
  • (woken from Dormancy), it will replicate one more time to all connections. After that happens, it will return to its
  • dormant state. Once Dormant, it is completely ignored by the networking system until Devs explicitly wake it via a call
  • to something like AActor::ForceNetUpdate.```
#

This sounds more similar to what @steep abyss is looking for, but I'm inexperienced on the matter of UE4 replication.

violet sentinel
#

read bottom of pushmodel docs

#

or top

obsidian cargo
#

Do actors attached to other actors share the same ActorChannel?

violet sentinel
#

don't think so

#

A channel for exchanging actor and its subobject's properties and RPCs.

chrome bay
#

yeah they don't, one channel per actor

obsidian cargo
#

Thanks! I tested some more and found I made some rookie mistakes on my transforms when spawning.

#

Looks like it is just fine to attach a replicating actor to a non-replicating actor

#

Obviously things could get weird if the non-replicating actor starts moving around

chrome bay
#

What you have to be careful about with dormancy is that when the actor "wakes" from dormancy, all of it's properties and sub-object properties will be sent even if they aren't dirty. Effectively it closes down the channel, and waking it treats it like it's a new actor

#

But it just links up to the original actor

obsidian cargo
#

Oh wow. That is quite expensive.

chrome bay
#

Yeah it can be, it's useful in a game like fortnite where you have thousands of replicated actors but most of them will never get an update (the trees/environement props etc.)

#

So they all start off as dormant, then when they change state that's when the engine makes a channel and starts replicating them

obsidian cargo
#

Can DOREPLIFETIME_WITH_PARAMS_FAST be applied to TArrays where you intend to mark the entire array dirty when you modify it?

#

I have an append only array that only gets read during OnRep

chrome bay
#

I think it should be fine

#

So long as you mark the array dirty, all the internal props will be compared

obsidian cargo
#

The PushModel example seemed to explicitly skip TArray

chrome bay
#

Ahhh maybe it does

obsidian cargo
#

I have a test project, I'll test in it before implementing with this assumption

chrome bay
#

But bear in mind push model is really only a CPU optimization

obsidian cargo
#

I was thinking, it would be nice to save the complete TArray compares since I will know precisely when every change will occur.

chrome bay
#

Doesn't really mean sending less data, just means potentially doing less comparisons

obsidian cargo
#

Exactly

#

I have a bunch of static terrain that will mostly not send anything

#

I don't want the server CPU analyzing stuff that doesn't have any players nearby.

chrome bay
#

It's worth nothing that Epic have even turned around and said they enabled it on fortnite, and they saw barely any real performance difference

obsidian cargo
#

I saw that note at the top of PushModel

#

It seems like since they did all the work, it is low hanging fruit for me

#

I'll try push model and re-evaluate IF practical application shows performance problems.

chrome bay
#

I can't see anything that prevents it working with TArray specifically

#

static arrays get special-case treatment because like USTRUCT members they are "unfolded" into the parent

violet sentinel
#

would this suffice for #multiplayer message fixed link

bool FDataCollection::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
{
    Ar << ReplicatedTools;
    bOutSuccess = true;
    return true;
}
chrome bay
#

Wouldn't work @violet sentinel if I understand correctly

#

You can't ever guarantee that one actor will arrive before the other

violet sentinel
#

i linked wrong question ๐Ÿ™‚

#

left first with just constant checks

chrome bay
#

yeah onrep I would suggest

#

And yeah you could do that but you wouldn't need to

#

RE the custom NetSerialize

#

USTRUCT() properties automatically are "replicated" so the "replicated" flag doesn't work inside USTRUCT

violet sentinel
#

so just marking extras with notreplicated is enought?

chrome bay
#

But TMap's can't replicate anyway (at least not via UPROP serialization)

#

So I don't think you need to mark it as not replicated

#

can't hurt though

obsidian cargo
#

What header do I need for DOREPLIFETIME_WITH_PARAMS_FAST?

chrome bay
#

"Net/UnrealNetwork.h"

obsidian cargo
#

Oh I have that one

chrome bay
#

Oh actually, might need PushModel.h now

#

#include "Net/Core/PushModel/PushModel.h

obsidian cargo
#

Does it require an additional module in build.cs?

violet sentinel
#

no, it is part of Core

chrome bay
#

I think you need NetCore in 4.27

obsidian cargo
#

#include "Net/Core/PushModel/PushModel.h

#

Looks like TArrays work with push model just fine

chrome bay
#

Ah good, I was just about to find out one way or the other anyway ๐Ÿ˜„

obsidian cargo
#

In my GetLifetimeReplicatedProps FDoRepLifetimeParams Params; Params.bIsPushBased = true; DOREPLIFETIME_WITH_PARAMS_FAST(AMultiplayerCharacter, LocationHistory, Params);

#

Header: UPROPERTY(VisibleAnywhere, Transient, ReplicatedUsing = OnRep_LocationHistory) TArray<FVector> LocationHistory;

violet sentinel
#

i used to have pushmodel in project, but with many people not following gudelines (not having setters that mark dirty and other things)
after having a hard time finding all missing marks just gave up and turned most of it off

obsidian cargo
#

I could see how it would be easily abused

#

In my one scenario, anything except an append to the array is invalid

#

So it makes sense to bury it and only have an append setter

#

In some of the tutorial content I saw "ReplicateUsing = OnRep_VariableName"

#

Isn't that redundant?

lost inlet
#

it's not hard to follow, the properties should be private, if they're exposed to BP then you can use Blueprint getters/setters

obsidian cargo
#

^

#

But sometimes the engineers (usually naรฏve jr) don't follow the rules

chrome bay
lost inlet
#

well you'd hope someone would be reviewing that code

obsidian cargo
chrome bay
#

Weird name for it tbh, not sure why they didn't call it "RepWithNotify" or something

meager spade
#

@chrome bay you do need to mark it notreplicated

chrome bay
#

The TMap?

meager spade
#

or it spits a warning (TMap)

chrome bay
#

Ahhh cool

meager spade
#

Zlo got angry with me cause i spammed his logs

#

cause of that

chrome bay
#

๐Ÿ˜„

grizzled flicker
#

so everyone says root motion is bad for multiplayer right? But if I take an in-place animation and make it into a montage and then because the feet move I need to add a keyframe + manually move the root isnt that the same as root motion? It seems to me that the best way would be to do an in-place animation but only make it for the upper-body slot and then keep the feet able to mvoe independently? Is this right or where am I wrong?

meager spade
#

RipWithNotify sounds much more like it does than ReplicatedUsing urgh

#

@grizzled flicker Rootmotion in montages is OK

#

but not in the animation bp.

#

i dont use root motion for TIP

#

i use a static one, and a curve

grizzled flicker
#

tip?

meager spade
#

turn in place

#

if you doing things like attackng with sword

grizzled flicker
#

ok i have nothing but root motion in my entire project but all i hear is how bad it is for multiplayer so...

#

ya i have this sword attack anim where the feet move forward so i figure ill just use root motion anim

meager spade
#

this depends, we normally play the animation in an upperbody slot so the feet keep moving, anyway this is not really multiplayer now so #animation we can continue

violet sentinel
chrome bay
#

TBF if I need a replicated world sub-system I just add a replicated component to world settings ๐Ÿ˜„

#

That was my OG subsystem method before actual world subsystems came along...

violet sentinel
#

yea, in my case i have to configure them per-level and per-gamemode and potentially save to savegame.

meager spade
#

i use actors..

#

they exist in world, easy to use

#

easy to serialize and reference and they replicate.

violet sentinel
#

yep, i use actors too now

#

before had just replicated uobjects

graceful flame
#

Is it possible to prevent cheaters from changing their FOV?

chrome bay
#

noop

#

utterly impossible

graceful flame
#

okay cool, good to know

dark edge
#

I had just put a component on game state

violet sentinel
#

you can add actor components onto it

#

AWorldSettings

sharp pilot
#

best multiplayer template?

violet sentinel
meager spade
#

fwiw, WorldSettings is also what particles attach to when you spawn them at location ๐Ÿ™‚

dark edge
#

I've been messing with UE4 since 2014 and this is the first I've heard of WorldSettings lmao

#

So what's the difference between it and GameState?

lost inlet
#

uh, a lot?

#

it's more where you can set level specific settings

#

the only similarity is that it's also instantiated as a replicated actor

elder sage
#

Can someone help me reduce some of these racing errors I'm getting? Player character can't read player state on spawn etc.

sour dew
#

How tf do i do multiple player

elder sage
lost inlet
#

Also wtf is that avatar

elder sage
#

Porn = funny I guess

sour dew
nimble parcelBOT
#

:triangular_flag_on_post: โ€ข_โ€ขpen15#3148 received strike 1. As a result, they were muted for 10 minutes.

empty dove
#

I am designing a pickup actor.
It's OnBeginOverlap is called on both Client and Server. How to design it so that it is called only on server? Because, in OnBeginOverlap, I destroy the actor. I don't want that to be out of sync

peak sentinel
#

Just check for authority

clever plinth
empty dove
peak sentinel
#

If server destroys something it should be destroyed on everyone

#

Ensure actor(s) are replicated

spring vortex
#

Anyone have any idea how I can solve this? Sometimes it does actually fire the sphere trace but less than half the time. I'm using a proximity spawner to spawn the AI. It always does damage to the server but only sometimes on the client. I've even changed it to ensure that the server is calling the spawn no matter who triggers it, but the issue persists. No owning connection for actor AI_Female_C_0. Function AttackMontage will not be processed. The montage always plays, but I'm using an anim notify to call the function from the anim graph to the pawn

meager spade
#

you can not send server/client rpcs from an actor not owned by the player.

spring vortex
#

Then how does one have the AI deal damage consistently in multiplayer? Are rep notifies out of the question?

spring vortex
clever plinth
#

Is there an option to have a dedicated server run inline in the current console window? Basically I want it to print in the powershell window I launch if from instead of being headless, or printing in another window. Basically the equivalent of UnrealEd-cmd.exe as compared to UnrealEd.exe. Maybe I have to create another target for it to make something like UnrealEd-cmd?

sinful tree
empty dove
#
    {
        OnActorBeginOverlap.AddDynamic(this, &ADamageChanger::OnBeginOverlap);
    }```
I have this code in BeginPlay, so that OnBeginOverlap is called only on Server, but still it gets called on Both Client and Server.
somber glade
#

if I make a change to the character movement , like changing the mode from X to None, if that is done on the server is that replicated by default, or should I also set that on the owning client?

meager spade
#

think you need to set it on Owning Client and Server

#

but not simulated

#

at least that is what i do..

somber glade
#

okay that's what I'll try then.

#

Thanks

chrome bay
# dark edge So what's the difference between it and GameState?

AWorldSettings - it's the actor that holds all the info when you open the "World Settings" dialog for that level. You can use your own world settings class globally for the project, the nice thing about it is it's guaranteed to always exist - but tbh GameState probably is a better choice, get a bit more control over per-level stuff then

#

It's useful if you want to attach some kind of meta-data to a world though too

shy solstice
#

Hi. WHY WHY WHY?!
I've checked everything in logs and with Network Profiler. My project consumes low amount of bandwith and has only few replicated actors/variables.
And yet, despite of having NetUpdateFrequency=60 and FixedFrameRate=60 server DOESN'T send actors for replication every frame. (checked through NetworkProfiler, simulation and real network test)

chrome bay
#

Well it doesn't send anything unless it actually needs to be sent, i.e. changes have been made

#

NetUpdateFrequency is how often the actor is considered for replication

#

i.e. the maximum rate at which the server will compare it's properties

shy solstice
#

But i've created Array, where every frame I increase Integer (Get 0), the rest of array elements, true, varies from time to time.

chrome bay
#

Get 0 in Blueprint returns a copy

#

It doesn't modify the original array

#

(unless you change it to get a reference, and modify that reference)

#

The Array and actor also need to be marked as replicated ofc

shy solstice
#

No no no, Replicated Array. I change it's first element every frame (Clear Array every frame --> add elements to array )

#

And still it doesn't send it every frame

chrome bay
#

If you're adding the same elements, then nothing will be sent

#

Show what you've done will be easier to see

shy solstice
#

Jesues, not the same

#

I increase integer, like i said

violet sentinel
#

show code (tm)

chrome bay
#

^

shy solstice
#

So variable changes its value every frame. Yet networking mechanism doesnt consider it for replication every frame

chrome bay
#

post code

shy solstice
violet sentinel
#

where from is it being called from?

shy solstice
#

EVENT TICK

chrome bay
#

Are you sure the actor is network relevant?

violet sentinel
#

do you check HasAuthority ?

chrome bay
#

^ that too

shy solstice
#

yes

#

trust me, everything is perfect

chrome bay
#

It can't be because otherwise it would work

#

I'd start by printing the value of the int to be sure it's incrementing, and also ensure the actor is network relevant

shy solstice
#

Isn't there some Unreal engine ompitimzing mumbo jumbo which blocks replication every frame?

chrome bay
#

nope

violet sentinel
#

there is not much guarantee variable will get send in same exact frame but only on next when engine runs replication

#

you technically can forcenetupdate but that is woodoo

chrome bay
#

In editor you can pretty much garauntee it will send same frame

#

And you are running an actual server + client instance in PIE to test with?

#

I.e. not playing in standalone or just with a listen server and 1 player?

shy solstice
#

Simulation, listen server + some clients. But I've made real network tests with network profiler. And in NP logs it looks like it send variables every two frames instead of every frame.

chrome bay
#

So it is sending something then?

#

Original post made me think it wasn't sending anything at all

#

Bump NetUpdateFrequency and MinNetUpdateFrequency to something higher than 60

#

Should guarantee it's being checked every frame

#

but bear in mind there's zero guarantee you'll get 60 updates a second outside of editor, due to real-world internet connections

#

So building anything dependant on that is a failed venture

shy solstice
#

4 frames from Network Profiles. Look at BallKurla

#

nuts

chrome bay
#

See above

shy solstice
#

i saw

#

128 + 52 bytes small amount i believe. On n+1 and n+2 frame it doesnt send BallKurla at all, even tough this Array which i was mentioning is placed in BallKurla.

#

Why TF at one frame server decided to not replicate anything?

chrome bay
#

What engine version are you on?

shy solstice
#

4.25.4

chrome bay
#

It says that BallKurla is taking up 7.5Kbp/s

shy solstice
#

Or maybe it behaves like this when it comes to Arrays?

chrome bay
#

A couple of other items and that would exceed the 10Kbps default saturation limit

#

So the engine will consider a connection saturated and not send anything more

shy solstice
#

๐Ÿค”

chrome bay
#

IIRC Epic bumped the defaults to 100 in 4.26 or 4.27, unsure which exactly

#

Try adding this in DefaultEngine

MaxClientRate=100000
MaxInternetClientRate=100000```
#

Default is 10000 IIRC

shy solstice
#

ok, thanks, thats some clue

chrome bay
#

Otherwise I imagine it might be some kind of precision issue with the frame rate and networking timings

#

If they're both dead-on 60 or they go even slightly one way or the other it might throw it off

shy solstice
#

But, how this makes sense? I have average internet speed. My outgoing speed is 31ย 250 bytes PER ONE FRAME!

#

So why this limit of 10 000 bytes per second?

chrome bay
#

For one frame that seems insanely high

#

The 10,000 limit is per-second not per frame

shy solstice
#

15 Mbps = 15 000 000 bits per second = 1 875 000 bytes per second = 31ย 250 bytes per frame

#

am i right?

chrome bay
#

Your real network connection doesn't matter in editor

#

I thought you meant 31 250 bytes per frame was what the network profile was saying

shy solstice
#

O,l but what is the reasoining behind having this MaxClientRate=100000 limit?

chrome bay
#

To not hammer bandwidth

#

It's a soft-cap on how much data to send a second

#

When the game tries to send more than that, the connection is "saturated" and so things will be sent less often

#

It's a "target" rate essentially

shy solstice
#

But why this default value is absurdly small, like 10 000 bytes, right?

chrome bay
#

10Kbp/s yeah

#

For reference, Unreal Tournament uses a value of 30Kbp/s

shy solstice
#

ok, thanks for some teaching ๐Ÿ˜‰

chrome bay
#

Epic bumped the default values to 100Kbps in 4.26/4.27, presumably because Fortnite - but realistically you probably don't want to be anywhere near that limit

shy solstice
#

[/Script/OnlineSubsystemUtils.IpNetDriver]
MaxClientRate=100000
MaxInternetClientRate=100000

this goes to some ENGINE folder right?

chrome bay
#

I'd start bumping that just to check if it is the saturation, but otherwise I suspect it might be a timing precision issue

#

DefaultEngine.ini

shy solstice
#

but engine or project folder?

chrome bay
#

project in Config

shy solstice
#

ok

shy solstice
#

@chrome bay I've managed to get replication every two frames, but no chance to replicate every frame ๐Ÿ™‚

#

but in real network we made tests with 4 people and every actor got replicated every two frame

#

so thats nice

#

but why every two frames and not every each frame, I have no clue

#

after changes

#

before changes

violet sentinel
#

expecting value to be replicated every frame is kind of weird, usually interpolate between received from server values (if it is movement data)

shy solstice
#

I know

#

but 1. im curious, 2. I use counter to synchronize gameplay, so for test purposes i want sometimes to make ONE-TO-ONE replication

bitter oriole
#

You cannot expect every variable change to replicate

shy solstice
#

I replicate array, where first item is counter which changes every tick. Game is fixed 60 frames. @bitter oriole

#

why i cannot try to rpelicate it every frame?

#

even for test purposes

#

๐Ÿค”

bitter oriole
#

Because it's nonsensical : 60fps means an update every 17ms, when networks commonly have 50ms of ping time if not 4x that. If you succeed, you will be receiving groups of 4-5 updates in the same frame, and then nothing for 4-5 more frames

violet sentinel
#

game and render work in separate threads also

shy solstice
#

my outgoing internet provider speed is 15 Mbps = 15 000 000 bits per second = 1 875 000 bytes per second = 31ย 250 bytes per frame

#

one float is 4 bytes

bitter oriole
#

It also doesn't work like that

shy solstice
#

๐Ÿค”

bitter oriole
#

A larger problem is that forcing replication to be reliable, if possible, would mean a 2s drop of connectivity (completely routine stuff) would give you a backlog of 120 packets to resend in loop

#

Which in turn would kill your connectivity for seconds

shy solstice
#

HOLD ON

bitter oriole
#

This is why replication works like that

shy solstice
#

I create a project, where i only try to rpelicate one fck INTEGER - 4 bytes

#

ON VARIABLE

#

should it be possible to replicate it every frame? 60 times per second?

#

OR NOT?

#

IN UNRFEAL ENGINE 4

bitter oriole
#

Not reliably

shy solstice
#

๐Ÿค”

bitter oriole
#

In any engine

violet sentinel
#

replication - no, direct write to network socket - maybe yes

bitter oriole
#

Maybe yes with massive caveats

#

The main one is as follow : lag time is variable

#

So say you have 60fps network updates - what happens if lag goes from 50 to 100ms for a fraction of a second because your sister logged into Animal Crossing ?

#

The other side then gets zero update for 4 frames (50ms / 16.7)

#

And then the next frame gets 5 frames (4 + the latest one)

#

4 of these frames are pointless

#

They contain intermediary values of a variable

shy solstice
#

It's all fun and games but you know what @bitter oriole ? While simulating in PIE it also rpleicated every two frames!

bitter oriole
#

Yes

shy solstice
#

So something is blocking

#

some UE4 code

bitter oriole
#

Try it on loopback too for fun and giggles

shy solstice
#

you know where it is?

bitter oriole
#

What I'm telling you is this : from the engine to the operating system to the net hardware to the actual network - nothing is designed for that

shy solstice
#

Ok, but it seems tah Net Update Freguency is bull shit

#

right?

bitter oriole
#

The update frequency doesn't magically make networking do things it cannot

shy solstice
#

but it seems that the max value is 30 !!!

bitter oriole
#

You can't update at 130fps for obvious reasons (the game runs at 60 from your own words)

shy solstice
#

No matter what, i cannot realisticly make it 30+ (net update frequency)

#

sorry, i remmeber- sometimes for a few frames i got replication every frame

bitter oriole
#

I literally told you about it

#

This is how networks work

shy solstice
#

real networks

#

now im talkkiing about simulating it on PIE (2-4 windows)

bitter oriole
#

Bold of you to assume PIE doesn't go through the OS net stack

shy solstice
#

๐Ÿค”

maiden ermine
#

Hey all - Playing in PIE from the editor, I've got a working standalone<->dedicated server setup if I run with the server as a separate process. I can travel to the server using the url "127.0.0.1:17777".
My problem is that I would like to also be able to run with the dedicated server in-process. However, when I try to travel to the server using the same address, it doesn't work.
Anyone know how I can successfully do this?
Note that I'm running the client as Standalone, because when I run it as Client - it automatically connects to the server and I do not want that.

bitter oriole
#

I'd also suggest doing all your work with say 100 ping, 1% packet loss, and packet reordering

#

There's no point trying to write MP code in good conditions

#

Good conditions don't exist even on a LAN net

#

See how real networks behave and write your code around that

shy solstice
#

I did some hardcore simulation, no worries

#

just i wanted to dissect my network code starting from the base - 60 FRAMES AND REPLICATIONS PER SECOND

#

๐Ÿ˜ญ

bitter oriole
#

Now that we're good on the fact that you'll never get one replication update per frame on client, just check out NetServerMaxTickRate

#

You'll be able to send on average (over say 10s) your 60fps updates

#

Of course that will be 10 updates in some frames and 0 for most of them

#

But you are happy with that

shy solstice
#

i dont use C++, will I be able to change it through ini file?

bitter oriole
#

This is an ini thing

shy solstice
#

ok...

bitter oriole
#

[/Script/OnlineSubsystemUtils.IpNetDriver]
NetServerMaxTickRate=60

#

DefaultEngine.ini

shy solstice
#

thanks

chrome bay
#

Ultimately as I said before any system built on top of reliable property updates at a fixed rate will fall apart. The UE4 docs specifically state that variable replication is lossy, and that is to some extent by design.

#

You may be able to get it to function in editor because there is no real-world connection - but it's a guaranteed failure outside of that very controlled environment.

#

Why in this particular instance it's not sending a prop update per frame IDK, but in practice, it doesn't matter anyway

bitter oriole
#

Unreal gives you a really powerful model with two simple mechanisms - replication for persistent game state, where intermediary values do not matter but getting the data when you join the game does, and RPCs, where every single call can be made reliable if an event is truly required, but only communicated to current clients

#

So if you need to positively send every single step change of a counter (which IMHO is wrong but okay) you'll make it a reliable RPC and watch your game stutter to hell

shy solstice
#

i know reality of using rpc

#

bad bad RPC, killer reliability

bitter oriole
#

But somehow you're trying to turn replication into RPCs ๐Ÿ˜†

shy solstice
#

@bitter oriole @chrome bay Thanks guys! Players of my game will be eternally greatfull. Good knowledge i gained today

charred pebble
#

I think multiplayer is the correct place to post this, and not in the sub system area.

Is it possible to host a session from a trigger box with steam/advanced sessions?
Canโ€™t seem to get the overlap to trigger hosting, but single player travels fine from another trigger box
I can confirm server traveling from pc based widget works fine, but want it as a overlap instead

limber gyro
charred pebble
pure vigil
#

Replicated actor spawned on a server with some (replicated) exposed on spawn properties. The values don't exist for the clients in the construction script. Is that just how it is or can it be tweaked?

kindred widget
#

Construction script is just an earlier beginplay as far as networking is concerned. You should never rely on replication in any events besides OnReps.

cinder tartan
#

how simple is implementation of networking with ue4? as in should i design with networking in mind or am i safe to create an offline preoject and implement networking later on

sinful tree
#

You'll want to build with multiplayer in mind.

pure vigil
#

bleh, ok. thought having it be exposed on spawn would guarantee the value would be set when the actor spawns clientside

lost inlet
#

it's relatively simple, but doing the latter thing is dumb

cinder tartan
#

thanks, will save me time later

kindred widget
#

If you build it correctly, you can network a singleplayer game incredibly fast later on. But building it correctly requires knowing the general ins and outs of UE4 networking. Without that foundation, it's likely better just to start learning that and implementing it now.

cinder tartan
kindred widget
#

Specially since that implementation will also help you learn UE4's architecture much better even for a singleplayer standpoint, I feel.

#

It's more about class interaction. Knowing what exists where, when, and why.

lost inlet
#

a multiplayer game played offline will just work in most cases, but far from true the other way round

cinder tartan
#

i've seen seems to mostly cover blue prints and how to use it rather then why

#

while how is standard in api's the why is kinda important if dealing with c++ i feel

#

otherwise ill go over some linked in videos in my spare time before i get started

kindred widget
#

I would start with Cedric's guide. Second pinned link in here I think.

cinder tartan
#

thats appreciated

#

ill read through that before i do up my uml diagrams

kindred widget
#

The general basics you're going to want to focus on is RPC and Replication, how they're different and how they work. Get an idea of the basic classes like GameMode, GameState, PlayerState, PlayerController, HUD, PlayerPawn/Character.

limber gyro
#

have u checked the logs to see whats going on?

cinder tartan
kindred widget
#

Replication is simple. You set values on the server, they are replicated to clients based on their conditions and may run a function after being set on clients called an OnRep.

cinder tartan
pure vigil
#

Random question about something I may have noticed but not 100% certain. In C++, it seemed like repnotifies ran on the server as well as clients but in BP repnotifies just run on the client. Am I crazy?

kindred widget
#

If you want the client to set the value, yes.

charred pebble
cinder tartan
charred pebble
#

Canโ€™t believe overlap > host isnโ€™t working, this should be simple connect cast and go

limber gyro
pure vigil
#

"instiations"?

charred pebble
#

It is

#

I can travel in editor

#

Just not in shipping

limber gyro
#

have u confirmed that the sessions is being created?

cinder tartan
# pure vigil "instiations"?

sorry used to unity terminology, essentially creating a new instance of an object/playerobject e.g. spawning a tree within a game via script

charred pebble
cinder tartan
#

i would essentially check a flag on client side then server would create object then replicate to connected clients right? or is there more involved

limber gyro
#

even in shiping u should have a debbug log

charred pebble
#

Maybe itโ€™s being over rid due to pc widget, doing this for vr

pure vigil
cinder tartan
#

or would replication create it on serverside and automatically send to connected clients

charred pebble
#

But have it setup for pc cross compatibility

kindred widget
#

Instances. But essentially, sure. It depends on the use case. If this is like.. Survival game, Client placing down a wall or floor tile, yeah. They would RPC their desire to the server, server would run checks, then do whatever it needed to do, which would ultimately replicate to all clients for the new state.

pure vigil
cinder tartan
charred pebble
#

So I know my adv ss isnโ€™t bonked

kindred widget
#

Nothing replicates from Client. Replicated objects need to be created explicitly on the Server.

pure vigil
#

If you try to replicate something from the client, nothing happens. RPC = Client talk to server. Replicate = Server talk to client(s)

kindred widget
#

In fact. As far as Networking goes. There's one simple rule for Clients. They can't do ANYTHING networking wise, except to RPC to server.

cinder tartan
limber gyro
pure vigil
cinder tartan
#

thanks think you guys have cleared up everything for me just about

kindred widget
#

It's automatic, assuming the actor is set to replicate, and the server thinks that it is relevant to the client.

pure vigil
#

But if you wanted to implement a chat system, client sends RPC to the server, server then tells clients to run a function to handle the message. See "multicast"

cinder tartan
#

thanks

kindred widget
#

Are you using C++ as well?

pure vigil
#

I especially love this diagram to remind me what exists on the clients, server and what is shared

cinder tartan
#

although will admit the ue4 api makes it almost like c# in terms of syntax

#

in comparison to raw c or c++

kindred widget
#

Haha. Unreal's wrapped C++ is stupid easy to learn.

pure vigil
#

its weird at first, for sure

cinder tartan
#

it really is haha i just wish there api documentation was a little more focused on the c++ side rather then the blueprint side

pure vigil
#

but then its easy

charred pebble
limber gyro
#

its inside a folder somewhere

charred pebble
#

Working on packaging, working with a potato

limber gyro
#

its not hard to find

kindred widget
#

But couple major notes. First, C++ OnReps are not automatically called on server. You need to explicitly call these on server if you want them to run there after setting a value. In Blueprints, these automatically run on server.

#

Check out the differences between NetMode, and NetRole. These will save you a lot of headache with guiding logic.

#

Learn FastArrays. They're cumbersome, and they have some minor drawbacks, but for some implementations, they are downright invaluable.

#

This isn't exactly multiplayer related, but I don't know how data is handled in Unity, but I would strongly recommend getting a grasp on GameplayTags. FGameplayTag. For sorting game logic, and keeping data separated well, these are also very invaluable.

cinder tartan
kindred widget
#

Normal Unreal TArray will replicate all changes in the array. So.. You have 20 items. You remove index 7. Index 8-19 shift down to 7-18. These have all changed, and will ALL replicate. With FastArrays, you can remove specific items without that issue. But more importantly, you get per item callbacks when the struct arrives on client, before the struct is removed from the client, and after adding on the server.

cinder tartan
kindred widget
#

Unsure what you mean with Map? If you mean TMap, those aren't replicated. Can't network them.

cinder tartan
#

looking at the syntax kinda looks like they tried to replicate c# but slightly changed things

kindred widget
#

Get very used to working with Structs. ๐Ÿ˜„

cinder tartan
#

looking at structs seems like there the equivelant of a c# model class when working in oop

#

basically just there to hold variables of that instance of the class?

kindred widget
#

Mostly. Though you can also add functions to them, both normal and static that can be used to handle the data on them.

cinder tartan
#

@kindred widget think you've given me all the info i need to convert my projects thanks heaps man!

kindred widget
#

@cinder tartan Oh. Speaking of C++. You ran into the UPROPERTY rules yet?

cinder tartan
kindred widget
#

Mostly simple. Most variables declared in headers should be UPROPERTY() marked. Specially pointers.

cinder tartan
kindred widget
#

I pretty much mark everything out of habit and because it's usually blueprint exposed. But pointers specially even in C++ alone need to be marked because if they're not, the things they're pointing to can be garbage collected.

#

Even if you don't mind that, it's still generally good practice to use a weak pointer than an unmarked one.

cinder tartan
#

yeah ill be sure to look into that a little bit more been using high level languages so much lately almost forgot garbage collection was a huge part with c++ lol

dark edge
kindred widget
#

They are. Both in personal projects and at work I use them pretty much everywhere. They make fantastic data sorting tools for datatables and such.

meager spade
#

They were never part of GAS

#

always had there own module, infact epic was going to make them part of the AActor by default

#

but they never did ๐Ÿคท

terse prawn
#

Is there a way out of the box to replicate a variable between a single client and the server, or would I need to setup my own requests and updates?

twin juniper
#

does anybody know if replication of data assets declared inside structs its bugged?

terse prawn
rough kestrel
#

hey anybody here has used photon? I was going throught the docs and couod not find anything on if a dedicated server build is needed. How wouod it be able to check for ohysics relwted stuff if there is no dedicated server stuff from the engine?

unreal gate
#

Trying to build my code but i'm getting this. Anyone experienced the same?

silent valley
#

Set your startup project to be your project in visual studio

ashen mica
#

What would I have to put down to open a port so my friends can join my game ?

#

I know I put my pc address for then local ip

#

So it's all 7777?

still owl
#

Hello! Does anybody have any insight on how to mitigate these client corrections? In my actual project im getting corrections when the client collides with moving AI with latency which feels terrible and i'm looking to reduce it or atleast mask it. I've setup an example of the problem below.

The Setup

  • ThirdPersonTemplate Example
  • AI that moves around randomly
  • Client on 100ms ping

The Problem

  • Huge amounts of corrections when colliding with the AI
#

It seems adding these to the DefaultGame.Ini solves the problem but im not sure about the consequences of doing this, or if its the recommended way to solve this issue?

unkempt tiger
#

Without reading on it, I expect that that max position error is what the CMC will use to determine when to correct client positions upon an incoming server state containing the 'real' client position, however if client authority is true then it becomes meaningless what the number is set to

#

The larger it is, the bigger the potential desync can be

#

Keep in mind that - at least with the set of solutions I'm aware of - solving the problem of client corrections when running into moving server auth entities (which are not predicted) is virtually impossible in bad enough network circumstances

still owl
#

solving the problem of client corrections when running into moving server auth entities (which are not predicted)

Im going to assume that AI Movement cannot be predicted since they only exist on the server or is this a possibility?

unkempt tiger
#

If the AI is somehow deterministic, then on paper it is a possibility

#

however I bet the reality of it is that that case is not taken care of, and will require you to put in time into making it so

#

which can be a terrible experience

still owl
#

Yup Agreed. For now increasing the correction range seems okay. My project is a simple coop game so it doesn't have to be SUPER precise. It seems corrections still apply if the current client position compared to the last server position is > MAXPOSITIONERRORSQUARED which should correct major desyncs (hopefully).

unkempt tiger
#

yeah, it should

#

as long as you dont need precise client locations, then that transforms the problem from feeling bad every step you take, to feeling bad every 10 or so steps you take, when running into that AI

still owl
#

Yeah exactly, which is better for sure.

#

How common is it to have to use these .ini lines to solve issues like this? I would have though increasing the correction radius would be a easily visible setting in the CMC somewhere

unkempt tiger
#

editing config to get the engine to match your needs is common, its another tool in your arsenal

still owl
#

๐Ÿ‘ Ty. Makes sense

unkempt tiger
#

Any good places to bind to the UReplicationDriver::CreateReplicationDriverDelegate() delegate? GameMode::BeginPlay feels a bit wonky (and I'll be surprised if it works)

winged badger
#

InitGameState

#

that is first easily overrideable function called on opening a new level

unkempt tiger
#

Thanks ๐Ÿ˜

eager jolt
#

which ports do UE4 use?

bitter oriole
#

Shouldn't matter much because of nat punch

#

7777 IIRC

eager jolt
#

tah

#

should ue4 be tcp or udp for portforwarding?

bitter oriole
#

UDP

#

But again, you don't need that

eager jolt
#

how do i portforward then

bitter oriole
#

You don't

#

No game should be coming out in 2021 with ports to open

#

That shit is 2000s stuff

#

In modern times you use NAT punch instead - the engine does it out of the box on Steam (well Steam does really)

eager jolt
#

thx ill research it

#

ive used hamachi to NAT punch (based off what the wikipedia definition is) but it limits me to 5 clients, any recommendations to get this higher?

bitter oriole
#

Hamachi is not NAT punch

#

Just use the Steam online subsystem and enjoy no ports issues

#

Or use your own service and implement natpunch yourself

eager jolt
#

is the steam online subsystem free for access?

bitter oriole
#

"test" as in "it will work perfectly well and no one will care until you ask money for it"

#

i think the game name filters ?

eager jolt
#

is space war perfectly legal?

#

ok

#

what alternatives are there?

#

what can i use as an alternative to hamachi

eager jolt
#

i mean legally

meager spade
#

SpaceWar is for testing purposes only

#

you may not release a game using the spacewar app id.

eager jolt
#

ok thx

#

do you have any suggestions for alternatives @meager spade ?

meager spade
#

you can use EOS, or purchase steam app id for $100 as mentioned above.

#

or setup your own system (which is a big task)

eager jolt
#

eos?

kindred widget
#

Epic Online Services.

eager jolt
#

is that difficult to use?

kindred widget
#

Probably barely different than Steam.

#

No personal experience with it.

eager jolt
#

is it free?

kindred widget
#

Dunno. Most likely.

eager jolt
#

apparently its free

bitter oriole
#

It is

#

Dunno if the engine does NAT punch with it but probably

floral mantle
#
    AActor* Owner = GetOwner();
    if (ensure(Owner))
    {
        UInputComponent* PlayerInputC = Owner->InputComponent;
        if (ensure(PlayerInputC))
        {
            // ensure condition always failes on client
        }
    }```
In that code (on actor component), the second ensure condition always failes on the client. It only works on the server. What am I doing wrong? 
And under there I am trying to execute a Server RPC and I get some weird error: 
```LogNet: Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor BP_PlayerCharacter_C_1. Function Server_SpawnWeapons will not be processed.```
sinful tree
#

That error usually indicates that the actor isn't owned by a player and thus the RPC can't be invoked.
Is this perhaps a copy of the character you've placed in the level?

floral mantle
#

I also found out that when I play with 2 players, I get 2 characters but only 1 controller spawned

#

When I run GetOwner() on the second character I get a nullptr

sinful tree
#

Well that would do it. No owner = no RPC. How are you spawning the characters?

floral mantle
sinful tree
#

Are you by chance running your Server_SpawnWeapons on Begin Play? If not, what Event triggers the call to Server_SpawnWeapons?

floral mantle
sinful tree
#

So directly from Begin Play of the Character -> Set Timer By Event -> Timer Goes Off -> Triggers Server_SpawnWeapons? No authority check?

floral mantle
#

yes

polar lotus
#

What's the safest way to authoritatively disable a player's input

winged badger
#

if you want it hack proof, unpossess its pawn

polar lotus
#

I feel like AActor::DisableInput is easy to cheese since it's client sided

polar lotus
winged badger
#

i think so, everything else is kinda client side

polar lotus
#

I only want it to suspend input for like 2 seconds or so

sinful tree
# floral mantle yes

Begin Play fires on both clients and the servers.
So when Player 1 spawns on the server, the server will call all of that.
When Player 1 spawns on Client 1, it will also call all of that.
When Player 2 spawns on the server, the server will call all of that.
When Player 2 spawns on Client 1, it will also call all of that.
When Player 2 spawns on Client 2, it will also call all of that.
When Player 1 spawns on Client 2, it will also call all of that.

See the problem? Begin Play can be a bad place to initialize things in multiplayer, especially with player characters that aren't always relevant as it can also fire multiple times on clients as the actor's relevancy changes.

The crux of the issue is that you're using Begin Play without an authority check, and you should probably be spawning the weapons server side anyway without requiring the client RPC asking for the weapons to spawn.

So it should go something along the lines of:
Begin Play > Has Authority (Authority Path) > Spawn Weapons

polar lotus
#

I'm pretty sure unpossessing a pawn would break a lot of my code

#

but only one way to find out I guess

winged badger
#

unless its competitive pvp

#

i would not go that far

polar lotus
#

If I unpossess a pawn, It's still connected to the APlayerState right?

winged badger
#

not by the engine

polar lotus
#

ok

floral mantle
sinful tree
floral mantle
#

ok, thanks

green veldt
#

Hi, quick question. I'm trying to send an actor and an object from a client to the server. The actor works fine, the object just doesn't arrive. Is there a difference on how they work or am I doing something obvious wrong?

queen mortar
#

Hey I have a question, I'm trying to create a multiplayer lobby but I'm having this problem when a host leaves lobby players will leave too and get back to menu but it's now working how it should because when they try to create new session or join other lobby they just can't. Any idea on how to fix it?

#

Here's my code when player returns to menu from game

green veldt
#

Just a basic object with some variables to store whatever I picked up. If that's the question... I don't know terminology tbh, I just use words.

lost inlet
#

so did you implement subobject replication for it then?

green veldt
#

I don't know what that is, so probably not. How would I do that?