#multiplayer

1 messages ยท Page 243 of 1

tawny parcel
#

player controllers are not replicated/created to all clients, so player A will have their controller but not player B's.

Player states are replicated (variables ect.) / given to everyone connected, so a replicated variable on player A's player state will be readable by player B

unkempt tiger
#

yes, however this doesn't answer why we need two actors

#

if I needed some replicated value that isn't seen by other players, I could always put it in the player state and set it to only replicate to the owner

tawny parcel
#

I def dont have the answer to why they do it - I just know how they are different. Personally I don't use player states at all really, so you can avoid them. Just remember to not expect player B to be able to read Player A's controller type thing

unkempt tiger
#

I understand

#

looking at the classes, it seems like the distinction stems from over-ooping programming practices

tawny parcel
#

yea it could just be an extra bucket so to speak to help organize code and give a general direction on how to set things up

unkempt tiger
#

it seems like they started with the controller because they needed to get connections and inputs working, but then they added the game framework and decided to add a game framework 'controller equivalent' class in an attempt to abstract the game layer from the.. 'engine' layer...?

#

anyways it feels like the consequences of that decision are a pretty big setback that just adds extra development drag when having to plan game systems

#

i think this single function just speaks to the mess that's created

flint scaffold
#

im on a development build

tawny parcel
flint scaffold
#

sorry i do not understand what you are asking

tawny parcel
tawny parcel
flint scaffold
#

oh you are asking if im running my game from a shortcut ? no i use the .project file

tawny parcel
normal viper
#

Is getting Player State > Get Owner (Player Controller), reliable way to look for target PlayerController in multiplayer?

lost inlet
#

relative to what?

daring gorge
#

is there a documentation // article about input buffers being implemented for multiplayer
do they have to be implemented in a certain manner or do we handle this locally?

dire cradle
#

That can mean different things in different contexts

daring gorge
# dire cradle Depends on what you mean by input buffers

i wanna save input , like when a player presses 1 and then 2 instantly to switch weapons, i wanna let one action be saved and qeue itself later.
same but for movement where if player wants to jump but right after a slide then save that input and do the action right after

dire cradle
#

You can do it either way depending on your game's needs

#

Having the buffer only on the server is easiest to implement and most reliable one, but latency will be noticable

#

But the best way is to probably have the buffer on both the clients and the server. The clients wouldn't wait for the server to do the action, and the server would just validate it.

#

You'd have to deal with interpolation on that one though, but it's worth it

odd iron
#

Hi friends,
I still have this question related to server Meshing ,
If I sync the player location and current server id to database ,
how i can make shards map render for all players ?

daring gorge
daring gorge
#

the movement code

dire cradle
#

Yeah it is

daring gorge
#

aight imma try this and see if i can make it work

dire cradle
#

Dont know any docs about it

daring gorge
#

okay, i was concerned since i wanted to implement curves into my movement, so each state feels gradual and i thought that + this might make latency a lot more visible or just break the movement

blazing bear
#

hello, I have a replicated array of bools, I have a problem where the client doesn't receive the correct value of all indices, so it's out of sync. I suspect this is due to arrays being replicated everytime one of its indices value is changed, and since I'm modifying the array of bools on a loop, I think it tries to replicate on every loop index...

#

is there a way to not replicate the array until it's fully modified after the for loop? I'm thinking of creating a temporary array, modify it, then assign it to the array so it becomes replicated once, but I wonder if there is already a built-in way to help the engine decide when exactly should it replicate?

dire cradle
#

I don't think changing the value of an element in the array triggers an update in the first place

#

Only if you modify the array, (adding or removing elements) it'd register a change to replicate

daring gorge
blazing bear
#

I've only tested it with an OnRep function, in an array of structs, if a struct member's value is modified, it'll replicate at least.

daring gorge
#

you could make a struct where you store a bool and a server index value, you can set the server index on server and use that as your index

blazing bear
daring gorge
#

use a buncha print strings to check?

#

if not then just do the struct thing where you use your own int packed in as the actual index

dire cradle
#

For regular arrays the order is maintained

daring gorge
#

oh then just use print strings and see whats the client returning and server doing

blazing bear
#

I'm right now trying a method, which is creating a temporary array, modify it on the loop, then assign it back to the array so it only replicates once

blazing bear
dire cradle
daring gorge
#

or someway to mark it dirty for replication

blazing bear
#

which is totally fine, it'll still replicate the server's version of the array so it's synced

#

I'll keep debugging this problem, I've been stuck on it for some time now

blazing bear
#

this is incredible, logging the array being modified shows that it's working as intended, but when I check the array on the client (client's world, not the server), it's out of sync.

#

if I force the array to be re-created on the OnRep function, then it's fine, it becomes synced, but I wanna know why is it out of sync in the first place..

#

what I notice is that, if the index [1] and [2] were true, and became false, then setting them back to true won't replicate it to the client, but the Index [3] will replicate because it hasn't been modified recently

blazing bear
#

Found the issue, the client modifying the array, before the server does so, causes the array to be out of sync, which is totally normal and expected, but when the server, shortly after, modifies it, the client doesn't receive the final replicated array from the server to become synced again, welp that's it.

latent heart
ruby lodge
#

Player state at index 0 should be the server/host for all players be it client or listen server, correct?

#

Because as far as the comment on the node, that's how it's supposed to be. I am kinda getting a different result however and can't wrap my head around why

#

I want to display the host in a lobby for all players and for the host itself, it works. For the first client joining, it's also displayed correctly, but from then on the players joining see themselves as the host

#

Although I just check if the player state is == player state at index 0

verbal ice
#

Easiest solution is to have a replicated bool on the player state

#

Host sets it to true for themselves

quasi tide
#

In theory, yes. In practice - don't rely on it. Those static getters have a way to get the actual one typically speaking. Such as getting the controller or getting the pawn or getting the player state. There is also the PlayerArray in the gamestate.

#

