#multiplayer
1 messages · Page 233 of 1
Although looking at the print strings Client 1 reduces the HP bar but the server isnt registering any actual damage.
Because the client isn't telling the server that it is trying to do damage
as the health is still printing 900.
This code is running on the client. It is not doing any kind of server RPC
I,ve tried multicasting, Run On Server, Switch Has Authority and cant get any of it to work xD
im being dumb probably xD
You just are missing the fundamentals.
Depending on where you called those, depends on if it works or not
So, for simplicity sake only - do this
- Create an event that is Run on Server and it expects the BP enemy
- Inside of that event, do the damage
- 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)
So would I need to change DealDmg to run on server to receive damage from a PlayerCharacter blueprint?
Ahh
You can only call server RPCs on actors that you have network ownership over
You basically need a run on server event inside something the client owns (typically playercontroller and pawn) to tell the server ANYTHING
Ohh so an AIController cannot send requests to the server?
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
Just do the 3 steps I outlined above
No point because AI logic is really only ran on the server in a vast majority of cases.
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
That will do it
The biggest thing to wrap your head around is the fact that your replicated actors exist on MULTIPLE COMPUTERS
And its not made clear that trying to call a server event inside an non-human controller player is not really possible.
your character exists on your computer and on the servers computer
I understand that each client has their own "copy" of actors which they interact with
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
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
the host is server AND a client effectively in a listen server context
Yep
in Unreal your mediation basically happens in aggregate through all the networking setup in all the actor classes
you don't have 1 thing that does the communication for you, each actor class encodes its own communication technique basically
People do the equivelent of that sometimes, just having some NetworkManager actor that shuttles data around
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 🙂
The venn diagram is the best little cheat sheet
I,ve seen that quite a few times as well
I have it saved 🙂
thank you !
So based on that diagram each PlayerController would own their own copies of the AIEnemys ?
each CLIENT would
the circle is each computer
This isn't true
I meant you would interact with the copies of the Actors the clients own inside their respective controllers?
Client's do not have ownership of the AIEnemy by default
Yes, but he said "own"
oh i didnt see the own
They don't "own" their copies
yeah no ownership
Maybe "own" is not the right word 🙂 the server is king i learned.
ownership and "it exists on my computer in my version of the world" are different things
server would own the enemy pawns, but clients would see their own copies
ownership is what you need to have to fire a server rpc through something
say you wanted to go open a door
Ah ok so the server owns the AIController enemys this makes sense now thank you!
input -> rpc inside your pawn -> door.open would work
input -> rpc inside the door -> door.open would not
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?
since you don't own the door
That makes sense!
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
That makes more sense to me now many thanks!!!
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 -
- It does hit/knockback prediction on client and if something is mispredicted then it rolls back its state
- 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.
yes there are examples, though lockstep and rollback aren’t the same thing
i think rollback netcode is a part of lockstep model
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.
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
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 🥶
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
Is there any recommended reading/watching I could do to learn more about this? Would love to make this decision with as much information as possible.
Getting character and physics to play nice in multiplayer is a very very tall order.
You basically have 2 physics engines at that point, with 2 different philosophies, with networking.
Say more about the 2x engines and philosophies bit, if you don't mind?
You can think of character and the character movement component as a physics engine that moves characters around. And then you've got a global physics engine that that moves everything else. And you have interaction between the two.
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.
What does no prediction look like in practice? The 2+ instances of the game simulate everything locally and don't bother reconciling it?
No prediction means you see everything exactly as it happened on the server.
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
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
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.
So how does source do it? Or specifically, Garry's mod. I have like a thousand hours in Gary's mod but I haven't played it in a very long time. I don't recall if it had physics prediction for non-character things
more like stuttering, but yea basically that
Nah you can get it butter smooth with the built-in tools.
The stock replication settings are insanely strict though.
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.
what I mean is if you disable prediction, the server has complete authority over your movement with no client-side smoothing, so you will see a lot of stuttering with most movements even at 0 ms
it gets a lot more prominent at fast speeds too
You have client-side smoothing. The client is doing all the physics too, it's just if it diverges from the server authoritative state too much, it gets hard corrected. Otherwise it gets soft corrected continuously
I'm not too sure, but Valve made liberal use of the Havok physics engine + their own skill to make things work
Is it possible to define custom network emulation profiles?
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?
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
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?
it replicates the path, and synchronously loads it unless you have the cvar enabled that makes that async instead
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
and that's enabled in Lyra I just remembered. net.AllowAsyncLoading=1
tyvm. I'll pull on this thread.
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.
Found this but the flow ends once the PC actor has been replicated. Not sure if it's a good idea to override OnActorChannelOpen for this purpose
https://dev.epicgames.com/community/learning/tutorials/vwYb/unreal-engine-client-connection-flow
Last resort was just to have the server request it after the player logs in
@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.
Is there a reason to go with GenericPlayerInitialization and not PostLogin? Something like the PC not being replicated on the client side or something?
PostLogin might be to early.
Also
GenericPlayerInitialization is called for both forms of travel.
Where as PostLogin is only called once.
So keep that in mind.
For those hosting a dedicated server in AWS, which instance do you use and why?
You would use whatever instance suites your particular games performance needs.
Generally speaking it will typically come down to CPU.
How many executables of your game can you run on a single instance.
I was in a t3a.medium and with 40 AI characters and 2 players, my CPU was 92%.
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...
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.
if you're using characters for ai it's almost definitely that
ServerTravel doesn't take extra options into consideration as far as I know. It's for changing the map as a server, rather than opening a map as a server. You should use UGameplayStatics:OpenLevel() or UEngine::Browse() first to give your listen option
ServerTravel does process extra options. Just that listen is not relevant for it.
Didn't know that, thanks for correction
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".
xD I did something similar but answer is no - you shouldn't do things like this
danm it 😂 god danm race condition is kicking my ass man lmao
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
GameState have AddPlayerState and RemovePlayerState functions which you can override to do something when someone joins or leaves. AGameStateBase implementation of these functions are where PlayerArray is being updated
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
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
That's a lot of RPCs in my opinion. You would want to prefer replicated variables or already build solutions instead of RPCs
I'm def open to a better way of doing it as long as i can get it working lol
Yes those are only available for cpp, you won't have most of the proper solutions with BP only
Does that include 'listening' for OnReps?
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
Like a dispatcher?
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
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.
I'd still support going with BP as a demo/learning project
BP-only can use BeginPlay and EndPlay of the PlayerState fwiw
Been trying to avoid using c++ as long as possible lmao
If i have to ill do it ofc
Shitty idea :P
Do Singleplayer then
too late for that 😂
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.
Sounds fun 
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.
This is what I mean with "proper". If you want to release the project at the end, BP only will end up with lots of performance and/or network issues
Or you piggy back of the events that already tell you that something specific is valid, like BeginPlay.
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?
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:
- Get the Current Value (if possible)
- 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.
Hey, I am learning c++ and I get this: what is the issue here?
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.
Please try to compile and share any errors from your output log instead of just the hinting.
Also this is #multiplayer and not #cpp
Also #cpp
thx sry 🙂 I assumed as its a multiplayer c++ thing it would be fine here too ill go there now 😄
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
Yeah I'm totally with you. I'm just tending to be a bit more drastic in telling people to use C++ for Multiplayer, cause otherwise they will be lured in by "Oh yeah, you can probably do that. Just try." blabla, which in the end will fail.
ConnectedPlayers doens't help much. The Array is probably in the GameMode (Server only) and the PlayerControllers in them aren't even available on Clients.
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.
Perfect, gonna give these a try and see how i get on lmao thanks mate! and thanks @upbeat basin
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
hey i need help can we use lyra for mobile game dev
or how can i set up this for mobile anyone know?
What am i doing wrong here? with this it now works for the client and doesn't work at all for the server, in fact when the player starts hosting a session which loads the pre lobby level, the begin play on the player state where im casting to the game state just after the has autority switch is failing
Not sure if you can help here either mate? @upbeat basin
You don't need to keep track of the playerstates that are in the game yourself. There is a "Player Array" in the gamestate already that does this which is managed locally on all machines.
You can utilize the begin play of playerstate to trigger an event dispatcher in the gamestate which can happen all locally as well.
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.
Sorry, trying to understand this but my brains a bit frazzled been stuck on this for days 😅 so from my images, is what I'm doing on my player controller's begin play fine first of all? When you say my widget construction are you talking about the widget being created and displayed from my player controller or the widget i create to show the player name cards?
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.
Okay so ive updated most of it, is this correct? i haven't done the Player Card widget yet because the OnPlayerLeave dispatcher is on the GameState not the PlayerState, should that one be in the PlayerState instead?
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.
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
@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
Ah gotcha 😛
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
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.
Nice one thanks for that mate, I've added that in and now its only creating the one player card for the host and then one player card when a client joins
Any ideas of getting the name showing tho?
What does this mean
how do i get around that so the name actually shows?
Client's seem to see the names just fine, but server doesn't, only their own name shows
Are you setting the name just once when the entry gets created?
Widget entry that is
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:
- Have something that calls an event dispatcher when the PlayerName gets changed (requires C++ I believe) that your PlayerCard widget can then listen for.
- 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.
- 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.
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
Will give this a go, was also trying to avoid binding a variable because of that but you're right it is just for a pre lobby, once the game actually starts the pre lobby wont exist anymore at that point anyway
Yeah then it's due to the player name not being set yet
Do what Datura says it guess
Pretty sure a frame delay would also solve it
So Delay(0) before getting the name
I actually think there is a "Delay Until Next Frame" node now
😮 is that allowed 😂
i thought delays are a no no
Delay 0 is, if you know why you need it, totally valid
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.
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.
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.
Looping Timer and a Delay that is hooked up to repeat as long as something is invalid is the exact same thing.
Internally a Delay is just a timer.
yes but a delay is fixed duration
whereas the looping timer at least can be more flexible depending on the loading speed of the machine
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
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)
So it doesn't really matter. Timer or Delay, it's not the solution
Just loop the Delay then
Still bad solution
I think we're saying the same thing ya
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.
ya thats what I suggested to do instead
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)).
according to alvaro is delta on 5.3 and prior. anyone knows how to enable delta rep on iris?
https://vorixo.github.io/devtricks/atomicity/
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?
Appreciate your help mate, I've got it mostly working, the names are displaying correctly for the server now if I use that 'Delay Until Next Frame' node @thin stratus mentioned before setting the player name on Event Construct, still got an issue with the player card not being removed when the player leaves but most of its working now 🙂
I tried using this way to set the players ready status but it only seems to fire on the client, am I doing it wrong? if the client ready's up the server doesn't see it
Replication only happens one way, from server to clients. Your button click needs to RPC to the server through a replicated actor owned by the local machine, and the server then has to set the value.
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.
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.
You should not be concerned with things like that.
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.
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.
You mean your game is Listen Server
And you are using the built in replication system to transmit data.
we are using that for certain things, but direct packet communication using EOS's P2P interface for sending/receiving player inputs
Why would you do that?
The game is build around deterministic lock-step simulation.
there's no replication for game state
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.
🤷♂️
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
You should probably be asking this type of question in #online-subsystems or #epic-online-services
The EOS P2P API has nothing to do with Multiplayer in UE
Its entirely abstracted away
not asking about the P2P interface though
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?
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
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.
Shouldn't there already be a variable keeping track of how long Jump was held?
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.
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?
I've been working with UE for 11 years and I've been through the CMC and Character a bunch of times. I basically just know it exists.
haha sounds reasonable
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.
I see, so basically you just need those variables that already exist and u r good to do it on the UpdateCharacterStateBeforeMovement(float DeltaSeconds)
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.
In theory, yes
I would probably do it like this:
- 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.
- Based on the result of 1. call
Jump()or a matchingMantle()function that setsbPressedJumporbPressedMantleto true. - Use those the usual way via the Flags in the SavedMove to tell the Server what the Client pressed.
- Use
UpdateCHaracterStateBeforeMovementor similar to handle thebPressedJumpetc. booleans. - 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.
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
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)
I can't understand what you mean by this question
I mean client is not NetMulticast
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
use GetDebugStringForWorld
I guess this is becasue I am in the same process?
also please be specific with who is calling the function and what is receiving the call to _implementation
gamestate on server
I assume you mean that something is calling it and every client is receiving the rpc?
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.
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
Multiplayer is not a second layer you put on top of your game. Singleplayer code is worthless for it.
If you want a Multiplayer Game you will need to code all your stuff with that in mind from the beginning.
Is there anything against using replicated timeline components? Or should I replicate server start time and let clients trigger their components accordingly?
Eh I guess I'll fall back to the second option anyways, stopping a looping timeline doesn't seem to trigger OnStopped delegate
I wanted to polish the game (animations, projectiles and vfx, then project it to mp.)
you do MP from the very first second you write the game's code
if you plan on doing MP
What Olsson said. Multiplayer from the start, not later.
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
HasAuthority() && !IsNetMode(NM_Client) ..?
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
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
Did that ever work in multiplayer? Could totally be that the template isn't set up for multiplayer
Pretty sure that project wasn't set up to be multiplayer.
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! 🙂
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
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 ??
You can see it here what I mean.
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.
Ah ok thanks for the explanation!
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?
On construct you have to read the current value and adjust it based on whatever the curent value is.
Found out it was an issue related to GAS destroying the 2nd player's pawn (due to no HP or improper ASC connections etc).
This is the construct of the pre lobby widget that creates the player name card widgets, i thought where i was passing the player state into it and using that for the On Is Ready binding that would of done it but obviously not lol so which on construct do i need to do it on, the player name card widget one?
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
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
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?
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?
The actor itself has a location and rotation which is what can get replicated when you enable replicate movement. A physics simulation typically happens on a component of that actor, and if you happen to simulate physics on both computers then they'll both be running their own physics simulation which may not always line up with what everyone sees in a multiplayer game.
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.
That makes sense. I thought this was the issue, I tried to get the client and server to get out of sync with each other by tossing that actor around, but so far no luck, which is why I was puzzled about what exactly was going on. I might still encounter that issue, still early experimentation for me.
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.
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.
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:
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?
GAS doesn't do anything special for Cooldowns fwiw. Also a Multicast to notify about the STATE of a Cooldown might be something you want to rethink. State should be done via OnReps.
The way you can solve this is rather simple: Use UTC on all machines.
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".
Why does Fire run on owning Client?
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?
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
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.
correct me if im wrong, but i think it because the fire function is in the gun base class so its not an owned client. if i have this all wrong is there any better way of creating this system?
the fire function is being called from the player blueprint
Your Input for firing is local already.
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
can anybody relate to this 
Hi there. There is quite a lot of resources on gas in #gameplay-ability-system .
For instance, Narxim's (pinned) have a working example of showing gameplay effect on a UI.
Translating it to only capture CDs should be simple enough.
That's a thing. Uh!
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.
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.
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
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?
Pretty much
thanks for help!
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.
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
If neither get controller or get pawn from a controller works ... that means there would be an issue on your project.
Check world setting (should have a player controller there along the pawn) and how the pawn is spawned.
Controller is supposed to exist in server and owning client only.
Check onpossessed() methods on pawn / controller to see if they are fired ?
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)
#multiplayer message
Those and the other one on the controller.
Entire Code is in blueprints id rather not add C++ to the project, wouldnt begin play to the same thing?
Ok doesnt work in a fresh project either, this is weird, lets see whether GetPawn does
It should be quite straight forward. You could check how a template project does it.
Even with a template project ?
Yeah
Must have missed something with the set up
Hum. Can you show world config ?
I may have to ask a stupid question, how could I do that?
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
?
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;
}
use regex
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.
Wait I might have a solution
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
that controller 0 is your local controller but still you can use islocallycontrolled on character 0 or islocalplayercontroller for controller 0 before doing any local intended thing
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.
Yeah so it works but now the question remains, this is on an inventory system, are you even able to replicate Widgets? As in, their data - the output of a Create Widget function, I cant seem to find a way to do it
You need to RPC to whomever to tell them to create the widget
Widget's themselves don't replicate
oh what
Most UI communication gets routed through the PC
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
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
indeed, it doesnt work
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
Have the WidgetWhichDisplaysAnInventory know about what InventoryComponent it cares about, it'd have to get that from its parent or from what creates it, and then it can bind its update function to InventoryComponentICareAbout.OnChange
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."
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
kind of meaningless to just say "16 players" without what they are doing
The multiplayer system itself doesn't need optimizing. What you're trying to do over the multiplayer system is what may require optimizations in order for the engine to be able to facilitate what it is you're trying to do.
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
what about an rts multiplayer game with huge battles? then thats where it gets tricky
@nova wasp @sinful tree
there are quite a few different schemes for how to do rts games in multiplayer
Totally depends on what you actually need to go across the network
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
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.
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
https://horugame.com/ really good example of some of the extremes that people can take to make large scale RTS in UE.
Yeah, but scrolling through it tells the story of how much they had to replace.
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.
Ye, exactly
That's why I mentioned the extremes
Super interesting stuff in there
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?
yeah i guess that is probably the best option i got
thanks for the suggestion about OnChange tho
seems so obvious but I wouldnt have thought about it
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?
My hunch is that the rendering is more work than the rest put together
How many rotations does a character have in your desired system? Are you using the built in Character?
Im using characters I animated with mixamo. Its third person, so I only care about the yaw axis^^
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
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
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?
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
It's certainly expensive if you have a lot of SkeletalMeshComponents
Even in Singleplayer
How do you make multicast events on actors that have no owners? They seem to only run on server.
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.
🫡
variables marked as replicated aren't being multicasted.
Not sure what you mean being multicasted. The actor itself needs to be replicated too to have any replicated variables.
marked actor as replicates, somehow managed to avoid needing that on client owned actors.
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.
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?
How production-ready is that part of the engine at the moment? We're on 5.4 and I think it's still marked as experimental, if I'm not mistaken. Did it get much further in 5.5?
A lot of the bugs and weirdness I ran into in 5.4 are fixed, but apart from that link theres no real documentation or examples so its a bit hard for someone without networking knowledge like me to figure out
Ah nice. I had to disable it just a few days ago because we were running into issues like client player characters sending physics objects into the stratosphere by running into them with the new networked physics mode enabled. Took me a while to figure out what was causing that. But we're on 5.4 still.
Yeah pretty sure you'd have a lot more luck in 5.5, they released a lot of changes https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-5.5-release-notes#:~:text=different export settings-,Simulation,-New%3A
"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.
Hello! Did you find a solution?
Hey! Not as of now, had to focus other issue but once I get to it, and succeed, I’ll remember about you ^^
Have you tried Lyra's Common Loading Screen Plugin im using it and it prevents that issue that your taking about @magic hazel
Haven't but someone mentioned it, I will be looking into it ^^
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)
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
Thanks for the tip, but unfortunately even changing FLinearColor to another one doesn't solve the problem and the screen is still black.
It works to change color on project start, but not in loading to world
@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"
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?
You can change th3 number of player above yh3 menu whetr you select the mode
There is also a late game setting that is not enabled by default in your Engine Settings. It'll add a button to create a new PIE window for a new client. Makes testing late join stuff easier.
It should be under Editor Preferences named as Allow late joining
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.
@kindred widget @upbeat basin thanks a lot, that`s it🫶
it executes fine on the parent blueprint so I suppose its an issue with calling it on a widget which is less than ideal
If I understand correctly what you're trying to do is possible, assuming it's the event broadcast in the OnRep function and binding the delegate inside your widget or something similar. It feels like where you broadcast the event is not being run for clients, where do you do it?
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
This is on the slot widget
wait
it shouldnt execute on server
nvm still doesnt work
That doesn't matter how you mark your event replication in widgets, they don't replicate
Yeah I know
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
I believe not
Uh, I don't think EventDispatchers replicate even thought there is a checkbox for it
It didnt work when it had it switched off either
Probably because you're just broadcasting on server
You need the broadcast/call to be on every player
it shouldnt be on every player though
it should just be on the owning player
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
Could you elaborate
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
Its currently just the function for adding Stackable Items, will add it to the other one too
Oh
Wel
Well
I can't see anything from the pic but I guess you got my point
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
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
But that code is running only on the server, is it not?
What I'd suggest is making your ItemSlotArray RepNotify and calling your event inside the function
Well I cant do it that way, but i could store the values id send over with the delegate in a RepNotify
So the clients can be notified when inventory is updated, broadcast the event and update the widget accordingly
It's already replicated though, what's the issue with making it repnotify?
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
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
i want to try something else first, if that doesnt work i will try this
A client RPC could be a dirty last resort as well
On what blueprint?
ohh the inventory
like call that when i want to call the delegate
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
I am suprised honestly that there is not a clean way to do this
Well clean way is this for me
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
Well you're already doing it since the array is replicated, only difference is you'll state that you want a function to be called when that happens
The cleaner way would probably going with cpp to use FFastArraySerializer
well yes but now i am sending to an x ammount of slots too
That should be doing what you want, only replicating the changes instead of whole array
if i dont have to use cpp i will choose not to really
Those words can spawn a wild eXi any time soon
- Blueprint
- Clean Multiplayer Code
^ Pick one
If you want the proper proper solutions, cpp is kind of must
Oh you got Jambax from the wildcard
welp
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
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
It's more of a knowing when something changes problem rather than something specific to widgets
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
You still can't replicate your event broadcasts whether it's a widget or not
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
Should be called on any change. Sadly in Blueprint that literally means any change
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
@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.
oh classic
I always explained it to myself that the Set w/ notify node is the thing that actually triggers this
Right so I should try that next
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.
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
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.
Also, maybe you're trying to run before you can walk.
I wouldnt say so, sure maybe it was a while since I worked before this
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
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)
Yeah but those would be quite rigid
Even if they suited my needs mostly, couldnt modify them afterwards could i?
You get the source code
You can.
which is most likely in c++
And you could look, and replicate too ...
And?
Not always. You'd be surprise about the bunch of plugins only made in BP on marketplace.
Yeah but at least for this I wouldnt like to do it
I already started the project in blueprints
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
I have to admit, I havent used C++ in Unreal before thats the main reason I dont want to
Rather: There, you have a class and a C++ / BP project
It isn't as scary as you might think
Well, even if, looking at plugins, or looking at code and trying to replicate in BP is not a bad idea IMO
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#
That I find easier actually
And understanding basic C++ is easier than looking at BP code too.
Great! It isn't much different then.
I mean C++ is really simmilar to C# which I know well
That's certainly a take...
Not in Unreal that is
It's a coding language and there is a C in it. Come on! 🙂
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#
Hoping Cpp guys are not looking this way ...
Either way, that is getting away from the main thing - C++ in UE isn't as bad as people may think.
I suppose I have to start using it anyways
Yes
And understanding C++ / replicating it in BP is not that hard either, except for the part you can't do.
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
Honestly my thought process was "Inventory, aha, UI, UI is good with blueprints, I will do it in Blueprints"
Yeah fair enough
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.
Yeah I intended to at some unspecified point the future which was just an excuse not to tackle it yet
Yeah that's up to you. Moving all your BP code to C++ is a lot of work.
This 1000 times. Often people think "need to use C++" means that 99% of the game needs to be in C++.
+1
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.
Ouch.
Cause all those BP assets are referencing each other through BP Cast nodes
Talk about an interesting task.
SizeMap of the almost empty test level was 3.2GB last week.
Oh, okay. So not a BP issue, a poor coding standard issue.
I cut off 1.4GB by now.
At least in my book.
Yes and no, BP only can hardly avoid the reference problem.
Might need to ask a stupid question, but where do I even start, not as in how do I start learning it but when I get to fixing this specific project, what parts of the code would be ported over to C++ and what would stay in BP's, or is it a case where I will know myself after I start using C++
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.
Yeah I tried to avoid using casts as much as possible in the inventory system
Each project is going to be different in how you do the C++/BP split. So, that is just stuff you end up figuring out what works best for you.
You can usually see it as a Tree Structure, where the Projects C++ code, as a Concept, is the Root.
You would create strong base classes, keep all Enums and Struct definitions in C++, and at the leaves you would find your BPs and Widget BPs.
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
Yeah thats kind of what i thought, watched the Alex Forsythe video on BP's vs C++ a while back
Fair enough yeah
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..
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.
You would be better asking in #animation.
But in short, through replication.
You will need to ensure you're properly replicating the setting of those variables through RPCs on your character to have that state reflected to/from the server.
make sure you have this selected on your character meshes, this will ensure the mesh and sockets are updated on the server
Thank you! Discovered that one a few months back, very much essential 👍
Not through RPCs please. State is done with Replicated Variables, not with RPCs.
Unless you mean ServerRPCs to tell the server to set some replicated variables, although even that is questionable
That collision mesh stuff is usually done by just telling the client to show the debug drawing based on an agreed upon timestamp
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
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)
Yeah no, state is always meant to be done via a variable. If you need a function to call when the variable replicates you use an OnRep. RPCs are only for one-time actions that anyone who missed them doesn't need.
If you RPC a value that makes the character visibly crouch and someone joins the server afterwards, they wouldn't see the change.
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
I think there is a communication disconnect here...
Give me a min, I'll make ss of what I mean
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
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.
It really depends on how important the inputs are, or what they’re used for
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.
Yeah I think we mean the same, but also gotta say you can't replicate variables inside the AnimBP at all.
So the Dodge Boolean in the AnimBP doesn't need to be marked replicated
I meant setting it in general, sorry.
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
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 💀
Yop makes sense
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:
@sturdy sand Try changing the UPROPs from VisibleInstanceOnly to EditAnywhere
Unfortunately that did not fix it.
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.
can't say without seeing code
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.
What do you think?
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
iris or not?
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
non iris in this case
The onrep is tricky, it's a pointer to another actor, but that actor needs to be destroyed
how are these related? in the same overall thing or totally random relations?
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
I think there's no guarantee the rpc and the bunch with the new object spawn are in the same packet is there
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?
yeah I'm confused as to what the RPC has to say here that the new actor doesn't know in net init
Im guessing you want to pass some data along as well? Just add that data into a rep var?
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
Yeah currently that's what I'm doing
who needs this to be perfect? the player it's for or close or everyone?
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)
what artifacts occur if they aren't perfectly swapped in one frame?
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
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
It's switching from an "alive" vehicle to the "wreckage" of it
oh rip... yeah that would be NASTY to make invisible instantly
big pop in if it misses
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.
I think I would prefer to just bonk the original network object
it can tear off all of the useless "alive" components afaik
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
I mean yeah it literally just spawns it I guess lol
yeah
I guess you could make them optional subobjects by hand... ugh
And there's no record of that stuff being destroyed, so it just becomes painful
Each day I get closer to describing each game object as one struct with some uint8s
I really like just keeping it structy until needed to be otherwise
Can someone tell me why GetCurrentAcceleration from CMC gets normalized when replicated to other clients?
from ACharacter::GatherCurrentMovement
if (IsReplicatingMovement())
{
FRepMovement& MutableRepMovement = GetReplicatedMovement_Mutable();
if (ShouldReplicateAcceleration())
{
MutableRepMovement.bRepAcceleration = true;
MutableRepMovement.Acceleration = CharacterMovement->GetCurrentAcceleration();
}
else
{
MutableRepMovement.bRepAcceleration = false;
}
as of 5.5 the default impl uses the cvar p.EnableCharacterAccelerationReplication
which is off by default
github search is honestly just not reliable at all
it's gotten a bit better but it just sucks especially for commit searching
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
you just need to have a local engine source in some IDE that can eat 1 million files
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
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
you probably want to use a fast array, no?
Pretty sure you just add the Array, instead of the new object itself?
AddReplicatedSubObject is wrong, is what im saying.
Oh really
I dont use UE5 so I cant specifically answer.
In UE4 you just use this.
WroteSomething |= Channel->ReplicateSubobjectList(ReplicatedAwards, *Bunch, *RepFlags);
yeah its changed since
Passing the Array.
Thanks for the input guys, Ill check out both ways
Is there a AddReplicatedSubObjectList variant?
That you pass an array into instead?
GAS just does
if (IsUsingRegisteredSubObjectList() && IsReadyForReplication())
{
AddReplicatedSubObject(Attribute);
}
for every new element
Fair enough
fwiw the fast array must also be a replicated subobject marked somehow
depending on settings
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
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
Ok thank you 🙂 its good to know that, I will keep looking!
A FastArray would be better suited to Structs in this case.
to be fair an inventory item would be better as a struct but the items will be holding gas info
If you are curious, there is a link in my Bio to a generic item plugin I wrote for free that uses InstancedStructs to do just that.
Oh cheers ill check it out, even just to learn from
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
You can get away with not even using a replicated array if you’re using replicated subobjects
@haughty ingot true, just have the array of subobjects and not replicate it. since they themselves are replicated. 😄
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
If I want to teleport actor, does I need to turn on replication movement in actor?
Yes, if you want to keep the location and rotation synced between server and clients
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.
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.
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
I remember doing that couple years ago. You can put your AI logic into PC. There was a hacky way to integrate it with BT, but might be a bit challenging.
Ah wait I think I got what you mean just now
In my case I had just simple running around, jumping etc to test CMC (the replication data usage of it)
Or I'm not sure, are you trying to control a pawn that is owned by a PlayerController?
My goal is to netprofil a game for a research studie. So i need my game to be played with X player at the same time with the same behavior. So i wanted to make it played by AI bots and then observe netprofilling result
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.
I didn't know that, did you found this info on documentation?
Ah okay, yeah I totally missed the case and don't have any idea about it
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.
Thanks you very much, i'll try it
It is basically getting as close to the "deployment" scenario as possible.
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
I believe UI is client-side only, so you shouldn't need an RPC at all for this.
i've had that fear whenever i pickup a exp drop / item from ground, somehow to not acumulate
- 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!
that's why i asked
I see
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.
@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
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?
Sure, why not? It's locally constructed.
Okay good was just checking in case i fucked something up lol
I don't know why you would want to mess with it personally, but you can.
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
What is MAP?
You mean the LevelBlueprint?
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.
Has anyone had issues with steam returning duplicate sessions when using FindSessions from the OnlineSessionInterface?
Don't wanna take your time but I have to ask because I do not understand this statement. Why do not use level blueprint for LEVEL SPECIFIC LOGIC? Like: if button A pressed open door A. I am not talking here about very large scale maps but some smaller ones like indoor or maybe hl2 sized maps or something
It is more a general statement than a hardfast rule. The big reason is because it simply isn't reusable and you can't get access to the level script easily. Not saying it doesn't have its place, but generally speaking, an AInfo type actor placed in the world would be better. Serves the same purpose more or less, but is more configurable and more reusable.
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.
AInfo? Never heard about this
Gamemode is an AInfo
Ah ok
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
Ok, thanks for explaining
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.
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.
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
But I also don't mess too much with the sequencer, so I could be off base on that.
Still learning and don't know everything. Yesterday I noticed I can put sounds into Niagara
I was playing them separately XD
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
Yeah but what if you want to execute more actions that just opening the door? Like trigger explosion, change light, play some music etc
- I'd argue that example should be AWorldSettings 😛
- I put that in the GM personally
ke * eventnamewhen doing something quick and dirty - I don't write tests with UE's suite
Yeah, for 1. I didn't know about the AWorldSettings properly back then.
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.
Well, it is for quick n' dirty stuff. Otherwise, I do it in C++.
Then I would code that too. I don't see any of this being a reason for the LevelBP.
Buttons triggering lights works exactly the same way. Just put the Light into the exposed variable.
You'd use an Interface to ensure that the button doesn't need to know what it's actually talking to.
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
Hm yeah
But you must code it in the specific way that you must know what you want to change in the actor
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.
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
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.
Ok I get it
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);
You do not need to declare the _Validate function with RPCs
I always used it and it works, my AC is linked with it
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
both gives the same error
So remove the _Validate declaration
it's like the _Implementation wherre you don't declare it in your header, but the generated file
and i can still have a body of it without declaring it?
Yes
it IS declared in the generated header
unreal header tool makes them for you! this is just like how bp native events work iirc
great, let me test it 😄
Just as Megafunk pointed out
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
great it works after removing the _Validate declaration 😎 Thanks Friends for the lesson
👍
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 :/
I think you're thinking of OnReps.
OH!
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.
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
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.
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
Are you sure the steam. part is should be there? I remember like it should be just <steamID>:<port>
well, idk, my only source of information is chat gpt
i ain`t find this nowhere
Idk how to search it online:))
Simple suggestion would be to look at the engine source code, find that error, and see why you trigger it
ah i am using C++
honestly, i dont know how to do this
source code of what ?
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
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
So i can send the code to the other friend, but the friend when he tryes to accept, it gives this error in the log
Oh thank you, didnt think to go that far, now i know how to debug it further