#multiplayer

1 messages · Page 175 of 1

sinful tree
#

That sounds like BeginPlay() with a netmode == NM_Client && actor local netrole != ROLE_Authority. This should ensure that it is in fact a client (not the server at all) and that the actor was replicated from the server (locally spawned actors would have ROLE_Authority)

nova wasp
#

PostNetInit I guess

#

beginplay would work as well as that can only fire after the initial bunch afaik

flat night
#

question: If your GameMode is designed for an Online Match (1 v 1) and you want to make a Local MP GameMode, would you make a Base GameMode and share functionality between them? Like for Local MP you'd need one UI overlay rather than every player creating it, and also Controllers would need to be created in the Lobby, rather than joining from another place.

sinful tree
# flat night question: If your GameMode is designed for an Online Match (1 v 1) and you want ...

I think if you use Beacons, you could effectively have one game mode while still being able to represent both a lobby and a local menu system for joining the game.
As far as within the game, that could probably be determined by setting a bool in the game instance that you're running local multiplayer only which you set if a second local player joins, and if true, check if the owner of your HUD class is == Get Player Controller 0 and if true, proceed with creating the HUD.

flat night
#

what is Beacons?

hoary spear
#

A lightweight replication point that you can use before fully connecting to the server

#

Allows you to rpc, without loading entire world

lament flax
#

Hello
i am (finally) reworking my multiplayer setup from BP to c++.

in my game, the core stuff is relative to the time of the day
each 0.x secs, fake seconds are added.

for now, all was done on server and replicated to clients. Since there is never anything that changes the delay between added fake seconds (except when all players are in bed, then we pass time faster until morning), i thought that :

  • on server and all clients, fake time is added over time (so UI and local stuff is always updated fast)
  • only server will broadcast some specific events to other stuff (eg : this door is only open between 10:00 and 11:00) to unsure "security"

is this a good design ?

#

also, if this can help, this is running on a world subsystem

chrome bay
#

(eg : this door is only open between 10:00 and 11:00) to unsure "security" this wouldn't matter

#

If a client wants to modify their local game instance they can do that, doesn't matter what you replicate ultimately

#

What matters is whether the client is able to proceed with an action they shouldn't be able to

#

If a client gets into an area they aren't supposed to be in, the server would have to "handle" it so they can't do anything meaningful there

#

There's no security in replicating something vs not, essentially

lament flax
chrome bay
#

That's fine, but keep in mind, the client could teleport themselves behind the door or something

lament flax
#

how ?

chrome bay
#

they just move their pawn locally

#

they can choose to ignore corrections from the server

lament flax
#

well, eventually they will get corrected to a point where they are back facing the wall they previously went through illegally ?

#

if not, im not sure how to handle this

lament flax
#

so i guess i'll have some other classes like the game state having replication and broadcasting stuff to the subsystems

chrome bay
#

Yeah subsystems have no networking ability

lament flax
#

im curious why

chrome bay
#

The only type that does is actors

lament flax
#

oh yeah i forgot the actor channel part

#

but maybe there is a way ?
i found that you could do that to UObjects

chrome bay
#

Any object that replicates needs to go via an actor

#

UObjects can only do it when they belong to an actor for instance

lament flax
#

but thats just curiosity i wont make it more complexe that its already

chrome bay
#

But my main point essentially was that replicating something to a client doesn't have any impoact on "security" from an anti-cheat perspective

lament flax
#

but i could technically have a singleton actor that is empty and linked to world subsystems to be replicated

chrome bay
#

So replicating only the time of day and driving everything from that is just as "secure" as replicating bools about doors individually

lament flax
chrome bay
#

truthfully it's not really

#

and you create more potential for bugs and issues by having multiple replicated states that essentialy denote the same information

#

If a client can derive the info it needs from a single property, that's far better design wise

lament flax
#

well in BP it was on GS

  • time of day (fake hours + fake minutes) changing on timer by event
    and then, broadcast events. So stuff like the door "that is only unlocked at some periods", would subscribe to "OnHourChanged" and change its "IsUsable" bool depending on given params.
chrome bay
#

yeah that's fine, honestly I would avoid any state on the door if I could help it

#

checking a timestamp isn't gonna break the bank

lament flax
#

so how would i dot that ?

lament flax
chrome bay
#

Just add an IsUsable function that checks the current TOD whenever you call it

lament flax
#

mh

#

why not

lament flax
chrome bay
#

Because more cached state means more things to go wrong or go out of sync, this is just a general programming thing not MP related

lament flax
chrome bay
#

If some other system looks at the TOD and thinks "door should be openable", then looks at the door and sees it isn't interactable, it's because you have two conflicting states

lament flax
#

like a missed broadcast event ?

chrome bay
#

Or that you queried in in between the broadcast event, or from an earlier callback in the event etc

hoary spear
#

Id probably store this info (if theres alot) in some data asset

chrome bay
#

In general the more stateless you can make something the more resilient it tends to be, I find anyway

lament flax
#

so checking on server "is usable" would be more costy than checking locally on the WSS "is it the good time"

hoary spear
#

So even thirdparty (npc f.ex) checks the DA when figuring out if doors can be opened etc

chrome bay
#

One huge pitfall of OOP is how stateful it is

lament flax
#

also, since im using GAS :

  • should i run the check in some stuff relative to GAS or basique methods
void nest
#

I'm having a strange issue that makes it so comparing a user unique net ID (from playerstate) no longer matches when the game has been shut down and restarted? However, when I print the ID (to string) they are identical. What's going on here? Is the unique net ID struct containing more stuff than a string that changes each time you launch the game or something?

#

Here's an even weirder twist to the issue. When I play using a development build it IS always the same. But on a shipping build it's different each time the game is relaunched.

#

My mind absolutely does not comprehend what in the hell is going on

#

Does anyone know what kind of dark forces are at work here?

chrome bay
#

What backend service are you using?

void nest
#

Steam

#

Online Subsystem Steam

chrome bay
#

And you're using FUniqueNetId::Compare to check?

#

Oh nvm, == calls Compare internally anyway

#

Should work fine AFAIK.

void nest
chrome bay
#

Unless for whatever reason it's not actually connecting to steam in one build

void nest
#

I just compare the Net Id Structs themselves

chrome bay
#

Because the "null" subsystem just generates random GUIDs each time.

void nest
#

I've made sure that the structs are only saved and compared after being validated

#

And I've printed them out and they are in fact valid

#

I've also checked the savegame data and it does contain the correct ID's

chrome bay
#

Guess you'd have to step through the code and see why the comparison fails

void nest
#

Yeah, gonna delve a bit deeper I guess

chrome bay
#

UniqueNetID's are wrappers around pointers so maybe it's failing because the pointer comparison fails

#

I'm willing to bet that blueprint == operator doesn't account for that

void nest
#

I'm gonna try and convert them to a string and compare the string to see if that works

#

Because whenever I convert them to a string, they always return correctly and identical

#

But it's like the struct has some other "things" that are different / invalid / null or dunno after a relaunch of the game

chrome bay
#

what the actual internal type is depends on what OSS you use

#

coud be anything

void nest
#

I guess the literal ID string is just one part of the struct

chrome bay
#

steams just stores your account CSteamID IIRC

#

There is no literal string, the data gets converted into a string

void nest
#

Hmmm

#

And could two different data sets convert to the same string?

#

or is that not possible?

chrome bay
#

theoretically yeah

#

I'm 99% sure the issue is because the FUniqueNetIdWrapper which Blueprint uses compares the actual internal pointer

void nest
#

So it's not smart to compare the structs?

#

the comparisson of the structs works fine as long as the game runs, between levels and all

chrome bay
#

Without actually debugging I really don't know

void nest
#

But when I relaunch the saved struct (read from savegame data) and the new net id struct no longer match

#

So my far fetched uneducated guess is that inside the struct data there's some kind of stamp that holds indeed a pointer to a gamesession or whatever else that is bound to a single running game session. And when the game relaunches, that part of the struct changes.

#

Gonna try and convert my comparrison system to compare the strings and see what that results into

#

If that works, I think we have our answer

#

What could also be the issue is that the unique net id struct can't be saved

#

But here's where the converted string will prob have no issues being saved

#

I think that fixed it

#

doing a final test

#

will report back

open adder
#

hey there! Could you provide a quick rundown of the database and matchmaking systems commonly used in competitive gaming nowadays? Thanks!

half iris
#

Do I understand correctly that when we server travel from one map to another, the only thing that travels with is the gamestate? Things like player controllers and such do not travel and just get spawned when the new level has loaded right?

hoary spear
#

Hmm gameinstance survives but not sure about gamestate

#

You can pack some stuff along for seamless afaik

chrome bay
#

GM and GS will transition as they are yeah

#

Controllers may also be kept

#

FSeamlessTravelHandler::Tick() is where you wanna look

hoary spear
#

This is exclusive to seamless tho right?

gilded vapor
#

IIRC: its usually something like in Editor GameMode/GameState are always GameMode_0, GameState_0 but maybe different in Shipping

gilded vapor
#

The docs on how GameMode "persists" is misleading because its "persistence" is more related to implementation details regarding seamless-travel then actually "persisting to the next actual level"

#

You can technically mark it as an actor to persist in "GetSeamlessTravelActorList" but this is ill advised you'll have to handle all the setup GameMode/GameState normally do for you

chrome bay
#

That's FName though, and that makes sense because FName is not case sensitive outside of editor

#

But yeah, names def won't be reliable

brisk swift
#

Trying to pass a USaveGame through to a server function but it is always NULL on the other side

chrome bay
#

Always will be

#

USaveGame is a local UObject on your machine, so you can't network references to it

brisk swift
#

how do i get the server to get the clients save game then

wet mica
#

Guys, i Need your help to understand multiplayer. In my APlayerController child class, i got mouse input to rotate top-down character (child of ACharacter).

void AWTPlayerController::OnCursorInputHandle(const FInputActionValue& Value)
{
    FHitResult CursorHit;
    if (!OwnedPawn.IsValid() || !GetHitResultUnderCursorByChannel(UEngineTypes::ConvertToTraceType(ECC_Visibility), true, CursorHit)) return;

    const FVector CharacterWorldLocation = OwnedPawn->GetActorLocation();
    const FVector TargetPosition = FVector(CursorHit.Location.X, CursorHit.Location.Y, CharacterWorldLocation.Z);
    const FRotator FinalRotator = FRotationMatrix::MakeFromX(TargetPosition - CharacterWorldLocation).Rotator();
    OwnedPawn->SetActorRotation(FinalRotator);
}

When i start listen server mode with 3 viewports:

  1. Server-player is rotating correctly in all viewport
    2 and 3 - clients, rotating only on their own viewports

If player controller owned by server, why rotations of this instances of characters is not replicated?

chrome bay
#

You're not sending an object when you send the RPC, your sending a reference to it

chrome bay
brisk swift
#

unfortunately i don't know the 'somehow'

chrome bay
#

Clients sending local files to servers sounds like a recipe for disaster ofc

brisk swift
#

I know you're really supposed to save data server side but I don't know how to go about that and you need some cloud storage right that i'm not paying for rn

dark edge
#

You never tell the server anything about the cursor hit location or the rotation that comes out of it

wet mica
dark edge
#

You need to send the server something

#

whether that's the cursor hit point or resultant rotation or whatever is up to you

gilded vapor
#

