#multiplayer
1 messages Β· Page 517 of 1
basically disable input of every player
ahh, I just put a check in the BR cahracter to set input to UI only
am i on the right track when it comes to using these?
How do you replicate a mesh that has had material change mid game to a jip client?
@spice skiff rep notify, material is an asset, and as such can be uniquely identified by its path in the package
so its network addressable
if its a DMI, you'll have to replicate parameters and set them client side during callbacks
im sorry this is quite confusing for me.. ill send some pics of what i have so far
the AddClothingNow RPC event is running from a serv -> multicast RPC
can you pass "Options" to dedicated server from client in blueprints or can I only do it by overriding InitNewPlayer? So far the test only works when we pass it directly into the GameServer.exe?Option1=test. I was trying to pass in information after a player joins and the server doesn't seem to be picking it up
Login functions can carry an options string
for some options, it might be too late to change them by then
Any suggestions regarding testing my GameplayAbility with dedicated server. I want to test right away on cloud, not local at all. At the moment I m thinking to connect my dedicated server via direct IP and check whether server grants ability or not whether it's replicating to other clients or not.
Do SMeshWidget replicate?
Or it behaves the same way like normal widgets and don't replicate
When I do PIE with dedicated server checked all I get is a black screen. Ideas?
The later @rich ridge widgets are owning client only by default
@solar halo Are you doing something with the viewport?
What do you mean?
I've even defaulted the gamemode etc and it still is a black screen.
Might be that you are not even possessing your pawn or a milion other things
Can't help without more information
That seems to be it.
ensure it, just in case. Gameplay initialization is quite long between gamemode, gamestate and pawns receiving playerstate from your controller
in your case if you ensure what you are saying your controller wouldn't have any controlled pawn on any context
How would I do that?
Ah, I thought you were talking about some setting.
@pallid mesa UMG widget will never replicate. I was talking about SMeshWidget because it comprise of actual meshes
It's still a Slate component
But it contains mesh right?
yes
So mesh should replicate at least
I am going to check something to ensure your statement, because I wouldn't be so sure
either way if you can't replicate the mesh you can ensure any player sees the same changes through message passing
See my purpose is to make Progress bar above players head using SMeshWidget. And if mesh replicate then I don't need to explicitly update the health to other players
take a look here, it doesn't look like it https://github.com/EpicGames/UnrealEngine/blob/6c20d9831a968ad3cb156442bebb41a883e62152/Engine/Source/Runtime/UMG/Private/Slate/SMeshWidget.cpp
@pallid mesa Yeah no clue. lol
Hello! I'm doing an inventory system, basically the client sends transactions to the server and also executes the transaction itself (so user can see ui updated without lag), It seems that the server only sees replicated variables, so either i have the inventory replicated (which doesn't work great: client does 1,2; server does 1,2; ui changes 1,2,1,2 because the server has some delay) or i have 1 inventory on client and another copy of the inv replicated, so the server can access this replicated inv, and can be used for validation, but the ui only changes with transactions on the client so its nice and smooth. This second method works nice but its not clean. The question: Is it possible to make the server have a variable that is not replicated or even better, is replicated on demand?
The inventory should be replicated anyway
Yes UE4 do have rep notify on condition
Clients shouldn't be in control of what they have in the inventory, the server should
Vars are only replicated when they are actually modified, but you can conditionally set whether a variable is replicating currently with DOREPLIFETIME_ACTIVE_OVERRIDE() (must be done inside PreReplication())
And you can put some condition on top of it as well
ohh didn't know that functionality on repNotify, I'll read about it
@craggy sable these RepNotify will work with dedicated server not with your API server.
Can I just confirm with you guys that this is the correct flow for a networked interaction:
- client handles input action
- calls a Run on Server event to tell server he wants to do something
- server validates it and calls a multicast to get back to the client that he can perform the action; the action gets executed both on the client and on server
@chrome bay the client is not in control of the inventory, (well, it is, but only on the local copy of the inventory) if the client tries to do a transaction that needs confirmation from the server and the server denies it based on its copy of the inventory or other rules, then the transaction will not be performed on server (it could on client, but that doesn't matter at all)
@rich ridge yes yes, i'm using dedicated server
I have a setup where my player pawns have TONS of actors attached to a parent chassis actor. That is, they never move relative to the parent.
If I have all the children set to replicate movement, are they replicating their world transform continuously or is it just being derived client side from the parent's world transform?
Are RPCs received in order generally? Can i assume a reliable RPC is received in order respect other reliable RPCs? I define order as: If RPC1 is sent before RPC2 its in order only if RPC1 is received before RPC2 at the server
@craggy sable I don't think you can make any assumptions about them. They are usually received in order if sent with a frame or two between them, but there's no guarantees. On LAN you might have 100% success, but across the Internet you have no guarantees at all.
I'm doing tests with a simulated network with a lot of lag, super high packet loss, packet disorder... and it seems that at least reliable RPCs are received in order (of course not reliable RPCs aren't because that would mean there aren't lost packets, which is against the unreliable definition)
reliable are always in order
But only on the same actor
between different actors no order is garaunteed
Does it actually send reliables using TCP rather than UDP? I guess you could do it over UDP too but given TCP already has that builtin..
interesting
what do you mean on the same actor? its in order if both RPC1 and RPC2 are defined in the same Actor but if RPC1 is in actor1 and RPC2 is in actor2 then theres no guarantee?
yeah
@thin monolith TPC does not guarantee packet order, it does packet recuperation, but packet order depends to the application layer not protocol
yeah I was more referring to the error control mechanisms in it :)
reliable are always in order
@chrome bay wouldn't that mean that the engine attempts to send only one RPC at a time, freezing all others until it has a confirmation from the client that he received it? That can't be right. Surely he attempts to send all RPCs and then just retries the ones that fail
The RPC's get added to a buffer and are executed in order
So while they won't be "blocked" as such, they will be queued up and executed in that order
When you drop reliable RPC's in times of high latency you'll get spammed with warnings
But if that happens then something has gone mega-wrong anyway
My point is, a round trip can take 100 ms, so if there is any ordering mechanism, that waits for a confirmation, then the game would be unplayable
Missing packets are NACKed, basically non-blocking correct messaging order
It's also why you should never send reliable RPC's on tick because you will almost certainly overflow the RPC buffer
hmm so is the queue only on the client side then?
the buffer is needed no matter which reliable method you use, scalable or not
so the server just shells out all requests at once, and clients waits to execute them in order
The queue is on both but it's not-blocking, RPC's are queued up on the network thread
@thin monolith tcp resends ACKs packets of the last received packet that are valid (valid means the packets before that packet are all received), so if server has packets 1, 2, 3, 5, 6 then it will send ACKs for 3 because is the last valid packet, and the client will resend 4, then the server will send ACK for 6 and 5,6 may or may not be resend (usually they will since its faster to send them that to ask first xD but if they were thousands of packets then some of the packets wont be resend since they are already valid in server)
the only blocking nature of the reliable algorithm are NACKed messages that need to be resent for the sender to update its last value
NACK -> Opposite to an ACK message
I ticked reliable rpcs once, it was fun :)
Yeah, do not recommend π
@twin juniper read the message i wrote to zomg (last message), i dont know ue4's implementation, but the client does not have to wait to send RPCs, they could be received disordered and executed only when all the packets before the next executing RPC are received and executed
Right, I think I get it now
at least thats how tcp works, but ue4 is free of using that or whatever implementation they want
its basically not a queue for sending, but for executing. You don't wait for each packet to be fully delivered before sending the next one, you send all, then the ones that arrive and have a successive order get executed, and others get asked to be resent
basically a scalable approach
@chrome bay to clarify, reliable doesn't guarentee order, if RPC 1 was dropped, but RPC 2 went through, then the order is not guarenteed.
RPC1 will go through, but not in order
If you call two Reliable RPC's on an actor (RPC-1 and RPC-2) in the same frame and they both get there, they will be executed in the same order you called them
But yeah if one of them is dropped because of overflow etc, it won't do that
My understanding is that in that same situation if RPC-1 has to be resent, RPC-2 will be buffered and not executed on the receivers end until RPC-1 is received.
reliable rpcs are guaranteed ordered
Yeah that's what I thought, but only within the scope of the actor channel they belong too
if you send too many it won't drop them, it will disconnect the client
with reliable buffer overflow message
Oh roger. Maybe the warning is an editor-only thing then
ye each channel has its own reliable buffer
anyone can help me how to get this mount working so i managed to get when press e it will play the animation to mount(not a good way but it will do for now) but it wont attach the player to component and posses the horse anyone know why and how to fix it?
https://gyazo.com/b0c3bb8d2d4229e38278a81bfe94b37c https://gyazo.com/e5c8518d587c7746c7635587abdadc6c
How can I set a custom Replication Condition from blueprints? I can set it to Custom, but idk where do i define the condition
@fleet raven thanks for clarifying
@karmic briar why are you going get all actors of class
why are you also using multicast
also you are repeating a lot of logic
for the get all actor of class idk when cast to bp_horse what the object part i should use so i just use get all actor of class the customevent part i changed it to server and what part of the logic that im repeating?
the overlap stuff for one
its all the same stuff except your toggling left or right
yeah thats for playing animation on the left or right
@craggy sable Custom only works in C++
It just lets you turn the property on/off in PreReplication()
But you can't attach other conditions to it, like OnlyOwner etc.
I just want the server and the client to have a replicated variable, each time i modify the variable on the client i do the same transaction on both client and server to avoid latency, but would be cool to replicate from the server if the transaction did not succeed on server or to replicate every few minutes
Just add a counter to it
Each time the server modifies it (or doesn't), increment the counter
That will ensure it replicates
Just a byte would be enough
You can't force a property to replicate if it hasn't changed. That sort of goes against the point of it.
if you don't have any variables in that actor that need to be updated frequently, you can set the NetUpdateFrequency way below 1 and ForceNetUpdate() when you need to make sure replication happens
i dont understand how that counter would help
Because the counter would force it to replicate because one of it's properties has changed
I.e the counter would be part of the struct variable you are replicating
{
public:
void EnsureReplication() { EnsureRepByte++; }
private:
UPROPERTY() uint8 EnsureRepByte;
}```
@winged badger its on the player controller (since i want to ensure its only replicated from the server to the owner, never other clients), i cant use what you said since it will affect player movement etc
player movement is done via character, if you're using CMC
and PC doesn't replicate to other clients at all
still not sure why you want to replicate it if nothing has changed, unless you are doing stuff in OnRep
You can do this if you want the OnRep function to be called everytime the server replicates a variable, even if it hasnt changed:
DOREPLIFETIME_CONDITION_NOTIFY(SomeActor, SomeProperty, Cond_None, REPNOTIFY_Always);
@chrome bay Im replicating an array, not sure if changing one of the elements like you said will trigger replication
either way thats not what i want actually
But the point is that the server won't replicate something unless it has changed anyway (at least, it will try not to)
changing an array element will replicate the property
as long as that property is UPROPERTY()
if its a custom struct
why do you want to always replicate it, even if nothing has changed?
I've done an inventory system that supports massive lag, packet loss etc. to avoid player input lag i do inventory transactions both in the client and the server, so the client state is always sync with the server or its a few transactions in advance. But this has a problem since the server is several transactions below, it will update the variable each time a transaction completes no matter if the transaction has already executed on client, so if i do 1,2,3 on client the server does 1,2,3 but the variable could change like: 1,2,1,3,2,3 (on client)
sounds like you want a FastArraySerializer tbh
How would I go about recording non-actor data into a demo, when it seems only actors replicate? Do I need some kind of dummy actor just to hold unspecific, global (but, crucially, time variant) data about the recorded demo?
I guess I'll try that
trying to do prediction without the ability to reconcile after a server update doesn't sound very useful
you need to figure out how to make the client re-run or discard "transactions" that occured
the state is always valid at the end
for an inventory, i would def be using a FastArraySerializer, it has call backs client side for PreRemove, PostAdd, PostChanged
the problem is not with how it replicates but with trying to implement prediction without correct handling of receiving server updates
when you get a value from the server it will be behind, that's just how it works
@meager spade not sure how can i apply the fast array
@fleet raven yes, i know, I've done several tests, one of them was having 2 variables, one replicated and the other not. The server does transactions with the replicated, the client no, and then i can sync from the replicated to the not replicated with custom logic
well with fast array serializer, every item has a id
@craggy sable each transation has a PredictionKey, i use a simple uint16
server confirms a transaction or rejects it, send a PredictionKey and a Timestamp
variables you changed after the server timestamp, you opt to trust the client on
i generally make a map <PredictionKey, Transaction> and have a function able to sum them all up
when server confirms, it sends its state at the time of confirmation, if applicable, and i just update it and remove that one Transaction
if it rejects the Transaction, rollback
do blueprints have unsigned integers? would be nice to code the predictionkey you define
not sure how to work with integer overflows
Hello guys! I've been trying to implement the advanced system (steam) in my project for a month, and still without success. Does it really work on version 4.21 of UE4?
Does anyone know why the ServerTravel command in an umodified vanilla template of the Epic Games' ShooterGame example does not work when you PlayInEditor?
It's clearly due to this check in the 4.24.1 Engine's GameModeBase.cpp:
// NOTE - This is a temp check while we work on a long term fix
// There are a few issues with seamless travel using single process PIE, so we're disabling that for now while working on a fix
if (World->WorldType == EWorldType::PIE && bUseSeamlessTravel && !FParse::Param(FCommandLine::Get(), TEXT("MultiprocessOSS")))
{
UE_LOG(LogGameMode, Warning, TEXT("CanServerTravel: Seamless travel currently NOT supported in single process PIE."));
return false;
}
but I'm unclear why !FParse::Param(FCommandLine::Get(), TEXT("MultiprocessOSS")) returns true as ShooterGame does not seem to implement a Multiprocess OnlineSubsystem (like Steam) by default
thanks Kaos, this checkbox is unchecked but I still hit that Warning:
is that the same one?
is there a limit to the amount of times a component can trigger its overlap event on a dedicated server? my bullets hit the mesh (yes the mesh has collision) and sometimes it triggers the overlap, sometimes it doesn't
@cerulean escarp are they going fast enough that they can tunnel past the mesh?
I think that might be the problem
they were going 10000 units of speed (idk what unit the projectilemovement component uses) and I set it down to 5000
it got a little better but some still slip through
I wondered if it was a server performance issue and it isn't, I loaded up 10 clients onto the server and every single client was replicating smoothly, and the bullets were acting the exact same as with only 2 clients @dark edge
Hello everybody. I have a question about organizing multiplayer. I have a listen server that knows about its controller and the playerβs controller and there is a client that knows only about its controller. In the controllers, I wrote the movement. For example, in the controller we take the link to the pawn that we control and move it at each tick (for example). The problem is that the server does not initialize the second controller. Now the question is how to organize it better and how it should look (how would you do)?
is there a way to get the bullets to always trigger an overlap and not skip at certain times?
CCD
already have it enabled
wait for both the bullet and the player?
or will just CCD on the bullet work
"Always" isn't a thing when you have physics
The best thing to do is to replace the overlap by traces on tick for the projectile
On each tick, trace the planned movement over the next frame with a volume trace
Or the past movement, if you want accuracy
We did this to achieve accurate, realistically-fast-moving projectiles (kilometers / second)
you lost me at volume trace
and I'm not quite sure I fully understand the logic behind this method
is the projectile doing the traces?
if you have a bullet that fast, why not use linetrace and use bullet as cosmetic instead ?
because I need to have bullet drop
The best thing to do is to replace the overlap by traces on tick for the projectile
At scale, what effect would this have on performance?
Of course, yes
@cerulean escarp In our implementation, yes, projectiles do the tracing
so every tick the projectile is tracing, and then what does it do?
Trace ahead in the current direction, length = speed * delta time
If hit, then you process that
You can also do it backwards by storing the current location, and tracing behind you
Less risk of error, one frame of lag
what's the performance compared to just straight up replicated projectile?
@cerulean escarp you can do bullet drop with traces. That's pretty much how every game does it.
@cerulean escarp do not! I repeat do not! Use replicated physics for 100m/s bullet lul
I meant a replicated projectile
You got to think about what the thing being a projectile gets you. It is practically point like, the diameter of the bullet doesn't really matter.
@cerulean escarp Honestly, fast physics bullets don't work in MP
No one does it for good reason
for physics I usually multicast and check only on the server
Just use traces. You trace each frame by the frame time x bullet velocity, adjusting velocity for drag and drop
so every player has it on locally
You should only use projectile movement for things like rocket launchers or grenades etc
The basic problem is that a real-world bullet has flown 50 meters in the timespan of an average Internet ping, so any sort of accuracy is only a pipe dream here
Well, that's when you get into prediction.
I think I'm going to go with the linetrace method
Just use line traces is the takeaway here. It's good enough for Arma. No need to have a physical shape being slung around in the scene.
I want it to feel like the average fps, and I thought that most did it with physics simulating bullets
yeah make it drop when it travels until the end of the trace
On top of it, consider that modern shooters use the shooting client point of view as an authority on whether the shot succeeded.
Which isn't easy in UE4
It's super easy in ue4.
It's really not
I'm still a little confused on how I can manipulate the line trace to include bullet drop and how to even change the speed of the line trace
Well of a sort. Pubg use client-side hit detection for a long time
Making it server authoritative is the hard part.
Well yeah, if you decide to ignore cheating, it's easy
@cerulean escarp trace from bulletpos to bulletpos + bulletvel * timestep
Then update bulletvel = bulletvel + 0,0,-980 * timestep
The 980 thing is World->GravityZ or something
If you want designer-friendly gravity
does this require Event Tick or could I use timers?
Tick
but isn't event tick a big no-no?
I would recommend doing it in a manager of sorts if you got tons of bullets.
How else are you going to run something every frame? Tick is only a No-No if it's being used unnecessarily
Tick is not a no go at all
ah
I have a full mechanical drive train simulation and tire model running in a multiplayer environment on tick, all done in blueprint, and it runs just fine. Don't worry about optimization until you need to.
It's a good thing to not use Tick for everything, especially in Blueprint, but if you need to and it's fine.
In C++ you can abuse Tick to unimaginable depths before it actually has a cost
I only have one actor ticking per player though, and chain off of it. I'll eventually go to a quasi ECS approach and only run the systems on tick.
Just don't use the UMG tick bind thing.
IMHO : use what's convenient and fast to iterate, and optimize later.
alright I'm starting to understand this system a lot more, I'll test it out and see what happens. thank you guys for the help I've been struggling with this all day
Has anyone made a good robust multiplayer projectile system for the marketplace? like something that runs like greased lightning?
I searched for one, but I don't think it included bullet drop
it has a ton of different calibers to choose from and like 41 different materials with realistic penetration values
only $8.99 too
Hi! I'm trying to replicate my SpawnDefaultWeapons-function, but it doesn't seem to work. What am I missing?
void AaCeProjectCharacter::BeginPlay()
{
// Call the base class
Super::BeginPlay();
if (Role == ROLE_Authority)
{
//Spawns Default Items at Spawn and sets correct InventorySize
GiveDefaultWeapons(WeaponInventorySize, MagazineInventorySize, DefaultPrimaryMagazineStackAmount, DefaultSecondaryMagazineStackAmount);
}
}
AWeaponMaster::AWeaponMaster()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
WeaponCollisionComp = CreateDefaultSubobject<UBoxComponent>(TEXT("WeaponCollisionComp"));
RootComponent = WeaponCollisionComp;
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WeaponMesh"));
WeaponMesh->AttachTo(RootComponent);
SetReplicates(true);
}
Is the weapon spawning on the server?
Yes
What a weapon is given, is an actor actually spawned? we need to see what the inside of your give weapon to function looks like
Okey, 2 sec
//Sets Default Items On Character and size of inventory
void AaCeProjectCharacter::GiveDefaultWeapons(const int32 WeapInventorySize, int32 MagInventorySize, int32 PrimMagCount, int32 SecMagCount)
{
Inventory_Weapon.SetNum(WeapInventorySize, false);
Inventory_Magazine.SetNum(MagInventorySize, false);
//Set Default Primary Weapon
AWeaponMaster* SpawnPrimary = GetWorld()->SpawnActor<AWeaponMaster>(Primary);
if (SpawnPrimary)
{
Inventory_Weapon[SpawnPrimary->WeaponData.SlotID] = SpawnPrimary;
CurrentWeapon = Inventory_Weapon[SpawnPrimary->WeaponData.SlotID];
CurrentWeapon->SetOwningPawn(this);
CurrentWeapon->OnEquip();
}
//Set Default Secondary Weapon
AWeaponMaster* SpawnSecondary = GetWorld()->SpawnActor<AWeaponMaster>(Secondary);
if (SpawnSecondary)
{
Inventory_Weapon[SpawnSecondary->WeaponData.SlotID] = SpawnSecondary;
}
//Set Default Primary Magazines
AMagazineMaster* SpawnPrimaryMAG = GetWorld()->SpawnActor<AMagazineMaster>(Primary_MAG);
if (SpawnPrimaryMAG)
{
Inventory_Magazine[SpawnPrimaryMAG->MagazineData.SlotID] = SpawnPrimaryMAG;
CurrentMagazine = Inventory_Magazine[SpawnPrimaryMAG->MagazineData.SlotID];
CurrentMagazine->MagazineData.StackAmount += PrimMagCount;
}
//Set Default Secondary Magazines
AMagazineMaster* SpawnSecondaryMAG = GetWorld()->SpawnActor<AMagazineMaster>(Secondary_MAG);
if (SpawnSecondaryMAG)
{
Inventory_Magazine[SpawnSecondaryMAG->MagazineData.SlotID] = SpawnSecondaryMAG;
CurrentMagazine = Inventory_Magazine[SpawnSecondaryMAG->MagazineData.SlotID];
CurrentMagazine->MagazineData.StackAmount += SecMagCount;
}
}
@dark edge I guess the problem is my inventory
When I try to change weapon in multiplayer, the game crashes.
This gives me some strange errors. Why?
UPROPERTY(Replicated)
AWeaponMaster* CurrentWeapon;
UPROPERTY(Replicated)
AMagazineMaster* CurrentMagazine;
- stop hot reloading
- it seems like you declared GetLifetimeReplicatedProps and forgot to actually implement it
@fleet raven I don't have GetLifetimeReplicatedProps declared :/
if I remove the Replicated UProperty Specifier, the error is gone.
it's all spelled out in the docs, read ze docz https://docs.unrealengine.com/en-US/Gameplay/Networking/Actors/Properties/index.html
Detailed information about how Actor properties are replicated.
(except the unrelated PCIP argument in the constructor, ignore that, that is ooooooold)
ah yeah. you are required to implement it when you put a replicated property
hmm
#define DOREPLIFETIME(AWeaponMaster, CurrentWeapon)
#define DOREPLIFETIME(AMagazineMaster, CurrentMagazine)
void AaCeProjectCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const
{
DOREPLIFETIME(AWeaponMaster, CurrentWeapon);
DOREPLIFETIME(AMagazineMaster, CurrentMagazine);
}
or?
which ones looks like the docs page?
the second one.
Yeah; but I got an error for not defining
also normally the first arg is the the owning actor, e.g. AaCeProjectCharacter, not sure about the fine details if that matters or not
You might need UnrealNetwork.h.
I have added #include "ReplicatedActor.h" and #include "UnrealNetwork.h"
fix the first argument to the actual class that contains CurrentWeapon and CurrentMagazine (i.e. AaCeProjectCharacter)
if it still wont compile, time to post output log
@hoary lark It compiles, but now the character refused to move. Animations are running, but the character is on the same spot.
working on server.
Once I've started replicating, then everything has to be replicated to work? π
that sounds like a more complex problem than I unfortunately have time for at the moment, but in general no this should just "add" the selected properties to UE's replication system... it shouldn't affect other unrelated behaviors as far as I know
@hoary lark No problem π Thanks so far.
missing Super call
in GetLifetimeReplicatedProps
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AaCeProjectCharacter, CurrentWeapon);
DOREPLIFETIME(AaCeProjectCharacter, CurrentMagazine);
}```
@sand tangle
Ahh, thanks! @meager spade
if only the community could help edit the docs pages to fix stuff like that. or even edit the unrealengine wiki 
Yeah, up-to-date wiki would be great!
I have to do this with everything?
#define DOREPLIFETIME(AaCeProjectCharacter, CurrentWeapon)
#define DOREPLIFETIME(AaCeProjectCharacter, CurrentMagazine)
#define DOREPLIFETIME(AaCeProjectCharacter, Inventory_Weapon)
#define DOREPLIFETIME(AaCeProjectCharacter, Inventory_Magazine)
void AaCeProjectCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AaCeProjectCharacter, CurrentWeapon);
DOREPLIFETIME(AaCeProjectCharacter, CurrentMagazine);
DOREPLIFETIME(AaCeProjectCharacter, Inventory_Weapon);
DOREPLIFETIME(AaCeProjectCharacter, Inventory_Magazine);
}
Hey, when it comes to internet speed tests, these days most of the websites out there are either very inaccurate, or purposely inaccurate, what do you guys do to test your connection?
if I want a client to interact with an object which then activates another object, should I first send that information to the GameMode to activate the object, or is there a better class to do that activation?
since server would activate the new object
if the object being activated by another object is important only for the match going on at the time, do it in the GameState class
@potent prairie If it's a Pawn -> MapActor interaction, just run an RPC on the pawn to do the interacting server side. If your objects are set up correctly, everything done serverside will replicate back out.
@meager spade yesterday you mentioned something about push model which is going to arrive in 4.25. could you explain something about it or guide me to a link
@rich ridge its quite a convulated thing, but i will post the link https://github.com/EpicGames/UnrealEngine/blob/master/Engine/Source/Runtime/Net/Core/Public/Net/Core/PushModel/PushModel.h
Hello everyone.
I'm working on a TPS with kind of abilities. When a player equip some weapons, he can perform attacks that make him dash in a direction.
However, he also have a Dodge with every weapon, that he can activate, but it's basically the same kind of movement, it make him ignore friction and set his velocity.
So what I did is, check on client for the condition, if it's okay then he tell the server and dash (local prediction), while the server do a second check and allow him to dash or not and then set his velocity server side.
The problem with this is that at high latency the player kept rollbacking so after some research I saw that UE4 implements a rollback system within his movement component. I rewrite it and it's working.
However, I don't know how to check the condition server side, since the action is a "dash" and it can be used at multiple instances (for the dodge, weapon ability 1, weapon ability 2, etc.).
Right now I got: Client do the input, it check the condition, if it's okay, then he say to the server he dash and the server doesn't check anything, which is dangerous in a networked environment. Is there a way to do this that I can't see?
Right now you have this? ->
Client presses dash key, checks condition locally. If condition is good then client performs the dash locally and sends a server RPC to ask the server to dash. If the server denies the request obviously the actual player position won't change and the client will be rolled back
so in your case you are saying that in a high ping environment, even if the server says the dash is good, the packets can arrive so late that the client gets rolled back anyway? (and then presumably teleported forward again when it gets the updated information)
The problem I have is the part where the server can check the request
Since I can have multiple condition depending of if the player is doing a dodge or an ability with a weapon
Im unsure why your server canβt check conditions as well. Is something not replicated?
@vivid seal Sorry for being late.
So I have the movement that is kind of a dash, but I use it for: Dodge and other movement abilities. So I just did a function for the movement without condition (Dash). Should I make one function for each condition? Doesn't it seems weird to have the function in the movement component of every weapon movement condition?
How do I create Implementation and Validate functions? With this I get "Can't find member error"
UFUNCTION(Server, Reliable, WithValidation)
void ServerFire();
void AWeaponMaster::ServerFire_Implementation()
{
}
bool AWeaponMaster::ServerFire_Validate()
{
return true;
}
Is this error when you try to build the project, or just in Intellisense?
Intellisense. Maybe i should try to build first;)
Yeah, _Implementation and _Validate aren't even declared until you build once
hi everyone, is it possible to use level streaming for clients connected to a dedicated server, while the server itself has it turned off so it can track all players connected? Or do I just need to have one static level?
If you're using GENERATED_BODY() you have to declare the _Implementation functions in the header yourself
when i spawn an object how to i ensure that it replicates to the clients or is that handled in spawn actor. I'm makeingsure that spawn actor is called on the server with RPCs from the player Controller
I'm using a blendspace with MoveForward and MoveRight values. Do I only need to replicate those two variables to replicate the animations?
ok but just setting bReplicates on the actor class being spawned then everything is good to go out of the box?
@chrome bay You don't have to
I know I never did
They're declared in the .generated.h file
Looks like this for one of mine
@pallid mesa right, :D. the player controller by default does not replicate pitch
what is the best way to have all of the player's UI's update when an object is spawned. Currently i'm thinking the spawn calls a multitask delegate in c++ that is BlueprintAssignable and then i bind it to a UI function in BP does that sound logical?
that sounds like a good solution yes
Yeah I do that quite a lot too
I have this struct to replicate a hitscan
USTRUCT()
struct FHitScanTrace
{
GENERATED_BODY()
public:
UPROPERTY()
TEnumAsByte<EPhysicalSurface> SurfaceType;
UPROPERTY()
FVector_NetQuantize TraceTo;
UPROPERTY()
int8 Seed;
};
But, which data structure do u think is the most appropiate to replicate at once 'n' (let's say n=10) projectiles of a shotgun?? maybe a TArray?
a TArray of this FHistScanTrace I mean
ok good deal never done it before so lets see how it goes. May check back in with debugging issues
First question - why do you need to replicate the scan at all?
maybe I'm missing something but...because I would like to see the shoot in every player
Sure, makes sense. The only trouble is the muzzle location will no doubt be quite out of date by the time you get it right?
I.e. the shot has to go from Client->Server->Client, at which point it's pretty out of date
Depends on the requirements of the game, but sometimes it's better to replicate the muzzle position and direction, then do the trace
Different approaches you can take though. My other project just runs the full firing sim on each client so they just keep shooting FX until they're told to stop
Sort of up to you how you want to handle it really, depends on the game
If you have really high fire-rates though, just bear in mind you're not guaranteed to receive all of those hits.
(hence in my case I opted for running the full firing sim)
If it's really important to see every hit, that might be the approach to take.
If it's not, just one of those per-weapon should be fine. You'll miss the occasional one but most people probably won't notice
ShooterGame does near enough the same thing
I definetly will take note of it and improve it
that's a very nice advice!
but, let's follow the actual example, just to know how would you replicate several projectiles at once (like a shotgun)
I calculate lets say 10 projectiles in a random cone in my client -> send them to server -> replicate to rest of the clients..... but which data structure would u use for it?
a simple array?
Hmm sort of depends. No doubt you have a seed to generate the random spread
So my advice would be replicate the seed & the muzzle location and direction only
Then let remote clients handle creating the individual shots.
Yeah
So long as it's deterministic, that should be fine
Is it the usual way to calculate the projectiles of a shotgun? or there is another simple or better way?
Ok I have a really nitty gritty question. I had to build a game engine for class and we had the concept of an event manager. Whenever we created an event we would register it with the event manager and the event manager would keep track of all the objects that registered themselves as caring about when it was called. I'm assuming UE does something similar. Is calling IsBound() the equivalent of asking the event manager if anyone has registered themselves as caring about the event?
@weary mortar That seems like the approach to me, anything where you don't have to replicate a whole array will be preferable almost certainly
@chrome bay cool!! thanks so much for your time and clarifications!! I will give it a try! π
Ok so I made the delegate and if I run it from the server everything is fine. However if I run it from the client then nothing prints and if i run it with a dedicated server i get errors
Header Code
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FNeoLevelControllerRefreshDelegate);
//UI Refresh Delegate
UPROPERTY(BlueprintAssignable, Category = "Delegates")
FNeoLevelControllerRefreshDelegate RefreshUI;```
Source Code
```if (RefreshUI.IsBound()) {
RefreshUI.Broadcast();
}```
Error Message ```Blueprint Runtime Error: "Accessed None trying to read property CallFunc_Create_ReturnValue". Blueprint: NewBlueprint Function: Execute Ubergraph New Blueprint Graph: EventGraph Node: Add to Viewport
I get 1 for each client
Here is the bp in question
just clicking PIE with the dedicated server throws the error
Hi guys, iΒ΄m trying to achieve to prompt the user for name/id, so i can bypass that string to a custom user handle with blueprints. Any directions to a guide or tutorial for this? thanks in advance!
is it more effecient to send say 5 multicast RPCS in a single frame, than spread out over frames?
so im replicating a struct that contains the servers location of an actor. if the value is above a certain threshold, i relocate the clients version to the servers version. basically just a correction. however, somewhat periodically it gives a rather large difference LogTemp: Warning: DistanceBetweenUpdate: 1.848640, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 10.591377, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 3.238062, Within Tolerance LogTemp: Error: DistanceBetweenUpdate: 60.252808, Correcting Location LogTemp: Warning: DistanceBetweenUpdate: 4.076781, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 8.671151, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 4.552180, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 9.480200, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 19.533621, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 4.951879, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 10.033470, Within Tolerance LogTemp: Error: DistanceBetweenUpdate: 76.530289, Correcting Location LogTemp: Warning: DistanceBetweenUpdate: 10.317989, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 10.372618, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 5.191772, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 10.444856, Within Tolerance LogTemp: Error: DistanceBetweenUpdate: 78.983315, Correcting Location LogTemp: Warning: DistanceBetweenUpdate: 10.565478, Within Tolerance LogTemp: Warning: DistanceBetweenUpdate: 10.523771, Within Tolerance
is it possible the client is receiving the info out of order?
i figured if it jumped back (from getting an old location) the next one would then correct it and snap it back, but it doesnt seem to be the case
Hey guys! Can someone point me to a quick primer on how to make a multiplayer shooter? I can do single-player no problem, but multiplayer always stumps me. Thanks!
@pliant quest https://www.udemy.com/course/unrealengine-cpp/
@pliant quest Start with a capsule that moves around, and figure out how you're gonna do your shooting prediction. From there it's fairly straightforward, just gotta keep the 3 views in mind for everything.
Thanks @dark edge @twin juniper!
@pliant quest Shooting lag compensation will be your biggest technical challenge. Movement is already predicted for you by the CharacterMovementComponent.
@dark edge What technique do you recommend? I've pretty much only used raycasting.
@pliant quest That's your hit detection. You need a way for hits to be verified by the server. For minimum playability, you can go with client-side hit detection.
0:00 Lag compensation
2:00 Interpolation
If I want to make a small Unreal multiplayer server for testing multiplayer, are there any services that people can recommend? I just want something that can support like, max 50 people running a very simple indie game for testing.
@rancid flame I like DigitalOcean, it's what I use. Never had 50 ppl on it but you can size up as big as you want.
@dark edge Thanks! What product is that? https://www.digitalocean.com/pricing/
@rancid flame I have the $20/mo one and I've never had a problem with it. Only ever tested up to 4 clients though. Server load will vary based on your game. You can prolly get by with the $10/mo one
You need to know how to cross compile the dedicated server for linux.
ah thanks for the tip
@dark edge hey I got the line trace ballistics system working perfectly, it detects the hit 100% of the time (at least from what I've seen) I do have an issue that I just found out about though.
the line trace doesn't follow the tip of the gun on other clients
it always originates from the same place relative to the actor
@cerulean escarp Where are you tracing from? A socket on the gun?
wait do you have 2 meshes, for 1st and 3rd person?
yes
the bullet actor spawns at a collision capsule placed at the first person gun model called Effects
Don't need a capsule there, just a socket or scene component
and on the client's view, the 1st person mesh is hidden right? But its still trying to spawn there.
THat's what you gotta sort out
the first person mesh is hidden for all other players except the owner of it
and the third person mesh is hidden for the owner only
And is there 1 gun or 2 per player?
2 per player, one does nothing though
the first person gun is the only gun that does anything
You're still tracing from it though, on the client's view
yes
that's why your traces are from thin air
in the right screen
you're tracing from where that invisible gun is
right but they should still spawn from the invisible gun at its elevation too right?
idk, depends on your setup. They need to not be doing that though, you need to have 1 gun and attach it differently 1st vs 3rd view
If it's your fist attempt, I'd just consolidate to 1 skeletal mesh and not do the 1st/3rd switching, you'll be running into fuckiness like this the whole time.
how would I do it with only 1 mesh?
Camera in the head, different materials for different views, etc.
It's a choice to make
But anyway, you shouldn't need to be doing the trace anywhere but firing client if you're doing clientside hit reg
then just tell the server "I shot from this point towards this point, and hit this thing
right now I'm having the server shoot the line trace
should I switch to the shooting being done by the client?
Type "net pktlag=100" and see how it feels
lol I'll give it a try
It'll feel like shit. You need to do either clientside hit reg or clientside hit with server-side confirmation for it to not feel like ass in any amount of latency.
alright I'll switch it over then
Go and read about why you need to do this stuff first, dont just do it blindly
Easy approach is to do the hit detection on firing client only. It'll feel great, but there's potential for cheating.
for the single skeletal mesh, the issue I had was that the gun wasn't in the right position and looked absolutely wrong, how would I fix that?
that's easier than editing the model*
hey I decided to try multiplayer and I ran into a problem maybe someone can help me understand the concept behind this, I have a pawn with most my logic in it, if I hit play with a dedicated server with 2 players I get errors on my HUD damage effect when dealing damage to the other player, so I watched some videos and saw a has authority node can help, so I put on in, and the errors is gone, but when I deal damage to another player the hud damage effect doesnt show up like it does in single player when it comes across the screen
how can I make it so the hud damage effect shows up for the player thats getting hit in multiplayer??
Don't switch on authority, switch on if locally controlled
Plus I'm not sure if playercontroller 0 is always local player in a networked game
instead, get the pawn's possessing controller.
@dark edge player controller 0 is always pointing to player who is playing on his machine
Should be safe enough behind a IsLocallyControlled check as long as you never have couch coop
Does the client own his player controller? If I want to execute something on the server from within a player controller, do I need to use a Run On Server event?
And when the Run on Server event is executing, if I get the Player Controller at index 0 in that context, does it return the Player Controller in which that code is running, or the one that the listen server posses, if its a different one?
I need a futurama suicide booth right now
Is actor attachment not replicated?
When I call a "Run on Server" event from within a Player Controller, it seems to be always called on the PC that the Server posses, not on the caller, what's wrong?
If you call a server RPC on a player controller, it will execute on the server version of that player controller
i'm having an issue where my delegate is not getting correctly replicated. I have the following block of code that is garunteed to run on the server
GetWorld()->SpawnActor(DefaultNoteClass, &InSpawnLocation, &InSpawnDirection);
if (RefreshUI.IsBound()) {
RefreshUI.Broadcast();
}
}```
and the following decaration for the RefreshUI delegate
```DECLARE_DYNAMIC_MULTICAST_DELEGATE(FNeoLevelControllerRefreshDelegate);
//UI Refresh Delegate
UPROPERTY(BlueprintAssignable, Category = "Delegates")
FNeoLevelControllerRefreshDelegate RefreshUI;```
However the call doesn't seem to get replicated to clients
any ideas why
this is the bp for the Widget that is bound to the function. I run the internal request from the server it spawns the new object and updates the ui on the server only. However when i run the request from the client it correctly spawns the new object but doesn't update the ui for either the client or the server
delegates dont replicate..
then what's the point of a multicast delegate
what would be the correct way to handle this issue
Your code spawns a (replicated?) Actor and then (you were trying to) tell clients to update their UI. This should smell redundant to you - clients should be able to know locally when they are receiving/spawning that actor and know to update their UI
how would they know that
they don't check every tick so i was attempting to use a delegate to tell them hey now it's time to refresh
Depends. Does only one player's UI need to know about this or is it a global thing like a mission objective? You could set your own "OwnedByPlayer" variable from the server and locally in some code like begin play check if the local player is its owner and update UI accordingly. This doesn't feel like it might be the absolute best way to me but it's a start - forcing any local player's UI info or changes across the network is... Questionable at best. Typically, with well designed UI code, the UI reads the game state only, and code-wise your game has no idea the UI even exists... the UI might need to subscribe to some kind of global delegate "NewNeoActor" or something that gets broadcasted by new instances of NeoActors for example. This is very very general discussion, I just woke up and I'm trying to keep my 4 mo old from screaming so I can't put too much thought into this right now, heh
Hey, I'm trying to make a simple third person arena game using blueprints in which the players can attack each other. However, I notice that only other players' movement animations are visible, but when they die or attack no animation is played. What can I do to fix this?
ok so any of the clients can spawn a new object and the ui for each client shows a list off all of the objects that have been spawned. It seems wildly inefficient to have the UI check the gamestate every frame to look for changes so i was looking for a way that whenever a new instance of the onject was spawned i could send a signal to each of the client telling them to update their ui
the ui changes aren't coming from the network just the signal that the ui should be changed
UI should subscribe to a global delegate
And when an object is received. It's "BeginPlay()" or something broadcasts that delegate and the UI responds accordingly
You need to make it handle race conditions too, such as if the object is received before the UI, in which case the UI should get the "list" of those objects and update itself first, then bind to the delegate
ok i think i get the global delegate, but i'm lost on the race condition. If the object is spawned the UI just does a get all actors of class to update the list.
he might have meant to say "before the UI is created" or "before the UI exists"
Typing an example. 2 secs
ahh so basically refresh on create before setting the binding
also looking at this: https://wiki.unrealengine.com/Simple_Global_Event_Systemis there anything wrong with just attaching the delegate directly to the game state?
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnObjectUnRegistered, ASomeObject*, OldMapData);
void ASomeEasilyAccessedActor::RegisterObject(ASomeObject* InNewObject)
{
if (InNewObject != nullptr && !ASomeObject.Contains(InNewObject))
{
ObjectList.Add(InNewData);
OnObjectRegistered_Delegate.Broadcast(InNewObject);
}
}
void ASomeEasilyAccessedActor::UnRegisterMapData(ASomeObject* InOldObject)
{
if (InOldObject != nullptr)
{
MapDataObjects.Remove(InOldObject);
OnObjectUnRegistered_Delegate.Broadcast(InOldObject);
}
}
void USomeWidget::NativeInitialize()
{
for (ASomeObject* DataBase : ThatActorWithTheList->GetObjectList())
{
AddObjectWidget(DataBase);
}
// Bind To UI Delegates
ThatActorWithTheList->GetOnObjectRegisteredDelegate().AddDynamic(this, &USomeWidget::AddObjectWidget);
ThatActorWithTheList->GetOnObjectUnRegisteredDelegate().AddDynamic(this, &USomeWidget::RemoveObjectWidget);
}```
Multiplayer is full of race conditions. You don't know if the UI will exist before the gamestate, or after, or if the objects will be received in some other order etc.
You have to code around that
In that case above, the delegates are in the game state (well, a component on it)
so can't it just add an isvalid check before i attempt to use it
You can, but if the UI is created before the gamestate exists it might not be able to bind to those events
So the gamestate also has to tell the UI when it first exists so that the UI can set itself up
ahh ok
TLDR everything can arrive in random orders so you have to work around it a bit
But that's a pretty general global event for keeping a list of objects and having UI create/remove widgets for them
thanks for sharing that big snippet π
welcome to who's broadcast delegate is it anywhere were the order is made up and process of initalization matters
There's more to it, so the GameState::BeginPlay() will look for all current ASomeObject's that exist and add those, and ASomeObject::BeginPlay calls RegisterObject() etc.
That way it doesn't matter which order they come in
etc.
I would add a wiki tutorial but the wiki has been locked down and it's just full of old tutorials for years now.
ok is there any huge advantage to making this a component on the gamestate as opposed to attaching it directly to the game state
Sorry for interrumptin
If I change levels on the server, will the client follow?
In our case it's a component because it's an optional part of the game
No other reason
ok
ok so i'm going to do this is steps to make sure i understand
first i created a class called UGlobalEventManagerComponent and added the following lines to the header
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnNeoNoteUpdated);```
second i attached it to the gamestate ctor
Header
UGlobalEventManagerComponent* GlobalEventManager;```
Source
```ANeoBase_gamestate::ANeoBase_gamestate() {
GlobalEventManager = CreateDefaultSubobject<UGlobalEventManagerComponent>(TEXT("GlobalEventManager"));
}```
then in the neonote class i added the delegates and their broadcast called
Header
UPROPERTY(BlueprintAssignable, Category = "Note Delegates")
FOnNeoNoteSpawned OnNoteSpawnDelegate;
UPROPERTY(BlueprintAssignable, Category = "Note Delegates")
FOnNeoNoteUpdated OnNoteUpdatedDelegate;```
Source
```void ANeoNote::BeginPlay() {
Super::BeginPlay();
OnNoteSpawnDelegate.Broadcast();
}
void ANeoNote::UpdateData_Internal(FNeoNoteData InNoteData) {
NoteData = InNoteData;
OnNoteUpdatedDelegate.Broadcast();
}```
does that look correct so far?
How can I change level in MP using blueprints?
Hey, I'm trying to make a simple third person arena game using blueprints in which the players can attack each other. However, I notice that only other players' movement animations are visible, but when they die or attack no animation is played. What can I do to fix this?
yeah i'm still lost on exactly what i'm doing. The more i look at the way i set it up the more wrong it feels but i'm not entirely sure how to translate the example
Its really hard to answer not specific questions
I mean, there are a bunch of free tutorials, a nice official documentation, the whole engine source, courses... there's no justification for a non specific question
I'm referring to a bunch of ppl, you included, but maybe i read wrong
i literally leave the most detailed questions i possible can every time just scroll up. I leave code snippets and explanations of what i tried and bp screenshots
from my experience i think its far better to ask simple questions (that doesn't mean they can't be advanced etc), maybe explaining why you need the answer (because some context is always valuable). You are free to ask whatever, but i can assure you may get a lot more help and participation this way
maybe i'm the only one that thinks this way idk
you seem to be misunderstanding how delegates work
what you want to do is put these
UPROPERTY(BlueprintAssignable, Category = "Note Delegates")
FOnNeoNoteSpawned OnNoteSpawnDelegate;
in your global component
then in your note, get a reference to the component and call broadcast on the delegate variable
ok so let me show you what i think i'm supposed to do. I narrowed it down to just one delgate for now and i put it in the global component like this
UPROPERTY(BlueprintAssignable)
FOnLevelControllerRefreshRequired LevelControllerRefreshDelegate;```
Then in the note class in the ctor and the internal update i call it by using
```if (ANeoBase_gamestate* GS = GetWorld()->GetGameState<ANeoBase_gamestate>()) {
GS->GetGlobalEventManager()->LevelControllerRefreshDelegate.Broadcast();
}```
my understanding was that i then need to deal with a race condition for the level controller blueprint and i'm trying to understand exactly how to do that
if you actually put it in the constructor that's gonna crash since it will run for the CDO
should be in BeginPlay or similar
sorry in begin play
typo
now i should be able to bind the delegate in bp's right and it should execute on all of the clients everytime the broadcast is called correct?
assuming we put aside the race condition for now
what makes you think it does anything on clients?
delegates are local, like calling a normal function
ok so then how do i go from here to updating all of the client's ui when the broadcast is called seing as it can only ever be called from the server
should i instead call a multicast funtion that calls the delegate?
the server changes the thing -> the change replicates to clients -> the client version of the thing runs OnRep_Stuff() and you locally call the delegate there
how about when the server spawns a thing
one bit of good news, you can be sure GameState is around when any client Actor calls BeginPlay
beginplay will run on clients
you can't be sure GameState ran BeginPlay, but you can be sure its replicated by then
but instead of calling the update on the internal i should be calling it on the onrep
this is the update code, what i'm understanding is to move it from UpdateData_Internal to OnRep_NeoNoteData
this will work fine as is and execute your delegate on both sides
ok now to actually hook this delegate up to the WB i can use this correct?
the image is too small to read
depending on what ServerUpdateNeoData does, that might loop
client gets OnRep->calls Update-> since its client it sends an RPC updating the server
yep yep good catch
replacing the image
what javish was saying was there i have to prep for a race condition when the ui is constructed as the gamestate may not exist yet for binding
why would you do GetPlayerController[0]?
as long as you connected the Owner pins spawning it
its GetPlayerOwner
with no chance of network wires getting crossed
thing about the GameState (and only GameState)
it replicates a variable that starts the Match on clients
that calls World->DispatchBeginPlay
you can have a hud before you have a game state
(Assuming GameMode, not GameModeBase)
yes, but you can't not have a GameState on HUD's BeginPlay
because without the GS, BeginPlay will never have been called
isn't that only when using the full GameMode thing
idk the full GameMode has all kinds of useless stuff in it
this is the updated binding code
its littered with junk
since the delegate is now on the gs
but the MatchState is handy
only if you really have the concept of a "match" I guess
i don't fully, no, but i still use it to control when the game starts
ok it works now thank you all for the help
after everyone travelled and finished loading
Hello guys! I'm having issues trying to make a dedicated server with steam since 2 months ago. I'm using the Advanced Sessions Steam plugin. The server is not showing up in the Internet tab of steam servers and the "Find Servers" is not working. Already read a lot of posts and tutorials but i cant solve this. Can someone help me? Thanks!
Is someone here a expert or have knowledge about the Server Client stuff in Unreal ? Means Replication RepNotify etc etc ?
If YES please message me :S
Do anyone know what internally happens when i set an array variable replicable? is the whole array sent over the network or only the element/s that are modified?
array defined in BP
@craggy sable in the programming logic should be the whole array. An array is nothing more than all memory adress that alocate variables togheter. If you replicate this, should replicate all those memory adress.
To go off of EvilPyros question, if the array is a bunch of actors who arenβt replicated, that means on a client theyβd all be null?
Asking because I had an array of UObjects I wanted to replicate, but I donβt think those support replication by default?
It doesn't matter at all, I know what is an array, the important part is that every element in an array shall be of the same size. Replacing an element does not require the whole array replacement at all. I'm asking what is the ue4 implementation, not if its possible, i already know that its possible
@craggy sable give NetSerialization.h a read, its documentation inside the header scenario
your statement may have sense if i was referring to a more sophisticated structure like a set or a dictionary, where modifying one element could have implications in the whole structure. I've searched in google a few times and it seems array modification is not entirely replicated, but i'm asking here to be sure since the results i found doesn't seem very legit
@vivid seal that depends on the situation, the way Network Addressing works with Unreal only non-replicated Actors spawned at runtime that don't have a stable name for networking can't be addressed
it doesn't send a pointer, it sends a NetGUID and as long as Actor can be uniquely identified on both server and clients, it can be resolved
your SM_Wall13 you have on your level has that same name on every machine that loads the level, and so the network reference can be resolved
its similar with ActorComponents - as long as their Actor can be resolved, any component on the CDO, as well as any replicated component can be network addressed
so in your scenario, kinda depends where the actors come from π
UObjects do not replicate by default
but if you override ReplicateSubobjects function in their Outer Actor and IsSupportedForNetworking function in them, they can replicate
Iβve been working this in BP, only chose object for them as theyβre essentially just two variables and a function that returns a bool, and created by an actor that is spawned at runtime, so I didnβt want to deal with the overhead of spawning a bunch of actors that only exist for 5-30 seconds or so. I might have to go make the base class in Cpp though or just deal with them being actors instead
@vivid seal What exactly are you trying to implement?
Conditional stat modifiers inside of buff actors. So when I apply a buff to someone it can have these modifier objects that will affect damage or healing or whatever depending on context. The function just takes a combat event struct, checks it for whatever conditions it wants, and returns whether the stat modifier is applicable to the event.
For an example, I have a buff that modified damage taken by fire spells that headshot. When I take damage, each of my conditional modifier buffs is iterated over and checks the event to see if it was fire damage, source was a spell, and the hitbox was a Crit hitbox, and if so, multiplied the damage by the modifier amount.
I need it replicated because some of the conditions could affect spell cast time βreduces cast time of spells again x type of enemyβ and I am client predicting cast, Cooldown, and Global Cooldown, so the client needs access to the modifiers to prevent having huge inaccuracies all the time.
@vivid seal Any reason you're not using the GameplayAbilities?
Are you predicting buff application?
Didnβt know any c++ when I started the project, so the setup looked intimidating. Wanted to make sure I could account for all of the things I had planned and implement them how I wanted. I honestly donβt know enough about GAS but I know they donβt client predict things like Cooldown timers and cast bars, so I wanted to be sure.
Plus rolling my own is a big learning experience.
No, not predicting buff application, but the objects are spawned after application
Oh shut
I could just spawn them on client couldnβt I
It is a giant pain in the ass. I rolled my own for spells and buffs because I have a ton of stateful ones. I went with buffs and spells as components.
Theyβre static so it would matter
Wouldnt*
It is a giant pain in the ass but I have the majority of it figured out at this point.
If everything's static you should be able to just go with buffs as data.
You know I mean the gas is a giant pain in the ass
Oh, yes Iβve heard that as well.
Buffs can do a lot of things, this is just one of their functionalities, and I need that function that checks condition so I canβt just use a struct
But the modifiers wonβt change at runtime so I could just spawn them on both client and server not replicated
Dunno why I didnβt think of that
The buffs themselves arenβt static but that particular functionality doesnβt involve any changing variables on the buff or the modifier objects.
I wonder, has anyone implemented a sort of actor spawning prediction?
Like spawning locally, and then replacing/editing when the server sided one comes back?
@vivid seal why are those modifiers not on the CDO, or loaded from a DataAsset?
Guys...i have a problem with my project
@ivory lintel what
I using Multisphere trace to get my targets...only valid when skeleton mesh component is hitted
when I do sphere trace with my client...works fine and get targets...
but when i Try to do the same with my AI controlled NPC
him don't get anything
quick Q - GameMode::DelayedStart - when i have this set to true, and i try to draw widgets (HUD) on my playercontroller it wont show up - Set this to false and same code... they show up fine.. what am I missing?
Same function/event?
if do the sphere trace with client and try to replicate the targets with RPC to my server...the RPC don't run
You're asking like 12 questions at once. Is the sphere trace itself working right in all instances?
i'm doing the spheretrace in tick of my animation montage state
works fine to players
oh fuck no lol
???
WHat do you mean it "works fine to players"? Does it work fine when a player character is doing the tracing, or when hitting a player character?
UAnimInstance is not supported for networking
means can't RPC
animation instances should also do no gameplay logic, nothing requiring access to World
if you want to trigger it from animation do a notify and handle tracing inside the paw
n
Yeah don't do the tracing in the animation, make a function or event in the pawn and fire it
i'm create a actor component and put this in my component
I can make a the trace inside a function of my component?
you can, and you can send the RPC as well from there
provided the component itself is replicated
@dark edge or @winged badger this way???
now the problem is: The server don't reach collision with skeleton mesh and don't do any collisions with left hand socket
this is my trace function...you can see anything wrong?
right socket don't find any target
left socket find some target
only have this problem doing the trace on server
if server don't run animations...how to get right bone hitted during a attack???
Example: I wanna to make 2 AI fight between and don't need a player on combat
how AI will get the right name of bone hitted
???
how server will make the right trace when attack?
well, by default it doesnt. theres a checkbox under Optimization on the skeletal mesh i believe. it basically doubles (or more) the cost of it all though
actually i think its a dropdown tab something like "update bones and refresh pose" or something
this?
the drop box above that that says always tick pose. i think theres one thats always tick pose and refresh bones
i dunno i dont have it open right now
???
yes its identical to what i just typed
also dont need the whole damn screen just clip the part u need
just keep in mind thats a pretty big hit to performance
yep...you are a super hero
i believe theres a way to set the skeletal mesh tick rate (for that setting there). do something like when in a safe area or out of combat etc, set it low. only make it faster when u need it
i'm trying to do a multiplayer action combat system
i can guarantee most dont use per-bone/server animation for a reason
ty
u can rarely be sure of the accuracy of somethings position to the point where it would be used like that
ud be surprised what u can do with hitboxes or simple traces
on an unrelated problem. anyone know how to handle lost (or maybe late?) packages. [2020.01.22-20.39.31:751][872]LogTemp: Warning: DistanceBetweenUpdate: 4.576660, Within Tolerance [2020.01.22-20.39.32:776][995]LogTemp: Warning: DistanceBetweenUpdate: 9.769623, Within Tolerance [2020.01.22-20.39.33:743][111]LogTemp: Warning: DistanceBetweenUpdate: 5.067805, Within Tolerance [2020.01.22-20.39.34:744][231]LogTemp: Warning: DistanceBetweenUpdate: 5.173212, Within Tolerance [2020.01.22-20.39.36:052][388]LogTemp: Error: DistanceBetweenUpdate: 183.223694, Correcting Location [2020.01.22-20.39.36:777][475]LogTemp: Warning: DistanceBetweenUpdate: 9.843454, Within Tolerance [2020.01.22-20.39.37:777][595]LogTemp: Warning: DistanceBetweenUpdate: 9.371847, Within Tolerance [2020.01.22-20.39.38:785][716]LogTemp: Warning: DistanceBetweenUpdate: 13.415794, Within Tolerance [2020.01.22-20.39.39:868][846]LogTemp: Error: DistanceBetweenUpdate: 73.230103, Correcting Location [2020.01.22-20.39.40:751][952]LogTemp: Warning: DistanceBetweenUpdate: 8.435667, Within Tolerance [2020.01.22-20.39.41:751][ 72]LogTemp: Warning: DistanceBetweenUpdate: 4.167860, Within Tolerance [2020.01.22-20.39.42:786][196]LogTemp: Warning: DistanceBetweenUpdate: 8.296682, Within Tolerance [2020.01.22-20.39.43:744][311]LogTemp: Warning: DistanceBetweenUpdate: 8.271205, Within Tolerance i believe the huge spikes are from packets maybe being out of order. only pops up when i use Net PktLag for testing
@winged badger just saw your reply, I honestly have never used a Data Asset, I will check them out. How do CDOs work? Is that the same as using BP Get Class Defaults? If so, can that access functions
if modifiers aren't added at runtime in an unpredictable way
they don't need to be replicated
each instance of a buff on each machine can instantiate their own modifiers separately
just needs to know which ones
Yeah I have an array of class references to the modifiers that spawns them when the buff is created. Is there a way to access the function to check the modifier without actually instantiating the modifier, just from the class. This is in Blueprints for reference.
They will not change at runtime
//.h
UPROPERTY() TArray<TSubclassOf<UMyBuffModifier>> ModifierClasses;
UPROPERTY() TArray<UMyBuffModifier*> Modifiers;
//.cpp
void BeginPlau()
{
Super::BeginPlay();
for (TSubclassOf<UMyBuffModifier> ModifierClass : ModifierClasses)
{
Modifiers.Add(NewObject<UMyBuffModifier>(this, ModifierClass));
}
}
and everyone has them
Okay, that was the setup I had but didnβt think to just spawn them on all clients instead of replicating. Thanks
if it doesn't change you don't have to replicate any ofit
Yeah, just a dumb moment. I donβt replicate anything that doesnβt change but it didnβt occur to me that that should also hold true with objects and actors and not just plain data types.
Lol
Why does playerstate ping report 1/4 of the real round trip ping time?
Ah, so it can fit in 1 byte
I have to make a pretty big design decision with my game. I have 2 options. This is for a modular vehicle building/combat game, like a multiplayer KSP with ground vehicles.
Should I...
- Have vehicle building be clientside, with the gameplay vehicle created on server when spawned. With this approach, all players can use 1 garage under the map, and it seems as if they have the place all to themselves. Changing state between construction/driving involves destroying 1 vehicle and building the other.
or
- Have vehicle building be live and on the server. Other players could see your vehicle in progress (Cool for collab I guess), and there's a garage on the map per player. CHanging state between construction/driving just involves teleportation and turning on physics.
I've implemented both for testing. Option 2 is what I have right now, but it feels like it might get a bit messy in the future. What do you guys think?
the vehicle not responding immediately to player pressing a button during the building phase is terrible UX
and the players will feel it far more then lag ingame
as there is nothing else holding their attention at the time
having vehicles in progress visible to other clients isn't really affected by option 1 or 2
as you're basically building a struct that defines the vehicle construction, and its easy enough to replicate - letting the other clients build the simulation of the vehicle on their end
Yeah that's option 1 and is how vehicles are saved.
In option 2, whatever live vehicle is in your garage just gets dropped to the ground to begin gameplay. The struct is used for saving/loading/respawning.
i'd go for more responsiveness during the vehicle construction - simulate them locally
that last bit isn't really a big pro, replacing it with a game ready vehicle is trivial
it can even look like you just dropped it on the ground
any lag there might make players decide that the game is laggy and/or unresponsive during the onboarding
I think I can still do construction live with instant feedback. The server view will just be parts teleporting around, but the local view is a drag and drop. On drop is when it's sent out to other views.
This is some fun debugging tho. Modular physics is a bastard. Right now I'm trying to get join-in-progress working right.
that creates some net addressing issues
you can't spawn stuff on clients then make it replicated
Yeah the spawn will have the ping delay
that leaves you in grey area of IsNameSupportedForNetworking
good point
and that is, single name mismatch and client gets booted out of the game
(wouldn't allow stuff to be replicated, but net addressing would work)
Yeah as is, the spawn is handled by server so ther'll be the roudn trip before it's visible
but with packet loss and packets arriving out of order, that is really nasty to keep in sync
ok so my rpcs aren't actually firing. I hit the breakpoint at UpdateData() but none of the others even though i am in DebugGameEditor
what have i missed?
I'm a bit new to networking, I think I've read most resources but it seems an rpc defined in an actor its not working, the same code works perfectly when its on a PlayerController. Its strange because i can replicate a variable that is stored in the actor when i edit it from an rpc in the player controller, but i cant do the same when i have the rpc in the actor.. Maybe someone can point the issue
pyro that is exactly what i was having a problem with
its an executed on server reliable rpc
it's because the server owns the actor you are trying to modify. so if you try to call to the server directly from a client the call gets dropped instead you have to create an interface to request the server to modify the property
give me 5 min to type the example
I'm doing it in BP
it's the same issue i believe
you have to create an interface that is accessed from the player controller
it's this page of the network compendium
i always forget about it
ohhh
yeah i somehow manage to forget about it every time i replicate a new variable and spend an hour trying to fix it until i remember
only multicasts can run from a non owned Actor
RPC's can not.
like ClientRPC/ServerRPC
Is a client-target build capable of running a level locally while waiting for matchmaking to find the client a server to join?
I'm just trying to figure out I can get away with shipping a stripped down client or if I will be forced to ship a standalone client and build logic to block attempts to load unauthorized maps locally
a client build can load all maps locally. it just lacks the code required to host a listen server that is included in normal ones
Perfect thank you
Was worried it couldnt and was thinkning how the hell is this going to work lol
Yesterday I was having a weird issue with an RPC call in Tick in my character class. All the call did was set an unused variable on the server, yet it caused the player movement to entirely stop replicating. Other networked things like look direction worked fine. Commenting out the call or calling it from a non-tick function solved the problem. Any ideas why this happened?
Yes, it was being called every tick until I fixed it. It was Reliable and only being called on the owner
calling a reliable RPC fuction every tick is going to kill your whole network
if it's something that gets called only occasionally that happens to be in your tick function, then it should be okay
Gotcha, not sure exactly on the terminology but to summarize it would be using up all of the allocated network bandwidth since it's called so often, and since it's reliable it takes priority over replicating movement?
Reliable functions ensure that the network packets arrive. If they don't arrive, they get resent. Unreliable means if the packets don't arrive, it just doesn't get send (good for repeated updates like movement, where even if you drop a few packets it'll get updated eventually anyway)
RPC functions on tick are almost always incorrect architecture, but even if they are they should never be reliable because it gets updated every tick
Thanks, I knew what reliable RPCs were but I had no idea that they could be such a problem π
Sometimes I feel like using Tick at all is incorrect architecture
You should probably feel deep pain and dread at putting anything in Tick
there are obviously use-cases for tick and it is a useful tool in the toolbox, but should be used with care
Definitely. Right now all I have there is debug line/text calls, and even that is overkill since the variables they represent aren't being updated on tick
Yes, they should definitely be event-based. If it's just a quick hack to see a variable sure, but the debt adds up the more you do it
Try to really lean into OnRep functions
UPROPERTY(ReplicatedUsing = myfunction)
Oh yeah, don't worry I almost always use those over normal Replicated variables.
Yeah so you've got the idea. Just keep your network clean π
on a similar note, do you have much experience with FSavedMove for replaying/correcting player actions? I half-understand it but it's such a pain that I've been ignoring it
Haven't touched that unfortunately
gotcha, I'll keep ignoring it then. Thanks for the help π
@pulsar maple @rancid barn Using tick is fine if it's used for something that must be done at high frequency.
Oh definitely. But I feel like there's usually a better option with what I've been working on recently.
When I first started learning game dev with Unity I relied way too much on Unity's Tick equivalent and was confused why performance sucked so bad LOL
Is there an in depth tutorial on the character movement component somewhere? Trying to read the source is giving me a headache, and the documentation leaves a lot of details out.
AFAIK the comments in the source are your best bet. I understand most of it but only after spending a lot of time trying things, discovering a networking issue, then looking for a solution to that issue in the CMC source
Trying to do a GetAllActorsOfClass inside a spectator pawn doesnt let me use GetWorld(), any ideas?
nvm was missing an include
can a replicated variable be received out of order?
@steady briar out of order with itself?
I'd guess it can. Not sure though. In what scenario would that be a problem?
Anyone here with custom movement experience?
I'm trying to follow https://wiki.unrealengine.com/Authoritative_Networked_Character_Movement but I've bungled something. My clients replicate properly to the server, but the server doesn't replicate to clients.
You can't receive a previous "Version" of a replicated field, no. But fields can populate 'out of order' from other fields.
it is possible for clients to miss certain values of the replicated variable too. if server sets 1,2,3,4,5,6,7,8,9 really quickly the client could see 1,4,5,6,9
That's still in order π
Hi there, something is wrong with my animations when launching the project in multiplayer. Animations of the posseded player in the client app got weird animation as you can see. I really don't know what is going on and did not find relevant info on the web about that (except turning off camera orientation toggle in character, but it doesn't help)
For Info, everythings works great when launching without multiplayer. My animations are from mixamo, I'm using GameplayAbilitySystem but pretty sure it's not related.
Does anyone already had something like that ?
@dark edge im periodically replicating an actors location on the server to the autonomous proxy, to see if it needs corrections. most of them say its well within tolerance, but occasionally i get one thats quite a bit off. problem goes away when i stop simulating packet loss. so... not sure if theres a way to see if a packet is old and disregard it
or.. is there a reason it might send the same info twice even if it was received? hmm...
That's well handled on the low level, so if you're getting something twice, it's likely user error and not something messing up with the packets themselves.
ya i printed the actual location, its not a duplicate
just now and then, when i am simulating packet loss, i get one thats quite different
If you want a sanity check you can always check the 'bunch' information while breaking on the replicated field or rpc
ya i have 0 idea what that means
It's all super low level stuff way up the stack trace.
well whats weird to me is... if 1 was wrong and i relocate the actor to match... wouldnt the next one be correct and also far away enough it would snap back?
How does a replicated property behave on the client-side in terms of it reflecting the newly set value that the client has set through a Run on Server node?
E.g. client pawn calls Run on Server where he calls Set on a replicated variable. Does the set execute instantly on the client? Since it is gated by a Run on Server, he has to wait for a roundtrip from the server to receive the update locally?
Yes, you would need to wait time equal to ping for the client to get the updated information
So if I need an instant update on the client to feel snappy, should I keep a local duplicate of that variable? Would calling the Set node on a replicated variable from the client set the value locally or just do nothing?
If you locally set the value of a replicated variable, it will change locally. The next time the object gets updated over the network, if the local value is different from the server value, it will become the server value
I can then just call Set, then Run on Server, and Set again there π
Yes. That would give you instant reflection locally, and if the server happened to disagree with what the client did, it would get corrected on the next network update
Thank you so much
happy to help
Do clients have any built-in way to know the other clients <facing/aim/control rotation>?
Should I just replicate the pawn's "Control Rotation" to them?
I believe you can access the base aim rotation from the pawns
Return the aim rotation for the Pawn.
Although if you want to have an aimoffset sort of rotation then you're probably going to need to replicate at least one value yourself
I want to have a replicated array of pointers to UObjects. I know that overriding AActor::ReplicateSubobjects allows for the replication of UObjects, as long as UObject has the actor as its outer. I'm doing this for the first time so I'm not very familiar with how outers work, especially in relation to this particular funtion
Could I have one of the actor's components generate the UObject, or does the actor directly need to create the UObject for ReplicateSubobjects to work?
ah, there's a UActorComponent version as well UActorComponent:ReplicateSubobjects, I'll try that
@twin juniper Control Rotation should already be replicated I'm pretty sure.
But Player Controllers don't exist on other clients
so I believe nothing at all is replicated
Control Rotation is not on the Pawn, but on the PC
@dark edge what you're probably thinking of, is the fact that the default Character has checkboxes for automatically using the PC's Control Rotation as the rotation of the Pawn
Yeah it's something like that. Anyways, it should be easy enough to just copy Control Rotation to a variable on the Pawn and replicate it out. I think that's what I use.
@unique kelp thanks that actually works!
Guys i have a question about passing actor references in RPC. Imagine I have two separate UI windows with slots in both of them. Every window has a referece to its own actor component than handles some functions to manage the slots. So now if i click on window A, I call a server RPC in the component reference of that window (OnSlotClicked), but I also want to pass as parameter the component reference of window B. So, what would be the value of the component B parameter reference on the server?
can't resolve references to widgets over network
Its not a widget reference, it would be an actor component reference
or send RPCs from inside widgets
the Component would have to carry that
Component is Network Addressable if - its loaded from a package (default component on a pre-placed actor)
but those can't send RPCs
if its Replicated (has to be a component on a Replicated Actor)
those can send RPCs
or a default component on a Replicated Actor (no RPCs)
The component is on the player character, so i think it should work
if you are woprking with BP, "default component" is anything visible in components panel on the Actor BP
as long as your Component meets any of the NetworkAddressable requirements, you just push a reference to it as an input on the RPC
and the NetDriver will figure out the rest
Lets see if it would work
Give me a moment to prepare an screenshot
Thnaks anyway Zlo π
Because maybe im not approaching it correctly
My system is not multiplayer already but i want to prepare the events to make it RPC compatible, because i was passing whole widget reference to them (the UI slot) so it wasnt multiplayer compatible
So, when the RPC is triggered, i want to pass the player inventory component as the storage needs to know it. As the inventory component is owned by the player character, it should work i think
I you need something more clear just tell me
RPC has to go through the InventoryComponent
you don't own the storage component to send a server/client RPC through it
So maybe just creating a TransferItem RPC in the inventory component would do the trick?
And passing the storage component as parameter?
as long as storage component is pre-placed, default component on a replicated actor or replicated
yes
Is there info on accessing USB/Ethernet port within UE (e.g. to send messages to a Raspberry Pi or listen to a broadcasting IoT device). Thanks!
@lilac stream For USB you would probably need to implement a serial communication library in a plugin. Searching on github reveals there are a couple repos that claim to do this:
@steady tendon I solved this originally with having two components. An InventoryComponent that I can add to the Player, the Chest, etc.
And an InventoryManagerComponent, that sits on the PlayerController and allows RPCs to go through.
This is used to move items between 2 InventoryComponents (could also be one and the same).
Not sure if that helps you, only quickly looked over the chat.
UE4 does have anHTTP library that you could use to communicate with your devices over the internet
@thin stratus @winged badger Thank you guys. Yeah eXi that would do the trick, because at the moment i only have what you say as your InventoryComponent (I call mine ItemsContainer) because i havent implemented multiplayer. As Zlo says, i would need another component to handle those RPCs owned by the player character or controller
Yus
Any extra advice? Hahahaha
I suppose you have finished something similar to this type of system
if you have something with custom logic - say a crafting bench
Hm, yeah for the marketplace.
you might want to consider having interacting with it spawn a replicated component on your PC/Character server side
instead of pre-packing all network logic there to begin with
lets you... extend what your networking can do without modifying the PC/PS/Character
The assets you saw on the screenshot were judt to test
Oh i misunderstood you
Right now the component is pre added to the player
Hello guys! I'm having issues trying to make a dedicated server with steam since 2 months ago. I'm using the Advanced Sessions Steam plugin. The server is not showing up in the Internet tab of steam servers and the "Find Servers" is not working. Already read a lot of posts and tutorials but i cant solve this. Can someone help me? Thanks!
You got your app ID set right?
Im having a really frustrating problem with my variable replication. in my blueprint im trying to grab the specific playerstate of a character through the game character the player is possessing. The server gets all the right playerstates but on the client side they do not. The problem is that the variable goes to building a 3D widget so for clients its gonna grab the incorrect player state and show the wrong name. Im trying to figure out what im doing wrong with my replication
Why is it grabbing the incorrect player a state?
Are you grabbing the pawns controller or just controller 0?
heres my code
when I print string of player state after casting to Game Character the server displays the right variable but the client has the wrong variable and im trying to figure out why its getting 2 different results
If i was just trying to do a server action I wouldnt care what the client has but since im trying to make a 3D widget that all the players see the same so I cant really ignore it
Okay first of all WTF. Why do you have a delay in your for each loop?
What exactly are you trying to do? Just say what game affect you want to happen when something enters that trigger.
Hi! I'm a replicate-noob. I'm trying to replicate my GiveDefaultItems-function, but I'm getting some errors.
Error C2556: 'void AaCeProjectCharacter::ServerSpawnDefaultItems_Validate(void)': overloaded function differs only by return type from 'bool AaCeProjectCharacter::ServerSpawnDefaultItems_Validate(void)'
Note: see declaration of 'AaCeProjectCharacter::ServerSpawnDefaultItems_Validate'
Error C2371: 'AaCeProjectCharacter::ServerSpawnDefaultItems_Validate': redefinition; different basic types
Note: see declaration of 'AaCeProjectCharacter::ServerSpawnDefaultItems_Validate'
The code: https://pastebin.com/JpdZYuf2
@sand tangle why are you replicating the giving of the item instead of replicating the state? I guess what I'm asking is why are you replicating the function instead of the data?
@dark edge That's a good question. π hmm
you can ignore the delay I just put it there to make sure it wasnt cause of it was replicating at the improper time
@quaint coyote any particular reason you aren't just using the overlapping actor whenever the event fires?
cause I want it to clear the widget list anytime a new player enters the box so I thought it would be easier to have it get overlapping actors when a new player entered. when a new player enters the box it clears the current 3D widget list and creates a new list based on the current players in the box
@dark edge Could you give me some tips on how I should proceed to replicate data? (AWeaponMaster and AMagazineMaster).
@quaint coyote k first off you should clear before looping
you right
Also you're gonna clear when non characters enter it. Instead you should cast overlapping actor to your character, and if it succeeds, then add that actor to an array and do the widget stuff on that array.
So you'll always have an up to date array of all characters in the box.
Same logic on end overlap except remove from array and reconstruct widgets
What actor does this function live on?
it lives on a blank actor with a widget component and a box collision component
@sand tangle it'll depend on how your stuff is set up. Is a weapon just a class or a struct or what?
@quaint coyote depending on how gameplay centric it is, you'll want some of the stuff gated behind an "Is Dedicated Server?". Widgets don't really exist on the server.
Is the GameCharacters Player State a variable you made or built in?
it is already built in to the character
I mean is it added or stock Unreal?
@dark edge Weapons are instances of AWeaponMaster. A Class with datastructs and all that. Same with Magazines. AWeaponMaster and AMagazineMaster are also an array on the character.
ah no its one I created and have blueprints inside
@quaint coyote Ya don't do that. Just go from pawn to controller to playerstate.
ok ill try that out
@dark edge Is it enough to replicate the weapon and magazine array with Condition OwnerOnly?
ok so would I be able to create an array of playerstates via run on server events and then after the array is successfully made then being able to replicate the array out to all clients or would the other clients see the wrong playerstates
and I shouldnt make the array of Player controllers cause the other clients wouldnt be able to recieve the data
hey guys, is there a way to determine who ended a session? (e.g. server vs client?)
I'm trying to display a message box saying the server shutdown... but if the client leaves the same message box appears
as the session is "destroyed" either way
@quaint coyote everyone already has an array of playerstates. It's inside the GameState.
gotcha
Actually rereading your question. Yeah you can do that. Repnotify the player state array and use the notify to rebuild the widgets clientside
Only the server will be able to associate a pawn with it's playerstate as the clients can't see all the controllers.
@sand tangle Arrays of classes?
gotcha ill have to read up on repnotifys cause I havent used them
@quaint coyote They are awesome and the best way to have state drive transitions.
@dark edge ```
/** INVENTORIES /
UPROPERTY(Replicated)
TArray<class AWeaponMaster> Inventory_Weapon;
UPROPERTY(Replicated)
TArray<class AMagazineMaster*> Inventory_Magazine;
Ya that'll work. You should do the actor spawning on server only tho.
Hey guys, anyone know if theres anyway to change the GameServerQueryPort in a packaged game?
Maybe someone can help me out here?? I have a crazy hard to track issue. Dedicated server, whether windows or linux, will sometimes hang. Timing seems random. It stops receiving connection, stops output to the console, yet the profiler (which shows nothing of note) continues tracking..
@bold dune predictable in any fashion?
Nope
Could be 5 minutes in, or an hour
It'll happen with no players connected if the AI is battling it out
Does it do it from servers launched in PIE or just standalone?
I've only seen it in a packaged server BUT I wouldn't rule out pie.. just haven't witnessed it
it can take a long time sometimes..
the more AI actively playing, the faster it usually happens.. but that's not necessarily the fault of the AI but their interactions which even a playe rcould do
Memory leak?
If I only cared about player experience (in a listen server setup), should I just make it client authoritative?
So when a player hits something (or gets hit), it sends that resulting damage to the server, and the server takes it at face value (I don't care at all about hackers).
Are there any weird downsides to client authoritative setups?
in my view it is always important to maintain some level of server authority for player movement, but it makes sense in a lot of cases to rely on clients to provide damage info (i.e. tell the server what they have shot)
I would really like player movement to be client authoritative if reasonably possible.
Like if the player would use some ability that should very quickly move him and want to avoid the server snapping him back due to latency.
I know that you can set a bool for that, but seems like there could be unforeseeable problems.
the CMC has an entire system built 100% purposefully for exactly that though
it's complex to work with the first time and could have some limitations if your systems are super complex
But the amount to move him is not fixed.
Like with launching the player. The server or the client doesn't know how much to launch him.
what controls the distance client-side?
It would be gameplay items that are random. Like a roguelite.
And I don't think the FSavedMoved/replay stuff in CMC want to take in parameters for this sort of thing.
Oh well, either way, so you think that clients authoritative is the way to go, in my case? The goal is most responsive and fluid gameplay. To hide as much latency as possible (and easily).
the only thing that scares me about going full client authoritative is if you ever have something in your game that pushes the players like piston traps or something, the character might look really bad on the server/other clients if the server thinks they got hit but the controlling client doesn't. but yeah the basic savedmove implementation doesn't store a lot of data so if you need to pass a lot of randoms across the network, another approach may be in order. it's all pretty modular so you might be able to "simply" set it to client auth for now and build your game, work on a solution later on if it becomes a problem
(it is possible to add data to it though - it's been a year since I did mine so I'm rusty on remembering it but I know I added a "sprinting" flag to the struct and pass it across the network)
Thanks. It's actually currently all server auth now. So... I have to do a bit of refactoring.
(oh wait, I think I just used the compressed flags so no I didn't really add anything to it lol)
Hey guys! question... Backstory: I am using an inventory system in my MP game and everything was working fine when it was housed on the character. I moved it over to the player state to house items in the event the player dies and needs to respawn with items etc. So now i'm having a hard time getting the server to change inventory items on the player state. What would you recommend?
@hollow iris What part is giving you the hard time?
So the player is calling a server function to change the item on the Inventory component... I have an on rep function when the item is changed do (stuff on character). It seems like the server is never actually changing the item on the inventory component but just on the client atm.
Server -> EquippedItem(RepNotify) -> Do stuff on client
Just wondering if its a issue with the component being on playerstate since it was workign on the character
TSubclassOf<class UInventoryItem_Weapon> EquippedWeapon;
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Server, Reliable, WithValidation, Category = Inventory)
void EquipWeapon_Server(TSubclassOf<UInventoryItem_Weapon> Weapon);```
```void UInventoryComponent::EquipWeapon_Server_Implementation(TSubclassOf<UInventoryItem_Weapon> Weapon)
{
EquippedWeapon = Weapon;
}
void UInventoryComponent::OnRep_EquippedWeapon()
{
}```
What class is doing the RPC?
The character atm. (Calling the function on the component)
So did you add an inventorycomponent to the playerstate as well? I suppose to act as a stash?
The character has a tweakobject pointer to the inventory component that is assigned on repPlayerstate
Playerstate has the actual component
Yeah I'm not sure you can call an RPC on playerstate, sec
kk, that seems to be the case from what i can tell
For gameplay programmers writing C++ code.
Where does the RPC live?
On Playerstate in the Inventory component
So it looks like i need to call the rpc from the character to change the data on PS
uh
most things should go through controller
I'd check that you're not able to call that function. Maybe make a test one to see if it makes it to server
This seems to work for me
Is your setup equivelent?
That's all in playerstate
wait do you even have a valid playerstate reference when you're trying to do this call?
it has to replicate out
yea its valid
I'd put the inventory in PlayerController myself. PlayerState is public, PlayerController is private
unless things should be public
They need to be for trading / looting etc
Not necessarily, those would be done on server
I mean playerstate is public to clients. every client sees everyone elses playerstate
Anyway, it should be working
From the Character -> Get Inventory Component (Tweak assigned on rep playerstate)
it is
Does the call make it to Playerstate? I mean up to the RPC?
It doesnt seem to be hitting the server. Im thinking it may be a owner issue with the component being on playerstate maybe?
I could just have the Playerstate house the inventory
instead of using a component
not sure
That shouldn't make a difference. Does an RPC through playerstate work? I mean one not on the component?
let me see
yea it does
sorry was trying to test in cpp and it was taking forer haha
So weird.... I switched the function to:
{
if (ROLE_Authority)
{
GEngine->AddOnScreenDebugMessage(-1, 1.5f, FColor::White, TEXT("Server!!"), false);
}
GEngine->AddOnScreenDebugMessage(-1, 1.5f, FColor::White, TEXT("Not Server!!"), false);
}
and it does the RPC
Will just have to play around with more i guess
So I think i figured it out... Will have to do more testing
Seems like it does have to do wht the component not having an "owner"
I'd put it on the PlayerController IMO and have the PlayerState just be a bag of state. Or do the RPC through the PlayerController but have the state live in PlayerState if it must be public to everyone.
Yea, that's the plan. Im gonna have the playerstate house the actual inventory and use a "manager" to do the rpc calls
I need the inventory on PlayerState to be consistent for logging off and back on etc.
@hollow iris keep one thing in mind on level transition the player state data clears
It's a persistent world. But that is good info to know.
But you could use CopyProperties to copy stuffs from old PlayerState
Gotcha
And PlayerController has Old player state as well
And new player state also
Rest you can figure out
Yea, that is good info haha I've mostly worked on gameplay related coding so all of the level transition / data wipe stuff is new to me. Will have to tackle that as it comes. π
Nowadays I m working on ASC
Same, my gameplay is ASC based as well.
That's also why I wanted the inventory on Player State. The items determine GA's and GE's on the pawn.
(ASC is on PS)
So r u planning to use PS to have all logic of inventory
That was the plan. Looks like I need to split it into 2 parts though.
Yes and never tightly couple features
Have an "Inventory" and a manager to move things around.