#multiplayer

1 messages ยท Page 689 of 1

grand kestrel
#

If it never changes then that would be best

#

If it does, you'll need to ping an RPC back and forth without sending anything after the first OnRep IMO, when the client gets the RPC back that array would likely be filled

#

You could also check !bHasBegunPlay to use RPC method assuming it's false during first OnRep (which would imply it should be populated in BeginPlay, which may not be the case)

jolly siren
#

I can just update the array on the client and server in the characters beginplay and endplay

#

I had a bigger issue though, my character wasn't relevant. So had to flip always relevant on

twin juniper
#

PostNetReceive is called only on the initial bunch ?

#

looks like it's called in PostReceivedBunch so i guess i have my answer.

deep shore
#

hello, everybody. If I simulate two clients in the editor, their movement appears perfectly smooth. If I spawn a spectator class that can move around freely, everything looks great, as well. If I set a view target so one client may spectate anotherโ€™s camera, there is terrible jitter for the spectator that doesnโ€™t exist for the client thatโ€™s actually playing. thereโ€™s no jitter to the camera, just the animations. any ideas on where to start looking to troubleshoot this? thanks in advance ๐Ÿ˜„

grand kestrel
twin juniper
grand kestrel
#

Example use case from my plugin

void AMICharacter::PreNetReceive()
{
    Super::PreNetReceive();

    if (GetLocalRole() == ROLE_SimulatedProxy)
    {
        bWasSimulatingPivot = bSimulatedPivot;
    }
    SavedRagdollActorLocation = RagdollActorLocation;
}

void AMICharacter::PostNetReceive()
{
    Super::PostNetReceive();

    // Received ragdoll update
    if (SavedRagdollActorLocation != RagdollActorLocation)
    {
        UpdateRagdoll();
    }
}
#

I've seen Epic use it FWIW @twin juniper

#

In UT, ages ago, it's where I learned about it

twin juniper
pearl fog
#

hey! how would you guys implement mutators? Right now we have two ways:

  • We simply have a replicated gameplay tag container in our GameState and our game code checks it, it's the simplest but also IMO not the greatest in term of encapsulation etc
  • Use seperate objects (like abilities) that modify the game state
    ๐Ÿค”
twin juniper
#

and have the GameplayTagContainer on the AInfo (AMutator)

#

and a boolean to say whether the mutator is active or not

pearl fog
#

oh I see yeah

#

yeah I think i'm going to do this, I don't think I should bother with seperate objects even if it looks more elegant it feels more complicated for just simple mutators

shy aspen
#

Is it possible to determine when a structure is fully done replicating? Or some sort of config or override that prevents OnRep methods from firing until the structure is fully done replicating?

#

I'm running into issues with a structure triggering an OnRep method multiple times as it's fields are being populated. Types like booleans seem to be coming through instantly but references to actors sometimes are coming through as null.

lost inlet
#

Check if itโ€™s begun play?

#

Though Iโ€™m curious as to why thatโ€™s an issue

#

Also you should expect some delay in actor references since itโ€™ll require the actor itโ€™s referring to to be fully replicated if itโ€™s a hard reference

somber glade
#

If my dedicated server's game mode spawns a pawn and tells a player controller to possess it, is there any reason that 'event possessed' should run twice? is that an editor error or is something wrong there? (4.26 running in editor as client with a dedicated server, 1 client) LogBlueprintUserMessages: [MotionControllerPawn_C_0] Server: Possessed LogBlueprintUserMessages: [MotionControllerPawn_C_0] Server: Possessed Same pawn both prints coming from the server itself. The default pawn for the gamemode is none.

#

I notice that if i set the default pawn to motioncontrollerpawn and just let the player automatically create one and possess it, the server possessed runs only once.

fading birch
#

What's likely happening is you're spawning 2 pawns and possessing them both. The game mode already spawns a default pawn, as per what you set in the game mode's setting for it.

#

which is under RestartPlayer iirc

somber glade
#

and when I check the world outline there is only a single pawn.

fading birch
#

do you have spectator specifically set to false?

somber glade
#

Start players as spectators is set to false.

#

and the spectator class is the just the base engine class, I don't use that.

#

The motioncontrollerpawn is reporting possess twice, same pawn, same controller as well if I print that out.

#
LogBlueprintUserMessages: [MotionControllerPawn_C_0] Possessed by: PC_UserController_VR_C_0

LogBlueprintUserMessages: [MotionControllerPawn_C_0] Server: Possessed by: PC_UserController_VR_C_0
LogBlueprintUserMessages: [MotionControllerPawn_C_0] Server: Possessed by: PC_UserController_VR_C_0```
#

there are also no pre-existing copies of the pawn in the world. It's pawn free.

#

Interestingly this happens both in multiplayer and in standalone singleplayer. So whatever is causing that isn't related to multiplayer.

#

On possess only gets called once on the controller

LogBlueprintUserMessages: [PC_UserController_VR_C_0] Server: Controller Possessed
LogBlueprintUserMessages: [MotionControllerPawn_C_0] Server: Possessed by: PC_UserController_VR_C_0```
nocturne mountain
#

hey, im trying to build either a dedicated server, or a listen server, so that i can test things outside just using the play button. but selecting the dedicated server doesnt seem to be an option like it normally is? additionally, when i build from Visual Studio, it says that server targets arent supported?

has anyone seen this sort of thing before?

#

even from project launcher it says that my ue5 ea doesnt support server targets, which is weird because its fully up to date? and as far as i can tell, eu5 ea actually does?

lost inlet
#

not supported from binary distribution

#

though I'm not sure why you're doing anything serious with the EA build

#

which is getting close to a year old now

nocturne mountain
#

oooooooh that would make sense

#

ill try to get the github version i suppose? or would that be the same thing

lost inlet
#

no, you can compile the server target there

#

it's still pretty experimental but the 5.0 branch there will be way more up to date

#

and you may want to pull from that branch frequently since it's still under active development

nocturne mountain
#

maybe thats where im seeing tutorials pull from

#

because it seems like their unreal 5 is different from mine in some ways. im guessing because mine is the EA. but there isnt a full build somewhere is it?

#

aside from git

lost inlet
#

huh? no

#

5.0 isn't in preview yet but since you're on the EA build I'd figure that you like living on the edge anyway

nocturne mountain
#

that makes sense

twin juniper
#

Hello guys.I am trying to make a simple voice proximity voice chat using dedicated server model.Can anyone tell mw how to do it??

upbeat basin
#

Can I safely call RPC events on BeginPlay? Is there any possibility that my client is not yet initialized to run the RPC?

marble gazelle
twin juniper
#

give a delay and run.You will be fine

#

Can anyone know how to implement voice chat in unreal engine

#

on dedicated server model

marble gazelle
#

delay is always the wrong answer xD

twin juniper
#

why??

empty axle
#

because you can never be sure that the delay is long enough to cover all the cases

#

resolving race conditions with delays is terrible idea

marble gazelle
#

And thus it's better to actually know when smth is ready. And its in fact not that difficult. The actor has two functions, I don't remember the names, would need to search my code, that notify the server that an actor is now being started replication on another client (next frame you should be able to send RPCs to the client) and on the client you also get notified that this actor now gets replicated so the next frame also should be ready for RPCs.

#

And I don't know but I would assume that after BeginPlay was called, we can be sure replication was already setup successfully. On the client only, for the server that must not be the case as you can have joined after BeginPlay was called.

chrome bay
#

Delay is by far the worst way to "solve" any MP bug/race condition. It's just a clear demonstration you don't understand the issue.
Don't mean to pile-in but I see this in "tutorials" now and it drives me crazy.

winged badger
#

our game will typically bounce over a 100 RPCs before BeginPlay is called, which is typically 15 seconds after level is loaded

#

but i agree on the delays, we spawn an entire procedural level separately on client and server, set everything up, and then we call BeginPlay

#

we don't have one delay involved

#

and it would not be possible to time it right with them anyways

#

delays are just.. insidious, when you have 1-2 timing issues, sure, you can make it work with delays

#

but as the game grows in complexity, there is no way you can keep 50 delays or 500 delays timed right

#

my approach is - everything needs to be ready before BeginPlay is called, BeginPlay just does some minor stuff, it doesn't set any game critical systems/data up

#

and definitely doesn't do anything that depends on timing, as there is no guaranteed order in which actors call BeginPlay

woeful ferry
#

Can you create another PIE session while running in editor, to simulate a client joining the server? I need to test a save system

twin juniper
#

Yeah I guess so๐Ÿ˜๐Ÿ˜.

#

Anyone know how to do voice chat in dedicated server multiplayer unreal engine

woeful ferry
#

I found it!

#

"Allow late joining" in editor pref

chrome bay
#

That a UE5 thing?

#

Oh. Nice

woeful ferry
#

UE4 ๐Ÿ˜„

upbeat basin
#

This is one of the best discoveries I had about UE4. I'm immediately going to try it. I've always travelled PIE clients to an empty map and then OpenLevel with localhost to simulate players joining to the server..

upbeat basin
upbeat basin
#

Oh sorry I thought it was answer to another message

marble gazelle
#

The functions I was talking about are:
Server side: AActor::OnSerializeNewActor
and on client: AActor::OnActorChannelOpen

#

you will btw fail if you calln an RPC IN OnSerializeNewActor, next frame seems to be fine

upbeat basin
#

I don't believe those exposed on blueprint readily?

marble gazelle
#

Don't think so^^ I do everything network related in code, sorry ^^'

upbeat basin
#

So even reliable run on client events don't assure they'll be called in client if I call them from server BeginPlay? What about variables that have onrepnotify functions? If I set a replicated variable on server BeginPlay, it should be replicated to the client whenever it's ready, right?

chrome bay
#

There's no reason you need to delay a client RPC. The gameplay framework calls Client RPC's on player controllers the instant they are spawned. So long as you have the owner set at that time, it shouldn't be an issue.

#

Same is true to properties, they are all sent in the initial bunch and onreps will be called before begin play

#

Note that there's a very good chance the RPC will be called before begin play also (client side)

marble gazelle
#

It becomes an issue if the Object you want to call an RPC on is not owned by the client and the client joins later, then BeginPlay may be called before you even connected

upbeat basin
#

I guess that's the difference between your and Jambax's answer right?

chrome bay
#

Yeah I see what you mean, if the client isn't around, no client RPC will be sent to them - but similarly if there's no client present, a client RPC can't be called anyway.

marble gazelle
#

well I assume. For me I take any object into account. If we just think about playercontroller Jambax might be right

chrome bay
#

<@&213101288538374145>

marble gazelle
#

But I for example had the issues with some RPCs and thus I used the Actor functions to be sure replication has started ^^'

upbeat basin
#

I don't think it should be a problem on my case since I'm working on my Pawn then, I don't need the logic to be run on simulated proxies

verbal tendon
upbeat basin
#

So it's fine that my character that spawns on a late joiner doesn't run the beginPlay logic for me

chrome bay
#

Nothing I can recall. RPC's that are received in the same frame as replicated properties are called after properties have been set, IIRC.

upbeat basin
#

In fact it already won't replicated to proxies since it's run on client