Does anyone know how to build shipping with crash logs/debug symbols?

Clients are crashing in a shipping build when seamless travelling though not sure why

lost inlet
#

I don't know why that's here

#

but there's a packaging option

#

but really, I wouldn't think of giving debug symbols to your players

gilded vapor
#

I'm just internally testing steam-integration

#

def wouldn't give debugs symbols/debug build to actual players

lost inlet
#

it's useful to have the symbols in the staged output though so you can copy them to the symbol server/the third party crash service you use after the build, but exclude them from steam (insert other platforms here) upload

gilded vapor
#

^^its here because multiplayer/seamless travel

#

packaging probs better though

lost inlet
#

well do you know for sure without seeing the callstack?

gilded vapor
#

Well the client is crashing after the server tries to seamless travel

lost inlet
#

also on past projects, we would upload to steam twice. we'd have internal builds that did have the PDBs included but anything external wouldn't have it

gilded vapor
#

The server itself makes it to the next level fine but all the clients hard-crash on a segfault

#

idk which

lost inlet
#

depending on project budget, it might be good to use some third party service to handle crashes for you. at my old studio we used Bugsplat

gilded vapor
#

Do debug builds (if uploaded to steam) still work with multiplayer?

#

That probs is the easiest if that works

lost inlet
#

well you can get debug symbols for shipping anyway, it's just a little harder because it's optimised code

#

you could do debug for someone internal to the studio to investigate

gilded vapor
#

What do you mean someone internal to the studio to investigate?

lost inlet
#

you wouldn't give debug builds to the public

gilded vapor
#

well yeah I'm debugging it myself of course hahah

lost inlet
#

multiplayer works regardless of the build type, it'd be pretty useless if it didn't

#

the only thing about doing a full-on debug build is that the perf will be shit

quasi tide
#

Ari actually recently did a video about a lot of debugging tips, even in shipping builds. Can't find it right now though. And at work, so can't spend to much time looking.

maiden flame
lament flax
#

they will have no "delays" because ping isnt involve but im still scared of having clients not synced between each other

#

because, the event that will "make start the time of the day" will be called by server, so if a client start after another they will be out of sync

unique kelp
#

Is there a frequency limit of sorts for animation notifies that can be triggered on a server? I am using a listen server setup and sometimes the server is unable to hear sounds or see vfx from notifies placed in an animation montage that I can see other players play. It has also happened with a simple notify that triggers a debug print.

hoary spear
#

You need to change the notify rules iirc

#

To be branchingpoint or whatever its called

restive vault
#

hi everyone. in a local multiplayer game i wish to have some UI elements which are across the whole screen, not seperated by each player viewport. is such a thing possible ?

hoary spear
#

Near the bottom

#

Addition settings

unique kelp
gilded vapor
gilded vapor
#

Listen server's only tick the character pose when it receives an update

restive vault
#

@gilded vapor so given that i want both for different UI elements, i would effectively have a widget for player screen and a second for viewport ?

gilded vapor
unique kelp
gilded vapor
unique kelp
#

I don't suppose it would be as simple as changing this

gilded vapor
#

There's a bunch of edge cases if you are using root-motion

#

Because the server will tick the animation on the server AND when it recieves updates

#

so the animation on the server will play faster than the client

unique kelp
gilded vapor
#

to fire off anim-notifies

proven pagoda
#

Can anyone help a little... If I use this function, it's replicated and all clients call OnDestroy. If I hit anything that's not the player, I spawn a Legacy Emitter at the hit location and I play the sound succesfully on all clients and server. If I use this Niagara System however, it only plays on the server. I made a NetMulticast RPC reliable to play the niagara system and even that doesn't play the Niagara system.

void AProjectile::Destroyed()
{
    Super::Destroyed();

    
    if (!ImpactParticles.IsEmpty() && !bHitPlayer)
    {
        const int32 RandomIndex = FMath::RandRange(0, ImpactParticles.Num() - 1);
        UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticles[RandomIndex], GetActorTransform());
    }
    
    if (!PlayerImpactNiagara.IsEmpty() && bHitPlayer)
    {
        const int32 RandomIndex = FMath::RandRange(0, PlayerImpactNiagara.Num() - 1);
    
        FFXSystemSpawnParameters Params;
        Params.Location = GetActorLocation();
        Params.Rotation = GetActorRotation();
        Params.Scale = FVector(1);
        Params.bAutoActivate = true;
        Params.LocationType = EAttachLocation::KeepWorldPosition;
        Params.WorldContextObject = this;
        Params.SystemTemplate = PlayerImpactNiagara[RandomIndex];
        Params.bAutoDestroy = true;
    
        UNiagaraFunctionLibrary::SpawnSystemAtLocationWithParams(Params);
    }
    
    if (ImpactSound)
    {
        UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation(), 0.25f, FMath::FRandRange(0.f, 10.f));
    }
}
gilded vapor
#
            TickCharacterPose(delta * root_motion_tick_character_pose_scalar);
            CharacterOwner->GetMesh()->ConditionallyDispatchQueuedAnimEvents();

#

@unique kelp

unique kelp
gilded vapor
unique kelp
#

I don't expect anything else

#

Lol

gilded vapor
#

I batch all of the frame data into saved moves for the CMC. (IE so each saved move has the current-time and play-rate of the montage

#

And when the server playsback the saved-move it sets the animation to the received time. So that player-movements and player-animations are always in-sync when sending from client -> server

#

And the server always ticks the pose as well, but at a SLOWER rate then the actual play-rate. (~.8f) and then it will jump to the proper position when it recieves in update

unique kelp
#

Interesting, I'll see what I can get away with for our use case, thanks!

#

Given me a lot to consider

gilded vapor
#

!bHitPlayer && bHitPlayer

twin flint
#

Has anyone got the mover 2.0 stuff working in 5.4? When i add the mover plugin and restart I get the error: ?GetPrivateStaticClass@UPlayMontageCallbackProxy...could not be located in unrealeditor-movereditor.dll

proven pagoda
#

I have all valid pointers and values and locations are proper and everything comes out expected values

#

Just the clients never play it

#

It gets all the way to play

gilded vapor
#

if (!ImpactParticles.IsEmpty() && !bHitPlayer)

#

if (!PlayerImpactNiagara.IsEmpty() && bHitPlayer)

#

Are these intended to basically be the same checks

proven pagoda
#

Yes those work as expected

#

No

#

One checks if I hit the wall or ground

#

the other checks if I hit a player

gilded vapor
#

ohh

proven pagoda
#

I have 2 different arrays of particles

#

one for the ground one for the player

#

This function works perfectly on every client and server for the legacy emitters

#

This same function calls the spawn niagara with all valid data and it doesn't spawn on clients

gilded vapor
#

So you're destroying it on the server?

proven pagoda
gilded vapor
#

is bHitPlayer replicated?

#

because you might be destroying your particle server side before it collides client side

proven pagoda
#

i didn't think about that

#

let me check please

#

You're a damn legend bro

#

Immediately solved the issue

#

Hero

#

thank you

gilded vapor
#

welcome hahaha

proven pagoda
#

Now I have to go back and undo all this extra trash code I wrote trying to be so verbose

#

I bet this function works just fine in the basic syntax

gilded vapor
#

^^I always have to go back and delete a billion print statements

proven pagoda
#

Well going back to undo my code because I thought it would work more simple broke it again

#

Looks like I did need to do all that verbose shit

#

That's so bad bro if it works don't fix it right

#

Bro there's no way I can't figure out how to fix this back I just had it working are you kidding

#

I'm dead

gilded vapor
#

bahahaha

#

I'm sorry

#

I've done that too

proven pagoda
#

Wow I thought it was just so simple as I didn't replicate a damn boolean

gilded vapor
#

nah nah

proven pagoda
#

and now here I am what 30 minutes later and all I did was break it

gilded vapor
#

you can't just replicate it

#

and a multicast-RPC

#

send* a multicast RPC

proven pagoda
#

I have it in a replicated function already that's called on all clients

#

It plays the sound and the emitter if I miss the player

#

The issue is when I hit the player

#

not trying to argue

unique kelp
#

If you have a RPC reading a replicated variable, it's likely that by the time the variable is replicated (end of the frame), the RPC will have already been executed

proven pagoda
#

I'm trying the rpc now

gilded vapor
#

^^yeah that's what I meant

proven pagoda
#

It auto replicates to fire on all clients

#

That's how I got away with the sound and the other emitter for just hitting the ground

#

None of that is replicated

#

now I need this boolean replicated properly

gilded vapor
proven pagoda
#

I should be able just to spawn a system on the locally controlled player

#

Destroy() calls a net multicast essentially already that I override

gilded vapor
#

Well I guess it doesn't really matter with how you set it up

#

I'm pretty sure you need an RPC to replicate that you hit the player

#

You could also just do the collision checks client side and locally predict the vfx~~

proven pagoda
#

I'm pissed because it was working all I did was have to call getlifetimereplicated props and add one DOREPLIFETIME and it worked

#

I had it figured out

#

I didn't have the RPCs and stuff

#

It's not replicating the boolean

#

it's so easy bro I just what am I missing

#

I tried the OnRep_bHitPlayer

#

It's not getting there true or false

#

This is crazy I labeled my boolean UPROPERTY(Replicated) and I have GetLifeTimeReplicatedProps override, calling super first, then DOREPLIFETIME(AProjectile, bHitPlayer);

kindred widget
#

For starts, I would consider EndPlay over destroyed. Or at least consider doing this stuff before running the super. Second it's better to use something more like a gameplay cue style setup for things like this. Less respawning of particles and whatnot.

proven pagoda
#

I'm sure this is exactly what the test is covering, I need a new variable and replicating it myself is proving to be difficult for me to understand

#

it's gotta be something easy I missed

#

I literally had it working the moment this guy says did you replicate that boolean

#

and now I don't remember what I did obviously that I went back and erased

kindred widget
#

Not sure I'd trust replication that close to destruction.

proven pagoda
#

Well is EndPlay called on all clients automatically if Destroy() is called on the server

#

No I can't see that it is

opal pulsar
#

does replicatedusing mean I dont also need to have the specifier replicated? Is it a 2 in one?

kindred widget
#

EndPlay is called before the Destroyed call. It's just done earlier.

proven pagoda
#

Right but I'm thinking of avoiding using another NetMulticast RPC

#

I can just use Destroyed() to play cosmetic effects until I change to GAS and use gameplay cues

kindred widget
#

IMO if you want to continue this route I would maybe consider setting a 0.3s lifespan instead of calling Destroy. Kill actor collisions and visibility, then set your replicated thing that it's hit something

#

Not ideal, but probably more safe for the visuals

proven pagoda
#

Other than these two items, what else do I need to do simply to replicate a variable? ```cpp
void AProjectile::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);

DOREPLIFETIME(AProjectile, bHitPlayer);

}

//////

UPROPERTY(ReplicatedUsing=OnRep_bHitPlayer)
bool bHitPlayer = false;

kindred widget
#

The actor needs to be replicated.

proven pagoda
#

It is already ```cpp
AProjectile::AProjectile()
{

PrimaryActorTick.bCanEverTick = true;
bReplicates = true;

CollisionBox = CreateDefaultSubobject<UBoxComponent>("CollisionBox");
SetRootComponent(CollisionBox);
CollisionBox->SetCollisionObjectType(ECC_WorldDynamic);
CollisionBox->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
CollisionBox->SetCollisionResponseToAllChannels(ECR_Ignore);
CollisionBox->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
CollisionBox->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block);
CollisionBox->SetCollisionResponseToChannel(ECC_SkeletalMesh, ECR_Block);

ParticleAttachPoint = CreateDefaultSubobject<USceneComponent>("ParticleSpawnPoint");
ParticleAttachPoint->SetupAttachment(GetRootComponent());

ProjectileMovementComp = CreateDefaultSubobject<UProjectileMovementComponent>("ProjectileMovement");
ProjectileMovementComp->bRotationFollowsVelocity = true;

}

