#multiplayer
1 messages ยท Page 25 of 1
So it could be that as far as the live session on the backend is concerned, the Player left.
But joining a Session also sets up a local entry in the Sessions Array for the Client, and if they don't leave/remove that, they can't join another one or create one, as that block it iirc.
Hope that somewhat helps
Been a while since I fought with that stuff
Does this mean every server have a session? Even without using create session?
@chrome bay Is there a function or so that one can override to handle uniquely identifying the entries with FA?
I'm trying to understand how I would handle a predictively added entry
No, rather the opposite
Sessions are totally optional. They are only used to provide information about the Server
Or the Player fwiw
If I join a server with a session, does it register me to it's session as well then?
I don't think I understand what you meant with the message I replied to
void AGameSession::RegisterPlayer(APlayerController* NewPlayer, const FUniqueNetIdRepl& UniqueId, bool bWasFromInvite)
{
if (NewPlayer != NULL)
{
// Set the player's ID.
check(NewPlayer->PlayerState);
NewPlayer->PlayerState->SetPlayerId(GetNextPlayerID());
NewPlayer->PlayerState->SetUniqueId(UniqueId);
NewPlayer->PlayerState->RegisterPlayerWithSession(bWasFromInvite);
}
}
void APlayerState::RegisterPlayerWithSession(bool bWasFromInvite)
{
if (GetNetMode() != NM_Standalone)
{
if (GetUniqueId().IsValid()) // May not be valid if this is was created via DebugCreatePlayer
{
// Register the player as part of the session
const APlayerState* PlayerState = GetDefault<APlayerState>();
UOnlineEngineInterface::Get()->RegisterPlayer(GetWorld(), PlayerState->SessionName, GetUniqueId(), bWasFromInvite);
}
}
}
@marble gazelle Did you ever do anything with FastArraySerializer where the Client could predictively add to the Array?
Not sure I really understand how I can handle this. I only find bits and pieces with "predict" in them in the Source Code.
Because I end up with two elements atm on the Client
Nope, for everything exotic I wrote my own replication^^
And yes, I agree, I also thought about it, that it might don't work, as the IDs don't match
Hmpf
@thin stratus Thanks for explaining the joining/leaving server sessions, I will call Destroy session on client to make sure the client can re-join other servers
I'm sorry^^ But with some constraints, like not replicating UObject references, custom replication code can be very simple, if you just use NetSerialize and not delta
Still wrapping my Array into a custom Struct then I guess
yes or the place where you have the array needs to impl custom replication
yeah when it comes to predictively adding elements you add it, tell the server you added it, then server either sends back a "failed" RPC where client removes it (using the ID to ref it) - or you get a replication update and the client can see whether it's been accepted. GAS does that basically
Yeah but the Adding is handled in two totally different scopes
It's a cooldown that is committed via GAS Abilities
No chance I'm gonna inject another set of RPCs to confirm stuff
Ah rgr, I thought this was a bespoke system
No, it replaces GAS GE Cooldowns
I need to add the Cooldown locally, predicted, so the Client doesn't try to activate the ability a gazillion times before the Cooldown replicates.
Also for instant feedback reasons of course
Any Resources on "Custom Replication", because that in itself is a bit of a general term
Like, I assume I would need to "simply" say "This is the added element, find it via the Tag and update the Replicated properties" and then similar for updating and removing
Well implementing NetSerialize / NetDeltaserialize ^^
For detla serialize I know its called basically each frame to check if smth has changed, for the other I'm not sure if / how it detects if smth has changed, maybe it's also the task of NetSerialize to check if smth has changed.
So keeping the "when is the function called aside"
What you need to do is basically (for NetSerialize)
Grab the array -> write it into the NetWriter
On the client deserialize it (You usually send the number of elements and then the elements)
and then on the client you can do what ever merge logic you want.
I assume I can use something like SafeNetSerializeTArray_WithNetSerialize to serialize the Array and also allow it to serialize the Entry itself?
(as this is also used for the initial bunch, you always need to send everything in NetSerialize. this is bandwidth heavy, but less CPU heavy than NetDeltaSerialze, this has better bandwidth as it can just send, what is needed, but you need to cache the last replicated states for each connected peer, but thats wrapped with the API, a lot of shared ptr stuff^^)
never used that, so no clue what it is doing
template<int32 MaxNum, typename T, typename A>
bool SafeNetSerializeTArray_WithNetSerialize(FArchive& Ar, TArray<T, A>& Array, class UPackageMap* PackageMap)
{
bool bOutSuccess = true;
int32 ArrayNum = SafeNetSerializeTArray_HeaderOnly<MaxNum, T, A>(Ar, Array, bOutSuccess);
// Serialize each element in the array with the << operator
for (int32 idx=0; idx < ArrayNum && Ar.IsError() == false; ++idx)
{
Array[idx].NetSerialize(Ar, PackageMap, bOutSuccess);
}
// Return
bOutSuccess &= !Ar.IsError();
return bOutSuccess;
}
Does need a fixed MaxNum I guess
do your elements impl NetSerialize?
There is a version without. not sure yet if I need to
template<int32 MaxNum, typename T, typename A>
bool SafeNetSerializeTArray_Default(FArchive& Ar, TArray<T, A>& Array)
{
bool bOutSuccess = true;
int32 ArrayNum = SafeNetSerializeTArray_HeaderOnly<MaxNum, T, A>(Ar, Array, bOutSuccess);
// Serialize each element in the array with the << operator
for (int32 idx=0; idx < ArrayNum && Ar.IsError() == false; ++idx)
{
Ar << Array[idx];
}
// Return
bOutSuccess &= !Ar.IsError();
return bOutSuccess;
}
do you impl the << operator?
No
hm test compile it, but IIRC this is not default created, usually you would use a call to some code to use reflection to read/write the data
Here is the comment on it
/**
- ===================== Safe TArray Serialization =====================
- These are helper methods intended to make serializing TArrays safer in custom
- ::NetSerialize functions. These enforce max limits on array size, so that a malformed
- packet is not able to allocate an arbitrary amount of memory (E.g., a hacker serilizes
- a packet where a TArray size is of size MAX_int32, causing gigs of memory to be allocated for
- the TArray).
- These should only need to be used when you are overriding ::NetSerialize on a UStruct via struct traits.
- When using default replication, TArray properties already have this built in security.
- SafeNetSerializeTArray_Default - calls << operator to serialize the items in the array.
- SafeNetSerializeTArray_WithNetSerialize - calls NetSerialize to serialize the items in the array.
- When saving, bOutSuccess will be set to false if the passed in array size exceeds to MaxNum template parameter.
- Example:
- FMyStruct {
TArray<float> MyFloats; // We want to call << to serialize floatsTArray<FVector_NetQuantizeNormal> MyVectors; // We want to call NetSeriailze on these *bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess){// Don't do this:Ar << MyFloats;Ar << MyVectors;// Do this instead:SafeNetSerializeTArray_Default<31>(Ar, MyFloats);SafeNetSerializeTArray_WithNetSerialize<31>(Ar, MyVectors, Map);}- }
*/
hm yeah, operator<< isn't default created for my knowledge, so either way you need to impl smth
So if I were to use this, I would use some temporary TArray when reading, and then modify the actual TArray of the CooldownEntry in whatever way I need?
On the server you serialize its array,
on the client you can read the entries from the Reader entry by entry, so you don't need to allocate an extra array for it
bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
{
if (Ar.IsSaving())
{
SafeNetSerializeTArray_Default<31>(Ar, Cooldowns);
}
else
{
TArray<FAbilityCooldown> LocalCooldowns;
SafeNetSerializeTArray_Default<31>(Ar, LocalCooldowns);
// Do custom merging with Cooldowns property
}
}
Something like that?
Or can I additional check if the Client is calling this?
Sorry, my usage of NetSerialize usually ends at the very basics of it
yeah
technically you can do an is client preprocessor cmd or a runtime check, but Ar save/load is enough
How does this behave if I were to ever send a ServerRPC with that property?
That should use NetSerialize too or?
But I guess the actual Array Property is then empty in that case
On the receiving end
RPC is not using NetSerialize
Ah
net serialize is for replicating state, RPC is well, RPC^^
But one can optimize Structs for RPCs too or not?
I mean, the CMC for example sends optimized vectors to the Server via FVector_NetQuantize
yes, if you send a struct via RPC it calls the same function, if the struct impls NetSerialize
Now I get what you meant^^
Sorry, I meant if I do
void ASomeActor::SomeRPC(FSomeNetSerializedStruct Struct)
yeah then the array will just be empty, as the target struct will be an default instance
Okay cool
I will see how far I get with this
Shelved the FastArray changes for now
RPC will use NetSerialize for a USTRUCT() if you have it defined
Not NetDeltaSerialize ofc
You can try it by sending an FHitResult through an RPC and breaking in NetSerialize()
Yeah my idea now was to wrap my Array in a Struct, bascially how Fast Array does it already, but not use Fast Array but just NetSerialize for that Struct and handling the small custom rules I need myself
WithNetSharedSerialization = false, // struct has a NetSerialize function that does not require the package map to serialize its state.
Just for learning: What does that mean?
Cause I see FVector_NetQuantize also set that to true
this looks new to me xD
but I'd assume it's if you don't need to replicate UObject*
It's sadly worded in a way that whoever knows perfectly what's going on has all info, and everyone else reads cryptic
as the package map is used to resolve the pointers
Alright
yeah WithNetSharedSerialization means no UObject and no FName's within
But it also only actually seems to be used by the shared serialization path in rep graph
I think a long time ago there was a net-GUID ack system for FName's too. I remember talking about it with someone @ The Coalition, but there was no trace of it in engine source that I could see
Man, just reading net GUID ack makes me shiver
๐
I can't recall what it was, but I had to deal with Actors just being invisible on Clients
Totally randomly AIs weren't showing
Basically same approach they use for uobjects but also for strings, so you can identify an FName over the network with a single GUID and not have to send the full string each time
Took me quite a long time to figure that out on The Ascent. Sadly not sure what that was again
Would probably be great for socket names and stuff
Or maybe it's for package names actually..
who knows ๐
unreal go brrrr
yeah, thanks
That should help iirc
Did not think I would ever post about that again, and funnily enough I remembered it a few minutes ago when writing with James
we swapped out a lot of hard refs recently and this started happening on level transition
never on 1st seamless travel, but afterwards
Are you on UE5?
static int32 GNetResetAckStatePostSeamlessTravel = 0;
static FAutoConsoleVariableRef CVarNetResetAckStatePostSeamlessTravel(
TEXT("net.ResetAckStatePostSeamlessTravel"),
GNetResetAckStatePostSeamlessTravel,
TEXT("If 1, the server will reset the ack state of the package map after seamless travel. Increases bandwidth usage, but may resolve some issues with GUIDs not being available on clients after seamlessly traveling."),
ECVF_Default);
There is apparently a console var by now
:D
They also seem to have taken my sort of solution as the fix
yolo
no, 4.27
I guess you can cherry pick the fix then and see if it helps
i can just add it to the engine easily enough
i don't even have to change the precompiled engine for non programmers since this doesn't matter in editor
thanks, this saved quite a bit of time

