#multiplayer
1 messages ยท Page 495 of 1
yeah
But could be much cheaper for AI etc.
Probably new NavSystem too.
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
it really should have a PMC then PawnNetworkedComponent -> CMC
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
Right now it's all intertwined right? Capsule / character / cmc
it's somewhat of a mess
It is, but the problem is more that the networking side of CMC is closely tied to the simulation
yep
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
it works fine for a prototype but past that you have to invest in taking the useful networking and simulation into your own class.
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
or having a vertical capsule represent a ship ๐
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
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?
there are many such people here, that is the point of this channel
Better to ask a specific question and people can help out ๐
how can i debug
where the server thinks my pawn is
and where the client thinks it is
@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 ๐
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 ><?
the character does not exist at that point
you should always use Cast not dynamic_cast
Why?
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
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
it first creates a controller, then later, it will create a character for it, then possess it
So what methods should I use to make it right?
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
yes, calling a server rpc on the server will execute it locally as expected
So are there methods/variables that tell me when pawn is possessed by a certain controller?
OnPossessed() / PossessedBy()
Those are called on the controller / character and can be overriden to do things
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?
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
True, did that. But still there is a problem that my mesh is not spawning and the functions dont work on pawn
Impossible to say why really without having the code in front of us
You got in on pm
If you pass a regular FVector into a function that takes const FVector_NetQuantize& will it be correctly quantized or should I remove the &?
Looks like you are adjusting speed on only client or server.
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 ><
@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?
@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
Not really
- You don't need to pass the Component, it exists on each instance anyway.
- Where does that call come from? Tick? If so, then you need to have someone be the Authority over this.
I used server, reliable and the projectile is breplicated true
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
it only works on server I mean I only see and hear on server
Otherwise you override the location again (rpcs take time after all)
is there any network sample projects
@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.
UFUNCTION(Server, Reliable)
void OnFire();
Mostly cause movement is done a bit different
im doing movement through physics
so instead of replicate physics im replicating the location and rotation
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
im not networking physics cause i did that and it was a big mistake
You said you're doing movement through physics
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?
If the object is simulating physics, it's using the physics engine
the physics engine is replicating?
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
@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
is there any tutorial for client authority
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
@twin juniper
- Send Location and Rotation from Client to Server via ServerRPC.
- In the ServerRPC, send a Multicast to everyone from the Server with the Location and Rotation.
- 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
@thin stratus What should I do to replicate the USoundBase? I did Replicated in UPROPERTY but it only works on server ><
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
In the Multicast, make sure you filter the owning client "IsLocallyControlled == false" and apply the Rotation and Location.
Or, if you follow along something like ShooterGame, you could increment a RepNotify Integer
oh okay i get it
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
@thin stratus so basically I need to create another method that is multicast and it only plays sound right?
u said server rpc
Yeah VFX SFX etc.
@twin juniper
OnTick, call "Re(Server)" IF "IsLocal" is true.
Re(Call) can be removed
Technically, if I'm not too tired, yeah
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?
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
its worth noting that if you try replicating a TScriptInterface
it will just silently fail, won't even toss a warning
Thanks
hey everyone, how do i get the replicated username on the dedicated server side?
you RPC it over
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
as i said, you need to send it via the RPC
I assume you are calling it on the client
but whats the point of the replicated player state and username
replication flows only server to client
once the server has it, other clients will get it
UE4 doesnt do p2p networking
but only way for client to push data to server is a RPC
^
ohhh that makes sense, of course like any other replication u4 tutorial ever xD damn
sry couldn connect the dots with c++
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
can i make this one "BlueprintCallable" as well?
Yes
then you just call ServerSetPlayerName from SetUserPlayerName if the Role is not authority
or better yet, if (Cast<APlayerController>(GetOwner())->IsLocalPlayerController())
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
_Validate, not _validation
yes _validate sry
if that one returns false, client that sent the RPC gets kicked
also a good place to implement some anti-cheating checks
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
ignore intellisense
I think I read in 4.23 you won't need the Validate by default anymore
@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
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
Also guys what is the right way to handle player input in player controller in multiplayer?
Like what RPC, properties to use etc
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
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
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
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
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
haha, using beacons or?
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
I have yet to familiarize myself with the steam docs
with something like UWorks at hand you can put that together in one afternoon
in BP
Yeah, it is a uni project so we have to manually implement everything
so this derives from the matchmaking part of steam or?
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
oh wait that is a plugin and not an official thing
no longer using steam?
no, Kaos volunteered last time ๐
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
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
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?
is the color name variable replicated
and where are you changing that variable on the client
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
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.
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.
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.
@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"
What's the name of the example?
OnRep is used for locally dependent values changing based off of a replication event.
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
And how should I actually write it in code?
c++?
yes
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
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)
no point sending const bool
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.
Sorry but for me it's too late to think. What do I change here?
Too much information ><
What's wrong with that?
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
wouldn't say it's bad programming practice
What ever imo it depends on the application
but what to do to make this lamp work on each machine XD?
Sorry but it's too late for me to think for myself ๐
quickly types out a prototype, give me a sec
ensures the value won't be changed, fairly sure it's also per epic's coding standard.
Yeah, it is.
its not
you wont see them use const bool for primitives
in function calls
same as const int32, etc
check all there functions
Standards and conventions used by Epic Games in the Unreal Engine 4 codebase.
i am familiar with them, been using UE4 for 3 years now
also have 20+ years programming experience
it says exactly that.
point me to the exact bit
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.
i never see that in the engine code
So I do have the server function to set the light based on bool
I see it a fair amount
And clients have no connection or what ever to use it ๐
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
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
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 give me two secs
so do you have a interaction component?
or something to interact with the actors in the level?
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?
pc calls pawn, pawn calls component when interact
basically yes but only on server machine ๐
so its a Server RPC from the client
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
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
having listen server issues with client disconnects. Just reposting my question here in case someone misses it: https://answers.unrealengine.com/questions/926788/view.html
@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
What would you guys say is the (reasonable) maximum for number of projectiles and characters in a networked game at a time?
@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
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.
@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
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.
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.
textures and materials usually have to be updated with rep notify or multicast from what ive learned
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
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
Thanks. I'll keep at it and try to get some more functional testing done
@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?
@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.
you create DIM
you don't assign it as material to the Mesh
there
you also need to create it only once
I also want help but I don't want to interrupt ๐
BeginPlay works, or GetMaterialInstance function that returns the MaterialInstance variable if its valid, if not creates one, assigns it to materials, and return it
@main spindle nah join in the fun lol
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
Ok, let me give that a try. Yeah, a valid one is present prior to spawning BP_Hitter
you still need to SetMaterial
in any case
also needs to be done just once, if DIM is not recreated all the time
Converted it to this:
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
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?
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
@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!
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
@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
nope, steam will do that under the hood
or perhaps I am not familiar with steam lobbies enough yet
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
yeah, but dont these things require level loading
or does steam lobbies work outside levels
its not a connection using unreal at all
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.
Ok so then what are the benefits of opening a session and not a level afterwards, if UE4 will fail
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
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
Right, so that's pretty much what I planned for.
Not sure what LastXXError means though
I would just always check if the queue is empty and if not start showing it one by one.
I suppose you could also just have a queue of general errors
Ah so you hold multiple queues for each type?
there's never more than one of these so it's not necessary to have a queue, just whether an error occured or not
Iirc the ConnectionLost error already comes with two different ones
My LobbyKit always returns two things, ConnectionLost and some generic "Error" shizzle
Right, so you just have one signle LastNetworkError and LastTravelError
And you check if they are set or not
And they display them
yeah
Are you using the same system for things like "You were kicked!"?
(or would you if you would have a kick feature)
I haven't actually set that up yet, it just shows "connection lost" 
wanted to do that eventually
Oh, how are you kicking them? :D
just destroying the player controller
Right that would probably end up being connection lost
there doesn't seem to be a real builtin "kick with message" function
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;
}
yeah I found that but I am confused how it works
void APlayerController::ClientWasKicked_Implementation(const FText& KickReason)
{
}
Probably the same way
if destroy is supposed to terminate the connection how would the rpc ever be received
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
destroying the player controller by itself doesn't actually do jack
somewhere the connection checks whether it still exists
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
oh
Now I don't know enough about connections
To know if that would allow the rpc to still happen
this is highly sketchy
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
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?
if (ThisActor->DestroyNetworkActorHandled())
{
// Network actor short circuited the destroy (network will cleanup properly)
// Don't destroy PlayerControllers and BeaconClients
return false;
}
I love how backwards the function name is
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
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
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
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?
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
ye
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
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
so they just dump it on the viewport client instead of the game instance, but otherwise same thing
Right but they call Disconnect
but only for return to hub, not the other kick 
I love the totally unneeded GameState
I wonder if the compiler is able to remove that
They never use the function without ToHub being true
So you can probably ignore the false case
extra 
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.
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
PostSeamlessTravel <--- Is only called on the server side?
@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
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.
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
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?
@sleek current You should never really be using those GetFirstPlayerController / character methods
I usually communicate things through the PlayerController to the HUD
But how do you do it if it's press button to interact
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
So pointer to pc in HUD, but still how do I get the value to actually get it?
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.
alright
so
PC pointer in component
But still how do I tell the pointer which memory address he should be?
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
Thank you, will try something like that
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
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?
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
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
Aight how to make sound of shooting projectiles and playsoundatlocation methods on multiplayer?
you run a simulation that does it
not always possible, depends on a game, but recommended
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++
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
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
so the individual chunks wont match on clients (unless the destructible mesh supports replicated movement)
replicate any damage worthy of note... tada
there is apparently a full chat system in GameMode/PCs of all things
waat
@pallid mesa i summon you
I mean, if I could just have access to like a shared player state or something, I can make my own chat
I just made the method server and reliable
cries in replication
and now it doesnt destroy it on anything but server
Well you need to play that on clients as well
server and reliable is client telling the server "hey i did this, its important"
nothing more
Aight then how can I call it on everything>?
vorixo did a chat system using GM/PC stuff built in the engine
he's usually lurking around
Yeah, he posted yesterday on twitter, so I know he is here somewhere ๐
hello
I can just leave the chat thing to the programmers, but I am just curious and wanna start learning MP in c++
so... ULocalMessages tapa
you know about them
to implement those
gave you a C++ component that you can invoke in BP's
feel free to use it and report what's missing
Did you do chat with them
who?
well with it (ULocalMessage)
yep chat and other sorts of systems
basically all UI msgs are based on that
- chat system
but it is all once all clients are connected
if you can centralise all messaging in a system that it already exists in the engine, good.
in the same map
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
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
i did not scroll up that far ๐
lol, its fine
you can still use ULocalMsg, however you'll need to override the send and receive implementations
ulocalmsg is a wrapper
but yeah, someone suggested using what steam already has as chat
you can mix steam and ulocalmessage
no issue there
actually /w @\username forwards to steam and prints on UI throught LocalUIMsg
in my case
Someone also mentioned steam lobbies, is that different than sessions
and I couldnt find it in the steam subsystem
i did
so I guess it is in the steam api
Kaos did an implementation recently, and is typing, it seems
cause I liked the lobbies idea, with silently connecting people based on region for examle
lobbies and beacons might be great to have a subset of players communicating between themselves
you could even run your ingame chat via steam lobbies
and not use your listen server's bandwidth
yeah, but does a chat really use that much bandwidth
it's totally compatible
not really... a chat shouldn't take much
you cap the char limit and you put int a coldown for spammers
Ayy I made it work on client's and on server
you will need those systems anyways
replicated variable instead of a multicast
I dont have any multicast
oof, I still have to fix some late join issues in the UT mod
lol, broke the engine a little there
had to do PR for 4.23 due to a net culling issue with posessions and late joiners XD
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();
EditDefaultsOnly makes no sense there
^
EditInstanceOnly does tho
well... your onrep doesn't make much sense
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
spicy
so what should I do?
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
you talk about things that I have no idea about, whats GS,timestamp, how to get to it
it can be set by default to something invalid, like -1 for objects that didn't go bang
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
Game State
AGameState in your case
timestamps refer to timestaps per specific receieved update
so, object explodes 2133 seconds into a match
timestamp is pretty critical in MP games, yes.
server replicates the float 2133 (its gametimeseconds)
Great advice
client recalculates what the server time 2133 is in its own gametimeseconds
SO I should create a GS class and play with its time stamp?
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
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
explosions should be multicast, the destroyed barrel state should be a OnRep
thats the code that will make every unexploded object go kaboom
and in this case an explosion for the client is a one time event that you shouldn't check on
explosions should only happen to the players relevant at the time
before BeginPlay on clients
as the initial state will replicate, before BeginPlay is called
and it will trigger the OnRep
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
Kaos provided a most straightforward solution
ensure also that this destructon code doesn't get called twice (hence only once per client)
you can do that by doing this
tbf kaos copied me >,>
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)
OldState when I call this method is just destroyed variable?
old state is the previous value of your onrep before it replicated
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
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
Server, Reliable sends that information to server
Who can't help me?
server, inside the _Implementation
sets the destroyed variable, which will set the objects visual state to charred remains
SO there should be 2 methods Destroy() one for client and one for server?
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
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
While at the Spawn node actor from class I have put in places instigator get instigator
Seriously wondering why APawn::Restart() isn't exposed to BP
Zlo but how many methods
@grand kestrel almost 100% reliable solve is to increase PS NetPriority to around 4
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
it can fail miserably if there is packet loss tho
@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 -__-
there are OnReps for PS in PC and on Pawn
Really? I didn't see any BP access specifiers
oh there are none
Yeah its very easy to solve in C++ or exposing it myself but I want it to be BP friendly
Who can't help me?
See so many poor BP users using a 1s delay from BeginPlay to circumvent it
Which isn't even 100% reliable
@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
@grand kestrel You are asking about Restart event right?
and Multicast _Implementation plays particles and visuals
^ best way to do it
can you implement a custom PS without breaking the plugin @grand kestrel ?
Sometimes
So for get instigator
I did something wrong and it doesnt call the destruction
@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
@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
sorry but
what
destructible isnt owned so implement server, reliable in the one that is owned
PFUFFFHHH here goes my brain XD
you ever read exi's compendium?
Yes I did but I dont remember the whole thing since it was an quality heavy punch of informations
So basically I should call an RPC in PC by some event or smth?
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
So destructible calls an event on PC with argument (this)
And then pc does what exactly? Besides then calling the server kaboom
@grand kestrel ik the image is kind of meme
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
Alright
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
How do the destructible can call a specific PC?
How can I get a memory address for each player?
or laughing at 6 months later "lol, what newb wrote this?"
I mean I know I dont want that I only want the kaboom to happen on the destructible but you ma bible man
how does the object go kaboom?
start with "player presses a button"
(the singleplayer version is fine)
could we pm?
others might learn from it
no
say you're playing solo
listen server
you press a button
how does that button get to kaboom
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
so then you're overcomplicating your life
still not calling the destroy
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
Input from PC->calls method in Pawn->Pawn calls a interact component->interact component calls interact method from interface on destructible->destructible kaboom
Interact should already be called on the server
we made that a server rpc if its a client
last night right?
we made the lamp
it was always a server RPC
the interaction is totally left withouit any rpc
interactable actor isn't plugged in yet
and it works
which mean Interact is an RPC tho
cause we did a check
if its not authority call ServerInteract
else we just call Interact
yes, that hasn't changed
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
(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
so I am right now at the version that works but only doesnt show the late joiners destroyed object
@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.
you don't explode it
you just change the mesh to look charred
spawn a crater decal
something
cant late joiner just see somehow the destroyed mesh?
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
What should I do to call the destruction if certain object is destroyed for late joiner?
GET INSTIGATOR
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
So I need to create an OnRep_Method() that does anything besides exploding again to make it look destroyed?
How can I send variables from actor to its widget component?
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
Basically I have a widget component with progress bar over the destructibles to represent the destructible life
but you can access the widget
Cast<UMyWidgetType>(WidgetComponent->GetUserWidgetObject) iirc
Help me
actually state a question don't just ask for help
@silent birch stop posting the same question in multiple channels, its against the rules of the server.
OK so help me?
Using a multicast event to create a save game file will make it so all clients will save a copy locally right?
does anyone know offhand if steam's IsP2PPacketAvailable, ReadP2PPacket, and SendP2PPacket are threadsafe?
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.
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
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?
Ok, thank you. 
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?
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
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' ๐
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?
Depends if maxhealth changes
Yeah it does
There could be hacky ways to update it locally
But it might just be better to replicate it
Cool thanks!
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
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
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
It's just if there are 50 AI and they are all replicating 2 floats 10 times a second
Would that still be tiny?
properties are replicated at frequencies
based on the update rate of the pawn
actor*
and they won't be at the same time
In the case of the AI it's 10 times a second and the player is 60
the NetUpdateFreq that is
Ok thanks, it must be the CMC eating up most of the bandwidth
yup
With 50 AI, it jumps easily up to 40 / 50 kb
cmc is terrible
every tick it can send a update
altho this is Unreliable
it still gets sent
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
also another thing
if a property doesnt change
it wont replicate
so unless health is changing it wont keep replicating it
It's regenerating 10 times a second
So unless their health is full, it'll replicate
sure but once its full it wont replicate no more
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
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
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?
@silent birch again, you are asking the same question in multiple channels. Please don't do that
Hi hi, how expensive for the network is to replicate a float 20 times per second?