kindred widget
#

Relevancy is all that's left then. And not killing it before it has a chance to replicate.

#

If the projectile is too fast, and spawns dies within a frame or three, it might not actually replicate to the client.

proven pagoda
#

It doesn't it travels for half a second

#

Way more than a few frames it's a gun bullet

#

Not hitscan

#

projectile

kindred widget
#

🤷‍♂️ Maybe try an AlwaysRelevant=true

opal pulsar
#

can you explain this one to me COND_SkipOwner what is the owner? say I spawned an actor on the server and made my character the owner (on the server obv because I cant spawn it on a client an replicate it) Does this mean my client is the owner who is skipped if I set that character as the owner but from the server?

kindred widget
#

Also still recommend a small lifetime set instead of direct destroy.

#

Owner is the net owner of the actor.

#

Use case for that might be a local authority thing like the player's mouse movements that you want to replicate to others, but not get replication calls on the owning client.

#

So you make the client do aServerRPC for their mouse movements, set it on server, and it replicates to all but the one who set it basically.

opal pulsar
#

thanks

kindred widget
#

There, mostly corrected. 😄

proven pagoda
#

This makes 0 sense the variable isn't replicating

#

It's just not replicating

#

It never calls OnRep

#

Even tho that's what's labeled and defined

#

I put a breakpoint it gets to the line where it sets the value of the boolean

#

it just keeps on going never get to OnRep

#

Why

#

And the worst part is literally now an hour ago that this broke I had it working

#

It worked an hour ago

kindred widget
#

It is a different value on the client right?

proven pagoda
#

Yes it's always false even tho in the Projectile.h I init the variable with true

#

I declare it bool bHitplayer = true; and the client returns false

#

And there is nowhere else in my code that I set it to anything other than 1 place I set it to true

kindred widget
#

I'm confused, how is it ever false?

proven pagoda
#

You tell me

#

It plays the hit ground emitters if I hit the player on the client

#

That only happens if bHitPlayer is set to false

#
void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
    FVector NormalImpulse, const FHitResult& Hit)
{
    if (ABlasterCharacter* Character = Cast<ABlasterCharacter>(OtherActor))
    {
        Character->MulticastHit();
        bHitPlayer = true;
        
        PlayerImpactNiagara.Empty();
        for (UNiagaraSystem* System : Character->GetHitNiagara())
        {
            PlayerImpactNiagara.Add(System);
        }
    }
    
    Destroy();
}
kindred widget
#

How are you testing that it is false on the client?

proven pagoda
#

I can't see it in any of my breakpoints because it reads the server version and it's true on the server

#

But the emitter is in an if check for !bHitPlayer

kindred widget
#

It shouldn't be initialized to true, the client will initialize it to that too and if it's already true then the onrep won't run. The projectile doesn't start hitting the player so it should be false by default.

proven pagoda
#

That's how I have it now

#

I did it just to test one compile

kindred widget
#

And you set it to false and restarted the editor?

proven pagoda
#

Yeah

#

but hang on I just realized

#

I have a multicast Hit event as well on the player I'm calling

#

I put all the niagara on the player

#

Lemme see about calling it from the player

#

Damn bro the problem is if I play it on the bullet it shows the niagara where it hits on the body properly

#

if I just spawn it from the character idk where I got hit

#

could play blood off the legs on a headshot

#

I made more replicated variables just for fun it's not replicating anything it seems

#

I broke something big somewhere

#

I deleted everything to do with replication and I have LNKR errors for overriding GetLifetimeReplicatedProps. I'm doing the delete binaries and other temp folders

lament flax
lost inlet
#

well a big fyi for world subsystems is that they don't support replication

lament flax
#

yes

lost inlet
#

if that's important, but I'm not reading the lore

lament flax
#

like any SS ?

lament flax
lost inlet
#

well if any was going to be replicatable, the world subsystem would've been it, but there isn't support

#

pretty sure you can use push model or good ol' ForceNetUpdate

lament flax
lost inlet
#

well I've not looked in a minute, but the game state probably has a low net update frequency

lament flax
#

ah

#

true

#

let me check

#

would still be better for easy access to have it in a SS

lost inlet
#

though you can sort of replicate world subsystems, by spawning an actor to proxy the data for you

lament flax
#

i thought about that with Jambax

#

maybe to much complexity for just that i should rework the system in the GS on server side and just incresse the net update frequency

#

maybe make a "time" component and attach it to GS

proven pagoda
#

I have this linker error of unresolved symbol in a generated file. I have deleted this function off of this class and it won't let me compile until I put GetLifetimeReplicatdProps() back onto my header file. Why must I have that function on this class in order to compile now from some stupid generated file?
LNK2001: unresolved external symbol "public: virtual void __cdecl AProjectile::GetLifetimeReplicatedProps(class TArray<class FLifetimeProperty,class TSizedDefaultAllocator<32> > &)const " (?GetLifetimeReplicatedProps@AProjectile@@UEBAXAEAV?$TArray@VFLifetimeProperty@@V?$TSizedDefaultAllocator@$0CA@@@@@@Z)

lost inlet
#

because your class contains a replicated property

proven pagoda
lament flax
kindred widget
#

Latency no. There's a slight extra size cost from what people say. Probably needs the actor and the component ref instead of just the actor. But it's mostly negligible for most cases.

proven pagoda
#

I have read all the documentation I can find about replication it makes no sense. This boolean isn't being replicated ever. I put a breakpoint on the first line in my OnRep function and it never triggers. On the server the value returns as expected but I am literally at a loss for words

#

I have all the files just like epic documentation says to have them

modest crater
# lament flax is there any extra latency if passing through a component ?

