#multiplayer

1 messages ยท Page 495 of 1

grizzled stirrup
#

Yep, that'll be very nice

#

As CMC is extremely expensive / bloated

#

It works great though

zealous saffron
#

yeah

grizzled stirrup
#

But could be much cheaper for AI etc.

worthy perch
#

Probably new NavSystem too.

chrome bay
#

I don't think the prediction thing will make it much cheaper tbh, they're still only planning to use it for player-controlled stuff

zealous saffron
#

it really should have a PMC then PawnNetworkedComponent -> CMC

chrome bay
#

But it'll make making non-CMC predicted movement a buttload easier

#

As it separates the networking layer from the simulation layer

#

Which is the most important bit

grizzled stirrup
#

Right now it's all intertwined right? Capsule / character / cmc

zealous saffron
#

it's somewhat of a mess

chrome bay
#

It is, but the problem is more that the networking side of CMC is closely tied to the simulation

zealous saffron
#

yep

chrome bay
#

So you can't easily adapt it for something else

#

In the case of my vehicles, I basically rewrote most of CMC's approach - but adapted it to be able to run different simulations

zealous saffron
#

it works fine for a prototype but past that you have to invest in taking the useful networking and simulation into your own class.

grizzled stirrup
#

Interesting. Yeah I have some cases where a capsule doesn't fit the shape of a charater very well and it results in movement not looking / feeling as good as it could

zealous saffron
#

or having a vertical capsule represent a ship ๐Ÿ˜

chrome bay
#

I was using one skeletal mesh component as the root for mine

#

No proxies, just offset the render matrix for smoothing

#

sort of worked

#

But has limitations

sleek current
#

Hey is there a guy who knows how to do things the right way in multiplayer C++ and is willing to help a noob out xd?

fleet raven
#

there are many such people here, that is the point of this channel

grizzled stirrup
#

Better to ask a specific question and people can help out ๐Ÿ™‚

twin juniper
#

how can i debug

#

where the server thinks my pawn is

#

and where the client thinks it is

sleek current
#

@fleet raven Yeah but I have a question about my whole pc class like how to do it right way in C++ for multi ๐Ÿ˜› and I think that it's too much and it would be a spam so I asked if I just could pm someone ๐Ÿ˜›

sleek current
#

Aight so I have a pc that should call on it's players functions related to input in beginplay() I have this line void AFarmTaskPlayerController::BeginPlay()
{
Super::BeginPlay();

Character = dynamic_cast<AFarmTaskCharacter*>(UGameplayStatics::GetPlayerCharacter(this, NetPlayerIndex));

}

#

For every player that has index != 0 it returns null in AFarmTaskCharacter

#

Anyone knows why ><?

fleet raven
#

the character does not exist at that point

#

you should always use Cast not dynamic_cast

sleek current
#

Why?

fleet raven
#

because that's what you use in unreal

#

also looks nicer

#

for the character not existing, check out how the process of joining works in game mode base::login

sleek current
#

It still fires NULL and that's not really a good argument if unreal wouldn't support dynamic cast then he would just remove it from unreal framework

fleet raven
#

it first creates a controller, then later, it will create a character for it, then possess it

sleek current
#

So what methods should I use to make it right?

grizzled stirrup
#

Is it fine to call Server RPCs on the server as regular functions? Instead of having to do

if (Role == ROLE_Authority)
{
   CoolFunction();
}
else
{
   ServerCallCoolFunction(); // calls CoolFunction() on the server
}

I'd instead do:


// Regardless if client or server calling this
ServerCallCoolFunction();

That way I could simply put the contents of CoolFunction into the RPC and save many lines of code

fleet raven
#

yes, calling a server rpc on the server will execute it locally as expected

grizzled stirrup
#

Thanks!

#

Makes life much easier

sleek current
#

So are there methods/variables that tell me when pawn is possessed by a certain controller?

grizzled stirrup
#

OnPossessed() / PossessedBy()

#

Those are called on the controller / character and can be overriden to do things

sleek current
#

void AFarmTaskPlayerController::OnPossess(APawn* InPawn)
{
Character = Cast<AFarmTaskCharacter>(UGameplayStatics::GetPlayerCharacter(this, NetPlayerIndex));
}

#

It doesn't shoot NULL now since I made if that check whether or not character is NULL on every method that calls movement/action on a player

#

But it doesn't spawn my player mesh and the actions only work on server

#

What am I doing wrong?

chrome bay
#

Why not just use the pawn being passed into the function?

#

You can get the pawn directly from the controller, there's no need to go through gameplay statics to get it

sleek current
#

True, did that. But still there is a problem that my mesh is not spawning and the functions dont work on pawn

chrome bay
#

Impossible to say why really without having the code in front of us

sleek current
#

You got in on pm

chrome bay
#

I can't help atm, am working

#

Even so can't go through all your source code ๐Ÿ˜„

grizzled stirrup
#

If you pass a regular FVector into a function that takes const FVector_NetQuantize& will it be correctly quantized or should I remove the &?

thin stratus
#

Looks like you are adjusting speed on only client or server.

sleek current
#

How can I make fpp projectiles replicated so I can see them on each client and server?

#

Tried RPC server, client and multicast and probably did something wrong ><

twin juniper
#

@thin stratus someone said to send the multicast event or the server event on a client replicate and set the location there

#

did i got that right?

thin stratus
#

@sleek current You need mark the projectile replicated and then let the Server spawn it by forwarding the fireweapon stuff via ServerRPC

#

@twin juniper Ehm not sure what exactly you mean :P

#

If someone suggested you something then you should make sure you followed their instructions properly

twin juniper
#

im doing this right now

#

is this okay?

thin stratus
#

Not really

#
  1. You don't need to pass the Component, it exists on each instance anyway.
  2. Where does that call come from? Tick? If so, then you need to have someone be the Authority over this.
sleek current
#

I used server, reliable and the projectile is breplicated true

thin stratus
#

E.g. if the Clien should have Authority (not the greatest idea), then you would need to let the Client send the location via RPC and then let the Server send it via Multicast.

#

BUT

#

You need to make sure that the Multicast is filtered for the owning client

sleek current
#

it only works on server I mean I only see and hear on server

thin stratus
#

Otherwise you override the location again (rpcs take time after all)

twin juniper
#

is there any network sample projects

thin stratus
#

@sleek current Not sure then, this is pretty basic stuff. You might want to go over everything once more.

#

@twin juniper Yeah more or less, but nothing that does this I would guess.

sleek current
#

UFUNCTION(Server, Reliable)
void OnFire();

thin stratus
#

Mostly cause movement is done a bit different

twin juniper
#

im doing movement through physics

#

so instead of replicate physics im replicating the location and rotation

chrome bay
#

It's never going to work if the Server is replicating the positions back to you

#

Networked physics has to be client-authoritative in order to work.

#

Server-auth is pretty much an unsolvable problem

twin juniper
#

im not networking physics cause i did that and it was a big mistake

chrome bay
#

You said you're doing movement through physics

sleek current
#

Alright so I made it work, actually the blueprint needed to change replication(it sucks that c++ even in constructor doesnt change values in already created blueprint) but all thats left is sound, it only plays on server any idea?

chrome bay
#

If the object is simulating physics, it's using the physics engine

twin juniper
#

the physics engine is replicating?

chrome bay
#

No, it doesn't work that way

#

The physics engine is constantly simulating on both machines. By the time the server told you what's happened, it's already too late

#

You will constantly be being snapped back in time when using server-auth

thin stratus
#

@sleek current Well it doesn cause you aren't modifying the BP

#

You are modifying the C++ parent

#

If the Constructor change would adjust all child BPs that would be shitty annoying

twin juniper
#

thats whats happening to the video i guess

#

so what do i do?

chrome bay
#

Use client authority

#

And anti-cheat on the server

twin juniper
#

is there any tutorial for client authority

chrome bay
#

Tell the server what the physics state of the object is, set the server to that then replicate it

#

No

#

Well, not that I know of

thin stratus
#

@twin juniper

  1. Send Location and Rotation from Client to Server via ServerRPC.
  2. In the ServerRPC, send a Multicast to everyone from the Server with the Location and Rotation.
  3. In the Multicast, make sure you filter the owning client "IsLocallyControlled == false" and apply the Rotation and Location.
#

That would be the most straight forward way to do it

#

Not the nicest but heeeyyyy

#

That has 0 smoothin though

sleek current
#

@thin stratus What should I do to replicate the USoundBase? I did Replicated in UPROPERTY but it only works on server ><