@marble gazelle Thanks for the hints, seems to have fixed it for now with the NetSerialize solution.
Awesome, any time^^
I am still trying to wrap my head round the join/leave flow in UE.
I have a dedicated server which is intended to be joined purely via IP:port. Thus I assume I don't need to do SessionInst->CreateSession.
But when the player is joining the server (via IP:port), it's the AGameSession::ApproveLogin that is determining if the player is allowed to join or not.
Am I correct to assume that Creating session is mainly to advertise online in "browser" style (like old school counter strike). But if joining directly, I don't need that.
Thus leaving the game by opening local map is a correct way to leave?
I found your forum post about a blog post you created about joining/creating/deleting sessions, but that one is sadly down. https://forums.unrealengine.com/t/blog-c-session-create-find-join-destroy/36931
if i set a timer by a server event does that timer tick on the server?
I really need to resetup my website
Sessions are just data containers in the cloud
They provide information of available servers to the ones asking for them
That is indeed the exact same as a CounterStrike server list
If you use steam you usually won't be able to connect via ip
But only via steamid
Steam usually hides the IP in whatever way possible
Perfect, thanks for confirming that. I was initially confused that Session != AGameSession.
No steam here, I am using Gamelift and have backend handled in AWS Lambdas.
if I call UEngine::Browse from a client while connected to a server. Will this disconnect the client from the server and travel then to the map?
nvm I think Clients will disconnect from current server. this means exactly that.
how many rootmotioned AI controlled ACharacter I can handle in mutiplayer ?
forget about rendering, ... im woried about replication and badwidth limits.
those characters are zombie btw
๐ค
default movement replication is heavy and root motion I guess it adds lots of overhead
Any idea why GameLift doesn't update the number of connected player sessions on a game session when I join it?
Oh, you have to specify the Game Session ID as part of the CreatePlayerSessionRequest.
how do I show notification error in editor ? message / error that popups in bottom right
@rose egret This has a decent showcase for it.
https://forums.unrealengine.com/t/display-message-in-editor-message-box/348252/2
Does anyone know how to stop the client from spawning before the server?
My pc is slower than my partners, and when we test with me being host, he spawns prior to me, and technically doesn't exist?
In UE 5.0 when using seamless travel, there's an issue with** client loading the map faster than server**, resulting in broken state, where server doesn't know the client is already connected, breaking the game.
I've heard that this issue was already seen in 4.XX version, then fixed in later ones and it once again **resurfaced **in 5.0. My latest info is that it SHOULD be **fixed **in unreleased 5.1, could anybody please confirm it?
Or does anyone have fix on this issue? I know about this forum post: https://forums.unrealengine.com/t/ue5-seamless-travel-bug-found-we-found-the-cause-and-also-have-a-workaround/583652/16 . But someone pointed out, that this workaround causes side effects, which once again aren't confirmed, confusing me once more..
I think I ran into this problem too, when I host the game in my PC everyone travels to the map, when I host the game on my brotherโs PC the same, but when I host the game on my less powered notebook I and my brother keep stuck in the loading. So my question is, if the bug has been reported in Jun 16, why its still happening now in Sep 21? Edit...
I am currently in the midst of implementing deterministic physics over the network in our racing game, which requires the state of the physics engine on both the client and server to match exactly for every simulated frame. I am running into an issue where the client and server get out of sync, where either the client or server runs slightly slower even though I am using the same timestep on both. In these cases I start to miss out on input from the slower side and I'm not sure the best way to solve this. I can delay simulating on the server for a tick when the clients are slower for example, but this results in jumpy behavior and overall seems like a poor solution. Is there a common way to deal with this sort of situation that I'm not thinking of?
You got an input buffer?
Yes, each vehicle has an input buffer. I believe the issue is that since the client and server aren't in sync, the client isn't capturing input as fast as it is being processed
Or on the other hand, the opposite problem, it's being captured faster than it can be processed. I've seen both happen intermittently
Is there a risk in enabling "Allow Client Side Navigation", so that the SimpleMoveToLocation functions in multiplayer? Is this opening myself up to potential cheating since the path is calculated on the client vs the server?
Multiplayer physics is hard man. That's why I'm glad my design doesn't need anything fancy, just server authoritative physics.
Sure is, I've been working on this for several weeks now. Thank you for trying. Sometimes I think I'd be better off with server authoritative but I've probably spent too much time on this already to scrap it
How are you gonna handle car to car collisions or is it all ghosts?
The goal is to predict everything, which is why I require every vehicle's input for every frame. That way when there is a collision, it happens exactly the same on each client as well as the server.
That part is already implemented but missing out on input is causing issues. Most of the implementation is based on how Rocket League does it, so I know it's possible, I just think I'm missing something
So you're NOT doing clientside prediction, there's still ping lag between input and Thinghappening?
No, I am doing client-side prediction
So you got rollback?
Yes
gotcha. Yeah I didn't go down that route because I'm doing player-made vehicles. It's bad enough already, implementing rollback for little jimmy's dividebyzeromobile with 12 wheels and 6 engines just feels like a bad time
But we're not racing, so I just live with the ping delay and everyone sees approximately what happens on server.
Totally understand that.
That would be quite a headache, even a relatively simple vehicle has a ton of variables to think about
I really only replicate the control state and the chassis movement. Everything else is local
so you and me don't necessarilly agree on how much the suspension compressed on that landing, or what RPM the engine is at this second, but we do agree on what gear I'm in and my throttle and the overall motion of my vehicle
Only slightly jealous. Our system has me tearing my hair out for the last few weeks. Unfortunately it's a very fast-paced game with very non-standard physics so we basically have to do it this way
But I feel like I'm rounding a corner on it, hopefully I can figure out the rest of these lingering issues
deterministic physics ough >_< shaky-shaky
is there something special with port 7777?
The engine is continuously creating a GameNetDriver for it even though I don't have that port specified anywhere in my configurations.
LogNet: Created socket for bind address: 0.0.0.0:7777 LogNet: GameNetDriver IpNetDriver_22 IpNetDriver listening on port 7777
Default port that unreal engine tries to use.
ok thx... thought i was losing my mind..
I think I fixed my issue but now I am getting this error
SetReplicates called on non-initialized actor
Directly setting bReplicates is the correct procedure for pre-init actors.
Hello!
Has anyone had an issue with AI rotation not replicating properly on client-side when using root motion? i.e AI character using a combo while rotates, client sees a straight root motion, and when the montage ends, teleports to the real server final location including the rotation over time.
There are certain conditions need to be met, otherwise won't happen at all:
-Allow rotation using root motion has to be on.
-Usually happens on top of hierarchical instanced meshes, or spawned meshes that were not part of the persistent level at initialization.
-Network might be need to be saturated.
Worth to mention, it is not happening 90% of time, it feels like happening over time, which makes it harder to isolate the issue. I'm also using GAS, thou shoudn't be relevant since AI is always server initiated. I'm also prioritizing net updates on AI to be completely sure positions of AI are refreshed, is there a chance that the rotation + root bypass the network priority?
Any pointers or clues will be much appreciated, thanks!
Yeah I know. The MySQL setup of my WordPress page is shite
Will restart it once I'm up
Thanks for reminding me
C++ | replication
yo,
I'm having an issue with OnRep, wondering if anyone knows the answer. The issue is that the repnotify seems to call before the actor has even spawned in? So the OnRep event will call, but the debug log will show a null actor, the actor is a blueprint actor if that has any effect. Im just wondering if this is solvable.
has anyone messed with Iris replication in 5.1? Seems like the plugin's enabled by default but not sure if it's really doing anything yet
no problem.
Should be available again
OnRep of a Pointer variable?
thanks
yeah it is a pointer, that a no go?
It's fine, but they usually replicate in two steps if the Actor doesn't exist yet.
Since a Pointer is just a NetGUID
You basically are getting an OnRep for the NetGUID which can't be resolved. Once the Actor is valid it should call again though.
Simply ensure the Pointer is valid before accessing it
it works about 75% of the time, but my log says that 25% of the time it just doesn't call, which is strange
I've been struggling to decide the best way to do automatic gunfire. The two main choices would be sending each individual gun shot, which is much easier to keep in sync but can result in somewhat choppy firing because of variable latency. The other being sending a startfire/endfire rpc which would be perfectly smooth, however variable latency also means they could fire less/more than the server and they become out of sync. This would only be a problem for higher firerate weapons but that's enough of a reason to make me wary of it. Of course I could just correct the ammo on the client after they stop firing but that's not ideal.
Am I correct in my thinking?
Client starts firing with a ping of 150ms, then stops firing at 100ms (extreme example but still, with a firerate that shoots faster than 20 shots per second it will be out of sync)
I'm not sure if it's even worth worrying about this edge case as it's so extreme
I have a mac 10 which is the higher end of firerate of weapons in my game and that's 18 rounds per second
nvm, after filtering the log and etc, i can see the function trys twice, issue must be somewhere else in my code
Start and End make a lot more sense than each individual shot
You can always send Timestamps and what not
To get an idea of how long the client actually shot for
And do some padding here and there
Fwiw, if the client stops firing the weapon, then that's what should, if possible, be the truth
Feels a lot better that way
You can set up some net sync clock to get some RTT and Latency data to play around with
Or use the ExactPing from the PlayerState I guess
Yeah that's what I was thinking, it's such an edge case when it gets out of sync
(although I think that is calculated with frames in mind)
For spray and such you can use a RandomStream that you reset when stopping/starting the shot
That's the ideal, currently I just give client authority on spread since cheating is not a huge concern, I'd rather not give client authority on everything though.
Server should have auth
Even if I add that though, client still has auth on hitreg otherwise I need to implement rollback. This is a party game played on listen servers with your friends btw
Multiplayer turnbased problem I'm wondering if anyone can help with?
Ive been converting movement into an actual button that spawns an actor via class but the actor is not spawning when I SR_SET_Movement on the button click, Im just wondering if the widget button should set a temp var on the PlayerController?)
https://media.discordapp.net/attachments/974031882599686194/1033331195796275270/unknown.png
pretty sure this is the problem...
and i know im not passing anything directly in here to SR_Set_Movement its just that in the button i thought i could set it with
https://media.discordapp.net/attachments/974031882599686194/1033331508871712768/unknown.png?width=1058&height=376
the button works as intended other than spawning an actor which is where i was going to move the movement logic into or should i be using the player state here to pass on the player controller and setting it in the player state from the button?
If it helps this is the spawning section in the player controller
https://cdn.discordapp.com/attachments/974031882599686194/1033334161546674256/unknown.png
But here is an example of what I mean:
We use GAS for our Abilities but we had issues with Cooldown, as Cooldown was fully predicted on the Client. But if the Activation of the Ability took 1 sec the first time and the next time 0.5 sec, the Server might still be on cooldown. (extreme numbers to make it more obvious).
So we changed it to Server Auth Cooldown with only predicting the Adding (so the client locally instantly is on cooldown). Removing was Server Auth.
To counter the RTT, so sending the ActivateAbility RPC and receiving the Data of the CD being over from the Server, we simply reduce the Duration of hte Cooldown on the Server by RTT.
Just an example of going a bit out of your way to make it feel correct on the client. @worn wagon
How do you go about calculating the RTT?
Using the synced server time variable?
Component on the PlayerController
That every now and then sends an RPC back and forth
With the Timestamps to calc how long it took
It's a byproduct of syncing ServerTimeSeconds
The default ones from GameState are garbage
Yeah I think you may have been the one who told me this before haha
Can also be @pallid mesa who wrote some docs about it. I did it similar , cause the concept is the same after all
Is this what you mean? https://medium.com/@invicticide/accurately-syncing-unreals-network-clock-87a3f9262594
When implementing real-time network multiplayer in a game, one very important tool is a reliable network clock.
Something along those lines yes
Check pinned messages
From Vori
Last link in their pin
Oh man there's a lot of good stuff on pinned
Thanks a lot, should be an interesting read ๐
I swear making the same singleplayer game in multiplayer increased development time by at least 4x
I can only imagine how difficult it would be without an engine that already has a lot of the groundwork covered
aye, feel free to ask whatev, it's a post that got semi-written in here compiling knowledge from many fellas ๐
so huge shotout to em all
I hate dedicated servers already
Can i claim I contributed with positive energy for when you get famous so I get something out of it too? ๐
I'm attempting to run the third person template on my raspberry pi as a dedicated server x)
nice :D
The first step towards world domination >:D
Can I mark actors on the level to replicate after they're loaded? Since they're spawned with the level locally, will this even work?
Could work, since I think they are stably named
I'm trying to add UI for each player through the player controller. The issue is when I try and print the controlled pawn, it prints out the same pawn. This leads me to believe only 1 player controller is active even though I have 2 clients + the server
But when I add UI through the player controller, it's visible on all clients, but it doesn't work. For example, the UI has a reference to the player it belongs to and whenever it needs to access that player, the game crashes because the reference is null. The reference gets set through the player controller. It works on the server, but not for any clients
wait nvm, I was being dumb
I just found this repo which has a lot of references to useful network stuff, not entirely unreal specific but still https://github.com/ThusSpokeNomad/GameNetworkingResources
๐
This is amazing, thanks for sharing!
I clicked on the WoW video and this is almost how it immediately starts off.
๐คฃ
Also I completely forgot that repository existed, I even had it starred D:
Can anyone help me ?
With what?
Destroy player in multiplayer
Your player is likely replicated so you just need to destroy it on the server and the engine takes care of the rest.
Lol. Riot has got similar spirits.
I did but it's not working
Can you show your player setup and how you destroy it? Also have you made sure by debugging or printing messages that your code actually gets executed?
Any ideas why a server initiated multicast will run on both a server and client. Yet the server adding a variable to a replicated array does not trigger an onrep on client?
That's the way multicasts work. They run everywhere as long as that actor is relevant.
Yeah, that was half of the point.
Do you actually update the array or do you update an element inside of the array? I believe the latter was a bit problematic if I recall correctly.
Straight up add. Has to be changing the array. Definitely ran on server.
Is a TArray of uint16. Uproperty, marked ReplicatedUsing
Has a DOREPLIFETIME
In a component, not sure if that's relevant. Both the multicast and the replicated array are.
The component is replicated too ofc right?
The multicast works. Was why I started with that. ๐
Right, right was double checking ๐
Sec. I didn't think to see if the value is actually arriving. Was assuming the OnRep would run without incident.
guys how to improve the optimization for the lag for the replication of the animations
Guess
Which also shouldn't be an RPC at all, but sadly that what happens when the net compendium is overlooked ๐
I'm still learning but multicast shouldn't be called for destroying an actor right? Cause any late joiners and irrelevant players that become relevant will still see the destroyed actor right?
Correct. Though it could have been destroyed for them if the multicast RPC was to execute on server, still not a good practice and error prone.
Replicated actors are ofc not destroyed by a multicast RPC
Hmm. Nope. No replication at all. :/
You are calling the OnRep explicitly after the addition right?
That's why it's firing on server?
At the moment for testing, yes.
Could it be that the client for some reason thinks that the local value isn't any different from the server's and thus not firing the OnRep
Have you tested with REPNOTIFY_Always?
Won't make a difference. I just tested the array client side on tick. It's not getting any replication at all.
๐
It's incredible how difficult it's to figure out how to do this while it's the most easy thing ever.
"Download cool compiler thingy, regenerate source build files, compile and it magically works"
Could you maybe show how you're doing that ? I have a replicated array in a component without any issues for OnRep
That's all i have (of course it does not have an OnRep, but it had one before without any issue)
It's not the array. I'm trying to replicate a simple array of instances that should be scaled to zero for a HISM component. The issue stems that I'm using the foliage components, which I cannot override the actor for. So a world subsystem is setting them to replicated and always relevant both on actor and client. The component being used I can actually subclass, so I was doing the networking there with the array. The component can RPC a multicast, but cannot seem to replicate this array.
Client just prints a length of zero. Server's shows correctly.
Uhh..Okay. That's a new one. O.o I can turn off replication in the component, and the RPC still works.
Well.. that explains why my replication isn't working, but what the fuck? ๐ Why can you RPC through a component that isn't even replicated?
Lol. Have a feeling that replication is broken for HISMComps
Yeah.. I was really kind of hoping not to need a huge container elsewhere.
What is a good way to approach updating UI? Currently, I'm calling a server RPC which will run some logic. And then from that server RPC, I call a client RPC which will set some variables in the widget and call the update function on it. The problem is the client RPC function gets called with authority and the widget UI reference only exists on the client. I've tried setting the widget reference to replicate but that doesn't fix it.
Widgets aren't capable of dealing with network things. The general flow is that the server updates something in for example the game state, player state, player controller or whatever and that when arriving on the client it gets passed on to your UI locally ๐
i'm not sure but RPC are handled by the component owner
that might be why
I can know when the update arrives on the client through repnotify right?
For example yes.
@solar swallow One thing to take into consideration for UI is that you have to follow the basic core concept. UI is for displaying the state of gameplay objects and allowing input into gameplay objects and that is all. UI should never have state of the game and should only contain state related to their own display. If you cannot remove all UI from the screen and then put it all back then your UI isn't set up correctly. And all of this is before any networking considerations. Gameplay should never know that UI exists. UI should be able to bind delegate or tick to update itself and gameplay classes should simply be able to go about their day setting new state and broadcasting delgates. If anything cares it should be bound to that delegate to do what it needs.
Nothing changes in this as far as networking goes except that you also need to broadcast those delegates where they matter in OnReps.
D:
Oh, I haven't been using delegates. I just call UI->UpdateUI()
Thanks for the info
Is it fine if the UI has a reference to the player so it can get health/stam/ etc values
i have a weird issue that only started happening when i updated to ue5...
I have a level called MainMenu, a MainMenuGameModeBase and a MainMenuPlayerController. I run game in standalone, and my MainMenuPlayerController calls ClientTravel like this:
ClientTravel(TEXT("127.0.0.1//Game/Maps/ClientGame1"), ETravelType::TRAVEL_Absolute, false));
which used to connect the player to a waiting dedicated server playing ClientGame1
now i get LogNet: Warning: Travel Failure: [ClientTravelFailure]: Invalid URL: /Game/Maps/MainMenu and nothing happens.
I don't understand why it's trying to travel to /Game/Maps/MainMenu when the URL is for ClientGame1
Hi!
I've just started to learn Unreal and I want to learn how to develop multiplayer games.
Do you know a book or something to start with? I want to know how multiplayer works in Unreal: about servers and clients, etc.
Thanks a lot!
im no expert but a lot of people pointed me to this and it helped for starting https://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf
Oh, great! Thanks!
Try my C++ Survival Game Course:
http://bit.ly/unrealsurvival
Discord:
https://discord.gg/meFRZfm
Today I do my best to teach the basics of networking to you in under 30 minutes. Enjoy!
Business Email: contact@reubs.io
this video helped me a lot
gives examples in bp and c++ as well as a proper explenation
Great! Thanks!
It's amazing! It has a lot of information!
Alex Forsythe also has a good video: https://www.youtube.com/watch?v=JOJP0CvpB8w
An overview of the essential concepts for writing multiplayer game code in Unreal, in under 25
minutes or your money back.
Sample project: https://github.com/awforsythe/Repsi/
Patreon: https://patreon.com/alexforsythe
Twitter: https://twitter.com/alexforsythe
00:00 - Introduction
01:24 - Net Mode
03:33 - Replication System Basics
05:13 - Acto...
and a soothing narration haha
Thanks!
2/3 suggested resources are in this channel pins. Worth to look there too
Thanks. I'm sorry, but I didn't know anything about pinned messages.
What you was suggested are the starter pack. Remember to look at the other resources while you climb your way up ๐
I'm sad, my Raspberry PI OS is 32 bit which Unreal doesn't like supposedly with the ARM architecture so now I need to upgrade it xD
guys do you know how I can show ping
in game i mean i am connected to dedicated server
and i want know ping there
Playerstate stores a compressed ping per player if memory serves.
i wanna see ping in log like when you play csgo, i will see in client widget FPS, ping and packet loss
anyone know why in ue5, ClientTravel(TEXT("127.0.0.1//Game/Maps/ClientGame1"), ETravelType::TRAVEL_Absolute, false));
ends up calling
Browse(...FURL="MainMenu?**closed**"...)
Because your URL isn't valid. It needs to look like 127.0.0.1?map=Game/Maps/ClientGame1 and from there on you can request that parameter on the server.
Although I'm not 100% sure if slashes work like that as argument, but you get the idea.
@ wizard, it works ๐ฅณ
Dedicated server running on my Raspberry PI from the third person template.
Only took two hours to compile the server and install a 64bit OS on the server lol.
Thom going places. ๐
Exactly! Going bankrupt.
Maximum player count: 0.5 (yes, half of one player)
(I kid, I kid)
To be fair it has 4 cores running at 1.6GHz, no it's not going to run Fortnite but it can definitely run a few players.
Yea
guuuys please can you give me tip how to show ping when I am joined to session ?
PlayerState has a variable named CompressedPing that you can read from C++ or Blueprints. Multiply it by 4 and you got your self your ping for a client ๐
that fixed it, tyvm
for the love of god, is there a link that describes FURL params clearly
this used to work in ue4
why by 4?
Because they divide it by 4.
/** Replicated compressed ping for this player (holds ping in msec divided by 4) */
So you need to multiply it by 4 to get the proper result again.
Although to be fair you can also call GetPingInMilliseconds() and that will do it for you.
You need to grab it from the player state. Which you can for example get from the player controller.
What engine version are you using?
GetPingInMilliseconds is a function on the playerstate. Don't call GetPinginMs. Call GetPingInMilliseconds.
Oh I didn't even realise lol.
ue 5
Then what Authaer said ๐
I think I'm misunderstanding something fundamental about replication...
My goal is that when I click on the ground, to make a RPC to the server passing the hit location, which uses UNavigationSystemV1::FindPathToLocationSynchronously to generate a NavigationPath. I then set that NavigationPath to a property named NavPath and have an OnRep_NavPath defined which attempts to use the navigation path. However my NavPath is always null on the client, even after OnRep_NavPath fires.
What am I doing something wrong? This is all within an ActorComponent that is set to replicate if that matters.
What is the correct way to replicate the removal of an instance of an instancedmesh in the foliagesystem?
Hello! I recorded a video showcasing our rotation replication problem, in case clicks about the potential issue.
As I mentioned before, it not always happens (which makes it hard to reproduce), but it happens sometimes on top of different procedurally generated HISM/ISM
Aparently, under saturated network root motion rotation is not updated properly and gets the update right after the notify ends, which translates into a teleport between the difference of the montage allowing rotation in root motion and not.
Does someone know what could be potential issues or way arounds? should I force net update on the tick notify maybe?
Thanks!
You need to call the onrep function manually after changing the value. And I think you also need to implement GetLifetimeReplicatedProps in order for the variable to get replicated. void ASomeClass::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(ASomeClass, ReplicatedVariable) }
I do have GetLifetimeReplicatedProps setup, it wasn't near the other code so difficult to screenshot it. I thought I would only need to call the Onrep function if i wanted it to run on the server? The OnRep_NavPath is getting called on the client after the change occurs, it just doens't have the variable value..
Do you have this option turned on in the project settings? I'm not sure nav data can replicate without it.
I do not. I didn't realize that blocked navigation replication for the client. When that is on, i technically don't need to make any attempt to do server navigation it just works with multiplayer. But i assumed that it was also not validating the navigation path on the server. Was that an incorrect assumption?
I know that the CharacterMovementComponent is naturally validating character movement against the server, so my entire goal had been to leverage that for click-to-move by generating vectors based on current location vs a path point. If checking that checkbox is all i need to do, to make click to move work securely in multiplayer, thats great
I dont really understand why that would prevent a Navigation Path i set manually on a property from replicating though..
Enabling that setting doesn't change the fact the property isn't replicating.
Dang. Thought that may have helped. If that's the case, then it's probably not something that can be directly replicated - like you can't just replicate UObjects, you have to do some extra work to replicate them.
Ahh ok, well thats good to know. I didn't realize that. I Do have one other question though. With that setting on, is it "safe" to use for multiplayer? Right now the default Top Down example uses SimpleMoveToLocation which works fine in singleplayer or on the server, but ONLY works on Multiplayer if that Allow client navigation checkbox you mentioned is checked.
I'm not certain with Simple Move To. One way to check is to spawn a wall only on the server (not replicated) that has some collision and see what happens when the client tries to move through it.
If it passes through it like it wasn't there, then it wouldn't be secure.
I've dug though the C++ for quite a while and I believe NavigationPaths still use the underlying CharacterMovementComponent. Ok, good point that should be fairly simple to do i think
I honestly can't really think there would be an issue other than the client thinking it can move somewhere where it actually can't.
Hi, I've recently got predicted root motion working with Gameplay Tasks and that's all functional. Now I'm trying to figure out how to also get server-initiated motion working (like knockbacks) without jitter. I know that I need the client to "predict" that he's getting knocked back locally first before actually running it on the server, but I'm having trouble getting that not to lag. Currently my approach is to replicate the gameplay task with the root motion down to the owning client in the CMC's ReplicateSubobjects, then have the client run the gameplay task (which performs the root motion), and send a flag up using network move data that they have executed the root motion, after which the server receives the flag and runs the gameplay task. This works except the client jitters a lot. I think it has something to do with the order of RPCs that happens, which was also an issue when I was predicting (needed to FlushServerMoves before performing any predicted root motion). Any ideas?
So, it looks like the issue regarding replication was that I was attempting to replicate a UNavigationPath. I switched to a TArray of FVectors and its replicating fine.
Hey just a noob question, is there any possibility to add like many server instances on one dedicated server?
If yes, is there any doc or any information about how I can configure that
I read that you can actually but with different port each instance
Although how can I make a simple system that close letโs say an instance and open a new one at each of available ports
Is there any limitations?
Thatโs all ty
Or should I choose aws gamelift and thatโs all ๐
Okay. So.. After a ton of breakpointing and tests. I am still baffled by this.
Facts:
โขActor is a part of the level. It's class does not replicate by default and server sets it to replicated shortly after starting.
โขActor is replicated.(Actor and it's component have no problem being sent over network through pointers)
โขComponent is replicated (Also tested this by tracing on the server and hitting it, and setting it in a replicated pointer, the client resolves a correct pointer).
โขArray of integers is marked ReplicatedUsing, property is DOREPLIFETIME macroed in GetLifetimeReplicatedProps.
Issue:
A replicated Array in the component still will not replicate. Adding a new entry on the server does not trigger any form of replication. The client's array size stays zero, the OnRep never runs.
Uh.. Huh. After writing that out I just had a recollection of.. I think Cedric telling me that sometimes actors won't replicate if you only have one replicated property. I added an integer, replicated it. And suddenly everything I expect to happen is happening. How fucking Unrealโข๏ธ
What is the best way to replicate components created at runtime. Currently, I'm creating a static mesh, spring arm, and camera component on the server. They are all set to replicate. The issue is only the Mesh is valid for the client, spring arm and camera component are both nullptr. Everything works properly on server. Mesh = NewObject<UStaticMeshComponent>(this); if(Mesh) { Mesh->RegisterComponent(); Mesh->AttachToComponent(GetRootComponent(), FAttachmentTransformRules::SnapToTargetIncludingScale); Mesh->SetStaticMesh(ShipProperties.Mesh); Mesh->SetWorldLocation(GetActorLocation()); Mesh->SetGenerateOverlapEvents(true); Mesh->SetNotifyRigidBodyCollision(true); Mesh->SetCollisionProfileName("BlockAll"); Mesh->SetIsReplicated(true); } SpringArm = NewObject<USpringArmComponent>(this); if(SpringArm) { SpringArm->RegisterComponent(); SpringArm->AttachToComponent(Mesh, FAttachmentTransformRules::SnapToTargetIncludingScale); SpringArm->SocketOffset = Mesh->GetSocketLocation("Camera") - Mesh->GetComponentLocation(); } Camera = NewObject<UCameraComponent>(this); if(Camera) { Camera->RegisterComponent(); Camera->AttachToComponent(SpringArm, FAttachmentTransformRules::SnapToTargetIncludingScale); }
quick question, is a mesh "collision enabled" property automatically replicated?
I'm talking about this one
if I change it on the server, will it automatically replicate to all clients?
I don't know if I'm doing something wrong but my client rpc is running on the server. I've declared it as a reliable client rpc with validation. I call it from the server. But when I check if I have authority or not inside the client rpc, it says I do. Anyone know why?
Multicast rpc calls on all clients. A listen server will have a client as the server. So that means the server will call on the multicast rpc.
Hi Guys, i use the move compenent to (node), to set the player in a right interact position.. works on server, on client to but the client cant move out of th eposition and is stucked and jitters. anyone have aidea?
Hi!
If I want to create a multiplayer game, do I need to do something special when I create the project in Unreal?
Thanks
I think I only have to set the number of players in the Multiplayer options to more than one, and that's it.
omg
u need to program your whole game to be multiplayer ready
and its a lot of work
I think he was referring to any special editor settings
If that's the case then that's sufficient for now. As time goes on you will start emulating lag and launching standalone/packaged.
Plan for multiplayer early. From: https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/Networking/Overview/
Yes that's exactly what vori meant
By the way, you are not answering my question.
You aim for MP from the start
There is no magical button that makes your game multiplayer ready
Sadly this isn't the case as of now ๐
So, I don't need to do anything in the editor. Just create a project. The same project will work as standalone or multiplayer.
You dont need any specific settings. You need first to define your server model (listen or dedicated) which comes by analysing how your game will be
or maybe both
No. You are not guaranteed that. Project can work differently in different configurations. Traveling is a good example to that. That's why at some point you leave the editor and start testing standalone. At least you can make the editor not "run all under the same process" so you can get close to the other configs
Unreal has settings to test your multiplayer features in engine by simulating a multiplayer connection in PIE through the two models I mentioned before
In other words: What do I need to do if I want to create a Multiplayer game? The first step is create the project in Unreal. What do I need to do to create a multiplayer game project in Unreal? Thanks.
But PIE testing isn't as trustworthy as running real connections (running each one in one process is better!)
So you need to learn any API that lets you create sessions with a subsystem
#multiplayer message
i.e. to read what you was suggested
for example CommonUser, and steam subsystem
then you need to understand RPCs and replication
which make up for Unreal's networking model
ยฟ?
Finally, once you've understood RPCs and replication you can start doing basic stuff
my core recommendation to learn these networking primitives is reading cedric's network compendium (pinned above)
you'll also learn things such as the gamemode only exists in the server
But... but... my client needs to access the GameMode, can't I just replicate it?
yes you can technically modify the engine to make it that way
kekw
reject tradition - embrace replicated gamemodes
Breaks the entirety of Unreal
๐ฎ
@timid moat i think you got enough info with all I wrote
Sorry, I don't understand you. I only want to create a game ready to be a multiplayer game. I don't need to know all the steps that I have later. I only want to know what I have to do in Unreal to create a multiplayer game here:
just click one of these and done
You create it just like you create a non-multiplayer game
THANKS
hehehe

Replicated Widgets when?
do u guys agree?
They are on their way 
I do. Also vulnerable to cheats ๐
Looks at the advanced vehicle template
Although the matrix is enough for me... for now
To which part lol
If we get Matrix multiplayer weโll get a million GTA knock-offs ๐
multiplayer code pollutes the source code in something that is meant for beginners to learn, so if someone isn't interested in multiplayer it will be a PITA
oh gta is almost fully client auth (said by someone I know that played many many hours)
it got some validation server side
and that's why its online feels as smooth as butter
Ah fair enough. Then their should be an option where you can opt to download the MP version of it. Ehh I mean it doesn't make much sense honestly, because then there will multiple teams working on the different samples
ye XD
That's also why they have cheats all over the place xD
Makes sense for them to be client auth though
well its the tradeoff XD
and the fact it's listen server is worse i guess
since host is the "server"
if a cheater is the host he can bypass all those server checks i guess ?
gta4/5 online are listen server yeah
that's why gta 4 online is still up
they shutted down 5 online on old old gen tho because they had servers to maintains (for online stats etc)
I'm looking into the Iris replication system, it's pretty interesting actually ๐
Enable delta compression for replicated objects. Default is true.
What a day, i f*cked up all of my project and i don't know how ๐
Source control is your best friend ๐
I have git
Source control is only as good as your last push.
Are you using cpp?
it would have been useless tho cause i don't push my project content folder on the repo
since it's huge af
yeah
my BP does not detect my HeroComponent anymore (cpp comp)
i don't modified it
Do you have any components in your classes marked as Editable in the UPROPERTY?
Well... Yes since it was working before last night ๐
That has the tendency to corrupt BPs.
Never mark components as Editable. Only Visible.
I just did a clean compile by deleting intermediate/Binaries
it's not
i don't modifed it
i guess it's on BlueprintType
wait a sec
nvm
UCLASS(Blueprintable, Meta = (BlueprintSpawnableComponent))
but still, i don't modified it. My BP_Pawn has the same issue, all corrupted i can't put my cpp character class as parent anymore for some unknown reasons
i don't modified those classes since a week
I even can't recreate my BP since i can't add my HeroComponent lol
It doesn't need to be a BlueprintType to be Blueprintable.
It just means you can't use it as a type in BP (for a variable)
Or cast to it.
Ikr
that's not the issue tho, i don't touched anything to it since it's existence since it's a lyra component
Didn't say it was!
there is not a single error ๐
I did mention the Editable/Visible thing, which you said you do have Editable stuff. Then you said you didn't. Shrug
except when i force open the BP to say it doesnt have a parent
yes mb, i though u was talking about BlueprintType/Blueprintable
clean BP, where the f is my HeroComponent lmao
i already made a clean compile again
that's literally the last thing i modified on my project and it has nothing to do with my HeroComponent or my Characters BP
Err.. What do you need for FastArrays in UE5? Made one like I'm used to. Have NetSerialization.h included, and I'm getting a ton of unresolved symbols like FGuidReferences
i had the same error a year ago, i guess i was missing a build include
You should not even need NetSerialization.h tbh
i don't have it included
you will need to add "NetCore" module to your build file afaik
yeah pretty sure it's this one ๐
i was searching but yeah it's that
Oh, yeah. Thanks. ๐ Just looked at the .h file for that. Docs still noted it as Engine. :/
Which docs?
There's the API reference.
Trying to replicate an array of structs using with ReplicatedUsing. Calling the replication function from the server, I see that both server and client call the replication function, however on the client the variable isn't updated - am I supposed to pass the updated variable in as a parameter in the OnRep_ function?
No
When you say "isn't updated" what do you mean?
Is the array size wrong? Is the data in the structs missing?
the array is empty, whereas Ive just added something to it on the server
It may not be replicated right away or it may not be relevant.
Or the class itself may not replicate at all.
Which class is it?
its a custom class. But ive set bReplicates = true and bAlwaysRelevant
a custom actor class
A custom class based on what?
Actor, right.
Just to check, you're absolutely not trying to set the value on the client and have it update on the server?
no the function that adds to the array is UFUNCTION(Server, Reliable )
but in other news it works now
just recompiled
this always happens when I ask questions on this discord
Lol
๐
XD
I mean Daekesh is a wizard, so that could be it
No doubt ๐
What class this RPC is in?
A custom actor class I made
Is it owned by the client?
each client has their own version of this class afaik
but the replication works now
the class itself is replicated
to the clients
There's only one real solution: FFastArraySerializer.
still, be careful where you call your server rpcs! they can only be invoked by client owned actors
Then it seems you are firing the server RPC from the server so that's why it's working. server RPCs will be dropped if not fired from client-owned actors
quack ๐ฆ
hmm how can I know?
If the RPC is firing, I'm assuming it is a client-owned actor.
Player state, pawn, controller - basically
I tested this in game from client and from server, getting the same - wanted outcome
GetOwner?
Looking through the logs for warnings?
so tell us Liine, where are you calling this rpc, in which function?
beginplay maybe? (it got already server flow, so no need for a rpc!)
no
I don't get why this is till going on, it works now right? Lol.
Yes it worksโข๏ธ
it is going towards a proper understanding of why the logic is working Thom
and that's critical to understand multiplayer
mouse click happens on client, PC elevates the click to server to do some checks, then calls this function to harvest some plant in game on the server which does some checks and agrees that plant should be harvested, updates an array of plants that are harvested which is then replicated to client for them to remove for the InstancedMeshcomponent that holds them
Nothing works under my radar 
Ok then you're already on server. No need to do any server RPC from that point
The server RPC the PC did is sufficient
So what was happening is that the second RPC was executing like a normal function
executed in the local CallSpace
what if I want to go that code path from somewhere else in the future
without already being on server
I know, still it's bad practice tbh
suppose a check and RPC would be better then
so its safe if it were to be called from client
I'm not sure I get the question. Do you want to be able to validate what the client passes through the RPC?
No I mean in the use case I have right now I know Im only every calling the functions from server, as I know I go through the PC etc, but if I were to, in the future, have a use case where this same code path could be taken from somewhere else, maybe on the client
I would then need to have a check in the function to see what kind of authority I have and if its the client to a call to the server instead
if I am to remove these uneeded server calls I have now
Well you can't fire server RPCs from actors that are not owned by the client.
right
If you are owned by the client then you will usually have Autonomous proxy as local role
yea
What methods are there to create a component on the server and then replicate it down to the client? I've tried setting the component to replicate but the client still doesn't know it exists
I've tried calling a rep notify but that seems to run on the server/authority only
The actor thats adding the components to itself is not possessed by any client on start, I'm not sure if that has anything to do with it
Show code to how you're doing this?
Do you assign the component to a UPROPERTY that is marked as replicated?
Is it added to the InstancedComponents array (not sure if required)?
SpringArm = NewObject<USpringArmComponent>(this);
if(SpringArm)
{
SpringArm->RegisterComponent();
SpringArm->AttachToComponent(Mesh, FAttachmentTransformRules::SnapToTargetIncludingScale);
SpringArm->SocketOffset = Mesh->GetSocketLocation("Camera") - Mesh->GetComponentLocation();
Rep_SpringArm();
}```
yes
not that I know of
I don't see where you are replicating the component
thats being called on server and then I call the rep notify
You are replicating a pointer to the component, not the component itself
There's a big difference between the two
oh
Need a replicated pointer, to a replicated component, on a replicated actor.
So if I just add SpringArm->SetIsReplicated(true) before I call the rep notify, it'll replicate the component itself?
Right
So. About the weird Replication issue where if you only have one property, it doesn't replicate. Is there any way around that without a second property? I can't seem to cause it with FastArrays which is nice. A Single normal TArray still won't replicate unless I add another replicated property though.
hmm an array with 1 element won't replicate? but it does with 2 elements is that what you mean?
Yes, but not always. Spent the last two days fighting with a component not replicating an array. Component was replicated, resolved correctly on clients, etc. Just no OnReps, and tick printing the array length on client was showing no changes. I vaguely remembered a conversation from around two years ago that sometimes stuff with single properties won't replicate, so I just added a replicated integer. And boom, Array starts working perfectly as intended. Just wondering why this happens.
In what scenario does GetOwner() throw a fatal error? How can an Actor not have a valid pointer to its own owner?
I've got a BeginPlay function that is doing stuff, and an OnRep is firing.
Error LogWindows === Critical error: ===
Error LogWindows Fatal error!
Error LogWindows Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000168
Error LogWindows [Callstack] 0x00007ffcb8293c39 UnrealEditor-Blaster.dll!ResolveObjectHandleNoRead() [D:\Epic Games\UnrealEngine\Engine\Source\Runtime\CoreUObject\Public\UObject\ObjectHandle.h:300]
Error LogWindows [Callstack] 0x00007ffcb82a4e6c UnrealEditor-Blaster.dll!AWeapon::SetHUDCarriedAmmo() [D:\Repo\Blaster\Source\Blaster\Weapon\Weapon.cpp:297]
Error LogWindows [Callstack] 0x00007ffcb8292123 UnrealEditor-Blaster.dll!UCombatComponent::OnRep_CarriedAmmo() [D:\Repo\Blaster\Source\Blaster\BlasterComponents\CombatComponent.cpp:370]
Line 297 of Weapon.cpp is this:
AActor* Testing = GetOwner();
The issue does not occur on a listen server, obviously as there is no on_rep called. But when I change to 2 players, the issue appears.
I tried googling around, didnt find much...
Owner is a replicated pointer to an actor. You can't guarantee the owner/actor has replicated (is valid on client) when that OnRep fires.
arh... ok. What is the "best practice" to defend against this scenario?
To have a TryInitialize() function that does what you want in both places (Your OnRep and OnRep_Owner) and ofc makes sure you don't do it twice
Interesting.
is there somewhere this is documented/discussed in more detail? I just double checked eXi's compendium and I dont see it there at a quick glance. I'm just wondering if there's more to know around this topic...
Nothing really. eXi's compendium is aimed towards introducing you to networking in unreal. You won't discover these stuff until you experience them.
Fair enough. I'm just keen to understand it some more - I'll have a play around. Thanks.
Sorry, maybe I'm missing something obvious - how do I know if the owner has not replicated if I cant actually call GetOwner() since that is causing the crash? What is the mechanism to detect this?
I mean there is nothing beyond what I said. Independent actors have their own net frequency, and as a result has their own rate of replicating stuff. There is no such guarantee that two independent actors have replicated at the same time.
There is however for POD types, which if changed at the same frame will replicate at the same time.
OnRep_Owner
OnRep is called when NetGUID resolves into a valid object on client
NetGUID is just a globally unique identifier for UObjects
And FNames iirc
In your case the NetGUID wasn't yet resolved so you was accessing a null object
ok awesome - i've got something working with that. Greatly appreciated @fathom aspen
Has anyone ever tried the Adaptive Network Update Frequency system? It sounds great honestly.
https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/Networking/Actors/Properties/#adaptivenetworkupdatefrequency
It does, not that I tried it though. Wondering for how long it has been a thing
No idea.
But this is exactly what my struggle always is, it's just impossible to predict what frequency you should set actors at. Especially in many games these days where everything is dynamic.
So in theory it sounds extremely nice to have that just be automatically updated ๐
Right, I find that a struggle too. But iirc NetUpdateFrequency is the maximum frequency, so it goes down if it's not considered for replication that much
So, I managed to get kicking player from session to work. But how I can do some feedback for kicked player? Right now player just lands in default level (main menu) without any explanation or info about kick reason.
Ah ok this is the case in the system you presented, not that it's by default. That's at least how I observe it in the docs
Pass a string along with kicked player for why they was kicked
Utilize the options string
which is part of the travel URL
The default kick implementation in GameSession is really weird. It calls a RPC on the playercontroller that is about to be kicked but the result can never be used because the method isn't virtual, is not exposed to BP and doesn't have any implementation LOL.
Sad day for the GameSession. Yeah it's really sad when you need a function to be virtual and it isn't xD
๐ฆ

Honestly Iโm up for the challenge, never done it before. Although Iโll need to look through the existing PRs first.
Donโt really care if they donโt merge it.
Yeah the whole procedure is fun tbh. My first PR was at least, and they ended up accepting it because it was a typo fix lol
Now that they accepted it, I have a bunch of them on the way
I don't understand? I am aware you can add additional options to map address, but how I can add new options? That travel happens automatically after kick...
The options string starts after the first ?
yes, I know about that. Are you suggesting kick reason is already in options?
How are you kicking the player?
I'm suggesting to add it there as an option
Also this ^
gamesession->KickPlayer
if there is some different way to kick player that gives control over travel, I would like to know
Just use an RPC with the kick reason before kicking the player.
Itโs what the engine does and fails at to properly make useable
I still cant wrap my head around it. Kick causes player to change levels, so I need way to inform game about it that can survive that travel.
map URL options would be great if I knew how to add options in this particular case. After all, I do not initiate travel - game does that automatically.
If you send a RPC to the client with the reason you can just store it somewhere and then retrieve it later on.
The engine / game session doesnโt seem to store it.
where? game instance?
For example.
My fears were real. Seems like the OSS does it for you
Are you using Steam?
no, EOS
Ah at least you are using one
I can modify that plugin, actually
I would look at what EOS does and try to modify it
(I already did it to remove some dumb bugs)
yep, I guess that will be way. thanks!
Yeah that's expected, considering they are the new kid in the hood
does this not work because the gate is on the client?
Gate is a macro that uses a local boolean. So this is ofc won't work as those are different ends.
better way to do this just use a replicated variable?
Not even that. Pretty sure GAS has its own way to handle that.
i dont use gas
Ah the names implied that. Then just fire a server RPC on input press that enters the gate.
Why is the game session kick system.. The way it is lol.
So by marking a member of a struct with NotReplicated it is essentially treated as a local variable correct?
And if this member was to be changed on the server but no other members were, the struct would not get replicated down?
Im trying to replicate setting the players Skeletal Mesh in runtime but can't seem to figure it out. I tried making a Skeletal Mesh varialbe RepNotify and then set the characters skeletal mesh in there and no luck. I have also tried setting up two different events, one on server one on client, to set the SK and no luck again. Any suggestions?
Make a replicated SkeletalMesh pointer. Add OnRep. when OnRep runs set character's Mesh SkeletalMeshComponent to the new SkeletalMesh. Set SkeletalMesh pointer only on the server.
Yes and most probably
using repnotifies, is there any way to ensure one notfy gets called before another?
Should property check functions be called on the server or the client?
For example, a function that checks if Health > 10
Most probably server. You don't want the client lying about his health and thus not dying. But if that is for some cosmetic stuff then it's not a big deal
There's not really a golden rule for it though. It just depends on what you want to do. Something like health is generally better to keep server sided, but it's not weird for a client to check if the health is smaller than a certain threshold and then maybe do something UI related like a flashing healthbar for example.
They will go in GetLifetimeReplicatedProps order
With FastArrayItem callbacks going before any OnRep
That is the case for POD types that are changed at the same frame and ofc in the same translation unit, right?
Its a general case
This is a TIL, amazing
If you csnt resolve an object replicated property points to, and you dont have repnofify always obviously that onrep wont fire at all
I should read more through the RepLayout and ObjectReplicator files ๐
But the order still remains intact
Right right. Makes total sense!
Note that i would not trust blueprints not to mix up their props
Ah right, totally forgot about those bastards. I could see them as a potential threat
If you added them in order, and msrked them repnotify in same order and havent rearranged the order sure
But bp has some funny serislization quirks
But how do they compare to the cpp props in general. Who gets the lead in the replication order?
It depends on how the NetDriver gathers props I guess. I would guess the cpp ones go first...
They are inserted at random every time you start up Unreal >:D
If the client needs to change a replicated variable, should that be done through an RPC to the server?
Yes.
If the client wants it to be reflected to others then yes.
Clients can only communicate to the server through RPCs.
Server ones to be specific
hm okay
to the server
๐
Also Wizard I have an idea for a blog post for you. Make a few random multiplayer features and post it as a post with "Here are X ideas to practice building multiplayer features!" ๐
I can literally not find a single thing on Google doing this.
Hmmm. That's more like challenges/quizzes right?
Challenges yeah.
That sounds great tbh. benui is doing something similar atm and it sounds cool
Thanks for the ideas 
make one about removing and adding instances of instancedmeshes from the foliage system in multiplayer
then link it to me
for... reasons
Lol
๐
Yeah it's turning great Thom, yea
I should make my own blog and just do challenges my self honestly x)
It's just annoying how little general info there is on the internet about multiplayer or even more fun things like challenges, interactive websites or whatever, when I first started in Unity and wanted to try multiplayer it felt like absolute black magic. Everything seemed like it was impossible to do because of complexity.
Then most resources online are just about how to do very specific things or talk about the concepts behind stuff. Which as a beginner back then was absolutely horrible to work with for me.
Time to start my own course guys ๐คฃ
Agreed. Not long ago I looked for Unity networking resources and I barely found a few. In Unreal there are much more, but it doesn't usually mean that it's better (you know bad tutorials exist).
I'm also pushing you to make your blog, I have enough posts on the list xD
I feel like the unreal ones are so basic that its hardly applyable knowledge
You are gamedev.tv now?
Lol.
Correct, basic and misleading. (FTFY)
that depends where super call is
if (const UBlueprintGeneratedClass* BPClass = Cast<UBlueprintGeneratedClass>(GetClass()))
{
BPClass->GetLifetimeBlueprintReplicationList(OutLifetimeProps);
}```
something like this replicated BP props
Ah right Super gathers BPs
And it's usually at the start
Interesting.
So after an extensive research I found out that UserWidgets persist a seamless travel for the following conclusion:
Upon seamless travel, any UObject (non-Actor) that is outerโd to a persistent Object will also be persistent.
The persistent world is always torn down regardless of the travel type. I couldn't yet prove the above conclusion, but I wrote my findings and assumptions on the topic if you're interested: https://wizardcell.com/unreal/persistent-data/#persistent-non-actor-objects-across-seamless-travel
I also didn't look into the MoviePlayer part yet. Hopefully that will provide me with some useful insights when I do, but for now I can take a break from this ๐
Also huge shoutouts to you for pushing me to write this!
Maybe the wrong chat but does the Steam subsystem support cross region lobbies?
what dependency do I need to add for macro MARK_PROPERTY_DIRTY_FROM_NAME ?
the answer is private "NetCore"
Hello, how skeletal mesh socket replication works?
When i try to replicate and draw socket position, position on server are incorrect(stays in default position), but animation and socket fully replicated on clients
Green == Server
Pink == Local Player
Blue == Network Player
Size just for visualization
I've noticed a different issue myself which is the socket on the server is correctly where I placed it, but on clients, its not, still not sure whats causing it yet
Fixed
In Mesh Optimization
hmm in my case this was already set
its strange, it lets me move it on the red and green axis, but the blue axis, only on the server takes effect
now that I take a closer look, it seems like it does let me move it, but the actor I have attached to this socket does not move to the socket blue axis position for some reason
I have HTTP request that returns just 0, without any fields etc. How can I grab this in varest?
Is there a way to know when the playerstate is valid on a listen server? On_Rep playerstate doesnt fire
You mean the Hosts PlayerState?
It will likely be valid immediately after the PlayerController is created.
The reason why its delayed for Clients is simply due to it needing to be replicated.
But since the Host is the Server, it doesnt need to have it replicated.
Gotcha, thank you. Thatโs what I meant. So itโs safe to do any logic I need initially on begin play or perhaps on posses?
On Possess would likely be better, but keep in mind thats only called on the Server
Yep. Thank you!
Was a good read. Thank you. ๐
Just wanna double check I'm not missing anything. Replicated variables replicate after construct, right?
For example, I spawn a weapon on server and replicate it. I have a PossessingCharacter variable that's replicated and set to expose on spawn with a value passed in. Yet when I try to access it in Construct, client show null ref. The only way to get this working so I can know what character is "holding" the weapon is to make a repnotify for the variable and call an Initialize function after it updates.
Seems like a poo design choice of the engine because it's counterintuitive and causes many problems and workarounds, but maybe there's a deeper code limitation with not being able to use passed-in variables in a contructor? Am I correct in my assumptions?
Expose on spawn means, that if you spawn this actor from blueprint, you'll get a pin to pass in the value to be set.
Aside from that, Construct is called before anything got replicated, so the earliest you should try to read values from replication is BeginPlay. The current state of all replicated values for an actor is sent with it's initial bunch. If you set the value after a new actor channel opened for this actor, it might get replicated later.
Thanks. Thing is, it's not set when accessing from the constructor, even if I did set it by passing it in. Shouldn't require replication to set a var so it's weird.
It does require replication. This is not a POD type, but an actor. The client has no idea it exists if it was not replicated or loaded from package.
OnRep is the way, and engine already does that using OnRep_Owner. At the time you attach your weapon to the character, the character gets assigned as Owner.
Is it normal to achieve severe rubber banding/character sliding when using default character movement component as a client using steam? There's no issue if both clients have decent hardware/internet connection, but as soon as I try it on my ancient laptop, I practically can't even move. What would be a good approach to fix this issue?
So long as you are applying input correctly (via Add Movement Input), you should mostly be fine.
Also check if the game runs properly on that device when offline first
It runs completely fine, I also tried setting client authoritative movement just to test it, and it fixed all issues but client authoritative movement isn't the way to go. Why it's confusing to me is because I just use the default 3rdPersonBP movement:
But the rubber banding and sliding (character keeps moving even when client doesn't hold any key) is unbearable
hi, does anyone know what could cause this type of error? everything worked just fine recently on old pc, where server would normally run, it's still old package which was running, also port on pc doesn't seem to be working.
Seems the port on your router is closed.
If you've changed computer, it's possible your router setup is broken...
On GameLift, if I have a fleet with ports 7777-7786 open, how do I specify the port I want a game session to use when I create it?
How are you creating the game session?
Via the AWS CLI.
Are you specifying a map on the command line?
Or some sort of URI
if you use the console command to change maps, you can do mapname?port=xxxx?otheroption=y?etc=blah
Hm, looks like I can pass specific arguments to the executable via AWS CLI's --game-properties argument; I'll try that.
Hello, I'm using a full body mocap, I would like to delay the animation of the 1 fronted character to several behind, anyway I could do this ?
#animation might
Not sure if this is the place for this, but does anyone here know anything about the general techniques behind WoW's client and backend? Like how their buffs, spells, casting, and movement are done?
It feels like it has some prediction but I'm not sure it does. I've never noticed a rollback on anything but movement.
@summer nova ^ I think you looked into this extensively
@dark edge you have the code on the wow pirate/private servers like MANGos
I'm trying to get my app to integrate with steam using my own steam app ID. I can get a player to connect when I use the general testing ID (480) but not when I use my own steam app ID. When trying to use my own steam app ID I am only changing the value for the app ID in the ini file. Is there any other change I need to make to get it working with my own app ID?
What's the general approach? Is it doing a clientside prediction type thing a-la GAS or is it all serverside? I know there's a big input window for inputs but it feels loose and yet tight at the same time. Kinda hard to describe.
@dark edge mmos are a whole different thing
to begin with, the client does more or less nothing but to play vfx
but it depends on the thing
for example inventory management is 100% server driven. The client does no logic whatsoever. If you have lag, its slow to rearrange items in your bags
for movement its all done clientside, and client sends movement information to the server
the server accepts it with no validation
damage/effects/etc are completely serverside
when damage numbers appear is because the damage was processed on server
You sure wow doesn't do corrections for movement?
So far what you're describing is a bit like if you did ACharacter(CharacterMovementComponent) + a spell/buff/stat system (with NO prediction) + input buffering (the cast timing window), that seem about right?
This is from inventory component attached to ThirdPerson character. It is replicated component and "Inventory new" is replicated variable.
This is from player interface event
This happens in game mode to save
Those inventory variables doesnt work but health and location etc works
Why is that?
@dark edge the wow server does absolutely nothing for movement
this is done to save performance, no need to raycast against terrain and similar
thats why things like speedhacks or flyhacks are quite common
I wonder why I haven't seen any cheating for a long time
maybe they're pretty heavy handed with the banhammer and since wow implies at least a decent amount of investment in the character you'd rather not risk it.
on wow classic they give 0 fucks
botters flying around have been there for a while
and moving below the ground
I'm talking retail, maybe retail has some more stuff
its the same server
mostly
its more that they ban people who get caught
but botters dont have an issue. new account gets made and the money gets sent to other places quickly
@summer novahttps://trinitycore.atlassian.net/wiki/spaces/tc/pages/2130106/Spell+handling+in+TC Very interesting
@whole grove you understand they handle a thousand players in one server
or more
movement is something that updates every single tick for every single player
I mean doing wow movement server authoritative wouldn't be insanely hard, but if they don't need to do it, the easier it is for them.
You have walking, flying, falling, swimming, and launching/jumping. THat's about it.
It's basically the CMC
also no collisions between pawns
it would be insanely hard
again, its 1000 players
CMC becomes the number 1 perf bottleneck in unreal engine at 100 players (battle royale example)
Oh it'd be heavy but code wise it wouldn't be anything groundbreaking
not worth it
you could use that cpu time to shove more players, directly lowering your server costs
thing is, because you need to buy the game, if there are cheaters they can just be banned
and you get extra sales
the trinity core and mangos server use to run 5000 players
on a beefy machine
thats with their fairly atrocious code really. I worked on some experimental tech where we could process replicated movement for 20.000 players
not 20k connections but 20k pawns running around, iirc, right?
the connections were simulated. getting 20k real players at the same time is not something that can happen lol
LOL. That reminds me of Splitgate.
To be honest, I would not want to scale a system for up to that many people. Does not sound fun.
Really struggling with implementing networked functionality and think Itโs because Iโve managed to screw up my understanding of what the client should be. Right now Iโm thinking of the client more as a visual reflection of the server instead of itโs own instance of the game which should maintain an accurate reflection of the serverโs instance. Am I right in thinking Iโm wrong?
For example, the client performs an action, the server is told and performs the action on its instance, correcting the client if wrong, the action is then replicated to the other clients, and they perform it.
No, you are not right in thinking you are wrong
Clients and the server are their own instances. With the exception of listen servers where a client is the server. The server is responsible for keeping clients in sync with its own view of how a world is. Clients donโt necessarily have to be a perfect reflection of the server though, with for example predicting character movement the client is in the โfutureโ compared to the server. Itโs a big mix of a lot of things ๐
if you can handle a couple thousand players concurrent in your game, that means you as an indie only ever need 1 server for hosting
even if its like a 5v5 shooter, if you can stuff 20 matches at once in 1 machine, thats a huge improvement
valorant does that for example
saves them loads of money
The company I work for has a game with a 1vs1 mode, in Unreal terms their โworldsโ are a separate thread running compared to other โworldsโ. Saves a lot of money probably to indeed not need a new instance per 2 players ๐
yeah I was wondering to what extent you were simulating... was it just AI's and just considering server overhead, or also bandwidth?
@pallid mesa a mass of pseudoplayers moving randomly
each pseudoplayer basically had a small AI script that updated its positions as if it was a real player wandering about. The rest of the engine thought they were real players
movement replication was realistic
does the validate from RPC have the potential to crash the server?
it could notify the system to disconnect the client/server who initiated the RPC call.
no
Well, unless you do something inside it that crashes the server
But by itself no
Where can I read the "additional server game options" in the editor preferences? I though they were on the client open parameters but doesnt seem to be the case.
GameMode.OptionsString?
hmm the only thing on that string seems to be:
Options String: ?PktEmulationProfile=Average
So it just disconnects the client from the server?
how do i get a reference to the widget on a client?
I made a reference to the widget as it was created in the character blueprint(the widget shows up on both the client and the server), but the reference is null for the client character and only works on the server
i do this, and the GameplayUI only exists on the server
Widgets are local only
what are you trying to do
Can someone explain to me what the reliable and unreliable tags actually do
Reliable means it will happen, eventually, and if it fails, it'll keep retrying.
i am trying to change some stuff on the widgets depending on which client did it
Unreliable is just fire and forget.
Use reliable for stuff that HAS to happen, and unreliable for stuff that is ok to mostly happen
One of the networking devs of fortnite said they set all RPCs to unreliable
Widgets should reflect state which lives elsewhere
Sounds about right
But they probably don't use RPC for stateful stuff
Something about it being sorted and issues that come with that, but itโs really just a mystery to me
one of the things that i'm changing is the score, which is supposed to be replicated on both, but it only changes on the server
They say it just resends the request but thereโs more to it
Score should live on PlayerState or GameState
or maybe Pawn, depending.
Wherever it lives, it does NOT live in a widget
widget just DISPLAYS the score
my score does live on the game state
but i can't get the correct widget to display the said score
K so what's the problem? Have you confirmed that score is replicating correctly?
yes, without the widgets updating, it works fine
Create a binding for the value, access your gamestate, fetch the value
Here's the thing with reliable. If its called "too many times" you could end up overflowing the reliable network buffer because all of those reliable RPCs have to be processed and won't ever be discarded. If that happens the client would automatically disconnect from the session.
So what counts as "too many times"? Probably a few actors calling reliable RPCs on tick or something like that.
shouldn't this be enough?
this still only updates on server
Make sure TeamB Score is replicated
sorry, i guess it wasn't replicating
one more thing, how do i do a similar one for player state(for health, which is on my player state)
get player state on the blueprints asks for a player state index, can i just give 0 and 1 for two players?
Access controller, access player state.
So just call get controller on your pawn. Then just get the player state. I'd recommend making something like this a BPFL
Guys, a quick doubt about events. I have this replicated event that casts to a component that has a replicated event calling a function. I'm wondering, if I make the first event call the function, it will be replicated? Or maybe having another replicated event on the component calling that function is necessary?
I'm laughing so much of that reaction because I feel the same 
Let me rephrase it, I have an event calling another event that calls a function. Both events are replicated, one of the events exists only to call that function. Is it okay having only the first event directly calling the function even if they're not from the same actor? 
Does anyone know how to set those inventory component variables that server can get those? Calling that function in dedicated server game mode to save.
hi devs , "PING" is this time taken for info to reach the server and come back , or only time taken by server to respond to client ?
There and back
I'll take some screenshots when I get home
by event I mean custom events, like event dispatchers, and by replicated event, I mean an event that is set replicated and runs on the server (or client etc)
It's hard to tell without seeing code, but seems like the other replicated event is redundant. If the second event is aiming for the same end the first event aims for then no you don't need the second event to be replicated (to be an RPC). @cold moat
Has anyone here had any issues with Gamelift on any version of Unreal Engine newer than 4.26?
4.26 is the newest supported version. I'd like to use a newer version of UE, but don't want to run into any show stopping bugs.
Why casting game mode on begin play in character class work for all clients and server but when pressing button ,it only work for server? I thought that the game mode class only works for the server, but in the test I did in Begin Play, it also works for the clients. why?
where other parts Gamemode works for clients?
It's "working" because every client on his machine has the BeginPlay event firing on both server and client. On server there is a valid GameMode, but on client there is none
For input, it fires locally, i.e. at the local controller level.
The host has the local controller at the server so it works for him
Other clients has it client-side so it doesn't
so the game mode exists on the client, but has no authority and no influence on the game, basically?
With this you will be getting "Accessed non errors" because the client is trying to access the GameMode and it's null
That's why you need to SwitchHasAuthority for example and use authority pin
Epic should port the behaviour where derefecering a nullptr crashes the game to BP ๐
Yeah maybe after they make TMaps support replication
Is that a pig I see? In the sky? with wings?!
so every client for all classes in the engine on his machine has the BeginPlay event firing on both server and client?
BeginPlay is an actor function
In the context of Pawns it does, yes
In the context of HUDs it doesn't. It fires locally
So it depends on which actor are we talking
Gamestate has an array of all playerstates, and you can obviously get your own whenever you want from pawn or controller.
I like how I edit and save
how clients can access to gamemode variables? I mean how can use RPC for that?
They can't.
You can't.
Ever.
Like you can't divide by 0 for example
Lol
The universe explodes.
On this topic, do you guys put logic in Gamestate or mostly data and do the logic in Gamemode?
I almost feel like they should have named it GameController and not GameMode
Some people disagree.
as an example , game will be finish and in game mode we have a function which announces it, How can this be announced to clients?
To parallel the PlayerController and PlayerState
It doens't control the game, only the current mode.
I always get confused on when to use gamestate and gamemode honestly ๐
Except when I need to replicate something.
GameFacilitator!
Iterate through PlayerXXX class and client RPC
I mean it does tho. It calls all the shots and is the top dog
AGameMode::Broadcast already does that @shy yarrow
I like to keep state only in Gamestate. If I find myself gating by authority, it goes in the Gamemode instead usually.
OnRep in GameState
so I can use joined player array and use RPC inside the players class, right?
Or a multicast event in GameState
The State of the Game is that it's over, here's your winners. Congratulations
Yes, OnRep is also one way
Yes, not GameMode. GameMode isn't a replicated actor, nor owned by client. So client/server RPCs won't work there
I use GameMode as the rules of the game. The things that only the server care about. GameState for transmitting data from GameMode to clients.
Depends on your definition of work!
They work, just maybe not as you expected. ๐
Does RPC works in blackboard tasks?I want to use for AI tasks
They are not actors, so no.
Probably not. You should use an ai player state for that maybe?
Do ai player states get replicated?!
They do.
They should. It is a player state
They are by default at least
do you know a good PDF file for learning this stuff better?
Wow.
Network compendium
Yes. This channel pins
I think you may be the only person to ever ask for a PDF regarding UE.
Lmao. This tbh ^