Unreal insights network profiling kills a lot of worries or assumptions about things, It really made me able to see the whole networking picture and how expensive stuff really is (spoiler, it's a lot cheaper than I had originally thought it would be and the headers are tiny, like 14bits or so and replicated variables have like 16bits for header/footer packets.). I'd suggest profiling with it.

lament flax
#

okay

#

now i need to understand how to use it xD

modest crater
#

Empty RPCs are around 24bits

#

I did some testing a while ago because I was worried but at least now I have a clearer perspective.

undone needle
#

Hey Y'all, been trying to render the Replication Net cull distance of my objects for debug and testing purposes to see what actual range might be best for my objects, nothing fancy here. I just can't figure out what box to check in order to do so.. Plenty of tutorials online that explains what Net cull distance is, but no one seems to tell me how can I see the range in game or in editor visualy, am I missing something here?

wet mica
#

If i want to save my casted pawn object in player controller, what the best place to do this? OnPossessed is calling on server site only, but i need to save it in both sites

soft copper
lost inlet
#

How often are you accessing your possessed pawn where saving off a casted pawn is even worth it

soft copper
wet mica
lost inlet
#

Well there's a delegate but not at my PC, but doubtful that will be even a worthwhile optimisation

undone needle
quasi tide
#

@wet mica Do you plan on doing dedicated servers?

wet mica
#

no, its listen server

soft copper
quasi tide
proven pagoda
#

I did the following things, and as of right now it works 3 players all clients and server. I replicated the entire array of possible niagara effects, and I added a multicast RPC that plays niagara as well. It works and honestly I just don't want it to break so I'm gonna leave it alone now

#

THank you everyone for whatever you helped with

undone needle
quasi tide
lost inlet
quasi tide
#

It does for that part

#

I asked before I read the rest of the stuff 😅

lost inlet
#

Yeah but you also have a delegate like that on the controller too

quasi tide
#

Because ULocalPlayer won't exist on a dedicated server

#

Overall, I don't think this is a worthwhile endeavor

lost inlet
#

It's like OnPawnChanged and it's on authority and client

quasi tide
lost inlet
#

But yeah not really worth it just avoid a pretty trivial cast

wet mica
#

I am trying to provide inputs to control top-down character from controller with enhanced input system.

So, i created 2 methods for it:

{
    if (!OwnedPawn.IsValid()) return;

    const FVector2d MovementVector = Value.Get<FVector2d>();
    const FRotator YawRotation(0.0f, GetControlRotation().Yaw, 0.0f);

    const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
    OwnedPawn->AddMovementInput(ForwardDirection, MovementVector.Y);

    const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
    OwnedPawn->AddMovementInput(RightDirection, MovementVector.X);
}```
and

void AWTPlayerController::OnCursorInputHandle(const FInputActionValue& Value)
{
FHitResult CursorHit;
if (!OwnedPawn.IsValid() || !GetHitResultUnderCursorByChannel(UEngineTypes::ConvertToTraceType(ECC_Visibility), true, CursorHit)) return;

const FVector CharacterWorldLocation = OwnedPawn->GetActorLocation();
const FVector TargetPosition = FVector(CursorHit.Location.X, CursorHit.Location.Y, CharacterWorldLocation.Z);
const FRotator FinalRotator = FRotationMatrix::MakeFromX(TargetPosition - CharacterWorldLocation).Rotator();
OwnedPawn->SetActorRotation(FinalRotator);

}

And first method, for movement, is work correctly on each client and listen server viewports. But second one is working only for listen server instance. Each client can see only own pawn rotating. I still cant undestand, why. Character setup is default
lost inlet
#

Well that's not really going to be fixed with caching a pointer, GetPawn works fine

#

You need to send that information to the server for it to do anything

#

Input isn't networked

quasi tide
#

Yeah, just do an unreliable server rpc and send 'er up

lost inlet
#

The server won't have any information about the client's viewport or camera matrix or anything as well

#

So the target location is what you would typically send

quasi tide
#

Pretty much just send up the information you need to either recreate it, or what the client ends up with.

wet mica
# lost inlet You need to send that information to the server for it to do anything

I aslo trying to replace last line with this method

UFUNCTION(Server, Unreliable)
void Server_SetPawnRotation(const FRotator& InRotator);

cpp:

void AWTPlayerController::Server_SetPawnRotation_Implementation(const FRotator& InRotator)
{
    if(OwnedPawn.IsValid())
    {
        OwnedPawn->SetActorRotation(InRotator);
    }
}

but nothing changed. Pointer check is valid, if i put log inside

lost inlet
#

And does the client actually own the pawn, is its movement replicated?

#

Though if it's something the player controller is possessing, you would typically also do it on the client too

lost inlet
#

And the rest of it?

wet mica
#

If i can see rotating only on client site, guess it is

lost inlet
#

Well if it's a character, I assume it's the one the client is actually possessing?

#

Still not sure why GetPawn<T> isn't being used

wet mica
#

yes, 100%

lost inlet
#

Then you have to "predict" it on the client too

wet mica
#

ill replcae to getpawn in a sec

steel vault
#

Quick question for anyone who might know. I have a "bounce pad" BP that is placed into a map. It runs logic on overlap that launches a character using their movement safe logic in a custom CMC. I'm still getting corrections on the client. The client sees you run over it slightly while the server is instantly bounced. I assume this is due to the client not predicting the launch since the launcher BP is performing its logic from the map (server owned). What's the best way to reconcile this? I'd like to avoid logic on the character itself checking for overlaps and doing prediction logic instead of the BP launcher itself handling it.

lost inlet
wet mica
# lost inlet Still not sure why GetPawn<T> isn't being used

now its looking like this, but nothing changed:

void AWTPlayerController::OnCursorInputHandle(const FInputActionValue& Value)
{
    FHitResult CursorHit;
    auto* CurrPawn = GetPawn<AWTDwarf>();
    if (!CurrPawn || !GetHitResultUnderCursorByChannel(UEngineTypes::ConvertToTraceType(ECC_Visibility), true, CursorHit)) return;

    const FVector CharacterWorldLocation = CurrPawn->GetActorLocation();
    const FVector TargetPosition = FVector(CursorHit.Location.X, CursorHit.Location.Y, CharacterWorldLocation.Z);
    const FRotator FinalRotator = FRotationMatrix::MakeFromX(TargetPosition - CharacterWorldLocation).Rotator();
    //OwnedPawn->SetActorRotation(FinalRotator);
    Server_SetPawnRotation_Implementation(FinalRotator);
}
void AWTPlayerController::Server_SetPawnRotation_Implementation(const FRotator& InRotator)
{
    if(auto* CurrPawn = GetPawn<AWTDwarf>())
    {
        CurrPawn->SetActorRotation(InRotator);
    }
}
lost inlet
#

Yes because you commented out the local SetActorRotation call

wet mica
#

yes, but it works on Current client, which takes inputs, and others client has no rotating to this pawn (controlled by input client)

#

looks like, that i didnt call to server about rotating?

undone needle
#

You're in listen mode I'm guessing?

wet mica
undone needle
#

Yeah so, it likely works on your client1 since he's the server but client2 fails because you're not calling your RPC properly. as client you need to let both your client and your server know that you're moving to this point to avoid desync. I'm guessing the Server call fails because of an authority problem coming from client2

wet mica
# undone needle Yeah so, it likely works on your client1 since he's the server but client2 fails...
void AWTPlayerController::OnCursorInputHandle(const FInputActionValue& Value)
{
    FHitResult CursorHit;
    auto* CastedPawn = GetPawn<AWTDwarf>();
    if (!CastedPawn || !GetHitResultUnderCursorByChannel(UEngineTypes::ConvertToTraceType(ECC_Visibility), true, CursorHit)) return;

    const FVector CharacterWorldLocation = CastedPawn->GetActorLocation();
    const FVector TargetPosition = FVector(CursorHit.Location.X, CursorHit.Location.Y, CharacterWorldLocation.Z);
    const FRotator FinalRotator = FRotationMatrix::MakeFromX(TargetPosition - CharacterWorldLocation).Rotator();
    CastedPawn->SetActorRotation(FinalRotator);
    Server_SetPawnRotation_Implementation(FinalRotator);
}

void AWTPlayerController::Server_SetPawnRotation_Implementation(const FRotator& InRotator)
{
    if(auto* CastedPawn = GetPawn<AWTDwarf>())
    {
        CastedPawn->SetActorRotation(InRotator);
    }
}

second function is server RPC. In first method, last 2 lines: i call it to local PC and to server one, No?

queen escarp
#

hey im using a texture for minimap rendering, since its multiplayer i need to create a new texture for each player right ?

kindred widget
queen escarp
#

aye

#

hmm

#

@kindred widget

#

can i do it in the wb somehow ?

undone needle
#

Okay unless there's something I dont get from your code, pretty sure I understand your problem;

Instantiating your CastedPawn in the server function everytime is what causes your issue.
There's a delay between client and server when instantiating on the server, causing it to be null a few ticks.
Since you reassign is everytime in your if statement, you're consistently calling your Cast, but it nevers complete on that tick so it never apply the setActorRotation on the server

#

thats why you dont get this issue on your client1, since he is the server, he doesn't get that delay to instantiate, so its always true for that client

wet mica
#

ill repeat problem:
client 1 (server) - Rotating correctly in own vieport and in others clients vieport
client 2 - Rotating correctrly ONLY in his viewport. Server didnt see rotating of this pawn too
client 3- same as client 2, but in his veiwport

undone needle
#

Yep, thats the behavior of the issue im describing

#

because you're recreating the same problem but with different functions.
few things I would do, start by checking with a UE_LOG if your client2 actually ever calls it, you'll see it probably never does

#

Now, try to hardcode a delay into that function of like, 2 seconds, just to see if that fixes the issue ONLY, using delays in RPC is a big no-no but can be tolerated for debugging
if that solves your issue, Init a timer that will check every ticks that your CastedPawn isn't null, once its properly registered, then call your function dans delete your timer

wet mica
#

But movement method is work correctly. Problem only in rotating input binding method
its ok:

void AWTPlayerController::OnMovementInputHandle(const FInputActionValue& Value)
{
    auto* CastedPawn = GetPawn<AWTDwarf>();
    if (!CastedPawn) return;

    const FVector2d MovementVector = Value.Get<FVector2d>();
    const FRotator YawRotation(0.0f, GetControlRotation().Yaw, 0.0f);

    const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
    CastedPawn->AddMovementInput(ForwardDirection, MovementVector.Y);

    const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
    CastedPawn->AddMovementInput(RightDirection, MovementVector.X);
}
chrome bay
#

Why is the movement handling in the controller anyway.. just move it to the pawn

wet mica
undone needle
#

I would assume your movement works because your PositionVector variable is replicated on server or your pawn is set to replicated movement. So even if your call fails when you call it on server, UE5 takes care of it anyway

#

you probably will get desync though once your project is deployed live

#

Anyway, best way to be sure, do a quick Log and check if the server ever calls your SetRotation for client2 or client3, I'd be willing to bet it stops at your if statement because its null everytime

modest crater
wet mica
lost inlet
#

that not even vaguely correct because why would a server RPC get called on other clients

#

also print debugging

undone needle
#

Do something more like this;

{
    UE_LOG(LogTemp, Warning, TEXT("Calls Function"));
    if(auto* CastedPawn = GetPawn<AWTDwarf>())
    {
        UE_LOG(LogTemp, Warning, TEXT("Casted Pawn is not null"));
        LogHereMethod();
        CastedPawn->SetActorRotation(InRotator);
        UE_LOG(LogTemp, Warning, TEXT("Called SetActorRotation"));
    }
}```
lost inlet
#

or just use the debugger

undone needle
#

Baby steps sswires, baby steps 😛

wet mica
lost inlet
#

the _Implementation function should only get called on the server, yeah. but I don't find print debugging particularly useful since when you hit the breakpoint you can check out everything in more detail anyway

wet mica
# undone needle Do something more like this; ```void AWTPlayerController::Server_SetPawnRotation...
LogBlueprintUserMessages: [BP_PlayerController_C_0] Server: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Server: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Server: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Server: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Server: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Server: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Server: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Client 0: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null

LogBlueprintUserMessages: [BP_PlayerController_C_0] Client 0: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Client 0: Hello
LogTemp: Warning: Called SetActorRotation
LogTemp: Warning: Calls Function
LogTemp: Warning: Casted Pawn is not null
LogBlueprintUserMessages: [BP_PlayerController_C_0] Client 0: Hello

every log is triggered in each client

wet mica
lost inlet
#

add a watch for UnrealEditor-Engine!GPlayInEditorContextString

#

and/or {,,UnrealEditor-Core}::GPlayInEditorID

undone needle
#

Shouldn't there be a Client 1 or Client 2 somewhere?

sinful tree
#

Not for printing Hello. PlayerControllers only exist on the owning client and the server. Any other clients don't have a copy of it.
(Unless of course you're calling this on those particular clients)

wet mica
#

this example

undone needle
#

can I see SetActorRotation function again

undone needle
#

I did, but i dont see your SetActorRotation function definition anywhere, essentially since it's being called properly, I'm guessing the issue is coming from there somewhere. the variable you're modifying is properly marked as replicated I suppose?

wet mica
queen pecan
#

Ah ha!
I packaged the game. Opened up 3 standalone packaged games
One host (player 1), one join as client (player 2), another join as client (player 3)
All joined in fine and can see each other. However, the moment player 3 moves, it disappears from player 2's screen. Besides that everything else works perfect. Player 1 sees 2 and 3. Player 2 only sees 1. Player 3 sees 1 and 2. All can interact with the world. Very weird.
This is Add BPC with IsServer check in Event Graph

However, if I switch to using Construction Script instead and remove the IsServer, then everything works and the issue is fixed.
Therefore I hereby decree that we should not dynamically add BPCs with IsServer in Event Graph anymore, move it to Construction Script

vestal anvil
#

Running into a pretty damn weird issue with replication right now..
BP: https://blueprintue.com/blueprint/xjugbei4/

The SpawnShip customEvent is set up to Run On Server on the player controller. The function for now is called on Beginplay for the player controller.

We can ignore the save loading part here, it works as intended.

The problem begins where the SpawnActor for the BP_Ship_C is done. For some reason, these actors are only spawned on the server, and not replicated to the clients at all. Doing it with a multicast does not seem to make a difference.

The Load Ship Parts function also spawns a ton of actors, all of which are replicated to all clients.

sinful tree
# vestal anvil Running into a pretty damn weird issue with replication right now.. BP: https://...

Are you certain you have the BP_Ship blueprint marked as replicated?
You wouldn't multicast as multicasting wouldn't work on begin play as multicasts are only received on clients that have the actor already so the PlayerController wouldn't exist on the owning client, and, as it is a player controller, it would only ever exist on the server and the owning client anyway, not other clients. Further, if multicasting did work, then you're spawning individual copies of the actor on each instance, not one that would be connected through replication.

vestal anvil
#

good to know about Multicast though!

sinful tree
#

Also, is BP_Ship a pawn that the player controller will possess?

vestal anvil
#

Its a bit odd to explain, but the player and [space]ship are 2 different things

sinful tree
#

Ok that's fine then.
It's just not great to refer to things using the indexes in multiplayer. A player controller normally has a reference to its possessed pawn directly through the function "Get Controlled Pawn", however, if this is run on a player controller's begin play, that might be before they've actually possessed their pawn which would break the "Get Player Pawn by Index" you're using as well as "Get Controlled Pawn".

This logic seems like it should potentially be within the "Possessed" event within the pawn as then you're guaranteed to have a player controller that has a pawn, and can use their references directly, though you could still store some references and settings back to the controller to ensure that the ship is only spawned once per player controller for example.

vestal anvil
#

In the long run the function wont be called on Beginplay, its mostly done there rn to debug part loading.
In the final implementation it will be called once the game actually begins

grim rain
#

hi have an actor that i want the player to not see but others to see. I spawn the actor and set an owner but this leads to the server owning all the actors and being ale to see it. How do i fix this? I set the OwnerNoSee on.

dark edge
#

is every player meant to have one of these or is it literally 1 actor that's visible to everyone but that one player?

grim rain
#

its a little light that i want others to see

#

everyone has one

#

but the owner shouldnt see it

dark edge
#

yeah so owner no see is probably the ticket

#

or on begin play, check ownership, turn off if owner = local player or however you want to do it

#

or turn on if owner is not the local player

grim rain
burnt sparrow
#

I need help with a variable in my character blueprint not working properly for a client in a session. It works perfectly fine for the server host player, but for any other clients, the variable State is resetting to CharacterStates.Base.Idle every frame. At the start of Event Tick which leads to the Base Movement exec line prints the current state, and at the end of the exec lines from the Set States is a macro that prints the new state. The new state seems to work fine when called, but the "current" state at the start of every tick is always Base.Idle.
I disconnected the Set node for Idle, and it made it work fine. This has me really confused - I have no issues with this in server host character, only in joined clients. Is it a latency error of some sort? How can I fix this?

sinful tree
burnt sparrow
#

Can't get a screenshot right now, but it gets a Vector 2D of my movement input action and uses a bunch of Compare Floats that check if both axes are 0.0 for Idle, Y is above .7 for Forward, and anything else for Moving

vagrant grail
#

Do we agree that in GAS, we need only 1 AbilitySystemComponent and 1 AbilitySet right ?

burnt sparrow
sinful tree
#

So if your Check Move Input macro is attempting to get the input action values on the server for other clients, it would always return as idle.

burnt sparrow
sinful tree
#

Replication only happens from server to clients, and input events are local only, so setting the value on the client would only set it for that one particular client. If it's set on the server and this is on your character class, then it could replicate out to everyone for the server's character, but only because they're the server so they can replicate to everyone.

#

A smarter way would possibly be to have the states determined on the clients themselves based on the movement data received rather than relying on the server to enforce the state.

burnt sparrow
#

I think I understand. Does that mean every character blueprint is essentially being processed on the server, not on the clients' side?

burnt sparrow
sinful tree
#

If you're using the "Character" class then it has the Character Movement Component which has some client-side prediction build into it.

#

Basically, Client Input > Add Movement Input > Client begins to move the character predictively > Sends Move data to Server > Server validates if movement is ok > Server sends out data to everyone else > Other clients see the character moving
If the server doesn't like the movement, it'll send a correction to the client attempting to make the move and prevent the movement from going out to anyone else.

burnt sparrow
sinful tree
peak mirage
#

Messing around with Iris, looks like its replication system will not update internal object location automatically (using built-in Spatial filter), anyone know how this works?

burnt sparrow
modest crater
sinful tree
#

And yea, if you did it on the server, then the server would do it and replicate it to you and other clients.

burnt sparrow
sinful tree
# burnt sparrow Okay, I think I understand, I can only use nodes that run on CMC tick. As for th...

Input Actions are local only, so setting that variable on a move input would only set it on the game instance that is pressing the input (which could be only on a client and therefore no one else would know that state). The server wouldn't know about clients pressing their inputs.
Clients and the server should be able to deduce the state of your currently simple system from the current Movement Mode of the CMC & the current velocity & acceleration of the CMC. In the Third Person Template project, the animation blueprints update their state on the Animation Blueprint Update which does exactly this - it reads in the current speed, and what the movement mode is, and then uses that in its graphs uses those values to display the character at different speeds and if they are falling/jumping.

burnt sparrow
sinful tree
# burnt sparrow Oh, alright. I guess I misunderstood it before. So, does this mean the server is...

Server is the only thing that can replicate values to others. Setting a replicated value on a client only changes it on that one client, no one else receives the change.
You can read an Input Action value on tick, but again, they would only have a value for the game instance in which they are being actioned, so if it's on a client's instance, only that client would have a value.

Event Tick happens to fire on both client and the server, but when trying to read an input action on the server on an instance of a character that is owned by a client (ie. only the client would be pressing the input) the server would always return 0 value for the action value where the client would have the actual input value.

opal pulsar
#

Lets say the client miss predicted something and now its value of, lets say a float is different, if I want it to be corrected but also not change it from the server, whats my best bet,

ForceNetUpdate on server or a specific Client_CorrectBlahValue rpc? Will forcenetupdate send things it thinks is already the same?

Is it actually a force update or has some other meaning like its really ForceEvaluationThisFrame where it still only sends things that it knows have changed from the servers perspective?

fossil spoke
#

If the Client changes something on its side, without the Server knowing, the Server has no way of understanding it needs to force the Client to correct.

shy thistle
# opal pulsar Lets say the client miss predicted something and now its value of, lets say a fl...

Depends on your type of game. If it's just a multiplayer co-op or something and you fully trust your clients to do whatever they want and the server will blindly accept what clients can do, you can do an rpc to tell the server that the server should change it's value to something and than that corrected value will get replicated back down to the client.

But if it's a game where you don't want cheaters/hackers, your server should always be right and it's more of a client is out of sync, so you should try and tell the client to update with the server's values.
If it's to do with movement however make sure you use the movement component for all movement logic for prediction and stuff.

opal pulsar
fossil spoke
opal pulsar
fossil spoke
#

No, its not a "force all values to be resent" its a "force my view of the network state to update on clients"

#

Hence its name, ForceNetUpdate

opal pulsar
#

Yeah okay, I was about 50/50 of which one it was as the last sentence said #multiplayer message

Thank you for confirming.

fossil spoke
#

If you do some research on how the CMC does prediction, you will notice it has a clear pattern which requires the Server to explicitly send an RPC to the Client when a correction is needed..

#

@opal pulsar You may also want to take a look at the Engines usage of INetworkPredictionInterface

#

It may help you understand further.

#

I think its pretty much only used on the CMC, but its been a while since I looked.

opal pulsar
#

Will do 👍

swift turret
#

i have a problem with splines

for some reason, client cant walk on mesh created with spline. Both listen server and client sees the same road, server can easly walk on it but client is being pushed back, like there is some collision on server side (but isnt becasue server walked there). Anyone had a problem like that with splines?

lusty kelp
#

why are people so ignore me list type here?

dark parcel
#

Is my English that bad or is what you said just doesn't make sense?

lusty kelp
#

never trust a hamster

dark parcel
#

where do you see a hamster?

lusty kelp
#

your icon

dark parcel
#

Good Sir, that is not a hamster

lusty kelp
#

ginabig whatnot

#

why are we talking?

dark parcel
#

I'm trying to understand what you are saying.

lusty kelp
#

oh nvm that

#

i just trying to find a tester

#

like it said in the hamchi vpn life

dark parcel
#

Ask a friend to test the game, it would be a real challange to find a random from discord to spend their time on your game. Just my 2 cent.

#

I for one, refused to download anything.

lusty kelp
#

nobody ask you

#

who the heck am I talking to?

#

nobody ask you to respond to me

latent heart
#

It's a public channel. Don't complain when the public talks back.

#

Especially when you're literally asking the public for help lol

dark parcel
#

Some people have no awareness

fossil veldt
#

what a dick

#

we have a solution for this

hoary spear
#

Block 😅

queen escarp
#

hey question

#

now im using linetracing to fire weapons on mp

#

but im missing the feel of a bullet "trace line"

#

but acctualy spawning the bullets

#

would be way more costly right ?

#

im only doing that for granades / missiles

latent heart
#

Of course.

lusty kelp
#

u found me out?

queen escarp
#

y i mean if it was singelplayer that would make sence

#

not on MP

#

advince on how to do a bullet trace ?

#

with linetracing ?

lusty kelp
#

u mean a bullet with linetracebychannel?

#

like firing out the gun

queen escarp
#

no i mean liek the visuals

#

i have all that

#

just want some more bullet "tracing" like trail

lusty kelp
#

ah i see

#

well post a video and this community may help you

#

May as in they are snobs

queen escarp
#

he

#

why would i need posting a vid tho

#

lel

lusty kelp
#

for example

#

aka reference to have the community to hek you

dark parcel
#

Line trace would imply instant hit detection anyway. Which is probably okay for realistic games with a very fast projectile in CQB.
In this case, do you need the trail? Could just handle the sfx as a smoke and flash and call it a day, imo.

#

For something that move over time, like Halo's game projectile, I don't think line trace is the solution. You will need a projectile component.

queen escarp
#

yeah well i dont need the trail but it would be more implying where the bullets are comming from

lusty kelp
#

do whatever they wish to do

dark parcel
#

Then you can just spawn the trail, take a look at Rainbow Six Siege

#

see how the trail looks like.

queen escarp
#

yeah thats what im aftger

#

its more the "how"

dark parcel
#

If you have some examples from marketplace, you can try to figure out how they do it, I suppose.

#

can't help you here as i've done little to no SFX

queen escarp
#

hm alright

tardy fossil
#

is it just me or does mover 2.0 use quite a bit more bandwidth?

latent heart
#

The answer is interpolation!

dry dove
#

Hello does the client own data that should be only on the server for ex if i want to make a connexion to database only on server, does the client have those informations too once it's compiled?

lost inlet
#

huh?

#

and the client only knows about stuff that is explicitly replicated

#

but directly connecting to a database server is also its own can of worms

cursive steeple
#

maybe the question is more towards if stuff get compiled into the binary (which it would if not using macros for server only code etc), but im just guessing, otherwise it makes no sense

lost inlet
#

well yeah if secrets are stored in default INI files, people could datamine that

#

unless this is saving progress in a local SQLite database or something, there are very few reasons why you'd want to directly connect to a database server

dry dove
#

yes i have my variables dynamic for security and also to scales servers

#

but the code compiled (gamemode) , is it present in my client?

cursive steeple
lost inlet
dry dove
#

it's to avoid to leak infos/gamelogic to hackers or cheaters

lost inlet
#

the game mode class isn't instantiated on the client when connected to a server, but it's knows of the game mode class

dry dove
lost inlet
#

what are you talking about?

#

directly connecting to a database server is already a no-go, but what exactly are you trying to protect?

#

the client won't know of any data on the server unless it's been replicated

dry dove
#

It's a shortcut sample 🙂 my friend

cursive steeple
lost inlet
#

WITH_SERVER_CODE is 1 on the Game target

#

it's only 0 on the Client target

#

UE_SERVER is used for dedicated server targets

cursive steeple
dry dove
#

thx a lot, it's clear now

undone needle
#

Hi everyone, I'm having an architecture pickle here and wondering if someone has a nice tutorial/doc for database connection best practices for multiplayer online.

I started by wrapping my SQLDatabase class in a ActorComponent since I feel like it should be store at 2 different places because theres 2 purposes to it, manipulating player information and manipulating "public" information (public storage for example). Having the owning client directly call the DB feels like a terrible idea and I feel like it should be handled by the server so I was thinking about putting it into player state for player information related, like, upon connection load that player character info based on his ID. But everything else, I'm not sure if it should be handled by GameInstance, GameState or am I even on right track here?

lost inlet
#

if it's a global database then it's probably better to just have a REST API so neither the client or server are connecting directly to a DB

undone needle
#

That's something I didnt even consider and I work with REST APIs on a daily basis lmao. Heum, but how would you go about handling the credentials from your game? I mean, the server or client will need to use creds in order to call the API and validate they have authorization to do so, there's technically a connection happening somewhere, even though it isn't the DB directly

maiden flame
#

I'm interested in best/most secure practices for this too.

tiny pier
#

no idea if i can get help here, but when I try to sort out my AWS gamelift SDK, I get errors saying Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY) (found version "3.3.0") despite me having OPENSSL_ROOT_DIR inside the system environment. anyone know what can cause this?

#

i've followed every form of documentation, youtube tutorial, forums, to no result

silent valley
# undone needle That's something I didnt even consider and I work with REST APIs on a daily basi...

Depends how you authenticate users really. If users are required to register with the service before being allowed to log in, then you have a login server that authenticates via Username/password/2fa/etc and the login server hands the client a token that is used to access the other game REST services.

As you know you can't store secure credentials in a packaged client so this is the only option.

undone needle
# silent valley Depends how you authenticate users really. If users are required to register wit...

Yeah sorry, was a little unclear in my last question, so yeah going the API route i would probably go a oauth2 authentication route and yes, what you described is essentially the game plan, register first through website, and login with U/P/2FA. What Im more wondering is the initial question. Because all we do here is replace SQL Database class with a API class. But that API class, where would be the best place to put it in the game so that I can access it whenever I might need it. I guess at this point since the token generated is valid to the player that restricts what he can do with the API but he still needs to be able to save and load his inventory for instance, so giving access to the owning client the API class is still a bad idea. So where would I put it so that the server makes the call and validation

silent valley
# undone needle Yeah sorry, was a little unclear in my last question, so yeah going the API rout...

ok well I'm not really sure for the architecture you're describing, for our game the user auths with the server and the server replicated all the information they need, there's no 3rd party (keeping those in sync is asking for lots of extra complications I'm sure).