thin stratus
#

So if it gets laggy, the server/other clients well have a dia show

#

@sleek current You need to Multicast when you fire

#

And in the multicast play the sound

twin juniper
#

In the Multicast, make sure you filter the owning client "IsLocallyControlled == false" and apply the Rotation and Location.

thin stratus
#

Or, if you follow along something like ShooterGame, you could increment a RepNotify Integer

twin juniper
#

oh okay i get it

thin stratus
#

And if that integer is > 0, play sound

#

And if it's == 0, stop playing sound

#

@twin juniper Yeah otherwise you tell the original client an old position -> snap back

chrome bay
#

One day I'll make a video on this

#

I must explain it at least three times a week ๐Ÿ˜„

twin juniper
#

this right

sleek current
#

@thin stratus so basically I need to create another method that is multicast and it only plays sound right?

twin juniper
#

u said server rpc

thin stratus
#

Yeah VFX SFX etc.

#

@twin juniper

OnTick, call "Re(Server)" IF "IsLocal" is true.

#

Re(Call) can be removed

twin juniper
#

alright

#

did that

#

is this right tho

thin stratus
#

Technically, if I'm not too tired, yeah

sleek current
#

Oh my god thanks multi bible man โค

#

If I want to create an interaction interface with interaction component do I need to setup replication on this as well or it will handle itself if its parent is replicated?

thin stratus
#

Interfaces have no sense of replication I would guess

#

So if you interact with something via an "Interact" function from an interface, then this should already be called on the Server and Client, so replication should happen before calling the interface

winged badger
#

its worth noting that if you try replicating a TScriptInterface

#

it will just silently fail, won't even toss a warning

sleek current
#

Thanks

shy nymph
#

hey everyone, how do i get the replicated username on the dedicated server side?

winged badger
#

you RPC it over

shy nymph
#

i have my own palyer state with an blueprint exposed function where i use the unreal internal "SetPlayerName"

#

on the client it shows correctly but the server always prints the original name

winged badger
#

as i said, you need to send it via the RPC

zealous saffron
#

I assume you are calling it on the client

shy nymph
#

but whats the point of the replicated player state and username

winged badger
#

replication flows only server to client

#

once the server has it, other clients will get it

zealous saffron
#

UE4 doesnt do p2p networking

winged badger
#

but only way for client to push data to server is a RPC

zealous saffron
#

^

shy nymph
#

ohhh that makes sense, of course like any other replication u4 tutorial ever xD damn

#

sry couldn connect the dots with c++

winged badger
#
UFUNCTION(Server, Reliable, WithValidation) void ServerSetPlayerName(const FString& InName);

bool APS_ValetPlayerState::ServerSerPlayerName_Validate(const FString& InName)
{
    return true;
}
void APS_ValetPlayerState::ServerSetPlayerName_Implementation(const FString& InName)
{
    SetUserPlayerName(InName);
}
#

should do it

shy nymph
#

can i make this one "BlueprintCallable" as well?

zealous saffron
#

Yes

winged badger
#

then you just call ServerSetPlayerName from SetUserPlayerName if the Role is not authority

#

or better yet, if (Cast<APlayerController>(GetOwner())->IsLocalPlayerController())

shy nymph
#

Why "_Implementation" and "_validation"

#

since Visual assist creates them automatically as well but when building since they are not in the header visual studio says they are not declared

winged badger
#

_Validate, not _validation

shy nymph
#

yes _validate sry

winged badger
#

if that one returns false, client that sent the RPC gets kicked

#

also a good place to implement some anti-cheating checks

shy nymph
#

but i cant build it since "ServerSetPlayerName_Implementation" and "ServerSetPlayerName_Validate" are not declare functions

#

only "ServerSetPlayerName"

#

i assume its correct and neccesary but its not building

#

oh nbm

#

nvm

winged badger
#

ignore intellisense

shy nymph
#

yea i figured xD

#

i hate that xD

fluid flower
#

I think I read in 4.23 you won't need the Validate by default anymore

shy nymph
#

@winged badger could you explain a bit more what you meant by good place to implement anti cheating or provide any ressource i would like to know more about that

winged badger
#

a real-life example, a battle royale type game, FPS

#

they wanted the gunplay to feel responsive

#

so they gave the authority over hits to the client

sleek current
#

Also guys what is the right way to handle player input in player controller in multiplayer?

#

Like what RPC, properties to use etc

winged badger
#

few days after release, a hack appeared that was teleporting other players when the cheater fires, forehead in front of the muzzle

#

validate function eas then made to check if server believes that hit was possible

#

and if it doesn't kick + ban

shy nymph
#

oh that makes sense, so since the server has authority the players would only be teleported on the cheating client right? and the server checks the position on the hit player on the cheating client and their actual position

#

@sleek current i think the playermovementcomponent handles all of that

#

thanks btw works like a charm now

winged badger
#

very much depends on the game

#

i prefer to avoid clutter whenever possible

#

so if i have a large amount of related replicated inputs, they'll typically end up in an ActorComponent on the PC

#

for example

high current
#

Is there a way to do global game text chat, whitout having a dedicated server or a database

#

also, how is the gameDNA firebase plugin, as I have that from a mega jam, but never used it

winged badger
#

steam lobbies can do it to an extent

#

our first game made a steam lobby for every 500 users i think, wasn't really a global chat, but it was busy enough

high current
#

haha, using beacons or?

winged badger
#

no

#

just steam lobbies

high current
#

And is there anything fancy I need to consider for chat

#

or just rpcing strings

winged badger
#

its not using unreal network

#

steam lobby

#

it can send text messages and it can set per user data (also limited to strings)

#

that's it

high current
#

I have yet to familiarize myself with the steam docs

winged badger
#

with something like UWorks at hand you can put that together in one afternoon

#

in BP

high current
#

Yeah, it is a uni project so we have to manually implement everything

#

so this derives from the matchmaking part of steam or?

winged badger
#

if you have access to it tho, just quick prototype with uworks will cut your digging thru Steam API to 20% the pain

#

i think so

high current
#

oh wait that is a plugin and not an official thing

winged badger
#

it was ages since i touched that stuff

#

yeah, but its not free

high current
#

no longer using steam?

winged badger
#

no, Kaos volunteered last time ๐Ÿ˜„

high current
#

๐Ÿ˜„

#

damn uworks is 132 euros

winged badger
#

advanced sessions might have something

#

but i don't think they do

#

all in all its not overly complicated

#

when user connects (hits multiplayer)

#

if no lobby with less then N members can be found

#

his game creates one

#

and people coming after just find it and join it

#

few callbacks for chat messages received and functions to send them

#

also, SetLobbyMemberData and callbacks to others changing theirs (like username)

#

and you get a free, quick and dirty "global" chat that works

high current
#

Yeah, sounds fun, altho since I have that firebase database thing, might try making use of that

#

IDK, we are still in the concepting phase, so for now it is mainly doing research prototypes, suggesting methodologies to use during production

full saddle
#

Question, widgets. I have a player tag and the color of the name displayed is binded to player's state "color name" variable. When i change the value of color name it only gets updated on local client. Why is this? Is it that the changes made to player state values dont replicate to server?

high current
#

is the color name variable replicated

#

and where are you changing that variable on the client

meager spade
#

you have to tell the server the new value

#

to replicate out

#

client changing value wont change it on the server, and only server can replicate properties

full saddle
#

Seems like when i change it straight up from the Char BP it replicates properly and when i do it from some other widget it only happens locally.

#

I knew i had it set up correctly, the logic seemed right for it not to work. This is some weird behavior coming from widgets tho.

high current
#

Replication only works if the proper chain of ownership is followed

sleek current
#

Hey, I am setting my light switch by interaction and I want it to work both on client and server at the same time as well for late join players

#

How do I set the RPC's?

#

Right now I tried Server and netmulticast, Reliable for the method that sets light on/off but server worked only on server as suspected >< and net multicast doesnt replicate to other machines.

zealous saffron
#

multicasts have to be called on a server to run on the server and all clients. You should use an OnRep() function for turning on and off the light rather than a multicast.

meager spade
#

@sleek current check the Blueprint Example in the learn tab of UE4 Launcher, it has a map showing about replication and OnRep vs RPC

#

RPC's are for one time events, which doesnt matter if a later joiner comes in, etc.

#

Replicated properties using OnRep is for things like "State, etc"

sleek current
#

What's the name of the example?

zealous saffron
#