#

I guess Frigerius' point is more about multicast events

marble gazelle
#

My point actually is that I wanted to sync stuff earlies possible and I ran into issues with trying to send RPCs too early xD

upbeat basin
verbal tendon
marble gazelle
upbeat basin
#

Alright cool, thanks for confirmations

verbal tendon
#

Ah google's the friend net.AllowAsyncLoading & net.DelayUnmappedRPCs

#

@marble gazelle

marble gazelle
#

hm interesting

verbal tendon
#

Basically delays the RPC until its params have been fully replicated

#

on the receiving client end

marble gazelle
#

Cool, will have a look on this, thx ๐Ÿ™‚

chrome bay
#

That's disabled by default and probably for good reason IMO

marble gazelle
#

Yeah I bet^^ I'll just check what it does in source and then I'll decide ๐Ÿ˜›

chrome bay
#

Calling RPC's that rely on it's params having already replicated sounds like a messy race condition waiting to happen

verbal tendon
#

Yup , which is why it's been forever since I played with that, but it exists

#

Basically also means you're fine designing your game logic to have a bunch of load dependencies

marble gazelle
#

well I have a working solution \o/

verbal tendon
#

Which is not a fun idea ๐Ÿ˜„

winged badger
#

delaying them until NetGUID for the Actor whose channel is used is acknowledged by the client makes more sense

silent plank
#

guys, the Visible property of a SceneComponent is not network replicated

#

how can I safely change it across the network

#

is there some kind of multiplayer event system I can use?

vast forum
#

Does SceneComponent not have setHiddenInGame? I think that replicates by default.

silent plank
#

oh you mean the function let me see

vast forum
#
    /** Whether to hide the primitive in game, if the primitive is Visible. */
    UPROPERTY(Interp, EditAnywhere, BlueprintReadOnly, Category=Rendering, meta=(SequencerTrackClass = "MovieSceneVisibilityTrack"))
    uint8 bHiddenInGame:1;
#

Are you maybe on an old version of UE4?

#

Ah nevermind.

silent plank
#

I am

#

but yours also isnt replicated

vast forum
#

Afaik it is, but let me check something

silent plank
#

is there a way to make a property replicate

#

other than putting Replicated in the macro?

vast forum
#

From my own notes:

#
// Visibility, collision, and tick-state are all replicated be UE, for replicated actors.
// Therefore we should only edit these actor properties for unreplicated actors, or the server.
#

Now this is for actors: I'm sorry if I'm being unhelpful in relation to scene components.

verbal tendon
silent plank
#

hm but this is the visibility of a component on an actor

#

but is there another system i can use

#

to propagate it to clients

#

other than to make it replicate?

vast forum
#

Is the component set to replicate?

#

I do believe it should function the same way

silent plank
#

i don't think so

vast forum
#

Well I would defer to you then, in this case.

#