personally I'd start with using the GameMode to authenticate the player (player connects, override GameModeBase::PreLogin to accept/reject, etc).
once player is successfully connected use your custom PlayerController class, or Pawn class depending on how you want it to work, to replicate inventory etc from server to client.

#

Choice of PlayerController or Pawn for storing inventory is down to the lifetime of the inventory. Is it tied to a specific character, or can the player switch characters, etc.

#

sorry I have to go out now but hopefully that will get you started

undone needle
#

yeah good starting point, thanks for the assist i appreciate it a lot

silent valley
#

using this method (everything through the server) you can store secure credentials in your official server package since you never release that to the public. this way the server can auth with the rest api using built in secrets, or secrets from the machine anyway

ember jasper
#

Hello there, fellow devs !

Do you know how optimized is replication ?
I mean : Can I have a data updated several times per second set to replicated ?

If I want to have players up-to-date when reconnecting or joining mid-game, nothing does it more efficiently than replicated variables I suppose.

But for variables frequently updating, I tend to – whenever possible – use Multicast to initiate the value going up/down for every player and another Multicast to update every player when the value changes direction or reach min/max value.

This however doesn’t suit player joining mid-game very well.
Unless maybe in the BeginPlay of many of my Actors I fetch for Server data manually ?

What are you thoughts on the matter ?