OnRep is used for locally dependent values changing based off of a replication event.

meager spade
#

so a IsLightOn bool would would be a replicated bool with RepNotify (ReplicatedUsing in c++), which basically ensures every client see the light on/off

sleek current
#

And how should I actually write it in code?

meager spade
#

c++?

sleek current
#

yes

meager spade
#
UFUNCTION() void OnRep_bLightSwitchedOn();
UFUNCTION(Server, Reliable, WithValidation) void ServerSwitchLight(bool bSwitchOn);```
#

something like that

#

client would call ServerSwitchLight

#

with either on or off

#

Server would set bLightSwitchedOn which would call OnRep_bLightSwitchedOn on all clients

#

then clients can set the light according to bLightSwitchedOn

#

if its a listen server, then server would need to call OnRep_bLightSwitchedOn itself or some function so the host also gets the light state set

zealous saffron
#

OnRep() will not run on the server fyi, so a good practice is to have a server RPC function that changes the value ServerSetLightSwitchedOn(const bool NewValue)

meager spade
#

no point sending const bool

zealous saffron
#

which contains what needs to be run on the server (turning the light off) and the OnRep() call.

#

really only used for listen based servers, if it's a dedicated server you wouldn't need this setup.

sleek current
#

Sorry but for me it's too late to think. What do I change here?

#

Too much information ><

meager spade
#

urgh whats with the const bool

#

bad programming practice ๐Ÿ˜„

sleek current
#

What's wrong with that?

meager spade
#

it doesnt need to be const

#

primitives in functions doesnt matter, if the function changes the variable its on the function. but its not needed

#

const on references sure, like const FVector& SomeVector

#

as changing that could lead to undesirable behaviour

zealous saffron
#

wouldn't say it's bad programming practice

meager spade
#

its pointless and un-needed

#

but ๐Ÿคท ๐Ÿ˜„

sleek current
#

What ever imo it depends on the application

#

but what to do to make this lamp work on each machine XD?

meager spade
#

i already explained it

#

have a server function set a bool, which is replicated

sleek current
#

Sorry but it's too late for me to think for myself ๐Ÿ™‚

meager spade
#

quickly types out a prototype, give me a sec

zealous saffron
#

ensures the value won't be changed, fairly sure it's also per epic's coding standard.

#

Yeah, it is.

meager spade
#

its not

#

you wont see them use const bool for primitives

#

in function calls

#

same as const int32, etc

#

check all there functions

zealous saffron
meager spade
#

i am familiar with them, been using UE4 for 3 years now

#

also have 20+ years programming experience

zealous saffron
#

it says exactly that.

meager spade
#

point me to the exact bit

zealous saffron
#

Example:

void AddSomeThings(const int32 Count);

void AddSomeThings(const int32 Count)
{
    const int32 CountPlusOne = Count + 1;
    // Neither Count nor CountPlusOne can be changed during the body of the function
}

One exception to this is pass-by-value parameters, which will ultimately be moved into a container (see "Move semantics"), but this should be rare.

meager spade
#

i never see that in the engine code

sleek current
#

So I do have the server function to set the light based on bool

zealous saffron
#

I see it a fair amount

sleek current
#

And clients have no connection or what ever to use it ๐Ÿ™‚

meager spade
#

and seems pointless, but like i said, i am not arguing over it just stating that is it pointless.

#

it will only affect that function call anyway, if the function changes it, its on the function

#

it won't affect anything else

#

pointers/references, etc then sure, i use const to ensure they are not modified by the function

zealous saffron
#

would disagree again, but to each his own, I can understand why you might see it as pointless. I'd use it to ensure that it wouldn't be changed by accident, also easier to read and grasp the point of the parameter.

#

Definitely would use it in the above case

#

that you said

meager spade
#

thing is they put it in the coding standards

#

to use const on pass by values

#

two functions here don't use them, and they dont get modified in the function

#

so ๐Ÿคท

sleek current
#

ahh

#

bible guys

meager spade
#

@sleek current give me two secs

sleek current
#

halp

#

โค

meager spade
#

so do you have a interaction component?

#

or something to interact with the actors in the level?

sleek current
#

yes

#

interaction interface and component are created

#

both work

meager spade
#

and this is on the player or has a route to the player controller

#

so when you interact with lamp

#

it tells the server you have interacted, and runs a function on the lamp right?

sleek current
#

pc calls pawn, pawn calls component when interact

#

basically yes but only on server machine ๐Ÿ˜›

meager spade
#

so its a Server RPC from the client

sleek current
#

component and interface have no replciation/rpc

grizzled stirrup
#

Has anyone experienced lagging out of PIE / standalone PIE games as a client when run dedicated server is checked?

#

It's really strange, it's as if you lost connection but any character movement components continue to extrapolate. It just lags out infinitely at a random point when playing

#

Actually just saw this in the logs: LogNetPlayerMovement: Warning: CreateSavedMove: Hit limit of 96 saved moves (timing out or very bad ping?)

#

But I don't recall changing anything to do with the CMC lately

old hamlet
#

i just need help with child actors

#

i have made a gun template that has multiple parameters that allows me to create a child actor that then could have different setting and have multiple weapons just by creating these child actors then setting them up
My issue is that i have 2 weapons and they are both child actors from the same parent , and so it gets confused and it messes up the functionality of both guns or shoots both together

gusty lily
#

@grizzled stirrup do stat net and check for saturated connections. proabbly over the limit, when this happens to me client connections get very buggy including not being able to move (can't send move info to server i guess), and not having items load in a level. You might need to raise certain bandwidth limits but as per my above post, i'm not sure.

#

you may have made changs to your game that blew out bandwidth

worthy perch
#

What would you guys say is the (reasonable) maximum for number of projectiles and characters in a networked game at a time?

grand kestrel
#

@worthy perch Depends heavily on whether you're pooling the projectiles or not

#

Also on your tick rate

#

Fortnite gets 100 players at shit tier 30hz tick rate who fire projectiles, but IIRC epic has high frequency low core servers

#

What you actually accomplish depends on you and the server

#

Expect to hit your limit at around 40 with ~60-80hz running on google cloud, with decent optimization

#

Gotta know what you're doing

#

Then again, Bluehole never knew what they were doing and still made PUBG with higher player count, so maybe I'm wrong

#

But it's all client-side

#

So they get lots of hackers

worthy perch
#

Thanks, Vaei.
And no, I am not pooling anything. I was vaguely told that it was too difficult and never really pursued it.
I am also relying on listen servers, which makes things weird in terms of performance boundaries.

grand kestrel
#

@worthy perch If you're using projectiles for everything you'll need to, because automatic weapons will tank the performance

#

Pooling isn't easy or fun, I've done it both for a physically simulated foliage system and projectiles so far, it's a fair bit of work ironing out the issues, UE4 really isn't built for it

#

Multiplayer makes it a lot harder, but its doable

#

The better compromise is to use hitscan for automatic weapons and projectiles for snipers, rockets, and so forth

#

Even with hitscan you can fake travel time

#

And bullet drop

worthy perch
#

The better compromise is to use hitscan for automatic weapons and projectiles for snipers, rockets, and so forth
Yeah, I had settled with this. And melee weapons.

mighty rover
#

So I think I've hit a wall in my understanding of replication. I have working gameplay for my game in a dedicated server environment. The pawn has an RPC event that runs once they log into the server, to spawn a new object attached to this pawn. Each player can see the movement of each other's objects accurately; however, this object has a texture parameter that is supposed to change the texture (via dynamic material) displayed on it. This texture is not being set onto the replicated pawn object. I can see from the dedicated server, via server print string that both pawns custom texture information is correct, it just won't change on the object. Any pointers? Thanks in advance. Here's a screenshot of game of both screens (don't mind FPS, right screen has focus lol). And signed in as the same login, so both names are the same, but repliation on UI is working as well.

slender yarrow
#

textures and materials usually have to be updated with rep notify or multicast from what ive learned

mighty rover
#

Both material and texture are replicated within rep notify's of the object blueprint. Then I set each variable after login from the pawn via reference, after the object is spawned within the pawn blueprint.

#

To eliminate material mismatch issues though, I set the default material as the material instance, and don't really do anything with it. Just update the texture parameter within the texture repnotify function

slender yarrow
#

also. If a rep notify variable doesnt change the function doesnt get called I believe. Maybe make sure 100% the repy notify value is changing when this event is fired

mighty rover
#

Thanks. I'll keep at it and try to get some more functional testing done

winged badger
#

@mighty rover unless that new object requires specific information from the client, its more elegant to just spawn it in HandleStartingNewPlayer in GM

#

did you create the Dynamic Material Instance both client and server side?

mighty rover
#

@winged badger - I'm only creating it within the repnotify of the object blueprint

#

the process of how it gets to that point is: Player logins into DS -> Pawn spawns -> RPC Event called within Pawn that spawns BP_Hitter -> Set BP_HitterRef -> BP_HitterRef -> Set Texture node.

winged badger
#

you create DIM

#

you don't assign it as material to the Mesh

#

there

#

you also need to create it only once

main spindle
#

I also want help but I don't want to interrupt ๐Ÿ˜„

winged badger
#

BeginPlay works, or GetMaterialInstance function that returns the MaterialInstance variable if its valid, if not creates one, assigns it to materials, and return it

mighty rover
#

@main spindle nah join in the fun lol

winged badger
#

if you put the texture ref as expose on spawn

#

then texture will be set before BeginPlay, both on server and client

#

assuming you provide a valid one server side when you spawn it

mighty rover
#

Ok, let me give that a try. Yeah, a valid one is present prior to spawning BP_Hitter

winged badger
#

you still need to SetMaterial

#

in any case

#

also needs to be done just once, if DIM is not recreated all the time

mighty rover
thin stratus
#

The CreateDynamicMaterialInstance function of a StaticMesh creates and sets the variable.

#

If you get the Material and cast it to DynMatInst then you can check if that's already set.

#

But your solution also works of course

flint belfry
#

Hey guys, Im working on a Multiplayer VR game for oculus quest, I have both quests connecting to a server hosted on my pc but the motion controllers arent replicating, have tried using different kinds of events, any help would be appriciated?

thin stratus
#

What are you doing to replicate them?

#

Cause they aren't by default iirc.

flint belfry
#

atm i have two spheres that im setting the world location the same as the motion controllers using a has authority node if it has authority i am using a multicast event and if its a remote im running it on server

mighty rover
#

@winged badger - almost fully working. Except the same texture is being applied to both player's objects, even though they should be different. But I'm in a much better position to solve this issue now than I was before, so thank you ๐Ÿ‘Œ at least the texture is changing now. Stoked!

summer nova
#

pooling being hard... what?

#

pooling is generally considerably trivial for stuff like projectiles

#

also, both fortnite and pubg are much, much worse optimized than they could be

#

AND they run 3 matches on 1 core of their servers

#

(overlapped, so when one match is ending, another one is starting)

#

if you know what you are doing

#

completely ignore the character movement

#

and use proper patterns and replication graph

#

im confident you can do MMO scale

#

300 players in 1 server should be doable if its planned from minute 1

#

if we were to fully rebuild PUBG from scratch, focused on scalability, we could do a battle royale with 300 players in one map at better perf than current PUBG

high current
#

@winged badger you suggested the global chat with the steam lobbies thing right

#

but that doesn't account for the fact that the host of the lobby might disconnect, so you have to select a new host and so on

winged badger
#

nope, steam will do that under the hood

high current
#

or perhaps I am not familiar with steam lobbies enough yet

winged badger
#

and you don't provide an interface for that player to be able to kick lobby members and such, or inform them they are lobby leader

high current
#

yeah, but dont these things require level loading

#

or does steam lobbies work outside levels

winged badger
#

its not a connection using unreal at all

high current
#

like beacons do

#

aah

#

ok

thin stratus
#

Beacons are also not required to use Steam

#

You have to draw a big line between Session/Lobby and whatever UE4 does.

#

You can for example create a Session and not open a new Level with ?listen.
That totally works, but connecting then (which then is UE4 again) will of course fail.

high current
#

Ok so then what are the benefits of opening a session and not a level afterwards, if UE4 will fail

thin stratus
#

There is none, just making sure you are aware that it would work.

#

They are not tied to each other.

#

Sessions only hold information.

#

@high current

#

Is there a general "flow" of error messages when having disconnects etc.?
I know we have HandleTravelError and HandleConnectionError or so in the GameInstance.
I also know that there is a function to remove a client with a given message (e.g. at the end of the match to send them home or to kick them).
I'm trying to figure out a way to pipe all of that throug hthe same code to show some dialog in the mainMenu

#

Currently thinking a GI Subsystem for handling these messages might be good. Then I can listen to the Travel and Connection stuff and also give it a public function to pass in a custom message.

#

Could hold them in a queue in case multiple ones happen

#

Also how valid is it to listen to the PostLoadMapWithWorld and checking if the current level is e.g. Level_MainMenu?

#

Because I only need to trigger emptying the queue of errors when the player is in the mainMenu

fleet raven
#

I just stored all these errors on the game instance (set LastXXError properties and otherwise ignore the callback) then in the main menu hud I check if they're set and decide to show a dialog or not

thin stratus
#

Right, so that's pretty much what I planned for.

#

Not sure what LastXXError means though

fleet raven
#

well there are multiple

#

LastTravelError, LastNetworkError, etc

thin stratus
#

I would just always check if the queue is empty and if not start showing it one by one.

fleet raven
#

I suppose you could also just have a queue of general errors

thin stratus
#

Ah so you hold multiple queues for each type?

fleet raven
#

there's never more than one of these so it's not necessary to have a queue, just whether an error occured or not

thin stratus
#

Iirc the ConnectionLost error already comes with two different ones

#

My LobbyKit always returns two things, ConnectionLost and some generic "Error" shizzle

fleet raven
#

hm

#

I don't use any online subsystem stuff so maybe they add more

thin stratus
#

Right, so you just have one signle LastNetworkError and LastTravelError

#

And you check if they are set or not

#

And they display them

fleet raven
#

yeah

thin stratus
#

Are you using the same system for things like "You were kicked!"?

#

(or would you if you would have a kick feature)

fleet raven
#

I haven't actually set that up yet, it just shows "connection lost" br_big_brain

#

wanted to do that eventually

thin stratus
#

Oh, how are you kicking them? :D

fleet raven
#

just destroying the player controller

thin stratus
#

Right that would probably end up being connection lost

fleet raven
#

there doesn't seem to be a real builtin "kick with message" function

thin stratus
#

There is but it does the same

#
bool AGameSession::KickPlayer(APlayerController* KickedPlayer, const FText& KickReason)
{
    // Do not kick logged admins
    if (KickedPlayer != NULL && Cast<UNetConnection>(KickedPlayer->Player) != NULL)
    {
        if (KickedPlayer->GetPawn() != NULL)
        {
            KickedPlayer->GetPawn()->Destroy();
        }

        KickedPlayer->ClientWasKicked(KickReason);

        if (KickedPlayer != NULL)
        {
            KickedPlayer->Destroy();
        }

        return true;
    }
    return false;
}

fleet raven
#

yeah I found that but I am confused how it works

thin stratus
#
void APlayerController::ClientWasKicked_Implementation(const FText& KickReason)
{
}
#

Probably the same way

fleet raven
#

if destroy is supposed to terminate the connection how would the rpc ever be received

thin stratus
#

They send a last RPC

#

And then kill the controller

#

I guess the Destroy of a PlayerController checks pending RPCs?

#

As we all know that Destroy isn't directly deleting

fleet raven
#

destroying the player controller by itself doesn't actually do jack

#

somewhere the connection checks whether it still exists

thin stratus
#

UWorld destroys

#

And that checks DestroyNetworkActorHandled

#
bool APlayerController::DestroyNetworkActorHandled()
{
    UNetConnection* C = Cast<UNetConnection>(Player);
    if (C)
    {
        if (C->Channels[0] && C->State != USOCK_Closed)
        {
            C->bPendingDestroy = true;
            C->Channels[0]->Close(EChannelCloseReason::Destroyed);
        }
        return true;
    }

    return false;
}
#

Which does this

fleet raven
#

oh

thin stratus
#

Now I don't know enough about connections

#

To know if that would allow the rpc to still happen

fleet raven
#

this is highly sketchy

thin stratus
#

It does stop the actor from actively being destroyed

#

Cause that early exists the destroy function of the world

#

I noticed that last time I treid to destroy a fake playerController that we used in Party Beacons to have voice

high current
#

Ill try to do the steam chat thing with the Advanced Sessions plugin, if not I guess I have to expose a bunch of stuff from c++, right?

thin stratus
#
        if (ThisActor->DestroyNetworkActorHandled())
        {
            // Network actor short circuited the destroy (network will cleanup properly)
            // Don't destroy PlayerControllers and BeaconClients
            return false;
        }

fleet raven
#

I love how backwards the function name is

thin stratus
#

Yeah :D

#

Either way, it's a bit weird that they would just destroy the PC to remove them

#

I would have guessed they send them back to the original level

#

similar to connection lost

#

Cause why would a kick want to trigger ConnectionLost

#

So one would need to save that the player was kicked, to make sure they don't show ConnectionLost

fleet raven
#

because it needs to actively cut the connection so players can't keep lingering around

#

if you told them to travel they could just not

thin stratus
#

Yeah sure, but send them home before that? The ClientRPC could just open the last level

#

If you leave a game you also just call OpenLevel MainMenu

#

I never actively destroyed the PC

#

But maybe I'm wrong there

fleet raven
#

yeah I am also doing open level mainmenu when the client disconnects itself

#

I'm just concerned that this rpc might not be guaranteed to arrive

#

say if the packet is dropped

#

does it wait with destroying the connection until it has been resent on the actor channel?

thin stratus
#

I honestly don't know

#

I do see that the UConnection checks if it's PendingDestroy

#

And doesn't trigger the ConnectionTimeout then

#

So technically that shouldn't show up (ConnectionLost)

#

Ah actually ConnectionTimeout != ConnectionLost, nvm me

#
bool AUTGameSessionNonRanked::KickPlayer(APlayerController* KickedPlayer, const FText& KickReason)
{
    // Do not kick logged admins
    if (KickedPlayer != NULL && Cast<UNetConnection>(KickedPlayer->Player) != NULL)
    {
        APlayerState* PS = KickedPlayer->PlayerState;
        if (PS)
        {
            if (UTBaseGameMode && UTBaseGameMode->IsGameInstanceServer())
            {
                UUTGameEngine* UTGameEngine = Cast<UUTGameEngine>(GEngine);
                if (UTGameEngine)
                {
                    UTGameEngine->InstanceBannedUsers.Add(FBanInfo(PS->PlayerName, PS->UniqueId.ToString()));
                }
            }
        }
        AUTBasePlayerController* KickedBasePlayer = Cast<AUTBasePlayerController>(KickedPlayer);
        if (KickedBasePlayer != nullptr)
        {
            KickedBasePlayer->GuaranteedKick(KickReason, true);
        }
        return true;
    }
    else
    {
        return false;
    }
}

#

That's what UT does

#

Let's check GuaranteedKick, shall we

fleet raven
#

ye

thin stratus
#

Aha

void AUTBasePlayerController::GuaranteedKick( const FText& KickReason, bool bKickToHubIfPossible)
{
    if (!AuthKickHandle.IsValid())
    {

        if (bKickToHubIfPossible)
        {
            ClientReturnToLobby(true,false);
        }
        else
        {
            ClientWasKicked(KickReason);
        }

        GetWorldTimerManager().SetTimer(AuthKickHandle, this, &AUTBasePlayerController::TimedKick, 1.0f, false);
    }
}

void AUTBasePlayerController::TimedKick()
{
    Destroy();
}
#

They delay it by a second

#

Sneaky

fleet raven
#

what does client return to lobby do?

thin stratus
#

One sec

#

First, here is the kick one

#
void AUTBasePlayerController::ClientWasKicked_Implementation(const FText& KickReason)
{
    ULocalPlayer* UTLocalPlayer = Cast<ULocalPlayer>(Player);
    if (UTLocalPlayer != nullptr)
    {
        UUTGameViewportClient* ViewportClient = Cast<UUTGameViewportClient>(UTLocalPlayer->ViewportClient);
        if (ViewportClient != nullptr)
        {
            ViewportClient->KickReason = KickReason;
        }
    }

    UPartyContext* PartyContext = Cast<UPartyContext>(UBlueprintContextLibrary::GetContext(GetWorld(), UPartyContext::StaticClass()));
    if (PartyContext)
    {
        if (PartyContext->GetPartySize() > 1)
        {
            PartyContext->LeaveParty();
        }
    }
}
#
void AUTBasePlayerController::ClientReturnToLobby_Implementation(bool bKicked, bool bIdle)
{
    UUTLocalPlayer* LP = Cast<UUTLocalPlayer>(Player);
    if (LP)
    {
        LP->LastRankedMatchSessionId.Empty();
        LP->LastRankedMatchPlayerId.Empty();
        LP->LastRankedMatchTimeString.Empty();
        LP->SaveConfig();
    }

    if (bKicked)
    {
        ClientWasKicked(bIdle ? NSLOCTEXT("General", "IdleKick", "You were kicked for being idle.") : NSLOCTEXT("General", "HostKick", "You were kicked by the host or admin.") );
    }

    AUTGameState* GameState = GetWorld()->GetGameState<AUTGameState>();
    if (LP && !LP->ReturnDestinationGuidString.IsEmpty())
    {
        ConnectToServerViaGUID(LP->ReturnDestinationGuidString, false);
    }
    else
    {
        ConsoleCommand("Disconnect");
    }
}
#

And that's the return one

fleet raven
#

so they just dump it on the viewport client instead of the game instance, but otherwise same thing

thin stratus
#

Right but they call Disconnect

fleet raven
#

but only for return to hub, not the other kick br_thinking

thin stratus
#

I love the totally unneeded GameState

fleet raven
#

I wonder if the compiler is able to remove that

thin stratus
#

They never use the function without ToHub being true

#

So you can probably ignore the false case

fleet raven
#

extra br_big_brain

thin stratus
#

We might need it.

#

So they also use ClientReturnToLobby when checking if a player idles

#

Which is fair

#

End from GameMode when calling SendEveryoneBackToLobby

#

Means they always just disconnect the player or send them to that Destination string

#

But that DestinationGUID stuff is UT specific

#

So yeah, disconnecting seems to need the delay for the RPC.
They do use Disconnect instead of OpenLevel(MainMenu).

#

And the rest seems the same.

fleet raven
#

waiting a second is extremely sketchy

#

what if the client was lagging?

thin stratus
#

Yeah idk tbh, guess you would see connection lost

#

Still don't get why the server can't kill the PlayerController after the player securely left

#

Why does it have to be based on the initial kick call

#

I mean if I disconnect it also cleans up the playerController

#

So why even bothering destroying it by hand

ivory portal
#

PostSeamlessTravel <--- Is only called on the server side?

grizzled stirrup
#

@gusty lily Re your reply about me lagging out of a PIE game as a client: the network definitely wasn't saturated at the times I lagged out, and even so I have greatly increased all of the bandwidth caps. I have tested on packaged builds and the issue doesn't seem to occur so it may be a bug with playing standalone as a client with a dedicated server instance, or some other rare bug that I didn't trigger on my more recent tests. It may well be due to some high fps related problem too as I set t.MaxFPS 500 on begin play

sleek current
#

Where do I write my widget show and hide methods in multi so only a player that shouldsee it will see it?

#

Because in most cases I found ppl use GetFirstPlayerController and that doesnt work for me. I have a press button to interact, and I have no idea which class to use for it to make it right or atleast work.

grizzled stirrup
#

@sleek current Use the HUD class

#

It's clientside

sleek current
#

Already done

#

But then I have a interaction component

#

That tells the pawn whether or not he has anything to interact

#

And I want to call there the ShowPressButtonWIdget() and hide methods

#

But goddamn I odnt know how to do it so it will work for multi

#

In single I would just create a pointer to HUD inside component to first player controller HUD

#

but here I have no idea how to do it in multi :C

sleek current
#

HUD = Cast<AFarmHUD>(GetOwner()->GetNetOwningPlayer()->PlayerController); it all goes to this line. Anyone knows how to get from a actor component of a pawn class it's pawn(owner) player controller?

grizzled stirrup
#

@sleek current You should never really be using those GetFirstPlayerController / character methods

#

I usually communicate things through the PlayerController to the HUD

sleek current
#

But how do you do it if it's press button to interact

grizzled stirrup
#

So get a reference to the PC and if it's on the server you can do a client RPC down to make the client show the HUD. If it's clientside then no need for a client RPC and you can call it directly

sleek current
#

So pointer to pc in HUD, but still how do I get the value to actually get it?

grizzled stirrup
#

No pointer to PC in interaction component

#

PC calls function which gets the HUD and calls the function on it

#

So PC is basically the messenger from external classes and HUD does all the clientside show / hide etc.

sleek current
#

alright

#

so

#

PC pointer in component

#

But still how do I tell the pointer which memory address he should be?

grizzled stirrup
#

Well it depends on how you have set up your interaction component

#

I'm assuming you interact from a character?

#

So the character could provide the PC reference

#

If your character implements the interaction component then you can get a reference to the owner / owning controller etc.

#

If your interaction component is on the actual interactables in the world then you can pass the Character / controller reference on interacting if needs be

#

I poll for the best nearby interactable actor two times a second in my character, if there is one, BestInteractable gets set which is a pointer to my interactable actor type

#

then if the player hits the interact key I run this

#
if (BestInteractable)
{
    BestInteractable->OnInteractedWith(this);
}
#

So now the interactable has a reference to the character that interacted with it and can do whatever it needs to: check if it can be interacted with by this character, show UI, whatever

#

I do this via a server RPC so it happens on the server but the logic is generally the same

sleek current
#

Thank you, will try something like that

high current
#

To make sure that I am on the right path, the text chat should be implemented somehow from
IOnlineChatPtrand GetChatInterface()

#

right?

#

Or did you guys mean it involves the usage of some things from the steam api that arent in the steam subsystem

sleek current
#

Hey, I have a widget component inside an actor. I want it to rotate to face each player, I know how to do the rotating part but how do I make it for each client and for the server?

high current
#

by not replicating it

#

ยฏ_(ใƒ„)_/ยฏ

#

Shaders are great for that, as you can make it face the camera inside the shader and you are pretty much done, but I don't know about widget materials

#

Otherwise, your rotation code just has to take the camera of the local player controller

#

so in this case getplayercontroller{0} might be actually useful

winged badger
#

you can just rotate it on Tick

#

with no replication involved

#

towards the camera of the local PC

#

he's doing c++, so UGameInstance::GetFirstLocalPlayerController() is what i'd go for

sleek current
#

Aight how to make sound of shooting projectiles and playsoundatlocation methods on multiplayer?

winged badger
#

you run a simulation that does it

#

not always possible, depends on a game, but recommended

high current
#

btw, Zlo can you shine a light on my question above, I wanna know if I am wasting my time figuring out how to expose the chatinterface to BP via c++

winged badger
#

if you fire 50 bullets in a second from your minigun

#

you don't really care if one client sees 30 hits and other 26

#

as long as you can do a close enough that is imperceptible by the player, and that simplifies your network, go for it

sleek current
#

Okay

#

How do I replicated destructible mesh?

winged badger
#

never saw that interface before

#

you replicate the condition that made it go boom

#

and you make it go boom on each client individually

#

i wouldn't try anything more accurate unless i really had to

high current
#

so the individual chunks wont match on clients (unless the destructible mesh supports replicated movement)

winged badger
#

thats what particle systems are for

#

smoke and mirrors

high current
winged badger
#

replicate any damage worthy of note... tada

#

there is apparently a full chat system in GameMode/PCs of all things

high current
#

waat

winged badger
#

@pallid mesa i summon you

high current
#

I mean, if I could just have access to like a shared player state or something, I can make my own chat

sleek current
#

I just made the method server and reliable

high current
#

cries in replication

sleek current
#

and now it doesnt destroy it on anything but server

high current
#

Well you need to play that on clients as well

winged badger
#

server and reliable is client telling the server "hey i did this, its important"

#

nothing more

sleek current
#

Aight then how can I call it on everything>?

winged badger
#

vorixo did a chat system using GM/PC stuff built in the engine

#

he's usually lurking around

high current
#

Yeah, he posted yesterday on twitter, so I know he is here somewhere ๐Ÿ˜„

pallid mesa
#

hello

high current
#

I can just leave the chat thing to the programmers, but I am just curious and wanna start learning MP in c++

pallid mesa
#

so... ULocalMessages tapa

high current
#

vo, where did the r go

#

I have a jira task

#

๐Ÿ™‚

pallid mesa
#

you know about them

high current
#

to implement those

pallid mesa
#

gave you a C++ component that you can invoke in BP's

#

feel free to use it and report what's missing

high current
#

Did you do chat with them

pallid mesa
#

who?

high current
#

well with it (ULocalMessage)

pallid mesa
#

yep chat and other sorts of systems

#

basically all UI msgs are based on that

#
  • chat system
high current
#

but it is all once all clients are connected

pallid mesa
#

if you can centralise all messaging in a system that it already exists in the engine, good.

high current
#

in the same map

pallid mesa
#

yes. Ofc, that consumes game server bandwidth

#

it's a in-game chat

#

but you can forward it to any other subsystem

#

such as a external chat server

high current
#

Yeah, no for ingame imma use the Ulocalmsg, as it it perfect for that. But my question was regarding just having global chat

#

and the thing is that we want to avoid using anything else

winged badger
#

i did not scroll up that far ๐Ÿ˜„

high current
#

lol, its fine

pallid mesa
#

you can still use ULocalMsg, however you'll need to override the send and receive implementations

#

ulocalmsg is a wrapper

high current
#

but yeah, someone suggested using what steam already has as chat

pallid mesa
#

you can mix steam and ulocalmessage

#

no issue there

#

actually /w @\username forwards to steam and prints on UI throught LocalUIMsg

#

in my case

high current
#

Someone also mentioned steam lobbies, is that different than sessions

#

and I couldnt find it in the steam subsystem

winged badger
#

i did

high current
#

so I guess it is in the steam api

winged badger
#

Kaos did an implementation recently, and is typing, it seems

high current
#

cause I liked the lobbies idea, with silently connecting people based on region for examle

pallid mesa
#

lobbies and beacons might be great to have a subset of players communicating between themselves

winged badger
#

you could even run your ingame chat via steam lobbies

#

and not use your listen server's bandwidth

pallid mesa
#

^

#

but still use ULocalMessage

high current
#

yeah, but does a chat really use that much bandwidth

pallid mesa
#

it's totally compatible

high current
#

well I guess yeah, if someone spams it

#

but still

pallid mesa
#

not really... a chat shouldn't take much

#

you cap the char limit and you put int a coldown for spammers

sleek current
#

Ayy I made it work on client's and on server

pallid mesa
#

you will need those systems anyways

sleek current
#

now only last question

#

how to make it work on late join?

winged badger
#

replicated variable instead of a multicast

pallid mesa
#

late joiners are my vibe, Zlo knows it

#

XD

sleek current
#

I dont have any multicast

high current
#

oof, I still have to fix some late join issues in the UT mod

winged badger
#

lol, broke the engine a little there

pallid mesa
#

had to do PR for 4.23 due to a net culling issue with posessions and late joiners XD

sleek current
#

UPROPERTY(EditDefaultsOnly, ReplicatedUsing = OnRep_Destroy, BlueprintReadOnly, Category = Destructible)
bool IsDestroyed;

#

void ADestructibleProp::OnRep_Destroy()
{
if (!IsDestroyed)
{
IsDestroyed = true;

    Destructible->AddRadialImpulse(GetActorLocation(), 1000.f, 1000.f, ERadialImpulseFalloff::RIF_Constant, false);
    Destructible->AddRadialForce(GetActorLocation(), 1000.f, 1000.f, ERadialImpulseFalloff::RIF_Constant, false);

    if (Particle)
    {
        UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), Particle, FVector(GetActorLocation().X, GetActorLocation().Y, GetActorLocation().Z + 15), FRotator(0.f, 0.f, 0.f));
    }
    
    if (Sound)
    {
        UGameplayStatics::PlaySoundAtLocation(GetWorld(), Sound, GetActorLocation(), 1.f, 1.f, 0.f);
    }
}

}

#

UFUNCTION()
void OnRep_Destroy();

winged badger
#

EditDefaultsOnly makes no sense there

high current
#

^

winged badger
#

EditInstanceOnly does tho

pallid mesa
#

well... your onrep doesn't make much sense

winged badger
#

that is also true

#

this will cause stuff like

#

you blow up a bunch of barrels and whatnot

#

and 10 minutes later i walk into net relevancy range and i see them explode

#

exact same issue as dead monsters getting up to play their death montage

high current
sleek current
#

so what should I do?

winged badger
#

sync your time with the server, using replicated var in GS if you don't care for more accurate solution

#

replicate the float Timestamp

#

which is server's GameTimeSeconds() at the time it blew up

sleek current
#

you talk about things that I have no idea about, whats GS,timestamp, how to get to it

winged badger
#

it can be set by default to something invalid, like -1 for objects that didn't go bang

pallid mesa
#

another thing you can do that is more expensive is to MCast the effects and onrep the functionality.......... <- that is if you don't care about performance in your case

high current
#

Game State

#

AGameState in your case

#

timestamps refer to timestaps per specific receieved update

winged badger
#

so, object explodes 2133 seconds into a match

high current
#

I saved this from the other day

pallid mesa
#

timestamp is pretty critical in MP games, yes.

winged badger
#

server replicates the float 2133 (its gametimeseconds)

pallid mesa
#

Great advice

winged badger
#

client recalculates what the server time 2133 is in its own gametimeseconds

sleek current
#

SO I should create a GS class and play with its time stamp?

winged badger
#

and if its happening NOW, it runs the kaboom code

#

it it happened 3 minutes ago, it just shows you the charred remains

#

GS already replicates the server's timestamp by default

#

what MrTapa c/ped there is how to make a more accurate system

pallid mesa
#

also... one last question, is this what I think it is?

   if (!IsDestroyed)
   {
            IsDestroyed = true;
#

that's usually used when you don't ensure your destroy function is called once and only once

meager spade
#

explosions should be multicast, the destroyed barrel state should be a OnRep

winged badger
#

thats the code that will make every unexploded object go kaboom

pallid mesa
#

and in this case an explosion for the client is a one time event that you shouldn't check on

meager spade
#

explosions should only happen to the players relevant at the time

winged badger
#

before BeginPlay on clients

#

as the initial state will replicate, before BeginPlay is called

#

and it will trigger the OnRep

sleek current
#

Goddamn, I literally have 1.5hours left to complete the task and you guys talk about stuff that I need to sleep with to compile XD

pallid mesa
#

erase that bit of code

#

and ensure variable initialization

winged badger
#

Kaos provided a most straightforward solution

pallid mesa
#

ensure also that this destructon code doesn't get called twice (hence only once per client)

winged badger
#

you can do that by doing this

pallid mesa
#

tbf kaos copied me >,>

winged badger
#
void OnRep_Destroyed(bool OldState);
#

when the OnRep is called, the OldState will contain a value before the replication

#

then you do if (Destroyed != OldState)

#

and you do not set the variable you're doing the OnRep for inside the OnRep

#

its set before the OnRep was called

#

(in BP doing that will create an infinite loop, btw - i hate networking in BP)

sleek current
#

OldState when I call this method is just destroyed variable?

pallid mesa
#

old state is the previous value of your onrep before it replicated

winged badger
#

OldState is destroyed variable before replication

#

and Destroyed is the destroyed variable after replication

#

by the time OnRep runs, its already set

#

to new value received from the server

sleek current
#

Alright then

#

What rpcs should I use in .h?

winged badger
#

so

#

your client makes an object explode

silent birch
#

I want in my game that if you shoot a person you have more to score but it adds to the one who was touched while I want it to add to the one who shot

winged badger
#

Server, Reliable sends that information to server

silent birch
#

Who can't help me?

winged badger
#

server, inside the _Implementation

#

sets the destroyed variable, which will set the objects visual state to charred remains

sleek current
#

SO there should be 2 methods Destroy() one for client and one for server?

grand kestrel
#

Is there a blueprint event for receiving a player state on client? I could add it myself but want BP only users to utilize it for my plugin

winged badger
#

and runs a NetMulticast, Reliable

#

inside which clients run the explosion visuals and sounds

#

its not a perfect solution, and can be improved upon

#

but its the only one you have time for, apparently

silent birch
#

While at the Spawn node actor from class I have put in places instigator get instigator

grand kestrel
#

Seriously wondering why APawn::Restart() isn't exposed to BP

sleek current
#

Zlo but how many methods

winged badger
#

@grand kestrel almost 100% reliable solve is to increase PS NetPriority to around 4

sleek current
#

Client makes objects explode that means there is one to explode, right?

#

Then server reliable sends it to server

#

so second one with same body for server

winged badger
#

it can fail miserably if there is packet loss tho

grand kestrel
#

@winged badger I really just want APawn::Restart but exposed by default.. in 4.22, so if there is nothing I'll have to do things differently

#

Just need an event on client once player state exists -__-

winged badger
#

there are OnReps for PS in PC and on Pawn

grand kestrel
#

Really? I didn't see any BP access specifiers

winged badger
#

oh there are none

grand kestrel
#

Yeah its very easy to solve in C++ or exposing it myself but I want it to be BP friendly

winged badger
#

plugin here is problematic

#

part

silent birch
#

Who can't help me?

grand kestrel
#

See so many poor BP users using a 1s delay from BeginPlay to circumvent it

#

Which isn't even 100% reliable

winged badger
#

@sleek current local sim is improvement

#

you can do when you get the rough version working

#

client wants to make something explode -> Server, Reliable RPC

#

server sets Destroyed and -> NetMulticast, Reliable RPC

#

that netmulticast will run on server, client who initiated it all and on every other client

#

OnRep_Destroyed sets the visual state of the object

#

Server RPC _Implementation applies damage and such

wary willow
#

@grand kestrel You are asking about Restart event right?

winged badger
#

and Multicast _Implementation plays particles and visuals

wary willow
#

If so, there is one expose to BP

#

Or is it Reset, looking now

high current
#

someone say, delays in BP

#

๐Ÿ™‚

wary willow
#

^ best way to do it

winged badger
#

can you implement a custom PS without breaking the plugin @grand kestrel ?

wary willow
#

Sometimes

silent birch
#

So for get instigator

sleek current
grand kestrel
#

@high current That's so gross and should be unnecessary, if they exposed APawn::Restart() to BP it's called once there is a valid PlayerState and PlayerController

#

It's effectively a BeginPlay with both of those present

#

And runs on server and all clients

winged badger
#

@sleek current destructible object isn't owned by your client's PC

#

so you need to implement the original Server, Reliable in an object that is

sleek current
#

sorry but

#

what

#

destructible isnt owned so implement server, reliable in the one that is owned

#

PFUFFFHHH here goes my brain XD

winged badger
#

you ever read exi's compendium?

sleek current
#

Yes I did but I dont remember the whole thing since it was an quality heavy punch of informations

winged badger
#

you can only send server RPCs through the PC

#

or object owned by the PC

sleek current
#

So basically I should call an RPC in PC by some event or smth?

winged badger
#

that would work

#

then the server version of the PC

#

tells the destructible to go kaboom

#

(that would be inside the RPCs _Implementation)

#

you make sure you send a pointer to destructible as an argument there

sleek current
#

So destructible calls an event on PC with argument (this)

#

And then pc does what exactly? Besides then calling the server kaboom

high current
#

@grand kestrel ik the image is kind of meme

winged badger
#

PC should have an idea that you're trying to destroy the object already

#

or your Pawn, or PlayerState, they can all send the RPC

sleek current
#

Alright

winged badger
#

having a random object in a level access your PC and start calling functions on it is kind of a code design you will end up regretting

sleek current
#

How do the destructible can call a specific PC?

#

How can I get a memory address for each player?

winged badger
#

or laughing at 6 months later "lol, what newb wrote this?"

sleek current
#

I mean I know I dont want that I only want the kaboom to happen on the destructible but you ma bible man

winged badger
#

how does the object go kaboom?

#

start with "player presses a button"

#

(the singleplayer version is fine)

sleek current
#

could we pm?

winged badger
#

others might learn from it

sleek current
#

After this multicast and server

#

it doesnt kaboom

winged badger
#

no

#

say you're playing solo

#

listen server

#

you press a button

#

how does that button get to kaboom

sleek current
#

Before it only didnt work for late join's

#

now the variable isdestroyed has wrong state on machines

#

and the hp goes to the negative value

winged badger
#

so then you're overcomplicating your life

sleek current
#

still not calling the destroy

winged badger
#

if you had it not working for late joiners only

#

all you need to add to that version

#

is OnRep_Destroyed with a variable that will make late joiners see the remains of a dead object

#

nothing else

sleek current
#

Input from PC->calls method in Pawn->Pawn calls a interact component->interact component calls interact method from interface on destructible->destructible kaboom

meager spade
#

Interact should already be called on the server

#

we made that a server rpc if its a client

#

last night right?

sleek current
#

we made the lamp

winged badger
#

it was always a server RPC

sleek current
#

the interaction is totally left withouit any rpc

winged badger
#

interactable actor isn't plugged in yet

sleek current
#

and it works

meager spade
#

which mean Interact is an RPC tho

#

cause we did a check

#

if its not authority call ServerInteract

#

else we just call Interact

winged badger
#

yes, that hasn't changed

meager spade
#

ok

#

making sure

high current
#

Wouldnt spawning a decal as a separate actor work better for that case, as you can actually destory the object and still have late joiners know what happened as the netdriver will spawn the decal actor

winged badger
#

(we do work together if anyone finds this exchange confusing)

#

@sleek current only thing late joiners need to see is that object is destroyed already

#

nothing else

#

so start from a version that was working except for late joiners

#

and add the code that does just that

#

change the object OnRep_Destroyed, if Destroyed is true, to look destroyed

#

nothing else whatsoever

#

we also helped lead you down the overcomplicated path, sorry for that

sleek current
#

so I am right now at the version that works but only doesnt show the late joiners destroyed object

meager spade
#

@sleek current just in a nutshell, RPCs are for telling the server (or server telling the client/clients) that something has just happend. Replicated properties are for maintaining a state across replicated actors (as long as server is setting the replicated property). RepNotify (OnRep) is used for things that should happen when that property is changed. RPC's are never sent to late joiners, but replicated properties (if they are different) are sent to the late joiner. So taking that in to account, your OnRep should just basically set the mesh/actor to the dead state. Your actual explosion should be an RPC or a property using some kind of time check to stop it being played again for late joiners. But the simplest approach is ReplicatedUsing to handle the state of the actor (exploded or alive) via the OnRep call, and a Multicast for the actual explosion. If a late joiner joins during the explosion, they won't see the explosion but who cares, they see the dead object already exploded tho. its just one of those smoke and mirror things, and you would be suprised how many games do it. its just simpler.

sleek current
#

What I did wrong here?

#

Still doesnt work for late joiners

winged badger
#

you don't explode it

#

you just change the mesh to look charred

#

spawn a crater decal

#

something

sleek current
#

cant late joiner just see somehow the destroyed mesh?

winged badger
#

late joiners load the object from the package (level)

#

it replicates its replicated variables

#

and runs any OnReps

#

then calls BeginPlay

#

(same case for walking into net relevant range)

#

so they see the object as is, after that is done

sleek current
#

What should I do to call the destruction if certain object is destroyed for late joiner?

silent birch
winged badger
#

you don't destroy it

#

you just make it look destroyed

#

no explosion again

#

just the aftereffects

#

and you have to do that from OnRep

sleek current
#

So I need to create an OnRep_Method() that does anything besides exploding again to make it look destroyed?

meager spade
#

thats the idea

#

OnRep should be for "State"

sleek current
#

How can I send variables from actor to its widget component?

winged badger
#

you generally don't

#

the Widget on the WidgetComponent should have a reference to the Actor

#

and if it needs to react to something specific when it happens, use a delegate after that

sleek current
#

Basically I have a widget component with progress bar over the destructibles to represent the destructible life

winged badger
#

but you can access the widget

#

Cast<UMyWidgetType>(WidgetComponent->GetUserWidgetObject) iirc

silent birch
#

Help me

meager spade
#

actually state a question don't just ask for help

meager spade
#

@silent birch stop posting the same question in multiple channels, its against the rules of the server.

silent birch
#

OK so help me?

velvet parcel
#

Using a multicast event to create a save game file will make it so all clients will save a copy locally right?

fringe dove
#

does anyone know offhand if steam's IsP2PPacketAvailable, ReadP2PPacket, and SendP2PPacket are threadsafe?

junior dragon
#

Hi, Everything works fine in single player but when I try to run editor for 2 players there's exception in this method and AIController is null

#

this code is in non player pawn character which patrolling along patrol locations.

fossil spoke
#

AIControllers only exist on the Server. Your not checking your pointers, therefore your causing a crash.

#
AIController = Cast<AAIController>(GetController());
if(AIController)
{
    // ... code here
}
#

@junior dragon

junior dragon
#

Thank you. It works. I would like to ask more.

How do I know which part should be separated from client and server (for example in this case GetController should only be called on server)?

And how do people usually separate code that should run only on server? Do people use if-else similar to my cases or a better way?

junior dragon
#

Ok, thank you. alex

twin juniper
#

how do I go about pawn possession in multiplayer? BP based, new at this and just learning the basics. Here is what I am trying, have also tried index 0. This is in my level BP, I have two pawns one with auto possess player player 0 and auto receive input player 0 and the other with the same for player 1. Only the server side works as I expect the client just spawns a new pawn. Don't understand the auto possess and receive input thing for multiplayer

#

Is the index 'reset' for client/server? So if I have a server and 3 clients then server will be index 0 and clients will be indices 0,1 and 2?

fleet raven
#

don't have pawns in your level, put player starts instead and the game mode will automatically create and possess pawns as necessary for joining players

twin juniper
#

Ok I'll try but surely there is a way to do it with pre placed pawns? Is my BP correct (aside from the specific index)?

#

of course it's wrong as mousing over 'possess' node it says 'authority only' ๐Ÿ˜‰

grizzled stirrup
#

If you are doing healthbars for other players and have in world pickups that affect Max health, it's pretty much essential to replicate both CurrentHealth and CurrentMaxHealth, right?

meager spade
#

Depends if maxhealth changes

grizzled stirrup
#

Yeah it does

#

There could be hacky ways to update it locally

#

But it might just be better to replicate it

meager spade
#

Then yeah you would need to step it

#

Rep

grizzled stirrup
#

Cool thanks!

grizzled stirrup
#

Will COND_AutonomousOnly on a replicated property ignore any non playercontroller owned actors such as AI characters?

#

Trying to only replicate health via a health component for human players and not AI

#

Doesn't seem to work by setting to AutonomousOnly and I believe SimulatedOnly will replicate from AI

meager spade
#

so

#

Player 1 connects to server, he is Autonomous.

#

Player2 connects to server, he is Autonomous

#

Server Replicates Player 1 to Player2, this is Simulated

#

and vice versa

grizzled stirrup
#

Ah ok thank you so there is no real way to gate player controlled actors other than maybe a COND_Custom condition?

#

Could potentially disable replication on the health component if owned by an AI controller also actually

meager spade
#

tbh no harm in really replicating the property to AI

#

very small bandwith use

grizzled stirrup
#

It's just if there are 50 AI and they are all replicating 2 floats 10 times a second

#

Would that still be tiny?

meager spade
#

properties are replicated at frequencies

#

based on the update rate of the pawn

#

actor*

#

and they won't be at the same time

grizzled stirrup
#

In the case of the AI it's 10 times a second and the player is 60

#

the NetUpdateFreq that is

meager spade
#

we have 100 ai replicating a lot of stuff

#

and hardly impacts net usage

grizzled stirrup
#

Ok thanks, it must be the CMC eating up most of the bandwidth

meager spade
#

yup

grizzled stirrup
#

With 50 AI, it jumps easily up to 40 / 50 kb

meager spade
#

cmc is terrible

#

every tick it can send a update

#

altho this is Unreliable

#

it still gets sent

grizzled stirrup
#

makes me wish I had the time to look into writing a very barebones CMC

#

with only the absolute basics sent infrequently

#

For AI and other actors that don't need precision

#

Thanks anyway I'll keep the floats replicated to all

meager spade
#

also another thing

#

if a property doesnt change

#

it wont replicate

#

so unless health is changing it wont keep replicating it

grizzled stirrup
#

It's regenerating 10 times a second

#

So unless their health is full, it'll replicate

meager spade
#

sure but once its full it wont replicate no more

grizzled stirrup
#

Yep

#

And actually once a second sorry

#

So it shouldn't be too bad

meager spade
#

nope

#

we have health regen on our AI

#

and like i said, we have very small impact

#

with 100 ai

#

CMC is what kills us ATM

grizzled stirrup
#

Great to know. It does make sense when you think about the fact that it's only 8 bytes at most 10 times a second

#

Whereas the usage with CMC is way higher

#

Will have to look into ways to optimize it a bit

#

I have tried many tricks to shave off time on anim updates and skeletal meshes which works great in terms of performance but the bandwidth usage is still there with the CMC

#

Tried Nav_Walking movmeent mode and a few other CMC specific tweaks but not much difference in bandwidth

#

May have to override if possible and call some of those unreliable RPCs only at a fixed rate

slender yarrow
#

is there any way to retrieve an external IP when a dedicated server is ran? Like is there a function in some class that can get the IP of the host when a session is created?

meager spade
#

@silent birch again, you are asking the same question in multiple channels. Please don't do that

tardy cosmos
#

Hi hi, how expensive for the network is to replicate a float 20 times per second?