Also, what Cyn said (and what I'd do personally)

verbal ice
#

The only "guarantee" I know of is for player controllers (0 being you)

#

Since player states can be moved in and out of the active player array I doubt order is guaranteed

ruby lodge
ruby lodge
lament flax
#

You might want to check the pinned multiplayer compendium

#

(Cedric's and WizardCell ones)

ruby lodge
oak pond
#

when I playtest in the editor with 2 client windows, is there a way to quit/close one of them without it ending the whole session? need to test quit messages

verbal ice
oak pond
#

ah thanks, weird how that doesnt show up in the autocomplete

topaz crater
#

Does anyone know at what point on the CLIENT with Real/Emulated Network lag, it is save to access both PlayerController / Player State for a Given Possesed Character for the purposes of binding to UI Data,

OnPosessed by and OnRep_PlayerState both do not seem to be reliable candidates. or is one of these for the CLIENT supposed to be reliably safe to access both of these.

verbal ice
#

Check if they belong to you

gray blade
#

incase its not clear if the server dies and respawn, the code works fine. But when the client dies and respawns they come back still in the death animation/montage.

topaz crater
# verbal ice BeginPlay of these

Im pretty sure that runs BEFORE the other functions and isn't guaranteed to have a valid player state yet on client am i wrong?

meager heart
#

Hey I'm curious if anyone is experienced with overriding movement physics / inheriting the movement component with multiplayer

I'm running into an issue where it seems like the server-side client actor's input vector is 0 (that makes sense), but it's causing some logic in my movement to fire incorrectly on the server which is causing the client to rubber band a ton because it's auto-correcting to the server's wrong calcs

Is there some other value I can check on the server that would equate to input? I tried getting the acceleration direction but that seemed very error prone because acceleration does not always equal input

dire cradle
#

The server won't know client's inputs since they are local

meager heart
#

Yeah I guess actually I don't even know if I should be doing movement logic if I'm on the server, I'm not sure why this logic is firing on the server because I see at some point the logic in the native movement component diverges if not locally controlled

verbal ice
#

And you can wait for the PC to BeginPlay too

meager heart
#

Alright yeah thanks for the help, I think I just need to figure out the difference between what should be firing on the server vs the client, anything related to input could maybe be moved higher in the call stack as to not fire when the server updates movement

topaz crater
# verbal ice BeginPlay of your playerstate

Ill try this but:

Isn't it possible that the ON Begin Play runs but it hasn't Possesed or Replicated fully to the client or the controller isn't full initialized yet.?

I need three things, Player State Valid, PlayerController Valid and Character or Pawn Valid, is there anything that for CLIENTS is reliably a sync point for these classes?

dire cradle
#

You can just put a check loop

#

Check every frame if it's valid, if not wait a frame and check again, repeat until it's valid

#

Pretty much guarantees there won't be any timing related problems

meager heart
# topaz crater Ill try this but: Isn't it possible that the ON Begin Play runs but it hasn't ...

If you check how Lyra uses the IGameFrameworkInitStateInterface, it's essentially to solve this problem here. Because it's not reliable when it's safe to access certain things, essentially every 'important' component/actor implements this interface and when each of they load in they broadcast to all other components to check if they are ready yet, and at some point everything loads in and everything is ready

meager heart
#

I don't think I described that very well, to put it another way for any given actor/component that has dependencies on other things being initializied, you make those depenendies broadcast when they're initialized, and the actor/component that you care about basically subscribes to those updates and each time one comes in it checks if everything it needs is initialized yet, if not then it keeps waiting, but if so it can run its logic

topaz crater
#

Any classes you know as an entry point that utilize it?

meager heart
#

I'll also add that it might look complicated / like a lot of work at first glance, but you can copy paste most of the code lol and you realize where it's used outside of those classes is really infrequently just to broadcast those updates

#

Hm let me check

meager heart
#

If you search for IGameFrameworkInitStateInterface you'll see which classes implement it, and there's only a few functions that they implement

topaz crater
#

Alright will do thanks again.

remote tusk
#

Hey everyone, Do you guys think its worth using GASP character for my multiplayer game? Its already replicated in 5.5, but i cant be sure if its already ready for usage since its the first patch. Or i can also use ALS, but not sure if its replicated already.

thin stratus
dark parcel
#

That's my perspective on ALS as well.

#

End up rolling my own very bare bone animation bp.

dark parcel
# remote tusk Hey everyone, Do you guys think its worth using GASP character for my multiplaye...

FYI ALS community version already replicates what ever in it atm..

But saying oh this system is already replicate doesn't magically make anything you build on top of it replicated. Replication just mean a process of communication between different machine. So if you want to add anything on top, it will be your job to ensure that the data is send and received appropriately.

And that's kinda difficult imo, especially as beginner. You have more to gain doing it from the ground up and understand what information need to be send across network when it comes to animation.

nocturne quail
#

since default CMC is replicated, so when Client_ApplyGroundMovement is called by server the movement will be replicated back to server as well or it will just be limited to the targeted instigator client?

    void RequestMoveForward(const float Value);
    void HandleGroundMovement(const float Value);

    UFUNCTION(Server, Reliable, WithValidation)
    void ServerHandleGroundMovement(const float Value);
    void ServerHandleGroundMovement_Implementation(const float Value);
    bool ServerHandleGroundMovement_Validate(const float Value);

    UFUNCTION(Client, Reliable)
    void Client_ApplyGroundMovement(const float Value);

in short: will the character be moving on server and on client? --> because default CMC is replicated

tardy fossil
#

if you move a pawn thats using CMC outside of the CMC, most cases it will just rubberband back

thin stratus
#

Or on anything that calls every frame.

#

And if you use the CMC then you shouldn't run any additional RPCs for movement.

#

It should all go through the default ServerMove RPC

nocturne quail
thin stratus
#

Sure looks like a method called via Input. And Input is processed every frame

#

At least axis input. Simple pressed/released would only call "once" I guess

dark parcel
#

quick sanity check. AIController only exist on the server right?

#

want to throw away the authority check if not needed.

#

Sorry to interrupt the ongoing convo.

nocturne quail
thin stratus
#

And value is what? :D you are still not sharing where this is calling from

nocturne quail
remote tusk
#

Finally finished my inventory, now its time to replication. One thing really scares me to use add impulse on multiplayer. I drop my items from inventory with mouse, and add impulse. Would it be bad for multiplayer performance? We will only make it work when dropping item. But still it needs to have a physics. Maybe i can change its collision profile after 2 secs etc.

#

Can my items that is dropped simulate physics? Would it be a disaster? ๐Ÿ˜‚ Because I am really afraid of using phsyics in multiplayer, in some video, it was really not intuitive to use phyis.cs ๐Ÿ˜„

thin stratus
#

If you have that a root component with collision and then a mesh component as the child, you can set the mesh component as the InterpolatedComponent (function you call on the ProjectileMovementComponent on e.g. BeginPlay or Construction Script or similar in C++ of your Actor).

#

It can do a variety of physics-like things, like bounces.

#

It's not reaaaally Client Authoritive, (only the CMC really has Client prediction), but if you set the (Start)Velocity on Server and local Client you can get a relatively smooth result, especially if you set up that InterpolatedComponent.

#

You could of course use Physics if you really wanted, but there is no prediction AND no smoothing built into it.

#

So to sync it you'd blindly replicated Movement on the Actor, and that might cause a lot of rubberbanding on the Actor.

remote tusk
#

Hmmm. I like that suggestion actually! I can simply fake it. It doesnt really matter that much.

#

Maybe i should add i projectile movement component to tem when dropping, and simulate it.

thin stratus
#

There is also the option to split the item and the drop in terms of classes. The drop can reference the item and take parts of it, like the mesh. Doesn't need the whole item to be spawned. Then the drop actor can have the component by default

tardy fossil
#

Physics replication is also quite bandwidth heavy

thin stratus
#

Cause what would "Physics Replication" even be? There is no button for that, despite enabling Physics and replicating the Actor and its Movement, potentially including the Component that simulates Physics (and that might be redundant if there is nothing replicating in it).
I don't think there is any builtin Physics data replication going on in UE, or?

tardy fossil
#

ah yea i guess it'd be more accurate to say the replicated movement of a simulated object is bandwidth heavy lol

prisma snow
#

Hiii! I am running into an issue when calling a Server RPC from a client. This function used to work properly, but when rewriting part of the UI of the game, I encapsulated the calling into a lambda:

UIData.OnLeftClick.AddLambda([ProductionComponent, ProducibleUnit]
{
    if (IsValid(ProducibleUnit) && IsValid(ProductionComponent))
    {
        AsyncTask(ENamedThreads::Type::GameThread, [ProductionComponent, ProducibleUnit]
        {
            ProductionComponent->AddToQueue(ProducibleUnit);
        });
    }
});

Initially I did not have the AsyncTask call, but I was getting an assertion about calling RPC from non-game thread, so I thought to wrap it in the AsyncTask to see if that helped (I didn't think Lambdas would get called from non-gamethread anyway).

Now I don't get the assertion anymore, but the client gets disconnected and I find this in the logs LogNetTraffic: Error: Received corrupted packet data with SequenceId: 2086 from client 127.0.0.1. Disconnecting, so I suspect that the AsyncTask wrapping is also not a good solution.

Probably I should just avoid calling the RPC from the Lambda, but I wanted to ask here and seek a bit of clarification ๐Ÿ™‚

nova wasp
prisma snow
nova wasp
#

lambdas do not magically change how rps work afaik... this is probably capturing something incorrectly

#

when in the frame is this called exactly?

#

can you show the callstacak of it without the async task?

prisma snow
#

The binding on the lambda happens on tick, and the execution comes from pressing a UMG button

#

let me check the callstack

#

Callstack for the binding

#

Callstack for the code inside the lambda just before the error)

nova wasp
#

I assume yes

#

I am actually not sure why it would complain here as this should just be inside of slate drawing

prisma snow
#

Yeah same

nova wasp
#

I would say for starters you should bindweaklambda with an owner pointer

#

also I have no idea if this capture makes sense

prisma snow
#

just in case something funky is going on

#

ok I'll try and let you know how it goes

open wave
#

doing my head in i have been trying to setup a dedicated server but i am unable to connect to it. I have done a source code build of ue5 and added the server and client builds the server loads and logs that it is running but it never shows up in the search box? anyone else have this what am i missing i opened up the 7777 UDC TCP on my firewall but im running server on the same pc anyways. if i create a server in game i can find it though

remote tusk
#

What might be the reason of my drag and drop is not working when 2 person exists, this only happens in server., client can drag and drop in UI. Server cant simply drag and drop, UI is not working for the Server, Client can drag and drop.
If I start 1 player stand alone, it all works fine.

#

On the left which is a client, i can simply drag from my inventory.
"Its not replicated btw." But it happens on multi side.

#

On right, i am unable to drag items.

#

which is occuring on the server.. Generally things bug out in te client side. ๐Ÿ˜„

#

Its not printing that event on the server. But in client.

#

Also checked for locally controlled, to create widgets, initilizce player etc. This is my UIComponent assigned in player controller.

#

If I start Number of Players as 1, it works fine on the server. But as soon as 2>, it stops working for the server, but it works in client.

#

How can i Debug this?

remote tusk
#

I think this is happenning because on the server, there is two UI opening at the same time, or client one.. IDK. Can it be opening the clients UI in his own screen?!

remote tusk
#

What I found is, When other client connects, It also spawns Widget in my server's screen. IDK why though. I already check for

#

is locally controlled

#

, Here in server, it logged 2 times

#

I solved it with that way, in UI Component class.. But still. MEH. I didnt like it, is this a good way of solving it, are there any checks?

remote tusk
#

So when I print BeginPlay in Player Controller, If it says SERVER, It's the guy who spawned in my Spawned Character right? So in client's my version, it will send the print as Client right?

#

So Server has all of the Player Controllers, for that reason, it logs 1 Client, and 2 server, when client connected to game. Client doesnt log 2 times client, because CLIENT has only ONE Player controller, and my CLIENT version in the client instance, is not printing.

#

I understood that part now. But why this logged as true in the server 2 TIMES?

quiet yarrow
#

use is server and is locally controlled targetting self inside pawn

#

Here is the relationship between the server and client

remote tusk
quiet yarrow
#

then the UI component is only seen by the server and the owner of that client

#

To be clear, the controller is only seen by the owner of that client and the server has a copy of that. So client 1 and client 2 know nothing about each others controllers

remote tusk
#

Yeah, but server has all of them right? Thats why everyime I player connected, server's Player controllers begin play works,which mean duplicated UI widgets in my case.

lost inlet
#

Your screenshot would be typical for 2 clients

remote tusk
#

But how to check to spawn on only owning client without RPC? Since the connected client is also Server in my instance, and controlled locally on his instance

lost inlet
#

There isn't a separate client for a listen server host

remote tusk
lost inlet
#

Yes, its own and the remote player

quiet yarrow
#

Server runs on each controller. Each player runs there own controller also

#

so 3 prints in your case

#

Not sure what you mean by duplicates tho. The server should be doing that unless you dont want the server to know about your UI component for some reason

lost inlet
#

You'd get 4 messages in dedicated server mode

remote tusk
#

In my case, If I check IsServer, and locally controlled, it will still spawn 2 widgets? Since when the client connected, it is the server in my instance, and is locally controlled? No its not.
Instead of checking IsServer, i was checking switch has authority.

#

Maybe that was the issue.

#

I thought IsServer and Has Authority would be same.

lost inlet
#

Not strictly true if a client spawns an actor on their client

remote tusk
#

If its not server, i would simply spawn widget, since clients have no other player controllers in their instance tright?

lost inlet
#

GetPlayerController(0) and GetPlayerCharacter(0) is almost always wrong in a networked game

remote tusk
#

Hmm, its time to check compendium again for Switch Authority & IsServer. I am not sure how to handle those stuffs in components. Since I call it in Even Begin Play in the component, it might not be possessed yet. But h ow to handle that in components, which events should on that we initialize?

quiet yarrow
#

If you use IsServer as blocking logic for the server for your UI component whatever you do or dont do would just happen on owning clients if thats what you want

remote tusk
quiet yarrow
#

Make it spawn on possess

#

If you want the UI to be local only just put IsServer before the event. both client 1 and 0 will run the code, but server will not add a "duplicate".

If its server do nothing.
If its not server do UI thing.

remote tusk
#

You are right.. Why i am even checking for server.
But then Server wouldnt have a UI, in the server Instance?

quiet yarrow
#

No the "listen client" would have the UI

#

the server just wouldnt double run the code

remote tusk
#

But my Server Instance would have UI?

quiet yarrow
#

Okay look. Server is not exactly tied to your listen client

remote tusk
#

What does that Player controller returns in the server instances? Since we have 2 Player in the server Instance,

quiet yarrow
#

you can skip a call from the server, but still have it run on your listen client

remote tusk
#

Hmm

quiet yarrow
#

dont do get player character

#

get controller

remote tusk
#

Sorry, i was supposed to do that.

#

Wrong screenshot.

#

So is the right Server Instance, is listen client?

quiet yarrow
#

So you know how we call a player that is the "host" of a game?

#

Thats still an client

#

but they have the server running on their machine too

#

So, you can exclude that server from running on specific code

#

that doesnt mean the code wont be ran

#

it just wont be ran on the server additionally for a total of 3 times

remote tusk
#

Hmm, What i didnt understand when I play in Listen Server, and check !IsServer, would it still return true? Since server is also a client?

quiet yarrow
#

It would be true and false I think

#

you would get two print screens right?

remote tusk
#

And thats whats confusing me.

#

My bad. I got another hello print. It printed only one, in the client, which is the second player.

#

But should I be spawning those UI in !IsServer check only?

#

Because I might be playing alone which i am the host, and it wont get spawn UI

#

Im almost there. I got understood all the stuffs in RPC, RepNotify, etc. And now trying to understand, what is what. and how to check conditions.

quiet yarrow
#

ah my mistake. Yes you will need to spawn on server as well

#

listen doesnt seem to act as a client and server at the same time

#

thought that was what you were having issues with

#

yeah so it shouldnt be running twice then. Show me your code

remote tusk
#

I will create smth. like this.

If It is server, and locally controlled, spawn Widget.
If it is not server, just spawn widget, on client. which is already doesnt have multiple instnace of player controller.

dire cradle
#

You can just check is locally controlled on everyone

#

it doesn't matter if it runs on the server or the client

remote tusk
#

So when player connects as a second player in my server instance, it wont log "Is Locally Controlled" right? But how do i check this in Begin Play, I dont think it would return right value.

#

Its my compoonent in player controller.

#

Get Player Controller -> Is Local Controller, is the way i check?

dire cradle
#

No wait

#

If you call get player controller it will always return the local controller

#

Unless you call get controller on a pawn

remote tusk
#

Its a UIManager component that inside of the Player Controller

quiet yarrow
#

is locally controlled is what you want to use to have it run locally only

#

I think thats all you want right?

remote tusk
dire cradle
remote tusk
#

Are there any better ways for components to get Player Character, like in Character's OnPossessed method.

dire cradle
#

In your component Get Owner -> Cast to player controller -> Is local controller

#

Assuming you have that component only on controllers

remote tusk
#

Yes, UI component is just a wrapper, to not hold all the UI stuffs in Player Controller.

#

Thanks guys. Its helpful. Now its time to learn IsServer vs. HasAuthority. difference.

#

Thank you guys. Its much more clear for me.

dire cradle
#

After you cast the owner to player controller you can save that reference, then you can simply call Get Controlled Pawn on it

remote tusk
#

And is Get Player Controller is fast look-up? It is searching or smth? I am afraid it would be smth. like FindObjects In Scene, and return.. which is expensivbe.

remote tusk
dire cradle
#

Check the pins

#

Yes

remote tusk
#

It gets the zero index for player controllers, which like you said its local one. But is it expensive to call that node?

dire cradle
#

The pinned messages, on this channel

#

It's not that it's expensive, but it's better to avoid using Get Player Controller (0) to get the local player whenever you can

#

It's not bad to use it, but it's not a good habit

#

I had to break that habit once

remote tusk
#

I want to do that before I get my hands dirty with them. I will check the pins and check for alternatives then!

dire cradle
#

The alternative is to treat it like any other actor, keep references to it when needed.

remote tusk
#

Hmm, so you mean locally. I got it.

dire cradle
#

For example in the player character you can call Get Controller instead of Get Player Controller (0)

remote tusk
#

Alright, now i should be more familiar with those checks like IsServer & Has Authority. I cant seem the difference though.

remote tusk
dire cradle
#

The problem with this is it locks you in to a certain structure. If you decide later to add split-screen for example, you'd need to refactor every single code that uses Get Player Controller (0)

#

If the game was singleplayer and you decide to add multiplayer later, it creates a problem as you'd once again need to go back and clean them up

#

But if you used the ownership chain to access the controller instead of Get Player Controller (0), you never have that problem

remote tusk
#

But that is if it is the dedicated server right* if changing to multiplayer.

#

Thats what i am doing for my interaction & inventory. ๐Ÿ˜„

#

In Listen Server, it would still return local.

dire cradle
#

You can still use it in multiplayer if you have no plans on adding split-screen. But where you use it matters

remote tusk
#

Thank you guys. โค๏ธ Now its time to create sessions. I already setup for Steam Sessions, can we still test with my friend from remote, can we use steam lobbies for testing purposes just by building and giving the build to my friend?

dire cradle
remote tusk
#

Why that might still logs 2 times? In Server and in Client, I see log 2 times.

#

I thought that would print only one, But as soon as the other client connects, it also prints Hello From Server.

dire cradle
#

Get Player Controller (0) will always return the local controller, so that branch always returns True

remote tusk
#

I think it still didnt click on me.

#

Ah, I see, so when the second client connects, in my Server Instance, it gets Player Controller which is local, and it still returns as is local.. Hmm.

#

God, I just want to spawn ONE UI in my server instance.

#

๐Ÿ˜„

dire cradle
remote tusk
thin stratus
remote tusk
#

Controller

thin stratus
#

So the screenshot above is in the PlayerController?

remote tusk
dire cradle
#

You can either call Get Owner == Get Player Controller (0)
or
Get Owner - Cast to Player Controller - Is Local Controller

thin stratus
#

Ah, so it's a Component on the PlayerController.

remote tusk
#

No it is the UI Component iside

thin stratus
#

Yeah then you'd do what Spynora wrote

remote tusk
#

I handle UI & widgets.

thin stratus
#

The second one

#

You one want UI per Player?

remote tusk
#

would it still return local?

remote tusk
#

Since it duplicates, I cant drag and drop.

thin stratus
#

Owner is the Actor the Component sits on.

remote tusk
thin stratus
#

If this is ListenServer + 1 Client

#

Then Client has 1 PlayerController instance, so one Component.

#

ListenServer ahs 2 PlayerController instances, so two Components.

#

One for its own PC

remote tusk
#

When we check Is Player Controller, it checks its local, but its already local for that server instance.

thin stratus
#

One for the Client's

remote tusk
#

But when we check our Owner, and check if its player controller, its not the local one.

thin stratus
#

So if you do GetOwner -> Cast -> IsLocal, on the LisnteServer it checks it once for the Server's and once for the Client's.
And on the Client it checks it once for the Client.

#

So you get:

  • Server
    • Server's PC -> IsLocalController: True
    • Client's PC -> IsLocalController: False
  • Client
    • Client's PC -> IsLocalController: True
remote tusk
#

Do I need IsServer check before that? OR its redundant now?

dire cradle
#

You don't need to check if it's a server or not

#

You only need to know if the controller is local

remote tusk
#

Alright, so we simply check if our Owner is the local, not the Player Controller in Get Player Controller.

thin stratus
#

IsServer would only be needed if you don't want the Client to have the UI.

#

Yeah cause, GetPlayerController0 returns the first entry in the LocalPlayer Array of the GameInstance in C++.

#

So this is always the ListenServer's PC on the Server.

dire cradle
remote tusk
#

But when checking for owner, its not the local one. IT says! Hey, you are the second one!

thin stratus
#

Well you basically pick the same PC for both checks

remote tusk
remote tusk
#

Thank you guys. It clicked for me.

#

Now i can see WHY Get Player Controller is such a headache if you dont know what you are doing.

dire cradle
#

That's exactly why you need to be careful on using it

remote tusk
#

I finally understood Print strings for multiplayer. For example, I print Hello in Player Controllers begin play. I can see my both instances send Hello like Server:Hello.
But how can i detect which one it was as it best? For example the second instance sent it. I log Controller display name but i cant really understand it

#

Is there anyway to understand who is exactly sending, For example Server's second instance. (which is the server version of the client pawn)

dire cradle
#

is local controller does that

#

if it's not the local controller it has to be the clien'ts controller running on the server

#

Clients only have their own controllers

#

Server has everyone's controllers

remote tusk
#

Revising it.

thin stratus
#

Hope that make sense.

remote tusk
#

I can see now why its bugged.

#

But what about Player Character now? Would I be getting it from player controller too? Hotbar and Inventory component is in my Character blueprint.

#

Would it be accessing right character

#

Is this same for Get Character, like in Get Player Controller.

dire cradle
#

Get Player Character is the same thing with Get Player Controller, but for characters

remote tusk
#

It would work, since we need the local character. WE already checked for owner local.

dire cradle
remote tusk
# dire cradle

Yes, thats what i will convert. But that would still work i think?

#

Since we already check local player controller, it will get the local character here and get values from there.

dire cradle
#

So you're still getting the Local Player Controller's pawn when you call Get Player Character

#

Not the one the component is in

remote tusk
#

Understood, but since its already returning local character, and we already checked for Get Owner's Is Local Controller, it would still get our right character. Because we already know its locally controlled now.

#

I am asking to understand it completely. ๐Ÿ˜„

dire cradle
#

Yeah true it would return the correct character

remote tusk
#

Because for the second client in our server instance, it wont get inside the if loop

#

Our main server instance will get in if loop, and get its own local character.

#

But as for best practise, i would do your way! โค๏ธ

#

Its better we just get it by chain.

#

Thanks. I can finally drag and drop my items.. Not duplicated hotbars and inventory.. ๐Ÿ˜„

#

For local components, ITs really great practice to know that. Thank you guys, this was really irritating topic for me.

#

Its much more clear.

dire cradle
# remote tusk For local components, ITs really great practice to know that. Thank you guys, th...

An overview of the essential concepts for writing multiplayer game code in Unreal, in under 25
minutes or your money back.

Sample project: https://github.com/awforsythe/Repsi/
Patreon: https://patreon.com/alexforsythe
Twitter: https://twitter.com/alexforsythe

00:00 - Introduction
01:24 - Net Mode
03:33 - Replication System Basics
05:13 - Acto...

โ–ถ Play video
brazen anvil
#

I want to add a left/right lean to my character for looking around walls. I want it to have multiple angles. So instead of just leaning and it going to a full 35 degrees, I want to have maybe 2 other positions in between. So for example, 0, 12, 24, and 35 degrees. My question is what would be the best way to handle limiting the rate at which this can be triggered? For example if they were leaning and rotating through all of these angles rapidly it would cause a lot of RPCs to be sent. Instead, should I set some sort of delay between the change? I was thinking once they lean, they wouldn't be able to change the lean angle until the lean was completed.

dire cradle
#

Watch this and it will make it much easier to understand

remote tusk
dire cradle
#

Instead of sending an rpc each time they lean at a specific angle you can just send the inputs and handle lean angles locally on both the clients and the server

brazen anvil
#

If the lean angle is changed it would need to be updated

dire cradle
#

How do players change the lean angle?

brazen anvil
#

keyboard

dire cradle
#

Yeah but like is it by holding the button? Pressing it multiple times?

brazen anvil
#

Not sure yet but I think it will be something like lean and while holding the lean button you would scroll or use the up or down arrows

dire cradle
#

You'd need to send a server rpc each time the player presses a button or uses their scroll wheel, there is no getting around that

#

For the angle you can use a rep notify variable with skip owner condition to update the lean angle to other players

brazen anvil
#

Yeah that should work

nocturne quail
#

in terms of optimizations which version is fine? A or B

A

MoveForwardKey(short int Value)
{
    RPC_RequestSimulateMovement(1, Value);
}

MoveRightKey(short int Value)
{
    RPC_RequestSimulateMovement(2, Value);
}

RPC_RequestSimulateMovement(const uint8 bDirection, const short int Value)
{
    const float VelocitySize = GetCharacterMovement()->Velocity.Size() + 10.0f; // Smoothness to movement since we don't use float for input Axis

    GetCharacterMovement()->MaxWalkSpeed = (VelocitySize <= MaxMovementSpeed) ? VelocitySize : MaxMovementSpeed;

    FVector Direction = FRotationMatrix(FRotator(0, PC->GetCustomControlRotation().Yaw, 0)).GetUnitAxis((bDirection == 1) ? EAxis::X : EAxis::Y);
    AddMovementInput(Direction, Value);
}

B

MoveForwardKey(short int Value)
{
    RPC_RequestSimulateForwardMovement(Value);
}

RPC_RequestSimulateForwardMovement(const short int Value)
{
    const float VelocitySize = GetCharacterMovement()->Velocity.Size() + 10.0f; // Smoothness to movement since we don't use float for input Axis

    GetCharacterMovement()->MaxWalkSpeed = (VelocitySize <= MaxMovementSpeed) ? VelocitySize : MaxMovementSpeed;

    AddMovementInput(FRotationMatrix(FRotator(0, PC->GetCustomControlRotation().Yaw, 0)).GetUnitAxis(EAxis::X), Value);
}

MoveRightKey(short int Value)
{
    RPC_RequestSimulateRightMovement(Value);
}

RPC_RequestSimulateRightMovement(const short int Value)
{
    const float VelocitySize = GetCharacterMovement()->Velocity.Size() + 10.0f; // Smoothness to movement since we don't use float for input Axis

    GetCharacterMovement()->MaxWalkSpeed = (VelocitySize <= MaxMovementSpeed) ? VelocitySize : MaxMovementSpeed;

    AddMovementInput(FRotationMatrix(FRotator(0, PC->GetCustomControlRotation().Yaw, 0)).GetUnitAxis(EAxis::Y), Value);
}
dire cradle
#

I don't think making a new function for each direction is very clean

#

You can probably get away with using a negative value for left and a positive for right instead

#

No need to use a new variable to decide direction

#

Wait nvm i misread the entirity of this

#

Tbh there is only 1 byte difference between A and B

#

I don't think that's worth duplicating code

#

If you absolutely need those bytes consider using int8 instead of short int

nocturne quail
dire cradle
#

Why not send inputs only when they change?

#

The movement code can still run on tick

#

You don't have to worry about a simple bool check (You can have hundreds of those every frame with no real impact)

#

That way you're not spamming RPCs every tick

nocturne quail
dire cradle
#

You can store the last input

#

then compare the new input value, if it has changed send the rpc

#

when it changes set the last input to current input

nocturne quail
dire cradle
#

It doesn't have to be replicated

#

You can check locally if your input changed or not

nocturne quail
#

that's the point, its all server authorotative... nothing is accessible from local clent unless server don't set it for them

dire cradle
#

The local player will always have access to their own inputs

#

You can't make that server authorititive

#

They are inputting on their own pc lol

nocturne quail
#

their local val not possible to use for mov inputs

dire cradle
#

Yes, I don't think you understood what I was suggesting

nocturne quail
dire cradle
#

Pseudo Code:

Vec2 LastInput = Vec2(0,0)

# Will run on Client
MoveForward(value){
  if(value == LastInput.x){return}
  RPC_MoveInput(1,value)
  LastInput.x = value
}

RPC_MoveInput(dir, value){
  if(dir == 1){
    LastInput.x = value
    return
  }
  LastInput.y = value
}

HandleMovement(){
  #move the player using LastInput values
  #will only run on server
}

Tick(){
  if(!isServer){return}
  HandleMovement()
}
#

Something like that

#

You could also bundle the forward and right values into a single variable first before sending them to the server, instead of sending forward and right individually

nocturne quail
full vapor
#

Hello. I have this widget in my game. The players can interact with is using the "Widget Interaction" component.

This widget is contained inside a blueprint actor who has a "SpawnIngredient" function. This function is bound to an event called from the widget when an item is pressed.

The problem is that I am not able to make this a server replicated function because the client who presses the button does not own the blueprint actor that the menu is created on.

How would I fix this?

queen mortar
#

Hello, any ideas on how to attach actor to an actor before client joins, so that the client would see it attached after joining?

nocturne quail
dire cradle
#

If not use a repnotify

queen mortar
nocturne quail
#

code

queen mortar
#

oh Im using blueprints

#

still the code?

nocturne quail
#

or post screen shot if code is small and can fit in an image

queen mortar
nocturne quail
#

you should have a bool, when you interact and attach an item set the repnotify bool to true

#

else set it to false when deattach

dire cradle
nocturne quail
queen mortar
nocturne quail
full vapor
dire cradle
#

@full vapor
For example, you could have a replicated actor component on the character for handling interactions.
The widget could send a message to this interaction component when you press a button, and would pass a value like an integer, representing the selected item.
The Interaction Component would then run a Server RPC with that value on itself.
The server would then pass the value to the target actor and it would spawn the ingredient as if it's the server that's interacting with the actor

#

That's only one way of doing it

nocturne quail
# queen mortar I dont know where to set the bool though. No matter where I set it, when client ...

it should work like:
InteractOnServer -> bAttached = true
then the repnotify function will be called
then you check:

if(bAttached)
{
  //here do your attachment
}
else
{
  //here do your detachment
}

every one will be notified for these changes, no matter current players or later joining players
this is just for listen server setup.
dedicated server setup will need you call the repnotify function manually right after when you change the bool.

full vapor
queen mortar
nocturne quail
queen mortar
#

Okay well thanks for clarification though

prisma snow
# prisma snow Hiii! I am running into an issue when calling a Server RPC from a client. This f...

So I've been doing some more research and testing into this issue, starting with removing the delegates/lambas from the equation to ensure that the actor component that was calling the function could do so, I also removed the parameters in case I was passing non net-addressable data - and I still keep getting disconnect from the player, so I think that the problem lies somewhere else.

I think that the most likely reason would be a missunderstanding (on my part) of server RPCs and connection ownership:

  • The component calling the server RPC is attached to an actor. This actor is owned by another actor (let's call it manager), who in turn is owned by the player controller. All these actors are spawned in the server, so authority is on the server.
  • If I call an RPC from the actor that owns the component, the RPC is dropped but client doesn't disconnect

However it is not clear for me, who "owns" this net connection - if the net connection is owned by the server, then according to the docs the RPC will be dropped.

fossil spoke
#

If you comment out the call to the RPC, does it still result in a drop out?

prisma snow
fossil spoke
#

I would breakpoint just before the RPC is called by the Client and verify that the Owner chain indeed does roll back to a PlayerController.

prisma snow
fossil spoke
#

If you dont, then you are probably falling into the last row of that table you posted.

prisma snow
prisma snow
fossil spoke
#

Not sure how it being an RTS changes anything really ๐Ÿคท

prisma snow
daring gorge
#
void AMyCharacter::MoveForward(float InAxis)
{
    AddMovementInput(RootComponent->GetForwardVector(), InAxis);
    TempMoveForward = InAxis;
}
ServerSyncRot(FRotator(GetControlRotation()), TempMoveRight, TempMoveForward, TempBoneOffset , TempLeanAlpha, TempTurn,TempLookup);
void AMyCharacter::ServerSyncRot_Implementation(FRotator InRot, float InRightAxis, float InForwardAxis, FRotator InTempBoneOffset, float InLeanAlpha, float InTurn, float InLookUp)
{
    UE_LOG(LogTemp, Warning, TEXT("ServerSyncRot Called! RightAxis: %f, ForwardAxis: %f, Turn: %f, LookUp: %f"),
        InRightAxis, InForwardAxis, InTurn, InLookUp);
    ServerSyncRotation = InRot;
    RightAxis = InRightAxis;
    ForwardAxis = InForwardAxis;
    CalcTurn();
    LeanBoneOffset = InTempBoneOffset;
    LeanAlpha = InLeanAlpha;
    if (IsDriver)
    {
        MouseTurn = InTurn;
        MouseUp = InLookUp;
    }

 }```
Guys im trynna replicate the axis values however for some reason the value doesnt seem to get replicated to the client.
am i doing something wrong here?
#

serversyncrot is called on event tick

trim onyx
#

What do you mean it doesn't replicate? Like the RPC doesn't reach the server or value is 0?

daring gorge
#

its honestly confusing me, the server keeps setting the value to the axis value then instantly sets it to 0?
as my logs read

LogTemp: Warning: ServerSyncRot Called! RightAxis: -1.000000, ForwardAxis: 0.000000, Turn: 0.000000, LookUp: 0.000000
LogTemp: Warning: ServerSyncRot Called! RightAxis: 0.000000, ForwardAxis: 0.000000, Turn: 0.000000, LookUp: 0.000000
LogBlueprintUserMessages: [Alpha_C_0] Client 1: 0.0```
however my client doesnt even get that fluctuation of -1. it just has 0 all the time
trim onyx
#

The value changing to 0 instantly could be because (if I remember correctly) the Axis events fire always even when the InAxis value is 0. So that could override your data.

daring gorge
#

so if i keep my axis held shouldnt it set to the value im holding at?

#

previously i used to call the server event in the MoveForward() but then i thought why call so many individual RPCs and try to reduce those to 1.
it worked fine if icalled the server event in MoveForward but not when i shift it to event tick

trim onyx
daring gorge
trim onyx
daring gorge
#

ye

#

and the log is in the cpp

#
LogTemp: Warning: ServerSyncRot Called! RightAxis: 0.000000, ForwardAxis: 0.000000, Turn: 0.000000, LookUp: 0.000000
LogBlueprintUserMessages: [Alpha_C_0] Client 1: 0.0
LogTemp: Warning: ServerSyncRot Called! RightAxis: 0.000000, ForwardAxis: 0.000000, Turn: 0.000000, LookUp: 0.000000
LogBlueprintUserMessages: [Alpha_C_0] Client 1: 0.0
LogTemp: Warning: ServerSyncRot Called! RightAxis: -1.000000, ForwardAxis: 0.000000, Turn: 0.000000, LookUp: 0.000000
LogTemp: Warning: ServerSyncRot Called! RightAxis: 0.000000, ForwardAxis: 0.000000, Turn: 0.000000, LookUp: 0.000000
LogBlueprintUserMessages: [Alpha_C_0] Client 1: 0.0
#

also weird pattern in log, sometimes it gets called twice

trim onyx
#

How ServerSync... declaration looks like?

daring gorge
#
        void ServerSyncRot(FRotator InRot, float InRightAxis, float InForwardAxis, FRotator InTempBoneOffset ,float InLeanAlpha, float InTurn, float InLookUp);```
trim onyx
#

maybe because the packets are unreliable server drops them?

#

Could you share tick function?

daring gorge
#

the event tick that calls this?

trim onyx
#

yup

daring gorge
#
void AMyCharacter::Tick(float DeltaTime)
{    
    Super::Tick(DeltaTime);
    ServerSyncRot(FRotator(GetControlRotation()), TempMoveRight, TempMoveForward, TempBoneOffset , TempLeanAlpha, TempTurn,TempLookup);
}
trim onyx
#

So I know what's with the double call, your ServerSync runs on client and server

daring gorge
#

is event tick client and server?

trim onyx
#

yes

#

almost all 'engine base functions' are called on both

daring gorge
#

then just HasAuthority() check right?

trim onyx
#

BeginPlayer, constructors, etc...

#

yup

#

but add !

daring gorge
trim onyx
#

because you want to call it on clients

daring gorge
#

yes im trying that

#

didnt fix it

#

even made it reliable

trim onyx
#

what would you get if you'd print the value of the input insted of calling rpc?

#

one input is enough, need to make sure the values are actully different from 0 on client

daring gorge
#

so print value on the axis event?

trim onyx
#

maybe in the tick and axis to be sure

daring gorge
#

oh okay let me try

trim onyx
#

Btw you may want to take a look at this:
https://dev.epicgames.com/documentation/en-us/unreal-engine/understanding-networked-movement-in-the-character-movement-component-for-unreal-engine
Somewhere in there should be described how CharacterMovementComponent replicates movement, it's similar enough to your idea so should help you.

Epic Games Developer

Detailed explanation of how the Character Movement Component handles networked movement

daring gorge
#

LogTemp: Warning: Event Tick ForwardAxis: 1.000000
LogTemp: Warning: Event Tick ForwardAxis: 0.000000
LogTemp: Warning: ForwardAxis: 1.000000

#

its setting itself to 0 again for some reason

trim onyx
#

ouf, that HasAuthority shouldn't have !

#

mb

daring gorge
#

but im printin it normally for now. let me just add that in

#

you mean like this?

trim onyx
#

nevermind I'm wrong crying

#

need the call from client to server so !HasAuthority() is the way

daring gorge
#

yheah cus server wouldnt know about temp vars

#

is it cause im not setting the temp var to be a UProperty?

#

shouldnt be imo but idek now

trim onyx
#

nah that shouldn't be the problem

daring gorge
#

LogTemp: Warning: Event Tick ForwardAxis: -1.000000
LogTemp: Warning: ForwardAxis: -1.000000

#

this is right

#

on !hasauthority

trim onyx
#

so now the client has correct values all the time?

daring gorge
#

the temp var which i was parsing in was correct all along

#

so i need to figure out the desync

trim onyx
#

Just to make sure, if you hold the input for like 5 seconds the server will start receiving only correct input?

daring gorge
#

let me try that

trim onyx
#

because you need to remember that RPCs are not guaranteed to reach in the same order they were send

daring gorge
#

weird, server prints 0 and so does client

#

in BPs

#

oh i dont think its calling the func

#

it randomly stopped calling the function

#

i think ill rebuild my project first haha

trim onyx
#

did you uncomment it in tick?

daring gorge
#

yeah honestly i have a feeling its my engine

#

this is what it runs like

trim onyx
#

your character is rubber banding?

daring gorge
#

sometimes my entire replication thing breaks and that rubberbanding happens then i rebuild and it fixes, it wasnt rubberbanding right now but i dont know whats wrong so might aswell rebuild to see

trim onyx
#

Do you use hot reload?

daring gorge
#

the compile button at the top

#

without live coding

#

thats hot reload right?

trim onyx
#

yeah, Hot reload is old name xd

#

but you do close the editor when compiling?

daring gorge
#

nope

#

i just keep it open and compile

trim onyx
#

better not to do that

daring gorge
trim onyx
#

If you're not using live coding that means your editor doesn't refresh after changes you make

daring gorge
#

yeah so the rebuilding didnt fix it

trim onyx
#

you did close the editor when rebuilding right?

daring gorge
#

yes yes

#

i closed it, deleted dervied data cache, generated new sln files and rebuilt

#

i think ill try the very same code in BPs and see quickly

trim onyx
daring gorge
#

thanks for the time by the way. i appreciate it.

trim onyx
#

if you figure this out you can share what was not working.

daring gorge
#

i will, i might have to hit the hay now since 0 sleep and its 8 am haha
but i gotta submit this project in college soon so ill figure and share

#

@trim onyx it works when i hook it to the actual axis event but not to event tick

#

and the same thing of making a temp value wont work

#

it has to go out from the actual axis event

trim onyx
#

hmm, I'll have to test this on my own. I'm curious why tick doesn't work.

dark parcel
#

You get your input from your enhanced input, what on tick do you even pass

#

It will just be 0

daring gorge
#

its the old input system not the enhanced input

#

im using 4.26

dark parcel
#

Regardless you need to pass the input values

#

Check the value before you think about rpc

daring gorge
#

we did, we checked the values on the tick too the ones before passing, it weirds out after the RPC

#

i just remade the same thing in BPs, it doesnt go as a seperate var, i have to connect it to the actual axis event

#

this worked.

dark edge
#

just tick -> if locally controlled -> send whatever you want to server

#

and it should be unreliable

daring gorge
#

yeah i tried that, it didnt work. let me try again

dark edge
#

What are you actually trying to do here?

daring gorge
#

replicate the input axis

dark edge
#

From where to where

daring gorge
#

i have vehicles and i dont possess them so i wanna take the input axis and then use those to control these vehicles

#

taking the clients input and replicating the float

dark edge
#

Tick -> locally controlled? -> yes -> send value to server
Get value -> set replicated value

daring gorge
#

the print string right after prints 0

dark edge
#

show the rest of it

#

and dont' make it reliable

dark edge
daring gorge
#

the player character, making it unreliable and showing

#

thats all there is to it, making it unreliable in cpp and building

dark edge
#

You can just get inputaxis Forward, no need for the axis value 0 variable

dark edge
daring gorge
dark edge
#

yes, where that call goes, the event

#

Where is the event for this

daring gorge
#

thats a cpp function that i sent above all it does is set the value to the rep variable, everything after is just a timeline that runs for the lean

dark edge
#

and you're sure it works?

dark edge
#

why do you have a timeline on tick

#

this is a mess

daring gorge
#

uh its for a lean function

dark edge
#

why is it on tick though

#

You presumably want to play it when you lean, unless you're trying to lean 60x per second

#

the fact that it might "work" here is just lucky, a timeline does not belong here.

#

Anyway, have you debugged? Where does the chain break down if it's not working?

daring gorge
#

the chain doesnt breakdown, it all works fine but only when i directly plug it in an axis event or the owning client thing calling this event
also ill remove the timeline, didnt know but thanks

dark edge
#

Then either tick doesn't happen, or the branch isn't being taken

daring gorge
#

let me print something on true and check

dark edge
#

or the value is being overwritten somewhere else.

daring gorge
#

it works for one client but not the other

#

they both return true however client1 gets 0 and client2 gets the replicated var

quiet yarrow
#

afaik the issue stems from get control rotation. If you dont replicate that in some way the rot is always 0, 0, 0

#

not sure if you are using that tho

daring gorge
#

yeah but the forward axis im trying to pass in even as a var doesnt get replicated. and yeah im using that too

quiet yarrow
#

if you are using get control rotation and multiplying it by the forward axis or anything obv it would be 0

#

idk how you are using it tho

daring gorge
#

im not multiplying

trim onyx
#

It's me again, because I've found out that you're using ListenServer, here is what I think is happening:

  1. You insert input on ListenServer.
  2. The ListenServer tick runs, but because your RPC is sever only it is not send to the other Client. (Using NetMulticast should solve that, and that's too the reason why using client RPC makes it work)
  3. The logs run for both Client and ListenSever, so you're seeing confusing data. (Use UKismetSystemLibrary::PrintString it will show you where the logs come from)
daring gorge
#

so @quiet yarrow has the very same system for one var

#

and hes got a listen server

#

is locally controlled thing works for him but not for me

#

idk if thats got to do with engine version

dark parcel
#

@daring gorge what does is locally controlled do in your words?

#

Just making sure you used it correctly.

#

And i failed to see why do you even have to use is locally controlled.

#

Inputs are local.

#

Your computer won't know if I press e on my keyboard.

dark edge
dark parcel
#

Why do we need that check for sending input.

dark edge
#

because it's sending on tick and not on input event

dark parcel
#

Oh..

dark edge
#

tick happens on 3 machines but there's only good input on one of them

dark parcel
#

Make sense.

quiet yarrow
#

and the bad input will usually come last. so it overwrites the good data

open wave
#

I have created a dedicated server and my search isnt finding it but when i direct connect to it. i can connect straight away. why cant my find sessions wont pick it up

thin stratus
ruby parrot
#

how would you update your UI on a replicated value change?
I know of RepNotify and binding from the UI Widget to the variable.

is one better than the other? Is there another way I dont know of?

e.g. I have a AC_Health with Health on it and now i do Server_GetDamaged(20) and now Health is changed from 100 to 80. Now the server knows(if only replicated) that it is 80, replicates it down to the client to 80 to, but obviously the UI has no not updated yet?

whats best practice here?

dire cradle
#

The widget would bind to that delegate and update whenever the health value changes

ruby parrot
dire cradle
#

Yes why not

chrome bay
ruby parrot
#

haha sry wasnt a "why not" question,more of a whats best practice ๐Ÿ™‚

chrome bay
#

People go too hard in the paint with "event driven" UI and they don't need to

chrome bay
#

I'm not joking btw

dire cradle
#

There isn't a set in stone way, it's mostly up to preference

#

To be honest on my personal projects I just bind the value directly and not care if it's ticking or not
But if you're concerned about the best practice you can make it event driven

chrome bay
#

There is zero benefit to doing that from an event and in some cases it could cost you more. If that widget is off-screen, you're still updating it and invalidating layout. Ticking the UI and updating simple properties that way means that it only updates if it's on screen (ticking != bindings btw)

dire cradle
#

binding still ticks

ruby parrot
#

ye but tick doesnt tick if it aint "active" i think thats what he means

chrome bay
#

bindings can potentially invalidate more than they need to. Literally anything is better than a binding usually, but bindings are ofc very convenient

ruby parrot
#

e.g. you could tick a widget that shows your health that is turned on/off like a "player stats screen"

chrome bay
#

A widget will tick only if it's painted and not culled, tick is really just "OnPainted" tbh..

#

But obvs there are layout considerations to make as well, since tick is post layout, so it really depends what you're doing

ruby parrot
#

ye, given that it is a healthbar +its value(current +max) ill go with the rep notify and delegate ๐Ÿ™‚ thanks for your help though โค๏ธ

#

Is there a way to RepNotify 2 different variables to the same RepNotify function?

e.g. i wanna be lazy and do RepNotifyHealth either time CurrentHealth and MaximumHealth has changed?

dire cradle
#

you can make both repnotify functions call another function like HealthUpdate or something

ruby parrot
#

yeah,i know that, but i want them both to call the same RepNotify"initial" function ๐Ÿ˜„ if it doesnt work,ill do your way... ๐Ÿ˜„

#

i wanted to avoid this: both literally being the same just for 2 variables

#

I hoped there was a way to :
HealthCurrent ->On_RepHealh
HealthMaximum->On_RepHealth

dire cradle
#

repnotifies are tied to the variables so no you cant make them call the same function

#

but can call a shared function instead like that

ruby parrot
#

aight np, was just outa lazyness and curiosity...this way works,so imma use it ๐Ÿ™‚

upbeat basin
#

I'm curious what happens if this is made in cpp though ๐Ÿค” can we legally give the same function to different ReplicatedUsing specifiers?

ruby parrot
#

ye in c# it would be "Getter and Setter" there you can just specify whatever function u wanna have called. but i got no clue about c++...havent looked into it yet, still getting the basics of MP in UE down first ๐Ÿ˜„

upbeat basin
#

Well OnRep/RepNotify functions and c# properties are kind of different concepts though

dire cradle
upbeat basin
#

I couldn't trust to use it even if it seems to work properly

#

UE gave me so many trust issues

dire cradle
#

yeah, I dont think they ever intended it to be used with multiple variables

#

A shared function works just fine lol

exotic wasp
chrome bay
#

Probably makes more sense to just pack them into a struct though

upbeat basin
#

That's neat

prisma snow
lament cloak
#

Is it normal for the PlayerState->GetUniqueId().GetUniqueNetId() to be nullptr on the client (several seconds after launching PIE)? I'm using the Redpoint EOS subsystem. This is in the editor, haven't confirmed in packaged build yet

#

Using the Dev Auth Tool

#

FIGURED IT OUT

#

I had to hit "Login before play in editor"

unique forge
#

On the Big screen as you can see, The Player 1 flshlight is flashing up to the ceiling, but on player 2, he sees player 1 flashes on the wall.

dire cradle
#

Control rotation is local

#

Use an rpc to send the pitch to the server, which then can be replicated to everyone else with a replicated variable

#

Yaw is already handled by rotating the character

unique forge
#

okay

#

so i need to create a variable

dire cradle
#

yeah

unique forge
#

do i have to delete them all?

dire cradle
#

No not at all

unique forge
#

the pic that i show

#

so just do nothing

#

on that bp

dire cradle
unique forge
#

im kinda new into this, i just watched a yt tutorial about it, and theres only 1 vid of them

unique forge
dire cradle
#

If you're new to multiplayer then watch this

#

An overview of the essential concepts for writing multiplayer game code in Unreal, in under 25
minutes or your money back.

Sample project: https://github.com/awforsythe/Repsi/
Patreon: https://patreon.com/alexforsythe
Twitter: https://twitter.com/alexforsythe

00:00 - Introduction
01:24 - Net Mode
03:33 - Replication System Basics
05:13 - Acto...

โ–ถ Play video
#

Replication logic might get confusing when you're new to it

unique forge
#

what about repnotify?

dire cradle
#

You don't need repnotify for replicating the pitch angle as it's going to update the rotation every tick anyway

#

You can also interpolate the rotation instead of setting it directly, that way the flashlight won't look choppy to others when you look around even if there is high ping & packet loss

summer tide
#

WHen I join a session it fails. how can i debug this?

dire cradle
#

usually the logs tell you why

#

check both the clien'ts and the server's logs

dark edge
dire cradle
#

Does it replicate?

quasi tide
#

Yes

dire cradle
#

i didnt even know it existed lol

#

you learn everyday

summer tide
#
[2025.03.10-20.08.32:306][290]LogBlueprintUserMessages: [GameInstanceinfo_C_0] GI: JoinSession Failure```
#

Could it be the cause

dire cradle
#

Yes

#

make sure theyre the same value

summer tide
#

SO I'm using lobby. DO I disable UsePesence

remote tusk
#

Hey guys, can we test our game with a friend that has the project already for multiplayer? I setup Steam & Advanced Steam sessions.

#

Seems like I cant see my friends session.

#

Or would it work, if my friend also "package" the game himself? And I do? I dont want to build and and upload to my friend as everytime. My friend has the project already.

summer tide
# dire cradle Yes

How do you check that during joining a session? I don't see a way to extract that info from blueprint session result struct

whole forge
#

I have what I think is a dumb question: I have an android game that I want to connect to a dedicated server running on my windows machine. I've been told that this is possible and that I need to package as a windows server and as an android client, and the two should be able to connect. Is that actually the case? I'm running over LAN if that matters

nocturne quail
#

why should the rotation applying part in my code not working? ๐Ÿ˜‚
it's already an hour i can't figure it out!

void ASurvivalCharacter::RequestFlyForward(const float Value)
{
    HandleFlyingMovement(1, Value);
}

void ASurvivalCharacter::RequestFlyRight(const float Value)
{
    HandleFlyingMovement(0, Value);
}

void ASurvivalCharacter::HandleFlyingMovement(const uint8 bForward, const float Value)
{
    if (!HasAuthority())
    {
        ServerHandleFlyingMovement(bForward, Value);
    }
}

void ASurvivalCharacter::ServerHandleFlyingMovement_Implementation(const uint8 bForward, const float Value)
{
    Multicast_HandleFlyingMovement(bForward, Value);
}

void ASurvivalCharacter::Multicast_HandleFlyingMovement_Implementation(const uint8 bForward, const float Value)
{
    if (bForward)
    {
        if(!HasAuthority()){
        AddMovementInput(GetActorForwardVector(), Value);
        }
    }
    else
    {
        if(!HasAuthority()){
        AddMovementInput(GetActorRightVector(), Value);
        }
        
        if (Value < 0.0f)
        {
            const FRotator ActorRotation = GetActorRotation();
            if (!(ActorRoll < -20.0f))
            {
                ActorRoll = ActorRotation.Roll;
                SetActorRotation(FRotator(ActorRotation.Pitch, ActorRotation.Yaw, ActorRoll - 1));
            }
            SetActorRotation(FRotator(ActorRotation.Pitch, ActorRotation.Yaw - 1, ActorRotation.Roll));
        }
        else if(Value > 0.0f)
        {
            const FRotator ActorRotation = GetActorRotation();
            if (!(ActorRoll > 20.0f))
            {
                ActorRoll = ActorRotation.Roll;
                SetActorRotation(FRotator(ActorRotation.Pitch, ActorRotation.Yaw, ActorRoll + 1));
            }
            SetActorRotation(FRotator(ActorRotation.Pitch, ActorRotation.Yaw + 1, ActorRotation.Roll));
        }
    }
}
whole forge
#

Did you ever solve this? I'm running into the same problem ๐Ÿ˜”

nocturne quail
# nocturne quail why should the rotation applying part in my code not working? ๐Ÿ˜‚ it's already a...

guessing i catched that bug: basically applying the old ActorRotation.Roll so the changes seems unseen ๐Ÿ˜„
this new version should work, testing it now

if (Value < 0.0f)
{
    const FRotator ActorRotation = GetActorRotation();
    if (!(ActorRoll < -20.0f))
    {
        ActorRoll = ActorRotation.Roll - 1;
    }
    SetActorRotation(FRotator(ActorRotation.Pitch, ActorRotation.Yaw - 1, ActorRoll));
}
else if(Value > 0.0f)
{
    const FRotator ActorRotation = GetActorRotation();
    if (!(ActorRoll > 20.0f))
    {
        ActorRoll = ActorRotation.Roll + 1;
    }
    SetActorRotation(FRotator(ActorRotation.Pitch, ActorRotation.Yaw + 1, ActorRoll));
}
remote tusk
nocturne quail
#

but if you change assets in content folder like adding new animations, mesh etc then yes you need to rebuild the whole and reshare

rare wharf
#

hi, making a truck kinda loading sequence to a game and i want the truck to drive off but when i interp the movement to the clinets from the server it's really choppy and I feel like it's not the best way to turn net update frequency up rly high to interp smooth, is there a better way?

rare wharf
#

yeah there's no gameplay purpose

fossil spoke
#

As in, like a Cinematic sequence?

rare wharf
#

yes

fossil spoke
#

Then just do it on the Client locally.

#

No need for the Server to do it.

rare wharf
#

wont they be out of sync? should i be making sure they are synced or does it just not matter?

fossil spoke
#

Is the Truck drivable by the Player?

fossil spoke
#

Then as long as the "start" of the sequence is in sync, the rest of it should be fine.

fossil spoke
#

They are just passively viewing the sequence?

rare wharf
#

yeah passive observer

#

cant walk just look around

fossil spoke
#

Yeah then just do it locally

#

You can sync the start and end.

rare wharf
#

thank you :)

fossil spoke
#

Im guessing you are using BP?

rare wharf
#

yes

#

i am new to multiplayer

fossil spoke
#

You will be pretty limited in the types of solutions you can utilize then.

#

Multiplayer in BP only is not ideal.

#

But while you are learning it should be fine.

#

If you are serious about learning to develop Multiplayer games, you will want to eventually learn C++

#

Get your feet in BP first though ,you can certainly learn a lot of the basics in BP only.

peak lintel
#

What could this warning be? 'ue5 LogNetPlayerMovement: Warning: ServerMove: TimeStamp expired:' when I'm moving with 2 clients.
Suddenly is like I have 200 ping. It's not a stuttering, because even the environment is starting to 'stop moving',
If I play with 1 client/or standalone everything works smooth.

nocturne quail
peak lintel
#

What dcmc means?
I'm using character movement. I didn't made any server movements/predictions

peak lintel
#

I've seen that and as I understood, the server is behind with the prediction/or client?
But, it's not the movement. Everything. Even the ui (damage indicator is not moving anymore) and I think this is why it's throwing the server move warning.
I've tested an older backup and it's working perfect.

This, current project, I made it yesterday, after I migrated from an older project to clean it up.

#

And it's going to 3 fps when this is happening

nocturne quail
peak lintel
#

I've also tested with built client version and server. The same.

#

And, just saw now. It's also throwing a warning with 'Video Memory has been exhausted'.

open wave
unique forge
#

Are sublevels automatically like for multiplayer too?

vapid gazelle
#

Not solving any specific problem, but I'm curious why first person shooters don't use a GGPO style network model for games with small player counts. Is there something about a UT-style FPS that makes GGPO a no go?

Quoting from Glenn Fiedler's great article:

GGPO style deterministic lockstep

All the benefits of deterministic lockstep without the lag. Each client frame process frames with inputs from the relay server up to most recent server time. Then, copy the game state (fork it) and simulate the copy forward with local inputs to present (predicted) client time. Continue predicting the fork until the next update arrives from the network, then discard the predicted fork, rinse and repeat.

When to consider:

You are making a fighting game.

When to exclude:

Don't use for physics heavy games because they are CPU bound, although as a con for this advice, Little Big Planet was networked using something similar to this approach, but one of their team members was the author of the physics engine!

Pros:

Can predict ahead using local inputs to hide lag.
All the benefits of deterministic lockstep.

Cons:

It can be difficult to make sure your game code keeps track of visual effects and sounds considering all the rollback that is going on.
In practice some amount of input delay needs to be used (eg. 2-3 frames @ 60HZ), otherwise rollbacks can be very disruptive to players.
If the game is CPU bound, you can get into a spiral of death where the simulation can't keep up with all the invisible resimulations.
Only suitable for games with low player counts. I would recommend 4-8 being maximum but perhaps it can be pushed up to 32.

https://mas-bandwidth.com/choosing-the-right-network-model-for-your-multiplayer-game/

mild sonnet
#

Can anyone confirm if a FNetworkGUID, specifically the FNetworkGUID.ObjectID, is the same for a given replicated object on every client? Since FNetworkGUID can't be a UProperty I'd like to pass around the ObjectID int64 knowing it will refer to the corresponding UObject.

rich geyser
rich geyser
nova wasp
#

if rollbacks happen a lot from interaction from other players it would basically shake your view around for example

#

but yeah the CMC is basically a tiny mini rollbacking game sim

#

it predicts input +state and sends a combination of input + some raw state to the server

#

and if the client is too far off they get bonked to rubberband back into place

#

it isn't one single holy chain of inputs as it includes state as well but its very similar

#

and yeah imagine input delay in an fps game lol

#

I am trying something similar but for view rotation 3 16ms frames of input delay seems insanely bad

#

so I always let clients change view rotation to whatever

thin stratus
rich dune
#

Hey, is there an opposite to Event Network Error. Like Event Connection Established to know if for example if the user is online again?

quiet yarrow
#

what's a cheap way to get closest player to an actor?

#

unreal engine expert AI is telling me to:
Get All Player Characters

Use Get All Actors of Class with Character or Pawn as the class.

Loop Through Players & Check Distance

Iterate through the players and find the one with the smallest distance.

Does that sound reasonable? or is there obvious better solutions?

#

also imagine this at scale. I will have hundreds of these. Perhaps all checking at the same time in rare cases.

dark parcel
#

expert AI? lol?

quiet yarrow
#

chatgpt guy lol

dark parcel
#

do you need to check for actors that are miles away

#

if not just do a sphere overlap and iterate over the overlapped actors.

quiet yarrow
#

imagine this. I have a stack of hundred balls. My character drives through the pile. On wake events fires for each ball: I want to check the closest player (usually just will be the player who woke them) to those balls then do an event

pale hazel
#

If your player-count wont change during runtime you can store references to the players so you dont have to query them everytime

then just check for the squared distance and compare them I guess

dark parcel
#

You probably want to register the ball to a manager so you don't have all hundreds of balls ticking

#

also does the ball really need to know players that are far away?

#

you can cull based on that data already

quiet yarrow
#

no probably not

#

also ball manager sounds good. Just havnt even tried managers yet. They sound intimidating lol

pale hazel
#

you just have a manager class that references all the balls and while it's ticking handles all their logic, instead of having all hundred balls ticking on their own

quiet yarrow
#

I need an example of what a manger can do, bcus I always here people say manager but Idk how it behaves and interacts with my actors

dark parcel
#

Actor tick can accumualte and butcher performance

#

instead all hundreds of balls ticking

quiet yarrow
dark parcel
#

you pass all the ball references to an actor

quiet yarrow
#

however I dont use tick on them for that very reason lol

dark parcel
#

and that actor alone can tick and loop through all the balls.

quiet yarrow
#

but its good to know I can

dark parcel
#

So you end up with 1 tick instead of 100 ticks

quiet yarrow
#

1 tick to rule them all type

dark parcel
#

you can also slice

#

so instead of doing everything in one loop when there are too many balls, you can slice it to multiple frames.

quiet yarrow
#

smart

#

especially when doing loops in bp

dark parcel
#

large loops in bp is performance killer.

#

just do it in cpp, for some casses the difference can be 100X or more

quiet yarrow
#

I had a loop for all trees

#

it turned into a hitch each time I chopped a tree down lol

dark parcel
#

looping over large data in bp is kinda gross imo.

quiet yarrow
#

for sure

#

I will likely move over the heavy parts as I get closer to shipping

#

but im kinda poo poo at cpp

#

anyways thanks for the ideas guys. im gonna get some sleep

#

cheers

pale hazel
#

I have a concept question:
How would you go about carrying replicatable data across multiple levels, data that is NOT tied to a specific player but rather to the general state of the game? E.G. some sort of overall score, collected items, defeated bosses, something along those lines.

The natural answer would be the GameState, right? Since it's replicated and every player has access to it, but the issue is that the GameState is not carried over between level changes.

The other possibility would be the GameInstance, but the GameInstance is not replicated, and I need the clients to be able to access that data.

So I guess my approach would be to keep the data in the GameInstance, and have the GameState react to changes in the data and copy those values over to itself, so it can then be replicated down to the clients who can use the data.

Is this a good approach? Are there obvious other solutions to this problem that I'm not seeing? This feels like something that might already have a built-in unreal solution, if so please let me know.

prisma snow
dark parcel
#

Is there a treshold settings I can adjust to stop correction on client? Preferably I don't want correction if the delta is just a tiny bit.

open wave
thin stratus
#

SubsystemNULL has no Online Sessions.

#

LAN or direct IP connection is all you get.

pale hazel
pale hazel
prisma snow
prisma snow
pale hazel
#

Yeah I appreciate the help

queen escarp
#

Hi!, Adding mapping Context for a player need to happen serverside ?

chrome bay
#

noop

queen escarp
#

hmm

chrome bay
#

input management is all local

queen escarp
#

that really messes with my issue

#

ill have to investigate further then

unborn kettle
#

hi, any luck getting mover working with Iris in 5.5.3 release? Or any one else that might have figured out a way to get them working together

fossil veldt
#

if you swap to the chaos prediction liason then likely it will actually work on iris

thin stratus
#

Pretty sure we have Iris running with NPP and Mover. But nothing I can share of course ๐Ÿ™ƒ

unborn kettle
remote tusk
#

Are there any cool tutorials about doing timers for multiplayer, optimized way

nocturne quail
remote tusk
#

Can you explain the workflow? My friend has already the packaged build, and I changed some stuff in blueprint, then re-package (idk if its same with rebuild),
send send him the .KB exe

nocturne quail
#

c++ timers don't need any optimizations they are lite weight

FTimerHandle BombTimer;
GetWorldTimerManager().SetTimer(BombTimer, this, &AMyCharacter::ExecuteBomb, Delta, false);
nocturne quail
verbal ice
#

Uh no

#

If you modify Blueprints this will modify assets

#

Unless you only modify C++ files, you shouldn't ever only send the .exes

nocturne quail
#

codes in blueprints

verbal ice
#

That will still modify assets

nocturne quail
#

i can confirm, i did changed the code in the UI widget and just shared my new .exe with the friend and he got new updates and was everyting working fine

verbal ice
#

If you modify a Blueprint, you're modifying an asset which isn't packed in a .exe file

#

Whatever you did isn't this

nocturne quail
#

so it was a magic then ๐Ÿ˜„

verbal ice
#

@remote tusk If possible I would get the project on Steam so you'll only upload changes between builds

#

I have a Steam app for development I just use for whatever project I'm working on, for that reason

#

Otherwise, you'll be better off compressing the built game and sending it all that way

#

Less error prone

remote tusk
#

Yeah, After prototyping, i am going to do that actually

remote tusk
nocturne quail
#

only to code as said before

#

so you can share updated .exe as a patch with your friend

nocturne quail
remote tusk
verbal ice
#

you're modifying a .uasset

remote tusk
#

every frame

#

For blueprint, I did this.

nocturne quail
#

i think this is why it was working when i changed the code in widget in blueprints

nocturne quail
nocturne quail
#

you can't avoid it, you can just slow it down @remote tusk

nocturne quail
verbal ice
#

Unless you're in an older Unreal version

#

with blueprint nativization

#

might actually be what happened to you

thin stratus
remote tusk
#

So, I should share my whole game? ๐Ÿ˜ข

#

Trying to understand prints in blueprint, is this mean My client is also seeing timer replicated? Since he sees the log?

thin stratus
#

No.

#

Editor just prints in every window.

#

The word in front of it is the important thing

remote tusk
#

Hmmm, So it should have written "Client:" if client had those.

#

What DO I miss here? ITs my game state class. I check authorty and start timer, Maybe I should send Server RPC right?

#

I thought since the Countdown is replicated, it would automatically do that, but i still need to send server RPC and edit it, even if i am sure it started in Server right?

#

Since I check here the authority, I became sure its the server changing value, but we still need to send Server RPC?

#

So like that.

remote tusk
#

I have changed my Cooldown to RepNotify, and print string like this.
I thought Server is also calling RepNotify's response event, but it seems like only the client is calling

grand kestrel
#

Finally looking into this client authority stuff now

So to recap, the client is reverting it's location to the location sent by the server (which is it's own location in the past due to the given authority). From TickComponent() if ClientData->bUpdatePosition is true, it will enter ClientUpdatePositionAfterServerUpdate(). If I set ClientData->bUpdatePosition to false when we have client authority then nothing else updates either (compressed flags, move data, etc). I need to stop it using the received location while still doing everything else. The problem in a nutshell is that it isn't using the received location anywhere I can see.

ClientUpdatePositionAfterServerUpdate() iterates the ClientData->SavedMoves and calls MoveAutonomous(CurrentMove->TimeStamp, CurrentMove->DeltaTime, CurrentMove->GetCompressedFlags(), CurrentMove->Acceleration) on them. This is what reverts the location. If I comment out the call to MoveAutonomous() the location stops reverting.

The problem is, nothing actually reverts the location. Ever. Anywhere. ClientTimeStamp is not used at all. Nothing reverts the location before iterating.

Except something does, I just can't find it. I've gone over it in detail. I must be missing it.

I get the feeling that commenting out MoveAutonomous() isn't preventing it from reverting somewhere, it only applies the reversion, i.e. the actual reversion must occur elsewhere.

remote tusk
#

Found out Decrement / Increment is not changing for server or smth like that. I have used set notify, and it works both for them.

thin stratus
#

OnRep, in C++, is an actual "Hey this value replicated and changed (optionally even when not changing)."

#

In Blueprints this is more like a PropertyChanged notifier, but not so much tied to replication.

#

That's why it also calls for the Server. It calls for generally changing the property.

#

Now, one would think that this really calls for any change, but there are a lot of nodes that don't trigger it.

#

Decrement/Increment apparently don't. I'm also sure a lot of Array functions that modify the array won't cause it to call.

#

At least not on the Server.

#

The only thing that usually always calls is if you use the "SET w/ Notify" nodes.

karmic trellis
#

helloo, I have a question about bServerAcceptClientAuthoritativePosition, If I enable this on CharacterMovement -forListenServer coop example- will it effect itself or I need to make some special things to do with it? All project has base project multiplayer movement.

thin stratus
#

ListenServer is a special case. It doesn't get affected by that. It's already the authority.

#

In case that's your question.

remote tusk
remote tusk
grand kestrel
dire cradle
#

whoops, i meant to edit the message, deleted instead

karmic trellis
#

oh so bServerAcceptClientAuthoritativePosition not effects in Listen servers. Ok thanx

thin stratus
thin stratus
remote tusk
#

Since I understand PRINTS better, i can debug easily. Thanks sir!

#

This is where MY Timer ends, in the server RPC. Should I RPC here to inform finish (game state) so that others can react to that. OR should I have a "RepNotify" boolean like IsFinished, and react to that? Which one is more scaleable for that case?

#

Or i can simply check on OnRep_Cooldown, and check Cooldown <= 0.

grand kestrel
grand kestrel
#

Only sim proxy (or physics) getting that

#

Have confirmed its not getting called at all for local

thin stratus
#

Yeah, makes sense.

#

@grand kestrel Are you sure CMC doesn't update the location? How are you checking for that?

grand kestrel
thin stratus
#

Why would it use those methods?

grand kestrel
#

Because it calls MoveAutonomous > PerformMovement > StartNewPhysics > PhysWalking > MoveAlongFloor

thin stratus
#

Pretty sure it will just set the Location without Sweep on the UpdatedComponent directly.

grand kestrel
#

Oh

#

No

#

I don't see how its relevant tho

thin stratus
#

But aren't you saying you can't find where the Client applies the Location the Server sent?

#

Maybe I misread

grand kestrel
#

Correct

thin stratus
#

Yeah, that's in ClientAdjustPosition_Implementation

grand kestrel
#

It doesn't appear to do that anywhere but the MoveAutonomous call (and rest of what it calls) results in the location being reverted on the client

#

I commented that out entirely and it still happens

thin stratus
#

Is this not what you mean?

grand kestrel
#

Let me test again

thin stratus
#

Like, that's what overrides the Loc and Rot, then sets the bUpdatedPosition, which then leads to the saved moves being re-applied

grand kestrel
#

Wtf I know I commented that out before
I thought it would be there and specifically checked
I overrode the function and didn't call Super
But maybe I didn't reload properly or something because it IS there ๐Ÿ˜„

thin stratus
#

Hm hm hm.

#

^ Vaei right now.

thin stratus
#

Lemme know if that solves your problem. I'm back to watching random animes.

rocky mantle
#

Is it possible to create a component on server only? Like, from the constructor? Or would I have to wait to do it at begin play?

grand kestrel
thin stratus
grand kestrel
#

Well, I need them to replay
Everything except the location...

#

I don't see where why or how its replaying the location, as far as I can tell, it isn't, except... it is

thin stratus
#

Okay I think I'm just misunderstanding. I thought you were against the Client accepting the Server location.

#

You also don't want it to replay the location?

#

I guess that makes sense

#

Cause that would cause the Client to run off

#

@grand kestrel

#

As far as I'm aware, all it does is:

  1. Ack SavedMove based on Timestamp (throw all old ones away)
  2. Apply Location from Server.
  3. For each SavedMove
  4. MoveAutonomous for current SavedMove
  5. PostUpdate current SavedMove (updates the SavedLocation to the new one from MoveAutonomous)
#

That SavedLocation is also barely used for anything important.

grand kestrel
#

I'm not sure if applying the location from the server even does anything
Its replaying the moves (via MoveAutonomous) that screws up the location

#

I just don't see where/how that is happening in MoveAutonomous

thin stratus
grand kestrel
thin stratus
#

It should show a big difference though. Strange.

#

Like, if you imagine there to be a 1 second delay, so the Client performs 1 second worth of movement predictively.
And then the correction comes in, if it were to replay those 1 second worth of moves, it would be 2 seconds ahead in location.

grand kestrel
#

Yeah. I think so too. But nonetheless :/

thin stratus
#

It#s of course the combination of the two. First it resets to the last ack Move and then it replays all moves that are still predicted to get back to the location the client was at.

grand kestrel
#

Oh wait I might be overwriting it to use the client's location lol, because it has authority

thin stratus
#

MoveAutonomous performs the move the same way it would have done when predicting. So it will run through the StartNewPhysics etc.

grand kestrel
thin stratus
#

So it will end up moving the component.

#

It doesn't. Why would it need to?

grand kestrel
#

๐Ÿ˜

#

I'm not following

#

When it does MoveAutonomous it rewinds the location

thin stratus
#

It shouldn't.

grand kestrel
#

I need it to quit doing that when it has client auth

thin stratus
#

Gimme a sec

grand kestrel
#

If I comment this out the issue goes away

#

It stops rewinding the location

thin stratus
#

But that shouldn't rewind anything t here.

#

Client accepts the new Location in ClientAdjustPosition_Implementation.
At that point, the Client got teleported back to the Location of the move that the Server deemed wrong.
So if nothing happens afterwards, the Client would now stand a few meters back.
It then acks the move based on the Timestamp, which kicks all SavedMoves that are older out, so only the ones that aren't replicated back yet will remain.
At this point the Client is still in the Location a few meters back.

Then it starts replaying the SavedMoves that are still predicted. Replaying here means that it takes the information about the "Input" of the player and simply performs the movement again.
Only that this time it originates from the corrected location. After all the SavedMoves are replayed, the Client will be more or less at the location it was before the correction. Just +- the corrected distance.

#

Replaying of the moves shouldn't reset the location at all. Quite the opposite.

#

If you comment out the MoveAutonomous you would cause it to not replay any of the movement it still has predicted.
It would just teleport the Client to the auth Location and that's it.

#

@grand kestrel I just scrolled to the original message of yours and I already wrote all of this once :D

grand kestrel
#

Yeah that makes sense. Sorry I was away from it so long I forgot it, I did read up but maybe not enough. I need to think this over. I'm probably doing something backwards then

thin stratus
#

What was the original issue again?

grand kestrel
#

It's probably simulating ahead by not reverting the location because I'm overwriting it

#

And thus snaps

thin stratus
#

Yop, that will also lead to a second correction then in theory.

grand kestrel
#

Yeah I'll play a bit with that in mind

thin stratus
#

Cause the next move after the replay will be based on the wrongly replayed location

grand kestrel
#

Yeah

#

@thin stratus this snaps to server location

#

This doesn't (but it also doesn't apply anything in saved moves besides location, such as stamina etc)

