#multiplayer

1 messages · Page 233 of 1

quasi tide
#

How does client 1 do the damage?

fiery wadi
#

Although looking at the print strings Client 1 reduces the HP bar but the server isnt registering any actual damage.

quasi tide
#

Because the client isn't telling the server that it is trying to do damage

fiery wadi
#

as the health is still printing 900.

quasi tide
#

This code is running on the client. It is not doing any kind of server RPC

fiery wadi
#

I,ve tried multicasting, Run On Server, Switch Has Authority and cant get any of it to work xD

#

im being dumb probably xD

quasi tide
#

You just are missing the fundamentals.

#

Depending on where you called those, depends on if it works or not

fiery wadi
#

Pressed 1 (Inside the player character)

#

Deal Dmg inside the EnemyCharacter

quasi tide
#

So, for simplicity sake only - do this

#
  1. Create an event that is Run on Server and it expects the BP enemy
  2. Inside of that event, do the damage
  3. After you set the "New Var" in the screenshot, call that event

Do this inside of the player BP

This isn't the best because it is highly exploitable, but it should show you how you should structure things roughly (when starting out)

fiery wadi
#

So would I need to change DealDmg to run on server to receive damage from a PlayerCharacter blueprint?

quasi tide
#

It still won't work

#

Because the client does not have network ownership of the enemy

fiery wadi
#

Ahh

quasi tide
#

You can only call server RPCs on actors that you have network ownership over

dark edge
fiery wadi
#

Ohh so an AIController cannot send requests to the server?

dark edge
#

The simplest setup that mirrors what you have would be like:

1 key -> run on server event
run on server event -> get actor -> apply damage

quasi tide
#

Just do the 3 steps I outlined above

quasi tide
fiery wadi
#

forgive the horrible naming.

#

Ahh omg you guys are genius,s I have been trying that for about 3 days

#

Got too much brainfog from articles and trying to understand the Cedric , wizardcell articles sometimes its hard to translate the "theory" into an actual ssscenario

dark edge
#

The biggest thing to wrap your head around is the fact that your replicated actors exist on MULTIPLE COMPUTERS

fiery wadi
#

And its not made clear that trying to call a server event inside an non-human controller player is not really possible.

dark edge
#

your character exists on your computer and on the servers computer

quasi tide
#

It is possible

#

You just have to have network ownership of it

fiery wadi
#

I understand that each client has their own "copy" of actors which they interact with

dark edge
#

your input only happens on your computer, and replication of variables only happens on the server computer. The client's version of the pawn needs to send data to the servers version of the pawn, that's the run on server event

#

the reason why your code worked for the host is that the input and setting the variables were both on the same machine

fiery wadi
#

last time i wrote any kind of networking things was using TCP Sockets and stuff so this is all kinda new and I had to typically write a server app to mediate between clients and server. xD

dark edge
#

the host is server AND a client effectively in a listen server context

fiery wadi
#

Yep

dark edge
#

you don't have 1 thing that does the communication for you, each actor class encodes its own communication technique basically

dark edge
fiery wadi
#

Ye which is what im trying to get my head around at the moment which is pretty tough tbh those articles are really good once you understand the basics but I think the main problem is that its hard to translate theory into practice without falling over some hurdles along the way 🙂

dark edge
#

The venn diagram is the best little cheat sheet

fiery wadi
#

I,ve seen that quite a few times as well

dark edge
#

Make it your wallpaper

fiery wadi
#

I have it saved 🙂

#

thank you !

#

So based on that diagram each PlayerController would own their own copies of the AIEnemys ?

dark edge
#

the circle is each computer

quasi tide
fiery wadi
#

I meant you would interact with the copies of the Actors the clients own inside their respective controllers?

quasi tide
#

Client's do not have ownership of the AIEnemy by default

dark edge
#

I mean in general if it's a pawn and is in relevency range

#

not ownership, a copy

quasi tide
#

Yes, but he said "own"

dark edge
#

oh i didnt see the own

quasi tide
#

They don't "own" their copies

dark edge
#

yeah no ownership

fiery wadi
#

Maybe "own" is not the right word 🙂 the server is king i learned.

dark edge
#

ownership and "it exists on my computer in my version of the world" are different things

dark edge
#

ownership is what you need to have to fire a server rpc through something

#

say you wanted to go open a door

fiery wadi
#

Ah ok so the server owns the AIController enemys this makes sense now thank you!

dark edge
#

input -> rpc inside your pawn -> door.open would work
input -> rpc inside the door -> door.open would not

vapid gazelle
#

Is there any reason to prefer LaunchCharacter over AddImpulse when trying to push a character into a particular direction? Is the former somehow better in a multiplayer context because it takes advantage of all of the CMC machinery to make character physics work nicely across the network?

dark edge
#

since you don't own the door

fiery wadi
#

That makes sense!

dark edge
#

It also sort of forces you to have the "interface" that the player has with the server be in the context of their pawn or playercontroller

#

you tell the serverside version of you to open the door, not you tell the serverside version of the door to open

fiery wadi
#

That makes more sense to me now many thanks!!!

grand mica
#

Does anyone think client-server based fighting games use some kind of server lockstep with client prediction/rollback model? Not the kind of lockstep that waits for the inputs from the client forever but upto a point.
The reason I am asking this is because I tried different cases on brawlhalla and I figured out -

  1. It does hit/knockback prediction on client and if something is mispredicted then it rolls back its state
  2. When two clients with different latencies hit each other at the same frame then the server validates the hit for both the client. Seems like this kind of result can be achieved when the same frame is processed at the same time on the server, hence, suggesting it uses some kind of server-lockstep model.
eternal canyon
grand mica
vapid gazelle
#

I noticed that the bigger the latency, the more physics-enabled objects my client ACharacter runs into fly into the stratosphere. It works great with a ping of 0ms, but the higher it goes (especially with packet loss) the more objects seem to violently react to being pushed around by running into them.

Fair to say that it's likely due to the client player suddenly finding themselves intersecting a lot with the object on the server, and the physics computation saying "this object needs to be impulsed pretty hard given how far the player went through" or perhaps the impulse is being applied multiple times back-to-back while the object is de-overlapping itself from the player?

I wonder if there's a way to tell the computation that I don't want the push from the player to be always within a certain range, not go from a flick to a rocket to the stratosphere.

swift sorrel
#

physics in general is hard to replicate

#

if possible, I'd recommend trying to rework whatever kind of physics mechanics you're doing into something that doesn't depend on physics (ie. character movement) which may be easier for the server to predict

vapid gazelle
# swift sorrel if possible, I'd recommend trying to rework whatever kind of physics mechanics y...

It's an interesting conundrum. Right now the whole premise of the game is that it's a physics sandbox, but it's unclear if this is actually technically possible in practice. I'm trying to figure out how to answer that question, because if ultimately this is practically impossible, especially if players are expected to interact and react to fast moving physically simulated objects, we really should nip this in the bud earlier than later 🥶

swift sorrel
#

yea, you might be digging yourself into a deep hole. I would not recommend trying to do a physics-oriented multiplayer game. especially if it's your first or even second project

vapid gazelle
dark edge
#

You basically have 2 physics engines at that point, with 2 different philosophies, with networking.

vapid gazelle
dark edge
#

And then physics plus prediction is a gigantic can of worms on its own. If you're okay with throwing prediction out the window, then doing everything through physics is fairly doable.

vapid gazelle
dark edge
#

Fully consistent, but you have ping lag between inputs and seeing a result

#

Prediction means you do stuff early locally, but sometimes you are wrong, and then you need to rectify that

swift sorrel
#

yea. basically character movement controller is already made to be networked and is intended to be kind of a starting point for most games. physics, on the other hand, doesn't have any such training wheels and is almost completely devoid of networking aids because of the nature of physics prediction in general (other engines apart from maybe Source struggle with physics prediction from the get-go). you're pretty much going to be fighting with physics networking each step of the way unless you know what you're doing

vapid gazelle
# dark edge No prediction means you see everything exactly as it happened on the server.

Ah I see. So nothing happens locally. Yeah that'd be rough, the hope was to go up to say 100-150ms and still be able to interact with someone fact moving physics objects. I think one saving grace here is that we're trying to cap the number of players to just 2, so even if you become client-authoritative, the only other instance to be confused by what happened is the server, there is no third of fourth player to surprise with reality suddenly changing from under them.

dark edge
swift sorrel
dark edge
#

The stock replication settings are insanely strict though.

vapid gazelle
#

Interesting, so this has a lot to do with what comes out of the box with UE, right? I remember someone mentioning that Mover 2.0 was supposed to be Epic's "fix" for this but we're nowhere near production grade for it.

swift sorrel
#

it gets a lot more prominent at fast speeds too

dark edge
swift sorrel
vapid gazelle
#

Is it possible to define custom network emulation profiles?

hot bramble
#

Is there a good doc that goes into how things like how UStaticMeshComponent replication works? What exactly is replicated? How and when does the client load the static mesh asset?

lost inlet
#

you do have source code access and it's easy to ctrl+f "replicated" in the header

