#multiplayer
1 messages ยท Page 673 of 1
Remove the Number print you have, and print whether the RPC is running. Print if the client is trying to send it and print if the server is running it.
the number print is the length of the array
and whats RPC i am new to multiplayer
RPC is RemoteProcedureCall. Your Server event.
Yeah. Also one when your client tries to send that message.
begin play
and the other on the on player join
Make sure your logic for this on beginplay is behind a branch for IsLocalController
yes did that, now client gets updated to array length 2 but server remains at 1
Show me what you have so far?
@kindred widget
Move the IsLocallyControlled check before anything else on Beginplay.
u mean is local player?
now client's one doesnt add
How many players are you playing as, and with what setting?
2
ONE AS LISTEN SERVER
oops sry for the caps
and the other one as client
Did you stop the prints for your other actor from earlier?
the other actor?
yes
i am currently printing from the controller
Then I'm unsure. What you're currently doing should work. RPC from local controller's beginplay, add email. Should add one email per connected client including the host.
๐ฆ
I have a simple problem which is deceptively difficult to solve.
I want to attach turret-actors to vehicles in a multiplayer game. You'd think this would be easy. So far, it's a nightmare. I've tried an "ATTACHMENT" variable on the turrets which points to the vehicle, and ONREP attaches it for all clients. This works, but only intermittently, seemingly because of unreliable netculling between them.
set car as the turrets owner
have it use the car's relevancy
attachment is replicated by default
you madman
in all my years, I've never had a reason to set an actor as owner over another
Hi there, I just need some small pointers as I am doing networking part for the first time and trying it out.
In which class should Authentication, Matchmaking, and all the networking part be handled in?
should it all be done in Game Instance or do they need to be done in different class? if so, can someone explain em to me?
Game instance is totally non replicated
But clients can save data there
GameMode GameState PlayerState PlayerController, those 4 will make the most sense to perform most of your networking logic
Thanks @low helm , appreciate it.
It's common to put some connection logic in the Main Menu widgets, maybe this isn't like.....the greatest idea. It's still probably better than putting it on your GameInstance, cause then it's always loaded.
I have a question on replication. I have an array of UObjects. The array is marked as replicated but for some reason the contents are not. When I get an element from the array, it is valid on the server but invalid on the client. The array length is updated on the client whenever I add or remove from the array.
Could someone enlighten me a bit more on array replication please?
Oh, so they have to replicated before being added to the array
thanks
Well they need to be replicated as well as the array
Okay. Let me read the blog before asking my next question
You can only refer to a UObject through replication if it's either a) stably named or b) created via replication, as the sub-object of an actor
Hmm. I understand b but not a.
Ahh, I see.
Unfortunately, there's no way for my UObject to be a subobject. Its immediately added to the array as soon as it is created
But it must have an outer of some kind?
The only way to replicate a subobject is via an actor, there's no workaround
These are UObjects that you are creating with NewObject presumably?
Yeah, so they'd need to be created using an actor as the outer, and that actor implementing ReplicateSubObjects for them
I'm reading through the blog now, and I'm seeing an almost exact solution to my problem. Its for the inventory also
Right. Thanks
@chrome bay , you aren't using RPCs anywhere right? for creating and destroying
Im having an issue with the thing im working on, I was trying to swap characters when I hit a certain key and it works fine, but when testing on the second player it started giving this warning
LogNet: Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor Character_C_2. Function ChangeModel will not be processed.
And then it gave that warning everytime even when I went back to the first player, anyone know what this means?
Nah just creating (+ destroying) server-side
Okay.
For the actor component implementation, we replicate subobjects in the actor component class but using the parent actor of the component as the outer. Correct?
yeah
If you use the component it tends to break things because client-side, they are always created using the actor as the outer
What's the point of item as UObject vs item as UStruct?
Alright. Thank you very much for the help
For me I'm using it for different classes of slot that have their own properties etc.
For me, due to the nature of some of the variables in a slot(UObjects basically), I chose to use UObject based on Lorash's advice. He said its bad to mix structs with objects
Also, I have some Inheritance stuff too.
But yeah for most inventory, you'd just use a struct or something most likely
My actual implementation doesn't replicate the objects now, they're created deterministically at each end and stably named
Which is naiiice
True. That was my initial implementation. But due to some design decisions and the variety of use cases of a slot. For example, character body parts are inventory slots in themselves.
Yeah, it has limited application tbh but can be useful. The only reason I really need to rep anything is because the slots are initialized from tables, and may have different layouts etc.
99% of the time though, a struct or actor comp is fine
On a side note to UObject replication. I noticed there some form of crazy slowdown when replicating a bunch of UObjects. As in about maybe 300 max. But only when testing in PIE with multiple windows. I read somewhere that it has something to do with some insane logging or something but could never find out what that meant or if there's a way to disable it?
Hmm nothing I've noticed
Quick question. What does the meta attribute DeterminesOutputType do? Also, do you know any docs on meta attributes, the official doc isn't very helpful
In BP it automatically converts the "Return" value to the same class as the input class
So it's just a convenience thing to avoid an extra Cast node in BP
Oh? That's nice.
tbh so many meta attributes aren't documented, they're like gold when you find them
lol. True that
My favorite isn't even a meta. I HATE pure blueprint nodes that return Arrays most times, because they're usually getters that do a bunch of looping... Which when properly marked in C++ are marked const.. which are automatically pure nodes in blueprint even when marked BlueprintCallable. You have to explicitly mark them (BlueprintCallable, BlueprintPure=false) to get them to be an actual non pure node.
Quick question; If I have several players, I would need several save files, right?
Depends on what you're saving.
Depends on game style.
If you're talking like.. ARK server. One save file saves everything. Or at least mostly everything, they save some data in separate files.
Where as at work, everyone saves all of their own stuff locally. So.. technically multiple save files, but it's all done locally on client so they only have their one file.
True that.
Kk, thanks
What would the OnRep method signature for this look like? Is there a complete list of valid OnRep signatures somewhere? The only one I know of is const T& to get access to the previous value.
Yeah the same
Oh it's just OnRep_Array(const Array& previous)?
So I have to compare each of the elements to determine changes
yeah
Awesome
So far as I've seen this replication stuff is pretty simple
It's a little odd that RPCs have to go on owner actors only
Could be easy to end up with spaghetti actors with all the RPCs
Is most of the complexity dealing with race conditions, throughput, and deployment issues?
Generally it's to avoid cheats and encourage a decent architecture, i.e. a client can't just ask the server to do something on an actor it doesn't own
Oh I can see that
The concept of "ownership" allows you to restrict what items a client might be able to influence
So far my validation methods are "return true"
yeah tbh most of the time they are ๐
If that Validate func returns false, the sender is immediately kicked
In my case, I'm working on destructible terrain (through voxels). It would be nice to put the RPCs on the voxels themselves, but they will have to live on the pawns.
Well it depends
Thus a little bit of creep towards "spaghetti" actors
The pawns themselves shouldn't care they live in voxel based worlds
you may instead have a general "voxel interaction" component that handles the RPC's, that can live on the controller
Yeah or the controller. It's a common approach for "interaction" systems for e.g.
I'm really big on single responsibility / single purpose in software design
I.e imagine a scenario where a crate can be opened by lots of players, they can't all own it, so the solution is to build a general-purpose "interact" system that sends an RPC, and passes the crate as the "target" of the interaction
That's really clever
And either the pawn or controller would have one of those comps
It gets around the limitations of ownership
yeah
But doesn't pollute actors that shouldn't care about interaction
Exactly
How would time sensitive details like melee attack combos be typically handled?
IE games like Dark Souls or Monster Hunter
Where you have to press the attack button at specific points of the animation
Due to latency, you can't be too strict on enforcing it
Hard to say, something like that might be determined entirely client side
But if you wanted to validate it, you would need some tolerance
I was thinking of adding some very crude validation
Attack 2 has to happen within 1.5 seconds of attack 1
The animation is closer to 0.75
someone may have done a validated combo attack with GAS
But would give plenty of leeway for latency, without giving a blank check on spamming the more powerful attack of the combo
(for cheaters I mean)
It's similar to the cooldown latency problem
yeah pretty much
Where else can I expect to see complexity with multiplayer in UE?
I've done a bit of dev ops for teams, so I'm not too concerned about services and dedicated servers, etc.
For my game I'm completely removing match making from the equation by keeping it LAN style play
Listen servers only
Anything involving client prediction is finicky usually
Oh ok. That is good to keep in mind.
Epics advice is to "predict as little as possible"
Assuming you can anyway
GAS tries to build it in as a fundamental concept
Right. I've already decided it is impossible to predict my terrain destruction
Anything physics-based is inherently a bitch
I'm working towards a slower paced combat style that won't be hurt by the latency
Ok that makes sense, the purpose of chaos is to make things deterministic
Other than that it's just the obscure race conditions that only present themselves 3/10 times in a real world situation
But you kind of learn to code around them as you go and find them
Awesome
Then it becomes second nature
It sounds like UE4 has solved the real complexity for us
I'm super familiar with the pitfalls of cross-platform serialization
Haven't done "replication between simultaneously running simulations"
yeah cross platform problems you don't really need to pay any mind to
But I have dealt with versioning, asset distribution, etc.
I mean the backend side of things can still be a pig at times
Is there a built in solution to validate the server and client is running the same game version?
I've had to build things in the past to allow any version of client to connect to the server to retrieve data. Super PITA
Saying client and server has to be the same version solves a huge list of problems
Thanks for the help! I've gone from "this all sounds terrifying and complicated" to "I've worked with much worse, this is going to be awesome"
I won't say it's entirely free of headaches but it's pretty good ๐
Quick question about replication - currently I'm using "get base aim rotation" as it's replicated by default; using it for my animation BPs head movement.
I've disabled all the "use controller rotation yaw / pitch / roll" options, but with the yaw option disabled it doesn't replicate.
I need it disabled as otherwise it makes the head turn too much and the body move along with the yaw rotation.
Any easier way to fix this other than creating another variable to replicate instead or something?
turn on your cmc to use Control rotation
if you don't want to use control rotation, then yaw will not replicate.
cmc?
So best way is to just use controller rotation yaw and fix the unwanted body / head rotation
CharacterMovementComponent
i counter rotate the body
and this is what i achieve
this all animation blueprint magic ๐
@chrome bay , thanks again for the help. I've gotten round to implementing the code example and it works perfectly well.
I only hope I'm not making a mistake replicating the entire inventory.๐
That is amazing! So smooth!
Total magic level stuff there
capsule always rotates, i just counter rotate the root bone
then when it hits threshold, i bring the root bone back with a curve
Here I am building with legos and @meager spade is busy carving a Michelangelo
OnRep isn't called on the listen server, yet a lot of the logic in OnRep also needs to happen on the listen server. Is it safe to directly call OnRep on a listen server in response to its own changes?
Doing so is not going to be 1:1 the same as how it happens on the client
Because the client resolves OnRep as an aggregated delta against multiple changes
So if the server has multiple changes in a single frame that invalidate themselves, calling OnRep directly on each change will give a different answer than the client receives (potentially no OnRep calls)
i find that approach.... impractical
generally, i'd make a SetWhateverImReplicating function
that i'd call on server, and from OnRep
i prefer my breakpoints not hitting inside OnRep functions on server
Does anybody have a workaround for replicated properties in an actor component not being set at component register/initialization time? Annoyingly the owning actor is fully initialized and runs postinitcomps before any default subobject props are read in
Grasping at straws atm, trying to see if there's a way to grab any "pending" value from the net driver/actor channel or something but coming up empty handed
If the component is spawned dynamically or the actor was placed in the world, it's not a problem - it's only actors which are spawned on the fly and their default comps ๐ฆ
whats a good way to replicate weapon sounds like right now i use a multicast to replicate my guns sound every time it fires but if there is lag it may cause all the sounds to bunch up and bee off sync to the gun
This is a really good point. Would be super confusing to hit a breakpoint on server you expect is client only.
I don't understand it enough to explain it, but look up BurstCounters
Oh wait, those might not help
You'll need a "cooldown" for the SFX
@chrome bay for us, its usually OnReps that fail
and doing RepNotify_Always usually fixes it
what if its a automatic weapon with rapid sound
Start a timer on the client to automatically simulate FX when it thinks the weapon is firing
Works fine so long as you have a fixed fire rate
Even multicasts/properties won't arrive at a fixed interval
we did have a scenario where actor responsible for procedural map sync did not replicate its initial data if host changed any settings before people joined his lobby
When does PostInitializeComponent happen in relation to replication?
on fucking release day
๐
I've got a really obscure setup, but essentially what I've found is that the actors construction script runs before sub-object properties are read in
Nice job QA!
But only if the actor is spawned
so would i send a rpc i tell it to play the sound every number of seconds before i tell it to stop?
our QA is lowest bidder that the publisher found
and they are worth every penny that way
The only way I can get around it is move the property to the actor table throw
Awesome
releasing a DLC tomorrow
engaged our own + community testers
last 2 weeks
im under constant fucking ambush by a barrage of critical bugs
that our QA did not find
Are you the Senior on the project?
lead programmer
Yeah, that's just the job description
But you have my sympathies non-the-less
I left the game industry for 3 years hoping it would be better
It wasn't
And the job was boring to boot
mine is everything but boring
not boring enough
@chrome bay not on both client and server
with deferred spawn, construction script on server runs only after you call FinishSpawning
instead of sending a multicast when ever the gun fires could i instead trigger the sound when ever the gun fire animation plays on the client
on client it waits for OnReps to call BeginPlay, but runs construction immediately
The idea behind BurstCounter is that you use a replicated int and OnRep calls instead of RPCs to determine when to run the effect
Basically BurstCounter > 0 means play the effect. Or something similar.
I haven't studied out Burst Counter enough to talk about the nuances
There's a lot of documentation on the concept around the web though
ive looked it up but all i find is doing it for c++ in UE
It has several advantages over RPC, but I don't intuitively understand the system well enough to articulate them
Oh right.. it is more a c++ thing
Sorry I assumed C++
Say I have 10000 static actors (buildings) in my level, and ONLY their visibility and collision settings need to be kept in sync between server and client (and only ONCE, basically from "Alive" to "Dead") -- what's the most efficient way to keep the state in sync?
Does this actor need to be replicated or should I just maintain a replicated TArray of "destroyed" objects in the game state that clients can access to manage their own state? Im not sure how much server overhead is associated with having that many actors to check for changes on every network update
i think Jambax's blogging career started and ended with burst counters ๐
@mighty garnet are they net addressable by default?
say, placed on the level
yep they're placed in the map
then a fastarray
ooo whats that
It's really cool, but not well documented
Fair enough
docs are in NetSerialization.h header
I searched google
This is the best source
header is litearlly more then half comments
Most the info I found on Google was actually WRONG, so I was a bit confused
even has a #if 0 example of implementaiton in it
sick
Helpful tip: Add an Owner pointer to your container and use that to chain out your rep events
Oh you mean don't make the owner a UPROP
you do not want to know what shit inherited blueprints put in there
Doesn't the container need to be a UPROP to replicate?
OMG
I finally get why C++ needs to use weak pointers
I'm a single man team not working with designers atm
Right, you need UPROP on the container reference inside the owner, so the fast array can be replicated
But you don't need UPROP on the owner reference in the container
Also, even though you mark the fast array as replicated, and do DOREPLIFETIME, it doesn't look like the OnRep function call even needs to be declared for the fast array
At least in my (limited) testing it seemed the OnRep function was ignored
Does it need the const T& method signature?
I wasn't getting OnRep to fire yesterday when experimenting with fast arrays
it doesn't
But I did have all the internal rep functions
I'll have to do more testing it seems
I want to understand the full lifecycle on these fast arrays
They seem very useful, but potentially just complicated enough to bite you.
does it explain this bit about container ownership because Im lost on that lol
i am using network managers
Not really
In my (dirty) test code I have this:
USTRUCT()
struct FExampleFastSerializedArray : public FFastArraySerializer
{
GENERATED_BODY()
UPROPERTY()
TArray<FExampleSerializedItem> Items; /** Step 3: You MUST have a TArray named Items of the struct you made in step 1. */
AMultiplayerCharacter* Owner;
// SNIP```
Just above SNIP I have my owner reference
For production use, I intend to put an interface pointer instead
Or you can use a weak pointer
In my AMultiplayerCharacter's constructor:
Then in the optional replicate calls I did something like this to call out to the owner:
{
InArraySerializer.Owner->OnReplicateRemove(/*Pass whatever details you need to the owner*/);
}
This is the replicate call on the individual item
You'll note the container comes in, which in turn has a reference to the owner
OnReplicateRemove is a function I defined on the owner in order to do game logic
oh super helpful thanks -- what's the purpose of using Owner rather than just defining OnReplicateRemove inside FExampleSerializedItem?
It's to make it easier to pass game logic outside the array
As it stands, the OnReplicateRemove is only going to know what FExampleSerializedItem knows
Which is perfectly fine for a lot of uses
But if you need to modify something like UI based on the changes to the element, it can be helpful to chain the event to your actor
ok so your character here will have some context that the item doesn't, right...
In your case, your FExampleSerializedItem will probably know about your level placed actors, so you might not benefit from the owner pointer
Exactly
Ok and last question, just so I can argue intelligently with my coworker -- what's the benefit of this approach over the default actor property replication in my case?
I understand it will be more efficient but exactly how or why?
I'm still learning how this works
But for me, the advantage of FastArray is that it is easier to tell an item has been added, removed, or changed
Applying UPROPERTY(Replicates) directly to a TArray gives you a copy of the array prior to the change
It is up to you to determine in what ways the array has changed
right that makes sense
and what about just checking Replicates on the actor, so my actors will just have their visibility and collision automatically synced to the clients?
that's easiest implementation-wise but I assume much less performant
I don't know enough about the replication graph to say why
I'm no where near the experience level to speak on topics of performance
I've been learning about replication for about 2 or 3 days at this point
Ok well that makes two of us haha
(UE4 replication that is, I know a great deal about serialization as a general topic)
I'd recommend at first using whatever approach is going to be the easiest to maintain
In matters of optimization, I generally end up implementing multiple approaches and measuring to see which is better
yeah good call
in this case I feel like it might be knowable beforehand whether or not the vanilla replication system will be efficient or not, but maybe I'll just have to try it and see what happens
dose UE replicate linetraces to all clients when fired on the server cuz if i do a raycast on the server everyone sees it
You must be doing the line trace locally
im only firing it from the server
also if i have a print string after they raycast it also says its from the server
seems clients only see the debuig line any of the code that the linetraces dose is all running on the server
so clients only see the debug line
Does this make sense? This is inside an actor. "Remote" in this case would be when this code is executed on a client that does not own this actor, right? So wouldn't "Rotate Server" never execute?
Correct. If the client doesn't own the actor, Rotate Server won't fire.
AMultiplayerCharacter* Owner; raw pointer? yuck
i use a TWeak in my FastArraySerializer to hold the onwer
mhm
Do you guys get those errors too?
Umm
Location, Rotation and Velocity is replicated via OnRep inside the engine if you are replicating the actor and enabled bReplicateMovement on actor settings
So if there isn't anything intentional, you dont have to multicast
Server can just set the rotation
Yeah it's dirty test / exploration code I wrote. If it were a pointer to an interface would you still use TWeak for it?
How do I get all PlayerContoller on Client side? I want to know the location of other players on client side
Player Controller is only replicated to the owning client
Ok. So I will have to get all the Pawns inside the level. Maybe by using the method UGamePlayStatics::GetAllActorsOfClass. Is there any other method, because in this method Client's own Pawn will be included in the list. I only want others locations.
It's tough for me to say what without knowing how often you need to know about the other players' pawns
You definitely don't want to overuse GetAllActorsOfClass
But I don't know if your design needs to worry about players leaving / joining
You don't. Get the player array from GameState and I think you can get their pawns?
Not sure on that tho. I know theres a replicated array of all PlayerStates but I don't know if that has the pawns.
All player states have a replicated reference to the player pawn btw
I'm having a tough time getting my brain around authority vs server vs client and what to check for this particular situation:
I have 2 players and they have laser particle systems.
I don't want to spawn the particle systems on the server (I can't anyway, particle systems don't work on servers).
When playing multiplayer I can use "Is Server" and if false, try to create the particle system.
But when playing standalone "Is Server" is returning true.
What should I be using?
Because in standalone you are authority
OK so what should I be using to spawn particle systems on clients in multiplayer and standalone?
ShooterGame seems to be just spawning them normally. I'm not working with dedicated servers so I dont know what kind of checks you need to do during emitter spawning, but what they're doing on ShooterGame is they spawn an "ExplosionEffect" actor from server and during beginplay they spawn particles
Probably that dedicated server checks happening internally in the engine
You can check for GetNetMode() != NM_DedicatedServer
This will return true if you're only a client or listen server local player
Ther are no clients in standalone.
I mean particles wont spawn on DedicatedServer
but you can just check if (GetNetMode() != NM_DedicatedServer)
but SpawnEmitter does this check anyway ``` if (FApp::CanEverRender() && World && !World->IsNetMode(NM_DedicatedServer))
@rancid flame IsServer will return false in only one place, if you're a client connected to a server. IsServer returns true if called on an object on the machine of the Listenserver, DedicatedServer, or Standalone(Singleplayer).
Authority on the other hand can be true on clients. Authority is simply true of this actor was originally spawned on this machine. Clients return this true for locally created actors, and false for things that have been replicated to them. A Server should return this true for anything.
In most situations, you don't need to check for some things. "Most" code is meant to be portable for Listenserver and Dedicated server, so as to not cause specific coding for the two. Spawning Sounds, or Particles for instance should be able to be called on both. Most of these things have code that specifically checks if net mode is dedicated server to keep it from running. Kismet blueprint calls do this for most "cosmetic" effects like sounds and particles.
Hi, are all these warnings normal when finding a session?
Has it got anything to do with the fact im still using the 480 app ID?
hi spawn an actor on server , but i cant see it on client
its replicates , always relevant , net load on client
do what kaos said, otherwise if you run a listen server, particles won't spawn in the listen server instance
Hello! How do you launch your game? I mean what is the configuration? Are you sure that you are not launching two separate hosts?
I started server from bat file
actually replicated object code is working
just not showing the static meshes
Do you enable visibility in the code after spawning?
i did not hide it . when i run with listen server its showing on listen server
yes working now
need replicates all the child static meshes also
thanks
๐
hay im new to multiplayer dose anyone know how to make a match making system like fortnite or splitgate?
Use a matchmaking service, like Steam's, GOG's, EOS, your own
hey guys, i have a function that is running on server, at some point in the funcion i call a multicast for playing a montage. the montage does not play if im using a dedicated server
it play instead if i use listener servers
there is some weird checkbox somewhere in the character that does this? im asking because i recently found an enum under skeletal mesh-optimization that doesnt update bone positions if they are not rendered by the server
When using PIE it looks like all GEngine->AddOnScreenDebugMessage calls appear in all windows. I'm making that call inside if (GetLocalRole() == ROLE_Authority) and the message is also appearing on all my client windows. Is this a settings thing, or is there a different logging method I should be using for testing multiplayer?
Is there a standard way to get the index of a player connected to a server? I just want to know like, "this player joined first so they're 0, this player joined 2nd so they're 1"
don't think there are any counters in multipalyer, there are indexes for local players but not for overall
Thanks, I guess I'll try to do maintain my own list with connected player info etc.
if assume they join in sequence can look at their position in GameState::PlayersArray
and from player state get controller (owner)
ohhhhh that's way better than what I was going to do lol
Game mode spawns bunch of system actors during init and sets them in game state
Game state has replicated array variable of system actors
On clients array often contains nulls for a long period of time since actors did not replicate yet
Currently looping the array in tick and until no nulls present i defer the game start but that sometimes takes several seconds
Is it possible to make sure that when game state replicates first time the system actors get replicated as well ?
there is FGlobalActorReplicationInfoMap::AddDependentActor but i assume it is only for RepGraph use
@violet sentinel I guess there is something named UniqueId or PlayerId in PlayerState
that is player network identifier
tldr: instead of engine comparing values you mark the property as dirty for it to replicate to client
in some cases saves time for rarely modified variables or arrays
?
all you can is mark, replication happen when engine decides
Correct
engine checks every NetUpdateInterval / NetUpdateFrequency
normal: always check, always send if modified
push: always check, send if marked as dirty
i think nowadays everyone is using fast, but it drives intellisense crazy
left one autocompletes fine
I have a map of key to value but only some values may replicate so i decided to try if this way would work
USTRUCT()
struct FMyActorRepData {
UPROPERTY(NotReplicated) TMap<FName, Actor*> AllTools;
UPROPERTY(Replicated) TArray<Actor*> ReplicatedTools;
}
UCLASS()
class AMyActor {
UPROPERTY(Replicated) FMyActorRepData Data;
}
do i need custom NetSerialize in this case? and would just writing array to archive suffice (array is set once on launch and does not change during game)
you need the bIsPushBased setting, and it present only when you set params
doesnt do anything
yes, you have to explicitly opt properties into push model
This push model is awesome! I'm so glad you were discussing this!
Is it "costly" to have a lot of actors marked with bReplicates = true, but no properties marked to replicate?
I'm looking at PushModel.h right now
There is some mention of Dormancy in PushModel.h as well
The descriptions in PushModel.h make it sound like the properties won't be replicated at all if you don't mark them as dirty
Which is exactly what you would want for properties that replicate very rarely. You want to notify when they are relevant.
But then it says ``` * Behind the scenes, Push Model does very simple book keeping, and will forward these dirty notifications on to the
- networking systems as necessary. The next time an object is replicated, we can simply check a few flags to determine
- whether or not a given property is dirty.``` So it sounds like the actors are still periodically checked.
I'd like to know this as well
I'm starting to replicate a destructible environment. Most of my replication will happen on level start, then most of the actors will be largely quiet in regards to replication.
Is Dormancy different than Push Model?
Again from PushModel.h: ``` * With Dormancy (see ActorChannel.h, NetDriver.h, NetConnection.h), we again go up a step and handle changes at the Actor
- level. Devs can decide whether or not a given Actor supports Dormancy, and at what dormant level an actor starts at
- (i.e., whether it's considered initially "active" in the game, or "inactive" in the game). When an Actor becomes Active
- (woken from Dormancy), it will replicate one more time to all connections. After that happens, it will return to its
- dormant state. Once Dormant, it is completely ignored by the networking system until Devs explicitly wake it via a call
- to something like AActor::ForceNetUpdate.```
This sounds more similar to what @steep abyss is looking for, but I'm inexperienced on the matter of UE4 replication.
Do actors attached to other actors share the same ActorChannel?
don't think so
A channel for exchanging actor and its subobject's properties and RPCs.
yeah they don't, one channel per actor
Thanks! I tested some more and found I made some rookie mistakes on my transforms when spawning.
Looks like it is just fine to attach a replicating actor to a non-replicating actor
Obviously things could get weird if the non-replicating actor starts moving around
What you have to be careful about with dormancy is that when the actor "wakes" from dormancy, all of it's properties and sub-object properties will be sent even if they aren't dirty. Effectively it closes down the channel, and waking it treats it like it's a new actor
But it just links up to the original actor
Oh wow. That is quite expensive.
Yeah it can be, it's useful in a game like fortnite where you have thousands of replicated actors but most of them will never get an update (the trees/environement props etc.)
So they all start off as dormant, then when they change state that's when the engine makes a channel and starts replicating them
Can DOREPLIFETIME_WITH_PARAMS_FAST be applied to TArrays where you intend to mark the entire array dirty when you modify it?
I have an append only array that only gets read during OnRep
I think it should be fine
So long as you mark the array dirty, all the internal props will be compared
The PushModel example seemed to explicitly skip TArray
Ahhh maybe it does
I have a test project, I'll test in it before implementing with this assumption
But bear in mind push model is really only a CPU optimization
I was thinking, it would be nice to save the complete TArray compares since I will know precisely when every change will occur.
Doesn't really mean sending less data, just means potentially doing less comparisons
Exactly
I have a bunch of static terrain that will mostly not send anything
I don't want the server CPU analyzing stuff that doesn't have any players nearby.
It's worth nothing that Epic have even turned around and said they enabled it on fortnite, and they saw barely any real performance difference
I saw that note at the top of PushModel
It seems like since they did all the work, it is low hanging fruit for me
I'll try push model and re-evaluate IF practical application shows performance problems.
I can't see anything that prevents it working with TArray specifically
static arrays get special-case treatment because like USTRUCT members they are "unfolded" into the parent
would this suffice for #multiplayer message fixed link
bool FDataCollection::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
{
Ar << ReplicatedTools;
bOutSuccess = true;
return true;
}
Wouldn't work @violet sentinel if I understand correctly
You can't ever guarantee that one actor will arrive before the other
yeah onrep I would suggest
And yeah you could do that but you wouldn't need to
RE the custom NetSerialize
USTRUCT() properties automatically are "replicated" so the "replicated" flag doesn't work inside USTRUCT
so just marking extras with notreplicated is enought?
But TMap's can't replicate anyway (at least not via UPROP serialization)
So I don't think you need to mark it as not replicated
can't hurt though
What header do I need for DOREPLIFETIME_WITH_PARAMS_FAST?
"Net/UnrealNetwork.h"
Oh I have that one
Does it require an additional module in build.cs?
no, it is part of Core
I think you need NetCore in 4.27
That did it
#include "Net/Core/PushModel/PushModel.h
Looks like TArrays work with push model just fine
Ah good, I was just about to find out one way or the other anyway ๐
In my GetLifetimeReplicatedProps FDoRepLifetimeParams Params; Params.bIsPushBased = true; DOREPLIFETIME_WITH_PARAMS_FAST(AMultiplayerCharacter, LocationHistory, Params);
Header: UPROPERTY(VisibleAnywhere, Transient, ReplicatedUsing = OnRep_LocationHistory) TArray<FVector> LocationHistory;
i used to have pushmodel in project, but with many people not following gudelines (not having setters that mark dirty and other things)
after having a hard time finding all missing marks just gave up and turned most of it off
I could see how it would be easily abused
In my one scenario, anything except an append to the array is invalid
So it makes sense to bury it and only have an append setter
In some of the tutorial content I saw "ReplicateUsing = OnRep_VariableName"
Isn't that redundant?
it's not hard to follow, the properties should be private, if they're exposed to BP then you can use Blueprint getters/setters
ReplicatedUsing is what ties it to an OnRep_### notify. Just using Replicated means no notify function
well you'd hope someone would be reviewing that code
Oh awesome! I didn't realize this. That explains some of the things I didn't understand.
Weird name for it tbh, not sure why they didn't call it "RepWithNotify" or something
@chrome bay you do need to mark it notreplicated
The TMap?
or it spits a warning (TMap)
Ahhh cool
๐
so everyone says root motion is bad for multiplayer right? But if I take an in-place animation and make it into a montage and then because the feet move I need to add a keyframe + manually move the root isnt that the same as root motion? It seems to me that the best way would be to do an in-place animation but only make it for the upper-body slot and then keep the feet able to mvoe independently? Is this right or where am I wrong?
RipWithNotify sounds much more like it does than ReplicatedUsing urgh
@grizzled flicker Rootmotion in montages is OK
but not in the animation bp.
i dont use root motion for TIP
i use a static one, and a curve
tip?
ok i have nothing but root motion in my entire project but all i hear is how bad it is for multiplayer so...
ya i have this sword attack anim where the feet move forward so i figure ill just use root motion anim
this depends, we normally play the animation in an upperbody slot so the feet keep moving, anyway this is not really multiplayer now so #animation we can continue
it works ๐ i made replicated subsystem-like framework
TBF if I need a replicated world sub-system I just add a replicated component to world settings ๐
That was my OG subsystem method before actual world subsystems came along...
yea, in my case i have to configure them per-level and per-gamemode and potentially save to savegame.
i use actors..
they exist in world, easy to use
easy to serialize and reference and they replicate.
Is it possible to prevent cheaters from changing their FOV?
okay cool, good to know
World settings? What is that?
I had just put a component on game state
that is global actor that always present
you can add actor components onto it
AWorldSettings
best multiplayer template?
shootergame i'd say, others don't really work in mp
fwiw, WorldSettings is also what particles attach to when you spawn them at location ๐
I've been messing with UE4 since 2014 and this is the first I've heard of WorldSettings lmao
So what's the difference between it and GameState?
uh, a lot?
it's more where you can set level specific settings
the only similarity is that it's also instantiated as a replicated actor
Can someone help me reduce some of these racing errors I'm getting? Player character can't read player state on spawn etc.
How tf do i do multiple player
If you genuinely have no idea how MP works, you should start with the Cedric document in the pins and just keep researching until you get how replication works
Also wtf is that avatar
Porn = funny I guess
A Kanye west album
:triangular_flag_on_post: โข_โขpen15#3148 received strike 1. As a result, they were muted for 10 minutes.
I am designing a pickup actor.
It's OnBeginOverlap is called on both Client and Server. How to design it so that it is called only on server? Because, in OnBeginOverlap, I destroy the actor. I don't want that to be out of sync
Just check for authority
You could do something like: OnBeginOverlap(...) { if (HasAuthority()) { Destroy(); } }. See here for details of what authority means: https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/Networking/Actors/Roles/
This way, it gets destroyed on Server but not on Client
If server destroys something it should be destroyed on everyone
Ensure actor(s) are replicated
Anyone have any idea how I can solve this? Sometimes it does actually fire the sphere trace but less than half the time. I'm using a proximity spawner to spawn the AI. It always does damage to the server but only sometimes on the client. I've even changed it to ensure that the server is calling the spawn no matter who triggers it, but the issue persists. No owning connection for actor AI_Female_C_0. Function AttackMontage will not be processed. The montage always plays, but I'm using an anim notify to call the function from the anim graph to the pawn
you can not send server/client rpcs from an actor not owned by the player.
Then how does one have the AI deal damage consistently in multiplayer? Are rep notifies out of the question?
It really is just a matter of who triggers the spawn
Is there an option to have a dedicated server run inline in the current console window? Basically I want it to print in the powershell window I launch if from instead of being headless, or printing in another window. Basically the equivalent of UnrealEd-cmd.exe as compared to UnrealEd.exe. Maybe I have to create another target for it to make something like UnrealEd-cmd?
You can start it with the -log flag I believe and it'll have a console for you that'll display messages.
{
OnActorBeginOverlap.AddDynamic(this, &ADamageChanger::OnBeginOverlap);
}```
I have this code in BeginPlay, so that OnBeginOverlap is called only on Server, but still it gets called on Both Client and Server.
if I make a change to the character movement , like changing the mode from X to None, if that is done on the server is that replicated by default, or should I also set that on the owning client?
think you need to set it on Owning Client and Server
but not simulated
at least that is what i do..
AWorldSettings - it's the actor that holds all the info when you open the "World Settings" dialog for that level. You can use your own world settings class globally for the project, the nice thing about it is it's guaranteed to always exist - but tbh GameState probably is a better choice, get a bit more control over per-level stuff then
It's useful if you want to attach some kind of meta-data to a world though too
Hi. WHY WHY WHY?!
I've checked everything in logs and with Network Profiler. My project consumes low amount of bandwith and has only few replicated actors/variables.
And yet, despite of having NetUpdateFrequency=60 and FixedFrameRate=60 server DOESN'T send actors for replication every frame. (checked through NetworkProfiler, simulation and real network test)
Well it doesn't send anything unless it actually needs to be sent, i.e. changes have been made
NetUpdateFrequency is how often the actor is considered for replication
i.e. the maximum rate at which the server will compare it's properties
But i've created Array, where every frame I increase Integer (Get 0), the rest of array elements, true, varies from time to time.
Get 0 in Blueprint returns a copy
It doesn't modify the original array
(unless you change it to get a reference, and modify that reference)
The Array and actor also need to be marked as replicated ofc
No no no, Replicated Array. I change it's first element every frame (Clear Array every frame --> add elements to array )
And still it doesn't send it every frame
If you're adding the same elements, then nothing will be sent
Show what you've done will be easier to see
show code (tm)
^
So variable changes its value every frame. Yet networking mechanism doesnt consider it for replication every frame
post code
where from is it being called from?
Are you sure the actor is network relevant?
do you check HasAuthority ?
^ that too
It can't be because otherwise it would work
I'd start by printing the value of the int to be sure it's incrementing, and also ensure the actor is network relevant
Isn't there some Unreal engine ompitimzing mumbo jumbo which blocks replication every frame?
nope
IT IS IT IS IT IS
there is not much guarantee variable will get send in same exact frame but only on next when engine runs replication
you technically can forcenetupdate but that is woodoo
In editor you can pretty much garauntee it will send same frame
And you are running an actual server + client instance in PIE to test with?
I.e. not playing in standalone or just with a listen server and 1 player?
Simulation, listen server + some clients. But I've made real network tests with network profiler. And in NP logs it looks like it send variables every two frames instead of every frame.
So it is sending something then?
Original post made me think it wasn't sending anything at all
Bump NetUpdateFrequency and MinNetUpdateFrequency to something higher than 60
Should guarantee it's being checked every frame
but bear in mind there's zero guarantee you'll get 60 updates a second outside of editor, due to real-world internet connections
So building anything dependant on that is a failed venture
See above
i saw
128 + 52 bytes small amount i believe. On n+1 and n+2 frame it doesnt send BallKurla at all, even tough this Array which i was mentioning is placed in BallKurla.
Why TF at one frame server decided to not replicate anything?
What engine version are you on?
4.25.4
It says that BallKurla is taking up 7.5Kbp/s
Or maybe it behaves like this when it comes to Arrays?
A couple of other items and that would exceed the 10Kbps default saturation limit
So the engine will consider a connection saturated and not send anything more
๐ค
IIRC Epic bumped the defaults to 100 in 4.26 or 4.27, unsure which exactly
Try adding this in DefaultEngine
MaxClientRate=100000
MaxInternetClientRate=100000```
Default is 10000 IIRC
ok, thanks, thats some clue
Otherwise I imagine it might be some kind of precision issue with the frame rate and networking timings
If they're both dead-on 60 or they go even slightly one way or the other it might throw it off
But, how this makes sense? I have average internet speed. My outgoing speed is 31ย 250 bytes PER ONE FRAME!
So why this limit of 10 000 bytes per second?
15 Mbps = 15 000 000 bits per second = 1 875 000 bytes per second = 31ย 250 bytes per frame
am i right?
Your real network connection doesn't matter in editor
I thought you meant 31 250 bytes per frame was what the network profile was saying
O,l but what is the reasoining behind having this MaxClientRate=100000 limit?
To not hammer bandwidth
It's a soft-cap on how much data to send a second
When the game tries to send more than that, the connection is "saturated" and so things will be sent less often
It's a "target" rate essentially
But why this default value is absurdly small, like 10 000 bytes, right?
ok, thanks for some teaching ๐
Epic bumped the default values to 100Kbps in 4.26/4.27, presumably because Fortnite - but realistically you probably don't want to be anywhere near that limit
[/Script/OnlineSubsystemUtils.IpNetDriver]
MaxClientRate=100000
MaxInternetClientRate=100000
this goes to some ENGINE folder right?
I'd start bumping that just to check if it is the saturation, but otherwise I suspect it might be a timing precision issue
DefaultEngine.ini
but engine or project folder?
project in Config
ok
@chrome bay I've managed to get replication every two frames, but no chance to replicate every frame ๐
but in real network we made tests with 4 people and every actor got replicated every two frame
so thats nice
but why every two frames and not every each frame, I have no clue

after changes
before changes
expecting value to be replicated every frame is kind of weird, usually interpolate between received from server values (if it is movement data)
I know
but 1. im curious, 2. I use counter to synchronize gameplay, so for test purposes i want sometimes to make ONE-TO-ONE replication
You cannot expect every variable change to replicate
I replicate array, where first item is counter which changes every tick. Game is fixed 60 frames. @bitter oriole
why i cannot try to rpelicate it every frame?
even for test purposes
๐ค
Because it's nonsensical : 60fps means an update every 17ms, when networks commonly have 50ms of ping time if not 4x that. If you succeed, you will be receiving groups of 4-5 updates in the same frame, and then nothing for 4-5 more frames
game and render work in separate threads also
my outgoing internet provider speed is 15 Mbps = 15 000 000 bits per second = 1 875 000 bytes per second = 31ย 250 bytes per frame
one float is 4 bytes
It also doesn't work like that
๐ค
A larger problem is that forcing replication to be reliable, if possible, would mean a 2s drop of connectivity (completely routine stuff) would give you a backlog of 120 packets to resend in loop
Which in turn would kill your connectivity for seconds
HOLD ON
This is why replication works like that
I create a project, where i only try to rpelicate one fck INTEGER - 4 bytes
ON VARIABLE
should it be possible to replicate it every frame? 60 times per second?
OR NOT?
IN UNRFEAL ENGINE 4
Not reliably
๐ค
In any engine
replication - no, direct write to network socket - maybe yes
Maybe yes with massive caveats
The main one is as follow : lag time is variable
So say you have 60fps network updates - what happens if lag goes from 50 to 100ms for a fraction of a second because your sister logged into Animal Crossing ?
The other side then gets zero update for 4 frames (50ms / 16.7)
And then the next frame gets 5 frames (4 + the latest one)
4 of these frames are pointless
They contain intermediary values of a variable
It's all fun and games but you know what @bitter oriole ? While simulating in PIE it also rpleicated every two frames!
Yes
Try it on loopback too for fun and giggles
you know where it is?
What I'm telling you is this : from the engine to the operating system to the net hardware to the actual network - nothing is designed for that
The update frequency doesn't magically make networking do things it cannot
You can't update at 130fps for obvious reasons (the game runs at 60 from your own words)
i know
No matter what, i cannot realisticly make it 30+ (net update frequency)
sorry, i remmeber- sometimes for a few frames i got replication every frame
Bold of you to assume PIE doesn't go through the OS net stack
๐ค
Hey all - Playing in PIE from the editor, I've got a working standalone<->dedicated server setup if I run with the server as a separate process. I can travel to the server using the url "127.0.0.1:17777".
My problem is that I would like to also be able to run with the dedicated server in-process. However, when I try to travel to the server using the same address, it doesn't work.
Anyone know how I can successfully do this?
Note that I'm running the client as Standalone, because when I run it as Client - it automatically connects to the server and I do not want that.
I'd also suggest doing all your work with say 100 ping, 1% packet loss, and packet reordering
There's no point trying to write MP code in good conditions
Good conditions don't exist even on a LAN net
See how real networks behave and write your code around that
I did some hardcore simulation, no worries
just i wanted to dissect my network code starting from the base - 60 FRAMES AND REPLICATIONS PER SECOND
๐ญ
Now that we're good on the fact that you'll never get one replication update per frame on client, just check out NetServerMaxTickRate
You'll be able to send on average (over say 10s) your 60fps updates
Of course that will be 10 updates in some frames and 0 for most of them
But you are happy with that
i dont use C++, will I be able to change it through ini file?
This is an ini thing
ok...
[/Script/OnlineSubsystemUtils.IpNetDriver]
NetServerMaxTickRate=60
DefaultEngine.ini
thanks
Ultimately as I said before any system built on top of reliable property updates at a fixed rate will fall apart. The UE4 docs specifically state that variable replication is lossy, and that is to some extent by design.
You may be able to get it to function in editor because there is no real-world connection - but it's a guaranteed failure outside of that very controlled environment.
Why in this particular instance it's not sending a prop update per frame IDK, but in practice, it doesn't matter anyway
Unreal gives you a really powerful model with two simple mechanisms - replication for persistent game state, where intermediary values do not matter but getting the data when you join the game does, and RPCs, where every single call can be made reliable if an event is truly required, but only communicated to current clients
So if you need to positively send every single step change of a counter (which IMHO is wrong but okay) you'll make it a reliable RPC and watch your game stutter to hell
But somehow you're trying to turn replication into RPCs ๐
@bitter oriole @chrome bay Thanks guys! Players of my game will be eternally greatfull. Good knowledge i gained today
I think multiplayer is the correct place to post this, and not in the sub system area.
Is it possible to host a session from a trigger box with steam/advanced sessions?
Canโt seem to get the overlap to trigger hosting, but single player travels fine from another trigger box
I can confirm server traveling from pc based widget works fine, but want it as a overlap instead
i am sure in theory it is, but you probably dont want to do that, can u make sure that session is created before travel is initiated?
If my understanding is correct I believe it's doing that from create advanced sessions > travel - on failure > print string
And I can confirm the logic works from a pc based widget
The goal is to let the player run into the host portal and kick off that way, maybe I need a delay before the travel?
Replicated actor spawned on a server with some (replicated) exposed on spawn properties. The values don't exist for the clients in the construction script. Is that just how it is or can it be tweaked?
Construction script is just an earlier beginplay as far as networking is concerned. You should never rely on replication in any events besides OnReps.
how simple is implementation of networking with ue4? as in should i design with networking in mind or am i safe to create an offline preoject and implement networking later on
You'll want to build with multiplayer in mind.
bleh, ok. thought having it be exposed on spawn would guarantee the value would be set when the actor spawns clientside
it's relatively simple, but doing the latter thing is dumb
thanks, will save me time later
If you build it correctly, you can network a singleplayer game incredibly fast later on. But building it correctly requires knowing the general ins and outs of UE4 networking. Without that foundation, it's likely better just to start learning that and implementing it now.
im moving from unity to ue4 so was more curious how much leave way it gives since ill have to adjust to the api im somewhat familiar with the editor already
Specially since that implementation will also help you learn UE4's architecture much better even for a singleplayer standpoint, I feel.
It's more about class interaction. Knowing what exists where, when, and why.
a multiplayer game played offline will just work in most cases, but far from true the other way round
is there decent documentation within the api? most the stuff i'
i've seen seems to mostly cover blue prints and how to use it rather then why
while how is standard in api's the why is kinda important if dealing with c++ i feel
otherwise ill go over some linked in videos in my spare time before i get started
I would start with Cedric's guide. Second pinned link in here I think.
The general basics you're going to want to focus on is RPC and Replication, how they're different and how they work. Get an idea of the basic classes like GameMode, GameState, PlayerState, PlayerController, HUD, PlayerPawn/Character.
i have never tried that but i assume a delay would help
have u checked the logs to see whats going on?
im somewhat familiar with those currently i made a simple movement system and gui to get a feel for the api but i want to rewrite it once things are planned out the replication is the main thing i want to grasp properly atm
Replication is simple. You set values on the server, they are replicated to clients based on their conditions and may run a function after being set on clients called an OnRep.
so essentially im just sending client data to server then echoing to other clients from the server? or am i missing anything in that process
Random question about something I may have noticed but not 100% certain. In C++, it seemed like repnotifies ran on the server as well as clients but in BP repnotifies just run on the client. Am I crazy?
If you want the client to set the value, yes.
Yeah Iโve debugged what I can but this is a shipping build
lets use instiations as an example i would call the rpc from client then server would create object and replicate to each client?
Canโt believe overlap > host isnโt working, this should be simple connect cast and go
have u confirmed that the overlap is trigering?
"instiations"?
have u confirmed that the sessions is being created?
sorry used to unity terminology, essentially creating a new instance of an object/playerobject e.g. spawning a tree within a game via script
I think the session is failing
i would essentially check a flag on client side then server would create object then replicate to connected clients right? or is there more involved
even in shiping u should have a debbug log
Maybe itโs being over rid due to pc widget, doing this for vr
Depends on how you want it handled. In general I try to have things as server-authoritative as possible. But if you wanted a client to click a button in the UI then spawn an object for everyone, the client would send an RPC to the server that would then spawn a replicated object (so it shows for everyone)
or would replication create it on serverside and automatically send to connected clients
But have it setup for pc cross compatibility
Instances. But essentially, sure. It depends on the use case. If this is like.. Survival game, Client placing down a wall or floor tile, yeah. They would RPC their desire to the server, server would run checks, then do whatever it needed to do, which would ultimately replicate to all clients for the new state.
If you create a replicated actor on the server (can turn on a flag on the actor to say it replicates) then yes, it will be created for everyone
so would replicate be run on clients as well as server or would server automatically create the object/actor on the clientside as well
Travels/host sessions when PC load out is done, uses a menu though
So I know my adv ss isnโt bonked
Nothing replicates from Client. Replicated objects need to be created explicitly on the Server.
If you try to replicate something from the client, nothing happens. RPC = Client talk to server. Replicate = Server talk to client(s)
In fact. As far as Networking goes. There's one simple rule for Clients. They can't do ANYTHING networking wise, except to RPC to server.
i think i've got the grasp of it now but let me rephrase if a replication is called on server does the client need to do anything to be able to see the object or would replicate tell the client to add the object automatically
i cant help u man, u gotta check those logs and be a bit more specific
In regards to a replicated actor, nothing else needs to be done on the clients
thanks think you guys have cleared up everything for me just about
It's automatic, assuming the actor is set to replicate, and the server thinks that it is relevant to the client.
But if you wanted to implement a chat system, client sends RPC to the server, server then tells clients to run a function to handle the message. See "multicast"
thanks
Are you using C++ as well?
https://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf this is a hella handy doc
I especially love this diagram to remind me what exists on the clients, server and what is shared
yeah i am, not a fan of blue prints personally expecially when i have a pretty solid grasps of c++ syntax already
although will admit the ue4 api makes it almost like c# in terms of syntax
in comparison to raw c or c++
Haha. Unreal's wrapped C++ is stupid easy to learn.
its weird at first, for sure
it really is haha i just wish there api documentation was a little more focused on the c++ side rather then the blueprint side
but then its easy
Will work on pulling logs will have to figure out how to do that on a shipping build
its inside a folder somewhere
Working on packaging, working with a potato
its not hard to find
But couple major notes. First, C++ OnReps are not automatically called on server. You need to explicitly call these on server if you want them to run there after setting a value. In Blueprints, these automatically run on server.
Check out the differences between NetMode, and NetRole. These will save you a lot of headache with guiding logic.
Learn FastArrays. They're cumbersome, and they have some minor drawbacks, but for some implementations, they are downright invaluable.
This isn't exactly multiplayer related, but I don't know how data is handled in Unity, but I would strongly recommend getting a grasp on GameplayTags. FGameplayTag. For sorting game logic, and keeping data separated well, these are also very invaluable.
they seem to just be your typical collections?
Normal Unreal TArray will replicate all changes in the array. So.. You have 20 items. You remove index 7. Index 8-19 shift down to 7-18. These have all changed, and will ALL replicate. With FastArrays, you can remove specific items without that issue. But more importantly, you get per item callbacks when the struct arrives on client, before the struct is removed from the client, and after adding on the server.
ohh second part is gonna be helpful although rest is basically the same as a raw map right?
Unsure what you mean with Map? If you mean TMap, those aren't replicated. Can't network them.
looking at the syntax kinda looks like they tried to replicate c# but slightly changed things
Get very used to working with Structs. ๐
looking at structs seems like there the equivelant of a c# model class when working in oop
basically just there to hold variables of that instance of the class?
Mostly. Though you can also add functions to them, both normal and static that can be used to handle the data on them.
yeah looking at a few examples atm since you can do the same thing with c# equivelant lol, seems simple enough but not i know what c# oop models are based off lol
@kindred widget think you've given me all the info i need to convert my projects thanks heaps man!
@cinder tartan Oh. Speaking of C++. You ran into the UPROPERTY rules yet?
only skimmed over some documentation of them but it seems pretty basic
Mostly simple. Most variables declared in headers should be UPROPERTY() marked. Specially pointers.
guessing thats got something to do with the editor itself?
I pretty much mark everything out of habit and because it's usually blueprint exposed. But pointers specially even in C++ alone need to be marked because if they're not, the things they're pointing to can be garbage collected.
Even if you don't mind that, it's still generally good practice to use a weak pointer than an unmarked one.
yeah ill be sure to look into that a little bit more been using high level languages so much lately almost forgot garbage collection was a huge part with c++ lol
Are GameplayTags separate from GAS now?
They are. Both in personal projects and at work I use them pretty much everywhere. They make fantastic data sorting tools for datatables and such.
They were never part of GAS
always had there own module, infact epic was going to make them part of the AActor by default
but they never did ๐คท
Is there a way out of the box to replicate a variable between a single client and the server, or would I need to setup my own requests and updates?
does anybody know if replication of data assets declared inside structs its bugged?
Replication condition owner only
omg thank you this saved me so much time ๐
hey anybody here has used photon? I was going throught the docs and couod not find anything on if a dedicated server build is needed. How wouod it be able to check for ohysics relwted stuff if there is no dedicated server stuff from the engine?
Trying to build my code but i'm getting this. Anyone experienced the same?
Set your startup project to be your project in visual studio
What would I have to put down to open a port so my friends can join my game ?
I know I put my pc address for then local ip
So it's all 7777?
Hello! Does anybody have any insight on how to mitigate these client corrections? In my actual project im getting corrections when the client collides with moving AI with latency which feels terrible and i'm looking to reduce it or atleast mask it. I've setup an example of the problem below.
The Setup
- ThirdPersonTemplate Example
- AI that moves around randomly
- Client on 100ms ping
The Problem
- Huge amounts of corrections when colliding with the AI
It seems adding these to the DefaultGame.Ini solves the problem but im not sure about the consequences of doing this, or if its the recommended way to solve this issue?
The ClientAuthorativePosition set to true implies the server will no longer have authority over client positions, which yes, can have very big consequences depending on the game you're making
Without reading on it, I expect that that max position error is what the CMC will use to determine when to correct client positions upon an incoming server state containing the 'real' client position, however if client authority is true then it becomes meaningless what the number is set to
The larger it is, the bigger the potential desync can be
Keep in mind that - at least with the set of solutions I'm aware of - solving the problem of client corrections when running into moving server auth entities (which are not predicted) is virtually impossible in bad enough network circumstances
solving the problem of client corrections when running into moving server auth entities (which are not predicted)
Im going to assume that AI Movement cannot be predicted since they only exist on the server or is this a possibility?
If the AI is somehow deterministic, then on paper it is a possibility
however I bet the reality of it is that that case is not taken care of, and will require you to put in time into making it so
which can be a terrible experience
Yup Agreed. For now increasing the correction range seems okay. My project is a simple coop game so it doesn't have to be SUPER precise. It seems corrections still apply if the current client position compared to the last server position is > MAXPOSITIONERRORSQUARED which should correct major desyncs (hopefully).
yeah, it should
as long as you dont need precise client locations, then that transforms the problem from feeling bad every step you take, to feeling bad every 10 or so steps you take, when running into that AI
Yeah exactly, which is better for sure.
How common is it to have to use these .ini lines to solve issues like this? I would have though increasing the correction radius would be a easily visible setting in the CMC somewhere
editing config to get the engine to match your needs is common, its another tool in your arsenal
๐ Ty. Makes sense
Any good places to bind to the UReplicationDriver::CreateReplicationDriverDelegate() delegate? GameMode::BeginPlay feels a bit wonky (and I'll be surprised if it works)
InitGameState
that is first easily overrideable function called on opening a new level
Thanks ๐
which ports do UE4 use?
how do i portforward then
You don't
No game should be coming out in 2021 with ports to open
That shit is 2000s stuff
In modern times you use NAT punch instead - the engine does it out of the box on Steam (well Steam does really)
thx ill research it
ive used hamachi to NAT punch (based off what the wikipedia definition is) but it limits me to 5 clients, any recommendations to get this higher?
Hamachi is not NAT punch
Just use the Steam online subsystem and enjoy no ports issues
Or use your own service and implement natpunch yourself
is the steam online subsystem free for access?
"test" as in "it will work perfectly well and no one will care until you ask money for it"
i think the game name filters ?
is space war perfectly legal?
ok
what alternatives are there?
what can i use as an alternative to hamachi
i mean legally
SpaceWar is for testing purposes only
you may not release a game using the spacewar app id.
you can use EOS, or purchase steam app id for $100 as mentioned above.
or setup your own system (which is a big task)
eos?
Epic Online Services.
is that difficult to use?
is it free?
Dunno. Most likely.
apparently its free
AActor* Owner = GetOwner();
if (ensure(Owner))
{
UInputComponent* PlayerInputC = Owner->InputComponent;
if (ensure(PlayerInputC))
{
// ensure condition always failes on client
}
}```
In that code (on actor component), the second ensure condition always failes on the client. It only works on the server. What am I doing wrong?
And under there I am trying to execute a Server RPC and I get some weird error:
```LogNet: Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor BP_PlayerCharacter_C_1. Function Server_SpawnWeapons will not be processed.```
That error usually indicates that the actor isn't owned by a player and thus the RPC can't be invoked.
Is this perhaps a copy of the character you've placed in the level?
Its spawned by the game when I play with 2 players
I also found out that when I play with 2 players, I get 2 characters but only 1 controller spawned
When I run GetOwner() on the second character I get a nullptr
Well that would do it. No owner = no RPC. How are you spawning the characters?
I am not spawning them myself I just set the controllers class and the characters class in the gamemode
Are you by chance running your Server_SpawnWeapons on Begin Play? If not, what Event triggers the call to Server_SpawnWeapons?
No its running inside a component of the character, 1 second after the characters beginplay using a timer
So directly from Begin Play of the Character -> Set Timer By Event -> Timer Goes Off -> Triggers Server_SpawnWeapons? No authority check?
yes
What's the safest way to authoritatively disable a player's input
if you want it hack proof, unpossess its pawn
I feel like AActor::DisableInput is easy to cheese since it's client sided
Is this the only way?
i think so, everything else is kinda client side
I only want it to suspend input for like 2 seconds or so
Begin Play fires on both clients and the servers.
So when Player 1 spawns on the server, the server will call all of that.
When Player 1 spawns on Client 1, it will also call all of that.
When Player 2 spawns on the server, the server will call all of that.
When Player 2 spawns on Client 1, it will also call all of that.
When Player 2 spawns on Client 2, it will also call all of that.
When Player 1 spawns on Client 2, it will also call all of that.
See the problem? Begin Play can be a bad place to initialize things in multiplayer, especially with player characters that aren't always relevant as it can also fire multiple times on clients as the actor's relevancy changes.
The crux of the issue is that you're using Begin Play without an authority check, and you should probably be spawning the weapons server side anyway without requiring the client RPC asking for the weapons to spawn.
So it should go something along the lines of:
Begin Play > Has Authority (Authority Path) > Spawn Weapons
I'm pretty sure unpossessing a pawn would break a lot of my code
but only one way to find out I guess
If I unpossess a pawn, It's still connected to the APlayerState right?
not by the engine
ok
Ok, and how can I check for authority in the actor component. It doesnt have an HasAuthority() method
ok, thanks
Hi, quick question. I'm trying to send an actor and an object from a client to the server. The actor works fine, the object just doesn't arrive. Is there a difference on how they work or am I doing something obvious wrong?
Hey I have a question, I'm trying to create a multiplayer lobby but I'm having this problem when a host leaves lobby players will leave too and get back to menu but it's now working how it should because when they try to create new session or join other lobby they just can't. Any idea on how to fix it?
Here's my code when player returns to menu from game
well what is the object?
Just a basic object with some variables to store whatever I picked up. If that's the question... I don't know terminology tbh, I just use words.
so did you implement subobject replication for it then?
I don't know what that is, so probably not. How would I do that?