#

This means I've stopped it from applying server location yet its still doing it as a result of MoveAutonomous called for the SavedMoves

#

I guess it must be applying the saved move's location somewhere

#

This isn't making any sense to me

#

What it comes down to is when simulating my saved moves I need to be applying the client authority right? Because I have no idea where I'd do that

#

I really hate that CMC pretends it can grant client location authority
But it can't do that at all, it can only provide complete authority where it can no longer receive/apply server moves
ServerShouldUseAuthoritativePosition() and bServerAcceptClientAuthoritativePosition are not specific to position at all

#

Without bUpdatePosition I can't receive stamina or any other changes from the server
With bUpdatePosition I can't not receive location from the server
I have commented out ClientAdjustPosition_Implementation to no avail, so long as bUpdatePosition = true then it will overwrite the client's location, seemingly nowhere at all -- nothing ever queries this let alone sets it

#

But yeah. I'm not doing anything backwards. It isn't simulating from the wrong point and then simulating ahead. I'm not applying anything anymore. All I'm doing is toggling bUpdatePosition. MoveAutonomous doesn't even use the ClientTimeStamp. Nothing reverts to server location. Except, its reverting to server location. It occurs when using MoveAutonomous to resimulate saved moves. Except, it doesn't occur there. I've been through everything it touches.

thin stratus
grand kestrel
#

Ah I'll put that back in