#multiplayer
1 messages Β· Page 678 of 1
hey! i'm implementing a projectile prediction system where I spawn a client-side version of a server-side actor while the server actor is not replicated, do you know if there's a way to know when a actor is replicated properly? i'm thinking of using a shared ID between the client/server and I use a subsystem to let know the client-side actor that the server-side version is there but I wonder if unreal implement a thing like this by default
ok, I checked UT's source code they do it using position checking it seems and not a shared ID or something like that
Wait what? I woulda thought GUID or something.
They just replace closest projectile?
it seems yup
this part is called in BeginPlay when role is not authority
Lol what
Has UE4 4.27 changed how the ?listen command works? I can't seem to open and host listen servers anymore?
are you testing that by running a packaged build or running instances in editor? if packaged, what are your package options, if in editor, how are you running each instance (standalone?)
also are you using an online subsystem?
(?listen is working for me in UE5 and was working in UE4.26 so i doubt 4.27 changed the way it works)
I'm testing in a packaged development build. I did manage to get a friend to join in, so I find it must be an issue with my other tester.
I would assume their firewall is having a fit with it or something
What's the point of that tho? Won't the projectile pop backwards after replication? Which in my opinion looks worse than appear after a small time.
Iirc they interpolate the location
So it doesn't pop. But this is really only useful for slow projectiles
There is no build in predictive spawning of actors yet
It's also questionable how much you can predict. Once you have your projectile spawned and synced, you might find yourself seeing it disappear early cause it already exploded or hit on the server and destroyed.
Interpolating backwards? Thats even worse xd As the client's projectile is a bit ahead than the server's.
So I launch a fireball then after a sec it starts moving towards me a bit to match the server's position?
Don't remember the specifics. Feel free to read UTs code :P
The movement you are talking about is barely if at all visible on normal ping
And trying to fix high pings is a lost cause anyway
I would personally not bother even predicting projectiles
I mean that might work on lower pings but yeah then what's the point of even using it then..
If at all something that overwatch does
Which is having some fake mesh tied to the animation
E.g. the cowboy trows a mesh in the flash bang animation
With the real one spawning in from the center of the screen, as you otherwise can't aim it properly
And the mesh one just vanishing
Basically invisible to the player
But like a rocket launcher, idk, you can pre spawn the rocket but once synced you run into the same issue on the hit end
Server will hit the rocket first
So at that point you could just not replicate the rocket at all
And have two versions
And since damage is auth you would also need to predict the damage
Otherwise the health bar is gonna be delayed or too early etc
Which means the only thing one could do to make this proper is only use the server to correct the client if the diff is really bad, taking ping into account
And otherwise have the two do their own thing, where client does only visuals and some fake healthbar change
And then we run into problems with simulated clients being elsewhere on your end than on the server
And you probably start flipping the table
Hence why I wouldn't bother
Like in WoW if the target moves a bit then the damage land time and the visual will get out of sync xd
Yeah it's really not straightforward or even solvable. There will always be some problems. The best thing would probably be checking what games like overwatch do and then see how they handle manually introduced lag
Yep
E.g. fire a rocket with pharah in a private match at a friend and make sure you have a 200ms ping for worst case
Would be interesting, I don't know what they do :P
Btw does every multiplayer shooter has a lag compensation system like CS:GO has?
Where the server calculates where an actor was X time ago for each client then decide the hit based on that
That only works for instant line traced shoots tho not projectiles
0:00 Lag compensation
2:00 Interpolation
most competitive games will use lag compensation yes, and it does work for projectiles, but makes the problem harder
where can i find tutorials on client side prediction
Fortnite does not use lag compensation
it uses client authority, with some server side checks.
projectiles on the other hand, they can miss :/
If you use struct inheriting FFastArraySerializerItem and it has UPROPERTY pointer to a replicated UObject, is it possible that client receives replicated struct item before the UObject is replicated? I create said UObject on server and immediately after create struct entry with pointer to that UObject, but afaik the order of replicating stuff on clients is not guaranteed, right?
Yeah I would make no assumption about it
Aw, that's a bummer. :/ But structs have no OnRep, so I suppose when the UObject gets finally replicated, PostReplicatedChange would be called and pointer would have the object then?
My UI needs data from that UObject so I have to make sure it's usable client-side
@tranquil eagle the PostReplicatedChange will fire if/when the Object item is pointing to is resolved
and in most cases, the object pointer will be resolved after you get the instances of Item struct replicated
is client side prediction absolutely neccesary?
if you like it the other way (assuming actor carrying the fast serializer is also replicating objects), change the position of Super call in ReplicateSubobjects override
does that mean it wont fire if its a nullptr and you call markitemdirty()?
in case its a first replicatiion, it will call PostReplicatedAdd with poitner to object being null, followed soon after by PostReplicatedChange with good pointer
Add can have a valid pointer, but depends on what you're replicating
if you are using a FastArray to replicate changes on Actors loaded from level that you really don't want to let replicate on their own for example, those NetGUIDs will be resolved usually long before first replicated changes happen
The way I have it now is like this, in the actor with the serialized array:
bool URPGUIMappingContainer::ReplicateSubobjects(UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags)
{
bool bWroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
for (const FRPGUIMappingEntry& Entry : UIMappingArray.UIMappingEntries)
{
if (IsValid(Entry.UIMapping))
{
bWroteSomething |= Entry.UIMapping->ReplicateSubobjects(Channel, Bunch, RepFlags); // Lets the component add subobjects before replicating its own properties.
bWroteSomething |= Channel->ReplicateSubobject(Entry.UIMapping, *Bunch, *RepFlags); // (this makes those subobjects 'supported', and from here on those objects may have reference replicated)
}
}
return bWroteSomething;
}
you can init it to false, bWroteSomething and |= the Super in the end
it will change the order in which subobjects replicate
depending on your setup, it might not change anything
but this would force the Actor replicated UObjects to replicate before the ActorComponents, for one
but it still does not give me 100% confidence that uobject is created on client before the array entry? Even if I change the order on server?
it wont
almost all my fastarrays have change implemented and add calling change
fastarrays replication callbacks are also in no way tied to OnReps
all item callbacks will happen before the fastarrays own OnRep does
shouldn't it be replicated after instantiating the uobject ?
there are a few specific setups
that can guarantee order
Actor is replicating an Array of UObjects and has an ActorComponent that has a FastArray with FastArrayItems having pointers to those UObjects
then if the Super call is at the end of ReplicateSubobject function
Objects will be there before the FastArray starts replicating its Items
you can get them in order if you pre fill the array
but that is the only way to guarantee order i would trust
then assign uobjects to specific indexes on your array
anything else and you have to rely on PostReplicatedChange to fire when the NetGUID to Object is resolved
so you getting an invalid uobject or what is the problem exactly xD
Well that didn't happen yet in play in editor but I just want to write it in the correct way so that I don't get weird crashes
we use more fastarrays then tarrays
haven't had any problems, except for weird serialization bugs when FastArray itself needs a reference to owner injected into it
i honestly think fastarray is effective for replicating large arrays
otherwise a normal array should be fine for small things
idk
its effective for replicating large arrays yes
And for per-item changes, right?
but its most effective when you require a per item callback to happen
as doing void OnRep_MyArray(const TArray<UMyObject*>& OldArray) then doing diff is just something you need to take a shower right after
oh that is nasty too much effort for nothing xD
its also more limited, as the FastArrayItems can keep per-client local states in it, by adding some non UPROPERTY or UPROPERTY(NotReplicated) members
which are easily managed from replication callbacks in FastArrayItems
Right now I just notify my UI that new item is added in PostReplicatedAdd. If I wanted to be 100% sure that my UObject is resolved I probably should check if it IsValid, if not do nothing in PostReplicatedAdd and in PostReplicatedChange check again and then fire a delegate that an item was added? Would this be 100% correct?
yes, you can also keep a non UPROP boolean in the Item to make sure you don't fire the delegate twice
if that matters
Nice! Thank you guys a lot. Multiplayer is really hard
only thing you need to be really careful about is when you do
void FReplicatedModule::PostReplicatedAdd(const struct FModuleContainer& InArraySerializer)
{
if (InArraySerializer.Owner.IsValid())
{
InArraySerializer.Owner->AddEquippedModule(*this);
}
}```
stuff like this, where the InArraySerializer.Owner is a pointer to the Actor that has the FastArray as a member
as unreal can suddenly decide that the Owner you set in say, constructor, is suddently a CDO of the class that declared the FastArray as a member
even if its a non UPROP TWeakObjectPtr
My multiplayer game at one point desync (This is normal because I use ragdolls and their position gets out of sync a little bit), the problem is that when the player get up I would like to force send the client player's position coordinates to be sent from the client to the server. How can I do this?
probably a reliable RPC to the server sending a getup from position request
if the server accepts it, it'd set the serverside position to the client's requested position (or meet it halfway should it be too far away or something)
I do a server call and then multicast to all clients but doesnt work
You should set the entire actor location not the capsule and mesh
get the player pawn/character and set location in the server
and i dont think you need a multicast since pawn is replicated to other clients they should receive the changes right away
Have you seen this happen if owner is set anywhere outside the owner's constructor?
initializing it after Blueprint init is done doesnt' break
haven't nailed down exactly what causes it though
one of my fastarrays is fine, if you derive a BP its fine, if you derive a BP from that BP, it breaks
one broke during 4.25 to 4.27 migration, inspite of us being unable to track down any code changes that might had caused it
That's crazy
Hi all. Does anyone know the difference between PlayerId and UniqueId of PlayerState?
My game instance on server needs to identify each connected player in multiplayer. My game has level transitions so the identification should work over multiplayer transition. I am wondering which one works for this scenario.
players using the same service to connect will have the same uniqueid whenever they connect
steam id number for steam, for example
GI doesn't need to know anything about connected players
or even be aware its a multiplayer game, its just not its responsibility
for level transitions in MP games you generally use seamless travel and you preserve the PlayerStates along the way
I already have a level transition functionality. What I want is to store a variable for each player on server before a level transition, and then use that variable for each player after that transition.
That is why I use my game instance to store those variable
like TMap<StructForUniqueId, MyVariable> in my game instance.
About UniqueId, that makes sense. but how about PlayerId?
If i leave a backend secret key in a BP method that gets called throug c++ inside a "if ue_server", is that safe, does that info get compiled into the client .exe? the class in question is game mode which suposedly only exists in the server
I don't recall it being possible to cut out BP code
If you only wrap the call it will especially not cut it out
so its not safe then
if i get the secret key from a file it might work tho
since i will only ship the file with the server
hey fellas. I'm looking for an advice. What do you think is a best way to implement a force field wall that allows passage only for players of one team?
I have a few ways in mind:
- on overlap with player, check his team, and if it is a wrong one, apply force to push him out
- create 2 collision profiles, team 1 & team 2, and have 2 separate player character classes, with different collision profiles, so player from team 1 will have "block" response for objects with profile "team 2"
- spawn an impenetrable invisible wall locally on client, depending on his team, so for each player on team 1, there will be a local impassable wall on each team 2's forcefield (tho i'm not sure how it will work out in terms of replication of character movement)
may be someone could give another idea?
IgnoreWhenMoving is a vanilla engine function? like on pawn or movement component?
@limber gyro you could store it defined in a cpp file with #if WITH_SERVER_CODE
and empty if not
so it is vanilla engine feature. great. thank you.
sounds like a good idea, never tried that with uproperties tho, do u think it would cause any issue?
@rugged sandal the pawns you want to walk through, need to call IgnoreActorWhenMoving and pass in the wall
i wouldn't make it a UPROP
why would the secret key be UPROP?
@steep abyss @meager spade thank you guys, it really helped!
im trying to figure out the best way to make some server calls work in BP, i would probably need to call it in BP
its how i would do it, but i am paranoid..
hahah
do u have any piece of code i can check how to implement a BPpure function? google is not helping and im a bit lost
nvm im just an idiot
why do i always find the solution when i write stuff here
Yes it's for custom serialization, it's usually not needed except if you're doing something very specific
NetSerialize is called once on client when the struct is serialized to be sent to the server. And once on the server for each client that is connected to it when the struct is sent to a client
Symmetric property of pawn owners
can netmulticast functions be declared in an interface?
i tried but clients dont seem to be recieving
no
So out of curiosity what becomes the bottleneck in terms of multiplayer over 50? 100?
Hello i have a question about unreal multiplayer,I'm a backend developer(Node.js) so i know some stuff about servers and how it works.
But i don't quite understand how UE4 deals with multiplayer, i've managed to build a server for linux and host it, after i open the level from the client i could successfully join the game from multiple clients.
But that was only for one level and one game instance, do i have to make another server for another level and a game instance?
For eample lets say my game has 2 different maps so for each map i have to make a new server?
And lets say i want 10 concurrent matches for each level/map so i need to run 20 servers in total?
Also is it a good practice to host multiple servers on the same VM but with different ports?do i run into bottlenecks?
@versed ocean GameTime (CMC, Replication, Actors Ticking, etc),
SkeletalMeshes, AnimationBP's, etc
if you want 50+ players, you need Dedicated Server, Repgraph and PushModel enabled. Then you need to optimize everything to make it performant, limit BP ticks, event drive things, etc.
SignificanceManager is another key thing, aswell as AnimationSharing if you have lots of AI the same, that kinda thing
Anyone else that cant create a session with Advanced steam sessions in 4.27?
@fading cape you need to run one server instance per world
@hardy valve i don't use Advanced Sessions, but sessions work fine for me in 4.27
what you mean one server instance per world
exactly what i said
you need to run a server instance, per world (world is map/level)
So back to my example i need to run 20 server instances right?
Ah would love to use that but i need PWs
10 matches would be 10 server instances
Got it, what about ending a match i should just kick the current players when the match ends?
and yes you typically run many instances per physical machine on different ports
yes you kick them out and kill the instance, (or however you handle it)
alright thank you so much for the info
@meager spade Sorry for the tag, but how do you solve people joining a "private" session for example? Since you cant have PWs? π
we do have passwords
we send them via session data encrypted
not super secure, but keeps the honest people out, just like any security
Is that also in Blueprints?
Or do you use C++?
Ah, well yeah i did but that seems broken in 4.27
Hello, I'm implementing a multiplayer character, and I've just noticed that it's impossible to customize the correction sent by the server to the client.
I've a character that has a stamina. On the server I'm able to detect that the client and server stamina is different, but differently from the client to server communication, it seems impossible to customize the server adjustment (There is no Archive / Serialization method). Is it possible to send custom data from server to client??
Do I've to override SendClientAdjustment completely?
π€ I can't find anywhere in the code a way to customize the client adjustment part, though it seems so wrong that the only way to send that additional data, is overriding SendClientAdjustment and send a different RPC.
Oh cool, I was just looking at legacy code. Basically what I was looking for is implemented by:
if (ShouldUsePackedMovementRPCs())
{
ServerSendMoveResponse(ServerData->PendingAdjustment);
π» π€
Can anyone help me out? I'm trying to spawn a point light for a character in BeginPlay. I want it to be spawned locally only. However in begin play everything gets replicated. I've tried:
- Switch Authority
- Is player local
- Running code using Owning Client only
But none of these three seem to work
Is Locally Controlled
Already tried that
When doing True, nothing spawns
With false, it spawns for everyone
@devout shadow Why is the owner of this character also a character?
it is a variant of the base character
you have the basic mechan9cs character and this is the character with special abilities, diff mesh etc
What I more mean is that if this is the character that is possessed, this thing's owner would be a controller. IsLocallyControlled should be called on self.
Since ServerMoveHandleClientError is still a legacy function, there is no way to customize the character status check and verify that both the client and the server are in sync.
I added this PR to fix this issue https://github.com/EpicGames/UnrealEngine/pull/8672 what do you think about it?
This works for everyone except listen server! So really close
@kindred widget managed to make it work by adding a delay...
I want to override a couple of numeric variables stored in data assets (weapon damage - weapon range, etc.) using my web service(has cPanel for overriding) at the beginning of the game. How can I override my data asset with my web service variables?
Does any know how to take the Open XR vr template teleportation system and move it towards multiplayer, currently the clients position and body is being replicated but when i try to begin the teleportation nothing appears.
Is there a stat command for displaying RPC call counts?
Or at least is there a way to visualize if the RPC send buffer is being saturated?
Usually I take a network packet capture and take a peek, there is some stuff kicking around in... one file. can't recall if its NetDriver or World.cpp that has some cvars around limits
Hi.. I am building a dynamic tile based world where there are
- A persistent level
- multiple levels each packaged in a separate pak file
- A Map Variable Which maps each Tile location to pak file and level in Pak File
Since this is a mobile based game, we are planning that
- The Server when it starts, will download all the pak files and create the world on the server.
- the users can download the pak files on mobiles that are near to them at a certain distance. If the player moves to any direction, the relevent new pak files can be downloaded in runtime.
So now the issues I faced:
- I tried Level Streaming: It seems I can not use level Streaming, as for level Streaming, the world needs to be aware of the different levels while packaging and here that is not the case.
- I tried Load Level Instance, But it creates a duplicate level instance on client as well as server. In that case any BP that is present seems to be not connected to server and hence not replicated.
Can anyone suggest what is the solution. ?
I don't know myself, but any of this maybe?
net.RPC.debug?
Not sure how much info that really gives
Profiler for Network or Unreal Insights might be the better choice?
You can create this yourself
One sec
:P I even made a custom one for The Ascent, where it created the same file but only for our own variables and commands. Quite handy
Yeah nice thanks.
Does anyone know if repnotify and skip owner condition works together? (I need a way to notify others and skip the caller)
I am using BPs
Have you tried it?
Anyone here have good experience with Collab viewer?
yes I have and it does not appear to skip owner and was wondering if others were successful
What class is this on and who's the owner?
In the controller class I have a "reference" to a replicated actor. When I want to update it's pose, I want am using an RPC on Server to set Owner (controller as parameter and the copy of the actor in level), then directly update the RepNotify variable w SkipOwner
like this
this is in the controller class
Yes I am, whenever the local user (controller via pawn) teleports
That sounds super fucky. Owner might not be replicating before the pose is.
The simplest way I can explain why I need to skip is because
this actor (which has its owner set every time someone teleports) contains "data" from a remote user
So whenever you teleport, you only want to update your "data" on others' pc
Hey, I'm seeing an unexpected result, where I'm using UMotionControllerComponent, and it replicates the location and rotation from server->client as soon as the component is set to be replicated. I'm not using "Replicate movement" on the actor that spawns and attaches the component or anything.
Yet I can't see anything in UMotionControllerComponent that has to do with replication of movement
Expected result: Component is replicated, but the location and rotation is not
Has anyone experienced this?
Alternatively, is there a way to conditionally replicate a component? Like, not the reference to the component, but the component itself.
I want the server to spawn it, and only the pawn that is possessed by a client should have that component spawn on their end
I would like to learn how to set up a login / registration system for a multiplayer game (dedicated server) and how to save data for each player (login data, experience, level, etc.)
Can someone recommend a tutorial to me or at least tell me what I have to learn for it. I would prefer C ++ tutorials. Thanks π
Get your own data server up somewhere with PHP or Node.js running, have a database attached to that
Then have dedicated server talk to that server with something like json data over HTTPS
Unreal side is essentially string formatting + the http module
Does PlayerController->PlayerState exist in AGameMode::PostLogin? It looks like it's nullptr at this point.
its not
PlayerState is instantiated in APlayerController::PostInitializeComponents
also, HandleStartingNewPlayer is generally better for player init
as it works for seamless ttravel as well
.
What is the actor and how is it getting spawned?
Why are you spawning player controller
You should set it inside your game mode and set this game mode inside your world settings
Then it will auto spawn for you without any issues
A PlayerController with no player to control it... You're either too advanced for my understanding or too naive, dunno which.
Hi, I am using a listen server for multiplayer and when I join with the client and try to sprint (SetMaxWalkSpeed) the server is able to but the client is not.
Is there any way for me to get the client to have working sprint? I think it is because the server does not know that the client is sprinting.
im new at this multiplayer thing so...
Do you wanna do it the correct way or the hacky way that will break with any amount of ping?
Correct way involves c++
:/
i asked the forums before this and they said:
The issue is the speed change hasnβt taken place on the server. Server is correcting, thus jitter.
Client responsiveness approachβ¦
Input β CMC: set Max Walk Speed β Event: Server Set Speed (Run on Server)
Event: Server Set Speed β CMC: set Max Walk Speed
Simple server auth approach
Input β Event: Server Set Speed (Run on Server)
Event: Server Set Speed β CMC: set Max Walk Speed
Downside to the pure server auth approach is latency of the player will delay the action.
i just really dont know how to do multiplayer
so idk
i just started
The 2nd half of that post will work. It'll still rubberband a bit for the slight time difference due to ping but it'll work.
okay
Or you can try this totally cheatable but maybe smooth approach, limit input while walking and only allow Max input while sprinting. It's totally client trusting but should work.
i wanna try and do it like that but i really dont know how
like how do you get it to do it only on the servers authority
π
But as Adriel said, you'll still get some slight rubberbanding if there's lag.
ok
Start with just replicating a single number. Learn to crawl before you sprint
i dont actually get any rubber banding with changing the walk speed
With lag and jitter?
i always test with 90 ping and 1% packet loss
Are you talking about just the naive approach of setting locally then rpcing it?
i mean i do it via GameplayEffects
Ye that's prolly doing it for you
but its the same thing, its set locally and then server sets it
still the same as a RPC tho
(if client is the one applying the effect)
Hmm ya I wonder how it's not jittering. You tried with extreme speed differences? Like 5x?
i have a kind of related question: for server-applied effects, do you immediately apply a movement speed change on the server, then on the clients? this causes a bit of lag. I've found i can reduce/remove the lag by RPCing the client to apply the effect, waiting the client's ping, then applying it on server/other clients, but obviously this makes things like slows applied later for clients on higher ping. is there another common approach for server-initiated movement effects on clients?
my current approach is almost like... forcing the client to "predict" the effect to prevent jitter
for client-initiated stuff i've got CMC all set up for that. this also applies for something like knockback, which im using root motion sources for. if i just play the source on the server and replicate it down, i get jitter. if i RPC the client to play the source first, then apply it on server later, i dont.
@dark edge no cause my game does not require such huge speed changes
Hi all
I got big fps drop when I set split screen for local multiplayer
do you know why and how can I improve performance please ? any advice ^^
Have your profiled it?
How can I do please ?
My scene has only 300k triangles and a landscape of 1017x1017 but with 4 players it has 30fps maximum..
What's the best way to do local workstation testing of multiplayer gameplay features? For example, if you have a game which requires 2+ players and you want to test that killing a player works. What's the best way to be able to test this without having to spin up a server, open ports...etc? Engineers work at their computer, so spinning up another server, docker containter, building, packaging...etc is just not a very fast workflow for getting work done quickly. What do you guys do? Currently, we have batch scripts which we run that open a server application and a client application. Also, the PIE mode is not the best tool because the final output of the game (in its packaged state) does not always properly replicate what's seen in the editor itself.
Why not just launch project as server and then launch project as client?
You can launch as dedicated server without cooking or building
The important thing to remember for rendering thread cost is that the cost is doubled in split screen!
omg
anyone has an idea of how to improve performance of cameras ?
lmao
i was just about to ask if this is gross or ok
Just camera as pos + rot on PlayerController
Yes but what I want is a setup where people do not have to go through all the added bandwidth that that adds
Does OnRep_ functions (on c++) does execute on server in dedicated server mode ?
i heard they were only executed on clients
For example, one major problem right now is our gameplay state:
- Players enter the main menu, and are allowed to login with either a RRG account, or with a Steam account (and a few other platform providers)
- Players are able to click 'Find Match' and upon doing so it will check for open lobbies
- Joining a lobby = connecting to an OnlineBeacon
- OnlineBeacon tells users to disconnect from the beacon and connect to the game server once everyone has selected characters they will play (imagine dota, league of legends).
- Game mode in the background spawns characters that the players selected and assigns them a unique id
- When players connect, the postlogin method fires and they possess their pawn based on their unique id
- Game begins
Do I just have to develop a new tool, outside of unreal or something to be able to simulate this?
The PIE system seems to struggle with online beacons, and once it disconnects in editor it is incapable of doing anything else.
If you've determined PIE doesn't work, just launch a couple of standalone clients
either from the editor itself, or make a batch script to do so.
Running a couple of batch scripts is hardly a lot of added bandwidth. Unless you're complaining about having to go through all those steps manually once the game has already launched in which case... yes, you need to develop something to automate that yourself. You don't need an external tool, you could just write some code (in C++ or blueprint) to automate all those actions if you want.
Make a console command to do it or something, and only enable it in development builds.
As of right now, we have two batch scripts, one which runs the server and the other that runs the client. However, the actual editor will not run (because of the design of our game) a designer, engineer or otherwise cannot just open the map and click play. We would have to create duplicate files, one for 'EditorTesting' and one for the actual game. This also adds multiple problems not only because of the file duplication, but also because of the fact that the general flow of working in the editor is essentially broken when coupled with the design flow I listed above. Having multiple batch files running is fine for now, but if there is better ways to make beacons, and the rest all work that would be great. For example, the dedicated server option in PIE needs to be able to have the dedi server run on a specific map, with the beacon and the main game map, while the player is on the main menu (all within PIE).
Is this possible?
PIE will launch everything on the currently loaded map in the editor. If you want the server to launch the current map but have clients end up in the main menu... you could add something that checks if you're in PIE and auto load back to the main menu when the instance starts.
Shouldn't be hard... check if you're a client and if you're running in PIE. If both are true, load back into the main menu.
If you don't always want that behavior on, you could add a convar or some other global variable to toggle the behavior and then add some editor ui (blueprint utility widget would be an easy way) to turn it on/off.
Hell, could just stuff everything into some editor UI that automates setting up PIE instances as necessary - start the PIE instances, force them to load into the correct maps, etc. Probably a better way to do it than hacking on PIE startup behaviors - especially if you still need the normal behavior at times.
Anyone know why after unpossessing my AI does not work on Clientside but works on listen server
I have the AI taking damage and the UI healthbar is working properly along with the animations, but when the death animation plays the AI should unpossess but it is now
Won't this cause the dedicated server part to simply turn off?
No? PIE dedicated server, assuming you've enabled running a separate server, should continue running in the background afaik.
If it doesn't, you could always just have an editor utility (like my last suggestion) start up a standalone server based on the currently loaded level.
just launch a separate standalone process, pass the path to the currently loaded level in the editor in the command line arguments.
Oh yeah, I'm not using that option
Then you're not running a dedicated server...
like, at all
you're running a listen server
which inherently is tied to a client's state
Start by enabling the dedicated server option in PIE settings (might be under advanced options... can't remember). Then try whatever manual workflow you have to load back to the main menu on your PIE clients and see if things work.
This won't work if you're using the Steam subsystem, because Epic disabled Steam in the editor.
Then have the editor launch standalone clients like I've mentioned. But it doesn't really matter - last time I checked steam doesn't allow for multiple instances of the game on the same machine. Local testing needs to be done with a different (probably null) OSS.
Testing steam multiplayer features shouldn't be something you're doing all the time - running with the null OSS should work fine for most development except when working on steam-specific features.
How can an engineer test multiplayer features with two clients, using steam. I guess it's not possible? Engineers work at their desk, on their workstation. They need to be able to play and test, at their desk (no remoting, no spinning up a server, docker container, ec2 instance...etc)
You need at least two PCs (or a VM).
how do I get the NetworkGuid for an actor ?
Testing steam-specific functionality should be the only time an engineer needs to actually do so. Testing general multiplayer and session functionality should not require steam at all - the null OSS can do all of that.
Hey how to make my Single player Third Person Template game too Multiplayer?
With blood, sweat, and tears. Mostly tears.
In all seriousness, start reading through the pins in this channel. There is no simple answer.
i would hope very little blood
lol
OnRep_ functions are not supposed to be triggered also on server ?
in blueprints they will, in cpp they will not, but you can manually call them if needed
ugh
calling them manually makes server side breakpoints hit in OnRep functions π€’
speaking of that, is there a way to tell what machine you hit a breakpoint on in PIE?
generally yes
callstack can tell you some of the time
or you can get a role and remote role of some actor relative to the scope in which the breakpoint is and put them into watch window for quick ref
For vs breakpoints there was a watch you can add to get which instance breakpointed
But I can never remember that
BPs usually show you anyway
I have some replicated actors in my lobby that can get destroyed, the problem is that if they are destroyed and a new player joins they still call their begin play before client gets informed that they already got destroyed. Is there anything that can block that from happening?
That doesn't seem like it makes a lot of sense. Replicated actors wouldn't replicate if they were destroyed on the server, so they wouldn't exist on the client, therefore their begin play wouldn't fire.
Are these actors something that exist within the level itself rather than being spawned by the server?
yup
Hi, I need some help with setting up audio tests with a listen server and a client in editor. How do you guys test audio replication in editor? I can only play sound from one window at the time, however I want both the client and the listen server to be active and play audio independent of which window is focused. Is this possible?
Okay so I solved it by using the setting Route Gamepad to Second Window and performed my "client" actions with a gamepad instead, while focusing on the server window. There as to be a more robust method though?
Make a bool or something variable. Set it to Initial Only. Default false, make an OnRep for it. Use this for the callback binding when it replicates to clients.
Server should probably set it true in it's beginplay. Clients won't. Then your server can have any connecting client run the callback. If it's destroyed on server, it shouldn't replicate so no callback.
I guess that might work, thanks
Your only other option is simply not spawning it with the level, but spawning it specifically through code on server.
i am trying to create a dedicated server build in UE5 for a game i made for testing UE5's new features i went over the steps Here https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/Networking/HowTo/DedicatedServers but got stuck when it came to packing the project, in UE5 from what i have seen there is no Build target option when packaging the game, im not sure if they moved this option somewhere or if there is a new way of doing it but any information is useful!
I downloaded and built UE5 early access 2 from source
@meager fable @kindred widget Set NetLoadOnClient to false?
That will cause them to be spawned through replication
No need to manually spawn them
Learn something new every day. π
looks way better, thanks
I'm testing out replication distance culling and it seems like anything with 'net load on client = true' does not get distance culled
players get culled but if the character is placed in the level manually then it does not
setting 'net load on client=false' makes any character placed manually in the level do distance culling as expected though
is there anything that makes manually placed characters behave differently with culling?
further testing shows, the manually placed actor doesn't get destroyed on client when out of relevancy range but it does stop replicating (with net load on client=true)
whats manually placed?
net static actors don't get destroyed
ones spawned at runtime do
net static actors will stop replicating out of relevancy range, and will send a full replicated property package when they become relevant again
engine differentiates them by the last bit in their NetGUIDs
With VM, for me,doesn't work.
the character that the other player controllers were controlling is manually dragged into the level
makes sense as it is a static actor
never knew about the net static actors - cheers for that info π
Hi, i have character selection set up which works for both server and client when I run the game through the editor with the settings in the image which still technically runs through steam, but when me and a friend have the game files and connect through steam the character selection only works for the server.. any ideas on why this might be working one way but not the other?
I have the net cull distance of player characters set to default, and they are always relevant, but for some reason I'm not seeing players at relatively short distances
I can see the weapons of the player though
But not the player character meshes
any help is appreciated
specific distances
Hm maybe a bounds issue for rendering?
Otherwise I would have said maybe it's the OwnerOnly see stuff
RPCs called in same frame packed into single packet right?
no
well
they can go in same packet
but they can not merge their payloads
that you need to do manually
Can anyone help me figure out how to resolve this lol?
'ERROR: Failed to copy H:\Source_4.26\Engine\Extras\Redist\en-us\UE4PrereqSetup_x64.exe'
Does anybody know how can I override the Data Asset Values from a web service ?
You are not talking about a solution that can be done easily without editing the source right π
In any case, it's not worth it. I was just asking to know if I can sync local/client ammo variable on weapon and servers one during reload
You can probably try the RPC batching technique epic used in the gameplay ability plugin if you need to send multiple RPCs in a short time
Thanks for the input
Hi mates, I'm new here and I have a question.
For a multiplayer character how should I do variable communication between character actor and anim BP?
Should I do it using Anim bp tick event which gets replicated variables from character and set to AnimBP variables or should I use interface messages to change variable in anim BP? They do same but I'm asking this for distance players who become a problem for relavency
iirc if an actor becomes relevant again its spawned again
You dont need interface in any case, why dont just get the anim instance from mesh and set your variables there
I'd use OnReps instead, they are fully client side (unless you call it manually from server) and called when replicated variable changed/initiliazed
use delegates/event dispatchers man
yeah I'm using onReps for my some variables but I'm doing something unusual to have a better client gameplay fluency in real world lag cases. For example to aim, I do a check and set locally and then call Server RPC. Server alsa do the same check and if valid it sets my onrep variable.
In my onrep function I eliminate the local player to prevent aim twice
like this
That's not unusual, it's pretty common. You're predicting the action then calling server RPC to apply it. What you can do is gate the logic in OnRep by comparing the network roles
is my ss correct usage?
If it's already done this way, server and clients will update variable anyway. Owner client does not involve in networking process
Yeah
Why do you care about relevancy? If an actor becomes relevant again onrep will be called immediately and that logic will run
Oh I didn't know that
Thank you for information
So I dont have to check my variables in anim bp tick?
No
On tick, engine checks replicated variables for you anyway
And OnRep detects the changes locally
It will apply it for you whenever a replicated variable changed
anim BP is a bit of an exception
as it should update all variables on Tick during (Blueprint)UpdateAnimation
so that the rest of it (animation graph) can run off game thread
it should also prepare all data for anim graph and store it into variables during UpdateAnimation
as any use of blueprint logic, even to AND two booleans, is enough to force the anim graph onto the GT
But isnt anim instance tick and other actors in the same thread? What could happen if you dont update simple state variables in tick and instead update them on external actors?
it is
but
generally its not worth creating an extra dependency to update BP anim graph from external source
the update on UpdateAnimation with anim graph being aware of its Pawn and nothing writing directly into anim instance
provides a nice clean separation for multithreading
and whatever you do to avoid updating the anim instance on Tick just isn't worth it
I see, thanks for the clarification
any gains would be in nanosecond range
potential cost is multithreading fail
no thanks π
OnRep is good if you need callbacks
but specifically (and just for) animation blueprint, no
I got it thanks
The other thing I'm wondering is how many shoul I have replicated variables in my caharcter?
I have around 70-80 replicated variables right now
as few and as many as you need to have the game working
70-80 seems like way too much though
makes me think you made a godclass
Yeah my character is kind of complex and most of the replicates are neccesary but I will try to reduce them
thank you
your character likely has too many responsibilities
like having weapons integrated into the character
ours has 14 replicated variables total
and game has over 50 months in development (released) with a full team
wow that's a huge efford
inventory is it own class, so are weapons, interactions are handled by the controller
I'm the only dev in my small team
playerstate is responsible for customizing the character/loadout
skills are also separate
it makes it manageable, maintanable
Actually I'm doing inventory and weapon works in separete components too
as you said managability is so important
I have a game where I'm using UWidgetComponents to show stuff in-world. But I want to control their visibility per-player. For example when a player is near an item, I want to show the item's item only to them. I'm still new to multiplayer, what's the right way of going about this?
There are several ways to do that, the most basic method is using proxy collisions which triggers on overlap. The other way is doing overlap checks locally in character via timer. The point is whatever method you choice, doing that checks locally in your client.
I was more curious about how to change the visibility to be per-client
You can do checks in items too but in this case you have many actors that are ticking even if you use timers instead of tick event
If you set the visibility locally so the result is will be per-client
Hi, I am new to multiplayer and was hoping you could help me with this problem. I have a "Teleporter" blueprint, and I want it to teleport whichever of the 2 players on my listen server back to a certain location. Is there any way to to this?
Hi, as I understand you want to teleport player who overlap the collison right?
Update: I tested it again, it only teleports the server client
yeah
It is because you are getting the player controller 0 in server event.
when you say "Character", which of these do you mean?
When I use "First person character" which is my player, it is incompatible with the actorbeginoverlap
any idea why setting the input mode to UI only on the server player (listen server) doesnt work however its just fine when i run it locally on clients? its running locally for the server, i just cant seem to set the hosts input mode for some odd reason
@twin juniper When in doubt, go through your code step by step and really think about what it's doing and if that's exactly what you want it to be doing. In your first draft of this, you were teleporting the first player's pawn, when you wanted to teleport the lawn that stepped on the trigger. You need to be VERY specific and logical when programming.
In software engineering, rubber duck debugging is a method of debugging code by articulating a problem in spoken or written natural language. The name is a reference to a story in the book The Pragmatic Programmer in which a programmer would carry around a rubber duck and debug their code by forcing themselves to explain it, line-by-line, to the...
On what event are you running it on, behind which logic?
the servers calling a function on its own character and the log is firing so it is running and setting
void AGreatShotCharacter::SetStageMode(ECurrentStageMode NewStageMode, const FRotator& StageControlRotation)
{
UE_LOG(LogTemp, Warning, TEXT("SetStageMode"));
if (IsLocallyControlled())
{
if (APlayerController* PC = GetController<APlayerController>())
{
switch(NewStageMode)
{
case ECurrentStageMode::None: PC->SetInputMode(FInputModeGameOnly()); break;
case ECurrentStageMode::Staged: PC->SetInputMode(FInputModeUIOnly()); UE_LOG(LogTemp, Warning, TEXT("SetStageMode Staged")); break;
case ECurrentStageMode::Active: PC->SetInputMode(FInputModeGameOnly()); break;
default: PC->SetInputMode(FInputModeGameOnly());
}
if (!StageControlRotation.Equals(FRotator(-1.0f, -1.0f, -1.0f)))
{
PC->SetControlRotation(StageControlRotation);
}
}
}
}
Hi, very noob question, but how would i make character to use item or some object on the map for multiplayer rpg game? I can't get all this idea with RPC and not RPC without examples
this should help make sense of what to do when
https://www.youtube.com/watch?v=ssKWex1-_io&list=PLnHeglBaPYu-wPX2jeWEpICr1X_a6K0_L&ab_channel=SneakyKittyGameDev
Patreon: https://www.patreon.com/SneakyKittyGaming
Discord: https://discord.gg/W5g6pZXfjh
In this video we start off a new little mini series that is aimed towards beginners with unreal engine C++ and Multiplayer!
This looks fine. It should definitely still run on listenserver just fine. Are you certain nothing else might be running it again after on a different switch or something else somewhere else in code could be setting the controls to something else?
ill have to check again but nothing should be overring that
Is there a setup where you can have it not load the server map? For example, I have these settings (image). The problem here is that the editor is loading the server map name override that I set, so for a player to automatically connect they need to type 'open MainMenu' or something. Even though I pressed play on the main menu it's taking me to the server map https://i.imgur.com/bEmUxAk.png
It's not a problem for engineers, but for designers it's an added step they need to learn. What actually seems to be happening is the client is automatically being logged into the server, its as if PIE is running open 127.0.0.1 when play is clicked.
Does anyone know why PlayerController::OnPossess(APawn*) is server-only? I want to notify the UI when the player possesses a pawn and it's kind of confusing why it's server-only.
Should I be using something else?
There is nothing BP for that. But there are client side virtual functions you can hook into in both pawn and controller in C++
Are you replying to me? I'm not talking about BP
Hello! Can anyone confirm if PlayerController gets destroyed when a client disconnects (in my case, dedicated server)? Or do I have to check if their connection is active somehow?
Yeah. Wasn't sure, usually that question is for BP, so bad assumption on my part. π But no uh.. I believe the restart events are what you're after. The Restart event in controller is not virtual but it does call SetPawn which is. And it also calls PawnClientRestart inside of the pawn, which is also a virtual. What you're mostly looking for to start your chain though is ClientRestart in PlayerController. That'll run on client during possession. Also runs on Listenserver as host during possession.
Oooh, SetPawn in clients sounds perfect, thank you so much!
what happen to the actor in the client if it is not relevant ?
is it destroyed ? then spawn again if it is relevant?
Depends on if it was on the map at load or spawned at runtime
Because Possess() runs only on the server which means OnPossess() still have authority
so in client side you will need to override this instead AcknowledgePossession(APawn*)
its spawn at runtime
im trying to create object pooling
if its get destroyed then object pooling is useless right? (on the client)
What are you doing where you need object pooling bit are also replicating all objects?
Typically pooling is used for high perf stuff implying lots of objects
I'd either pool clientside or just spawn them.
But if perf is a priority you might not want the full ACharacter
maybe i will try profiling it later
by the way, what about this
is it get destroyed?
ok, thanks
SetVisibility is client-specific, and SetHiddenInGame is replicated?
Other way around. HiddenInGame isn't replicated. Visiblity is.
Can I have a property marked as replicated on my UINTERFACE and have it replicate for any UCLASS that implements the interface? I'm guessing I'll have to add it to the GetLifetimeReplicatedProps method in all classes that implement the interface?
Pretty sure you cant have UPROPs inside an interface.
Hey there !
So ... I got a question.
I have an ASC on my playerstate. I want to use this ASC on my controller.
When I start the game with 2 clients (from UE5 / Play / As Client), Controller C0 is OK, event though OnPossess it called twice (first time no State, second Time OK, but Controller C1 (the second one) never gets the correct reference using method PlayerState = Cast<ABasePlayerState>(InPawn->GetPlayerState());
I also used a if(IsLocalPlayerController()) before to see what could happen, and actually the Controller C1 is ... not local.
but I should have 2 characters, with 2 states and 2 controllers on my computer right ? And C0 and C1 should be local at some point=
that's my understanding, which is kinda false seeing how it behaves
if you have any idea, feel free to let me know ...
I've got a door opening/closing that isn't replicating. Both server and client can open it, but it's not propagating to the other. I've got replicating enabled on the actor, and component replicating on the static mesh component which is moving, plus multicase on the Open/Close custom events.
Btw I followed Tranek's GAS Documentation for that, and almost did the same thing in my controler, but somehow, it doesn't work correctly
now that i think about it, that could actually be useful hahaπ€
π
but ig that would be more a components job rather than an interface
Try asking in #gameplay-ability-system ??
well the ASC is fine actually. It's just the PlayerState access in the controller that gets messy
Make sure you havent forgot to call Super somewhere.
Ehhh
You shouldnt be setting the PlayerState to your cast
If your using it locally, create a local variable.
If your cast ends up nullptr, your basically nuking the PCs PlayerState
PlayerState is a variable on AController you should not be setting its value directly, ever.
ABasePlayerState* BasePlayerState = Cast<ABasePlayerState>(InPawn->GetPlayerState());
Use a local variable instead.
Alriiiight
I learned something valuable
what, so I basically nuked an already existing variable ...
lol
Yes, potentially with a PlayerState that doesnt belong to you.
the strange thing is the compiler let me define this
(don't mind the forward declaration in front)
oh yeah
The Controller already knows about its own PlayerState
just tested and it work fine !
thanks a lot man π
just made my day
@fossil spokeagain, thank you a lot π
π
have a good day/evening y'all !
You got replicate movement checked? Also either replicate state or events. Not both.
When i checked that on the actor it gave an error that i needed to set it to Moveable. Though i have the actor as Static for baked lighting, its just the single component which moves relative.
Actually i have an idea what might be my problem
when a function is used with ReplicatedUsing and the function has one parameter, it will have the property's old value as the argument right?
I wanna test it but I'm deep in code it might be a little while before I can
How you gonna move a static door? Either it can move or not.
Is the component movable?
Doorframe is static. Door itself is movable.
But i realized something talking through it. Ill continue to mess with it. Thank you for responding.
I'd just repnotify a float
@fossil spoke , you're right. No UPROPERTY's allowed in interfaces. Maybe I'm stuck using a component then. I just want to have a uint "Team index" available for several different pawns. I can't put it in a parent class because UE4 doesn't support multiple inheritance (and some of my classes inherit from pawns and some from character). I can't put it in an interface because it doesn't support replication.
I was thinking a component for a single property is overkill, but I guess it works.
Or just have the interface expose a function GetTeamIndex which must be overridden by the implementing class to provide its value...
... yeah, that would work.
hi all, if I spawn a replicated actor on server, then send a client RPC after in same frame, is the RPC guaranteed to arrive to client after replicated actor spawns on client?
I've been using a replicated variable and OnRep so clients can tell when a variable changes and it works great in Client and ListenServer. But when I test the game in Standalone, the OnRep isn't called (I guess because the player is now the authority). Is there a standard way to deal with this or am I going to have to test for standalone and try to manually call my OnRep function?
You must call OnRep manually for Server in C++
Blueprint its done for you.
what is the minimum requirements for running a basic unreal dedicated server? Like what is the cheapest ec2 instance that can handle it?
You arent going to find a concrete answer to that question.
Hardware requirements depend on the resource requirements of your specific game.
No one but you will know what the requirements of your game are.
Start with the cheapest EC2 you can find and simply try running a Server on it. Profile its performance and decide if its sufficient or not???
anyone know if advanced steam sessions plug in is available for ue5
or if its possible to use an old version of it
when i put the 4.27 version in the plugins folder it fails to build
Depends, are you making Chess or Fortnite?
Is there a reason for this piece of code to not be executed on server ?
UE_LOG(LogTemp, Log, TEXT("%.2f"), FocusedInteractable->RequiredTime)
GetWorld()->GetTimerManager().SetTimer(TimerHandle_Interact, this, &UZircoInteractorComponent::Interact, FocusedInteractable->RequiredTime, false);
I'm running this code in a function that is executed on server and client, the UE_LOG does print on server and client but the timer only runs on client ? (UZircoInteractorComponent::Interact only print log)
Show more code than just this
Also speaking to people like that who are trying to help you is a bit counter productive
So thereβs no RPC to call it on the server?
Thatβll be why
wait a min
i'll show u
void UZircoInteractorComponent::BeginInteraction()
{
if (bIsInteracting)
{
return;
}
if (GetNetMode() == NM_Client)
{
ServerBeginInteraction();
}
if (FocusedInteractable)
{
FocusedInteractable->BeginInteract(ZircoPlayerController);
UE_LOG(LogTemp, Log, TEXT("%.2f"), FocusedInteractable->RequiredTime)
GetWorld()->GetTimerManager().SetTimer(TimerHandle_Interact, this, &UZircoInteractorComponent::Interact, FocusedInteractable->RequiredTime, false);
}
}
Again it does work, required time is print on server and client, but for some reason the timer is executed only on client
void UZircoInteractorComponent::Interact()
{
UE_LOG(LogTemp, Log, TEXT("UZircoInteractorComponent::Interact"))
}
comparing GetLocalRole() != ROLE_Authority is a bit better than GetNetMode() == NM_Client
but what does ServerBeginInteraction look like?
does it just call BeginInteraction?
good luck to have GetLocalRole in a component
?
GetLocalRole is only for actor
yeah but anyway that's not rly the issue there π
timers don't really have a networking component associated, so is there anything else manipulating that timer handle, did you add a breakpoint to ::Interact, how did you verify the server output
so is there anything else manipulating that timer handle
it's only set there
in the function i showed
Oh wait
nvm
void UZircoInteractorComponent::EndInteraction()
{
if (!bIsInteracting)
{
return;
}
if (GetNetMode() == NM_Client)
{
ServerEndInteraction();
}
if (GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_Interact))
{
GetWorld()->GetTimerManager().ClearTimer(TimerHandle_Interact);
}
if (FocusedInteractable)
{
FocusedInteractable->EndInteract(ZircoPlayerController);
}
SetIsInteracting(false);
}
It's cleared there
i just tried to comment the ClearTimer and it does work on server now
sooooo
Should i just put the timer on client ?
if it's appropriate
but something is causing EndInteraction to be called prematurely by the looks of it
that's where debugging would be handy
void UZircoInteractorComponent::Interact()
{
if (FocusedInteractable)
{
FocusedInteractable->Interact(ZircoPlayerController);
if (GetNetMode() == NM_Client)
{
EndInteraction();
}
}
}
Tbh it's designed like cr*p, soooooo
How u guys handling client/server interaction ?
i don't rly like the fact that client is doing interaction things before the server does
I mean for tracing, focus etc it's ok but not for interaction
not much better actually, except it's a bit worse because it's a part of our monolithic pawn class rather than a component
Argh
it works, technically
Well first of all... check authority rather than NetMode as was already mentioned - otherwise if any of these methods are called on an actor you don't have authority over you're going to attempt to run server RPCs from them (which won't cause issues... but it'll complain in the log and in other situations could be the source of bugs in your code).
Next, why is only the client ending the interaction? In fact, why does the client need to RPC that it ends the interaction at all? The server should know the timer, and should be what always decides the true time for it to end. Any action the client takes is either input (starting the interaction) or just predicting what the server will end up doing (ending the interaction).
Next, why is only the client ending the interaction?
It's not the case ?
EndInteraction also calls ServerEndInteraction
Yes, and that makes no sense
Interact only calls EndInteraction when on the client.
also i looked, components do have the GetOwnerRole() accessor
Why does the server need to be told by the client when the interaction ends? Isn't there a timer that the server already knows about?
if you can't be bothered getting the owner and then calling GetLocalRole
if (FocusedInteractable)
{
FocusedInteractable->EndInteract(ZircoPlayerController);
}
SetIsInteracting(false);
This has to be done on server, SetIsInteracting is modifying a replicated var, and EndInteract does manage interactors array on FocusedInteractable
Yes, but the server shouldn't be told when to do that by the client
so you would do the opposite ?
From what you've posted, the client initiates this whole thing in BeginInteraction which RPCs to tell the server that it wants to begin interacting
a timer is started on both, but the client's timer should be treated purely as a prediction of what the server is doing
So the server has a timer running to run Interact (and therefore EndInteraction), it doesn't and shouldn't be told to run EndInteraction by the client when it already knows when it should happen.
The way you posted would only make sense if Interact() was triggered by a second input on the client rather than a timer started on both.
yeah true
so how would you manage it ?
timer calling a server event and make the server manage all of the interaction ?
BeginInteract on the client runs ServerBeginInteract, which calls BeginInteract on the server. Both start a timer (assuming you want the client to predict the outcome), both run Interact and both run EndInteraction. No further server RPC necessary.
If you don't need the client to predict the outcome and can deal with the bit of latency of having the server send results back, don't even bother setting a timer on the client.
well you would have one if there's cancelling functionality
Well i'm okay with you but, for example i have some cancelling things
i'll show u
Ok, so you have an extra server rpc called for cancelling.
void AZircoPlayerController::OnTagsCancelled(const FGameplayTagContainer& CancelledTags)
{
if (GetNetMode() == NM_Client)
{
if (CancelledTags.HasTag(FZircoGlobalTags::Get().Interacting))
{
EndInteraction();
}
}
}
mmmh k
Well, assuming the cancellation is triggered by a client input.
Otherwise the server can just handle all of that too.
it's cancelled by tags, so it's called on client and server
so endinteraction is happening on server first ?
it's an event
i don't rly like that tbh
If this is an event happening on both the client and server then there's no further RPC necessary.
It'll get called on both.
think you are trying to over complicate things
the way i did it with client, the client was checking if interacting if not then dont call rpc
with the way u telling me to do it will just spam RPC
if someone want to spam them
ikr, that's why i asked if someone has a better and much simplified design
the way you currently have it someone could just never send EndInteraction. Or send it earlier than allowed.
because you're having the client trigger all of this stuff.
Client initiates the interaction -> Tells server -> Server actually does the interacting logic -> Tells client interaction is finished either completed or failed.
that is all that needs to happen
what if client does need interaction logic ?
server does send an event too ?
If AGameModeBase has GetNetMode() and can return stuff like NM_Client, how would you ever get that when the client can't get the game mode?
you predict your interacting (play a local montage, etc)
GetNetMode shouldn't ever return NM_Client for a gamemode.
it has GetNetMode because everything does.
yeah UObject holds that function, and actor holds GetLocalRole. GameMode will just inherit these
how you want to predict that with a timer
but GameMode is never created on client and its not replicated, so you don't need to do any role/server checks.
since client and server logic need to happen in same time
i dont predict with a timer per say
client knows the interaction time of said item
shows a interact status for X time, but it can hold it there till server returns back
how u handling that ?
now i also handle movement, this calls and RPC to server to tell it to abort the interaction
that is all the client does
same, that's what i showed above
so if i interact with a chest, then move as client, this sends an RPC to the server to abort the interaction
but calling an rpc each time ur moving and interacting
that's not much for nothing ??
my whole interaction system is 4 functions on the PlayerController. ServerStartInteraction, ServerAbortInteraction, CanInteract, ClientFinishedInteraction that is it
i mean for the server <> client stuff
oh
the interface goes on the interactable actors
π
ServerInteract in an interface π
in fact it's not a good name since it's runned on client and server
it was supposed to only be runned on server when i created it
yes its a bad name
that's why
i also added CanFocusInteract
anyways
gonna try what u told me, thx for ur help guys π
Do you tracing on server to check if the interaction client trace was correct ?
ok ok
but not a "you hit this" trace
u do not have timed interaction ?
i do
clients predict it
so before ServerStartInteraction
but server also runs the time
i just call StartInteraction(Actor), this determines the type on client, then i tell server i am interacting
server basially runs the same logic without visuals
if its a timed interact, it starts a timer
just like the client
So ServerStartInteraction -> StartInteraction
well depends on your function names..
how are u handling interaction on actors
i mean
for example my interactable does have a interaction component
interface to get what stuff it needs
a UWidgetComponent
via the interface
wut
so each of your interactable have a interactionTime var
but its dependant from then, not a component or so
well i have about 5 different interactable actor base classes
so its not much work..
π
so for example pickups are inheriting from it
then i have a few very unique things (like interactable AI)
pickups are seperate
due to cost
(spawning cost)
spawning cost ?
KaosGameplayActor also has an ASC
and tons of other things
which pickup does not need
building ?
That's what i did above
everyone told me it was not that good ?
or am i wrong
?
.
that
that's what u descripting
Youre not storing interactors ?
no
how ??
it knows who finished first
how u handle that
ikr but how can the server know who finished first
when interaction finishes, it checks if the interactable is still available
u do a check to only do it one time ?
before giving to player
oh k.
only server controls this value
you would never get interaction the same frame
or the same time on a server
its nigh on impossible
so you basically have a variable on the interactable to say if its available or not
correct
hello, I am trying to play an animation of an actor with my character. But the animation works only locally. So the server cannot see the client's animation, and the client cannot see the server one
dont ever use GetPlayerCharacter
when dealing with replication
also you need to make sure the NewSpell is replicated else multicasts wont fire
My Inventory Component is set to be replicated, but when i call an equip function from client to server, it doesn't seem to have an item object i need. What is wrong?
Tho i don't think it's being created on server. And how can i replicate an UObject? Just by creating it on server?
bit more to it than that
void UZircoInteractorComponent::Interact()
{
if (FocusedInteractable)
{
if (FocusedInteractable->bInteractionBlocked)
{
UE_LOG(LogTemp, Log, TEXT("Interaction is blocked"))
return;
}
IZircoInteractionInterface::Execute_Interact(FocusedInteractable->GetOwner(), ZircoPlayerController);
if (FocusedInteractable->bOneTimeInteraction)
{
FocusedInteractable->bInteractionBlocked = true;
UE_LOG(LogTemp, Log, TEXT("Blocked Interaction"))
}
}
if (GetOwnerRole() == ROLE_Authority)
{
EndInteraction();
}
}
I got a problem with my Interact function, bInteractionBlocked is set AFTER the interaction, but sometimes if i'm spamming the Interaction input it does skip the interface execution ? is there a reason ?
I add item to my inventory when i edit defaults
Is it fine with get controlled pawn ? It is still not working, and NewSpell is replicated
Yep, i thought about it, but idk how should i do it else
if i'm spamming slowly it's all good, if i'm spamming quickly it does skip the interface execution and so just block the interaction for next time ?
and you need something to replicate the subobjects (owning actor/inventory)
What should i override then?
ReplicateSubobjects
virtual bool IsSupportedForNetworking() const override;
to return true
the in your actor/component
My player is replicated, inventory is replicated by player. Array of Item Stacks is replicated by Inventory
yeah but not ur item
and since uobject are not replicatable by default u need to override some things
{
bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
for (UMyItemBase* Item : ItemInstances)
{
if (IsValid(Item))
{
WroteSomething |= Channel->ReplicateSubobject(Item, *Bunch, *RepFlags);
}
}
return WroteSomething;
}```
for example
Oh damn, thank you very much, tho!!! I would never find out about this by myself
and you need to ensure netname stable actually
override virtual bool IsNameStableForNetworking() const override; to also return true
So nobody knows ?
nvm fixed it
π
What was it?
me being dumb as always
i forgot to remove bCanPickup from my Pickup Actor
Im crying right now, guys, you are awesome, thanks for help!!!! I was trying to figure out about this for like 4-5 days, without any progress, except i understood RPCs finally
since i implemented smth better to detect if smth can get interected
gg π
@viscid monolith good 
so do you have other idea. I am starting with ue, and I don't understand how something can run on the server but not be visible by the client
If you are just starting out with UE, don't start with multiplayer
I mean it has been like two months
This really is the default state of any object - to exist on the server first and only there. Getting it on the client is the hard part.
Multiplayer is 5x more work than single player, imho
yeah but the problem here is that it is also working on the client
but it is not visible by server
Your statements are contradicting one another, which one is it?
both actually
Also you are shooting yourself in the foot trying to learn too many things at once. If you are just dabbling in UE you need time to absorb and learn the different concepts. Starting right away with a Multiplayer game is a bad idea
Your earlier problem statement was that it runs on the server but is not visible on the client, now you say it's not visible on the server but is also working on the client ?
Both are those are essentially the same class of problems. Make sure the object is created on the server, not on the client, that it replicates, that any data on it that needs to be replicate is also marked as such
And the way that is accomplished is that the function you are currently calling that creates the actor, needs to be gated behind an RPC that executes on the Server
@ivory palm An actor that is spawned on the server and set to replicate will also be spawned on the client. If not set to replicate, it'll exist on server only. An actor spawned clientside will only exist there.
Show your code
Whoah yeah don't do that. First problem is calling multiple run on server event
Just do 1
You mean the actor I spawn must be a pawn? Because I replace the GetPlayerCharacter by GetPlayerPawn
This is all sorts of spaghet and fucked up. Start small, just do
Input -> Run on server event
Server event -> spawn actor -> set ref/attach/whatever
You've got race conditions all over the place as-is
Get that working before adding the interface calls and whatever else you're doing.
Anyone has an idea on how to approach this complex problem?
I'm making a VR multiplayer game where the player has 2 hands and a full body. The full body can't be seen by the owning player, but can be seen by other plays. The hands can only be seen by the owning player and not by other players.
I want the hands to be able to collide with other player's full body IK, but not the player's OWN full body IK. I can't seem to find a way to make this happen + also make it replicate properly.
Some people recommended making a seperate collision channel, but I don't see how that would solve this problem?
TLDR: I need to find a way to not collide with own body, but be able to collide with other player's body with my physics based hands
Set own body hidden
The visual aspect is done. It's completely working
However, because the hands collide with its own body, it's super buggy
Doesn't hidden also hide collision?
It doesn't
Which is a good thing, otherwise my hidden hands wouldn't be able to do their job
- the problem with that situation is a discrepancy of how other players see you interact with physics
Ideally I'd have some function saying: Hands ignore own actor
And have that replicate over all characters
So every pair of hands will ignore their own full body
Move this to #legacy-physics
Alright will do!
Is there any ID for each actor that I can use to send a datas for multiple replicated actors from the server? I want to request player names from a client and assign them to the corresponding actor. I could do this by making each actors to send their names to the client one by one but that wouldn't be effective, so if there would be an ID I could send a map that would include IDs for each name, but I am not sure if there are even something like that already for them that I can use in BP.
There isn't, network GUID's are unique per-connection
The only actors you can "stably" refer to by name, are ones which are stably named, i.e. loaded from the map.
dynamically spawned actors are inherently not stably named, unless you have some bespoke deterministic spawning code for them.
Not really sure I understand the question though, tbf. If it's a replicated and is relevant to a given client, you just use a pointer to refer to it - the engine will resolve it to their instance of that actor.
What if I make a multicast function that has the actor references? Will the client know which one is that?
lol u just answered
So long as they are replicated actors spawned by the server and relevant at the time they receive the RPC, they will resolve yes
thanks
To avoid race conditions, support join-in-progress and relevancy etc. and the like, any stateful changes should be replicated properties
RPC's are for events rather than something that permanently alters the state of the game
What do you mean by player names, like the actual player name as in their steam name or Avatar name?
That should already be replicated
True, I can just make name variable to be replicated, so I don't have to deal with it manually.
What exactly are you trying to do, add names to a players units or something?
I don't use steam
My issue is already solved thanks
Can I get the unique net id of other than local player from somewhere or do I need to make a replicated variable for that?
Isn't the ID stored in the PlayerState, so it's already available
Indeed looks like it is, thanks
Very important caveat on this that is not obvious, the actors will need to have replicated before this will resolve properly, or by default the engine will resolve it to a nullptr. There is a config that changes the default behaviour to have the RPC be delayed until everything is replicated properly.
This can for example happen if you spawn an actor on the server, and have it instantly run AI code that does things before the actor is fully replicated to all clients
One more question. How would i add item to inventory? Currently i tried different ways of doing it, but im not sure if inventory gets replicated to clients. Maybe i should do something with ReplicateUsing metamodifier? I currently call Server RPC to add items to character, but on server it actually works, tho, it's not being replicated to client i guess. In PIE details i can see item being here, debugger shows the same, but when i open UI from client, my Inventory has no items at all, and inventory UI is empty. Component is set to replicate and if i add items though Edit Defaults Details page it actually replicate to all clients and server.
(If i do the same for the server player, it actually works right)
Ofc, i set component to replicate.
thank you for the clarification
Can anyone tell me if there is a particular reason that something would work inside the editor for both client and server but when ran through steam on two separate devices it only works for the server?
Question is still open, i have absolutely no idea why this happens, i tried everything i could even think of.
@viscid monolith keep your item stack upto date with the servers copy
via the OnRep
ReplicatedUsing=OnRep_ItemStacks or something?
this is why i don't use Instanced for repicated stuff
and it smells really bad what your doing
instanced indeed sucks with rep
Okay, then im removing Instanced
might not be the problem but ye π
And what exactly should i set for OnRep? Inventory component or Stacks in it?
I'm going to plug this while at the same time recommending against it, because for the vast majority of inventory systems you don't need discrete object instances.
https://jambax.co.uk/replicating-uobjects/
^
Okay, thanks, gonna look at it
server creates the new item right?
problem is you overrode NetNameStable
you need to handle that to return false
if server spawned the item
and thats.. tricky
Yes, server spawns item
i would keep this stuff seperate
Instanced for Pregiven stuff
then again urgh i hate that also
same π