Thank you very much for your attention ! 👍

chrome bay
#

The trick is to NOT update things that fast. You're not doing yourself any favours by brute forcing reliable multicasts instead

#

If it's an unreliable multicast, then it goes through the same system as property replication anyway so is pointless

undone needle
#

Also, multicasting is usually a bad idea, unless every single client needs to know what is happening with that specific data, which more often then not, you realise that only the server needs to know

ember jasper
#

Thanks @undone needle !
I agree !

#

Thanks for the answer @chrome bay !
You mean, no data should be updated that frequently and replicated, right ?
If high update frequency is for the smoothness of a visual, obviously it's gonna be played independently on each client and not replicated.
But if it is a data such as a battery energy level you recommend me to refresh the value a lot less frequently, such as once or twice per second ?
I suppose the client can interpolate between those values for a smooth visual representation.

undone needle
#

its a case by case basis but the idea is there yes, unless its player movement, and even then i dont necessarily agree with unreal that it needs to update 100times per seconds if you do something else than a FPS. But for your battery level, how quickly does the battery energy drops? If the score drops every 5 seconds, updating it once every 2 seconds is fine depending on what the battery is used for.
For instance; battery for a player cell phone, it doesn't matter if he gets to use it 1-2 seconds more than what the server actually said he could.
but battery that powers a generator that prevents player from going through a wall, that one should be updated several times per second so that all players that tries to go through said wall can all do so once the energy level hits 0

ember jasper
#

Thans again @undone needle for the insight !
It now seems obvious I should reduce the frequency and replicate it !

Have a nice day, both of you !

chrome bay
#

You won't get a steady stream of updates in the "real world" anyway, so relying on it is not a good idea. You must design things to be resilient to data loss.

ember jasper
maiden flame
#

Something like: Client clicks widget button, button calls event inside pawn with a server RPC. Server RPC calls a RepNotify function which sets the skeletal mesh.

north jacinth
#

Let's say I want to do p2p with server validation, like how some games treat the server as a third player with final authority, while the connection between two players is peer to peer for lower latency. Would I just use a bunch of RPCs or something? I have the infrastructure to serialize inputs, game state, and rollback if needed Also, is putting server code on a gamemode class the way to go? Any good resources resources to learn more about how server builds work and how the details of how built in replication works?

gray blade
#

hey yall, what startegies do you do to make client side hit detection feel more responsive?

errant mulch
#

hello guys! excuse me if this is not the place to put this question

i have this section of bp in a power up that one of two players can pick up in mid game, the idea is that while is getting picked up, it does a small animation (the one in the timeline), the animations plays correctly on one client, but not in the other player client.

the bp is replicated, as his components and timeline, along with the movement.

what i am doing wrong? how can i fix it so the timeline plays on both clients?

gray blade
undone needle
#

that's 100% what's going on. When calling from client, a multicast RPC gets dropped, it needs to be called from server

errant mulch
#

so, if i have an event for pressing and another one for releasing, that would total 4 custom events that i need to make?

gray blade
#

my advice would be to remove the word server from the two you already have

#

-Then you make a new event and name it "serverPicking up"

#

-set the new event to run on server

#

-then with the new event call the old event

#

-then on E run the new event

#

Repeat same process for the release event

#

How can I hide the emitter from the instigating player?

obtuse field
#

How should I deal with server and client misaligns in sandbox games. E.g. player on the client breaks an Item, but there is a lag and on the server Item is not actually destroyed. Now, server should have full authority, so, the client's chunk should be reversed if misalign occurs. But, sending whole chunk is obviously a very bad idea. I also can't just sore item's location as its ID, as this isn't minecraft's type of building system, items can be placed freely

devout sonnet
#

I'm losing my mind. I can't seem to understand RPC implementation. Can someone hold my hand and walk me through how to get the opponents name that is saved in their Game Instance?

fierce egret
obtuse field
#

Use Player's State

#

As, as the @fierce egret mentioned, Game Instance is not replicated

undone needle
#

Just to be 100% I get this right, the reason why a player inventory should be in player's state is...?

#

I mean, it's not like someone else needs to know what's in another player's inventory (aside from some games like mobas) or am I missing something important here?

obtuse field
sinful tree
obtuse field
undone needle
#

That's the part I was missing, makes a lot more sense, thank you both

sinful tree
#

Now in terms of getting a player's name from the game instance to the playerstate....
You'd need to send an RPC on an actor that is owned by that player (like their player controller or player state) and pass the name as saved in the game instance as an input on that RPC.
Within that RPC call, you'd set that value into a replicated variable on the PlayerState. Once this value is set on the server other clients will receive it.
Updating your UI is either event driven by using an OnRep and pushing the value into your UI or triggering an event dispatcher on the playerstate that your UI would bind to, or otherwise using a bind within the UI to constantly read the value from the particular playerstate.

devout sonnet
devout sonnet
obtuse field
sinful tree
#

This isn't correct.
Begin Play of the playerstate will fire on the server and all clients. This effectively would be setting the name of all playerstates present on any instance of the game to the name in the game instance of the game running this code.

obtuse field
#

You don't want to use it in this situation

devout sonnet
#

ok

obtuse field
# devout sonnet ok

Also, remember to set player's name server side via RPC, just like Datura described

devout sonnet
#

So a custom event that is set to execute on server

obtuse field
#

And CustomPlayerName must be set to replicated

undone needle
devout sonnet
obtuse field
#

If you have to check it, then change it back

devout sonnet
#

i'll do repnotify because the players wont be joining at the exact same time and will need to update the name.

gloomy tiger
#

Not really sure what I am missing, but running SetActorLocation on the server against a replicated actor makes it 'slide' from X to Y from the client's perspective - it's not instantaneous as it is from the (listen) server's perspective. Any clues? (Note1: it's not a APawn with CMC or whatsoever)

undone needle
# obtuse field Cut Game Instance completely out of this equation

Isn't there situation where having Game Instance holding player name would make sense thought?
Example: Login in, assign player name to game instance, join matchmaking-> join game -> load level. This would destroy every items aside from game instance here, or am I wrong?

obtuse field
#

You won't pass it to server or client from there

obtuse field
#

When player joins, game instance from new client have no effect on the game instance on the server

sinful tree
dark parcel
#

I kept my player name in a save game object. Player join, send server it's save data.

#

I seen epic using game instance to store avatar and player name but that's like, meh

obtuse field
dark parcel
#

Very old tutorial

dark parcel
obtuse field
dark parcel
#

Player may cheat, I can't really stop them at my current level

obtuse field
#

Did you store anything else in this save game object?

dark parcel
#

I will store everything, it will be kinda baldurs gate

#

Player r free to cheat, it's their lost

obtuse field
#

If its by the game design, its ok
👍

undone needle
dark parcel
#

I can't store it somewhere because player may join other people game with the same gears and data

devout sonnet
dark parcel
#

Unless I do some auth with cloud saving etc, but as newbie I rather focus on simple mp game first

obtuse field
undone needle
dark parcel
obtuse field
sinful tree
dark parcel
#

Hard travel destroy most things tho

obtuse field
#

Because I have somewhat bad memory, I misinterpreted my thought

#

You can send data between levels via OpenLevel

#

I'm not sure about player's state tho, how was it done

#

But it wasn't out of the box for sure

dark parcel
#

Hmm there's a function that have old player state output. Not sure if that's for reconnecting player or for server travel

lament flax
#

how can i call onrep on server ?

dark parcel
#

U don't?

#

Unless u r in blueprint

obtuse field
lament flax
#

so you cant even force it ?

obtuse field
dark parcel
#

U don't need to tho?

lament flax
#

the listen server can update itself

dark parcel
#

You are already the server

lament flax
#

UI update is in the OnRep method

dark parcel
#

Can make the change right away

undone needle
#

@obtuse field Sounds good, I'll go double check that myself 😉 Anyway Gtg, see ya!

dark parcel
#

Doing it blueprint way is actually redundant and feel very wrong imo

lament flax
#

thats why im switching to cpp

dark parcel
#

I'm saying about the repnotify part

lament flax
dark parcel
#

For server, make the change right away. For client on rep notify

lament flax
#

so i need to make another function

obtuse field
lament flax
#

i guess this is the way

dark parcel
#

Just call the function?

lament flax
dark parcel
#

Why not, but depend on what you are doing I guess.

lament flax
#

seems weird to call a OnRep_ method

dark parcel
#

That's not what I'm implying tho

#

Wrap what you want to do in a function

#

For client on rep notify, call that function

#

For sever. In the code where you want to call it. Just call the function. Use switch has authority to make sure the code only run on server

#

I think you should break down what data should be send over and how client handles it.

#

Knowing what data goes around in what machine and how each machine handle them simplify the thought process imo.

lament flax
devout sonnet
sinful tree
obtuse field
#

@undone needle

north jacinth
#

