#multiplayer
1 messages · Page 246 of 1
What about keeping a buffer or received moves on server in hope that it will be enough to keep a steady flow of moves to tick?
Would the extra introduced lag be worth it?
Yeah that's what NPP does fwiw. It keeps a buffer of 2 to 6 frames.
The problem you run into with that is that it will be even more difficult to sync the CMC to outside CMC. While that barely happens, the Server would then end up performing older moves in a world that is newer.
I can imagine that being a bit of a headache.
the issue is that there’s no fundamental problem but if you watch the video carefully you’ll notice that the character’s animations are jittering. I’m not exactly sure what’s causing it I haven’t made any changes and I’m using the default TPS Template.
Doesn't that happen regardless since we are waiting for the server rpc to arrive?
Also i have a question, since you are working with mover, i guess you had do deal with this problem already. What are some things that i would need to pay attention to if i implemented a buffer?
I guess the main difference is that with Mover you are relying on NNP, which means that everything is kept behind by 2 to 6 frames. While using cmc only the moves would be buffered, so if i send a rpc, the move produced on the same tick will be used by the server way after the rpc is received, due to the buffer
What do you mean with "implementing a buffer"? What buffer do you want to add?
You mean the Input Buffer into CMC?
If you want to do that for CMC, I assume you'd need to:
- Obviously create some form of FSavedMove_Server but on Server-side. Optionally extendable if you want to inherit from the CMC and add more to the FSavedMove_Server.
- Split the Movement logic out of the ServerMove RPC, and let that thing only add into the buffer.
- Process the Buffer during TickComponent if it's large enough, otherwise skip.
- Handle faults, where the ServerMove RPC hasn't arrived in a while and increase the buffer limit in that case.
- Potentially need to send multiple packages, not just one, so the Client can send potentially dropped input packages alongside the new one.
- Might also need to handle overflow of the buffer, when the Client sends updates faster than the Server can process them.
NPP works largely different than the CMC, so there is probably a lot more to code and be aware of.
Yes a buffer of received moves on server.
Thanks, i might actually give it a try at some point. Even tho i'm not sure it is worth it lol
hello friends does anyone know if the network emulation feature is accurate. im currently deciding whether or not to use client predicted hit markers and hit reacts so i set the latency to 50ms for everyone. with no client prediction the delay is massive. on a game like marvel rivals when the latency is 80ms the hitmarkers and stuff is pretty much instant even though i can confirm marvel rivals does not predict hitmarkers and hitreacts cuz when i switch to a high ping server theres a delay.
I wouldn't predict hit markers. They should only play when damage was actually applied, else it is kinda not intuitive for the player (imagine seeing an hit marker and no damage was ever applied). Projectile impact particles and sounds, plus blood splatter should be fine to predict. Hit react i'm not sure if i would, for the same reason as hit marker
yeah im leaning towards no client predicted hit markers but the latency at just 50ms is incredible. plus this is for a casual coop game which will always trust what client says it hits so idk
Yeah, I definitely wouldn't predict hit markers. The point of them in a sense is that a client can be certain the server accepted that hit
Also, under good conditions, you would receive the hit marker and the targets new health at the same time, so things would correlate more
We even skipped playing blood effects on hit targets in HLL until the characters new health data was received, because players complained about seeing blood but not damaging people.
did you set both incoming AND outcoming data to 50ms? cause i think those add up
ye i did but wouldnt that add up to like 100ms
50 incoming + outgoing on client and server equal 200 ms RTT
oof
Whats RTT ?
If i may ask
Hey, so I have made my own little weapon pickup system, by creating a custom class off of USkeletalMeshComponent to serve as a base UWeaponBase then creating deriving classes off of that for each weapon (i.e. Pistol, AR, etc.), so for the most part it works however there is an odd bug I can't seem to figure out for why that is happening, where only on the client when I attach the weapon component to the player, a duplicate model is spawned mid-air of the last position, I genuinely don't know why that is occurring.
I made it a component as I wanted to have an easier making different firing mechanics for different weapons
Player Character class
void AArenaCharacter::EquipWeapon(TSubclassOf<UWeaponBase> weapon_class, EPickupWeapon hand_slot)
{
if (weapon_class == nullptr) { GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, TEXT("Passed in weapon class is invalid!")); return; }
FTransform transform = {};
auto new_component = AddComponentByClass(weapon_class, false, transform, false);
UWeaponBase* new_weapon = static_cast<UWeaponBase*>(new_component);
if (hand_slot == EPickupWeapon::LeftHand)
{
if (LWeapon) { LWeapon->DestroyComponent(); }
LWeapon = new_weapon;
LeftWeaponChanged();
}
if (hand_slot == EPickupWeapon::RightHand)
{
if (RWeapon) { RWeapon->DestroyComponent(); }
RWeapon = new_weapon;
RightWeaponChanged();
}
return;
}
void AArenaCharacter::LeftWeaponChanged()
{
LWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::KeepRelativeTransform, "WeaponL");
FVector rel_loc = { 7.305939f, -2.074861f, 0.856694f };
FRotator rel_rot = { 7.849671f, -7.375999f, 168.191764f };
FVector rel_scale(0.5f);
FTransform transform(rel_rot, rel_loc, rel_scale);
LWeapon->SetRelativeTransform(transform);
leftHandWeight = 1.0f;
GEngine->AddOnScreenDebugMessage(1, 2.0, FColor::Yellow, TEXT("Equipped to left hand!"));
}
void AArenaCharacter::RightWeaponChanged()
{
RWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::KeepRelativeTransform, "WeaponR");
FVector rel_loc = { -7.305939f, 2.074861f, -0.856694f };
FRotator rel_rot = { 7.849671f+180, -7.375999f, 168.191764f };
FVector rel_scale(0.5f);
FTransform transform(rel_rot, rel_loc, rel_scale);
RWeapon->SetRelativeTransform(transform);
rightHandWeight = 1.0f;
GEngine->AddOnScreenDebugMessage(2, 2.0, FColor::Yellow, TEXT("Equipped to right hand!"));
}```
UWeaponBase
#pragma once
#include "CoreMinimal.h"
#include "Data/FWeaponData.h"
#include "Components/SkeletalMeshComponent.h"
#include "Interfaces/IWeapon.h"
#include "WeaponBase.generated.h"
/// <summary>
/// Weapon model base class
/// </summary>
UCLASS(Blueprintable, BlueprintType)
class ARENAFPS_API UWeaponBase : public USkeletalMeshComponent, public IIWeapon
{
GENERATED_BODY()
public:
UWeaponBase();
protected:
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
protected:
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void Triggered();
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void Started(float elapsed_seconds);
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void Ongoing(float elapsed_seconds);
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void Cancelled(float elapsed_seconds);
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void Completed(float elapsed_seconds);
public:
#pragma region Weapon Data Access
UFUNCTION(BlueprintPure, Category="Weapon Info")
FName GetName() { return weapon_details.name; }
UFUNCTION(BlueprintPure, Category="Weapon Info")
FString GetNameAsString() { return weapon_details.name.ToString(); }
UFUNCTION(BlueprintPure, Category = "Weapon Info")
bool IsAmmoNotZero() { return (weapon_details.ammo > 0) || weapon_details.isAmmoInf; }
UFUNCTION(BlueprintPure, Category = "Weapon Info")
bool IsAmmoZero() { return (weapon_details.ammo <= 0) || weapon_details.isAmmoInf; }
#pragma endregion
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (Category = "Weapon Stats"), Replicated)
FWeaponData weapon_details = {};
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (Category = "Weapon Stats"), Replicated)
int bullet_damage = 0;
};
Round trip time. Time it takes between the moment of sending a network packet and the moment of receiving a response for it from the target machine
then i dont understand why its 200 and not 100
client -> server (50ms)
client <- server (50ms)
It's should be more like
Client outgoing -> +50ms
Server incoming -> +50ms (Server received ping)
Server outgoing -> +50ms
Client incoming -> +50 ms (client received pong)
i dont understand the difference between the outgoing and incoming
there were some choices here, even ignoring not following UE naming conventions. why would you replicate what I assume is immutable data about the weapon, like the name?
why would it extend SKMC?
Both vs only one here as well is what you are missing
Don't take this as the acutal explanation (I might be wrong on some points) but download and upload bandwiths should be separate. So like if you're downloading something, it can effect your other downloads with slowing them down as well (incoming). Or if you're uploading something and need to upload something else on another program, same happens (outgoing)
So the editor emulation can add delay for both of them for both server and client
so when we say 50ms as ping, is it 50 ping on incoming and 50 ping on outgoing ?
or 25 for both
I don't think it's possible to determine it like that. Consider server outgoing and incoming are both 20ms. But client has shitty ISP so it has 80ms for outgoing/incoming. Ping should be 200 since RTT is the sum of all
And I don't think incoming and outgoing would be same, since again the bandwidths we get from ISPs for them are not equal
Honestly, I think initially wanted to do some DataTable stuff then realised it was pointless, so I just kept the struct as it is since there is no difference to me.
well the actual issue at hand, in the BP it's evident that a client could call EquipWeapon, which creates the component
so you get a clientside created component, and then you get the serverside component replicated to you
For example my download speed is 100mbp/s and upload speed is 5mbp/s. My outgoing(uploading) ms should be higher then incoming(downloading) ms
(Again, with the disclaimer of not being sure if these would be considered as good or actual real life examples, but the emulator delay idea should be something like this)
Would that be an issue, since am not planning to do dedicated server yet, and I think even if I were to use steam sessions one player would act as the host anyway no (I have not used the Advanced Sessions plugin as of yet)?
yes because there are still clients
it's just the the host isn't a client
if a client creates a component on their machine, it doesn't magically create one on the server
but it ends up creating a component on the server anyway, so you end up with a duplicate
Right, so how would I go around fixing that, while still making it work on both ends?
I am trying to work through a possession bug. I have a fired projectile (simple pawn) that I possess to track and support rotating the view around. It's movement is updated through a tick on the server that is a simple calculation based on an ASC velocity. It doesn't use a movement component. The possession works, but it completely stops until unpossessed. Does that behavior sound familiar?
by presumably making it so the component is only created as authority
What would be done for remote?
I don't know what you mean
a replicated actor component created serverside will be created on a client when it replicates
I see
Doesn't seem that it wants to show nor update my anim poses
Also shooting one bullet seems to put me back to the main menu level
Just asking cuz there’s no video about it.
Does it need to replicated when:
4 letters (with 1 code each letter) are in 1 level to find and the players can read the codes and actives them to open the door
What’s the logic behind this and what to do
Hi, is it possible to have 2 different player controller classes being used by 2 separate players at the same time? I have 2 different character types, killer or victims, I was gonna set up a player controller base class and then have 2 child class from it, one for the killer and one for the victims to use so the base class would have all shared logic that all players need then the individual child controllers would have logic specific to that character type that the other character type doesn't need, but because you can only assign the default player controller in the game mode can i even have different pawn types using different controllers or does every player have to be using the same player controller class as any given time?
Theoretically if you would override where it is being spawned (if it's a virtual function) you could chose your own class to spawn depending on what you want to check (ignoring whether it would cause any problems or not here as I don't know). However it would be more common to separate gameplay logic with different pawns rather than different controllers I believe
I have this issue that whenever im joining session it puts the character into such state for 30 seconds or so. the ping is irrelevant here, and ive used stat net before but didnt notice much. i put debug logs in Event OnpostLogin for when the character gets manually spawned and possessed - and it runs, despite the fact that character is stuck in this pose... anyone got any ideas?
lately it also has rubberbanding issue where the character gets pulled back but it didnt happen before, and all logic should be replicated
How do you handle OnReps_ where Actor pointer is being replicated and this actor pointer itself can have it's own replicated properties, which may not be set / replicated yet? Only thing that comes t omind is handling this with delegates, but it does feel off doing it that way.
Is there anyone who can help?
I don't understand the difference between Dynamic Instance and Server Meshing.
Can't I play 250 players on a map using Dynamic Instance method?
round-trip time
Hey I have set up a basic VOIP with a positional and radio voice mode. I already did the part where I can switch between those, but I only want the selected players(those, who have a walkie-talkie) to be able to hear the radio voice mode. Is there any way I can do it in blueprints?
Yes and it depends. On how have you set up your basic VOIP.
A simple solution would be to locally mute all of the walkie-talkies, if you yourself don't have one.
A cleaner setup would be selective replication. Replicate your walkie-talkie voices only to those who Do have one.
Okay thanks for the suggestions I'll try it
So im stuck at this situation
The server can open the wall and its visible for all users like clients. but when the client tries to open the wall, the wall is still closed, server side is also closed when client tries to open it
So what im trying is, On the keypad you tip the code in and hope the code is right, then the wall should open up. This worked for server side but not client side
This is likely because you're attempting to call a server RPC on an actor that isn't owned by a client. You'd have to RPC on an actor that the client owns first (like their player controller, controlled pawn, playerstate, or a replicated component of one these objects), then when running on the server call to the wall's "Wall Open" function. Once there and running on the server, you should only need to set the OnRep bool variable (ie. no multicast). The OnRep would trigger and execute your destroy component node.
First client and then server?
I can only assume here that you're starting the interaction on the client as you haven't shown what starts this whole sequence. If you're pressing a button to start the sequence, that button press only happens on the client, so your logic will be only executing on the client until you call to the server through an RPC.
If you are trying to call the RPC to the server from a client on an actor that wouldn't be owned by the client, like your wall actor, then the server will reject the RPC and nothing further happens. If the server calls that same RPC it will still work because it's already running on the server anyway.
Schau dir Unreal Engine 5 2025.03.21 - 22.55.52.01.mp4 und Millionen von anderen Unreal Engine Videos auf Medal an, der größten Spielclip Plattform.
this is the whole bp
it is because of the interaction or something?, ive read your comment and still dont know what i should do, im kinda new in this replicate stuff about client see and not see blabla
Every instance of the game can be thought of doing its own thing.
When you have an actor like your keypad there, it exists as an entity on the client machine and on the server. The code can be executing in either place at any given time based on what starts that code execution.
When you want to communicate doing something to the server, you can only communicate to the server from a client on a client owned actor. You cannot use the keypad itself to perform that communication because it won't be owned by a client. If you don't do this communication to the server, then the server will not know that you're doing it, and it can't replicate anything out to anyone.
The general flow of an interaction is something like:
Key Press > RPC to Server > Server validates and does things > Server replicates results of that interaction.
To simulate what a keypad would do, you'd have to:
Record which keys are pressed > RPC to server the full value the player wants to input (has to be done on a client owned actor though!) > Server validates if it's correct or not > Server opens door.
hm
So when E press to interact
thats where i put the rpc
thats located in my thirdperson bp
Probably not. Your interaction system allows the player to use mouse clicks to enter the value on the keypad and your "E" interaction seems to pull the keypad into view and to allow your mouse click inputs on the keypad .
The only time you may need to actually RPC is when you want to send the player's guess to the server, OR if you wanted to RPC every single input on the keypad to the server. In either situation, that RPC must be done on a client owned actor.
hm
you mean like on that video, when he put the 4 codes (1234) and hit enter, and at hit enter i should do rpc?
That's one example, yes.
to clarify, you mean the Onconfirmed custom event?
thats when he got the passcode right with the correct code etc
like this i guess?
@sinful tree that didnt worked xd
The RPC to the server can't happen on the keypad. The keypad isn't owned by a client so the RPC would be rejected.
Hm
Where should I put that
When it’s not on the keypad
On the wall_bp?
In my very first message to you, I stated this: You'd have to RPC on an actor that the client owns first (like their player controller, controlled pawn, playerstate, or a replicated component of one these objects)
The keypad or wallbp
Is either of those client owned?
I don’t think so idk
Based on their names, my own guess would be no, and you probably wouldn't want them to be specifically client owned since you'd probably want anyone at any time to be able to perform interactions with them.
Can you like give me an example for it? So I can maybe understand further what you trying to explain me 😄
Normally I always do that replication when is not working, but never tried about like puzzle replication which is not existing on any YouTube tutorials etc.
Aha hm.
Like what you meaning by that routing with player controller
Like get owner node etc?
Anyone know why my OnRep_PlayerState only gets called when I walk a certain distance toward the player?
relevancy most likely
Player interacts with keypad. Presses keys and then sends the key sequence to the server through the PC.
Interacts by meaning like when he’s typing on the buttons or when he press E and the camera is focusing on the keypad
When he presses the sequence of keys and then hits the confirm button, send the rpc
Im tryna understand how it works about it etc. I never tested it
tested what?
So when the player is hitting the enter button, then I’ll add the RPC?
Replication multiplayer puzzle etc
I only know about animation replication and stuff
But never tested in that way
Replication rules don't change.
RPC rules don't change
Regardless if you're working on UI, animation, gameplay.
I feel like you might want to show the keypad numbers changing on other clients
it might be useful to make a simple command that just sends an enum that represents a given key being pressed on the object that changes it on the server
then the server sends state to everyone including the person who pressed the button unless it's valuable to predict ahead of time on the client
It depends on how the puzzle is set up.
How about instead of working with a keypad, work on just getting a door to open with a single button press.
Tried it
either way you just need some way to send an rpc to the server from either the character or controller (or a replicated component on one of those)
It works but it’s like happening for everyone
When I hit the collision box then I can open the door
isn't that the point? why does it need to be isolated to one person here? is the idea that only the person who opened the door sees it open?
Collision isn't the same thing as clicking an input.
Aha okay
Collisions occur on all possible instances of the game. Input only happens on the instance that is triggering that input.
I mean I want to try that all 4 player include server and client can open it but somehow the client can’t but server can
I would say for starters just try to make a simple RPC that every client (or listen server) can call that makes ANYTHING happen on the server then all other clients... just to demonstrate you can
This is not to make a door open but to just learn about how to do this for everything else
If clicked button what should I add after then to work
in order to call on RPC on client that runs on the server you need to make a Server rpc on an object the client owns
owns here being the player controller or possessed pawn
it depends on how this button is loaded I think
If it is loaded with the persistent level I believe it should be possible to send an rpc with the pointer to the button as it is stable
if it is dynamically spawned you can just make it replicated if need be which might not be a bad idea if it needs to replicate things about it
I'm actually not 100% sure about sending pointers to persistent level loaded actors... I've generally worked with dynamically spawned things
Uh
by pointer there I mean blueprint reference to be clear
Since you know how to make MP puzzle can you give me an example to understand? About the keypad pressing button, 4 codes, correct >>>> door opens
ah yeah seems the actor should be stable for networking if it is loaded with the level
Not much of a difference. It's all a network guid anyway.
I literally did.
Is it without interface?
it depends on how it is sent
Doesn't matter. I don't use interfaces that often though.
You need to go through the fundamentals
make a new custom event in your character or controller bp that is replicated to run on the server
That’s what I was thinking
We can't explain it anymore simple really. The only other option is to walk you through it, line by line, and I don't have the time for that right now.
Like Interact custom event (Server)
sure
and that event will need to have information about which button was pressed (I assume there will be more than one) and anything else you want
Wait I had some screenshots about that, not on my pc rn
the cool thing is unreal magically turns references to actors in an rpc to the actor reference on the other side of the rpc call
If I ever knew how this works, but basically I know some but not in this situation
Pressed Enter → Get Player Character
→ Cast to ThirdPersonCharacter
→ Call Client_SendCodeToServer
This is what I understood
That’s what I add to keypad bp innit
I may be missing something, but I think if you just make
- the keypad actor replicated, and the door
- make an RPC call to the server from the keypad actor when its successful, then call door change and such on multicast. It should work
Sorry I didn't look deep into your setup, but maybe just your door/keypad are not replicated?
RPC call to the server from the keypad actor when its successful,
is the keypad actor owned by the player?
server RPCs (from client to server) will be dropped every time if you don't call them from something your client's connection owns
it needs to be on something like the player controller or pawn in most cases which are actually owned by the client
maybe he could setowner on the keypad when interacting if he wanted to keep the calls on there
SetOwner needs an initial server RPC. And you'd remove the ability of others to interact with it if you do that.
how would the server know who the owner is?
hmm that might be all right, it'd have to be done from the player itself/controller then. I don't know if he wants others to be able to interact with it at the same time/if that's possible in his situation though
It would make more sense to me to have some simple interaction rpc from the pawn or player controller that has what is being interacted with as the rpc payload
I'm not sure I have ever seen temporary ownership just to make an rpc inside of something get called on the server... I think there's a world where it makes sense to have one player "own" something temporarilly like if they are the only one who can carry X object
but the server must know about the ownership transfer so... yeah just make a new rpc on something that it will work on already instead of doing this I think
ah I suppose the playerstate would work as well
Yeah an example for this was a game I worked on that allowed you to catch a ball and shoot it. The ball logic for shooting etc was in the Actor, so on pickup we assigned ownership to the player. A simpler example would be a weapon that got picked up I guess.
I discovered there is a way to iterate ufunctions in uclasses.
In this example its to track all reliable multicast
Hello friends is it inefficient to have a replicated variable of type primarydataasset
So this is what i did
he tells me the password is wron
even tho is the correct pass
is it like this?
i think the whole keypad coding is a chaos
sadly theres no tutorial for on youtube how to use it and to understand it
Okay
i figure it out
The only problem i got is, that the camera isnt like reset or something
this is the camera settings etc (1st pic)
Schau dir Unreal Engine 5 2025.03.22 - 17.02.16.01.mp4 und Millionen von anderen Unreal Engine Videos auf Medal an, der größten Spielclip Plattform.
a clipf of mine what i mean by that
Hello, I was wondering if there was anybody here who can help me understand a struct replication issue.
I have a TArray of structs to represent inventory slots. The structs' members are: a bool to check if the slot has an item, a data asset ptr for static item data, an int for stack size, and int for index.
The inventory array is replicated on my inventory component.
The replication works perfectly fine if only the server is editing the members. I can add items, remove items, override slots, etc, and the client will replace it's values with the server's values.
I wanted to add some client side prediction to make moving items feel more responsive, so before sending the request to the server, I have the client edit the array index on it's own. What I want is for the client to modify the struct, the server will receive the request, make the move on it's end, then replicate the state back to the client.
For some reason, after editing the struct with the client, it basically bricks that slot. The slot will have the correct data on the server but on the client it will only have the stack size, and index replicated to it from the server, the bool and data asset ptr will not.
I also tested with just a struct var, no array, and I get the same issue. Is there a problem with clients modifying replicated structs not allowing them to replicate properly?
Thanks
You might need to have a distinct set of information that the client is allowed to mess with
also for things like this replicating an entire array is probably undesirable as it's not easy to figure out what changed on the clients end... if you are using Iris they can delta serailize but you might want a fast array to be able to respond to individual elements changing
Thanks, I will look into this. I guess I was just more wondering why it works fine until I have a client try to modify the value locally, and why certain members are being replicated while others aren't.
Like I guess it would make sense if maybe it was having trouble checking if the data asset ptr changed, but if the integers are still replicating fine, I would expect that at least the bool would also still be able to replicate.
Did Epic change how extending the CMC works? i.e. the FSavedMove_Character stuff, changing it to a new subclass and all?
no
Where do I change the allocation of the saved move to use my new class?
I'm probably just rusty from not having used it in a while but I'm confused
you still extend FNetworkPredictionData_Client_Character and override AllocateNewMove
from what I can tell
ahhh right, forgot I had to extend that
for some reason I thought AllocateNewMove() was in the CMC class itself
oops
and AllocateNewMove is where the actual saved move is made
yeah it's a bit confusing
I feel like they could have replaced this with instanced structs or something by now
yeah
and then I override FNetworkPredictionData_Client* UCharacterMovementComponent::GetPredictionData_Client() const to change the network prediction data to use my extended class too right
I think so
so yes there is still a thing to override on the cmc itself
I guess worth mentioning there is the new Mover plugin but I have only heard bad things about how expensive it is
ehhhh if I'm not using the CMC, it means I'm using the GMC 
Only using the CMC as a client requirement atm
i thought mover was supposed to be efficient 
Thanks by the way, using FFastArraySerialializer fixed my issue
Going to ask this here as well just in case; has anyone had issues with getting the enhanced input subsystem to work properly on a dedicated server-type situation? I have been wracking my brain about this for about a week and can't seem to find a solution despite my searches. Inputs work perfectly fine in a standalone singleplayer environment, but for some reason refuses to work when connected to a dedicated server. For context; the process goes like this:
Join request is sent to server > OnPostLogin event triggers in Game Mode (player controller is successfully created for each connected player) > HandleStartingNewPlayer event Triggers in Game Mode (pawn is successfully spawned and possessed by PC during this event) > Character's Possessed event triggers [server only] (after casting to player controller, enhanced input subsystem is checked for validation and returns IS NOT VALID - mapping context ends up not being added...) > PlayerController's OnPossess event triggers > Join succeeds > Controller and Character tick events start.
Now, I've tried different ways of trying to add the input mapping context (both in player controller, as a local player, and in the character) but couldn't get any different results. I'm not sure if it's an order of operations issue, or if I'm missing something obvious. Any help is appreciated though!
I do mine in the PC's AcknowledgePossession callback. It is called on the client when the PC possess a pawn.
Only the client needs to register to the input
I may have tried that before but I'll try it again just to make sure I didn't miss it
yea, I figured as much, which is why I did it before in the PC but I may have only tried it during begin play which may be too early
Hm... still not working, though I'm getting a warning accessing none on the return value for the subsystem for some reason now
which doesn't make sense, it should be coming straight from the player controller, unless I messed something up/missed some step somewhere 🤔
could it be that... I'm trying to get a reference to the player controller too early?
this is a long shot but.. could it be that commonUI is potentially messing with input mapping?
On Posses only get called on Server, binding input there as client is already the wrong move as the function only get called in server.
Use OnAcknowledgePossession as Duroxxigar suggest. I had mine on the same spot.
Also use IsLocallyControlled to filter pawn that you don;t possess. You only want to bind to the character you possess.
It's honestly a bit unintuitive that it's only on server
I wish it was named OnPossessOnAuthority or something
I did switch it over to the player controller's possession event, still didn't seem to work. this rabbit hole is much deeper than I expected
show code?
Ha.
The custom Delta Serialization by me, followed by Iris integration and then somewhat re-written MovementModeStateMachine while loop (also by me) begs to differ.
Getting NPP and Mover to where they should be before even starting to use them is its own project.
I cant seem to find a way, to replicated the dodge system that I implanted(I AGSP). Anyone that you be able to tell me how?
i been working on this issue for about a week now i have tired multiple things and keep going around in circles running ue5.5.4 source and advanced sessions 5.5.4 my server is running and is successful on created and starting the session i see my ai doing updates and on my client side i can see the session in my search when i click to join the server closes down saying there an error with a uobject. but i dont know what uobject it is nor how to find it.? in developer mode
Assertion failed: this->PropertyClass [File:H:\epic\Engine\Source\Runtime\CoreUObject\Public\UObject\UnrealType.h] [Line: 2872]
You'd need to have your IDE (Visual Studio/Rider) connected to the Server when it goes down.
yeah i have it does a breakpoint on this line in unrealtype.h file like 2872
the handshake is completed and the client goes to join i can hear footsteps from my ai from the server but thats it then it goes back to main screen
any idea, why main dynamic mesh is changing his relative height to fit the ground, when moving, but for another client only, not for owner?
https://cdn.discordapp.com/attachments/1068735774364794911/1353392969864187924/2025-03-23_17-37-42.mp4?ex=67e17cec&is=67e02b6c&hm=441715d6b4e44b21de5207f806568f3e9ec489a3ed4c09d8b478ec70343bfe18&
Does it work fine in standalone
in standalone there's no other clients
like I probably mentioned before, you have to go through the callstack and look for clues
the callstack isn't always enough information
Are you calling the multicast from the server
Try marking it reliable (generally bad practice for multicasts) I would recommend using a rep notify instead.
yes, its from the server
yes, its reliable
I would recommend using a rep notify but from what I can see in your video the multicast is only running on client 2? Refer to this chart on multicast RPC's
You multicast probally isn't actually being called from the server as if it was it would arrive on all machines yours isn't even running on the server so it's just running on the invoking client
multicast is calleds from the server and running correctly everywhere
Oh okay there was a misunderstanding then I thought your issue was that your multicast wasn't running on all machines
it's in blueprint format 😅
I set up an "is local player controller" check because otherwise it returns none, even though I presume it's being checked client-side
Binding Input in Possess is wrong.
That's only called on the Server. You can't bind any local Client's input there. Your code here basically only works for the Server and then with the IsLocallyControlled stuff it is only calling for the Server's own Pawn.
Please use "OnControllerChangedEvent" or whatever it is called by now, and filter that with IsLocalController on the NewController pin.
Interesting, this time it goes through the whole input mapping process successfully, but I still can't seem to send any inputs/use any input actions. this is all sorts of messed up. could there be some setting I'm missing or overlooking perhaps, that otherwise works fine on client-side? perhaps something that might be eating or overriding inputs?
could it be that having input actions on the pawn while having the input mapping context on the player controller might be causing issues?
Aha, my suspicions were correct, it's the input mode itself that was somehow not getting set correctly. I'll do some more digging around and see if I can solve this issue
Hey everyone! How do you guys handle line-tracing, or hit detection in multiplayer?
Do you directly send RPC and let the server instance line trace, or simply do in local, and call the result on server like interactable.interact?
When I line trace in server, or even better with GAS, server & client, I get different results, sometimes it doesnt find target for example in the client, or in the server. So what are the proper way of handling hitscans etc? I dont mind cheating.
For example I call an anim montage, then with notify, I create a line trace, and check for Harvestable (which is a tree,) I simply simulate chopping a tree here. But as said, sometimes in server, it returns Does Implement interface (BPI_Harvestable) true in server, but false in client.
ok, looks like i find how to fix it
not sure, if this is a best way, but this is in a Character movement component
changing Network Smoothness mode from Exponential to Disabled fix rotation and height changing of the mesh when moving
I think it depends on what you are doing - I generally try to keep core gameplay on server if possible and replicate. If it's important to have an immediate response then you might want to do it predicted or even client authoritative.
For example selecting units in our RTS is client-authoritative: Player clicks on unit and it will linetrace locally. It is not core logic nor important to check (there is little cheating possibilities).
But things like "unit did damage to this other unit" is server only and then the new health is replicated
When I set Network Emulation Profile to average, I see a lot of jittered movement on clients-side on Unreal Engine Game Animation Sample on version 5.5. Could anyone solve the issue ?
The Network Emulation profiles introduce some amount of Packet Loss, this is likely contributing to those corrections being necessary.
Turn off the Packet Loss.
It is better but not good enough. It is not smooth as legacy animation system(default third person template). Am I right to assume the new animation system lack of client-side prediction ?
Animation has nothing to do with Client Side Prediction
Some devs at Epic said that GASP doesn't work well with latency yet. Timestamped link: https://www.youtube.com/live/3RlnclPo-3U?si=vUK3fijKMVSqGTDR&t=2160
With 5.5 came some updates not just to the engine itself but to some of our sample projects as well - the Game Animation Sample Project included! This week w...
It doesn't but
Add a fluctuating latency and watch what it does to distance matching when observing sim proxies
So you can see poor even jittery results as a result of latency
Sure but thats not what he asked.
I see a lot of jittered movement on clients-side on Unreal Engine Game Animation Sample
Seems like its entirely relevant to me
is it easy to solve the issue ?
Poor latency can cause animation to look jittery, haven't tried GASP but because it monitors motion and de-sync disrupts motion I wouldn't be surprised if it looks jittery
There wouldn't be an easy solution if that's the case, but I haven't seen any video
I didn't see any issues regarding that on the project I'm working on. Hm.
But also not sure if we are doing anything special on the animation side of things.
Even on non-perfect scenarios ?
The real question is if you're de-syncing or its just fluctuating latency
My client usually tests with quite a lot of players on properly hosted servers.
That's as bad as it can get
And we use NPP and Mover to drive movement. The trajectory prediction I was able to get with mover isn't even that great compared to the CMC version. Although also not too far off.
If there would be large problems we would already have heard about it
I also didn't see any issues in our latest internal review meetings about MotionMatching.
That said, can totally be that we have something somewhere that I don't know about that improves this
Might just be their network test settings aren't real-world
Hi how do I replicate my scene capture component 2d and render target? I am using it to get the owning players character then display it when inventory is open
This is my current logic, when in inventory
It's working but only shows one of the players for all players
Hello everyone. So for scalability of multiplayer networked games, people would use the gamelift plugin right? And host servers through aws? This is so aws would handle dedicated servers in different regions around the world. Is this how a game like marvels rivals work? Not sure if people can answer that last question but any advice would be great!
Replication is not a magic work. What part of the scene component are you actually trying to send over the network?
Because pretty sure you can't do that on the material.
There are only thing you can do with networking in unreal.
Send over variable or give instruction to run function.
You can replicate the object reference to the material but the state will not be the same.
Gamelift is one option, Playfab is another. They manage Dedicated Server instancing and matchmaking for you, yes.
They are expensive though.
And can take a bit to setup properly.
What would be the best way to handle this then? Essentially what I want to do is have a seperate camera when the inventory is open that captures the players character from a scene capture component
This
ok, something is absolutely messed up with my game. no inputs work when a player connects to a dedicated server, not even debug keys. what could possibly be causing such a thing to happen? UI is still interactable (ie. I can interact with widgets, which adjust various things about the possessed pawn in the world). I've made sure to remove every instance of Set Input Mode (all 3 variants, including Game Only and UI only) in my game just to rule out the potential that it might be those settings which are causing the game itself to not accept inputs. What else could I do?
Those capture are local
You have 2 options. Spawn the character under the world. And do a scene capture. The only thing that needs to be replicated is the equipments of the target you want to view.
Second is to spawn another UWorld. Look into lyraPocketWorld or if you have the money look at multiworld plugin.
alright, progress has been made. I had ticking disabled on the player controller (don't ask why, just me being dumb), and didn't think it would affect begin play or other events until I could set actor tick to enabled at the end of possessing a pawn. big mistake... 😅
isn't it fine if its' local? I just want each local player to be able to see their local character?
The capture has to be local
I mean what would I know about your computer capturing some 2d scene component.
That's why nothing needs to be networked
Unless you are looking at some other characters where you need to pull the data from server (e.g equipments)
I don't need to pull any data just the local player
K then I don't know why you are trying to "replicate" it
From my setup, it's showing other players
like the first player that joins it only shows them
Just set them to not active by default
And call some function to activate it once a character is possesed
That's probably how I would do it.
ok ill try rn ty
@dark parcel on possessed is only called from serv would it still work?
No, use acknowledge possession for client
Where can I find that?
Not blueprint exposed but then , trying to recreate rust with blueprint only sound futile imho.
It's a function you can override but only in native class because epic don't expose it to bp for some reason.
@dark parcel So if I have 1 player connected I can see my character in the inventory, if 2 players connect. the character in the inventory is not visible for either player
This is all the logic is
Those snippets is not enough to guess where the underlying problem may be.
Could be that your scene capture reference the same texture target
And some uninteded scene component write to it
At this point I can only recommend debugging on your end.
I'm not setting the texture target at runtime should I be doing that?
This is the material
If you don't update it how is it suppose to render the character
the scene capture component is capturing every tick
https://www.youtube.com/watch?v=XWXXoAgugD8&t=297s&pp=ygUocGxheWVyIGNhbWVyYSBpbiBpbnZlbnRvcnkgdW5yZWFsIGVuZ2luZQ%3D%3D this is the tutorial i followed
👉Get The RPG Inventory Course : https://bit.ly/4cSYsBh
👉Get My Free Unreal Engine Beginner Course : https://bit.ly/46mUWMr
Timestamps
0:37 - Introduction to creating user interface
2:00 - Adding and displaying a 3D overlay widget
3:23 - Implementing functionality to show/hide the 3D overlay
5:08 - Creating material for render Target mannequin
6...
bit off topic question to unreal but does anyone know how gta online network works?
i read its a peer to peer solution where every player connects to every other player
and they have like a maximum of 32 player lobbies
How do you achieve something like that? Does unreal provide a way to do that?
as far as i know using listen servers are unreal's way of peer 2 peer connection
but doesnt that make 1 player the host?
How do I replicate this so it works on dedicated servers? https://www.unreal-university.blog/unreal-engine-step-by-step-guide-to-displaying-3d-meshes-in-widgets/
UE doesn't support P2P networking. You have to do a custom solution.
Correct, the listen server is the host… so one of the player IS the server. Despite being the server, they can still play like normal (however has server authorities obviously)
isnt listen server peer to peer?
The same way they do in UE. By sending network packets to each other.
UE just requires everything to be routed through a server.
Client sends data to server
Server authenticates and handles that data
Server sends that data to the clients
This is the complete opposite of a P2P architecture. There is no server.
P2P = everyone communicate with everyone.
Imagine 3 players
P1 will have to receive and send data to p2 and p3
For p2 it will receive and send data to p1 and p3
Server to client = client don't communicate directly to each other.
With p2p there's no central authority
worth noting P2P does still typically have a “server” but it’s generally referred to as a host
the main diff between the models is that on server auth clients never talk with eachother, on P2P they do
and that P2P doesn’t have to have a host, but usually it does because it’s more sensible
Was talking about listen server
Yes - but they were asking how communication happens in a P2P setup.
You literally answered the question you were replying to with incorrect information.
Describing a completely different architecture than what they were asking for.
Oookay!
hey guys! I'm having a small issue regarding pickups in multiplayer
so basically, I have made pickups for a multiplayer game I'm working on (there are around 200-300 pickups in the map)
the way they have been setup is, there is a server-sided overlap check for actually collecting the pickup and increasing points, and I'm using a local overlap check just to play visual effects and sound effects, and hide the pickup (server is the one calling the destroy function)
basically, my issue is that, sometimes there is an overlap mismatch (due to ping obviously), and so, the client collects the pickup, but the server doesn't, so it's still there on the server, but not on the client
I want the collection of the pickups to feel responsive, so I NEED to have the local overlap code
how do I tackle this issue? any ideas?
Generally speaking if you do client prediction (which kinda is the case) you will inevitably get into issues when client and server disagree. And in this cases you need to figure out the best solution depending on your game - first, who is right? Client or server? And then, how to resolve the conflict
That will never really work reliably. What if your client overlaps because it miss-predicts? Now the pickup is hidden forever
well, that is what I'm kinda confused about
I do have a system, which will make the pickup reappear after 1 sec if it's not already destroyed, but the pickup popping up outta nowhere looks weird
I mean personally I think I wouldn't predict the pickup at all
Yup
yeah exactly
I wanna avoid RPCs on every pickup call, bcoz there will be pickup overlaps almost every second
(I know I can mark them as unreliable but wouldn't that still be too many RPCs?)
The only way to really recover, would be to set a timer - if the pickup hasn't been destroyed on the client within a recent timestamp of being predictively "collected", then you show it again. However I'd argue that as a player, that kind of misprediction is extremely egregious, you've already played the effect so why is the pickup suddenly reappearing?
It's like predicting hit markers etc - if misspredictions are frequent, you're just making the experience worse
Yeah very confusing. Since pickup in principle can have a bit of delay (is it location based, or does the player need to "click" it?), I'd just do it in the server
it's overlap based
Also if the chance for two players picking up the same item is small or none, you could do it client-authoritative.
just overlap and it's picked up
that is no issue actually
so would you recommend calling RPCs each time?
Yes
It really isn't that big of a deal
Are you collecting 29038720394587320945782340598734 pickups a second or something?
nah
I mean for hit markers specifically, definitely
Not sure what you'd need to RPC for pickups
Just run all the overlaps server side
then I would either:
- Do it client-side only and just notify the server that item was picked up (because there is no concern for cheating or players conflict over who picked up first)
- Just do the easy thing and do it server-side. And maybe increase the radius of the overlap a tiny bit to give players the impression that pickup is earlier than touching the item. Maybe a bit hacky xD
yeah that's what I'm doing currently
alright
I did actually make the client's pickup radius slightly smaller to minimize this issue lol
xD Well just get rid of the client-side prediction
players won't notice a big delay and a reliable experience is way better even if it comes with a little lag
alright noted
Yeah, just don't do client prediction on this. You don't need client prediction on everything
I think I kinda do though in this case
I'll send you a clip to show you what I'm talking abt
nope, you don't
i guess I can have only one thing then - reliability or reponsive pickups
alright anyways, I'll look into it
thanks for ur inputs guys, appreciate it :)
Thing is I'm assuming the actual pickup is added to your inventory or adds heath or whatever server-side only (it should be if not) - so really it's not more responsive as such, you're just trying to hide the latency - but it will be visible in other ways
nah, it's just destroyed, and the server calls +1 on the score lol
I get what you mean though
keep in mind also that overlaps themselves aren't all that reliable, since unless your frame of movement finishes by overlapping the pickup, it won't be detected as an overlap
So there could also be issues with it being collected on one end and not the other because movement deltas are too large
Especially if you are moving fast and/or with low FPS
yeah true
What would be the better way for that ?
Hi, im kinda having issues about the replication stuff
when a player dies, the spectator UI should appear on that player, who died, but it only comes to the server and doestn show on the clients
Hey guys, I am having a conflict about a topic.
- When I left mouse click, I swing my pickaxe tool, which I want to happen on the server and client in both. So for that, I first send RPC to server, and then multicast for my anim montage.
- This swing tools returns a anim notify, which I can detect hits. But since I play that montage on both server and client instance, it sends notify on both client and server, but i want to DO that DETECT hit on the server only. So it confuses me how to continue from then.
You can filter on receiving end of notify
Can you extend it please? What do you mean by filtering
Event -> are we authority? -> yes -> do thing
Aha, you mean has Authoirty check on notify call. Thanks
I would like to move character on a spline. How should I update players location in order to replicate correctly ?
I am trying to solve this with Has Authority, But it still prints two times on TraceHarvestable.
I simply Server RPC -> Use Item, then MC to play Montage. after montage send hit event, I simply want to call Trace Harvestable on the USER itself. or the server. Or the owning client. I also tried owning client and it doesnt print when has authority checked, because its the client that i try.
OK, this check is working. BUT WHY though?!
Should not it send RPC only to the owning, even if I dont check authority. I know MC is sending 2 times to server and client... Ah now understood while typing.. 😄
Server executing a ServerRPC will act as a normal Event.
If you execute a Multicast on an Actor that is owned by a Client, and in there you call a ServerRPC, then you will end up with the ServerRPC executing twice on the Server.
Once for the ownign Actor calling it, once for the Server calling it.
If you use SwitchHasAuthority there, then you don't need to make the event as a ServerRPC.
got a question, im asking that on my mind for days
If player gets killed, normally destroy actor, so enemy dont focus the dead person, but i was thinking like, when hes dead, then i can see his ragdoll character, but i dont know how i do it with destroy actor, cuz that will destroy the ragdoll
don't destroy it then
I'd make a bool like bIsDead or bIsAlive and have that be what represents the state
then you can onrep it and whenever it changes change what needs changing
OnRep / RepNotify is the best
hm yea
pawn seeing, can see him? true, isdead false runs to player,
if entered monster box collision, which means he dies, can you see him? false, isdead true?
<
was on my mind
Certain static meshes appear blurry on high-end client PCs when Texture Streaming is enabled (MipBias 0 so high, PoolSize 3500). The issue occurs only on clients, not servers, and resolves when approaching the object's initial spawn location. The powerful PC has a problem, the weak one does not. Could the problem be related to replicate / level bound? When I get closer to the static mesh that was added first, it fixes the problem for those static meshes.
Any idea?
Hello! I was getting up to speed with the UE quick start to multiplayer guide but I'm a bit confused about one small detail.
So as I understood it the OnHealthUpdate() function is supposed to send a message to the client that was hit with the projectile and also send the message to the server that player x now has a certain amount of health left. When I test this in** Stand alone game** with netmode as listen server it works as expected/I understood it. But when I do it with play in editor both the client and server show each other's messages at the same time. Is this normal? or perhaps I'm missing some knowledge about how PIE works for multiplayer?
Standalone works separately so you see the messages separately, in this mode you see the messages in the same place. Everything is normal.
GEngine is a singeton
So every viewport in pie will see this debug message
This is fine and expected assuming you called that
Hi Megafunk. What could be the reason for such a problem only on the client side and not on the Server?
.
Ah I see. I didn't know it was a singleton. That makes more sense!! Thanks👍🏿
Can anyone help me figure out how to add basic multiplayer functionality to my game?
I'm working a moba/autobattler/rts and I have two actors that can spawn other actors for minions. Wrote an rts scrolling style camera, now I want to actually start testing and writing unit combat
but for the life of me I can't figure out how to implement player handling and team assigning and whatnot cos it's not clear where I'd put that logic
Am I going to have to write some server stuff in game mode and then some client stuff in my current playercontroller to connect or handle connecting?
- Player requests to spawn the minions
- Server gets the team from the player's playerstate and assigns it to the minions on spawn
- Minons should be Pawns with the default AIController, just so you can use the AI Move to commands (I don't recall if the Move To and Simple Move To nodes want you to provide a controller or not)
"1) Player requests to spawn the minions" I plan to have them spawn every x seconds (with a potential upgrade to shorten this timer) and clients just request to add stuff to queue or upgrade what will be spawned
I already have replication working on the minions and stuff, but what I'm saying is I'm not even at a point these are problems I can solve yet
Then there needs to be some way that you would define which player gets which spawn.
That is game specific
If I start a play session with two players, both spawn on same team, both get same player controller, etc
Both won't get the same player controller.
and then the server crashes because the host doesn't have a playercontroller when I run it as dedicated so my spawnunit function can't get the location of the enemy spawn
There is one player controller per local player on a machine
Wouldn't it still need a playercontroller?
No
I thought ai controller was a subtype of player controller...
ahh okay, mb
I should have said controller originally
though I guess what I said was still technically true cos the same playercontroller class is getting loaded into both players atm lol
The same class - sure, the same instance, no.
yeah, true. I'd like it to be a different class then, I can't figure out where that logic is handled
since it's already being handled and I've put no handling in for it
Spawning the player controller happens in the GameMode.
Spawning the player also happens in the GameMode
The AIController is a property in the Pawn class
okie dokie so I could do different logic based on the order people join the server pretty easy
what bout down the line when I want to start a game mode with predefined values for certain players and certain players to connect etc, rather than freeform type deal. How do I send data to the server to spin up a game mode, and or how do I pass arguments to the game mode?
Through the URL
While it isn't technically passing args to the GameMode itself, you can parse it however you want. So it can be used as a way to do so.
Cedric's guide, that I linked to you before, covers the URL if I recall. If not, the other linked resource does.
fair enough, once I can get two actual different players kind of spawning into the map I can start cooking properly
I still can't see how I'd do this...? Would I have to do it in pre log in? Everything after that takes a player controller as a param so it's already set at that point
I'm guessing I need to override AGameModeBase::SpawnPlayerController()
Is your goal that 2 actual players join, but the second player is basically spectating as Player 1 and an AI battle?
Havent seen you in a while, no longer with Epic?
I never did seek the role haha!
Working on anything cool?
Nothing on-topic for the channel. Wanna catch up? I can open DMs
Sure
Nah, just that one player joins via netcode (to get that implemented and working) and the 2nd player is an AI controller, just to get a testbed going to develop in
With the intention down the line of potentially making it 2v2/3v3
Err, would the process not be all but identical?
Oh like a client pilot? Just something that plays like a player?
yeah, I guess so. I just need something doing stuff on the other team
That is just AI
I assumed it would have to join like a player and an ai controller would take the place of a player controller
The whole point was to mock up the network code while I was getting the gameplay working
well not enough mock up, actually set it up so once I get gameplay at an okay point, I can get someone else to join and see
with little to no changes
That should also take me one step closer to some automated tests down the line too
Yeah, you’re going to need to spawn an AI controller. You should write everything expecting an AController instance, so that it plugs and plays with players or with AI. It might be easier if your functionality is componentized
so overloading the SpawnPlayerController function is the way I wanna go?
For now I was just gonna do something like If Players == 1 { SpawnPlayerController} else if Players == 2 {SpawnAIController}
Even if you’re having the AI controller play back your inputs (like AddControlRotation not the specific key presses)
it's a top down rts game, I'm not certain if I'm gonna add individual unit control yet
it may end up being more like Majesty than Dota
Uh, actually you wouldn’t want to change SpawnPlayerController at all here. You want to have one actual connection join, and then the game has an AI that can act as a player 2
Right, that's where I'm lost. How do I tell it to use my ai controller class for the 2nd player?
There is no 2nd player at all
I'm gonna be overly verbose describing concepts, but I'll do it this one time
The process UE follows to get a player in the game is different than the process to get AI working.
How do I have the 2nd controller that's spawned into the game be an AI controller and not the default class?
Like, I added all the c++ properties ima need to handle two teams for the feature set I have now
I'd like to start simulating having an active player in control of the 2nd team
When the game starts, check how many players are connected (you can check this in the gamestate's player array). If less than some number, let's say 2, because you're only doing 1v1 for now. Then in the StartPlay function, spawn the AIController you made that acts like a human player.
So I'm not gonna set the "number of players" in players to 2?
Well, not the AIController - but the Pawn.
From what I remember, you spawn an AI pawn on the server. The Pawn class specifies a custom AIController class, and a second setting controls whether an AI controller is automatically spawned for that pawn. I can’t remember where, but you can even have the AI Controller get a PlayerState
Because when you spawn the Pawn, it'll spawn the AIController
there's no way to have the 2nd player just use an ai controller instead of a player controller?
in the scenario where I set "number of players" to 2?
and spawn 2 game instances
ya, so why can't the 2nd load something different for a controller?
Because it is a whole different player. You're simulating a player connecting.
Well, that’s technically possible, but they would still both be player controllers
You'd have to put them in spectator mode.
I'm fine with the ai controller actually being a player, given I'm trying to simulate a player
*actually being a playercontroller
Ok so you want to see both viewports specifically?
at the end of the day I'm not leveraging any advanced AI features at the moment, it's just going to be if statements and maybe a state machine
2nd one wouldn't be necessary, but probably ideal if I can see the UI that would be visible to a player making those actions
But you are leveraging advanced AI stuff. You're trying to get AI to simulate being a player.
No I'm not, I'm trying to call a function when a condition is met
just cos a player could do that with a keystroke or button press doesn't make that "advanced ai"
Making the AI issue commands like a player and responding with believable tactics to the human to make it seem like it is another human player is advanced AI
Right, that's not what I'm going for
Yeah I mean you’re kind of headed towards just having your regular player stack and having a custom subclass that just replays a sequence of recorded key events
I just don't wanna do stuff like "press this button to queue this research" every time I reload the editor while I'm working on gameplay
or "spend gold on this when there's more than x available"
if I could do that, and work on netcode at the same time....seems like it would save a lot of time
If I just have to hardcode a pawn spawn into a new testpawn class or something I can go that route
just seems odd to me I couldn't have a 2nd player controller that could automate some gameplay decisions
it doesn't seem to different to me to a scenario where the game would require players have different controllers for different roles
You don't often switch the player controller
Technically nothing is stopping you from doing this right now. You could detect that one controller was the first player and the other is the second player, on the server, and replicate the “second player” status down to the relevant controller.
OnRep you can start all kinda timers and timelines. Or run state trees.
All of this lives in your main player controller class.
yeah was hoping it wouldn't end up a big shitfight in one file
and that this was my pathway to figuring out how to implement netcode and whatnot
fuck it I'm just going to figure out how to do it, there's no point in doing it any other way except that it's easier, but ultimately it's gonna solve problems I need solved down the line. I'm not backtracking after all the gameplay development to get replication working properly. That's insane
{
static ConstructorHelpers::FClassFinder<APlayerController> PlayerControllerBPClass(TEXT("/Game/RTSCameraController"));
if (GetNumPlayers() == 0)
{
return Super::SpawnPlayerControllerCommon(InRemoteRole,FVector::ZeroVector,FRotator::ZeroRotator,PlayerControllerBPClass.Class);
}
if (GetNumPlayers() == 1)
{
return Super::SpawnPlayerControllerCommon(InRemoteRole,FVector::ZeroVector,FRotator::ZeroRotator,ATestAIPlayerController::StaticClass());
}
return Super::SpawnPlayerControllerCommon(InRemoteRole,FVector::ZeroVector,FRotator::ZeroRotator,PlayerControllerBPClass.Class);
}```
won't compile at the moment but I feel like that's 99% of what I need
Anyone happen to know why a property might be constantly resetting/switching between 0 and a given value that's constantly being updated, on the server, when updated by tick?
use your debugger and place a watch on the property
Sounds like you need a monad to control what's writing to it
Please don't use the class finder stuff. Just expose a TSubclassOf<>.
Also, are you sure it's a good idea to spawn an AIController for a connecting Player? Or is it just called like that and it's simply a different PlayerController class?
Yeah I've updated it a little haha, it's just a different playercontroller
{
UE_LOG(LogTemp, Display, TEXT("AMyProjectGameMode::SpawnPlayerController"));
if (GetNumPlayers() == 0)
{
return Super::SpawnPlayerControllerCommon(InRemoteRole,FVector::ZeroVector,FRotator::ZeroRotator,PlayerControllerClass);
}
if (GetNumPlayers() == 1)
{
return Super::SpawnPlayerControllerCommon(InRemoteRole,FVector::ZeroVector,FRotator::ZeroRotator,ATestAIPlayerController::StaticClass());
}
return Super::SpawnPlayerControllerCommon(InRemoteRole,FVector::ZeroVector,FRotator::ZeroRotator,PlayerControllerClass);
}```
Get num players seems unreliable
custom counter it is then
@copper vortex What's the idea behind this anyway? I haven't had the need for two different PlayerController classes yet. Especially not in the SwapPlayerController call.
Given this only calls on SeamlessTravel, so you start with PlayerControllers being the same, then you travel and you want to split them?
Nah this is called by the login function
I just want a player controller that I can code some AI functionality into for testing actual player interactions and stuff
Seems to be working now, TestAIPlayer controller loads in on player 2 when I start a PIE session with 2 players, so now I can make it do stuff
Yeah it's called by the Login function via HandleSeamlessTravelPlayer.
Actually, is it called by login?
yeah
login calls SpawnPlayerController() with two variables
which calls an overload with 3
which calls an overload with 4
which calls SpawnPlayerControllerCommon
All good.
and it basically just feeds in the data I feed into the super call there
Ah I finally found the code that spawns the dummy playercontroller.
I was talking about that with someone a couple weeks ago but I couldn't remember where they do that.
ULocalPlayer::SpawnPlayActor
// The PlayerController gets replicated from the client though the engine assumes that every Player always has
// a valid PlayerController so we spawn a dummy one that is going to be replaced later.
//
// Look at APlayerController::OnActorChannelOpen + UNetConnection::HandleClientPlayer for the code the
// replaces this fake player controller with the real replicated one from the server
//
Might also be interesting for you, as that spawns a PlayerController for a brief time before the correct one replicates.
And I think that uses the APlayerController class directly.
Might not be needed to be addressed though
lol this explains a lot of "why is there a player controller here?" situations
that makes sense though because too many things rely on it to want to have an in-between that could just never arrive
Probably also a nice example of how one would handle that for any other predictively spawned actor that later syncs up.
Yo guys I am working on a coop game where there is essentially two versions of the same map and first player is on the first version while the second player on the second version.
Now what I did for now is created two levels and then added them to main level as the sublevels what I mean
MainLevel
Map1
Map2
and both sublevels are set to always loaded now I am wandering is there maybe a better more optimized way
what is the main optimization concern here?
the authority would probably be a bit forced to have the level loaded unless you just want 100% trust to run the game on each client locally and pass information between (which is actually probably possible, but something still has to the authority even if it's meaningless and replicating actor handles is going to be annoying without replicating them the normal way which would mean just having each level on the server/client anyways)
I'm thinking they might mean from a workflow/design perspective rather than performance
I don't understand what "two versions of the same map and first player is on the first version while the second player on the second version" means in terms of how they differ or overlap
does one need to see the other moving around in the same space but with subtle changes?
like timelines for example player 1 is playing in past and the player 2 in the future and e.g. there is this cube in the present when moved by the player 1 that same cube will be moved in the future by itself
and the maps work that both maps are always loaded on server and the client now there isnt any issue right now because map is small but I was wondering when the maps get bigger will there be any issues and if so
is there a better way to set this up
https://www.fab.com/listings/7e786da1-35e1-458e-96e0-7b1bdb333b39
Do I absolutely have to use such solutions if I don't intend to introduce any non-standard movements?
🎥 DEVELOPER SHOWCASE - Check out this showcase of GMC-based games made by our community.🎞️ TRAILER - Watch the original GMC release trailer.🎮 DEVLOG - Hear about indie developer Rory's experience with the plugin (not sponsored).🏄 SURF DEMO - Surfing GoldSource physics demonstration.🐇 BHOP DEMO - Bunny Hopping GoldSource physics ...
Will I always have slippage etc. with Character Movement Component?
Hi everyone, I have a problem I can't figure out. And I'm hoping I can find some help here. 🤞
In my level, I have a Keypad that allows players to open a door to escape.
In single-player, everything works perfectly: the Keypad appears, the camera switches, no issues at all.
But in multiplayer, here’s my problem : ( Probably due to my poor knowledge of multiplayer and replication... 😕 )
When the server interacts, everything works as expected: the camera switches correctly.
When a client interacts, the behavior depends on how replication is handled:
Either the Keypad appears for everyone (both the server and the client).
Or nothing appears for the client, but the keypad pops up for the server.
So, the client does send the interaction, but the Keypad seems unable to differentiate who is interacting (server or client).
My current logic: ( See Screenshots)
Result:
Nothing works as expected…
I’ve tried multiple approaches, but I still have replication issues. So I guess I'm missing some knowledge here to get the logic right.
I’m still looking for a solution, but if anyone has an idea, I’d really appreciate the help! 🫵 🔥
so ULocalPlayer always spawns a local & dummy PC ? whats class does it have ?
and the server will later create the real one, and replicate it to the client ?
If I understand correctly when player presses E the camera should focus on keypad right?
Yep exactly
I assume when E key is pressed C_InteractKeyPad event is called?
Yes, but idk if it's the right way to do this
Even if i call the logic inside the PlayerController that dosent work :/
Would I mind send all the relevant functions that are connected to this logic
Give me a moment, I'll send it to you 🙂
is there a cmera on the Keypad actor or do you use Player Character Camera?
Don't worry about the door not opening on the client side when the correct code is entered. For that, I think I can do it like I did all along in the other levels.
I use a Keypad actor Camera
How do you show Interact E like collision line trace or?
Is an interaction interface
Note: I also have buttons all along my levels that use the same interface interaction and my buttons are well synchronized in multiplayer, the doors, the enemy AI, etc. It's just this keypad that's causing me problems.
in InteractionLogic who is GetPlayerController 0 that is supposed to stand for player who need pressed E and you want focus on Keypad?
Yes, that's right.
Each player who presses the keypad should be able to play the keypad code for themselves
Assuming you are using listen server if I am not wrong PlayerController 0 is always the server controller so if i correctly understand the code you are always focusing PlayerController 0 onto keypad which is server controller
Yes, that's true. Is that where the problem lies? How can I fix it? Do I have to run the "set view target blend" code in the player controller and then run the rest in RPC classic?
well i dont how would this work but I would do it in PlayerCharacter
When E is pressed and if it is in Keypad area
Run On Server Event
SetViewBlendSpace
get player controller of the character/self
then get ref to keypad and get camera
if that is somewhat understandable hopefully
you can just try to see if it will work with then if does change whatever needed
Yes, thank you! I'll try that and let you know how it works.
Nop... That simple logic allways show me the Keypad for the Server when the Client interact with it... 😕
But when i use the "GetPlayerController" and i set it to "1" instead of the "reference to Self" that the opposite which happens ; Server interact -> Server show to client (1) Keypad
So, I thought I could use the "IsServer" node and in the "Branch" true --> Get player controller (0)
False --> Get Player Controller (1) But the client or server leads to "True".
Oh, I just had an idea and I feel like I'm on the right track! 🤞
APlayerController and yes.
someone knows how to destroy the capsule component?
run on server -> get capsule component -> destroy component
or just you can change the collision settings of capsule for pawn et.c
Certain static meshes appear blurry on high-end client PCs when Texture Streaming is enabled (MipBias 0 so high, PoolSize 3500). The issue occurs only on clients, not servers, and resolves when approaching the object's initial spawn location. The powerful PC has a problem, the weak one does not. Could the problem be related to replicate / level bound? When I get closer to the static mesh that was added first, it fixes the problem for those static meshes.
Any idea?
tried that
didnt work
same for no collision
visibitly
but not trie for collision settings, but idk what i put it there
Trying to make a multiplayer Tetris game. I have a component on a player controller that is suppose to handle the input movement for the game, but when I attempt to move in game it refuses to update on server.
We have the input on a component, the input event calls a function/event on a replicated reference variable for the Tetris game. The objects moves, then snaps back to its previous position as soon as the server updates its position to move it downward. I've tried every variation of calling the server, multicast, rep notify etc. but no luck to get it to behave as expected.
Does anyone know why?
Hey guys, I have a confusion on Multiplayer.
If I spawn an actor in Server.. Then Send Multicast RPC, with "spawned actor" parameter, is this meaning client can also acces that spawned actor on its instance?
For now, I spawn a tool in server, then send multicast rpc with that tool object reference as output, then in Multicast, i simply attach it to actor, but it seems like Client has invalid reference on it.
Here, Is Valid execution doesnt return TRUE.
unreal engine multiplayer makes me want to rip my hair out
So am I stupid here or missing something massive when it comes to IRIS? I followed all the steps in the documentation and loaded up my project and so far everything still works 3 clients at a time in game code, but if I want my player state to be handled with IRIS I just register this and that's it? I don't need to mark any other properties? I tried reading Lyra I found a few files that also had this but I didn't see anything else special about replicated properties using IRIS... I just feel like setting it up with a few code snippets and a boolean and then just override this virtual registration and in one line my whole actor is ready to go?
why does this event not replicate for player 2
player 2 can see when player 1 does the event, but player 1 cant see when player 2 does it
im guessing it's because the look rotation isn't properly replicated. also, probably don't want to use a multicast here. just do the pickup on the server
found out the problem, unreal didnt set the 'current animation' variable for player 2 for some reason
you can either figure out how to get the look rotation replicated properly, or send a transform as a parameter in trace pickup
now imagine unity MP 
There's no guarantee that your multicast will be received after the reference is valid on the client. If a client requires the reference to do something with it, then you should be using OnRep variables and using the OnRep function to drive the logic that requires the reference.
Thats it man.. I think you got a point. But how that reference will be valid for the client? Since I pass it as parameter, i thought he would instantly get it from the input.
This nodes are called on server. I also SetOwner for Equip Item Reference after spawning.
Then here, I simply try to get ItemRef for the client. I'm sure that MC is called on both instance, but ItemRef is null on client, which means i cant access it. I also tried to add a delay before Attach Item node.. But I think it doesnt make sense after MC.
Passing references through RPCs doesn't mean you're giving them the reference, you're asking them to refer to the object, if it is valid on their end. That's why you need to use an OnRep.
And something like this is stateful, you shouldn't be using multicasts for it anyway.
Hmm. I will convert this to OnRep, i will replicate the Equip Item Ref and listen RepNotify. Thanks.
One thing I need to be sure of that is, Is that a timing issue, or If i send a parameter from Server to MC, would this client have a valid reference, or he will never get it. I mean is it possible to set a Reference in server, then pass it to client with MC?
A simple case is, Spawn an actor, set it as reference (no replication), then pass it to Multicast.
Since the client will also have the multicast, would it get server's reference, or it will be always null?
This info will be game changer for me. 😄
It's party timing, yes. The multicast would be sent immediately but there's no guarantee that the reference to the object exists on the client at the time the multicast arrives. If it was valid at the time, then the multicast would be referring to a valid reference.
It would always be null in that case if it is not a replicated actor.
Hmm. So if Equip Item Ref is not replicated, Even if i set in server, then pass it in Multicast, Client wont have its reference, nevertheless the timing.
And if i am replicating it, there is no need for multicasting anyway for timing issues, because when I spawn it and set it, it might not be replicated in the client after I call multicast.
That was the issue for me yes. Now only question left for me.
As you can guess, Attach Item was called only on the server only after multicast, because client has no valid Item Ref. But Client can still successfully attach the item on his hand. Does this mean, when attach actor is called on server, it will be replicated on client automatically?!
When you spawn a non-replicated actor it only gets spawned on the instance that spawned it. It cannot be referenced across the network.
When you spawn a replicated actor on the server it can eventually be spawned on clients, but it's not guaranteed to be valid on all clients (things like network relevancy, come into play too), and yes, it can take some time for any clients that would have that actor relevant to actually spawn it on their end meaning it'll be a moment before they will have a valid reference to that actor.
Attachment I think is one of those things that is automatically replicated for you. It's been a while since I messed with it.
Thanks man. Now i am trying to convert this into RepNotify, In MC, I would easily pass the references for Socket etc. But now, I set my Equip Item reference, but where do I get those references now?
Maybe the data will be passed also be replicated.
Anyway thanks man. I always thought if passed data is not replicated, it would still has a reference on Client.
That also relives me that every actor that is far away can see my attached item, even they were away and come closer.
Anyway i was just confused, I have already have the data inside the variable I have set as interface.
I will set it via of it.
Now since this Equip Item Reference has another Rep Notify inside of it, "like Setting Collision status, is it wrong to call it in here RepNotify? OnAttach simply sets a replicated variable to set its collision. But If it called on client, would it effect it?
Finally.. My client cant interact with the item that is attached on another component. I was completely mad why my MC is not called on ItemRef, resulting not deactivating collision.. That client can take items from other client.:'D
Not a bug, its a feature..
not without seeing your code
Why do you need to multicast anything here? is this actor replicated, and is replicate movement turned on?
how to call RPC on actor placed in editor world ?
uhhhhh
what do you mean by placed in editor world?
just placed at editor time?
aka the map gameplay starts with that actor already there?
It's the same rules as when they're spawned at runtime.
if i set an actor to DORM_DormantAll and send a server->client RPC, should it go through?
how about if i call Destroy() on the server? will the client also destroy the actor?
Hey guys asking for your experience here
If I replicate an array of UObject as inventory Items instead of array of structs what am I gaining losing?
Typical array size being 5-20
I don't know about dormancy but if you call destroy on replicated actor on server then the copy in the client's machines will get destroyed too.
guys, I'm doing a dedicated server product, game similar to dota. I was thinking about running dedicated server for each match. How to properly orchestrateit? I guess somehow using EOS.
I have login server that should prolly take care of UX regarding the lobby/match making stuff powered by EOS.
At some point this login server should run an instance of dedicated game server for match. Is there anything in UE that can help me do it? Or it's my own system that should take care of running game server on particular map with particular gamemode?
Is it the right approach to do it? Is there any document/video that describes similar setup?
since we are both in Druid's server, did you not get his dedicated server course?
it probably doesn't cover matchmaking but should cover the part where you run an instance of AWS fleet.
I'm not yet considering production setup
I'm thinking about the architecture right now. Will it be AWS or not, I'm not sure yet
I would probably just make some serverless logic to handle the matchmaking.
yea, the problem is not in matchmaking itself. the problem is how to correctly trigger dedicated server process run for particular match. and how to deliver it's credentials to all players
I have 1000 ways of how to do it in my mind, none of them optimal probably, so wanted to hear some opinions on that one 🙂
I will try to look into it. I've been doing some of the GAS, but it was very very wide and covered much more then GAS. I'm afraid that dedicated server one will be similar.
It does have a lot of hours, but I just take what I need.
well it's only 33 hours actually. not so much for Stephen course
Thanks, I will try to look into it
I mean apart from matchmaking, what else would you need. Credential can be obtained and verified with AWS icognito probably.
not far in the course, but pretty sure AWS have most of what you need.
Icognito for credential, Dynamo DB for data base, AWS lambda for serverless
you need separate dedicated server for each match right? one ip/port address must be somehow delivered to clients. I thought that maybe there's something inside EOS to handle it
but if there isn't then I will just pick one of the 1000 ways to do it in my current setup. I just run simple droplet in digitalocean, don't need to run separate server for each instance of the game, I will just have two processes running. easy to do 🙂
yeah, those dedicated server would be an instance of AWS fleet
which be initiated by anything
I would just let your matchmaking logic run the instance then broadcast the info to all players to join
yea, okay, I guess this is the way
the idea is to run the server only on demand
@subtle kernel
instead having one on stanby and waste resource
it's different question, more into devops sphere
I'm not there yet
can be own servers, can be aws, it all depends
with AWS you can use your own server / machines too
called AWS anywhere if I recall correctly
yea, I'm totally aware of AWS capabilities
I'm just prototyping/demo right now
so need a way to play test it. I have several servers running for different stuff, so I just use them for now
any clues, to do jumpscare replication?
i though its similiar like the others<
server > client (run owning client> view target, play sound, play animation blabla
well its working like for the serversided, but when server is spectating other player after he dies, he sees like the animation of the monster is like stuck or something and doesnt use the normala animation (walk/run)
for client side, when client side get jumpscared, the jumpscare appears in serverside, dunno why
Excuse me if I'm missing the obvious, but in what circumstances this could even happen? I'm having onauthority functions called on client, even in not replicated actors such as spawner.
Why client has authority? checked if I got any flag but nothing looks particularly special.
Idk how listen serverz works in BP debugger
Has anyone else run into the issue where attaching actors while also having the most parent actor simulate, results in the client not getting the attachment replication correctly?
From what I can tell the AttachmentReplication on the actor has never replicated if the actor is considered "simulated", and if any of the parent actors down the chain of attachment are simulating, they are all considered simulating, and it skips replicating this property.
Not only that, but if I fix this in AActor, it turns out that attachment replication never actually welds bodies together, so it ends up becoming a further problem because the movement replication starts fighting the attachment on the client.
Client will have authority if the actor isn't replicated
What happens if you try to attach them on server and locally, instead of attaching on server and hope for replication
Thats fine, I've actually done some custom attachment stuff where I override GatherCurrentMovement and just do nothing, then handle the attachment manually. I'm just shocked this doesn't work.
attachment replication works great in most other circumstances, its just with simulated physics bodies it completely ignores it causing a massive desync between client and server
Because i'm beginner i think 😂
There is not, EOS doesn’t have NAT Traversal on dedi
Can recommend kubernetes
and terraform
if you’re doing something more industrial scale
nah, I was only asking regarding anything inside unreal engine to do this workflow. if there's no, then it's pretty straight forward how to implement. seems like everywhere else 🙂
like discovery part could be done on EOS side
ya
you can do discovery I believe but you cannot do IP masking
@subtle kernel https://docs.redpoint.games/eos-online-subsystem/docs/networking_authentication/
Can recommend this doc
How to authenticate players when they connect to game servers.
https://dev.epicgames.com/documentation/en-us/unreal-engine/using-lyra-with-epic-online-services-in-unreal-engine This is a great guide for setting up EoS
You can check out how they do it in lyra for a working example
@fossil veldt You ready for Chaos Mover?
Is it considered best practice to key off of pawn control switching in APlayerController? I am trying to set up widget changes with the hud.
is that what all those custom character collision constraints are that I'm seeing in the engine?
Na it's a commit with a Mover implementation backed by Chaos.
What's all this
That might be something I need if it can play nice with physics driven gameplay. Walking around isn't a core part of my project but it's something I do want.
ah yes, 47 files changed to walk around with physics
no 
i knew it was coming and im still sadge lol
Most of them are adds
RIP NPP :D
Mover is an Unreal Engine plugin to support movement of actors with rollback networking, using the Network Prediction Plugin or Chaos Networked Physics.
wtf is chaos networked physics
there's too many damn systems up in this, that's like what, 3 ways to replicate physics?

unless Chaos Networked Physics is a superset of the old physics replication system
it honestly doesnt surprise me at all
100% not. They already said last year that are looking into it.
in a lot of ways mover on chaos prediction context makes total sense even
And LEGO Fornite uses non-predicted Physics already
And they have predicted physics for their new vehicle system via chaos too
is that the system that's in play if you just have a physics driven actor with the default replicate movement and replicate physics settings?
Na, they will only put "Physics" stuff on it
Doubt.
thing is people have been forced into channeling prediction via cmc for ages now even epic
Just enabling physics + Rep Movement will only replicate the transform directly
dont see how this will be any different
Pretty sure the stuff behind the lego blocks is different
Problem is the way the data works. GAS is not a constant stream of data
yea
This is what I'm using right now, it appears that the old UE4 physics replication system is now just a mode within the Chaos universe?
er
I mean it works pretty good
the question is if any actually works well 
Thank you! Interesting. So the spawner is actually spawned by the server on auth. So in theory client shouldn't know about it at all.
To be precise, the spawner is a no-replicated child actor, but the parent actor is replicated.
the old method works pretty good
I wish it had velocity syncing but it does its job
Yes, that case. I think actor needs an owner to send RPCs.
SetOwner(GetWorld()->GetAuthGameMode()); // called in BeginPlay(); ```
Is it a good way to set owner for placed actor on the world ?
There's no reason to do that. Clients don't have a game mode replicated, while the server can send any RPC as it's the authority. So for clients it won't do absolutely nothing, while for server it'll do something useless
Route the rpc through a thing the client owns
What are you trying to do? What's the game mechanic
So having a replication issue when spawning projectiles. So the way im spawning projectiles is via a gameplay ability and using a HasAuthority node. The issue is if i turn and shoot the direction of the bullet is more towards where i was last looking but then if i wait a bit and shoot again its where im looking once again. This is when i 'Play as Client'. Wondering if anyone has any tips
The Client has to wait for the Projectile to be replicated down from the Server.
The Client is ahead of the Server, so when the Server is told to "Fire" its slightly behind the view of the Client on their Machine.
The Client might need to predict the spawning of the Projectile on their Machine locally and tell the Server where and in which Direction the replicated Projectile needs to be created.
Then when its replicated, it can be synced up.
Predicted Projectiles can get tricky, its an advanced topic for sure.
Whats the proper way to go about this? Still getting used to GAS etc. So replication setup is different to what im used to
This isn't necessarily an issue with GAS, its more the fact of how replication works and how you are managing it.
You are unlikely to solve this in Blueprint alone.
The Unreal Tournament source code on Epics Github has predicted projectiles.
You need to know and use C++ in order to achieve their solution.
I can happily do it in C++ if needed. Most of the project is built off that. So i'll take a look at their code. Cause the ballistic code is custom that i've done. But still learning and getting used to multiplayer setups
void AThirdPersonMPCharacter::SetCurrentHealth(float healthValue)
{
if (GetLocalRole() == ROLE_Authority)
{
CurrentHealth = FMath::Clamp(healthValue, 0.f, MaxHealth);
OnHealthUpdate();
}
}
```
This is from the multiplayer quick start tutorial, I'm trying to transition code I already have in place to a multiplayer model. Could I do if (GetLocalRole != ROLE_Authority) { return} inside my already existing do damage function?
I have have replication setup aligned with the rest of the tutorial, that is
Also: currently combat logic is handled inside my ai controller inside actors that are spawned. I have to have the server communicate to the clients that those actors have entered combat, no?
Or like...does the server just keep clients honest? They simulate the same stuff the server is, and just asks for permission to do some stuff sometimes and accepts what the server says if they're not hacking but that's done to keep the client in sync?
Yeah that's usually done through state variables in the pawn itself.
I was told the opposite in the c++ channel and just refactored lmao
question is the same either way though right?
What opposite?
That the state machine shouldn't be in the pawn, it should be in the aicontroller
state machine for what?
Well I didn't say state machine
well if you're doing stuff based on state isn't that a state machine?
The thing is that AIController is usually Server-only. So if your AI is in some state, like in combat, and you need that information on the client, then it has to be placed somewhere where it can replicate.
Basically just deciding if the pawn should move, or do attacking stuff
Fuck me lmao, okay refactoring back then
so this is AI decisionmaking or if it CAN do those things?
ai decision making
then yeah that seems pretty AI controller related to me
AI decision making is done via BehaviorTrees
I'm not too fussed on keeping clients honest or doing anti cheating measures at this point
If it is something that has to be simmed locally then you can give them a separate AI controller ran locally I guess?
Or your own state machine fwiw
Heads up btw - BTs are going the way of the dodo. They plan on deprecating them in the future in favor of STs.
You don't really need to sync that all to the client. You can also only have bits forwarded to the client
yeah that's what I've done, it's just a two state system with a processtate function inside the ai controller c++ class
I feel afraid to even suggest anything becuase I feel like it will just cause an argument later
good luck
yeah thanks man it do be like that lmao
The main problem you seem to have is understanding or knowing what parts are relevant to clients and what parts can remain server only.
So at this point, I need something like EnterCombat inside the pawn, and also something so the server tell the client when to call combat animations or?
State Machines for AI behavior, either BT, StateTree, your own, etc., would mostly sit on the server. The client usually doesn't need to know the exact things going on.
But there might be some things you want to tell the client to drive UI, sounds, animations, etc. and those can be, additionally placed into, e.g., the pawn.
What that is specifically is depending on your game
yeah I'm fine with that, I still don't have my head around...what the client is simulating and what the server is simulating, I'm trying to seperate the two now to get multiplayer going properly
It depends
The client usually doesn't simulate much, despite the few client predicted things that make sense.
It wouldn't simulate any AI stuff fwiw
So I have a working ai controller that can tell a pawn what I need it to do, you're saying without further effort that will require replication to get clients to know when to play combat animations and stuff?
and....based on what you just said, moving that logic into a pawn would solve that issue but that's not how it should be done?
Yeeeaaahh
replicated state needs to be on something the client can see
but the server can choose what goes in there from anything else
the client doesn't need to know WHY its doing something in most cases
code runs on server and changes things + calls rpcs that run on clients
So basically the AI controller I have atm is calling a DoDamage function on the pawn
A StateMachine in the AIController is fine and correct fwiw. The client doesn't need all of it replicated. If the state Machine decides to play a Montage and you need thst to happen on everyone then you'd have some RPC or Replicated Variable in e.g. the Pawn that is set by the state machine
void ABasicPawn::DoDamage(int Damage)
{
if (GetLocalRole() != ROLE_Authority)
return;
HP = HP - Damage;
OnHit();
if (HP <= 0)
{
OnDeath();
if (!Friendly)
{
Cast<AMyProjectPlayerController>(GetWorld()->GetFirstPlayerController())->OnKill();
}
}
}```
I'm gonna call the HP value replication function after the calculation soon
What I'm trying to figure out is if those OnHit() functions need to become network replicated functions?
In theory that's fine so far. From here on you need to choose what should replicate.
HP is often something you'd set to replicate. Usually with RepNotify to get a callback when the value changes for UI and other effects.
HP, the fact they're being hit, and I guess the fact that particular actor is choosing to hit them so the attack animation for that actor can be played?
If you need a one time event to play some sounds or hit reactions, then you can use a Multicast for example.
Some peeps also handle this via RepNotify with some timestamp in it to not play it when someone connects 30 minutes later
But that's just details.
In theory you'd have played the attack animation before the damage was even dealt, right?
Uhh, so basically I'm gonna do something like Multicast(This UNIT GOT HIT BY THIS UNIT WITH THIS THING AND THEY DID OR DIDN'T DIE) after I do the hp calculation?
That's probably a goal yeah, I hadn't really gotten to the visual elements of it yet
Could do that if you need that as some single UI pop-up. It really depends on the requirements
It's hard to give a suggestion with the little info you share atm
rpc seems like a bad choice to do it all in one go... use onreps whenever you can get away with it imo
property replication does not get dropped and does not force being reliable to arrive
this is better for stuff that is a "moving target" through and if it needs explicit separate events an rpc is of course fine
Basically I'm working on a rts/moba style game. Actors are being spawned by an actor assigned to that player atm. Those actors run towards each other, and I just finished writing the AI controller code to make them pick a target and start calling a dodamage function (I did a bit of work on the visuals and stuff so I have an animation blueprint going and a death animation and stuff). I started actually getting it towards networkable state recently and now I'm here
changing health from an RPC sounds like basically praying the game is deterministic... I would at least have the final hp value in an onrep
So now I'm trying to get my newly networked run and attack stuff functionality calling my old TakeDamage and Dodamage animations
and death stuff
Yeah you do need to make sure if it's something that should only happen "now", that the OnRep doesn't call 20 minutes later when someone connects 😅
true, you don't want an "event" to be an ancient onrep
you can be evil and send a timestamp though lol
Will it matter if I'm planning on fixed team sizes? ie players will never connect randomly except as a reconnect
I kind of wish there was a sort of state buffer property scheme that would gaurantee sending missed steps
Yeah that's what I suggested earlier. Jambax does that sometimes I think
but that would just be a reliable rpc in isolation (without order gaurantees)
Yes
Relevancy range causes the same problem.
Uhh what's relevancy range?
You don't want the whole game to be relevant to every player. So if someone comes close to the AI later, then the OnRep triggers for them too.
like fog of war type stuff?
So it's not limited to just connecting
I think for an RTS game I don't know if relevancy can keep up with camera movement
perhaps it can
Probably not without an engine change. There is a shitty hard coded delay
But is your game an RTS?
I mean in a perfect world they just do RTS mp the fancy way and go full lockstep but that is a massive undertaking... with small unit counts regular replication can handle this just fine imo
Wasn't aware of that
basically
I'm uncertain if players will even get direct control over any units atm
they did say "Basically I'm working on a rts/moba style game"
I just have missed it or it was before I started answering
It seems like a sort of systemic city sim game from that older game you are inspired by, no? @copper vortex
like for example you place a building and workers use it
yeah I might lean into that harder once I finish with combat prototyping, I'm not sure
I'm not sure exactly but it seems like the players mainly place buildings as the way of interacting
Yeah, you can't order units to attack other units, you can just put bounties on them etc
SimAnt was very similar back in the day too
jfc that was 1991
So yeah I guess I'm going for SimAnt meets majesty meets league of legends?
How many units will be active in the worst case?
A bit of a tough question but to me it might change my answer considerably if you expect to sim 20,000 actors
Wellll, I haven't put much thought into that. The factorio player in me says "as many as possible"
but realistically probably not more than 100
If you want Factorio scale sim you can forget about using any built in unreal gameplay code honestly
3 digit scale I think you can get away with just fine
Ultimately I think there's a point less is more anyway right?
for sure... sometimes it's not really meaningful to just add 2000 of something
I have spent a lot of time making things super fast for no real reason when the real game might not even need 10 of something at once
Well the....poor gamer?...in me also wants to optimise stuff so people can play on their potatoes too
or play with their kinda shitty net connection
That's also why I'm kinda leaning into the indirect control. Take the best part of idle games and actually add strategy and adrenaline to it
You can get away with some HEINOUS things with round-robin style ticking
but the killer will probably be animation if they are all skeletal meshes
Yeah, I'd like to think I could put blocks in place. I almost did for setting up the gameplay loop but ehhh I wanna learn actual game dev stuff
So basically anything I do, I'm going to have to add timestamps to my network calls?
or I'm gonna have a bad time?
no, that is just an example of where you can use a timestamp to tell how old a property's value is from the server perspective
it's useful when you care about precise timing or if it showing up later is nasty
righto, I'll cross that bridge when I get to it
" When an authoritative version of a replicated actor is spawned on a server, it automatically generates remote proxies of itself on all connected clients. It will then replicate information to those remote proxies. If you destroy an authoritative actor, it will automatically destroy its remote proxies on all connected clients."
Does this mean I could just make the pawns with my ai controller authoritative versions? and my events will get passed along automatically? Or do I still have to setup calls to trigger animations and such?
Seems like if not, multicasts are what I want.
Otherwise I don't see way to use onreps to pass along the fact I want it to play an "I've been hit animation"
"replicate information to those remote proxies" is exactly what it says
it replicates replicated properties
and RPCs called from the server targetting the replicated object
why not? you can just onrep a "play animation"
the built in GAS framework animation replication is entirely based around onreps
it uses an index that changes so even if the animation is the same a new one is sent
FGameplayAbilityRepAnimMontage
this way the state is persistent as well
so you can even send being stopped in a certain montage state
you don't have to do this though I guess
this setup is kind of intended to do everything montages can do locally which is more than you probably need
What's a play animation in this case?
in my example it would be a Montage playing on an anim instance
Montages are just a fancy way of wrapping a single (or more) animations in a single asset
that gets played on a slot then read back in an anim node graph
yeah I'm using the paragon assets, pretty sure they use montages
any unreal game that has an "attack animation" will typically do it through montage playback
Paragon used GAS (it was actually the reason it was made) and GAS replicates montages through onreps
which works quite well if it is a third person game
as it kind of hard-codes having only one playing anim instance (argh)
possible to work around with some overriding and a lot of code copying but most of the time that restriction is fine
ohhh I was kinda going to avoid that until I wanted to lean into the moba stuff, if that's the easiest way to do this I'll look into now
naw, it's wayyy too overbuilt for what i'm looking to do right now
"
You have to replicate the variables responsible for having your character crouch and aim.
As an example, if your Character sets a bool value to true when crouching that your Animation Blueprint uses to know when to blend between standing and crouching, other clients need to know of that change too. So make sure that the crouch bool (or whatever you use) is replicated and being set by the server (authority). This will replicate the variable to the other clients and they will know to change the Animation Blueprint as well."
So my animation blueprint has events, not bools or values atm, I don't see way to do this without making a server -> client call to that function in pawn
unless I put something like a flag on the pawn "NeedsToAttack" that gets cleared by the animation bp after it plays that animation
and checks that value every tick
Yeah okay, looks like a multicast function is the way to go for now
UFUNCTION(NetMulticast, Reliable)
void ProcessHit();
void ABasicPawn::ProcessHit_Implementation()
{
OnHit();
}
UFUNCTION(BlueprintImplementableEvent)
void OnHit();
void AMyAIController::AttackTick()
{
ABasicPawn* TargetPawn = Cast<ABasicPawn>(Target);
if (TargetPawn->HP >= 0)
{
TargetPawn->DoDamage(5);
TargetPawn->AttackTick();
TargetPawn->ProcessHit();
}
}
I just need to get something similar done for the actual attacking animation and I think I'm making progress 😄
When would I choose unreliable over reliable multicast?
whenever you can get away with it missing
reliables are a tad more expensive... I would say read the docs on how they work
ty
in competitive game (fortnite,..) do the server actually sending other player's data which is close but not visible to the main player back to the main player?
for example, player behind the wall, do they get unrelevant with the main player?
Or it will still send but the data is hidden by some shenanigans black magic under the client so it wont be read and hack by the player.
Hey guys why will the replaction / custom event. Not carry over. If i do the crouch function do not work any more.
No, only distance. If the server decided relevancy based on what’s visible there would be a delay for the client and it would show people popping in out of thin air
Just do without replication
that's exactly what happening on the screenshot it seems 🙂
Since Unreal Engine 4.23+, WithValidation is deprecated for server RPCs.
Hi is this statement true?
you can still do server rpc with validation, why not? but I dunno usecase for that actually. some version checking maybe
it was just a statement and i didn't believe it so i thought i would ask
WithValidation used to be compulsory but now it's optional
that is what they meant
WithValidation crashes client if it's false, right?
it was deprecated that i thought no that can't be true
it kicks, not crashes
it'd be pretty terrible if the server could crash a client
like some cheating?
i am only asking where i should look don't expect anyone to go through my code, but i've managed to introduce something that is causing a desync, not managed to do this before
is it just cmc no custom code?
cmc? i am sure i've put some custom code in that is screwing things up as i've extending the movement component
yea, character movement component. if you did something there, that's probably the reason
yeah it must be i am so blind, my walk/run mechanics are acting weird in multiplayer mode, i think the character is stuck in run in play as client
is there a server side only call on APlayerController OnPossess i think is only on the client
Hello, I'm wondering what WithValidation is usually used for? I get that if it returns false, the client will be immediately disconnected from the server, but when is it actually used? Any examples?
When you want to kick a client for sending impossible parameters, e.g. you know they're cheating
onposses is being called on server only, if I'm not mistaken