#
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=StaticMesh, ReplicatedUsing=OnRep_StaticMesh, meta=(AllowPrivateAccess="true"))
    TObjectPtr<class UStaticMesh> StaticMesh;```

the answer, through an onrep
#

though I've never had to replicate a SMC

hot bramble
#

Well yes I have the source but I'm hoping to short cut reverse engineering the entire replication system. My question is more broad with SMC as an example.

How does the replication system load any unloaded asset? Does it synchronously load the UClasses and objects the frame they're replicated or does the system do that sort of thing off the game thread?

lost inlet
#

it replicates the path, and synchronously loads it unless you have the cvar enabled that makes that async instead

carmine bluff
#

Any ideas why ServerTravel->("Game/Levels/MyLevel?listen") changes the map but doesn't actually listen? When I do a commandline standalone and specify the map with ?listen it does listen

lost inlet
#

and that's enabled in Lyra I just remembered. net.AllowAsyncLoading=1

hot bramble
rich geyser
#

Anyone know if there there is a client side delegate/function override that is called after a traveling is complete, and the player controller has been replicated? Looking to send information to the server after logging in.

#

Last resort was just to have the server request it after the player logs in

fossil spoke
#

@rich geyser Im not aware of a specific function on the Client that does this.

#

What you can do, is override AGameModeBase::GenericPlayerInitialization and send an RPC down to the Client to tell it that its been setup.

#

Then the Client is free to do whatever, send an RPC back with some info, pull down a loading screen 🤷

#

Whatever

#

Overriding an ActorChannel would be a last resort.

#

That should never be your go to solution for anything.

rich geyser
#

Is there a reason to go with GenericPlayerInitialization and not PostLogin? Something like the PC not being replicated on the client side or something?

fossil spoke
#

PostLogin might be to early.

rich geyser
#

Ah ok. I was afraid of that.

#

Thanks!

fossil spoke
#

Also

#

GenericPlayerInitialization is called for both forms of travel.

#

Where as PostLogin is only called once.

#

So keep that in mind.

torpid lantern
#

For those hosting a dedicated server in AWS, which instance do you use and why?

fossil spoke
#

Generally speaking it will typically come down to CPU.

#

How many executables of your game can you run on a single instance.

torpid lantern
#

I was in a t3a.medium and with 40 AI characters and 2 players, my CPU was 92%.

fossil spoke
#

If you think thats a problem, then you need to focus on optimizations that target CPU usage.

#

Profile -> Identify Bottlenecks -> Implement Optimizations -> Profile -> Compare Results -> Repeat...

torpid lantern
#

Totally. My hunch is it's character movement and AI pathing. I'm a profiling noob still, can't figure out how to profile the dedicated server in isolation. Needs more YouTube videos.

exotic wasp
#

if you're using characters for ai it's almost definitely that

upbeat basin
thin stratus
upbeat basin
#

Didn't know that, thanks for correction

thin stratus
#

You can, for example, just fine send your game settings via your own keys

#

?Key1=Value1?Key2=Value2

#

And then grab them via the OptionsString in the GameMode on "the other side".

blazing spruce
#

Is this allowed? lmao I'm running out of ideas crying

#

😂

bright summit
#

xD I did something similar but answer is no - you shouldn't do things like this

blazing spruce
#

danm it 😂 god danm race condition is kicking my ass man lmao

tardy fossil
#

personally i wouldn't send an RPC to a client to have him open up the widget.. I'd have the GameState have a replicated variable (like a bInPreLobby boolean or a ENUM of states the game can be in) and have the HUD class on the client create the widget based off the replicated variable in the gamestate

upbeat basin
#

For the pre-lobby state I'd go for Omnicide's solution, a state variable with repnotify which HUD can listen for

#

Where do you call GetGameState and have a null for it though? GameState should be calling all actors' BeginPlay's, so it should be available on BeginPlay, even if it doesn't have the replicated variables up to date yet. Which you can solve with OnRep functions to be notified when they are updated

blazing spruce
# upbeat basin GameState have `AddPlayerState` and `RemovePlayerState` functions which you can ...

I dont see these functions in the overridable section so i assume thats c++?

So i set up a repnotify 'GameStateReady' bool set to true on game state begin play? How does the HUD listen for it? Do i not need to cast to the HUD from the OnRep function? I'm also not using a HUD class at all, player controller does all the widget stuff

If you have a look at my original post with the images i included im calling a 'Update all Player Lists' event on the game mode on OnPostLogin and OnLogout, which calls a 'Update UI' event on the client on their player controller which calls over to the pre lobby widget to clear the PlayerList and re-add them back in by looping over the player array, this is where the game state is null for the client when they first join the session, works fine for the server player

upbeat basin
#

That's a lot of RPCs in my opinion. You would want to prefer replicated variables or already build solutions instead of RPCs

blazing spruce
#

I'm def open to a better way of doing it as long as i can get it working lol

upbeat basin
#

Yes those are only available for cpp, you won't have most of the proper solutions with BP only

blazing spruce
#

Does that include 'listening' for OnReps?

upbeat basin
#

By listening I meant broadcasting event inside the OnRep/RepNotify functions

#

Other objects can bind themselves to that events to also get notified when the value replicated/updated

blazing spruce
#

Like a dispatcher?

upbeat basin
#

Yes

#

If you don't want/need a proper solution, I'd just use the widget tick to clear and generate player widgets. Which is a bit heavy so it can be a bit optimized with storing PState->Widget map to only create for new players in array and remove the ones that no longer exists in the array

#

Otherwise, AddPlayerState, RemovePlayerState and OnRep_PlayerState are already there and can prevent you from all of the RPCs

thin stratus
#

You'll find that a lot of Multiplayer coding is about knowing when what is available to you.

#

Also BP-only Multiplayer is of course a joke. You'll need C++.

#

But that might be obvious already.

upbeat basin
#

I'd still support going with BP as a demo/learning project

thin stratus
#

BP-only can use BeginPlay and EndPlay of the PlayerState fwiw

blazing spruce
#

Been trying to avoid using c++ as long as possible lmao

#

If i have to ill do it ofc

thin stratus
#

Do Singleplayer then

blazing spruce
#

too late for that 😂

thin stratus
#

The harsh truth is that Multiplayer will sooner or later need you to use C++

#

And a Project that is 90% BP and 10% C++ is not properly balanced.

#

You'll find yourself needing Structs and Enums, Variables and Functions that you created in BPs in C++

#

And then you gotta refactor a shit ton to get them up there and replace all the references.

blazing spruce
#

Sounds fun crying

thin stratus
#

If you do Multiplayer, go in with at least a 50/50 ratio of C++ and BPs overall.

#

Best would be 70-80% of core logic in C++. There are SO many things in C++ for Multiplayer that are not available in Blueprints.

#

Not even counting the performance part.

#

A demo/learning project that doesn't care about being a dumpster fire can use BPs for most of the time I guess

#

For your specific issue, you are already dealing with stuff not being available in BPs, which is OnReps for some of the Classes.

#

The Delay thing to grab a reference that is invalid at time X is of course bad.

#

As Layso said, you usually use OnReps, combined with Delegates, to notify whoever needs to know about an Actor becoming valid.

upbeat basin
thin stratus
#

Or you piggy back of the events that already tell you that something specific is valid, like BeginPlay.

blazing spruce
#

For the most part i can do the OnRep/delegate stuff in BP however i know OnReps in BP aren't exactly the same as OnReps in C++ right?

thin stratus
#

In theory, they are the same.

#

Deep down they are something totally differnt I guess.

#

They are PropertyChanged Notifiers.

#

That's why they trigger on the Server in BPs, or when the Client locally changes the Value.

#

Despite that, they will behave the same in terms of replication.

#

Your Lobby setup should work like this:

  • PlayerController, probably on BeginPlay, locked to IsLocalPlayerController, should create your LobbyWidget
  • Your LobbyWidget should make sure that it binds to "something" that notifies it about a new Player joining. This can be the GameState for example.

There should be no RPC required here.

#

In 99% of the cases, when dealing with things that can be valid but don't have to, you have a setup of two steps:

#
  1. Get the Current Value (if possible)
  2. Bind to an Update Delegate
#

E.g. Get the current List of Players via the PlayerArray -> Bind to some Delegate that notifies you when the Array changes.

ruby parrot
#

Hey, I am learning c++ and I get this: what is the issue here?

thin stratus
#

Of course, in this specific scenario, PlayerArray is a non-replicated variable with no proper OnRep or update events in Blueprints.

#

So either you go to C++, or you make your own PlayerArray and mange it manually.

thin stratus
ruby parrot
blazing spruce
#

Interesting, ill give those a go, like i said i don't mind using C++ if i have too ofc as long as i get it working lol, i did originally try having a 'connected players' array that i add too OnPostLogin and remove from OnLogout but this was also giving me problems

thin stratus
thin stratus
#

If you do a custom Array you'd need to put it into the GameState.
Then mark it as RepNotify, add a Delegate (EventDispatcher) that calls when the OnRep calls.
And then in your PlayerState, on BeginPlay -> HasAuthority -> Yes -> GetGameState -> AddPlayerStateToCustomArray, and similar on EndPlay

#

And if you add your Lobby in the BeginPlay of the PlayerController, then you'll also ensure that the GameState is valid.

blazing spruce
#

Perfect, gonna give these a try and see how i get on lmao thanks mate! and thanks @upbeat basin

carmine bluff
# upbeat basin `ServerTravel` doesn't take extra options into consideration as far as I know. I...

Thanks for this, I was trying to find an alternative. The course I did on Udemy used ServerTravel() with ?listen in the URL, and it worked for me on 5.2 and seems to work for them on 4.27, but for some reason this project I'm doing in 4.24 it does not. I guess maybe they updated it between (4.24, 4.27)

The course in question: https://www.udemy.com/course/unrealmultiplayer/?srsltid=AfmBOooAu9I8tFpefFMrFXoU5Qno0RNDFx1EL2_Qul2rMm5_OeJv-Y7T

mental rock
#

hey i need help can we use lyra for mobile game dev
or how can i set up this for mobile anyone know?

blazing spruce
#

Not sure if you can help here either mate? @upbeat basin

sinful tree
#

Your widget construction should also be reading the current value of the Player Array when it constructs itself to ensure that it's not missing any potential dispatcher calls, for example, if the widget is being constructed some time after OnConnectedPlayerStateChange is called.

#

Ideally here when you're creating your widgets, rather than just passing the name and "isReady" you should just pass along a reference to the playerstate into the widget. You can then set it up to listen for other dispatchers that relate specifically to that playerstate to then be able to update itself without having to reconstruct your widgets over and over.

blazing spruce
sinful tree
# blazing spruce Sorry, trying to understand this but my brains a bit frazzled been stuck on this...

Yea the player controller part is fine, that's just creating your main widget I imagine.
The widget construction for each of the player cards you could just feed in a reference to the playerstate it belongs to, and then within that widget bind to event dispatchers that exist on that playerstate, and read the values directly from the playerstate as needed.

Here's it sorted out a bit more for clarity.
GameState
Create OnPlayerLeave and OnPlayerJoined event dispatchers in GameState that both have an input with a PlayerState.

PlayerState
BeginPlay of your PlayerState calls the OnPlayerJoined event dispatcher in GameState passing along reference to "self".
EndPlay of PlayerState calls OnPlayerLeave event dispatcher in GameState again passing along reference to "self".

Main Widget
On Construct of your Main widget read the Player Array from GameState and create a Player Card widget for each of the entries in the array, passing in a reference of the PlayerState Array Element in the loop.
On Construct of your Main widget also should bind to listen for the OnPlayerJoined dispatcher in the GameState, and when it receives it, create and add a Player Card widget and add it to the container, passing along the reference to the PlayerState passed in through the EventDispatcher.

Player Card Widget
The OnConstruct of the Player Card widget will now have a PlayerState reference when it is constructed, and you can bind to the OnPlayerLeave that exists in that PlayerState. That bind should "Remove From Parent" to remove itself.
The OnConstruct can be used to set any initial values that currently exist in the PlayerState now
You can have the OnConstruct listen for any additional event dispatchers that may exist in your PlayerState to know when certain values changes later and then the widget can just update itself.

blazing spruce
sinful tree
#

Oops, OnPlayerLeave should be in the GameState -- this lets you do other things by only needing to listen to the GameState rather than having to try and listen to a specific player, but still get notified whenever any player leaves the game.

#

So in your PlayerCard widget, have it bind to OnPlayerLeave in GameState, check if the leaving playerstate == playerstate that the Player Card widget has assigned, and if so, it can remove itself from parent.

blazing spruce
# sinful tree So in your PlayerCard widget, have it bind to OnPlayerLeave in GameState, check ...

Updated that but still getting a few problems, the first one is that when the host player starts the session it creates 2 player cards for them immediately, but then correctly only creates one when the client joins, another issue is that the server player cant see the client players name, clients see both names correctly tho and last one is that when the client leaves the session it doesn't remove that player card it just stays there, any ideas?

#

Just double checked and the playerstate == playerstate check is going false

thin stratus
#

@sinful tree just fyi. We already talked about this and to avoid c++ stuff I told them they could make their own PlayerArray if you want to have a simpler time due to being able to make it repnotify

#

But I see you went a different direction which is fine too

sinful tree
#

Ah gotcha 😛

thin stratus
#

Also there is a nasty delay with the player name on the PlayerState iirc

#

They don't set it deferred

#

But after it spawend. So BeginPlay will have an invalid player name on the server

sinful tree
# blazing spruce Updated that but still getting a few problems, the first one is that when the ho...

So you might be able to prevent it if you were to keep track of what cards were already created, but that means more arrays than necessary. You could have this event in the main widget call a function that returns true or false as to whether you already have a card for that particular playerstate. Within that function make it have an input of playerstate, loop through the contents of the PlayerList (there should be a way to get children of it which will give you an array) then loop through them, cast to your PlayerCard widget and check if the PlayerCard playerstate == funciton input playerstate, if so, return true and then on the completed of the loop you can return false. This should make it so that the function will return true if it finds the playerstate, and otherwise return false if it doesn't. You can then branch from that funciton and if false then poceed with creating a Player Card widget for the PlayerState.

blazing spruce
#

Any ideas of getting the name showing tho?

blazing spruce
#

Client's seem to see the names just fine, but server doesn't, only their own name shows

thin stratus
#

Are you setting the name just once when the entry gets created?

#

Widget entry that is

sinful tree
# blazing spruce Nice one thanks for that mate, I've added that in and now its only creating the ...

You'd have to know when the correct name is received to then have the widget update. If you're using the built in PlayerName variable that exists on the PlayerState, you have two options:

  1. Have something that calls an event dispatcher when the PlayerName gets changed (requires C++ I believe) that your PlayerCard widget can then listen for.
  2. Make it so your text widget just binds to the PlayerName variable to set its value - this means your widget is basically constantly polling it which isn't great for performance, but if this is just for a lobby it should really be a non-issue.
  3. Alternative, don't use the PlayerName built into the playerstate (but you lose some built in stuff with online subsystems I believe) and use your own variable that you update yourself, and call your own dispatcher for when it gets updated.
blazing spruce
# thin stratus Widget entry that is

It is now yeah, now ive got the player state being passed into the PlayerCard widget that gets created I'm just pulling the name from there and settings the PlayerNameText on EventConstruct but previously i had it the player name being passed into the PlayerCard widget (where i am now just passing the whole player state ref) and the time before that i had the OnPostLogin set a replicated PlayerName variable on the player state by casting to PlayerState>GetPlayerName

blazing spruce
thin stratus
#

Do what Datura says it guess

#

Pretty sure a frame delay would also solve it

#

So Delay(0) before getting the name

quasi tide
#

I actually think there is a "Delay Until Next Frame" node now

blazing spruce
#

i thought delays are a no no

thin stratus
graceful flame
# blazing spruce i thought delays are a no no

Delays are fine to use. Especially for certain aspects of gameplay such as when some value changes and you need it to automatically change again after x number of seconds. That sort of thing. But adding delays to try and handle loading and data syncing is usually a bad use case.

cinder orbit
#

Did they change something in 5.5.1 for player spawning?
I have default classes set, & 2 player starts in my level--I used to be able to test in editor, Number of Players 2, Net Mode Listen Server & both would spawn in. Now player 1 spawns in & player 2 is glitched at 0,0,0 and unable to control or eject w/ ;
But both the pawn & controller class fire begin play events for the 2nd player.

blazing spruce
graceful flame
# blazing spruce But in this case it *is* for syncing data isn't it? 😬

Typically when there's a delay used to wait for something to sync it can done in a better way for instance I refactored some blueprints which were using a delay to wait for something to instead just dispatch an event at the end of its begin play execution chain.

Another approach which doesn't use dispatchers is to make an event timer on a loop so that it runs continuously checking for that thing to become available. Once it's found the loop stops, that way it handles any variance in time which a delay using a specific duration can't always do unless you make a longer delay which just increases the amount of time a player needs to wait overall.

thin stratus
#

Internally a Delay is just a timer.

graceful flame
#

yes but a delay is fixed duration

thin stratus
#

So yeah, that's both not a good solution.

#

A timer is too

graceful flame
#

whereas the looping timer at least can be more flexible depending on the loading speed of the machine

thin stratus
#

It's the exact same thing

#

A Delay is a Timer

#

fwiw, a Delay uses the LatentActionManager

#

But despite that, it's the same thing. You can loop a Delay by simply calling it against if whatever you are waiting for is still invalid.

#

An each time it is called you can alter the Timer on it if you want

graceful flame
#

I don't understand how they're the exact same thing. Say there's a delay of 1 second because its being used in this bad usecase scenario of waiting for something to replicate or whatever the original quesiton was about. You might have to increase to 2 seconds or 3 seconds depending on how fast things load, but a looping timer can just keep going for as long as it takes which maybe less or longer than the fixed duration of the delay. (but they are both not ideal to use for that sitaution in the first place)

thin stratus
#

So it doesn't really matter. Timer or Delay, it's not the solution

thin stratus
#

Still bad solution

graceful flame
#

I think we're saying the same thing ya

thin stratus
#

All I'm saying is that Looping a Timer to wait on a replicated data is bad

#

It's nothing different than Looping a Delay

#

If someone wants to know when replicated data is valid, they should use RepNotify.

#

Or an Event that already exists, such as BeginPlay to know that the actor is valid.

graceful flame
ripe lotus
#

if i have a replicated struct, with a few properties marked as uproperty. and i change only 1, is the whole struct sent on the network or only the property i've changed?
i know i've read this somewhere online but can't find it anymore (and can't remember (and need to know)).

noble sentinel
#

When I host a server and people join, they cant use any inputs, they are stuck freezed, no mouse or keyboard input.
When I try it on listen server/client on PIE and joining the server session from client, client spawn as flying spectator.
When I try it on listen server/client on PIE and joining the client's session from server, everything works fine.
If I spawn right in the level instead of joining session from main menu, everything works fine.
It was working before but now I am keeping getting this, what can be the problem?

blazing spruce
blazing spruce
sinful tree
#

So here... Instead of setting the bool directly in your widget, you could send an RPC to the server on the playerstate, and when running on the server, set the value.
I'd highly recommend against using a flipflop here for state as well - use the value of the replicated variable to control what is being displayed.

#

You may want separate RPCs, one for Ready Up and Unready, this way if a player happens to spam the button they'd only be requesting one or the other, and which you call is based on the replicated variable from the playerstate.

rich geyser
#

Hmm was thinking about something related to UniqueNetId replication in PlayerState. Does the server actually have authority over the uniquenetid on PlayerState despite PlayerState being owned by a particular player's connection? Thinking / worried about potential cheating where you change your uniquenetid.

fossil spoke
#

The UniqueID is just a copy on the PlayerState.

#

Its a copy of the one that is on your actual connection to the Server.

#

Changing the UniqueID on the PlayerState is likely going to do nothing.

#

Except maybe screw with you game locally.

#

Its not a vector for cheating.

rich geyser
#

well our game is P2P if that makes a difference

#

we're using uniquids to identify and send input data to each of the other clients.

fossil spoke
#

You mean your game is Listen Server

#

And you are using the built in replication system to transmit data.

rich geyser
#

we are using that for certain things, but direct packet communication using EOS's P2P interface for sending/receiving player inputs

fossil spoke
#

Why would you do that?

rich geyser
#

The game is build around deterministic lock-step simulation.

#

there's no replication for game state

fossil spoke
#

If you are implementing or have an actual understanding of how to develop a deterministic lock-step game in UE, you shouldnt be asking if the PlayerStates UniqueId can be spoofed.

rich geyser
#

🤷‍♂️

fossil spoke
#

Eitherway, you shouldnt be routing Inputs based on the UniqueId attached to them, you should be routing them based on the connection they come from.

#

The UniqueID is effectively the connection identifier

#

The EOS P2P API has nothing to do with Multiplayer in UE

#

Its entirely abstracted away

rich geyser
#

not asking about the P2P interface though

flint epoch
#

This is kind of a broad question but I was wondering if someone can give me some guidance. If I have a saved_move on the CMC that tries to do 3 mechanics at the same time basically. So it tries to do one, if not the other one and so.

So on my character class I have the enhanced input. And it works, when I press the input (all 3 at the same time).
But I am not quite sure on where to modify my code to have 1 of those mechanics work as usual (when I press input). but the other 2 start working after I have held the input for 0.2 seconds.

Im just not that familiar with this, before using the cmc I used to create one input for each mechanic. But now I save all the ones that share it on one single move to optimize it.

Could anyone give me some guidance with this?

thin stratus
#

Saved moves should only really store information. They shouldn't execute anything, at least not in terms of movement. The movement should be fully coded into the CMC. You should not even worry about the saved move after you coded the state into it.

#

And the delayed actions can either be outside the CMC, locally, or you keep track of the timings with a timestamp in the CMC and execute the movement if the player is still holding the key after x seconds based on the timestamp

#

All in all I'm not sure if your problem is even CMC related

#

@flint epoch

flint epoch
# thin stratus <@481645292299485196>

I see. Im sorry if it is a basic question but the place where I actually put what mechanic it should use is on my UpdateCharacterStateBeforeMovement(float DeltaSeconds) function.

In here I have

// Try Mantle
if (MultiCharacterOwner->bPressedMultiJump)
{
    SLOG("Trying Multijump")
        if (TryMantle())
        {
            MultiCharacterOwner->StopJumping();
        }
        else if (TryHang())
        {

            MultiCharacterOwner->StopJumping();
        }
        else
        {
            SLOG("Failed Mantle, Reverting to jump")
                MultiCharacterOwner->bPressedMultiJump = false;
            CharacterOwner->bPressedJump = true;
            CharacterOwner->CheckJumpInput(DeltaSeconds);
            bOrientRotationToMovement = false;

        }

}

Which basically just tries to mantle first and so, in the end he just jump if it is not available the other mechanics.
Now, since I want the jump first and if I hold the input then tries the others, I would have to change the order first.

What I tried was to create this variables in the CMC
float JumpPressedTime;
bool bIsCheckingJumpHold;
const float JUMP_HOLD_THRESHOLD = 0.2f;

And with that adjust the logic on there. as well as created 2 new functions StartJumpHoldCheck() and StopJumpHoldCheck()

And on my character class I used those 2 functions one on Jumping() and the other on StopJumping().

With this I managed to made what I want work on the server only if I implemented bPressedJump = true; on Jumping(). However, this seems wrong since it was working when it was false before.

And on the client I just jumped forever as long as I held the input.

Since this didnt exactly work, I was wondering what would be a better aproach for this.

thin stratus
#

In the CMC.

#

Ah, actually Epic put it onto the Character again.

#
/** 
 * Jump key Held Time.
 * This is the time that the player has held the jump key, in seconds.
*/
UPROPERTY(Transient, BlueprintReadOnly, VisibleInstanceOnly, Category=Character)
float JumpKeyHoldTime;
#

The FSavedMove_Character also already keeps track of that JumpKeyHoldTime = Character->JumpKeyHoldTime;

#

Shouldn't that be enough for what you want?

#

Ultimately the Character is the one using it, but you should be able to use it in the CMC just fine.

#

CharacterOwner->ClearJumpInput(DeltaSeconds); is called in UCharacterMovementComponent::PerformMovement, which is called on both sides. And that in return does JumpKeyHoldTime += DeltaTime;

#

So Server and Client should both have a matching time (dropped packages aside).

#

The only thing you might need to do is adjust this:

/** 
 * The max time the jump key can be held.
 * Note that if StopJumping() is not called before the max jump hold time is reached,
 * then the character will carry on receiving vertical velocity. Therefore it is usually 
 * best to call StopJumping() when jump input has ceased (such as a button up event).
 */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category=Character, Meta=(ClampMin=0.0, UIMin=0.0))
float JumpMaxHoldTime;
#

Also Character.

flint epoch
# thin stratus ```c++ /** * Jump key Held Time. * This is the time that the player has held ...

Im still trying to understand everything, so what you are saying is that if I want to implement this functionality on the CMC. I would have to modify my UpdateCharacterStateBeforeMovement(float DeltaSeconds) function logic with JumpKeyHoldTime float which already keeps track of how long it has been held?
Anf if I wanted it to check on the character, I should use the JumpMaxHoldTime.
right?

Btw if I wanted it to be inside the character. It wouldnt be posible with this structure, right?

void AMultiplayerTPSCharacter::Jump()
{
    bPressedMultiJump = true;
    Super::Jump();
    bPressedJump = false;

    UE_LOG(LogTemp, Warning, TEXT("Jump isserver:%d"), HasAuthority())
}

Also, when searching for functions and variables fast do you use something or is it just practice?

thin stratus
thin stratus
#

Originally I found out by literally going through every function of the CMC. You'll find the Character functions eventually.

#

I wouldn't code this into the Character, unless the Character has a function that is exactly what you want.

#

The Jump() function itself is local only.

#

You gotta choose if you want to handle the decision of Mantle/Jump/etc. locally, before even sending the flag, or on the Server + Client Prediction.

#

If it's really just about the Key Inputs, I would argue that it's fine to handle it locally.

#

As long as you do the tests for "CanMantle" etc. still in the CMC on Server and predicted on Client.

flint epoch
thin stratus
#

Which means you can do all of this "Held" stuff with just the EnhancedInput side of things.

#

And if your Triggers and InputActions gave you the answer you want, you can send bPressedMantle, bPressedJump etc. as true

#

And then handle jumping/etc. in the CMC.

thin stratus
#

I would probably do it like this:

  1. Locally on the Client, when the InputActions are pressed, figure out if the Client is holding the Key, etc. Basically determine here if you want to Jump, Mantle, etc.
  2. Based on the result of 1. call Jump() or a matching Mantle() function that sets bPressedJump or bPressedMantle to true.
  3. Use those the usual way via the Flags in the SavedMove to tell the Server what the Client pressed.
  4. Use UpdateCHaracterStateBeforeMovement or similar to handle the bPressedJump etc. booleans.
  5. Check if the player can actually perform the Jump/Mantle etc., and handle any kind of "fallback" logic (e.g. Wants to Mantle, but can't, so fall back to Jump).
#

That way you don't have to bother with syncing this, keeping track of hold time in the CMC etc.

#

Input is a pretty local thing after all, and handling how long a player pressed a key is totally fine just locally.

#

The important part is to check if they can do the thing they want to do when they send bPressedXYZ in the CMC.

flint epoch
# thin stratus The important part is to check if they can do the thing they want to do when the...

I understand ty. Btw, I noticed you mentioned bPressedJump and bPressedMantle. I only have bPressedMultiJump that basically when it is true it calls 3 functions, Jump, Mantle,Hang. (In the future it may call more). Would you say it would be better to separate them?
While I am writing this I just realized something.
On my SetMoveFor and PrepMoveFor I have this

Saved_bPressedMultiJump = CharacterMovement->MultiCharacterOwner->bPressedMultiJump;

(the other way around for the second one)
But on an scenario, where I would have bPressedMultiJump and bPressedMantle (for example). Is it posible to store them both on the Saved_bPressedMultiJump so I use the same amount of space? So far I just have bPressedMultiJump which triggers all 3

nocturne quail
#

Client marked function is being called on all clients, is not the Client mark intended to be calledd only on local/owning client?

UFUNCTION(Client, Reliable)
nova wasp
nocturne quail
#

it works now like a multicast event

#

UE_LOG(LogTemp, Warning, TEXT("ClientTest_Implementation was called from %s"), *GetWorld()->GetFirstPlayerController()->GetPawn()->GetName());
this logs on all clients with their names

nova wasp
#

use GetDebugStringForWorld

nocturne quail
nova wasp
#

also please be specific with who is calling the function and what is receiving the call to _implementation

nova wasp
#

I assume you mean that something is calling it and every client is receiving the rpc?

thin stratus
#

Whatever you are seeing is probably just false information.
ClientRPCs call on the OwningClient of the Actor. GameState doesn't even qualify for that and the ClientRPC would just call on the Server in that case.

ornate moat
#

Hey peeps.

I have a general purpose question..

Are there any custom events for servers? I have everything setted up for single player, shooting, projectiles, etc.

But on servers dosen t work. Ty

thin stratus
upbeat basin
#

Is there anything against using replicated timeline components? Or should I replicate server start time and let clients trigger their components accordingly?

upbeat basin
#

Eh I guess I'll fall back to the second option anyways, stopping a looping timeline doesn't seem to trigger OnStopped delegate

ornate moat
woeful ferry
#

if you plan on doing MP

thin stratus
meager heart
#

Is there a good way to check if an actor that a client may have authority over is running on the server?

  • I typically use HasAuthority(), however in the instance this actor is spawned by the client locally that will return true, and I want it to return false unless it's explicitly the server version of the actor that also gets spawned
  • This is for projectiles which is why I'm spawning a local actor as well as a server one
chrome bay
#

HasAuthority() && !IsNetMode(NM_Client) ..?

meager heart
#

Yeah that should work, I was just checking if there was some other HasAuthority() equivalent which was intended to be used for that check specifically, but I can run both

fiery wadi
#

Can someone do a sanity check for me please, In the Top Down Template the server and client are acting differently, IE The server can click a location and the character moves to it but the client will not walk to the location but startt to walk the instantly stop and you have to hold the mouse button down for him to keep running unlike the server. In 5.4

thin stratus
sinful tree
fiery wadi
#

Ahh ok thanks I,m not going mad then as it says the characters are set to replicate and replicate movement and the character movement component are set to replicate so I thought they were set up for MP, I,ll have to write my own functions to process server and client movement then, Thanks! 🙂

thin stratus
#

It's probably just the click that had to be sent to the server and then the move executed there. Character is always set to replicate I believe

fiery wadi
#

Its weird though why the client starts to move but then stops instantly but the server works as expected surely if the server didnt receive the mouse click the client wouldnt move at all ??

sinful tree
# fiery wadi Its weird though why the client starts to move but then stops instantly but the ...

It's because it's using navigation which by default only exists on the server. The "Move To" function that is called in the controller when the button is released calls "Simple Move To" which uses the navigation system to facilitate it. The reason why it works when holding the button down is because it's using a triggered input that fires evey fame and calls "Add Movement Input" which is something that clients can do nomally.

fiery wadi
#

Ah ok thanks for the explanation!

blazing spruce
#

Hey, this readying up works fine when the players are in the pre lobby, everyone can ready up and see each other ready status by setting the background colour of the PlayerNameCard widget but it doesn't show green for any other players who join the session after those players have ready'd up, when they join they'll just see the default colour instead of green, how should i go about solving for that?

sinful tree
cinder orbit
blazing spruce
blazing spruce
# sinful tree The player card.

Thanks mate, i've got another issue still happening with the OnPlayerLeave binding on the player card widget, the player card gets removed on the clients screen whenever a player leaves the session but doesn't on the server's screen the player card stays there, do you know why that's happening? OnPlayerLeave gets called from the player state's End Play event

nova wasp
#

Can replays be made to delay creating objects until a game state is received from the replay? I'm struggling to see a simple way to order demo driver objects beyond prioritization

#

Perhaps easier to just fix individual cases here and there but it's a bit annoying pawns can arrive before the gs

bright lance
#

I’m playing a root motion montage on a player, via client multicast, on a listen server. I send a request to the server when a button is pressed, the server then sends a multicast to all clients. When a non-server client sends the request and then plays the animation it looks choppy/broken. When the server client triggers the animation it looks correct.

At first I thought maybe the server is trying to correct the root motion. Since both the server and the client will be trying to adjust the position of the player. But I didn’t see a way to disable the root motion on the clients. Is this the issue or is there something else?

vapid gazelle
#

Ok, this is bizarre and I feel like I'm missing something obvious here. Could someone sanity check this?

I have an Actor that's just a static mesh sphere with physics enabled on it on both client and server. I turn off Replicate Movement (bReplicateMovement in Actor.h) on the Actor and nothing seems to really change. The actor's location, rotation and velocity seem to still replicate just fine to the client. Maybe the actor is a little more jittery without it, but overall I can barely tell the difference if you were to ask me to A/B test it.

What exactly does this do? Is this only useful for the CMC?

sinful tree
#

You can see what happens by running the FPS sample project and running it multiplayer then shooting balls at some of the blocks.... They'll move around differently on different instances of PIE because they're simulating physics on each instance separately without replicate movement/not being a replicated actor.

vapid gazelle
sinful tree
# vapid gazelle That makes sense. I thought this was the issue, I tried to get the client and se...

If you're simulating physics on the root component, then I believe that will make it so the actor's location/rotation gets updated which you can then replicate by enabling the replicate movement option, so then you may only need to simulate the physics server side and then replicate its movement to everyone... The only problem here is that there will always be some delay between a client interacting with the physics object and then actually seeing some result from that interaction.

vapid gazelle
#

Ok I actually just found out that someone had turned on the 5.3 experimental physics prediction feature on the project which is why the thing was not de-syncing. As soon as I turned that off, without Replicate Movement, the simulation clearly falls apart.

robust knot
#

I need some help with my networking in ue5. I have a main gun blueprint class and a main bullet class, i need the gun class to spawn a projectile (the bullet class) at a component in the gun class. This works fine in standalone but when use in on a dedicated server the bullet spawns at the bottom of the player. Here is the gun blueprint:

torpid lantern
#

How do I solve for displaying server-side cooldowns?

My charracter inventory components has a "cooldownDB" - map (name:datetime)

When an item is used, the system (server) adds the item ID as a name & the time used as a the value to the cooldownDB map.

The server then muti-casts a notifier.

My inventory widgets bind to the notify construct, when they get a message they fire logic to compare the notify payload (ID & time) with self. If the widget is of the same ID / item, the widget starts a looping event timer. On loop, the timer updates a text widget showing seconds remaining.

The issue I'm having is my server is saving the datetime in UTC server time, which does not match 100% the client's UTC time. So I believe my system is converting a server timestamp to a client's local time. As a result, the widget's cooldown remaining does not reflect the server's time.

--

For a solve, I was thinking of having the server store duration remaining instead of a timestamp in the map. But I'm a little stuck on how I'd keep that duration remaining accurate. I'd need to instead run timers on the server and I'd rather just store a static var, somehow..

Otherwise, thinking of sending a MC when the item is used and maybe the client keep a local copy of the map DB.

Plan C is to convert my item use to a GAS ability. I think there's some sort of cooldown management tracker, but I am not so familiar with GAS.

Am I on the right track here, or is there a cleaner way to go about this?

thin stratus
#

Server and Client's UTC should match. Otherwise the real world would have a problem.

#

The only thing that will always be a bit differnet is when you ask for the UTC.
If you check the value on the Server and then RPC to check on the Client, the UTC of the Client will be the Ping duration "later".

thin stratus
torpid lantern
# thin stratus GAS doesn't do anything special for Cooldowns fwiw. Also a Multicast to notify a...

I think this ping duration is tripping me up. That or my server is funky. My prod offsite server has a UTC variance of +-2500 MS. When I run the same test with PIE there is no variance. The variance appears to be somewhat static with each server machine reboot, but does change.

2500ms That feels a bit high for a +ping and I don't notice any lag in movement, ai pathing, or inventory interaction.

I don't know much about how UTC works on computers. Do they sync with a central authority? Is it at all possible that Server might think she's 2.5 seconds ahead of Client?

verbal ice
# torpid lantern I think this ping duration is tripping me up. That or my server is funky. My pro...

Lookup the Network Time Protocol. Either way, yeah it's possible to have time desync. Windows generally re-syncs with a time server every so often, dunno about your server. It tries to factor in latency as best as it can when syncing clocks, but it's never going to be perfect. 2.5s of delay is plausible, I'm p sure my computer and other servers have that, since sometimes my 2FA auth codes don't work when they're right at the start of their validity duration.

#

What eXi is saying I think is to compare the UTC time of server and client. The difference is the "UTC ping", or the difference in their os times.

#

So then, when the server says "hey, this ability is on cooldown until UTC time XXXXX", the client can get the "server's time" using its client UTC and adding the "UTC ping" difference.

#

Which tbh, with the mismatch that may happen, I don't see why you'd use this over the game state's server world time seconds

#

You run into the same "issue" @thin stratus

#

unless i'm missing something

#

you're still at the mercy of ping, except this time between client & server on the UE side, and the clocks of client & server on the NTP side

torpid lantern
#

TIL "get server world time seconds" - thank you!

Right now I am sending events to the client, and the client is creating a local cooldownDB. I like the idea of moving to OnRep, I feel like that might be less complicated.

robust knot
#

the fire function is being called from the player blueprint

thin stratus
#

So you'd, if at all, use a ServerRPC to tell the server to actually fire the gun

#

Hence my question why it#s a ClientRPC

unkempt tiger
#

can anybody relate to this thinkderp

pine sage
#

Translating it to only capture CDs should be simple enough.

normal viper
#

Would storing UPlayerState on actors that are ''spawned'' in the world be reliable way to check if these actors belong to ''this'' player or not?

Like, we would manage Spawning of Actor trough Component that is attached to Player State, this spawned actor will get ''reference'' to UPlayerState on spawn. Now when I (Player) click on that actor I will compare UPlayerState (of the ''player'' that clicked (me)) to the UPlayerState that is on the actor and proceed.

quasi tide
#

Use the Owner property that is there for all actors.

#

No separate UObject needed

normal viper
#

Hmm, so what ''type'' I should provide as Owner when I spawn something? Specifically that would be for RTS type of game with a lot of units/buildings. And how can I use it to check if I own that actor/unit/building later? Like do I compare what? Not sure If I ask the right question.

quasi tide
#

APlayerState

#

A more common approach is to just have a team enum

#

And assign that on spawn

#

Then if they're your team, allow processing of commands

#

A players team would be in their playerstate

#

If you want to do the Owner approach, you would just call Get owner and compare that with your own PlayerState

normal viper
#

Okay, got it

#

just to confirm if it's in right direction. Let's imagine you select actors with marquee. I would get all selected actors from rectangle, get their team/owner (by interface for example), and compare it with my player controller team/owner? More or less?

quasi tide
#

Pretty much

normal viper
bright lance
#

Should playing a root motion montage from a multicast with a listen server networking model just work? Non-root motions do, but when the root motion montage plays on non-listen server clients it looks like the montages positions are being overwritten and the animation doesn’t play right. The montage is playing on the player character. Worth noting root motion montage looks fine when it’s on the listen server player.

ashen scroll
#

Is it possible to use Get Owner on a Pawn and have it be replicated, because I am not sure if its an issue with the project itself (might be, cant get the controlled pawn on the controller itself either), but I cannot access the Controller of the pawn at all on the server, it works for the client though. Both the Player Blueprint and the Controller are replicated.

#

I have this basic set up for testing

pine sage
ashen scroll
#

I will thank you

#

I mean I hope I can get GetController working since I basically switched all the code for spawning the HUD and Inventory Widgets to being on the Player (in order to fix get pawn not working)

pine sage
ashen scroll
#

Ok doesnt work in a fresh project either, this is weird, lets see whether GetPawn does

pine sage
#

It should be quite straight forward. You could check how a template project does it.

ashen scroll
#

Must have missed something with the set up

pine sage
#

Hum. Can you show world config ?

ashen scroll
#

I may have to ask a stupid question, how could I do that?

nocturne quail
#

is there some global thing which i can set example: bShould_Include_All_RPCs_Only_In_Server_Build ?

#

its just very time consuming to put include in server build macro above every RPC call

ashen scroll
nocturne quail
#

I can do this but its not guaranteed to find all RPC calls

#include <iostream>
#include <fstream>
#include <regex>

int main() {
    std::ifstream file("YourSourceFile.cpp");
    std::string line;
    std::regex ufunctionPattern("UFUNCTION\\s*\\(.*\\)"); // Regex pattern to match UFUNCTION attributes

    if (file.is_open()) {
        while (std::getline(file, line)) {
            if (std::regex_search(line, ufunctionPattern)) {
                if (line.find("UFUNCTION(Server") != std::string::npos || line.find("UFUNCTION(Client") != std::string::npos || line.find("OnRep_") != std::string::npos) {
                    std::cout << "#if SERVER_BUILD\n";
                    std::cout << line << "\n";
                    std::cout << "#endif\n";
                }
            }
            std::cout << line << "\n";
        }
        file.close();
    } else {
        std::cerr << "Unable to open file";
    }

    return 0;
}
normal viper
#

I have question.

Ignore the events and hover this. Let's say this is from inside BP_Unit. Would this this actually be ''reliable'' in a way that does it make sense it will always Get the player controller of the player that actually hovered over something? Like in other words, is there a possibility, that player 2 hovers over something and it actually would show it for player 1? or i'm tripping and this will kind of work like intented.

ashen scroll
#

Out of non posessed I cant get a valid controller for the Server, now the issue is it seemingly is not valid for the player

#

Oh right I see it only runs on the server

nocturne quail
hearty kite
#

If I plan to spawn an actor pool, when the players run around spawning blueprints from PCG points and back again, am I spawning the pool on the Server Only (GameState) or on each client (PlayerController)? Note. I have to keep a reference to the client's ISM component saved on each blueprint so I can respawn the ISM Component back when the player Ends Overlap.

ashen scroll
quasi tide
#

You need to RPC to whomever to tell them to create the widget

#

Widget's themselves don't replicate

ashen scroll
#

oh what

quasi tide
#

Most UI communication gets routed through the PC

ashen scroll
#

wait so you cant replicate them at all

#

Well that kind of

#

messes up a bit and a half

#

So how can I even go about doing this, updating the slots in an inventory when an items added, i don't recall why but i believe it didn't for for me to update it on every single individual slot so i tried with all my might (uselessly it seems) to have the slot widgets be stored in an array I can use to update them

quasi tide
#

That should be driven locally.

#

(Note - I don't know what you're trying to do)

ashen scroll
#

honestly at this point i dont either myself

#

hopefully i can revert the commit to where i was still updating the slots individually and see why i opted to change it

#

i think there was a reason other than me perceiving it at cumbersome for performance

ashen scroll
#

I see now what conclusion I came to initially

#

Is it even possible to pass a refference of the Inventory ActorComponent to the slots, and have it update without manually doing so each time you change the values on the component

#

the way it is now, i cant send any updated data to the slots from the inventory, i am trying to have them update when an Event Dispatcher on the inventory gets called

dark edge
#

then the inventory component just fires OnChange whenever something changes, and anything that cares can update at that time.

#

If there's nothing that cares (inventory isn't open), then nothing happens.

#

"Hey, whoever cares, I changed. Either update or don't, don't matter to me, but just letting you know."

torn gulch
#

Is unreal out of the box multiplayer system bad for performance? Does it usually need optimization?
From my experience most features in unreal that are out of the box, are suitable for a game of like 16 players

nova wasp
sinful tree
nova wasp
#

If you are trying to make an MMO server it would definitely not just work out of the box I guess lol

#

some things are kind of done per-connection which is fine with lower playercounts

#

but it doesn't scale to the extreme... that said It's not that hard to just add your own data channels to unreal

torn gulch
#

what about an rts multiplayer game with huge battles? then thats where it gets tricky

#

@nova wasp @sinful tree

nova wasp
dark edge
tardy fossil
#

multiplayer RTS in general are tricky and usually use some tricks to make it feasible bandwidth wise, like only replicating waypoints and having client side do path finding

thin stratus
#

There is also something that a lot of beginners (to UE or in general) tend to forget: Unreal Engine was mainly used for a very unknown and dead Arena Shooter-type game. And the core of that whole network setup, without any new things Epic added over the years, is tailored to that.

You find tons of stuff in the Engine that still screams Arena Shooter, and the networking is largely setup to scale to the needs of a 16-64 (and 64 is already a high count) of Arena Shooter, where the maps are smallish, you gotta worry about movement, some replicated weapons, some pickups, projectiles, and that's probably it (hence whey CMC and ProjectileMovementComponent are the only thing with prediction and smoothing setups).

And the majority of Games that got released with UE4 with Multiplayer were probably (I don't have numbers or anything, so this is gut feeling) ListenServer Coop/Party Games and Dedicated Server Survival Games.
Only after PUBG started to tackle the 100 player mark and Fortnite also wanting to do that did we get the ReplicationGraph to improve network setup to support so many players.

Now, an RTS is definitely not something that Epic had planned to use the Engine for. And that's also what you should keep in mind. The requirements for an RTS may very well exceed what UE's standard network setup supports. Older existing RTS are often of course not using UE, or if they do they either managed to adjust it or replace the parts that didn't work.

swift sorrel
#

This is the same situation for engines like Source/Source 2 (more specifically, Dota 2) where the game is tailored to a certain type of framework so moving away from that for your game is asking for a lot of loophole-jumping

haughty ingot
thin stratus
#

Just one of the videos:

Custom DX12 rendering pipeline in UE4, custom netcode, pathfinding, movement. 1500 bytes/sec (1.5KB) of bandwidth. Deterministic lockstep P2P of the floating-point variety.

haughty ingot
#

That's why I mentioned the extremes

#

Super interesting stuff in there

crimson garden
#

Yo folks! What is the best approach to replicate movement on skeletal mesh with simulated physics? I know that is not supported out of the box, but Im trying to find custom solution for this. Basically I have PhysicsHandle that works perfectly with StaticMeshes - server and client have exact same movement for "thrown" object. I would like to add support for SkeletalMeshes as well. Currently I'm trying to attach SkeletalMesh to the StaticMesh via PhysicsConstraint and simulate SkeletalMesh movement via StaticMesh movement but it doesn't work - location are much different for client and server. Do you guys have any tips how to solve this problem?

ashen scroll
#

thanks for the suggestion about OnChange tho

#

seems so obvious but I wouldnt have thought about it

gleaming crest
#

What is "Indie" Best Practice for character rotation in multiplayergames (no lag compensation/client prediction)? Just send the world mouse cursor position every tick in an RPC?

dark edge
dark edge
gleaming crest
#

Im using characters I animated with mixamo. Its third person, so I only care about the yaw axis^^

finite kernel
#

https://www.youtube.com/watch?v=P8FnmProZHQ
52:45, i just noticed new UE video on off channel
Nice to see Fortnite is now using Iris replication officially, hopefully that means it will get fleshed out relatively fast now

Watch this recorded session from Unreal Fest Seattle 2024 that explores the features on the roadmap for Unreal Engine including UE 5.5 and beyond.

To learn more about Unreal Engine, check out our website: https://www.unrealengine.com/en-US

#UE5.5, #UnrealEngineRoadmap, #UnrealEngine, #UnrealFestSeattle

▶ Play video
thin stratus
#

In theory, unless you specifically turned that off, you should have the AnimBP also run on the Server or not?

#

PrintString and check I guess

daring gorge
#

how does one make a widget component have a constant size? ive read reddit posts saying to use a world context widget and manually rotate it, however then how do i get ref to the local pc or camera for the clients?

pine sage
#

It is, which is cool and not cool too.

#

Dedicated server are not rendered, so having all of those animations running and bones calculated can be not very useful

thin stratus
#

It's certainly expensive if you have a lot of SkeletalMeshComponents

#

Even in Singleplayer

harsh vine
#

How do you make multicast events on actors that have no owners? They seem to only run on server.

chrome bay
#

Owner doesn't matter for Multicast

#

What matters is whether it's replicated or not

#

Unreliable Multicast goes via property path IIRC so they do actually need to be replicated.

harsh vine
#

variables marked as replicated aren't being multicasted.

chrome bay
#

Not sure what you mean being multicasted. The actor itself needs to be replicated too to have any replicated variables.

harsh vine
#

marked actor as replicates, somehow managed to avoid needing that on client owned actors.

mild jungle
#

Anyone using Resimulation? https://dev.epicgames.com/documentation/en-us/unreal-engine/networked-physics-overview?application_version=5.5#:~:text=suit your project.-,Resimulation Mode,-The Resimulation replication
Should I be only applying forces through my Physics+NetworkPhysicsComponent and letting it replicate or should I be ticking physics on all clients? Especially things like (custom)Gravity. My setup is basically this: https://vorixo.github.io/devtricks/phys-prediction-use/ but with skeletal meshes. Having deviations, especially for quick changes like jumping.

ancient flare
#

Hey, I'm trying to solve a custom replication graph issue. After a sequence is player, some NPCs are teleported to certain places in the level. For some reason, some of the NPCs locations are never replicated to clients until they move again post teleport. Could someone with experience in custom replication graphs give a hint?

vapid gazelle
mild jungle
vapid gazelle
thin stratus
#

"Resimulation". Couldn't they just put the already existing terms they had and slap Physics infront of it?

#

So it's Client Prediction with Reconciliation

#

We could check if UE qualifies for a World Record in "Most Network Prediction Systems in one Code-base".

#

Hears some specific plugin crying in a corner.

magic hazel
#

Hello! Did you find a solution?

hoary timber
sonic obsidian
hoary timber
magic hazel
# sonic obsidian Have you tried Lyra's Common Loading Screen Plugin im using it and it prevents t...

Yeah, I've tried it, but it didn't help.
I have a loading screen while the level is loading, then instead of problem (the camera is at 0.0.0, you can see how World Partition is loading) now there is just a black screen for the same time (the square on the bottom right is frozen). After that, the loading screen appears again for a few seconds and then the game itself.
I would like the loading screen to remain instead of the black screen (for example add loading screen again)

sonic obsidian
# magic hazel Yeah, I've tried it, but it didn't help. I have a loading screen while the level...

That black screen you see is from this class FCommonPreLoadScreen in CommonPreLoadScreen.h/cpp im pretty certain as it matches ur black screen if you can rebuild your loading screen widget in slate it would work as you intend heres the slate widget you see there

{
    ChildSlot
    [
        SNew(SBorder)
        .BorderImage(FCoreStyle::Get().GetBrush("WhiteBrush"))
        .BorderBackgroundColor(FLinearColor::Black)
        .Padding(0)
    ];
}
``` in `SCommonPreLoadingScreenWidget.cpp`
#

im pretty sure its this class but i havent tackled that issue yet i also have the same thing

magic hazel
twin vessel
#

@grand kestrel Sorry to bother you, i was looking at you PredictedMovement repo and its wiki, and i'm confused by what should be in SetMoveFor and what in SetInitialPosition.
I saw that in SetMoveFor you copy in the SavedMove only Boost and SlowFall, while in SetInitialPosition you also copy Snare.
Do you have a rule of thumb to clarify what should be where?
I do not quite get what counts as an "initial position"

pale rivet
#

Hello!
I launch my level as listen server, and I want to join one more local client while I`m playing as listen server.
How do I create one more viewport window as client that will join to ongoing match?

pine sage
kindred widget
upbeat basin
#

It should be under Editor Preferences named as Allow late joining

ashen scroll
#

Is it possible to bind an event delegate to an event on a Widget Blueprint, and have it not break in Multiplayer? It seems to be the best way to add Updating Slots in my inventory system - send an Event Delegate with what should go into the slot in question, and the desired index so it only executes on the slot it should, but even though I seem to bind it correctly (refference to the parent blueprint on which the delegate was created is valid, it continues execution aftewards, in standalone it works as it should). I am fully aware I might have done something incorrectly and so the delegate is not being executed when playing as a client but id like to know if I can even do it as such.

pale rivet
#

@kindred widget @upbeat basin thanks a lot, that`s it🫶

ashen scroll
upbeat basin
ashen scroll
#

If you are asking where the Delegate is being called, the Inventory Actor Component which sits on the Player

#

It is replicated, all logic on it works in multiplayer

ashen scroll
#

wait

#

it shouldnt execute on server

#

nvm still doesnt work

upbeat basin
#

That doesn't matter how you mark your event replication in widgets, they don't replicate

ashen scroll
#

Yeah I know

upbeat basin
#

Are you broadcasting the event in every player?

#

Is it possible you're just doing it in server?

#

Try to debug under what context you are on the broadcast

ashen scroll
upbeat basin
#

Uh, I don't think EventDispatchers replicate even thought there is a checkbox for it

ashen scroll
#

It didnt work when it had it switched off either

upbeat basin
#

Probably because you're just broadcasting on server

#

You need the broadcast/call to be on every player

ashen scroll
#

it should just be on the owning player

upbeat basin
#

So inside your RepNotify function or with a multicast (which feels like not useful for this inventory update)

#

Okay but is your owning player aware of what's/something being changed?

#

Can you show your flow for the Call node

ashen scroll
#

Could you elaborate

upbeat basin
#

If you do a change in server (since they're probably replicated properties) and call the event on the same place, you're broadcasting only on the server

ashen scroll
#

Its currently just the function for adding Stackable Items, will add it to the other one too

upbeat basin
#

I can't see anything from the pic but I guess you got my point

ashen scroll
#

wait

#

let me take multiple screenshots

#

This however is being run on the server

#

So I should do it somehow on the remote?

#

Like perhaps store the values id send over and then send them off it

upbeat basin
# ashen scroll

If this is running on your server (again assuming since you set a replicated variable) you're calling the event only on the server as well, hence your client's don't get the broadcast

ashen scroll
#

wait

#

cant i just do a switch has authority

#

and put it on remote

upbeat basin
#

But that code is running only on the server, is it not?

ashen scroll
#

No the client gets the info too

#

actually

#

yes I believe so

upbeat basin
#

What I'd suggest is making your ItemSlotArray RepNotify and calling your event inside the function

ashen scroll
#

Well I cant do it that way, but i could store the values id send over with the delegate in a RepNotify

upbeat basin
#

So the clients can be notified when inventory is updated, broadcast the event and update the widget accordingly

upbeat basin
ashen scroll
#

wait actually yes it could work sorry, thought you said a different array which has the items after they have been added, and the issue with that would be the slots would get items that are over the max stack size

#

Yeah true I could do that

#

though, how could I know which index to send then

#

Like lets say I add 250 Apples, max size a 100
they get distributed as
Slot 0: 100 Apples
Slot 1: -||-
Slot 2: 50 Apples

#

How could then know which of the indexes to send, I mean I guess I could send the entire array and then get the item on the widget

upbeat basin
#

I don't know if there is a better solution but that's kind of what I do, compare the updated inventory with previous value to find what's added/removed/changed and update those slots

ashen scroll
#

i want to try something else first, if that doesnt work i will try this

upbeat basin
#

A client RPC could be a dirty last resort as well

ashen scroll
#

On what blueprint?

#

ohh the inventory

#

like call that when i want to call the delegate

upbeat basin
#

Although I want to state that I don't support it so much, yes

#

That would require you to send all your parameters with the RPC since you might (or persistently, I don't remember if RPCs are always faster than the property replication or if it's undefined order) receive the RPC sooner than the array's replication on client, so index only wouldn't suffice. So double the dirt

ashen scroll
#

I am suprised honestly that there is not a clean way to do this

upbeat basin
ashen scroll
#

I tried so many different things because I dont want my solution to be delete all the slot widgets and spawn them again

#

Yeah but like a cleaner way, sending an entire array even though you dont need most of it is not that clean really

#

but i suppose the best option i got

upbeat basin
#

The cleaner way would probably going with cpp to use FFastArraySerializer

ashen scroll
upbeat basin
#

That should be doing what you want, only replicating the changes instead of whole array

ashen scroll
#

if i dont have to use cpp i will choose not to really

upbeat basin
#

Those words can spawn a wild eXi any time soon

chrome bay
#
  • Blueprint
  • Clean Multiplayer Code
    ^ Pick one
upbeat basin
#

If you want the proper proper solutions, cpp is kind of must

#

Oh you got Jambax from the wildcard

ashen scroll
chrome bay
#

BP is just garbage for MP games. Once you've sampled the sauce you will never go back to networking in BP

#

Not that you can't do it, it's just an uphill battle

ashen scroll
#

i mean it worked fine enough for AI

#

probably would have worked better if it wasn't widgets I was working with

#

though

#

I reckon I could try a different version of something i did before

upbeat basin
#

It's more of a knowing when something changes problem rather than something specific to widgets

ashen scroll
#

well I beg to differ because if it werent something that doesnt replicate like widgets I could do this all on the inventory

#

and I did do it, but then I found out widgets dont replicate period

#

I missunderstood a reddit post saying that exact same thing

upbeat basin
#

You still can't replicate your event broadcasts whether it's a widget or not

ashen scroll
#

Wait what

#

Ok but still, at least I wouldnt need them then

#

i hope there arent many other things that dont replicate which i will need to use in a simmilar way

#

wait

#

Is a RepNotify on an array only called when a new element is added?

#

wait even if it were

#

its still broken

#

this is not being called at all on spawn, even though thats when the array is getting its slots

#

this gets called on start to set up the array but its not getting triggererd

chrome bay
ashen scroll
#

Ok so something doesnt work

#

Since its not getting called on any changes

#

well there goes my daily dose of motivation to continue trying to fix this inventory system

#

off I go doing something I need to

thin stratus
#

@chrome bay @ashen scroll I always had to call the Set node on it to trigger it.

#

But I haven't done any BP Array stuff in ages, so maybe that changed the last few years.

chrome bay
#

oh classic

thin stratus
#

I always explained it to myself that the Set w/ notify node is the thing that actually triggers this

ashen scroll
#

Right so I should try that next

thin stratus
#
if (SetNotify->HasLocalRepNotify())
{
    UK2Node_CallFunction* CallFuncNode = Node->GetGraph()->CreateIntermediateNode<UK2Node_CallFunction>();
    CallFuncNode->FunctionReference.SetExternalMember(SetNotify->GetRepNotifyName(), SetNotify->GetVariableSourceClass() );
    CallFuncNode->AllocateDefaultPins();

    // Copy self pin
    UEdGraphPin* NewSelfPin = CallFuncNode->FindPinChecked(UEdGraphSchema_K2::PN_Self);
    UEdGraphPin* OldSelfPin = Node->FindPinChecked(UEdGraphSchema_K2::PN_Self);
    NewSelfPin->CopyPersistentDataFromOldPin(*OldSelfPin);

    // link Set Node -> new CallFuncNode
    UEdGraphPin* OldThenPin = Node->FindPin(UEdGraphSchema_K2::PN_Then);
    check(OldThenPin);

    UEdGraphPin* NewThenPin = CallFuncNode->GetThenPin();
    if (ensure(NewThenPin))
    {
        // Link Set Node -> Notify
        NewThenPin->CopyPersistentDataFromOldPin(*OldThenPin);
        OldThenPin->BreakAllPinLinks();
        OldThenPin->MakeLinkTo(CallFuncNode->GetExecPin());
    }
}
#

Which I might be right with

#

UK2Node_VariableSet* SetNotify = Cast<UK2Node_VariableSet>(Node);

#

Doesn't explain why the replication of the array doesn't trigger it though.

ashen scroll
#

I should have expected that I'd have just as much trouble making an inventory system in Multiplayer than I had with making it in Unity last time

#

Hopefully will take less than 2 months this time

thin stratus
#

To be fair, you are doing it in Blueprints, which is significantly more annoying.

#

And the way to do a more robust Inventory for Multiplayer isn't even available to BPs.

quasi tide
#

Also, maybe you're trying to run before you can walk.

ashen scroll
#

But I mean, the AI work for multiplayer I did wasnt easy either, though I imagine if I tried this right after I finished with that id have more success

pine sage
#

There is some inventory plugins available too. Not necessarly the best in town (never used one) but arguably something that would make your life easier.

#

Anything related with UI + MP is annoying (as in: hard to do at first, boring after)

ashen scroll
#

Yeah but those would be quite rigid

#

Even if they suited my needs mostly, couldnt modify them afterwards could i?

quasi tide
#

You get the source code

ashen scroll
pine sage
#

And you could look, and replicate too ...

quasi tide
pine sage
quasi tide
#

You're not going to escape C++ in UE

#

At least in multiplayer land.

ashen scroll
#

Yeah but at least for this I wouldnt like to do it

#

I already started the project in blueprints

quasi tide
#

So?

#

It is trivial to convert to C++

#

Go to Actor at the top > Add new C++ class

#

There. You now have a C++ project

ashen scroll
#

I have to admit, I havent used C++ in Unreal before thats the main reason I dont want to

pine sage
quasi tide
pine sage
quasi tide
#

It's not like raw C++

#

It is C++ on rails

#

Just stay within the confines of UE's framework and it is like writing a crappier version of C#

ashen scroll
pine sage
#

And understanding basic C++ is easier than looking at BP code too.

quasi tide
ashen scroll
#

I mean C++ is really simmilar to C# which I know well

quasi tide
#

That's certainly a take...

ashen scroll
#

Not in Unreal that is

pine sage
quasi tide
#

Raw C++ is like...nothing like C#
Using the rails and the stuff that UE set up for C++ in their ecosystem is sort of like C#

pine sage
quasi tide
#

Either way, that is getting away from the main thing - C++ in UE isn't as bad as people may think.

ashen scroll
#

I suppose I have to start using it anyways

quasi tide
#

Yes

pine sage
#

And understanding C++ / replicating it in BP is not that hard either, except for the part you can't do.

quasi tide
#

If you want to avoid C++, you'll end up having to rely on 3rd party plugins that fill the gaps for you.

#

And I can't say I've ever seen a half decent inventory plugin to be honest

ashen scroll
#

Honestly my thought process was "Inventory, aha, UI, UI is good with blueprints, I will do it in Blueprints"

quasi tide
#

You still can do the UI in BP

#

UI just reads from gameplay code.

ashen scroll
#

Yeah fair enough

thin stratus
# ashen scroll I suppose I have to start using it anyways

Let me tell you, with by now 11 years of experience with UE, if you want to create a Multiplayer Game, you need to use C++ in Unreal.
There are way too many variables, functions and classes that aren't available in Blueprints.
As well as almost no control over bandwidth, let alone the abysmal performance overhead of Blueprints.

#

And "need to use C++" means Core Logic in C++, more script like stuff in BPs.

#

Even UMG Widgets are a lot easier to just write in C++, make UTextBlock a BindWidget variable and then design them in BPs.

ashen scroll
thin stratus
#

Yeah that's up to you. Moving all your BP code to C++ is a lot of work.

quasi tide
pine sage
#

+1

thin stratus
#

I currently have to fix load time in a project that leaned too much into BPs for their Multiplayer Game.

#

It's really bad...

#

60s+ load time of the editor.

pine sage
#

Ouch.

thin stratus
#

Cause all those BP assets are referencing each other through BP Cast nodes

pine sage
#

Talk about an interesting task.

thin stratus
#

SizeMap of the almost empty test level was 3.2GB last week.

quasi tide
#

Oh, okay. So not a BP issue, a poor coding standard issue.

thin stratus
#

I cut off 1.4GB by now.

quasi tide
#

At least in my book.

thin stratus
ashen scroll
thin stratus
#

You can make a lot of stuff SoftRefs, but once you need to access properties or functions, you gotta cast.
And either you litter your project with Interfaces or you live with it.

ashen scroll
quasi tide
thin stratus
ashen scroll
#

The approach I would have chosen if widgets could be replicated did involve a bit of casting but i minimised it at least, was on start too

ashen scroll
ashen scroll
#

well for the time being, think I will leave this on the back burner for a bit

#

Find something else to work on until the game jam next month

#

Not making a multiplayer game however..

vapid gazelle
#

Any suggestions about ways to see what the state of an animation is on the dedicated server? E.g. say you're server-authoritative and the server needs to play animations in order to compute collisions correctly rather than just having a T-posing mesh. Is there a way to somehow see what that animation looks like on the dedicated server?

I remember seeing videos from the VALORANT team that show them displaying the server's collision mesh somehow, overlapped with the one that clients see, but I imagine that doesn't come out of the box with UE.

teal frost
rustic sable
vapid gazelle
thin stratus
#

Unless you mean ServerRPCs to tell the server to set some replicated variables, although even that is questionable

thin stratus
#

There are games that don't run animations on the server at all

#

There you usually need to approximate the hit location

#

Other than that, I don't think there is a visualizer in general. You could try to open the animation blueprint and select the server's version in the debug drop down

#

That might display you the looks of the character in the preview of the animbp

teal frost
# thin stratus Unless you mean ServerRPCs to tell the server to set some replicated variables, ...

In my experience, setting a variable on the player via input alone/on client - while just having the variable set to replicated, then pulling that variable from the animbp, results in it only playing for that client and not replicating the current state to all other clients. But setting that variable on the server or mc (i think) as well properly replicates the current state to others (could be doing something wrong though. I relatively recently started really learning animation stuff)

thin stratus
#

You use ServerRPC for anything the server can't know about. Such as the input pressed for firing a gun.

In theory also for jumping but that is already handled via a server RPC in the character movement component.

#

Starting an interaction, like pressing a 3d button or lever can be an RPC too

teal frost
#

I think there is a communication disconnect here...

#

Give me a min, I'll make ss of what I mean

thin stratus
#

Sure. I mean you wrote that a replicated variable used in the animbp (presumably the variable is in your character) to drive it doesn't work for all clients so you also Multicast the value on top of that.

#

Maybe I misunderstood

plain bramble
#

hello, for player inputs whic being sent to server it all must be reliable ordered or unreliable, i am afraid that some important inputs like jump/fire/reload wouldn't received by server

#

and then when server broadcast them to other clients, it also should be reliable or not.

haughty ingot
teal frost
# thin stratus Sure. I mean you wrote that a replicated variable used in the animbp (presumably...

Sorry it is taking so long, family apparently decided I shouldn't have time for it lol. Also kind of got sidetracked by a new rabbit hole while hastily throwing this together lmao.

But in general what I'm saying is this would not work (first 3 ss)to replicate animation state to other clients to display the correct animation. (dunno if this was me misunderstanding.. but if you meant to replicate variables inside the animbp, that is fine if you're using event blueprint update, but if you're setting variables the alternative way through blueprint threadsafeupdate, you can't replicate the variables)

Anyway, to my understanding you would need to make at least a server call to set the pulled replicated variable in the player character or wherever you're pulling that data similar to the last ss.

thin stratus
#

So the Dodge Boolean in the AnimBP doesn't need to be marked replicated

teal frost
thin stratus
#

You have to have the replication happen in the character

#

Na just commenting on the screenshot

#

But the RPC is right to be needed to tell the server to set the Boolean

#

Cause variable replication only goes from server to clients

#

But yeah guess miscommunication. It sounded like you wanted to Multicast the change on top of that

teal frost
# thin stratus Na just commenting on the screenshot

I understand, I changed it to replicated for the ss lol cause I was confused on wording, so i set it as such for the "bad example". This is how I had it set up before changing to montages. I'm bad at wording this stuff sometimes. Really need to work on that somehow. In most other things I do I don't have this problem 💀

sturdy sand
#

Hi. So I'm running into issues with editor details not showing an objects content (it just shows blank for some reason). Now I'm posting this message in the multiplayer channel because this problem only happens when I'm in multiplayer (playing as a client) and everything goes as it should in singleplayer. Here's the related to the problem code: https://paste.ofcode.org/9Jyc7VaZNmUET6hLNuZSjj this is an inventory system and the nested containers inside the collectablebase is where the problem rises. I'm cutting some pieces of the functions that are not related to the problem. Thanks!

#

The blank object details:

#

this is how it supposed to look like:

fossil spoke
#

@sturdy sand Try changing the UPROPs from VisibleInstanceOnly to EditAnywhere

sturdy sand
#

Unfortunately that did not fix it.

steep island
#

Hey, am not sure what I am doing wrong, I am trying replication for the first time in UE5, still learning as I go using the network compendium resources and whatever else I may find.
Basically, when I fire a projectile on the client instance, then it works fine, projectile fires, hits other player which is the host, does damage, HUD gets updated, however the moment I shoot from the host aiming at the client I get double hits for some reason, I suspect it's do with the shooting logic, but not sure how I can fix it.

steep island
#

Just posting it

#

The idea behind it was to reduce the input lag for clients when they shoot so they don't see that delay between button presses.

#

Line traces I reckon would probably be easier but I do want to use projectiles from time-to-time.

steep island
chrome bay
#

Anybody know, if you spawn an actor and call a reliable multicast instantly, are clients tat actor is immediatelly relevant for garaunteed to receive that multicast in the spawn frame?

#

Rarely ever use them but might finally have such a use case

nova wasp
#

I think with Iris I would try following the reliable attachment path if it can't resolve the object locally yet

#

but I'm not entirely sure... like would it stop the entire reliable queue for that net object to be sent forcibly?

#

I would rather rely on an OnRep that makes the actor start being visible + usable without having guarantees that net init and this rpc are together but I doubt you can get away with that

chrome bay
#

non iris in this case

#

The onrep is tricky, it's a pointer to another actor, but that actor needs to be destroyed

nova wasp
chrome bay
#

Unrelated really, the second actor is "replacing" the original one but the idea is to have a seamless transition on the client, which is obviously quite tricky. I've done it before but it's been a bit reliant on timers and whatnot which just isn't that clean

nova wasp
#

I think there's no guarantee the rpc and the bunch with the new object spawn are in the same packet is there

fossil spoke
#

Why do you need the RPC? Shouldnt the fact that the Actor is spawned on the Client be a substitute for the RPC?

#

Is BeginPlay not sufficient?

#

On the Client side?

nova wasp
#

yeah I'm confused as to what the RPC has to say here that the new actor doesn't know in net init

fossil spoke
#

Im guessing you want to pass some data along as well? Just add that data into a rep var?

nova wasp
#

I think you could just abuse TearOff rules to allow there to be an interstitial state

#

where one can come before the other

#

I have done this in the past to stop local destroy to not happen until we are okay with it

chrome bay
#

Yeah currently that's what I'm doing

nova wasp
#

who needs this to be perfect? the player it's for or close or everyone?

chrome bay
#

Original actor is torn off, but, it still has to be a replicated property on the "replacing" actor so that actor knows when it can replace the torn off one (need to receive the tear-off first)

nova wasp
#

what artifacts occur if they aren't perfectly swapped in one frame?

chrome bay
#

So the dilemma is I can tear the actor off server-side, but I can't destroy it instantly, because then it could reset the "source" actor property on the actor replacing it, and that actor could take a while to be received. Timers are really the only option without some kind of really cumbersome ack protocol but it's just a bit grim

nova wasp
#

feels like you have two properties needed here

#

and to only fill the second field locally once it's transitioned and has all needed replicated info

#

also hard for me to judge without knowing exactly what the transitition does

chrome bay
#

It's switching from an "alive" vehicle to the "wreckage" of it

nova wasp
#

oh rip... yeah that would be NASTY to make invisible instantly

#

big pop in if it misses

chrome bay
#

Yeah... it's just grim. I've gone back and forth on just destroying as many components and whatnot on the original vehicle as possible, which might still be an option.

nova wasp
#

I think I would prefer to just bonk the original network object

#

it can tear off all of the useless "alive" components afaik

chrome bay
#

Well this is extra fun, I noticed that if you destroy default subobjects (replicated or not), and the actor leaves + comes back into relevancy range, the clients still have those component loool

#

Which I kind of expected.. but also.. ffs

nova wasp
#

I mean yeah it literally just spawns it I guess lol

chrome bay
#

yeah

nova wasp
#

I guess you could make them optional subobjects by hand... ugh

chrome bay
#

And there's no record of that stuff being destroyed, so it just becomes painful

nova wasp
#

Each day I get closer to describing each game object as one struct with some uint8s

vocal quail
#

Can someone tell me why GetCurrentAcceleration from CMC gets normalized when replicated to other clients?

nova wasp
#

as of 5.5 the default impl uses the cvar p.EnableCharacterAccelerationReplication

nova wasp
#

which is off by default

dark edge
#

fuck

#

i was looking for like 10 mins lol

nova wasp
#

I was confused by the root motion one

#

for a few minutes there... so same lol

dark edge
#

I'm confused by this

#

github doesn't find CharacterMovementComponent.cpp

nova wasp
#

github search is honestly just not reliable at all

#

it's gotten a bit better but it just sucks especially for commit searching

dark edge
#

I find it pretty useful for trying to figure out where the hell something actually happens

#

like if I don't know where to start

#

but if I do know where to start I just cruise through definitions in my IDE

nova wasp
#

you just need to have a local engine source in some IDE that can eat 1 million files

dark edge
#

what i like about Github is finding someone else who's tried to do a thing before

#

Like I found this when digging through contact modification stuff and there's all sorts of great code in this project

fervent delta
#

I have an issue with 5.5 replication of an array of UObjects.
The array is updated and replicated to the client when a new item is added to the array

UPROPERTY(BlueprintReadOnly, Category = "Inventory", ReplicatedUsing = OnRep_InventoryContents)
TArray<TObjectPtr<UBGM_ItemBaseObject>> Replicated_InventoryContents;

The ItemBaseObject has FORCEINLINE virtual bool IsSupportedForNetworking() const override { return true; };
And the property Replicated_Quantity is set to replicated

When I add an item to the inventory array I call

    AddReplicatedSubObject(NewItem);
    Replicated_InventoryContents.Add(NewItem);
    MARK_PROPERTY_DIRTY_FROM_NAME(UBGM_InventoryComponent, Replicated_InventoryContents, this);

and this is replicated correctly. but if I want to change the quantity of an item in the array the client does not receive this update until the array contents is changed and OnRep_InventoryContents is called, If I manually call OnRep_InventoryContents this only runs on the server since all functions are ran on the server.

Ive thought about calling a client RPC to tell it to update the quantity at the index but I do not know if this is the right way to go about it.
Both the inventoryComponent and the UObject have virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const override; setup correctly

nova wasp
#

you probably want to use a fast array, no?

fossil spoke
#

Pretty sure you just add the Array, instead of the new object itself?

#

AddReplicatedSubObject is wrong, is what im saying.

fervent delta
#

Oh really

fossil spoke
#

I dont use UE5 so I cant specifically answer.

#

In UE4 you just use this.

#

WroteSomething |= Channel->ReplicateSubobjectList(ReplicatedAwards, *Bunch, *RepFlags);

fervent delta
#

yeah its changed since

fossil spoke
#

Passing the Array.

fervent delta
#

Thanks for the input guys, Ill check out both ways

fossil spoke
#

Is there a AddReplicatedSubObjectList variant?

#

That you pass an array into instead?

nova wasp
#

GAS just does

        if (IsUsingRegisteredSubObjectList() && IsReadyForReplication())
        {
            AddReplicatedSubObject(Attribute);
        }
#

for every new element

fossil spoke
#

Fair enough

nova wasp
#

fwiw the fast array must also be a replicated subobject marked somehow

#

depending on settings

fervent delta
#

Yeah im abit unsure on fast Arrays, thought there was only TArrays. looking through documentation now.
Otherwise i might have to use the onrep_quantity update from the item itself to let the inventory know the quantity has changed and I dont wish to do this

fossil spoke
#

There is likely some quirk about it thats missing.

#

You shouldnt have to do that.

#

You also shouldnt have to use a Fast Array for an array of Objects

fervent delta
#

Ok thank you 🙂 its good to know that, I will keep looking!

fossil spoke
#

A FastArray would be better suited to Structs in this case.

fervent delta
#

to be fair an inventory item would be better as a struct but the items will be holding gas info

fossil spoke
fervent delta
#

Oh cheers ill check it out, even just to learn from

fervent delta
#

ah figured it out, If updating a objects property which is replicated, the OnRep for the array will not be called since the array has not technically changed.
I made a function to log the inventory contents and quantity. After setting the quantity of one of the inventory items I called a client RPC which ran that logging function
The quantity of items on client was incorrect, server was correct.

But If i called the logging function from the OnRep_Quantity from the object itself OwningInventory->LogInventoryContents() it logs the correct info. No idea why (client and server) Guess ill just call the UI update message function from the inventory item onrep seems a bit odd but eh

haughty ingot
fervent delta
#

@haughty ingot true, just have the array of subobjects and not replicate it. since they themselves are replicated. 😄

haughty ingot
#

You’ll just have to add them to the array manually when they’re created on each connection that cares. But that’s the idea

#

But just an option

pseudo wagon
#

If I want to teleport actor, does I need to turn on replication movement in actor?

upbeat basin
split siren
#

I have a team-based replication using Iris. Where is the best place to manage the team replication groups?
I am considering 2 options, in GameMode or in custom UEngineReplicationBridge.

crisp galleon
#

Hello there, do someone know if it's possible to test a multiplayer game with AI that simulate real player? I mean that the AI must be considered as a client and not only simulated on the server.

upbeat basin
#

AI is considered as a player, as it's controlled with AAIController (inherits from AController, same parent as APlayerController) and has a pawn in possession and even can have a PlayerState if you enable it. But it's not considered as a client, since server has the authority over AIControllers and everything owned by them

#

So basically they are some replicated actors that have no owning connection by any player client

split siren
upbeat basin
#

Ah wait I think I got what you mean just now

split siren
#

In my case I had just simple running around, jumping etc to test CMC (the replication data usage of it)

upbeat basin
#

Or I'm not sure, are you trying to control a pawn that is owned by a PlayerController?

crisp galleon
split siren
#

Depends on which part you want to debug, if you need to see the network traffic, packaging it and spawning multiple client processes with a "--aiclient" flag (or whatever flag name you choose) and 1 server is the cleanest way I found. You can easily automate it with a script.

crisp galleon
#

I didn't know that, did you found this info on documentation?

upbeat basin
#

Ah okay, yeah I totally missed the case and don't have any idea about it

split siren
#

Not sure about docs, but the logic is
package your project for client and server

  • run server (headless)
  • run x clients (headless) with a flag that triggers your "AI logic" in PC
  • inspect the traffic
#

I like to run the server from IDE directly, just in case there is a crash

#

Or you can do it without the flag to always run the AI logic in PC.

crisp galleon
#

Thanks you very much, i'll try it

split siren
ornate moat
#

i should use Multicast only on things should effect the server inplicit?

i have a UI menu, wich i believe i don't have to use multicast just open the ui?

Exemple : Begin play -> Multicast SRV_UI -> SRV_UI -> create widget... -> add to viewport

cinder orbit
ornate moat
#

i've had that fear whenever i pickup a exp drop / item from ground, somehow to not acumulate

thin stratus
# ornate moat i should use Multicast only on things should effect the server inplicit? i hav...
  • UI is Client side only, it shouldn't be created on the Server
  • You should use RPCs if you want to execute one-time events on either Server, Client, or everyone
    • Rules apply to which RPC you can call where
  • BeginPlay, for example, doesn't even need a Multicast if it's either a replicated Actor or one that is placed into the scene
    • BeginPlay calls on every instance, so it will already call on Server and Clients. It's actually the opposite that you would need to limit it to Clients, or the owning Client specifically depending on the Actor, to not have the Widget be created everywhere multiple times.
    • BeginPlay can be too early to use IsLocallyControlled in a Pawn/Character, as it might not have a valid Controller yet!
ornate moat
#

that's why i asked

ornate moat
#

Thank you so much

#

i have this Scene, where there's a BeginPlay Event that's casting to the BP_Humans, wich add the Widget, but if there are 2-3 clients, it's getting more UI's one on top of eachother, is there a easier way to do so?

Casting to playerController or idk.

ornate moat
#

@thin stratus Sorry for the ping,

if there's a Event BeginPLay in the MAP, with a add to viewport, that event gotta happend to all of the players, 'aight?

#

and they will overlap

blazing spruce
#

Hi, i know the player array on game state is managed automatically, but i can still manually remove something from that array if i need to cant i?

quasi tide
#

Sure, why not? It's locally constructed.

blazing spruce
#

Okay good was just checking in case i fucked something up lol

quasi tide
#

I don't know why you would want to mess with it personally, but you can.

blazing spruce
#

its too slow at removing an exiting player, on logout fires quicker than the player array updates and im using bp's so im limited to the override events i can use ofc

#

my only concern was if i remove the exiting players player state from the player array manually on logout which happens first, then because its still updated automatically it'll try to remove a player state that now isn't there because ive removed it manually, could that kick up errors or would if fail quietly

thin stratus
#

You mean the LevelBlueprint?

ornate moat
#

Yes

thin stratus
# ornate moat Yes

LevelBlueprint exists only once per Map (also not really the place you should put much logic, if any). BeginPlay would call once per Player (incl ListenServer) and DedicatedServer. The Widgets wouldn't overlap, but if you use a DedicatedServer, then you should filter that one.

surreal plaza
#

Has anyone had issues with steam returning duplicate sessions when using FindSessions from the OnlineSessionInterface?

bright summit
quasi tide
haughty ingot
# bright summit Don't wanna take your time but I have to ask because I do not understand this st...

Honestly, the reason people recommend avoiding the level blueprint for logic (even for smaller maps) is because it can quickly become messy and hard to manage. If you’re doing something simple like “button A opens door A,” yeah, it works fine. But the second you start adding more complexity—like multiple doors, interactions, or reusable mechanics—it becomes a nightmare to debug or reuse.

The big issue is reusability and maintainability. Let’s say later you decide to add a second map with a similar button/door setup. If all your logic is in the level blueprint, you’re basically stuck either copy-pasting it or re-creating it from scratch. Instead, if you use actors/blueprints with self-contained logic (e.g., a “Button” BP that sends an event to a “Door” BP), you can just drop them into any level and they’ll work. No rework needed.

bright summit
haughty ingot
#

Gamemode is an AInfo

bright summit
#

Ah ok

haughty ingot
#

And game state

#

I think player state too but I could be losing it and I can’t look

#

It’s just an actor that has no bounds, and is not calculated in the world bounds computation

bright summit
#

Ok, thanks for explaining

thin stratus
#

With C++ you can do more with the level blueprint. You can also provide your own class and what not.

#

But people often fall into the trap of using the LevelBlueprint due to being able to reference actors in it more easily.

#

And then they start copypasting that stuff into the next, and the next and the next level.

#

If you know what you are doing and you have a valid reason to use the LevelBlueprint or the LevelScriptActor, then you can do that.

#

But when I wrote the other person my assumption was that they are not at a level where they should fall back to it.

quasi tide
#

Like, the movie director requires to be used in the level script if I recall.

#

So, it isn't like you can escape it per se.

bright summit
#

Yeah I think for my approach this is the best option, but I am not sure. I don't see any tutorials which would show advanced interactions in level between actors

quasi tide
#

But I also don't mess too much with the sequencer, so I could be off base on that.

bright summit
#

Still learning and don't know everything. Yesterday I noticed I can put sounds into Niagara

#

I was playing them separately XD

thin stratus
#

Only things I use the LevelScriptActor/LevelBP for:

  • Very specific stuff where I override it in C++ and extend it's properties and logic to be reused
    • E.g. I had a client once where the levels had an optional "360° Movement", where you could drive on walls etc. That was a boolean I exposed in the ALevelScriptActor (the C++ Class behind the LevelBP), so that they could mark the level as such if it supported it.
  • To expose simple and quick debug console commands in test levels. Events in the LevelBP can be executed via the console via ce eventname
  • To code actual tests with UE's test suite
#

Other than that, I probably never touch it.

#

"If Button A pressed, open Door A" is something I would always ode into the specific actors with exposed Actor variables on the Button to reference the Door.

#

Makes sure it stays reusable and doesn't really add any more work than doing it in the LevelBP

bright summit
quasi tide
thin stratus
#

And for 2. I try to not litter actual classes

#

If I wanted to have any events that stay around I would code them into the CheatManager.

quasi tide
#

Well, it is for quick n' dirty stuff. Otherwise, I do it in C++.

thin stratus
quasi tide
#

I just make a whole new event graph in the GameMode and call it like "DEBUG" or w/e

#

So it still stays separate from the rest of the stuff

thin stratus
#

Hm yeah

bright summit
thin stratus
#

Why though

#

The specific Actor will just implement the Interface function(s)

#

And do what it needs to do.

#

That doesn't change when using a LevelBP.

bright summit
#

I mean that when I create button actor I create OnPressed multicast delegate and then I can bind to it any logic I want in level blueprint

thin stratus
#

Yeah and I simply have a Pointer or an Array of Pointers exposed to Instances, and then reference whatever I want to modify in them and call an Interface Function on those when the Button is pressed.
The Actors then implement the interface and do whatever they need to do.

#

Button doesn't need any extra logic, despite handling its own state (in case it can do more than just get pressed) and calling the Interface function

#

This really doesn't need the LevelBP at all. And can then easily be reused everywhere.

bright summit
#

Ok I get it

nocturne quail
#

What this complain is about?

12>   Creating library C:\ARMA_U5.5\Intermediate\Build\Win64\x64\UnrealEditor\Development\ARMA\UnrealEditor-ARMA.sup.lib and object C:\ARMA_U5.5\Intermediate\Build\Win64\x64\UnrealEditor\Development\ARMA\UnrealEditor-ARMA.sup.exp
12>Module.ARMA.1.cpp.obj : error LNK2001: unresolved external symbol "public: virtual bool __cdecl AWeapon::ServerSpawnBulletWhenSighting_Validate(struct UE::Math::TTransform<double> const &)" (?ServerSpawnBulletWhenSighting_Validate@AWeapon@@UEAA_NAEBU?$TTransform@N@Math@UE@@@Z)
12>Module.ARMA.2.cpp.obj : error LNK2001: unresolved external symbol "public: virtual bool __cdecl AWeapon::ServerSpawnBulletWhenSighting_Validate(struct UE::Math::TTransform<double> const &)" (?ServerSpawnBulletWhenSighting_Validate@AWeapon@@UEAA_NAEBU?$TTransform@N@Math@UE@@@Z)
12>Module.ARMA.5.cpp.obj : error LNK2001: unresolved external symbol "public: virtual bool __cdecl AWeapon::ServerSpawnBulletWhenSighting_Validate(struct UE::Math::TTransform<double> const &)" (?ServerSpawnBulletWhenSighting_Validate@AWeapon@@UEAA_NAEBU?$TTransform@N@Math@UE@@@Z)
12>Module.ARMA.6.cpp.obj : error LNK2001: unresolved external symbol "public: virtual bool __cdecl AWeapon::ServerSpawnBulletWhenSighting_Validate(struct UE::Math::TTransform<double> const &)" (?ServerSpawnBulletWhenSighting_Validate@AWeapon@@UEAA_NAEBU?$TTransform@N@Math@UE@@@Z)
12>C:\ARMA_U5.5\Binaries\Win64\UnrealEditor-ARMA.dll : fatal error LNK1120: 1 unresolved externals
UFUNCTION(Server, Reliable, WithValidation)
void ServerSpawnBulletWhenSighting(const UE::Math::TTransform<double>& BulletTransform);
bool ServerSpawnBulletWhenSighting_Validate(const UE::Math::TTransform<double>& BulletTransform);
fossil spoke
#

You do not need to declare the _Validate function with RPCs

nocturne quail
nova wasp
#

also there is no reason to use the TTransform template directly... just use the short hand regular FTransform
using FTransform = UE::Math::TTransform<double>; // UE_DECLARE_LWC_TYPE(Transform, 3);

#

unless you are somehow inside of a template that can't use using

nocturne quail
fossil spoke
#

So remove the _Validate declaration

nova wasp
#

it's like the _Implementation wherre you don't declare it in your header, but the generated file

nocturne quail
fossil spoke
#

Yes

nova wasp
#

it IS declared in the generated header

fossil spoke
#

Because the generated code declares it for you

#

Same with _Implementation

nova wasp
#

unreal header tool makes them for you! this is just like how bp native events work iirc

nocturne quail
#

great, let me test it 😄

fossil spoke
#

Just as Megafunk pointed out

nova wasp
#

sometimes the parameters can be slightly different though and take arrays by reference

#

so if you still get linker errors read the parameters to make sure they line up exactly

nocturne quail
#

great it works after removing the _Validate declaration 😎 Thanks Friends for the lesson

fossil spoke
#

👍

vapid gazelle
#

Ok I'm confused. I swear NetMulticast called from cpp was supposed to not run on the server calling that function, and the server needed to explicitly call the implementation locally, but in Blueprints you didn't need to, it would run everywhere.

Now I look at the source and it looks like NetMulticast runs everywhere, identical for both cpp and Blueprints. Did I hallucinate this difference? I remember there was explictily something inconsistent between native and bps when it came to certain RPCs :/

latent heart
#

I think you're thinking of OnReps.

vapid gazelle
glacial berry
#

Does anyone have any tutorials on getting Chaos Modular Vehicles (ue5.5 new plugin) replicated? cause HOLY MOTHER OF GOD im going to throw my computer out the window.

dark edge
#

Doubt it, they're brand new

#

if the example project isn't working replicated then it's either not really possible or nobody has done it publicly yet

split siren
#

Is there any built-in way to debug Iris, more specifically filter groups? In RepGraph you could use debug actor to print buckets and the whole graph, but can't find any debug tools like that for Iris.

odd hamlet
#

Hi does anyone know how a connection string should look for a friend steam invite? if i send this connection string steam.76561198867930852:7777
it will give me this error : Warning: STEAM: FOnlineAsyncEventSteamInviteAccepted: Failed to parse connection URL

#

I don`t even know how should a connection string should look like, WTFFFF

upbeat basin
odd hamlet
#

i ain`t find this nowhere

#

Idk how to search it online:))

chrome bay
#

Simple suggestion would be to look at the engine source code, find that error, and see why you trigger it

odd hamlet
#

ah i am using C++

odd hamlet
#

source code of what ?

upbeat basin
#

Are you trying this manually? Accepting steam friend invite should join you to the inviter's session and you should be able to resolve the connection string from the session to connect, if it's not automatically connecting as well

#

There shouldn't be any need to know what connection string is

chrome bay
#

The source code of the engine. That errors gets posted from somewhere, you need to find where that is, then start debugging it and finding out why it fails

#

Took a few seconds

odd hamlet
odd hamlet