If I want to do p2p with server validation, like how some games treat the server as a third player with final authority, while the connection between two players is peer to peer for lower latency, how should I go about it? Would I just use a bunch of RPCs or something? I have the infrastructure to serialize inputs, game state, and rollback if needed Also, is putting server code on a gamemode class the way to go? Any good resources resources to learn more about how server builds work and how the details of how built in replication works?

devout sonnet
obtuse field
sinful tree
# north jacinth If I want to do p2p with server validation, like how some games treat the serve...

There is no P2P in Unreal. Everything is client->server, including listen servers (where one player acts as the host of the game), which means there will always be an authority that is in control of the game. You wouldn't necessarily gain any better latency between clients unless they happen to be closer to each other and on higher speed networks than the server itself - eg. if you had two LAN computers playing, then you could make an argument that they could potentially have better latency between them then the server.

devout sonnet
obtuse field
sinful tree
obtuse field
north jacinth
# obtuse field He can always use TCP connection

That's what I was thinking, actually have that working already with GGPO, but I was wondering if anyone had ideas how I'd do that alongside an unreal server that is allowed to lag behind players but do stuff if serialized game states after rollbacks differ too much.

#

would I just have to code a custom server entirely separate from unreal?

sinful tree
# north jacinth would I just have to code a custom server entirely separate from unreal?

Effectively, yes. Sorry I responded a bit quickly before fully reading the question... Not necessarily, but you wouldn't use most of Unreal's built in systems for handling replication for anything relating to your players or actions they take, but you could use Unreal to simulate what is happening based on the data received and then attempt to manipulate what is happening in the P2P system. You'd have to program how Unreal should be responding to certain events within the P2P system, and have the server simulate it and correct anything based on what it thinks should've happened. What I mean by effectively yes, is that you would be creating something separate from Unreal's own replication system to handle what is happening in the P2P system.

glad robin
#

Ok so I am a little lost with this. I can create and join sessions and all that with a little server browser thing, now I am trying to just get the direct invite/join through Steam matchmaking setup.
Loading the packaged game I can go start a game and invite through steam friends and it pops up on Steam but how do I access that invite? I can see that there is the 'OnSessionInviteReceivedDelegates' which passes the InviteResult but it does not seem to fire ever.

north jacinth
sinful tree
# north jacinth Ah, that makes sense. How would I run certain code on the server asynchronously ...

Online multiplayer is already async. Your copy of the game won't be running exactly as it is on the server, and the server doesn't have to replicate all actors. So for example, you could have actors on the server that represent the client's characters and then have the clients have their own representation of those characters and there doesn't have to be a network pointer between them but then you wouldn't reference them over the network in the standard way. The clients can playback their own version of those actors based on the information in the P2P system and then receive instructions from the server to then set those actors to what the server wants (though the clients could technically ignore it). This is what I mean though - you're basically having to reconstruct how Unreal networking would work to facilitate such a system.

Under normal Unreal networking, the server is normally considered ahead of the clients as it is the authority and most actions that clients performs requires the clients to ask the server to do it, so then the clients are behind until the server replicates the results back to them - so by the time the clients get the data the server would already be however many milliseconds ahead in its own processing. It's when you do client prediction that the clients would be considered ahead of the server, but still they communicate to the server what they are doing and then the server is then "catching up" to them, and correcting if it doesn't like what they are doing.

#

I'm not sure I understand what you mean by async RPCs.

north jacinth
#

I wanted the server to simply lag behind the clients, validating the packets they sent to each other with the same code the clients currently use for simulating "ticks" (not unreal ticks, our own update function)

#

it wouldn't be hard to send the serialized data, but I'm new to this type of networking specifically

sinful tree
#

Unreal kind of doesn't have a lot in terms of client prediction. The character movement component included with the character class has some predicted movement built in, and if you look into the Gameplay Ability System it opens up actions that players can take that are client predicted.

north jacinth
#

only thing I've done before was outside the context of unreal and was just serialization and deserialization

#

so if I ran the function to process an update as a server rpc, would it allow the clients to continue their execution until receiving a response from the server to force a rollback or disconnect if deemed necessary?

#

thank you so much for your time btw

twin juniper
#

Hello, What's the common approach to implementing typical MMO targeting in a multiplayer game? Is client authority with server target validation sufficient? Thanks!

#

or would be better use GAS TargetActors?

#

Additionally, if you could provide some learning resources regarding this topic, it would be greatly appreciated!

sinful tree
# north jacinth so if I ran the function to process an update as a server rpc, would it allow th...

The clients can do whatever they want to do locally and then report things to the server using a replicated actor they own.
You can have the server tell them to do things after the fact if necessary but that doesn't mean that the client has to do it either.
What is important is that the server is the authority, so at the end of the day, it's the server's copy of the game that should be considered the "real" version of the game being played, so if one client continually reports things incorrectly, it would constantly be getting corrected, especially if it didn't do something you told it to do.

I think the hard part here is the reconciliation as you can't use Unreal's own built in systems for movement and prediction for those characters.

north jacinth
sinful tree
north jacinth
sinful tree
# north jacinth server code goes in gamemode, right?

It can technically go anywhere as you're able to differentiate whether you're running on the server or client. Game Mode is something that will only exist on the server, and can be excluded from client builds if your intention is to run dedicated server builds exclusively it can make sense to put it there if you wanted to ensure code specific to the server isn't distributed to clients.

woven basin
#

Check the pins for the network compendium. Start there.

torpid lantern
#

How might I go about replicating a timer?

  • Server actor (bp_forge) does a thing and the server starts a 60s looping timer

Goal: Player opens bp_forge widget and can see a progress bar of that server's timer for that actor

I've tried replicating the Timer Handle, but client is still not able to read it. My thoughts are to instead replicate a "time elapsed" variable, and update it using another timer or tick. Is there a better way to do this?

I figure I'll have maybe 10-30 of these timers going within player cull, and ideally 300+ server-wide.

woven basin
#

And then read pins on how to network sync clocks better.

torpid lantern
#

How would I go about creating a variable for that start time, is that just a "now"?

woven basin
hoary spear
#

Offset by ping but works pretty well

#

The client timer is ofcourse just a 'prediction', server shows up with the final say

dark parcel
#

I tend to think what client see is a mere illusion

hoary spear
#

Yepp

torpid lantern
hoary spear
#

Oh la la

#

Neat!

quasi tide
#

All me baby

gray blade
sinful tree
gray blade
#

@lusty sky

#

if it makes sense for some reason I think the cursor dictates the drop event and not the image

torpid lantern
pallid mesa
sturdy sand
#

yo just want to ask. Do the ue5.4 dedicated servers work on the release or do we have to wait a little?

#

can you run a server for 5.4 game?

tardy fossil
#

yea they work

sturdy sand
#

Ight

undone needle
undone needle
#

Question regarding Player States, since they are replicated to ALL clients, I should absolutely avoid to store any unnescessary data as much as possible right? Example; Let's say a character's gun, I should NOT store the whole gun reference because the mesh is already loaded in the game locally for everyone, instead just the gunId with properties like ammos should be stored on the player state and have the logic to spawn the mesh handled locally by the clients, is my reasoning correct here?

latent heart
#

Why would you store the player's gun on the player state at all? Surely it's on their pawn.

#

Unless it's some sort of persistent inventory?

undone needle
#

Was just a random example to illustrate the point is all

latent heart
#

I'm actually curious how it replicates class references now.

#

However you're right. Replicating as little as possible to maintain the game state is generally best.

#

Just avoid multicasts for anything related to state.

undone needle
#

I try to avoid multicast period ^^
But thanks for the confirmation

latent heart
#

They have a place, tbh. Like a global chat could probably just be multicasts? I guess?

undone needle
#

Depends on the chat, you don't want to multicast to all player if a player doesnt have access to a certain channel in my opinion

latent heart
#

Mutlicasts don't get sent to things which aren't relevant.

#

So manage your relevancy.

#

That includes standard distance relevancy if you're doing it on world objects.

#

But, yeah, it migth just be easier to send single-rpcs to each player than create that whole system.

undone needle
#

Forgot about that for multicasts, but then I feel like a chat is a very bad use of multicasting. Imagine you have a world chat in your chat box but two players are too far away from each others to be relevant, they wouldn't see the other's message then

latent heart
#

Then send the multicasts via gamestate - always relevant.

#

Or the player state, ofc

undone needle
#

Oh, player state only relevant based on net relevancy, game state always relevant

#

gotcha

#

wait, player state is always relevant too?

latent heart
#

Yes

undone needle
#

Why?

#

Men everytime I feel like I start to understand RPCs I get thrown a curved ball

#

I mean, If a player state purpose is to store a player's data and replicate it to everybody all the time, then what's the point here?
I get it for small FPS matchmaking stuff. But like, Imagine you got a huge map. Who cares of what happens to Player X when he's not even close to where you're at?

latent heart
#

That's why player states and player pawns are different things...

undone needle
#

I get that, partly. When I look a UE doc, they state that player state is the perfect place for example a player's health. But what do I care about the health of someone who's not even in my range?

latent heart
#

A UE doc? Which one?

#

It also might just be out of date and not relevant to game design in the last 10 years.

#

Or it's dependent on the type of game you're making.

#

And maybe player health is relevant to you on the other side of the map if you're in a party together.

#

Etc.

maiden flame
#

Yeah, they're not rules, and it will depend what's most suited for your game. As long as you understand the implications of where you store your information, it's all good.

undone needle
#

Well, I mean, it's obvious that I want my player's health in a player's state for server replication. What I don't want is that to be relevant across the whole network. I thought that was the job of Game State

latent heart
#

Then put it on your player's pawn.

maiden flame
#

So the pawn becomes a natural choice.

undone needle
#

And your party example makes sense, but I would assume that the net relevancy changes for people that are in the same party with you

#

Okay so, as long as I never destroy the pawn it will be fine?

latent heart
#

You can have the health on the player state and not replicate it.

#

And then set it on each new pawn as you make them.

undone needle
#

Well, I need to replicate it so that the server knows where his health is at

latent heart
#

What

#

Replication only happens server to client.

#

And you definitely don't want the client having authority of something as important as health.

undone needle
#

Oh okay, I see what you mean

maiden flame
undone needle
#

so, the player state could hold server side only the player's health and not replicate it, and have that player's health on the pawn that takes care of replication and since the pawn is relevant only within range, then only the people close enough would get to know that player's health is what I understand?

latent heart
#

Basically the system I'm suggesting is that the server has health in 2 places - Once on the player state for its own purposes and once on the pawn which is replicated to relevant clients. When you spawn a new pawn, jsut copy the value across. When the health changes on the pawn also back that value up onto the player state.

undone needle
#

Yeah okay got it

latent heart
#

Of course you'd do this by wrapping the health in a setter function so it always gets set on the PS.

undone needle
#

I'll try that, thanks a lot for letting me know that PS is always relevant, that would have been a problem

latent heart
#

Or you could simply transfer the health from one pawn to the next.

#

Or, well, if a pawn is destroyed, isn't the health 0 anyway?

undone needle
#

Yeah obviously

latent heart
#

Unless you switch between pawns.

undone needle
#

Nah the pawn remains at 0 health cause i want his inventory lootable if another player decides to loot him only

#

respawn after a short timer

latent heart
#

So why does the player state even need health?

#

Surely if the player respawns and their corpse is there already, you'd need 2 health values in your original plan?

#

(2 on the player state)

undone needle
#

Nah the original pawn is destroyed upon respawn, so it could technically always be the same, or I could delete the first one on respawn and create a new one on respawn point