You can of course make some system on top of it, if needed (although I still question whether it's required)

winged badger
#

as long as its net addressable, there are a ton of ways to making it replicate stuff to clients without it being replicated

silent plank
#

but there's no Unreal system for multiplayer events?

vast forum
#

I would ask my own question: What would prevent me from creating a blueprint-exposed delegate, in my UGameInstanceSubsystem?

Unrecognized type 'FOnMyEventSignature' - type must be a UCLASS, USTRUCT or UENUM

#

Trying to add UPROPERTY(BlueprintAssignable)

winged badger
#

that is not a USTRUCT, yes?

vast forum
#

Ah, true, and UObject isn't on that list

#

Ah ok so it's just about as simple as the error message tells me.

#

So following up on yesterday, where I was using GameState to replicate an FName, what is the best way to provide a delegate/notification when the FName changes?

winged badger
silent plank
#

i can't if i don't know what i'm looking for xd

winged badger
#

try with what are you trying to do then

#

best way, replicate FGameplayTag instead of FName, OnRep with a delegate broadcast on Set and OnRep

vast forum
#

My current system is storing the source-of-truth inside of the GIS, and just using the replication component with a UFUNCTION(NetMulticast, Reliable) to propagate the value to all clients.

#

Weird... I have the same issue when I move the delegate into the UCLASS UActorComponent

thin stratus
#

Your GameInstance should not have Gameplay Code

#

And it also can't really replicate things

vast forum
#

I know it can't replicate things

#

Hence the replicated UActorComponent attached to the GameState.

thin stratus
#

Alright

#

Well either way, RepNotify should do what you want

vast forum
#

But it sounds like my way of doing the replication was bad

#

So I was storing the FName on the custom GIS, and then updating that on all clients by running a UFUNCTION(NetMulticast, Reliable) function on the replicating component.

#

It sounds like I should replace that by storing the FName on the replicated component, and switch it to being RepNotified.

#

My only annoyance/confusion is that I want to pipe all "interaction" with the system through the game instance subsystem. i.e., I want MyGameInstanceSubSystem->OnFNameChanged....

thin stratus
#

Hm well the GI and its Subsystems aren't really meant for this

#

You already have the GameState and hte Component

#

That should be enough

vast forum
#

The GIS exists for two reasons:

  • convenient, single point of contact with this information
  • re-hydration of the data, after a seemless travel (gameState gets destroyed)
vast forum
#

Well, I feel like a failure sadmox

Ever since I moved my stuff from a DynamicMulticast into a the component as an OnRep variable, my client is always wrong

#

Cedric I'm reading through your PDF Compendium right now. Really good stuff!

#

Slight update: Replicated works, ReplicatedUsing doesn't :/

verbal tendon
#

No need to feel like a failure, this is the natural circle of things

vast forum
#

Thanks for the kind words ๐Ÿ˜

I'm also feeling a lot better cause I got most of my stuff working. It's amazing how useful a little mentorship goes.

verbal tendon
#

It sure is ๐Ÿ™‚

#

Especially with Unreal a lot of it is just knowing how to do the thing right, because there are so many options

vast forum
#

sometimes small mistakes pile up, leaving an insurmountable task, and a few offhand clarifications can clear everything up.

woeful ferry
#

Doesn't it compile or doesn't get replicated?

vast forum
#

In the end I solved it.

#

I guess I would write a few of my misconceptions, in case it helps anyone:

  • BlueprintAssignable must be DYNAMIC_MULTICAST
  • ReplicatedUsing doesn't need to set again the variable (just confused about the flow)
#

Those were the latest in a long list

peak sentinel
#

Would it make sense to predict impulse for CMC?

#

as simulated proxy

twin juniper
#

How do I go about making a UDP socket request ? Is there any built in UE libraries for it or do I have to rely on sendto/recvfrom?

cosmic epoch
#

How do I get rid of the jittery movement of Clients from the Listen Server's perspective? I also want to keep using networked root motion, if that's relevant for a workaround. This jitter ofc only occurs when emulating a certain degree of latency, not when ping is below 50ms etc.

#

If somebody has an answer, please ping me, thx

#

@grand kestrel I think u mentioned having looked into this issue in depth in the past?

slim mist
#

Has anyone here used VR Expansion for multiplayer? I'm wondering what the recommended Movement Replication Type is for Grip Components

#

I'm starting to refactor my VR Character such that their actions are replicated

grand kestrel
#

This issue was specific to root motion on Z axis and the listen server's character from the client's perspective, but the issue is the same in both cases, and neither have a solution on either UDN or elsewhere

#

It's listen server, it's in the entire foundation and hasn't been fixed since 2014 when it was released BlobShrug

#

Neither Paragon or Fortnite use listen server, Epic do not care about it

#

As there's no solution literally anywhere, it stands to reason that listen server as a whole is inadequate and they're not going to remake something they've ignored for nearly 8 years which they have no use for themselves

twin juniper
#

What's wrong with listen servers?

dark edge
#

Or do I have autonomous and simulated proxy backwards

peak sentinel
#

For example clients shoot enemy AIs and they get pushed back way too later

#

That's expected and how it's have to be, but just looking for possible workarounds

peak sentinel
dark edge
#

Idk, the whole prediction ecosystem in stock ue4 is a bit of a mess. You got CMC, Network prediction plugin, and GAS but no domain agnostic framework.

peak sentinel
#

I'm fine with diving into some low-level things with CMC or anything else, but just the idea itself seem to be doesn't making sense. I wanted to get some opinions about would 'predicting' something as simulated proxy would make sense at all

cosmic epoch
grand kestrel
#

It's not a solution

#

Selectively skipping the TickCharacterPose in SimulatedTick can help, but not solve it

#

There were loads of ideas on UDN such as disabling combining moves (ew), limiting listen server fps, and so forth but none of them solved it, some made it a bit better, some made it worse, none made it acceptable

cosmic epoch
#

But what do all the UE4 games with listen servers do then? Have jittery animations? UKaos said something about clamping listen server tick to 30fps? uve also mentioned a fix for client rotation on listen servers in a thread I saw today, does that still apply?

grand kestrel
#

I don't have jittery animations in every situation

#

I don't use forums much at all so definitely don't remember that, but the best settings I've found to eliminate mesh rotation jitter for my turn in place system was ENetworkSmoothingMode::Linear and NetworkSimulatedSmoothRotationTime = 0.01f (and ListenServerNetworkSimulatedSmoothRotationTime)

#

That goes for dedicated too though, not just listen

cosmic epoch
#

I see, for me, a regular jogging state machine already jitters badly on the listen server when using the Average network emulation profile

#
#

That was the thread where u wrote about it a year ago or so

grand kestrel
#

Since 4 years? Try 8

#

๐Ÿ˜„

#

Oh, right, I remember that

#

It literally forces your network smoothing mode to exponential regardless of your setting lmao

#
else if (NetMode == NM_ListenServer)
{
    // Linear smoothing works on listen servers
    // but makes a lot less sense under the typical high update rate.
    if (NetworkSmoothingMode == ENetworkSmoothingMode::Linear)
    {
        NetworkSmoothingMode = ENetworkSmoothingMode::Exponential;
    }
}
#

You definitely should use that fix if you want linear on listen, because it makes a lot less sense to have your mesh jitter -_-

#

...Which reminds me, I wouldn't have been able to test linear with listen, I should check if it helps, I didn't have my own fix in my tests

#

I love how it doesn't even tell you it's overriding your setting

cosmic epoch
#

Does this also help with non rotation jitters?

#

Yeah, the docs are really great...

grand kestrel
#

Dunno

#

Gonna check now

#

For this particular issue, or at least my issue, it makes 0 difference

cosmic epoch
#

Because I just tried that fix I mentioned earlier and it still doesn't look completely smooth when running

#

Not sure if it's the animation or the position update that's badly interpolated

grand kestrel
#

This is a better fix though because it wont overwrite after you change to exponential just FYI

void UCMC::OnRegister()
{
    const ENetworkSmoothingMode SavedNetworkSmoothingMode = NetworkSmoothingMode;
    
    Super::OnRegister();

    // UE4 forces this back to exponential which
    // BREAKS turn in place and any mesh rotation!
    const bool bIsReplay = (GetWorld() && GetWorld()->IsPlayingReplay());
    if (!bIsReplay && GetNetMode() == NM_ListenServer)
    {
        NetworkSmoothingMode = SavedNetworkSmoothingMode;
    }
}
grand kestrel
cosmic epoch
#

I see, weird thing is that the tooltip for this setting says it's only for simulated proxies, not for authorities

#

Makes sense since they overwrite it anyway for these I guess

#

So to sum it up, if I want to make a fast paced arena game with a listen server, there's no way for me to get a good experience movement/ animation wise?

dark edge
#

I'm sure there is, but you'll have to be comfortable enough with the character system and animation system that you wouldn't have to ask this question.

#

You can always roll your own character and not use ACharacter

grand kestrel
grand kestrel
#

But sure, there's certainly nothing wrong with doing that yourself, and you get a great example to work from, and it's nice to narrow it down to only the functionality you specifically require

cosmic epoch
grand kestrel
#

Well, it wont on it's own, not unless Epic recreate, or create a new character using it

#

And no guarantee they'll bother with listen server much if at all

fossil spoke
#

Does anyone have any thoughts on how I would implement an "Initial Only" replicated variable within a Struct?

cosmic epoch
#

Guess one can only hope, I really don't get how they can ignore listen servers so badly, they're really popular for small games

fossil spoke
#

As in the only time i want it to be sent to Clients is when they first receive it.

#

Alternatively, is there a way to determine within NetSerialize if its the first time sending to that Client?

soft dawn
#

I'm curious what the best way to handle this race condition is. I record stats during gameplay, kills/deaths, attacks, and hits (attacks that hit a target player). There is a bool which is toggled to determine if stats should be recorded, true during InProgress, false during prematch and post match. The final kill (which ends the game and sets the bool to false) sometimes doesn't record my final attack stat because the the bool is now false. This can result in possibly more hits than attacks which shouldn't ever happen. I'm guessing the same is probably true for my kill/death stats which are more important. Quick "solution" would be to make sure no actions can happen on match end (attacks, players shooting, deaths, etc) and then just put a small delay before i stop recording stats. Does this seem reasonable? I guess i just introduce the chance that stats that shouldn't be recorded after a game is over are actually recorded. Things like projectiles in flight causing hits, deaths that happen after the match, etc.

ember vine
#

not sure if there's a nice way to do it, I feel like struct replication is abit weird - I'd probably end up using a multicast with some serverside bool to see if it's been sent out or not for staggered session joiners @fossil spoke sounds like a terrible solution though now I write it out

#

@soft dawn is the bool a replicated var managed by the server ? Just set it after you do your end match logic

peak sentinel
#

I'm not familiar with CMC deeply but still couldn't find a reasonable purpose for that thing ๐Ÿ˜„

dark edge
soft dawn
dark edge
soft dawn
#

most of the time i get both a hit and an attack recorded correctly, but like 1 in 10 times I get a hit and no attack recorded. This is in blueprints too so maybe that is causing it

ember vine
#

Server needs to manage all stats and the bool, then it can handle it no problem without there being any race condition

#

Blueprints won't be the issue

dark edge
#

It's probably your logic. Make sure the stat is recorded before the bool is decided

#

You might be going Hit, Kill, Set bool, TryUpdateStats

ember vine
#

@cosmic epoch I can't find the thread and not at my PC rn, but if you remind me tomorrow I can find it. Basically some absolute gigachad found out how to fix it - you essentially need to inherit the movement component and use that and do some overrides. Fixed the listen server jittery interp perfectly for me

#

I can't remember the specifics though need pc

cosmic epoch
peak sentinel
#

We may receive updates at a rate different than our own tick rate.
this could be the reason for that 'won't fix' thing

deep shore
#

@ember vine I would love to see this thread, too!

ember vine
#

Okay I will get out of bed see if I can find

deep shore
#

@ember vine thank you! but itโ€™s nbd to wait until tomorrow if youโ€™re in bed!

soft dawn
#

@ember vine @dark edge thanks, looking at it further, something is resulting in multiple hits on some of the shots, seems to happen when i'm firing a lot

ember vine
#

np

soft dawn
#

I'm using easy ballistics, i wonder if the penetration is causing two impacts on the player ๐Ÿค”

ember vine
#

and i cant find this thread, all i've manage to do is find an old notepad file with the code in

MoveAutonomous(float ClientTimeStamp, float DeltaTime, uint8 CompressedFlags,  const FVector& NewAccel)
{

    if (!HasValidData())
    {
        return;
    }

    UpdateFromCompressedFlags(CompressedFlags);
    CharacterOwner->CheckJumpInput(DeltaTime);

    Acceleration = ConstrainInputAcceleration(NewAccel);
    Acceleration = Acceleration.GetClampedToMaxSize(GetMaxAcceleration());
    AnalogInputModifier = ComputeAnalogInputModifier();

    const FVector OldLocation = UpdatedComponent->GetComponentLocation();
    const FQuat OldRotation = UpdatedComponent->GetComponentQuat();

    const bool bWasPlayingRootMotion = CharacterOwner->IsPlayingRootMotion();

    PerformMovement(DeltaTime);

    // Check if data is valid as PerformMovement can mark character for pending kill
    if (!HasValidData())
    {
        return;
    }

    // If not playing root motion, tick animations after physics. We do this here to keep events, notifies, states and transitions in sync with client updates.
    if (CharacterOwner && !CharacterOwner->bClientUpdating && !CharacterOwner->IsPlayingRootMotion() && CharacterOwner->
        GetMesh())
    {
        //// We disable this as it causes listen servers to see clients in an extremely jittery manner
        //if (!bWasPlayingRootMotion)
        //    // If we were playing root motion before PerformMovement but aren't anymore, we're on the last frame of anim root motion and have already ticked character
        //{
        //    
        //    //TickCharacterPose(DeltaTime);
        //}

        // Trigger Events right away, as we could be receiving multiple ServerMoves per frame.
        CharacterOwner->GetMesh()->ConditionallyDispatchQueuedAnimEvents();
    }

    if (CharacterOwner && UpdatedComponent)
    {
        static const auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("p.NetEnableListenServerSmoothing"));
        int32 EnableSmoothing = CVar->GetInt();
        if (EnableSmoothing &&
            CharacterOwner->GetRemoteRole() == ROLE_AutonomousProxy &&
            IsNetMode(NM_ListenServer))
        {
            SmoothCorrection(OldLocation, OldRotation, UpdatedComponent->GetComponentLocation(),
                             UpdatedComponent->GetComponentQuat());
        }
    }``` looking at this now i have no idea how this works honestly im honestly quite sussed out by it
#

but i know we deffo had a solution for it, i cant really test it rn though

#

there may have been some other settings or something as well that needed applying, but not sure

deep shore
#

That was very kind of you to look that up for us. Thank you, @ember vine !

#

will definitely take a look

fossil spoke
cosmic epoch
fossil spoke
#

Im figuring that the Struct could hold an internal list of connections that its already had NetSerialize called for it.

#

Then any subsequent calls can ignore serializing specific properties into the archive if its connection exists in the list already.

somber glade
#

So I have my VR pawn set up to replicate hand position based on the local motion controller position. For some reason this causes a crash on my dedicated server, yet worked fine in a listen server environment. It's a very simple setup. The local pawn checks the position of the hands, then makes an RPC to the server. The server multicasts to all clients, branches on not locally controlled, then sets the position of the hands. The dedicated server logs are fairly useless, and I'm a bit confused as to why this works fine in a listen server but not a dedicated server.

To clarify multicasting and then filter by not locally controlled means that it should set the hand position on all the other clients which aren't the client doing the actual moving, correct?

cosmic epoch
#

@ember vine @grand kestrel so I ended up trying 3 things to alleviate the Listen Server jitter, of which 2 & 3 helped me reduce the issue by about 90% (almost as smooth as a simulated proxie in a client game)

  1. Modifying the [/Script/Engine.GameNetworkManager] inside DefaultGame.ini according to a suggested change by UKaosSpectrum (no difference for my issue sadly)

  2. Override CharacterMovementComponent::MoveAutonomous to comment out TickCharacterPose(DeltaTime);

  • override ACharacter::PossessedBy to comment out Mesh->bOnlyAllowAutonomousTickPose = true;
    This fixed the jittery animations as suggested, not sure about the drawbacks it might have for root motion anims/tasks
  1. Override CharacterMovementComponent::OnRegister to do the opposite of what it usually does at the last if statement (force Linear Network Smoothing Mode for the Listen Server when itยดs set to Exponential) as suggested by @grand kestrel . I left the Network Smoothing Mode of my Character at Exponential in my blueprint settings.
    This improved the jittery movement interpolation on the Listen Server a lot, but itยดs still not 100% as smooth as having a Simulated Proxie with Exponential smoothing on a client

To summarize, I think the last riddle that needs to be solved is the difference between Linear and Exponential Network Smoothing Modes for the Listen Server, why Exponential causes jittery interpolation on the LS, and then to make Exponential behave the same as it would on a simulated proxie, which is buttery smooth

grand kestrel
cosmic epoch
grand kestrel
#

if (CharacterOwner->IsLocallyControlled() && CharacterOwner->HasAuthority()) { TickCharacterPose(DeltaSeconds); }

#

@cosmic epoch MoveAutonomous only calls TickCharacterPose "If we were playing root motion before PerformMovement but aren't anymore"

#

The bOnlyAllowAutonomousTickPose change didn't help me, but could just be because my issue is a bit different (but related)

#

Are you testing with reduced FPS (~60)?

grand kestrel
cosmic epoch
#

yeah, my CPU struggles to get over 40-50 fps for the 2 viewports

#

though what I donยดt really get is that Simulated Tick is supposed to be only used for Simulated proxies, which isnยดt the case here, unless the docs are only telling half the truth as always

#

the Listen Server has Authority for the client actor after all, or does that somehow still qualify as a simulated proxy because it gets the input from the autonomous proxy on the client?

cosmic epoch
cosmic epoch
grand kestrel
#

Not too weird, it seems to be an issue with similar origins but it's very specific so I guess those "fixes" wont solve everything

cosmic epoch
#

seems that forcing Linear smooth mode skips some rotation sync code, which combined with ur TickPose skip results in rotation of the char mesh not being synced at all anymore

cosmic epoch
grand kestrel
#

Mm I didn't think to add some logging there, just took the comment at face value (oops)

cosmic epoch
#

itยดs ok, u probably oversaw the ! in if (!bWasPlayingRootMotion)

#

I really wonder if this "Smooth local view of remote clients on listen servers" stuff even helps in any way?

#

apparently it neither helps with the terrible animation fps nor with the position interpolation in a meaningful way, despite being enabled by default, so maybe itยดs broken?

empty dove
#

CharacterMovementComponent::UnpackNetworkMovementMode returns OutMovementMode EMovementMode::MOVE_None instead of EMovementMode::MOVE_Walk, when passed ACharacter.GetReplicatedMovementMode(). I am not doing any packing on server side. Is it not supposed to auto-work or am I doing something else wrong.

cosmic epoch
#

@grand kestrel ok I think I finally fixed it for good, and the solution was easier than I thought. I applied the OnPossessed and the MoveAutonomous animation fps fix and then also set the listen server position and rotation smooth intervals to the same ones used for simulated proxies in the CMC blueprint.

#

Now I can't tell the difference anymore between a non owned character on client or on listen server, and root motion seems to be fine too

cosmic epoch
vivid seal
#

is there a way to spawn a non-replicated object (in this case a client-predicted projectile) on the client, rpc a pointer to that object to the server, have the server spawn a real object (the real projectile), set a var in the real object using the pointer from the client (that points to nothing on the server), and then have that pointer replicate back to the owning client to identify the fake projectile associated with the new real projectile? I'm trying to figure out a good way for projectiles to know which fake client projectile they are replacing when replicated back to the owning client without setting up some kind of global projectile manager system

cosmic epoch
#

Pointers to actors are rpced via GUID and that only works if they are replicated or pre existing props

vivid seal
#

would it be really really dumb to somehow convert the pointer to a string before rpcing it, then convert it back to a memory address after replication?

#

im just not sure how to easily set this up. if i use generic IDs it'll work just fine except I need to store a map of all fake projectiles and their IDs somewhere that that the real projectile can query

cosmic epoch
#

Why not generate an ID for it instead?

#

And rpc that unique ID

vivid seal
#

where would you store them?

#

gamestate or a player component i guess?

cosmic epoch
#

U could generate it on the fly with a seed

#

A seed that's synced between server and client

vivid seal
#

yeah but what i mean is after the real projectile replicates, it knows it needs to replace fake projectile #1579, how does it find that projectile? it needs to query something, or use GetAllActorsOfClass, which i probably dont want to do

cosmic epoch
#

Well u can simply store all fake projectiles in an array

vivid seal
#

yeah but where do u put the array? on the player? on the game state? on a projectile manager class?

cosmic epoch
#

Anywhere I guess, maybe on the projectile owner or in the game instance or game state

vivid seal
#

i just feel icky tying projectile logic to the player class itself lol, i guess anything will work just doesnt feel particularly clean

cosmic epoch
#

Many games have projectile managers

#

Might be the cleanest way

vivid seal
#

i could do a projectile manager that's just a component of the gamestate i guess

cosmic epoch
#

I think u can even make ur own singleton

vivid seal
#

alright, thanks for the discussion, i'll probably go with a manager class for now unless i find some reason not to

cosmic epoch
#

I heard unreal tournament has some nice code for predictive projectiles

vivid seal
#

still wild to me there's no built-in anything for this, and i know everyone has different implementations but it just feels like one of those things that every single FPS has to code at some point, even just a basic implementation built into unreal would be neat

cosmic epoch
#

Yeah, although the Gameplay Ability System has some nice predictive targeting actors

grand kestrel
#

I learned from it a long time ago and I fully completed what they aimed for

#

Don't recommend anyone uses their method other than the prediction, it's a mess

#

I'd just use GAS though for forward prediction now, no need to reinvent the wheel

#

The major part is rewinding hitboxes for projectiles (the actual projectile code is incomplete too though)

grand kestrel
verbal tendon
grand kestrel
verbal tendon
grand kestrel
#

I had a dream where Epic did those instead ๐Ÿ˜‰

verbal tendon
#

I had those too. They all died a horrible death when I looked at the source code ๐Ÿ˜„

grand kestrel
#

Cruel reality huh

upbeat basin
#

I'm adding a replicated component to an actor in BeginPlay of my server. Is the replication of the component to the client done by flagging the component itself as replicated or the actor that owns it?

chrome bay
#

both

#

They both need to be marked as replicated, since comps' replicate via the actor

cosmic epoch
peak sentinel
#

Is this per variable or per RPC or per packet?

cosmic epoch
chrome bay
#

Should be per packet

#

That's why they moved the character movement RPC's into the character actor and out of the movement component.

#

Cheaper but even tighter coupling

cosmic epoch
#

Interesting, wouldn't have thought that 5 bytes per packet makes such a difference to them

peak sentinel
#

100 players should make difference

cosmic epoch
#

Especially considering that it will try to squeeze as many rpcs into one packet as possible

chrome bay
#

Fortnite numbers though init. Economy of scale plays a big role

cosmic epoch
#

Guess they wanted it to be extremely accessible, even with low bandwidth connections

meager spade
#

its also server costs

#

running through props and comps == more game time on the server

summer tide
#

@kindred widget I should move the discussion to this channel. What about things like Possess/Unpossess, AttachToActor? How can you tell about them?

fathom aspen
#

I know this was a long time ago, but did it work for you what Zlo suggested, or you stuck with SetViewTarget?
Cause I'm having the same jitter you are talking about ๐Ÿ˜ฆ

kindred widget
ashen bay
#

If you were to make Server Accept Client Authoritative Position true, then wouldn't it stop using the server prediction to teleport the player to the "server's predicted position". I'm trying to achieve a simple death ragdoll, it doesn't seem like its accepting my client authoritative position changes and continues to move the ragdoll camera and capsule component to where the server thinks the body landed.

undone plinth
#

Hi, I can't seem to be able to SetViewTarget to a client spawned camera. Any body got any advice?

kindred widget
#

@undone plinth When are you calling this?

undone plinth
#

On the player controller

#

It spawns it and its there in the worldoutliner but just doesn't set the view target

kindred widget
#

That is way too early.

#

Several things call SetViewTarget. Off the top of my head, CameraManager's PostInitComponents, and PawnRestart at least set it, there are a couple of other initializing functions that call that.

#

If you want to call it that early, I'd recommend overriding the PlayerCameraManager's SetViewTarget, and do your own thing, if fail, call Super.

undone plinth
steel gust
#

in terms of best practice, If you bind a function up to some UI ie a button dynamic multicast delegate, and have the player cause the UI to broadcast to a bound function, how do you then make sure the server calls it / or have the client tell the server you want to call the function

winged badger
#

i'd never reference the UI from game code

#

unless its the HUD that just spawns and places widgets around

#

UI can and has to reference the game code though

#

so its ok for a button to directly access and call a function

#

basically, getting the game to production level usually includes scrapping some 4-6 iterations of the UI

#

and you really don't want to end up fixing the game code because of that, game code should not care if there is even any UI

#

if you have any c++ involved, its painfully easy to reliably access the PC, and with it, other classes that can send and receive RPCs from any widget

quasi tide
#

I agree with Zlo - I typically only have the PC add/remove widgets on an as needed basis. The widgets rely on event dispatchers to update themselves.

verbal tendon
#

The only time I've ever done this was for the entire project somewhere. This goes into DefaultGame.ini

ClientAuthorativePosition=true
MAXPOSITIONERRORSQUARED=9000

One is to set the mode to use your client authorative position, the large value on the error is to make sure a codepath doesn't ignore the client auth movement anyway

#

You can use those as a starter point to look into making changes that work for your particular use case. There's only one place incode that uses the max position error. Not sure about the client auth check, but happy hunting! ๐Ÿ™

ashen bay
#

I will give it a try, thanks man ๐Ÿ‘

quasi tide
#

I didn't even know you were able to do this. Seems quite risky.

verbal tendon
#

Keep in mind this is inside the ini file and will affect the entire game, please don't just copy paste. I've given those as a reference for you to look into, it should help finding what you need. Don't just apply blindly, just like with everything else in UE

ashen bay
#

Yea, gonna test it out first and see what happens

verbal tendon
#

It's not like the one thing you actually want to have to develop a multiplayer game ๐Ÿ˜

quasi tide
#

I thought UE just hard-required server authoritative.

vital thunder
#

I'm currently looking to the shooter game epic games provide in the market place. I just saw that and was wondering what's the point of it. I'm not sure I get it. It seems like the replication is paused when something is inside the player bounding box. BuildPauseReplicationCheckPoints just created an array with different points all on the edge of the player bounding box

grizzled stirrup
mighty garnet
#

Does anyone know a good resource for explaining good practices with respect to order of operations when initialising widgets?

#

I'm finding that often my widgets need to bind to eg the character or player state, but those objects haven't yet been replicated from the server

#

so they're null when I try to bind

#

I assume I should be waiting for all necessary replication to happen, THEN initialise my HUD (for example)

dark edge
mighty garnet
#

but not sure if there's a standard architecture for this

mighty garnet
dark edge
#

You can do either.

mighty garnet
#

seems scary to me just delay looping until things are ready but if that's how people do it....

shy aspen
#

you shouldn't have to use delays or bind

#

binding, last time I checked, kills your performance

dark edge
#

Binding is fine for a quick and dirty UI. I wouldn't try make EvE online with it but it's fine for a small operation

mighty garnet
#

binding to a delegate?

#

like, in general?

shy aspen
#

binding to a delegate is fine

mighty garnet
#

ah

shy aspen
#

binding your UI elements to a function is terrible

mighty garnet
#

oh yeah I hate that anyway

shy aspen
#

yeah, avoid it like the plague my friend

dark edge
#

Even just binding to a property is fine if you don't have a thousand of them.

mighty garnet
#

I was expecting that there would be engine delegates I could bind to in BP

#

like OnRep_CharacterPossessed or whatever

#

I see one for player state which is good

shy aspen
#

what are you specifically trying to do? in almost all cases you can get away with an event-based system where one event triggers the next without having to delay / poll for something

mighty garnet
#

yeah that's what I want

shy aspen
#

are you running into some sort of race condition where something isn't ready?

mighty garnet
#

yeah

#

on Event Construct

#

in a bunch of widgets

#

the widget is trying to bind to a given actor's delegates (eg character)

#

but it doesn't exist yet

shy aspen
#

how does the widget get created / added to the screen?

mighty garnet
#

the hud class has a setup method

#

that spawns everything

shy aspen
#

ohh the good old HUD class

#

tbh I've never used it lol

#

I usually create my widgets on my controller or pawn, depending on the widget

mighty garnet
#

it has an Event Initialise method that kicks everything off

shy aspen
#

I don't use that HUD class at all - you're referring to the one you can specify in the game mode?

mighty garnet
#

yeah

#

Im converting a game from single player into multiplayer

#

(not my idea ๐Ÿ˜† )

#

it uses this HUD class

shy aspen
#

rip lol

mighty garnet
#

ya

shy aspen
#

depending on how deep its tentacles are, you might be able to move the setup from the HUD to a simple Create Widget -> Add to Viewport on the character, which means the character is 100% alive and existing when the construct on the widget runs

#

what's the class calling on the event Initialize? is it just creating other widgets?

mighty garnet
#

yep

shy aspen
#

oh, you can probably just call that same logic on the begin play of the character then

dark edge
mighty garnet
#

oh yeah good idea, I guess there's no reason to use the hud class necessarily

shy aspen
#

exactly

#

if that's the only thing its doing

dark edge
#

I like the hud class because it's a good place to put all your UI instead of crowding the player controller.

shy aspen
#

you can still put your UI in a HUD class

#

widget class*

#

call it W_HUD lol

mighty garnet
#

yeah could just avoid the engine lifecycle stuff

#

makes sense

#

will try that, thanks ๐Ÿ‘

shy aspen
#

I believe the HUD class is old school - other vets in here can correct me if I'm wrong.. I've only been using the engine for ~3 years

shy aspen
#

just remembered you said you're going from single to multiplayer

#

avoid creating the widget if the character / controller isn't local, otherwise you'll get all kinds of weird behavior (stacked widgets, null references, etc.)

mighty garnet
#

ah yeah don't want widgets on the server, good call

shy aspen
#

also don't want widgets from other clients

dark edge
#

Keep this in mind

mighty garnet
#

ah yes Cedric

#

all over that

dark edge
#

That's another reason I like using the HUD. Only one exists in a world (besides splitscreen) and only for the local player.

undone plinth
#

Hey, I have a actor that has a mesh comp with bReplicates and bReplicateMovement enabled. I'm only moving it on the server so its smooth on the listen server. I thought it would Lerp the transforms for me? But the client sees it stuttering.

#

Any advice?

shy aspen
#

bReplicateMovement replicates the movement for you but is most likely what's giving you that stutter

#

if you're going to handle the movement yourself, you need to set bReplicateMovement to false

undone plinth
#

Ahh okay

#

Ill give that ago

shy aspen
#

good luck ๐Ÿ™‚

undone plinth
shy aspen
#

right since the server is setting the position on tick, not the clients

#

you'll have to look into movement interpolation

#

like what data is required for your clients to simulate an actor moving from point A to point B

#

that data needs to be sent to your clients and your clients will set the actor location in their instance of the game

#

your server will also be doing it, but the idea is that everyone is doing the same thing collectively using data provided from your server

#

what's APerson inherit from? are you using your own custom character vs. ACharacter?

undone plinth
#

Yeah inheriting from AActor only. So I need to roll client side prediction.

#

?

#

I feel like though I've rolled replicated AActors before and it seemed to lerp between positions/move normally in examples I've had before. I'm gonna load one up and see if its an issue

kind ember
#

Why you no use Character class?
Its already have movement prediction.

peak sentinel
#

Store the client position on OnRep_ReplicatedMovement (or something similar to this) and interpolate it to server location in tick

#

GetActorLocation() on simulated proxies is server's location

#

The values you stored in OnRep is previous update's location

#

You lerp to GetActorLocation() in tick

#

If it's player controlled pawn forget about it, its too complex. Just to CMC instead

peak sentinel
#

There are several question marks there though
-> Why dont you use ACharacter instead?
-> If you dont want ACharacter, why not APawn instead of AActor?

lament cloak
#

So I know Reliable RPCs are guaranteed order on the same replicated Actor.

However, does anyone know if this is true for the Destroy() method? In otherwords, if I call a Reliable RPC on an actor, and then destroy it immediately after, is the order guaranteed?

kind ember
lament cloak
# kind ember I assume thats an server RPC, if server destroyed the actor, why would it matter...

I've got a Multicast that calls an event on a non-replicated actor. But I also want to call that Multicast immediately before it gets destroyed.

So clients receive the multicast, call the event on the non-replicated actor, but then very soon after the replicated actor with the Multicast needs to get destroyed on everyone.

Just wondering if I should expect that to be out of order during packet loss

#

Example:

MulticastDoThing(FVector Location)
{
   //.. do stuff
   if(GetLocalRole() == ROLE_Authority)
   {
      Destroy();
   }
}
kind ember
lament cloak
#

it's replicated

#

i guess that was worded wrong

#

Ignore the non replicated actor

#

If that Destroy() somehow gets received on the client first, then that Multicast wont run, that's what I'm trying to wonder. It seems to work but I'm not sure if this is a potential race condition under packet loss

kind ember
#

There is also OnDestroy or OnPendingDestroy iirc.
What you trying to do before destroy?

lament cloak
#

It needs that Location vector to pass it into another actor (which isnt replicated)

#

Like this

MulticastDoThing(FVector Location)
{
   OtherActor->SetActorLocation(Location);
   if(GetLocalRole() == ROLE_Authority)
   {
      Destroy();
   }
}
kind ember
#

Oh, then you don't even need Multicast,

Look up AActor virtual functions, cuz I am sure the clients get a function call from server to request client to destroy their actor.

lament cloak
#

How am I supposed to send the location then? It's an arbitrary value

#

I think I'm going to have to test this rapidly under heavy simulated lag to see if I can break it. Digging through the NetDriver to see how Destroy() actually works is kinda crazy haha

kind ember
#

Oh lol,
Yea probably add a timer or something

lament cloak
#

yeah that's the other solution

#

can just hide it and then destroy later

#

worst case

kind ember
#

This some sort of treasure hunt mechanic?

lament cloak
#

Hah no I'm over simplifying the code, it's an ability that throws a flag in Capture the Flag. We get odd desyncs here and there and I'm trying to figure out what the hell is causing it, it's extremely rare

#

The ability gets destroyed after it throws the flag, but we're not going to be doing that anymore anyway.

summer tide
empty dove
hollow eagle
#

yes

#

Override GetLifetimeReplicatedProps, call Super, and then there are some other macros you can use to replace DOREPLIFETIME... will find it in a sec

#

RESET_REPLIFETIME_CONDITION(ACharacter, ReplicatedMovementMode, COND_SomethingElse)

empty dove
#

Grateful

empty dove
hollow eagle
#

Declare it in your class, then.

#

it's just a normal function - the fact that the declaration gets generated for you when you have replicated members is just a nicety.

empty dove
#

Ok.

twin juniper
#

so he most likely forgot to include it

hollow eagle
#

GetLifetimeReplicatedProps, not the REPLIFETIME macros.

twin juniper
#

yes

hollow eagle
#

UnrealNetwork.h cannot declare a function for a class it doesn't know about...

twin juniper
#

it's declared in the parent class then

#

i never declared GetLifetimeReplicatedProps in any of my headers

hollow eagle
#

Yes, because UHT auto-declares it for you when you have replicated properties.

#

Declaring in a parent class does not declare it for child classes to override. You still have to declare that you're overriding it.

twin juniper
hollow eagle
#

Not if he doesn't add any replicated properties...

#

Which is precisely what he said. So again, he needs to declare it himself.

#

This is one of those dumb niceties that UHT shouldn't do because it hides normal C++ features and confuses people who aren't intimately familiar with the engine.

hollow eagle
#

Same with UHT auto-declaring _Implementation functions...

twin juniper
#

you right, i just checked and it's auto declared by UHT

#

weird feature

hollow eagle
#

At least in the early days it seems like UHT's design was to generate as much for you as possible... which just makes things confusing. It feels like they've gone back on that a bit at least, they haven't removed that codegen but it at least lets you declare things yourself if you want (iirc it originally didn't).

pure mango
#

Character Movement does not replicate...

  • Owning Actor is replicating
  • Character Movement Component, Component Replicates is CHECKED
  • Checked on the other client/server, the Max Walk Speed is still 600
#

I guess you have to Multicast? But then what's the purpose of the "Component Replicates" in Character Movement Component if it doesn't even work?

hollow eagle
#

CMC replicates just fine without you changing anything.

#

That specific property is not marked to replicate.

#

Notice the lack of the "replicates" icon (the two spheres) on the set node.

twin juniper
hollow eagle
#

anyway, ^ too. I don't remember if CMC replicates that data manually or not but it's definitely not going to work from the client.

twin juniper
#

you just set it on the server

#

and it will replicated to clients

#

depending on the rep condition

#

and if you do that in cpp you can even do better and override the GetMaxSpeed function

#

so you can have let's say MaxRunSpeed, MaxSprintSpeed implemented in the component itself

pure mango
#

I tested it out like this:
Basically, if I press "5" on the client then walk on Client:

  • On Server: everything looks fine, walking slow
  • On Client: looks differently here, the animation is walking as if the speed is 600, but the actual distance covered is as if you're speed 10
    This has a "stuttering" effect
sinful tree
pure mango
#

I see, it's like how siliex mentioned, there's no two spheres in Set Max Walk Speed

#

So even though the Character Movement Component is replicating, that variable is not replicated

#

Is that right?

shy aspen
#

a class or component can be replicated but its variables can be set not to replicate

sinful tree
#

And you can usually tell if the variable is replicated by these little bubble icons.

pure mango
#

Gotcha, okay
So the solution is simple, Multicast

shy aspen
#

no need

#

just make sure you set it on the client side too

twin juniper
shy aspen
#

other clients will see the speed set by the server

#

the owning client will see the speed set on himself + the server

#

the owning client's speed will match what the server has so you won't get that crazy correction stutter

pure mango
#

I see, gotcha
Thanks you guys

dark edge
grand kestrel
#

It's pretty messy to follow code-wise but I guess they're penny pinching due to characters usually being the most significant bandwidth hog

upbeat basin
#

Hey all, is there a race condition here in the picture, considering two clients asking to verify their killing shot on the server which calls this function? I don't want to add any more kills to the scoreboard if the final kill is taken. Is this bool check enough considering both RPC calls should run sequentially on the server after they're received? (if this knowledge is correct of course)

I'm always intrigued about how does event graph and events work sequentially. Especially for the RPC cases. If two clients call an RPC that calls the same event on GameMode, will the second execution wait for the first to finish? Will they work on the same execution line if first takes long time without delays? What if there is delay node? If I can get a little insight or a pointer to where I can get more information about these, I would be grateful as well.

hollow eagle
#
  1. There's no guarantee for ordering of RPCs from separate clients - there can't be.
  2. RPC execution happens on the game thread so one cannot interrupt or run at the exact same time as another.
  3. Delays and other latent nodes work the exact same way as they do with other blueprint events. A delay in one event will not affect another - delays (and other latent actions) do not block anything from executing, they just cause nodes hooked to the right side to execute on a future frame.
    There's only a race condition here if the server isn't authoritative (ie clients can decide their own score).
upbeat basin
#

By order I meant the order according to their arrival on server. I don't care which kill reaches to the server first. I just don't want to increase the kill score over the limit. So according to your answer and second explanation this should be fine since I store the scores in GameState as replicated variables. Thanks very much!

verbal tendon
#

However one thing to be very aware of when doing things like this is to:
(1) Verify someone else hasn't completed the action ( easy with your current example )
(2) Make sure the params are still valid. The client could be referencing in actor that's already been killed on the server, or the game's state could've been changed in a way that makes the params no longer relevant. Something to be mindful of

past seal
#

Hello peeps!
I am having a problem with possesing a pawn through gamemode. I have a UI on each client where you can either select team A or team B. So the UI calls the event "On Team Selected" on the GM which has two inputs(playercontroller and team). The event spawns a character and joins the relevant team, but only if it is the server host. I am guessing this is because the gamemode only replicates server stuff.

Any solution to this? I have thought about using gamestate or simply just having this logic in the playercontroller instead.

marble gazelle
#

GameMode usualy doesn't replicate at all

#

not sure for peer to peer, but with a dedicated server you don't even have a game mode on a client

verbal tendon
past seal
#

Thanks guys, i figured it had something to do with the gamemode only existing on the server yes. I'll look more into client rpcs, kind of a newbie ๐Ÿ˜„

final quest
#

How much does it cost to make your make game online multiplayer like fortnite, apex etc

verbal tendon
#

If you have a complete singleplayer game that you now want to throw money at to magically make multiplayer capabale, or if you have a game idea/funding and want to plan to make a game but don't know how much effort it is to make it MP, or if you need to decide whether or not you want to add MP to your game, etc....

#

There are a ton of potential scenarios that you can find yourself in, and there's not one magical "cost" formula for everything

#

Context is King

bitter oriole
#

These games are the most expensive to run

final quest
bitter oriole
#

Just read above

#

Evaluate how much development time your team needs for each

verbal tendon
dire holly
#

hello! Can someone pls confirm me, that one of the following events (GM) is being called when client joins server map?

#

I mean - I've situation, where the player is in sort of single player map, and if he clicks the UI join button server map is loaded. So my question, if those events are fired again, or not.

dark edge
dire holly
#

cant simulate the server client travel so easily

#

so was curious if someone has this knowledge already

#

this is run when I start the game, just I'm not sure I can rely on this when client travels to server map

dark edge
#

If you can't test it in 5 seconds then get that working first.

dire holly
#

thanks Adriel, very insightful

#

I wanted to spare exactly that time

verbal tendon
dark edge
#

Launch with a bat file

verbal tendon
dark edge
#

It is on my machine lol

dire holly
#

thanks guys, even I've playfab involved and need to test on oculus - therefore this complicated things a bit with server deployment etc

#

to be more informative - I think I found the answer

#

it's not relevant for Adriel, as he knows the answer with his knowledge about how to test this in 5sec

kind ember
dull chasm
#

Hello, I'm looking for some advice related to the character movement component in a multiplayer scenario. I'm working on a top down style game, and my current movement strategy is to use a client side navigation mesh to create acceleration based movement to the local character movement component, additionally, I have orient rotation to movement set, as the camera is fixed to be centered on the character. This seems to be working great! The wrinkle is that I'd like to add the ability to "turn and face" a direction when a character uses an ability (I'm using GAS but I think that's able to stay out of scope here). I think I'm out of my depth on this, but I couldn't find a way to introduce a rotation only "move" to the CMC, in fact it appears it wouldn't view that as an "ImportantMove".

I've hacked something together using a combination of cancelling any outstanding navigation, and using AActor::SetActorRotation on all of the AutonomousProxy, Authority, and SimluatedProxy scenarios. This actually works relatively well, but sometimes the AutonomousProxy can end up with the wrong orientation. I think this is a result of the AutonomousProxy fully applying the local AActor::SetActorRotations before a ClientAdjustPosition happens from one last small move from the previous navigation. I can only reproduce when there is some amount of "momentum" from a previous move request. I guess I could build something to "wait" for outstanding moves to be fully processed, but my goal was to get this rotation functioning as smoothly as the rest of the client side navigation, even if the AutonomousProxy has latency to the Authority. Ideally I would accomplish this without using any movement. I considered forcing the character to move a small amount in the direction I want them to face, but I'm not sure I can guarantee a "full" rotation, without introducing a non trivial amount of "forward" movement.

I'm quite confident I'm doing this wrong and fighting the CMC, but I'm not sure where to go from here.

#

Maybe I can subclass and add a new packed flag, like crouching, to ensure a rotation only move would be replicated?

low helm
#

Ahh fighting the CMC, a tale as old as time

#

how many units will the player control in this game?

#

and are you worried about cheating?

#

I've had really good results with entirely client-driven movement using Pawns and SmoothSync (the plugin)

#

Also, in some setups I'm pretty sure this could work

#

like on a timeline or something

dull chasm
#

I'd have to take a look at that plugin. Players control a single pawn. I don't think the control rotation suggestion can work without moving away from the client side nav mesh strategy as I'm using orient to movement and ignoring all control inputs (maybe I'm misunderstanding your suggestion)

#

I'm pretty new to all of unreal, was the scenario I layed out completely crazy, or is my understanding of my situation fairly accurate

low helm
#

I mean, you're pretty deep in a pretty common problem

#

so you're not dumb

#

I use smoothsync because I trust my players not to cheat

#

if you're making League of Legends....you need proper server oversight

#

now that we discuss it I'm pretty sure I've had this problem before........was remaking Age of Empires 2 and I had to tell me guys to move a little forward whenever they turned to face a different direction

rustic kraken
#

Hey Guys, I have an actor with an event that should run on server. My character right clicks and then that event on that actor gets called, but it isnt triggering, caz afaik actors need to be owned by the client, but idk how to do that, any help regarding this?
I am trying to do a simple building system where right clicking sets the actors materials and some other infos through an event. Is there a better way to do that?

dark edge
rustic kraken
#

I didnt get you, actually i am new to multiplayer

dark edge
#

Run on server event on the pawn or controller

#

Make an Event SetActorMaterial

rustic kraken
#

but its not only set material

#

but all these

dark edge
#

That's fine

rustic kraken
#

i have to do all of them in the character bp?

dark edge
#

Where are you doing it right now?

rustic kraken
#

on the actor itself

#

this whole event

low helm
#

But once you get onto the server, you can trigger an event externally

rustic kraken
#

so can a multicast event call this actor function

#

i will run an event on the server from character bp

#

which triggers a multicast => then actor

dark edge
#

Nothing to do with multicast

low helm
#

So if you want to detonate a nuclear bomb, you start on your character.
RUNONSERVER ---->>> SendDetonationAttempt

Then the server version of your character can tell the server's version of the bomb to run it's DETONATE event.

rustic kraken
rustic kraken
low helm
#

Multicast isn't great because it'll only work for players who are near the object when the change occurs. What you want is a variable on the object with ONREPNOTIFY replication, so everyone can run an event in response to the change of the variable.

dark edge
rustic kraken
dark edge
#

And set them for Onrep
Onrep MyMaterial -> apply changes etc

rustic kraken
#

should this work?

#

built block is the actor i was talking about

#

and this is the character bp

dark edge
#

The actual flow would be like
In pawn or controller
Input -> run on server event -> set variables in building actor

In building actor
Onrep MyVariable -> apply changes (change material, do whatever)

#

Basically the SERVER version of the pawn or controller is what's doing the thing

low helm
#

So if I want to change the color of a banana for all players, the flow would be like this.

My character sends a message to the Server version of my character.

The server's character send a message to the banana to change his BananaColor Variable (which is replicated with onrepnotify).

Each client's banana receives the change in BananaColor and runs the onrep event.

dull chasm
rustic kraken
#

ok lemme try what u guys told me, thanks a lot!

dark edge
#

Onrep is the best. Then if someone late joins they see the banana as the correct color where they wouldn't have been around for the multicast

low helm
#

m sorry I couldn't help more, maybe fiddle with turning control rotation on and off

dull chasm
#

I'm going to try subclassing the CMC/FSavedMove_Character to override IsImportantMove and see if I can get a rotation only move replicating using a new flag for the "look at" operations.

#

I think the right goal is to get this rotation move into the CMC saved move machinery, but it's probably going to be hair pulling work. I'll at least learn something along the way ๐Ÿ™‚

#

Oh, maybe I can hack this in with a movement mode change! Then I won't need to subclass FSavedMove_Character and deal with all of that fallout

stray badger
#

Is there a convention people use for multiplayer projectiles? I can't find any actually useful information to make this work properly.

dark edge
#

@dull chasm could you just not have the CMC care about rotation at all?

dull chasm
#

I do want my characters oriented to where they are moving at all times. What would you suggest manages the rotation other than the CMC?

unkempt tiger
#

(although I'm pretty sure that CMC should be capable of doing that itself)

dull chasm
#

It's absolutely capable, it just conflicts with my desire to every once in a while set an explicit rotation while stationary :)

kindred widget
#

@dull chasm AI controllers with FocalPoints makes that much easier with the pawn's CMC set to smoothly rotate to it's control rotation. Otherwise you're looking at creating your own logic somewhere like the Pawn. Make a local space vector or something and always set rotation towards it if it is not 0,0,0

dull chasm
#

I'll look into that thanks! My players don't have any direct input (it's click to move) to the character anyways so that may work very well

lime iris
#

Does anyone know if there's an online multiplayer game that users don't need to sign up (or make an additional account externally or separate from the store account), but can also do cross-platform play? Btw, just searching for a good example (to avoid double sign ups...)

verbal tendon
dark edge
sinful tree
#

I know from Steam, there was no account sign-up process.... Not entirely sure it's cross-platform.

lime iris
#

I'll look into it!

harsh lintel
#

I have this variable in an actor component class

UPROPERTY(ReplicateUsing = OnRep_MyArray)
TArray<UObjectChild*> MyArray;```

`OnRep_MyArray` is called however if I iterate over the array of pointers

for (auto Single : MyArray)
{
// Use "Single"
}

`Single` is NULL, is there a way to fix this?
harsh lintel
vivid seal
#

okay so i'm trying to do projectile prediction, my current approach is to have the client spawn a fake projectile, assign it an ID, send the server the spawn params and ID. Then the server validates whether to spawn the projectile, if so it will spawn the authoritative version, which has an OnRep for owning player that will replace the client's fake projectile. The tricky part is how to catch the server up to the client's fake projectile. I can use Predict Projectile Path with the client's ping, but I'm not sure what to do in the case that the server actually hits something within that prediction. Do I just immediately notify the client to destroy his projectile and perform hit effects on the server, or do I only register hits if the client thinks he hits something?

#

the other case is if the client's fake projectile hits something before the server rep replaces it

grand kestrel
#

You just call the projectile actor's tick and pass the prediction time as deltatime

#

None of that accounts for player rewind though, it's not easy to achieve with projectiles, forward prediction is only the easy half of that puzzle, players will still complain the hitreg is bad (and it will be)

#

Also spawning projectiles is asking for trouble if you have guns instead of say, magic spells with low rate of fire, spawning them costs a lot, need to pool them instead

grand kestrel
vivid seal
timid moss
#

Does anyone know if the CharacterMotionComponent in the new prediction plugin will also remove the need to the Character class?

rustic kraken
#

so i did this rep notify

#

with an extra variable "Was actor placed"

#

so now everything calls perfectly

#

but even if i set the independent vasriable to true (it also prints true in servers and clients) but actually remains false

low helm
#

why do you think it remains false

#

if it says it's true

rustic kraken
#

i really dont know

#

what could cause that

rustic kraken
#

same thing is happening, altho new visibility is set to true

#

it isnt making it visible

#

this is a different bp btw

low helm
rustic kraken
#

i can see that its not independent as theres no check mark on the actor's variable

rustic kraken
# rustic kraken

and for this, its obvs because i can see the character not becoming visible

low helm
#

you're saying you end the play session?

#

or F8 just detaches from pawn? I don't use it

rustic kraken
low helm
#

yeah ok

#

ok so I want you to take a picture of the PRINT STRING result when you get it

#

and post it

rustic kraken
#

okk

low helm
#

why don't you jump in my private server and stream your setup in greater depth so we can really get to the root of this

rustic kraken
#

ok!

#

send me the invite through dms

lean widget
#

mienkraft?

fathom aspen
#

Minecraft old school

limber gyro
#

Hey guys having a hard time trying to debug a timeout issue, the logs dont say anything much just that a timeout has ocurred, how do i debug this?

tawny wind
#

goddamit replication will fry my brain.. if one player moves his head and i want to tell all clients, hey THIS player moved his head, is a SELF reference in the "move head" function right or wrong? for the other clients the self reference would be THEIR headrotion and not the headrotation from the client who turned his head.. atleast the player moves his head for a second and immidiately goes back to default..

dark edge
kindred widget
#

Also skip owner.

tawny wind
#

so i would write two functions, one for the client who does something and one for simply setting the value so others can see the result

dark edge
#

IF you're using ControlRotation as the view rotation of the pawn, there should be another rotator that can be used on non-owning clients, sec

#

ya this one

#

IIRC it's automagically synced up to ControlRotation, but also exists for remote clients while ControlRotation doesn't

kindred widget
#

Only need one function for setting the head rotation. Call that locally on the owning client and then RPC to server the direction. Have server version set that value to be replicated, skip owner. OnRep call the head rotation function.

#

BaseAimRotation is for Pawns mostly. It uses replicated Pitch, but assumes Yaw from the pawn rotation.

tawny wind
#

oooh yeah now i get it, thank you i will try that

dark edge
#

IDK why the hell they didn't just make control rotation available everywhere but if it lives in the Controller it makes sense

kindred widget
#

Yeah. Rotators replicate very small. Not really a huge issue to replicate one.

#

Specially with roll being ignored most times, and they compress into shorts and bytes anyhow, most rotators are between 3-4.7 bytes.

dark edge
#

@tawny windIf your end goal is that everyone sees everyone looking in the correct direction, then replicate some rotator (Call it AimDirection or whatever) OR leverage BaseAimRotation if that works for your setup. Do not directly replicate things that can be derived from that.

kindred widget
#

I mean to be fair, this is framework from like dial-up days. ๐Ÿ˜„ So I get the stingy sentiment with networking to that degree, but still. Not so true anymore.

dark edge
#

For most shooter type games 2 rotations is enough, that is, body facing rotation and aim rotation.

tawny wind
#

Yeah thats exactly what i'm trying to do, thank you both!

sinful tree
tawny wind
#

Thank you very much Datura, thats exactly what i wanted to be sure about, i guess the symptoms have another cause then

tawny wind
#

okay so i finally got it to work, its probably dirty and i will rewrite it later but i will see, i simply send the rotater with a custom event(multicast) and set the aimrotation with it and the animbp reads it with a cast so the animation can use it, i'm a bit confused about the idea of setting a value to "replicated" since you need to cast to the clients anyways, right now its working fine without setting the rotater to replicated

#

do i mix something up right now?

#

i guess with the current method i send way to much data for such little functionality but this is my first multiplayer project so i cant really tell

daring portal
#

Gooood afternoon!

I'm attempting to use a NetMultiCast to toggle visibility on an object.

Functions like SetActorLocation do work, and I've checked on the client-side that the right object is being called and the client has authority over it, but ToggleVisibility and SetVisibility do not seem to have any effect on the rendering of the item, though the visibility flag of the mesh component does toggle correctly.

Is there something else that must be done to support toggling visibility over a network?

#
// using static mesh actors
  for (TActorIterator<AStaticMeshActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
  {
    const auto before = ActorItr->GetStaticMeshComponent()->GetVisibleFlag();
    ActorItr->GetStaticMeshComponent()->ToggleVisibility();
    const auto message = FString::Printf(TEXT("%s Authory %d Visibility (Before %d, After %d)"), *ActorItr->GetName(),
      ActorItr->HasAuthority(), before, ActorItr->GetStaticMeshComponent()->GetVisibleFlag());
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, *message);
// prints that the flag has changed on both the client and the server but only server visibility changes
  }  
 
 
// using a function in a subclass of actor
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
  class UStaticMeshComponent* MeshComponent;
 
  UFUNCTION(BlueprintCallable, NetMultiCast, Reliable)
  void ToggleVisibility()
  {
    GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Toggling"));
    MeshComponent->ToggleVisibility();
  }
dark edge
#

@daring portalWhy not just set hidden in game on server?

#

you shouldnt need to multicast anything

daring portal
#

I would like the object to be hidden on all connected machines and setting hidden on server does not seem to replicate either

verbal tendon
#

So you're only checking what the state switch is on the server, not on the client, where you're actually experiencing the issue

daring portal
#

The debug does print when I click the button though.

#

The message on the client machine's screen would be client side, no?

#

Let's say I did this over from scratch ๐Ÿ˜„
What would be the best way to do it?

verbal tendon
#
  {
    GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("Toggling"));
    MeshComponent->ToggleVisibility();
  }```

This is your multicast fucntion
#

that executes on both server&client, but it's the least information you get in terms of debugging

#

all your debugging is at the server-side where the RPC is created, so you know what the visibility state is on the server when you do it

#

like with any debugging, trying to zoom in on where the issue might be is a crucial skill

#

So you want to narrow down the possibilities of where the problem may lie. Adding more information in the relevant places is a good way to start

daring portal
#

This is what I'm getting on my server (left) and client (right)

verbal tendon
#

Uhm. So.

daring portal
#

On the left side, the server, those items did disappear. On the right side, the flag is false but the items are still visible. Another command, such as moving the items up or down (for nonstatic) replicates as expected.

verbal tendon
#

Presumably // using static mesh actors is being called from both client and server, instead of just server, but that wasn't the point I was trying to make

daring portal
#

Ah, I see you were talking about the multicast function on the object one, let me isolate that and add more debug ๐Ÿ™‚

verbal tendon
#

You'll probably see that it runs twice and hides it then makes it visible again on the client

#

Assuming the RPC is being created on both client&server, instead of you having that piece of code only run on the server

daring portal
#

So I've put the call to iterate for all visibilitytoggleable actors and to call toggle visibility on them outside of an RPC call- it runs only on the server, then the individual objects should have their RPC's run correctly, as I understand it.

#

The drape in front of the camera becomes hidden on the server but not on the client, though the client also sends the message that the drape's visibility flag has been set to false.

#

It seems like the message that is coming from the server is also displaying on the client. ๐Ÿค”

#

I see, it is actually the RPC that isn't working as expected- not the visibility toggle. Odd, all my other RPCs work. I'll figure out what I bungled!

verbal tendon
#

Fyi I have no idea whether or not that's networked. I only ever use UE_LOG

daring portal
#

I'll switch back to using UE_LOG. Is it possible to look at only the client instance's logs?

verbal tendon
#

If your RPC doesn't work and you've setup everything properly, you might be trying to call the RPC before the actor has replicated to the client from server

hollow eagle
#

AddOnScreenDebugMessage isn't networked, it's just because you're in PIE that it appears everywhere.

#

If you were running separate processes it'd only appear on the instance that called the function.

daring portal
#

Is there any setup I should do for actors that are static in the scene that I would want to network? For my other actors, it seems to be working as expected.

#

Oh bloody hell I'm an idiot

#

Of course UStaticMeshActor has replicates false by default

verbal tendon
#

So... just a random thought here

#

And bear with me

#

The thing with networking is, you always want to do as little as you can get away with

#

your line of thought would be, if you can do it on a local per client basis, you should

#

Here you are now thinking of replicating all of your static mesh actors to toggle their visibility, making one RPC call for each actor in the world every time you want to do this

#

Instead you could have a single RPC call that says "ToggleVisibilityOnSMs"

#

and in the executing logic, it iterates over all your meshes and toggles the visibility locally

#

So instead of doing 100x RPC -> 1 per mesh, you do 1x RPC -> For all 100 meshes

daring portal
#

So that's what I had in the game mode, and I thought that's what the TActorItr would accomplish

#

But for some reason it wasn't

#

I had...

    UFUNCTION(Exec)
    void Toggle();

    UFUNCTION(BlueprintCallable, NetMultiCast, Reliable)
    void ServerToggle();

void AScenarioGameMode::Toggle()
{
    ServerToggle();
}

void AScenarioGameMode::ServerToggle_Implementation()
{
    for (TActorIterator<AStaticMeshActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
    {
        const auto before = ActorItr->GetStaticMeshComponent()->GetVisibleFlag();
        ActorItr->GetStaticMeshComponent()->ToggleVisibility();
        const auto message = FString::Printf(TEXT("%s Authory %d Visibility (Before %d, After %d)"), *ActorItr->GetName(),
            ActorItr->HasAuthority(), before, ActorItr->GetStaticMeshComponent()->GetVisibleFlag());
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, *message);
    }
}
}
#

My understanding is that the reliable multicast would run on the server and all clients, but it seems I have done something wrong.

verbal tendon
#

You're only calling ServerToggleSurgicalDrape not ServerToggle ?

#

In the code snippet above ToggleVisibility should not be an RPC

#

because otherwise, again, it gets called twice

#

assuming everything is setup properly

daring portal
#

Fixed the name of the function in the sample. Calling Toggle() with a console command which should call ServerToggle.

#

Rather, which I would like to call ServerToggle that will run the implementation on all connected machines.

#

Maybe rather than showing what I have, I can describe what I would like, which seems like it should be simple. I would like a console command any connected machine can run that will call its associated function on every other connected machine.

verbal tendon
#

You're also missing the _Implementation function declaration in the header

hollow eagle
#

That isn't necessary. If it was, it wouldn't compile.

daring portal
#

It doesn't get created by the generator? Looks like if I add it to the header it still compiles.

hollow eagle
#

Including _Implementation declarations is optional (though I personally prefer to include it since it makes code generation less "magical").

verbal tendon
#

Makes the code base more explicit rather than implicit, and that's always a good thing

hollow eagle
#

I agree, it's just not a problem here.

daring portal
#

That's interesting it compiles either way. There must be some macro magic to ensure that it doesn't create multiple declarations.

#

Or more likely the header tool just checks if it already exists and doesn't add it.

hollow eagle
#

UHT generates declarations for these functions if you don't write them yourself.

#

Yep.

daring portal
#

Right so if I wanted a command any machine could call such that a function runs equally on all machines, how would I do that? Not how I did it above, obviously ๐Ÿ˜„

verbal tendon
#

okay

#

so

#

you have an RPC inside of gamemode

#

gamemode only exists on the server

#

( this is why it's important to show all the code )

#

Which means it cant run on any of the clients, which is why your code isnt working

daring portal
#

Ah yup, that'll do it. So move all this to a manager class and I'm golden?

#

How do console commands work on the clients if they have no game mode instanced?

verbal tendon
#

As long as the class is an actor that's replicated and has properly replciated to all clients you're golden

verbal tendon
daring portal
#

Probably for the best ๐Ÿ˜†

verbal tendon
#

Childhood trauma from the vast majority of games not allowing me to use the console due to it falling on a dead key on my keyboard, and it not being remappable

steel gust
#

Anyone had issues with an Array of structs not replicating?

chrome bay
#

Noop, should work fine

#

Presuming the struct is a USTRUCT() with it's own UPROPERTY members

steel gust
#

Yeah they are

#

Is there some specific criteria I must meet when modifying values at struct index or individual struct members values?

chrome bay
#

not at all

steel gust
#

I must have mangled something somewhere then

daring portal
#

(moving everything to a manager class solved things, thanks @hollow eagle @verbal tendon )

chrome bay
#

whatever you changed, the engine will compare the next time it checks the actor for replication

#

and determine what to send

wary sand
#

Hello what's the best practice to pick up items in a multiplayer ue4 game ? Because obviously if you create an RPC from an actor that is not owned by the RPC instigator ( and instigator is not the server), the RPC will be rejected so you cannot do things directly like this, so do I list all the items on the ground in the world and give a reference in my RPC from an other owned actor to retrieve the item ? what's best practice ?

chrome bay
#

Send RPC through an actor (or component) you do own with a ref to what you want to pickup/interact with

wary sand
chrome bay
#

Generally you design the system so you can use it for a variety of things of course

wary sand
#

are there apis to get all actors in the world ?

#

how do I use that ref ?

#

how do I get it

verbal tendon
#

๐Ÿ˜

chrome bay
#

Shoot a ray out to see what it hits etc, lots of ways to do it

wary sand
wary sand
chrome bay
#

you can

wary sand
#

~~

#

but memory ref are not the same

#

on all instances

chrome bay
#

It doesn't matter, the engine handles that internally

wary sand
#

how is it possible ?

#

okay

chrome bay
#

So long as the actor is either a) stably named or b) spawned on server and replicated, you can reference it over the network

wary sand
wary sand
chrome bay
#

You can set the owner but that has other problems

#

A) you can't have more than one owner, so how do you handle two players

#

B) Owner is replicated property and inherently latent, so there are responsiveness issues

wary sand
verbal tendon
#

So in a MP environment the way you'd mitigate the latency

#

is by playing a pickup animation instantly locally on the client

#

Instead of waiting for the item to change ownership, or whatever you're doing you can already kickstart the visual process on the instigating client's end

chrome bay
#

But yeah generally, you have a general-purpose interaction system on either the controller/pawn, and that handles the networking and interaction

#

Items might have a component or interface that forms the "interactable" behaviour

wary sand
wary sand
verbal tendon
#

<@&213101288538374145>

wary sand
#

whuw that was fast

wary sand
wary sand
steel gust
#

I am so ready to fight my array, I wonder if its because I have an array inside an array thats causing it not to replicate properly, hmm

wary sand
# wary sand with the ref ?

I create an interact function on Items needing a controller ref, to find the pawn and inventories to interact with ?

wary sand
steel gust
#

Oh that would be it then

#

Ty

wary sand
steel gust
#

Array of structs with array of structs in

#

Was just an easy way to sort some stuff thats modular, but I can change it

wary sand
steel gust
#

Seems to be mangled, but I am pretty sure I have heard something similar before

verbal tendon
#

As long as everything is defined and replicated properly that shouldn't be a problem

#

You cant expect the parent class to take care of it, each of your container element class needs to handle replication properly separately

wary sand
#

Maybe one of your structs is not a UStruct and stuff

steel gust
#

All the structs are marked properly, ustruct, body, uprops etc

#

and the top level array is marked for replication with doreplifetime, and the super is not missing either

chrome bay
#

Struct props don't need to be marked as replicated (they can't, in fact)

steel gust
#

You cant add replicated in to struct props

chrome bay
#

yep

steel gust
#

Very sure

#

Its prob just an issue due to the depth of the arrays and such

#

I am just gonna create a better solution, its overdue anyway

#

omgg

#

I didnt know TMaps cant replicate

#

Gonna scream tonight ๐Ÿ˜‚

verbal tendon
#

But also if you're going for that kind of nested replication, you gotta think that you maybe shouldn't ๐Ÿ™‚

#

Part of that is branching responsibilities out to appropriate manager classes, rather than packing everything into one place into nested data structures

steel gust
#

Well I am actually just doing some digging right now out of curiosity

#

I made a TArray of structs with just a Int in

#

to see if it will replicate

#

oh fuck

#

I forgot to set the component to replicate

#

omfg

#

xD

chrome bay
#

lol

harsh lintel
grand kestrel
harsh lintel
#

okay then maybe that's the reason, I'll try waiting for them to be replicated

jolly siren
#

Is fast array replication more efficient when replicating a large tarray once? Or do the benefits only come into play when changing values within the array and re-replicating?

harsh lintel
# grand kestrel Yes

So if I have the pointers as part of an array, how do I know when the pointers of the array are valid on the client ๐Ÿค”

#

I create the objects on the server, and I all replicate is the array of pointers

#

and I don't quite understand how to send those objects to the client

kind ember
grand kestrel
#

You could use the OnRep to set a pending bool that is evaluated on the next PostNetReceive, just means it's behind by one rep cycle

#

Haven't had to deal with it myself so not sure if there's an easier/better way that's skipping my mind, actors could add themselves to the array

pseudo schooner
#

Hey, I need a second set of eyes on this, I feel like I'm taking crazy pills.
I have an Actor AI that is set to replicate. This actor has an Actor Component that is also set to replicate. Inside this Actor Component is a variable that is set to replicate. I call a run as server function inside the player controller to update the variable inside the AI Actor Component. The server sees this change, the client has no idea it happened. Does this sound like I'm doing something obviously incorrect?
I have also tried to update the variable as a multicast from the player controller, also does not seem to update the client. The actor itself seems to be replicating just fine, it's just this Actor Component that does not want to update across the network

sinful tree
pseudo schooner
#

@sinful tree The client was throwing a Null error so I added a repeating function in the AI that just prints the variable to console every two seconds. Both server and client print the variable, only the client always prints Null

sinful tree
#

What type of variable is it that you're setting?

pseudo schooner
#

It's a reference to a player controller

sinful tree
#

Are you hoping to see that player controller reference on a client other than the one that set it?

#

ie. Client 1 sets the value, Client 2 needs to see it?

pseudo schooner
#

Yea, I need a list of any controller that is interacting with this AI. So anyone who interacts with it gets added to an array. Only the array does not replicate across

sinful tree
#

So that won't work. Player Controllers only exist on the local client and on the server. Clients cannot get reference to other client's player controllers.

#

Best you can do is possibly playerstate or their controlled character.

pseudo schooner
#

Ahhh

sinful tree
#

It sounds like you're setting it correctly otherwise.

pseudo schooner
#

Okay, so if I were going to tackle this issue: Basically I'm syncing a widget state. It's a dialogue, so there's one leader, and the rest of the players are subscribers to the conversation. The leader sends his decisions to the subscriber controllers and their UI updates accordingly. Since I cannot use references to the player controller, what do you think the best way to tackle this would be?

grand kestrel
#

If it needs to persist across characters (changing possessed characters or character destroyed etc) then playerstate, if it never needs to exist across characters then it can go on either, personally for something that has very little to do with the actual character's actions or movement I would put it on the playerstate even if you can use either, unless the dialogue changes between the actual character, note that AI don't get a playerstate by default (need to enable bWantsPlayerState for AI if you want them to have one)

kindred widget
#

@pseudo schooner Is this for stuff like SW:TOR dialog type stuff?

pseudo schooner
#

@grand kestrel I do lock the characters during conversation, and I have to move their camera around occasionally but I have an event system to handle most of that. I'll look to see if I can pop them in the player state, I'll have to look into getting AI access to it, thanks for the heads up.

Yes @kindred widget. It's very similar where one person leads the conversation and the others are along for the ride. But I'm adding something like Divinity where players can jump into an ongoing conversation

#

Btw, thank you @sinful tree

grand kestrel
pseudo schooner
#

@grand kestrel I was actually just thinking...would it be "wrong" to have a component in the AI that tracks the current dialogue and sends all the subscribed controllers updates? AI is on the server so it should have access to all controllers, and the conversations are disposable data. I can have the widget just send a message to the AI Component any time a selection is made instead of watching other players states for changes or jumping through multiple systems just to send a message

kindred widget
#

If I was going to write that into Unreal, I would personally do it through Playerstate. When a Dialog starts, spawn an actor server side and let it replicate. Set an array of "Users" as player's Playerstates. OnRep, if player is supposed to be in said dialog, then play the whole thing locally through a sequencer using a faked character(to avoid CMC issues, it'd be easier to clone characters and not full depossess current pawns). So the only thing that really needs replicated is that the player should start the dialogue, and each "Scene" that needs to be played, and then player's decisions if they're allowed to input them.

rotund badger
#

Hey very new to multiplayer and networking, and wondered if anyone could point me to some great resources on how to implement a secondary client-to-client co-op gamemode in a single player game, or if it would even be worth attempting that

short arrow
rotund badger
short arrow
#

Well what I can tell you now is if you want your game to be co op you need to program it to be co op from start up to the very end. Do you have any multiplayer experience?

rotund badger
#

I do not

#

but the multiplayer portion would be using a completely different set of levels and actors, so I shouldn't have to replicate anything else surely?

#

It's less like a single player game where someone can join you, and more of a different mode, that is separated from the base game

short arrow
#

If Im not mistaking Playing together means being in the same level. That's how it works in ue4 (I could be wrong)

#

Server and client can't be on two different maps

rotund badger
#

It does, but think of it like this

Single player has level 1, 2 and 3 and character 1

Multi player has level 4, 5, 6 and character 2

#

They would be on the same map just the single player content is separated form the multiplayer content

pseudo schooner
#

@kindred widget I'm a bit less advanced than you it seems but I will do some reading on this and see if I can implement it. Thanks for the suggestion! Also thanks @grand kestrel

short arrow
#

That would work fine in theory. You just need to properly replicate what's going on in the playerstate of the character, and the gamemode

#

The server needs to know what's going on between both clients

rotund badger
#

ah I see the documentation only mentions client-server not client-client

#

is what im looking for not possible?

short arrow
#

Yes

#

That would be client server

rotund badger
#

would I have to have at least 1 dedicated server

short arrow
#

It's really just client server client

#

You can use dedicated or listen server

#

All you need to do is just tell the server for example important information like. "Client has finished level 1"

#

So that way the other player can know about it.

rotund badger
#

does the mean I could use the lobby host as the listen server for the other players

#

When launching a multiplayer game, there are two methods in which the game can be hosted. The first, is by using a Listen Server (default setting) which means that the machine that has the authority is also running a client and can play the game normally while hosting for other players.

This seems like what I'm looking for

short arrow
#

Yeah that's fine you can use a listen server... you're still gonna have to do what I said. What are you expecting the difference to be exactly between listen server and dedicated server?

rotund badger
#

A dedicated server means I'm either going to have to show the player how to set one up, or I'm going to have to rent server space, whihc I don't want, a listen server, not entirely sure, but it appears it can just use the players game as the server host

#

thats what it seems like

#

now I could be totally wrong

#

but im also not sure if there would be any security issues of having the player be the host, aside from the ease of cheating

#

which im not worried about, but if a dedicated server system would be easier, I suppose server space for my game wouldnt be that expensive to rent

short arrow
#

A listen server is when the player is also the server. Basically their computer is the server. Dedicated server is when there is no player, just a server and no client

rotund badger
#

yeah thought so