#

both ways could work

latent heart
#

So the body is only lootable for a short time? Teh time it takes to respawn?

undone needle
#

yeah exactly

maiden flame
#

For health you don't really need to transfer anything, just a default value on the pawn will do?
As long as health changes are verified server-side.
Idk, seems more simple to me than having it in two places, if not always relevant.

#

Unless it's a mechanic to change pawns and retain the same health or something.

undone needle
#

Yeah thats what I'm realizing, I dont have much informations for my game that requires to always be relevant, most of it happens based upon range

maiden flame
#

Kewl beans

undone needle
#

Aight, thanks a lot to you both, you saved me from a lot of refactoring

visual mountain
#

My Blueprint tabs keep rearranging. Is there a reason for it/ method to prevent it?

tiny pier
#

when opening my server (using -log), it opens then closes instantly

lethal blade
#

Post logs

tiny pier
#

there are none

#

unless they hidden somewhere

vernal shadow
#

Hi, i need a bit guidance with one problem i have in setting up a multiplayer game. I need (and want to) keep some input on the Player Controller, and currently I'm a bit lost. What is the idiomatic way to register input with Enhanced Input Component in MP scenario like this. Latest i got in debugging is that Input Component doesnt exist on any PC (when using Play as Client option), with Play as Listen server just one player has a properly working input. is there any tutorial that i can reference to?

tiny pier
tiny pier
#

ok it's cuz i did shipping not development

sinful tree
# vernal shadow Hi, i need a bit guidance with one problem i have in setting up a multiplayer g...

You may be receiving that error because you're attempting to access the input component on an event that fires on both the client and server and the server's copy of the player controller won't have the input component where the client side would. In blueprints, the below example works just fine for setting up an input component on a player controller.

In C++ I believe it would be set up something like this if you defined IA pointers on your player controller.h

void AYourPlayerController::SetupInputComponent()
{
    Super::SetupInputComponent();

    auto* EnhancedInput{ Cast<UEnhancedInputComponent>(InputComponent) };
    if (IsValid(EnhancedInput))
    {
        EnhancedInput->BindAction(OpenMenuAction, ETriggerEvent::Triggered, this, &ThisClass::Input_OnOpenMenu);
    }
}
lost inlet
#

what's with the meme of the list initializer syntax when an equals sign is perfectly readable

vernal shadow
sinful tree
glad robin
modern cipher
lost inlet
#

I've been seeing it quite a bit recently

latent heart
vital barn
#

I have an event node on the BeginPlay GameState that I want to trigger on both server and client. But for some reason it doesn't trigger on the client unless I put a 3 second delay at the beginning of the node. Why could this be?

kindred widget
#

??? None of that should be triggered on a client anyhow. It's a server RPC

vital barn
#

Ah sorry I should have explained, the last node leads to an actor with a Server-Multicast RPC

#

as I said it works great if I put a delay node but not without it

kindred widget
#

That would be your issue then. It likely hasn't replicated to the client yet. This is also state. State is exceptionally rarely multicast. You should prefer replication. Instead of putting that value on the GameMode. Put it on the GameState with a setter and a delegate and make your objects bind to that and pull from it.

vital barn
#

Alright, I'll read up on delegate and do this. Thank you! ☺️

tiny pier
#

i have created a server using a virtual machine and created a 7777 port. used the "open level" node and pasted in the public IPv4 address, however my player does not get connected to the server/change map. no idea what the issue is

worthy oak
thin stratus
#

You may wanna check the logs of both server and client

#

And see how far either gets

torpid lantern
#

I am wanting to stitch together a series of dedicated servers. I've read the documentation and it looks like I can do this using non-seamless travel.

I'd like to work on this feature without having to package and fully deploy two servers each time I test it.

I've found a command line that looks like it spins up a local server and I'm able to connect to this server in PIE using the Open Level (by Name) node and 127.0.0.1:7777 as the "Level Name".

So, I can hit that command line a second time, it appears to launch a second server process; cool. But how can I get the IP of that second process - and ideally, how can I configure the IP of that second process?

Here's the command line used to start the local dedicated:
"C:\UnrealEngine\Engine\Binaries\Win64\UnrealEditor.exe" "C:\Homestead\Homestead.uproject" GoblinForest -server -log -nosteam

The goal here is to jump between Server A and Server B during a single client session.

thin stratus
#

The port is +1

#

So 7778

torpid lantern
#

Amazing, thank you!

tiny pier
#

nvm i just checked a port checker website apparently it is closed

#

even though i set it to open on virtual machine

tardy fossil
#

oh weird, actor's position and rotation spawned by a server are slightly off on a client.. i wonder if they get compressed or something

torpid lantern
# thin stratus The IP is the same

Follow-up question: I'm wanting to send a payload of data along with the player (attributes, inventory, etc.). I could use a detached web service and pull in that payload after level transfer, I could look at ways to sync the server-side .sav files, but I think it would be easier to use the game instance.

How bad of an idea would it be to store the data on the game instance during the transfer. I'm concerned that an enterprising player might figure out how to inject data during level load.

undone needle
#

an enterprising player will figure out how to inject data one way or another if he's really motivated regardless

lament flax
#

is there any issue replicating a GameplayTag ?

hollow eagle
#

no

thin stratus
#

If you need data between 2+ DedicatedServers and Clients shouldn't be able to cheat, you need to both host the Servers and some Database away from them

kindred widget
torpid lantern
mental star
#

One other question I have. I get using Projectile Motion for something replicated like a ball.
What kind of physics would I want to have per stage?

#

Assume this is an Online Multiplayer Mobile Tennis game. We're planning different courts / types of bounce etc.

glad robin
pearl bear
#

I created a VM on Azure, then run my dedicated server on that machine but when I am trying to connect it via public IP I couldnt do it. Everything works pretty well on my local machine with 0.0.0.0 but not with public IP

#

Should I do anything else than copy my dedicated server exe to machine and run it?

mental star
#

I'm asking about the stages themselves

#

Like different materials give a different bounce

#

So, would I want a court to be just a physics material?

fossil veldt
#

don't if def specifically on clients ect or the tag list will mistmatch on client and server

twin juniper
#

Quick question:

Should I learn networking in general in c++ first, or straight to ue5 multiplayer?

fossil spoke
#

Learn how replication works before trying to do a multiplayer game.

#

Just simply try getting a Door to open and close via Player interaction on multiple Clients.

undone needle
#

Keep in mind that Just the door is very little but is a good starting point. What you need to understand is that there is a lot to know and it can get extremely confusing, and frustrating at times. Good news is, plenty of good documentation and tutorials out there, sink your teeth into that, learn the information and try to apply it in a test project until you have a good grasp on things before starting implementing it in your project.

civic turtle
#

If anybody knows a solution to the 9999ms server ping bug while using steam subsystem please let me know (@ me).

Seems like the bug was set to "Wont Fix" in 2018 for somereason.
https://issues.unrealengine.com/issue/UE-27444

tbh displaying ping is an important part of making a game that uses server lists, its the thing that everyone looks at when picking a server to join. I have no clue why a bug like this is not high priority to fix? Again if you know any alternatives please let me know, I did see elliotek post on the forums about it (https://forums.unrealengine.com/t/steam-session-ping-9999/327245/78) , but he edits read only files which the engine doesn't even compile any of my new changes in for somereason.

Its crazy that this bug has not been fixed ever since 2016.
Similar thing is with the in game active player count being always set to one. Thankfully I managed to update the sessions player count manually using the update session function given by the session interface so thats at least solved. but this one I have no clue on how to solve

somber tundra
#

Hey, can anybody here help me debug my item drop system for MP? I can get pickups working, but havve no clue how to sync up item spawning

maiden flame
queen escarp
#

@civic turtle thats bc u use steam test id..?

maiden flame
sinful tree
# somber tundra Hey, can anybody here help me debug my item drop system for MP? I can get pickup...

If you post some of your code someone should be able to help, but the flow would sort of be something like:
Client Initiates Drop request in some manner (ie. OnDrop of a Widget on to the main canvas) > RPC to Server on client owned actor/component with reference to the item object and/or inventory you're trying to manipulate with any kind of index of the item (never just a refernece to the Item ID) > Server validates object exists in the inventory in question > Server removes object from inventory if player is allowed to remove it > Server spawns replicated actor to represent the dropped item.

civic turtle
# queen escarp <@1010299636545769554> thats bc u use steam test id..?

it could be, but are you 100% sure about that? Im waiting for the steam page to finish reviewing so I can have access to my own app id and use it. But it seems like people in the forums were also getting this error while using their own app id. I guess I will know soon anyways, but from what I read it might be deeper than that

civic turtle
queen escarp
#

Hm ive only heard it from others tbh never tried it myself so not sure tbh

maiden flame
civic turtle
somber tundra
#

I figured out a bit here and there, but I also have a follow-up

#

So, I have an item dropping item system on an item that simulates physics

#

Obvious syncing it between clients sucks donkey dick, and I'd rather have the item not simulate it so it doesn't have to sync

#

However, when I drop the item, I still want to play a small impulse animation, but I can't do that without simulate phyiscs

#

Is there a possible workaround?

queen escarp
#

@civic turtle also do you know in guessing your games uses listen server, is it same ports needed to open on your router ad before ? (After release)

summer tide
#

If I open two multiplayer windows in standalone mode. How do I know which one is server and client?

thin stratus
#

@somber tundra if you just want to yeet the item a bit, put a ProjectileMovementComp on it

#

Or make a second actor just for this that then when it lands spawns the correct item

thin stratus
thin stratus
#

Hm, not sure if the window title would state anything

summer tide
#

it doesn't

thin stratus
#

Probably best to just put some debug UI on the screen

#

You can get the owning player of the widget and check if it had authority

#

And then change some text based on it

summer tide
#

Any console command to check that

thin stratus
#

Don't think so

summer tide
#

ok thanks

pearl bear
pallid mesa
gusty slate
#

Hello everyone,
I am curious what is the best way to replicate an array between clients while I don't care about the order of elements inside it? I basically have a general counter for some accomplished feats that is shared between players (for quests) and I want to properly replicate that so each player's quest log can display the proper numbers

#

would that be a FastTArray?

pallid mesa
#

if you want to do some operations in the client after replication, such as adding something in your UI, Fast array has some very convenient callbacks per member

gusty slate
#

I think I read about them once, they don't guarentee member order yeah? But as it's just counters, I don't really care about that

pallid mesa
#

disregarding performance, fast arrays offer you a very neat amount of QOL features

#

so if you dont care of the order and your data struct has some members that you will use for your quest system, its a good option

gusty slate
#

I see, thank you I think I'll have a look 🙂

pallid mesa
#

now in terms of performance... tarray v fast array - depends on the use case (one might be faster than the other), you can read here in the message history some posts from Jambax explaining how they work more in detail and when to use each

gusty slate
#

It definitely isn't going to be a big array so I don't think that matters to my use case

#

it's more the QOL like you say to properly interact with edits

pallid mesa
#

the name is a bit missleading hahaha, it doesnt mean that the fast array will be always faster 🤣

gusty slate
#

ah I see 😂

pallid mesa
#

but ye take a look, might suit ur purposes

gusty slate
#

PostReplicatedChange Does a change include Add/Remove aswell?

fossil spoke
#

Change relates to an existing element having its members values changed

gusty slate
#

I see, ty 🙂