#multiplayer
1 messages ยท Page 211 of 1
If you have to send it use a reliable RPC I guess, but be warned this is expensive
What I do is have an ack between client and server where they must share X frame being sent across
this is just network update rate I think in your case with this onrep, stuff gets sent far less than the actual simulated frames
If you want to send the state of literally every frame then you need to store it in a buffer somehow and send that over
you mean send a the moves done over a few frames to the server? In a single go?
I am sending a new move in tick()
and yes an old move like unreal does it
If it's not reliable or acknowledged somehow then you are at the whim of packet loss
yeah, movements. They can't be reliable rpc
can't afford it to be slow
there is literally nothing stopping you from sending anything you want as an rpc
as for speed yeah if this must be fast an unreliable rpc is the way afaik
yess
server to client: "here is the latest frame I have received from you"
client: "cool, now I only need to spam frames after N frame in rpcs"
is what I do
If you can't gaurantee the thing showing up on the other side you use reduncancy and gaurantees... A replicated property that changes 100 times a second will not have every single change reflected on each side with default network settings let along network conditions
the issue I am seeing with packet loss is -
The tick() of the client makes new moves and send it over the server. They get added to an array of all unacknowledged moves. But when there's a packet loss, the move doesn't get ackd and it has to be retransmitted.
The clarity I don't have is - what does the server do with the new moves when it knows the older one haven't been ackd yet.
And with more packet loss - the unackd moves list will just grow over the time and the server is still processing 2-3 moves a time at max
@nova wasp
a couple things
first of all, if you are using unreal's bandwidth emulation (the default average/bad settings)
it is 100x worse than real life packet loss
in real life if you see more than 1% packet loss you are going to literally disconnect lol (in my experience)
it represents a truly abhorrent spike but constantly on
does the server have a sequence of moves without gaps?
You still haven't really shared if this is rollback lockstep with only sending input
or just trying to re-invent the cmc (sending moves and resimulating them in isolation)
yes, currently i am sending moves on tick() of the client. Not combining any moves
In my case, with missing moves all you can do is predict the next frames of input as being the same buttons being held
i haven't done the rollback part yet but I have stored the moves in an array, yes.
at this moment I can go with rubberband effect and write down the rollback eventually
this is how pretty much all netcode in games works for moving things... you have to predict a bit of what happens as you have only partial information
it might be an amazing deterministic prediction, or a bad one but good enough
with my rollback setup a misprediction is inherent to EVERY frame as you constantly get new differnet input from other clients... what this means is I resimulate the entire game tick a dozen times a frame to redo the newly received state (oh goodness)
Often times a misprediction can be corrected almost invisibly
lets say -
Client send - 1,2,3,4,5,6,7
Server gets - 0,0,1,2,3,4,6,7
When it recieves 6 - with the logic running on server, the server will notice there's a large gap between the last result and the current one. So, it would make my pawn to snap.
What most rollback games do is actually only display a delayed frame, so that any mispredictions are already resolved by the time you reach X frame. This also delays your input but vastly reduces the chances you get caught with funny mispredicts (2-3 frames at 16ms in most)
what happens in the common case is that 4 would say it's MOVING in a certain direction at a certain speed
so next frame, you don't receive any new state
but you can say "well, they are probably moving this way"
the CMC in unreal is received on clients as just "it's here moving this way" and the TRUE position on sim proxies is actually incredibly shaky and jerky
but because the skeletal mesh component's position is interpolated smoothly at all times (lagging a bit behind) it's quite smooth looking even though it's actually teleporting slightly almost every net movement update
yeah I noticed. They defer the movement of the mesh.
but my concern is for local client being corrected and then snapping during packet loss
unreal accepts a certain degree of difference on the client?
you are never 1:1 with the server
but it's about being close enough
i'll show you my code. Don't judge if it looks messy. I am experimenting a lot of things lately xD
void UPawnAgentMovementComponent::MovePawnAgent(float DeltaTime)
{
static int frame = 0;
frame++;
APawnAgent* pawnAgent = Cast<APawnAgent>(PawnOwner);
const FVector& inputVector = pawnAgent->GetInputVector();
FRotator DesiredRot = inputVector.Rotation();
m_newVelocity = FVector::ZeroVector;
m_rotation = pawnAgent->GetActorRotation();
//UE_LOG(LogTemp, Warning, TEXT("m_rotation: %f, %f, %f "), m_rotation.Pitch, m_rotation.Yaw, m_rotation.Roll);
if (!inputVector.IsZero())
{
int rando = rand();
m_rotation = FMath::RInterpTo(pawnAgent->GetActorRotation(), DesiredRot, DeltaTime, 10.0f);
m_newVelocity = inputVector;
m_newVelocity.Normalize();
m_newVelocity *= 300.0f;
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 0.5f, FColor::Yellow, FString::Printf(TEXT("Local Actor Rot: %f, %f, %f "), pawnAgent->GetActorRotation().Pitch, pawnAgent->GetActorRotation().Yaw, pawnAgent->GetActorRotation().Roll));
}
}
//UE_LOG(LogTemp, Warning, TEXT("Client frame %d m_position before update: %f, %f, %f "), frame, m_position.X, m_position.Y, m_position.Z);
UE_LOG(LogTemp, Warning, TEXT("Client frame %d inputVector: %f, %f, %f "), frame, inputVector.X, inputVector.Y, inputVector.Z);
m_position = pawnAgent->GetActorLocation() + m_newVelocity * DeltaTime;
UE_LOG(LogTemp, Warning, TEXT("Client frame %d m_position after update: %f, %f, %f "), frame, m_position.X, m_position.Y, m_position.Z);
pawnAgent->ResetInputVector();
}```
this is for the local client
I'm going to suggest you just use the new mover plugin or the CMC here, this stuff is seriously hard to do
static int frame = 0;
frame++;
ohhhh no, do not do this lol
very very bad
yeah, I was thinking "probably just to mess around" there lol
ServerMoveAgent(DeltaTime);
const FVector LocDiff = m_position - MoveData.position;
const FRotator rotDiff = m_rotation - MoveData.rotation;
FRepMovement& repMovement = PawnOwner->GetReplicatedMovement_Mutable();
if (!LocDiff.IsNearlyZero(UE_KINDA_SMALL_NUMBER))
{
if (!FMath::IsNearlyZero(LocDiff.X, 0.01f) || !FMath::IsNearlyZero(LocDiff.Y, 0.01f) || !FMath::IsNearlyZero(LocDiff.Z, 0.01f))
{
PawnOwner->SetActorLocation(m_position);
}
else
{
m_position = MoveData.position;
}
}
if (!rotDiff.IsNearlyZero(UE_KINDA_SMALL_NUMBER))
{
if (!FMath::IsNearlyZero(rotDiff.Pitch, 0.01f) || !FMath::IsNearlyZero(rotDiff.Yaw, 0.01f) || !FMath::IsNearlyZero(rotDiff.Roll, 0.01f))
{
PawnOwner->SetActorRotation(m_rotation);
}
else
{
m_rotation = MoveData.rotation;
}
}```
this is for the server
it checks if the difference isn't large then just accept the client's position or rotation
serious question: why not just use the built in stuff here? You are pretty much making the CMC over again here but very slowly
but this wouldn't be true if there's a packet loss because server's last position can't match up
my game doesn't require that much of stuff that CMC does. My stuff is very simple and I have covered some cases already and I need to cover packet loss in this now
also, its a fighting game that I am aiming
i don't think Unreal's CMC is made for that
If you want true fighting game style GGPO rollback you need to basically replace this entirely with a full fixed ticking lockstep setup that is deterministic
GGPO is for peer to peer. I am gonna have server client. The game can have 2+ players
easier said than done of course lol
the ideas behind lockstep are not inherent to being peer to peer
full fixed ticking lockstep setup, what exactly is this? I have capped the fps to 60 already
essentially nothing in unreal will work with lockstep determinism if they use floats of any kind but I assume the goal is to get... close-ish
this means actually running the simulation with the EXACT SAME input and output on all machines
yes exactly
and no turning on fixed ticking will not do this lol, you basically have to replace unreal's game framework entirely
but I think getting close is much more reasonable
you still have to have the ability to send the actual "true" state of things from the authority I guess
this is extremely hard and requires some fairly extreme restrictions
but 2d fighting games basically simulate... almost nothing
and can get away with being quite aggressive with resimulating frames and buffering state as opposed to a 3d game with physics
have you seen Divine Knockout? What I am planning is kind of very closer to that.
Yeah I will avoid all the physics and do it with something very simple
yeah... I'm not sure which way I would go here
I would see if this game has any talks about how they handled things
it looks rather simple simulation wise so I imagine you could get away with raw ints as transforms/ custom collision
yeahhh but hwo much precision am I gonna lose with floats? considering Unreal's scaling. 0.001 is just extremely minute and non noticeable.
anyways, it's just a bit complicated to handle the transforms and stuff through ints
how large is the range of values you need to represent
bleh
yeah it's very complicated, you are the one who wanted full rollback in a fighting game though?
i am going with the rubber band effect for now ๐
i mean instead of having a rollback. lets just have things synced properly in the game and then go for rollback
sure, you still need a buffer of previous things that happened
I have that at this point, yes
anyways, you gave me your time. Really appreciate it! Thank you so much!
can i put code in the dedicated server? cuz all tutorials just do two targets (client, server) and call it a day
aaaahh with the #if macros right
so i do #if client #if server and thats it? cool
you can even have target specific modules
Heya, what's the best method for replicating structures in a crafting game? Like a Chest for example.
I don't want to replicate the actual chest because then it exists for all players, even when some are very far away.
Is there a better way to handle replicated objects at a distance? Or should I make the chest actor not replicated at all, and just sync it manually through playerstates and stuff?
I believe you're looking for relevancy and dormancy?
You can also define replication conditions for variables on your DOREPLIFETIME() macro
I didn't get what exactly you are trying to achieve but these should help you prevent unnecessary replication on clients that don't need the data
is linux the preferred/stadnard os for game servers?
Imagine on Minecraft, someone puts a chest or a crafting table down
then someone else runs very very far away, I need the chest to despawn on their client, but persist for whoever is nearby
Will relevancy and dormancy despawn the thing for clients that don't need it, but keep it alive for those who do?
That's why im wondering if it's just easier to spawn it for everyone locally and manage it manually
That's already the default behavior of relevancy, it checks the NetCullDistanceSquared to determine if the actor should be destroyed on local world if the local player pawn is exceeding that distance
Ooooh awesome.
At the moment whenever a structure/crafting table/etc is spawned by the host, everyone gets it no matter how far they are
So I'll look into that! ๐
Is it possible that you've marked it as always relevant?
That overrides the relevancy checks
I haven't changed anything besides the default lol
Just click "Replicated" checkbox and away I go
But yeah I'll read up on that, thanks!
Well default value is probably too big for your map already.
You can try to lower that to test and see actors getting destoyed when you get distant from them
Yeah good call, I'm also just wondering actually, if their functions would then properly replicate
Like if a Chest is set to "Open" while someone is far away and then comes in close
Does unreal automatically rep the variable when the chest re-loads into their game
And also is it even smart to have thousands of replicated objects managed by unreal
Be aware that relevancy will destory and spawn your actor, causing your BeginPlay and EndPlay to be called for each object that becomes relevant again
Or just let them be done locally and only changes are replicated
And they will be a different instance, any local values you saved will be lost
Replicated variables will be replicated again
So your states should use OnRep to correct themselves according to servers state when they become relevant again
Like your open state
So don't trust multicast RPCs
Awesome, good to know!
Though it might be better doing it locally anyway -- considering there could be thousands spread all over the world
Yup
You won't even be receiving them when an actor falls out of relevancy, since it's destroyed
Keep your state with a replicated boolean, let the client adjust whatever adjustment needs to be done according to that boolean locally
Don't trust BeginPlay for an actor that becomes relevant again either, it's not guaranteed to get your replicated values yet during the BeginPlay as far as I know
Depends on how well you can optimize your network usage
Begin play is the worst and has caused me so many headaches already lol
And great right on, thanks for the info man
does anyone know how to make multicast RPC work when the calling actor gets destroyed right after executing the RPC?
seems like it simply gets dropped
to add some context - I would like to spawn a niagara effect on destruction
I've had that issue before in Unity. The destroy happens on all clients immediately while the RPC gets queued up for the next call
What you can probably do is either spawn the effect on OnEndPlay()
btw isn't that what Unity does? sending inputs instead of position?
Or have the object send the Server/Multicast to spawn an effect to a different object rather than itself.
Hello! Does anyone know how to check if the PlayerState is a host (Listen Server)? I mean so even client would know who is the authoritative player of the session, so the IsLocalPlayerController() wouldn't help me.
HasAuthority
er sec
if HasAuthority and IsLocalController will tell you if a controller is the server and the servers controller
there might be some analog for PlayerStates
Gimme a sec I'll try it
Ah I already tried this one, the problem is client gets false cuz of IsLocalController()
You need to figure out who's host on the server
then you can set some replicated variable
Good idea though
APlayerState* HostPlayerState = ULeScoringComponent::GetHostPlayer()
with HostPlayerState being replicated
Based, thanks!
Worked like a charm, thanks again
Hi,
the gamemmode does only exist on the server, however only the gamemode has the applicationLifeCycle component where I can check if someone put the application the the background. How would I handle this on a client?
@dark edge so I found the issue, my client doesnt think its hitched to the wagon. however i cant find a proper way to tell the client that they are hitched without things breaking
Your one client or everyone except the server?
Just the client hitching. Other client and server see the constraint properly
here is client to client
as you can see the client shows no constraints attached, but the server shows it accurately
if this is just a limitation of the physics being replicated I would rather the client have the constraint be more accurate and the server/other clients be lagging behind. Im still fairly new at this so any suggestions are welcome
idk what unity does lol.
at runtime can i toggle between netserilaize and deltanetseriliaze for a fast array item ?
or is it only defined at compile time
what you consider "no safer then checking location"
yeah, because it is no safer, that has nothing t do with unity, i've never touched unity.
Is it fair to say that setting RPCs to "reliable" isn't entirely optional, it's actually something you want to be pretty thorough about, even though early on in a game's development you might not get bitten by it because you don't have enough network throughput that unreliable RPCs get dropped in favor of high priority ones?
I might have misread the docs, but my impression is that if something is essential to the integrity of the game state across the network and is not being spammed on tick, you want to mark it as reliable or risk the call being dropped and your clients getting out of sync?
yes its safer
it's as safe as validating player position
but introduces more friction when syncing client and server
IMO more than 90% of your rpcs should be unreliable
because there is rarely a case where its important to not have it droped
if you give me examples of your cases i can tell you more specifically
dont forget that missing a RPC means a player kick, so you absolutely dont want that for something recurrent or stupid
Is there a rule of thumb here that one might want to follow? My impression is that there are roughly two categories:
- things like player changing weapon, player respawning, player changing class - all of these are pretty essential and uncommon operation that you don't want to gamble not be transmitted to the clients
- operations like your position or rotation changing which are a stream of updates where if you drop a bunch of them it doesn't matter, it might introduce some jitter, but otherwise it's not mission-critical
for 2. you are right
for 1. not really, lets take the weapon change example:
lets take fortnite as an example: you have multiple guns, you scroll up/down to switch selected weapon
here is how its breakdown (its a example, idk how fortnite does this):
-
the inventory is a array of FMySlot, thats is replicated OnRep (impossible to lose data over time), the data is set on server
-
to change weapon, on scroll input event, we call an server RPC (unreliable, because if we miss it, be dont care, the player just have to scroll again)
-
once server RPC called and received, we do what we want (here, add 1 or -1 to the index), then replicated it (OnRep), the client will have its new weapon in hand
as you can see, most systems doesnt need reliable RPCs
as a more general way of saying:
- if you are on client and want to tell something on the server, most of the time you can do unreliable RPCs because if its missed the player can just recall it (inputs, widget buttons, ...)
- if you are on server and need to do something on client, either use unreliable RPCs (if its a one time cosmetic thing, like play a short sound) or uses variables (most of the time, OnRep)
does this help you ?
to change weapon, on scroll input event, we call an server RPC (unreliable, because if we miss it, be dont care, the player just have to scroll again)
I don't get why this isn't a problem. At least I as a player would prefer if an action I took (e.g. change weapon) was always executed by the game, not occasionally dropped requiring I repeat it. This would make me feel like the game I'm playing is janky and "inconsiderate" as far as UX goes.
Also the important bit here is how likely this is to not be replicated. Are we talking once in billion weapon changes? Or are we talking once every 10 weapon changes?
well
- RPCs are rarely droped, its only if you have a very bad conenction
- imagine a player having a lag spike, or just always lagging at 80-120ping, he will get always kicked out (cannot play at all)
i made it simple but usually for selected slot/hotbar things you predict on client then get corrected by server, thats what i do for example
same for shooting, you never use Reliable RPCs
if you want to test this out, play in PIE with net emulation at like 100-200 ping and spam shooting/scrolling whatever, you will be easily kicked
60 to 80 ping is average
well yeah, in most shooters bullets wont fire or fire to late
What?
Mostly all games have predicted firing
for a noob it doesnt change anything, for a pro player 50 ping and its over for him
What ?
because he will have faster reflexes
as soon as i have over 50 ping in volorant i see the difference for example
But that is still irrelevant though
Sure lower ping is better
But it depends on server location and stuff
anyways, whatever high ping is, no point in using reliable RPCs in the examples i gaved
And your net connection
mh, didnt saw that in valorant or fornite when i played
the effects are predicted locally but not the kill
what is your timeout before kicking a user for a missed RPC ?
well thats what i am saying
But actually firing gun is not
Also valorant has rewinding so ping is irrelevant
Fortnight uses the data from the shooter so again ping is irrelevant
i should be more precise:
- the local effects (animation bullet trace, shot VF) will be instant
- the damage (and so the kill) will not
Yes this is the way all games do it
But if your determining what ws hit on server
Then you will have issues
Unless you use rewind logic
not if the player kills you before
i saw that (if you play with high ping)
- you shoot the player (HS so he dies instantly) -> he doesnt shoot you back -> he dies (delayed)
- you shoot the player -> very fast he shots you back -> he will mostly not die (maybe because ping has a priority on rewinding ? idk if valorant uses data from mutliple users to test if he has the time to shoot)
im talking about valorant here
the also very good example of better ping is better is fornite building retake
Valorant likely only has a maximum rewind time + shooter advantage. If two players kill each other, whoever reaches the server first will survive, since the other one will be dead (and therefore cannot have killed someone)
any alternatives to physics constraints that might replicate better?
This is true in any game
World of latency
Ay
Hey y'all, anyone know what's the typical way to network player inputs for larger scale games like battlefield? Since in that scale i'm guessing bandwidth and CPU tends to be a problem, I was thinking perhaps going oldschool quake3 style is the way and just sending a compressed command buffer each frame, what are y'all thoughts? Maybe i'm overthinking it and I can just get away with RPCing every state change like reloading individually + push based replication?
(I should be clear before anyone answers that i'm not interested in using GAS here)
I don't understand the question perhaps others might not understand it either
2 large scale games could still handle it in different ways even if they are similar in size and number of players active at once or in the same map
Well lets say - I a client, presses R to reload my gun, how do we send it to the server and do it in a way where it would work well in a match with many many players without using GAS, that is the question
You could send an RPC to the server telling it you are reloading your gun; then the server replicates that to evewyone (who is relevant)
Regardless of approach if you want the server to know you do need to send a message to the server telling them what happened.
And the server will have to then tell everyone who needs to know about what happened; I don't think that's avoidable.
You can -optimize- by having features such as automated reload or stuff like that; so that players don't need to reload; or similar stuff; but reloading in itself I don't think is any issue compared to shooting or movement; movement is like wayyy more work and way more stuff than reloading
Well I understand that much lmao
I'm just asking how is the most optimal way to do that for a game like battlefield
and I do not believe it is RPCs
How is that hard to believe
If you think about something like Quake or the Source engine, then a usercmd is sort of a proto RPC and that's sent every "tick"
Ya but the thing about the quake one is that it iirc it compresses the inputs into a bitmask so it's absolutely tiny
but I guess yea it's RPC every tick or RPC every action
hmm
What's the typical way pre-GAS of acking inputs like that then, do you just wait for the onrep?
Like if you predicted something like ADS, and the server goes no fuck you, how would you usually rollback
Just send another RPC back from server to cancel the status?
Probably more of a nack than an ack since the former is less likely
should i use #if ue server or if (net mode ==) vlabla
I did something way back when that kinda worked, I would shadow variables like weapon state clientside so reconciling differences via the OnRep was less complicated
I would shadow variables like weapon state
How do u mean
WeaponState variable, replicated
AutonomousWeaponState, not replicated. Locally controlled would get and set this value instead via accessors
ahhh gotcha, interesting
I could do smthn like that actually, I'm doing similar to GAS tags
I used a setup like that for ammo too
Since for singly loaded weapons like shotguns, the values could get out of whack
ah yeah I can imagine
Different usage, I think?
If you uses the macro, the code should only be included in the target build.
Netmode works for PIE
Should never use multicast for something that needs to be in sync.
What should i do?
Level bp, prob server 0nly
So multicast apart being the wrong choice is just not gonna work
Learn how to replicate with repnotify
And server rpc to communicate from client to server.
Server send seed for the random number -> player propagate change based on the incoming seed to change the weather
And server RPCs won't work from level BP because the client doesn't own the level BP actor
Though at least Epic were kind enough to make the level BP actor replicate
I would not use it for a lot of things
think i have an idea ;3
Like the thing you doing has to be incredibly bespoke for that specific level for it to be justified
Start from having the server output a random number and ensure all clients received that same number.
From there it's just about using the number to choose which weather to use
get the random value from outside of the level Bp correct?
Yeah don't use level bp, create an actor and place it on the world. This actor can hold reference to the world object, e.g. lights, door, w.e
But i can still set the sky atmosphere inside the level BP right? cause getting a ref from another actor would just add another step?
No, in blueprint especially the communication only goes one way with level blueprint.
Just don't involve level bp at all for your weather system
Contain them in an actor instead
I see, so how do I ref the sky atmosphere and volumetric cloud actors inside of it?
wait i realize i can add them as comps
Create a variable of the type inside the actor class you create.
Mark it instance editable, expose on spawn.
Drop an instance to the level, use the eye dropper tool to select the target actor.
sweet i just added them as actor components
That will work but you should know how to set references too.
Because there will be instances where you want to do one over the other.
Yeah. i already have a lightning system and it was probably best I unified that and those two actors
i can just drop this in to if I decide to make another map
Im only using the level Bp to call all my loot spawn points and enemy spawn points when the day changes
and im not even certain that is the best way
No, just avoid it for now
Question about Network debugging with Visual Logger. It appears that Epic has made improvements to it. From testing an analyzing the Visual Logger time line is now in sync for object time stamps?
meaning the client and server are in lockstep with the visual logger time line
before this you had to provide your own Lambda function to sync the client and server to line up correctly in the visual logger timeline (like sea of theives did).
seems like now its working out of the box?
Quick question is world partition replicated for us or do we have to do this ourselves?
There is no replication for WP. What do you want replication for?
I would assume the server needs to load all partitions relevant to each client but each client only needs their own partition to be loaded
Heyas, what is the best way to replicate a TMap of UObjects? ๐
Ive got an open world game where the state of crafting stations is a UObject. Meaning if a furnace is cooking, theres a uobject that handles it, so it can coninue cooking while the player is in another area
(Its done this way so states can easily be applied to anything)
But how would I go about replicating something like that? ๐ฌ
TMap arent replicated
Dont replicate a tmap would be the best way :p
you have to replicate it your way
just a thought, why did you chosed a UObject over a struct ?
and why do you need a TMap
Uobjects are awesome (says the new uobject user , replacing my old struct approach)
Uobjects are far more dynamic , easier to expand upon :p
Haven't tried those yet
But they're less bp friendly without an additional library set of functions
what's the type of key in TMap?
I know, but TMap isn't replicated, I think he can use TArray in alternative of TMap if key is int32 type like {int32, UObject}
Just a different approach
You can just have a struct with a key value pair I guess
OnRep -> populate TMap in the receiving end
Or if the keys already exist on server and client...
Good
This feels like an odd thing to do though. Like you have a crafting station that has a thing queued. Your crafting should just exist, like.. You have an array of shit queued, or maybe only one. This queue should have a started time and a completed time. Even if you allow 500 things to craft at once, you should have only a single timer for this table that gets updated to the smallest craft time. When the timer finishes, you finish crafts that are finished and find the new best timer.
For a client this means just simply getting the replicated data. They don't need to know anything more than the start time, end time, and current server time, and what the item is to display necessary info to the user.
For a server this means that if you're actively unloading zones, you need to save it and reinitialize the system and check those times anyhow when you reload and it just gets replicated to whoever is relevant anyhow.
Hey!
Iโve been wondering why my character jitters on the client side when on a platform, whether they rotate or change position.
After 15 hours (no kidding) of meticulous testing, I disabled the camera lag, and suddenly all my problems were gone.
No more jittery movement on platforms, everything runs so smoothly in multiplayer now. So cool.
HOWEVER, now my movement feels so rigid, itโs awful. The camera lag added a really smooth, stylish feel to the movement, and it looked great.
So now Iโm stuck and asking for help. How can I make camera lag work properly in multiplayer?
Any ideas? Has anyone else experienced this?
Thanks so much!
Camera manager
Custom lerping ?
Seems like the camera boom struggles to keep up
Which ofc is a bit weird unless it replicates and get corrections or something..
Camera lag shouldn't have much to do with multiplayer?
maybe your platform is not interp smoothly on clients
Thats what im thinking, it should be a client only thing
Iโve had this same issue where adding camera lag makes things very jittery and laggy
So I actually donโt use it at all for that very reason but Iโd love to find a way to get it to work without that negative effect
maybe it's fighting with something
@crisp shard Is your camera's spring arm attached to tha Capsule, or the Mesh component? If it's attached to tha Capsule, then attach it to the Mesh.
Platform move like this
It's already attached to mesh !
I don't see why it's impacting multiplayer as well
You probably should interp the location for client
i also tried custom camera lag with Vinterpto and it result in exactly the same issue
you can't send movement data fast enough from server to client to be buttery smooth
most rotation/movement probably interpolated to smooth it out on clients
Hey everyone, I'm working on a first online multiplayer and to be honest, I don't see the appeal of GameState. I feel like everything that is in there could aswell just be handled in GameMode for safety reasons. Am I missing something?
Game mode can define the rules of the game and handle matches while game state is a place to store the state of the games
game state also replicated while game mode is server only
Scores can be something shared if you want players to see the same score for example
it make perfect sense to store that in the game state
since game state is replicated
yes, i got that. But if I got it right, the client can alter stuff that's in the gamestate.
Client can alter anything in their own machine
won't affect the game
Lets say they make them self rich, by changing the gold to 99999
But they only change their own gold in their own machine
in the server, their gold is still 50
oh, that's what i was afraid of
what exactly are you afraid of?
Maybe but i don't understand why a non replicated camera act like this
when the client want to purchase something, resolve it on server
that he could change the values inside the gamestate and that it would affect others
no?
they would only change the value for them self.
The only way for client to communicate to server is through server RPC
In a sense, what client sees are just visual, or illusion
Iโm using a sprite but it is setup like third person POV (3D world) but it is attached to the sprite not the capsule
the real value is hold by the server
Random Q but if I have different โcasting timesโ or โhold timesโ for doing different attacks but want them to all have the same Input Button would it be possible to change the value of the โholdโ time for the input to trigger based on which attack it is?
You need an ability system. Not to mess with the input system.
lmaoo damn
like GAS?
i mean , i suppose i could do it via an RPC / timer but that just sounds terrrible in praticality
Why do you need an RPC?
If you were just going to modify the inputs timer anyhow, all you need to do is wait in the ability itself locally on the client and then do whatever you were planning on doing when the hold time ended on the client.
yea you're right on that
i just don't use GAS but yea that would be sick nasty bon blick blasty
as they say
Much like CommonUI, I don't work without it anymore. ๐
lmfaoo two things i haven't switched to and my project is now pretty large, almost 2 years deep, but things still work , but those two things (mainly GAS) is somehting i would definitely start with if i were to make a new one
i don't know cpp enough to get in there and use it to it's potential
im also using 2d sprites as characters (3d world tho)
Yeah, I get that. ๐ I wish we had redone our last project for it when we had a small window but we were too far in.
You don't really need C++ for anything other than attributes really. A vast majority of the rest of it is BPable.
yea i have also read up a bit on that being the main cpp only thing and i do have GAS companion although, im not using it obv lol
i'll have to just do it at some point and change things. but mannnn would it be a task. legit would change almost every action
I was thinking maybe it works for only server and not for clients. But if what MyNansAGoat said is true then that pretty much is what I was looking for in the question.
Im not sure how to replicate things coming from the animation BP. Couldn't find anything online specifically about it. Anyone have any tips?
you don't replicate the anim bp itself generally
you replicate the parameters that you pass to the animbp
so in this scenario im casting to my character and pulling info off the cont/actor rotation
I would need to replicated the pitch and yaw within the character bp then when I cast I pull those variables instead?
ahh that worked. So I assume yes
I have a 2nd skeletal mesh on my character. I can't get it to replicate from the client. (if playing as server, it replicates for everyone. If playing as client, it doesn't)
I have setisReplicated to true on the mesh. Any ideas how i can get this to replicate??
Nothing replicates from a client.
If you want to send data to the server, you have to use RPCs.
hey im trying to set initial speed in an actor with ProjectileMomvent Component but that dosent replicate obbiously, any tips on how i can replicate that ?
does calling a regular function inside a server rpc, makes the regular function also run by the same instance (server) ?
Why do you need to replicate the speed if the speed is constant?
Just set the speed when spawning the actor and every copy will move at the specified speed.
non-rpc functions will just run on the machine they are called on...
you can call another rpc from inside the code on the server I suppose if you wanted to, like client-> server then client -> server as a response etc
yeah that's what I thought, I just wanted to make sure that a non rpc helper function for example called inside a server rpc is running on the server as well
If you are unsure, show your code
I'm on my phone right now, pc is off. but basically, the autonomous proxy character calls a server rpc to interact with an actor, the server rpc runs some stuff, and in case the said actor is an item, it calls a non rpc function inside the inventory component that picks up the item and attaches it etc.
Well you are already inside the server rpc, so that regular function only run in the server machine, unless there is a client or multicast rpc that calls that function.
You can just print string to check btw.
that's cool then. also how can I check with a string or whatever? I've been meaning to know which instance is running a code but haven't searched how
Print string with blueprint node will come with server/client prefix
Or if you want to use the logger, you can see how to get the prefix from the cpp code.
Just be aware there is bug associated with it on 5.3-5.4 I think where it always show client 0
Epic made some changes and fk it up.
ah I'm not using bps, but yeah pretty sure it'd be possible with the logger, I'll check that later
just with multiple clients or even the server is misinterpreted as a client?
You can call the print string function in cpp. I think it's somewhere on the kismet
What version of UE are you using.
I'm on 5.1 and no prob
yep I know, I use the GEngine->AddOnScreenDebugMessage, but that never prefixed its message with the particular machine. but anyways I'm sure there is a way
the very latest, I think it's 5.4.2
Well I suppose you can just get the net mode of the caller
Oh you would need the client ID tho, I would look at the print string implementstion
Hopefully it's fixed in 5.4.2
aah alright I'll keep that in mind then
I'll check about that and see
Is it common for games to use projectile prediction for something like grenades, or just for things like guns and rocket launchers?
I think every games predicted that? Even if I have high ping in battlefield, the grenade are thrown right away.
Same with any other fps game I played afaik.
depends on the game (the requirements that is)
valorant for example doesnt
I don't remember having delay when throwing a grenade or firing rocket when playing raze
Maybe I just don't notice it
Hey, simple question, what is the best place to store mp variables like kills, score, deaths etc, which are states (i.e: have to use repnotify). I understand that the best place to store is in playerstate, but i dnt understand why. What is the difference if we store in gamemode in an array
The difference is that the GameMode works completely different than the PlayerState
GameMode only exists once and only on the Server. You can't even use RepNotify there
PlayerState exists per Player and is always replicated to everyone.
So i dont have to do any replication programming in playerstate? So store kills there normally without an array?
There is still a replication aspect
You decide whats reped and whats not
Inside the PS
I think i would store this on PS
Hello. I'm using the default unreal character blueprint with movement component. But I'm experiencing strange stuttering/jittery movement when viewing clients moving from the server's perspective. Now here's the weird thing. Clients seen as clients and seeing the server from client all works fine. It's only clients viewed from the server that jitter around. What could be causing this?
So u set the variable of kills in PS from playercontroller on getting a kill. It will call a function in the PS to set the variable of kills. Now this variable shud be replicated? Or repnotified? I understand this variable is kind of a state variable so needs repnotified then? Can you please clear my confusion
- you dont have to always use the PC
- i would use repnotify to avoid missing updates
So call from playercharacter to PS for setting the repnotified variable of kills?
I have a server death event in playerBP which gets called when health<=0. So i can jst simply call the update kills function in PS from here?
Can anyone here link me to or explain to me how a dedicated server takes advantage of multithreaded code. For example if I have a single core server and Iโm using MASS to make math calculations on multiple threads for AI movement doesnt that single core only have 2 threads? Is it even worth writing parallel code or is it expected that if your game is running multithreaded calculations on the server you rent a machine with high core/thread count ? Yes Iโve googled, even asked AI Iโm asking here because I want to hear from someone with experience.
Yes this is fine
The simple thing is to just try running parallel tasks in a dedicated server build and see what it does
True, and I've done some tests with the local server playfab provides with their gsdk. However, since I don't understand the underlying architecture I'm just making guesses on what's actually happening. It doesn't help that my pc is the server so I have 32 threads and everything runs at light speed lol. I guess I will have to push out a small fleet. I just wasn't sure I could run unreal insights on a cloud server.
Hey is it true that i cant do any sort of logic inside level blueprint if i m using a dedicated server?
no thats not true
oh wait level blueprint i have no idea
but i dont see why it would be different for a dedicated server
I have a function that sets some variable in GM. The level bp, after begin play, and waiting for a few secs, checks that variable and performs some logic. This works if i m playing frm PIE. But when i m packaging and running the game on dedicated svr build, the level bp logics are not getting executed
Whenever i see 'wait/delay' in multiplayer setting to retrieve some value or reference I cant help but think this is a bad bandaid to an exec flow problem
Please, in laymanโs terms plss
Wait/Delay in a live environment will not always time out correctly, depending on ping/lag-spikes
Also, if you are trying to check the GM from the Level BP on the Client, that will always fail...
"It is only available on the server. Clients don't have an instance of the AGameMode class and will only get a nullptr when trying to retrieve it."
https://cedric-neukirchen.net/docs/multiplayer-compendium/common-classes/gamemode
Understood, thanks. Will change the code of level bp
Anyone care to help me try to figure out why my constraint to a AI pawn isnt replicating? Im on day 3 with this issue with no clear solution...
I'm having an issue on clients only with my Motion Matching anims. If the direction value is 0 then my anims are smooth, however if I'm going in any direction other than directly forward the anims stutter really badly. The character movement isn't correcting the movement is smooth, it's just the anims and it's only on clients. Any ideas where I could look I been at this for a long time
I also took motion matching away and made a regular anim instance with state machines and it does the same thing
I calculate direction with this function but I don't see why these values would have issues between client and server
So question about Mover/NPP. Should the client, which is predicting its own movement, effectively be "ahead" of the server in time with its own local movement?
NPP isn't retroactively changing things to account for ping times with inputs or anything?
We've got a situation where when a client is moving in just a straight line with no course correction, the time input is received and acted upon, the server thinks the client is further back along the line it's moving on than where the client thought it was when it sent the input. By quite a margin.
So teh client is a good 100ms ahead of the server.
In this image:
- Blue: where the server thinks the client is when the client sends input.
- Red: Where the server thinks the client is when it receives the input.
- White: Where the client actually is when it sent the input.
yellow?
I created a project based on Third Person template:
private:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
UInputAction* FireAction;
UPROPERTY(VisibleAnywhere)
class UTextRenderComponent* Message;
protected:
/** Called for firing input */
UFUNCTION()
void Fire(const FInputActionValue& Value);
UPROPERTY(ReplicatedUsing = OnRepNotify_CounterChanged)
int Counter = 0;
UFUNCTION()
void OnRepNotify_CounterChanged();
UFUNCTION(Server,Reliable)
void Server_IncrementCounterBy(int amount);
TPCharacter::TPCharacter()
{
// ...
Message = CreateDefaultSubobject<UTextRenderComponent>("Message");
Message->SetupAttachment(GetCapsuleComponent());
Message->SetIsReplicated(true);
}
void TPCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
// ...
EnhancedInputComponent->BindAction(FireAction, ETriggerEvent::Triggered, this, &ThisClass::Fire);
// ...
}
void TPCharacter::Fire(const FInputActionValue& Value)
{
Server_IncrementCounterBy_Implementation(10);
}
void TPCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ThisClass, Counter);
}
void TPCharacter::OnRepNotify_CounterChanged()
{
Message->SetText(FText::AsNumber(Counter));
}
void TPCharacter::Server_IncrementCounterBy_Implementation(int amount)
{
Counter += amount;
if (GetNetMode() == NM_ListenServer) {
OnRepNotify_CounterChanged();
}
}
But I don't see the Message changing when clicking the left mouse button on client machines, what is wrong?
The Message changes only when I play on Listen Server machine. The Message is successfully replicated to other clients.
Yes
ThisClass is just an alias of TPCharacter, it is not the culprit.
this tho
Trying Server_IncrementCounterBy(10); now.
well done
It works. Thanks.
there is a default array of players in the GameStateBase
how to get information, by which number a player is registered in this array?
i compare player state from array and self, but every of this returns 0 for every client, means he is first one
Shouldn't relied on the order anyway
You can't. The array is filled locally. There is no order to it. You'd need to make your own and make it replicated and only fill it as the server
If i change a replicated var on a client, will it get restored to the server val? Do i get a repNotify func call again?
No
If you change it on the client, the server doesn't know you changed it, so you won't receive an update. That is, until the Server changes it again and thinks it's different from the last acked value.
does this mean that the server is also tracking what it thinks the values are for all clients? pure curiosity
I'm trying to code an item/inventory system similar to minecraft's one.
So i have a inventory component with an array of ItemStacks (objects replicated through replicated sub-objects).
ItemStacks point to one item data asset, and has an array of fragments (objects replicated as well through the inventory component)
Items have a array of default fragments which are used to initialize the item stack's fragments array.
(Fragments are saved on the Item stacks only if they are different from the item's ones. If they get modified back to the default value, they get removed from the stack)
ItemStacks have a use function, which then calls the item's use function (which takes as parameter the item stack). The item implements functionality, but saves data on the fragments of the item stack
My problem is that i realized that this works well until i try to implement any kind of client side prediction to the item use mechanic, since if i was for example to have an ammo fragment, on the client i might rapidly remove ammo count till it reach zero, which would result in the fragment being removed, but then the server would replicate the change of the ammo count one at the time, resulting in the fragment being added again to the item stack (both on client and server since the fragment list is replicated)
My question is how would i deal with this, since i feel like i cannot just create fragments client side, since they are "replicated objects"
Should i just scrap the system?
Please tell me if i did not explain this stuff clearly enough
(Ping me if you answer)
Doesn't exist!
depends. We have two cases here, replication and delta replication.
Replication just sends the complete state from the server to the client, once the server detects a local change.
For delta it's on the one hand users impl, but in general you keep a per connection cache that stores the last state so it can calculate the delta to be sent to the client (full replication if old state doesn't exist)
๐ฎ
Maybe my eyes are deceiving me, but I'm sure there's a yellow mark there ๐
Optical illusion.
I'm still wondering if it's just a bad setting or something. Idk.
I'd have thought the server would be simulating the clients at present time, not 100ms in the past.
So what's the deal with Network Relevancy?
I have my objects CullDistanceSquared set to 1, yet it still perfectly replicates to all players
Everyone can see it at all times/distances and it sends/receives all events/calls
Is there some other setting that must be enabled to use network relevancy?
is it an actor ?
if yes, can you show the settings
if when you spawned it it was relevant everyone will see it, but it wont get updated if not relevant
Oh how does it become not relevant?
Also sorry about the other day, I asked a question but then had to leave immediately unfortunately
no worries
This is part of my other question actually.
I've got a open world crafting game like minecraft. I'm not sure how to handle the structures people create. Like if someone builds a furnace and puts food in it.
Trying with network relevancy, so the furnace is visible and working for those near it, but ignored for everyone else
The other option was making the furnace local, and just RepVaring it's state to everone.. but that's a TMap of UObjects lol
you can set a default distance relevancy
thats what i do when player builds
the "overlay" building piece isnt rep if to far away
what replication event got called that makes you think that its relevant ?
Well right now I just set it on the player pawns to test, and they're all visible and animating perfectly at all ranges
I assume a cull distance of 1 should break them at some distance right?
- its normal that they are visible, since its the player pawn my guess is that its forced to at least exists
- the animation is local, so if the actor isnt relevant the animation just wont be updated to whatever replicated state it used
can you test on a simple actor ?
make it display a var that increments each tick/few secs on server and thats reped to clients
go close then far away and see if its stops
Good idea! But does this also turn off it's rendering?
Ah poop lol okay. So probably not good for open world then?
you will need that
As you'd be able to see those blueprints from miles away
but for some game like MC, idk if you want to spawn/destroy the actors on client if to far
or just make them hidden and not net relevant
you can still use the classic cull stuff
like shadows etc arent displayed when far away
Yeah it's just odd if there's hundreds. Also my trees and bushes are designed the same way as those placable objects -- as they can grow and animate dynamically
So that means if all players are spread out, all the trees/bushes/structures in every players area, would also exist to everyone else nearby lol
make all of that animating stuff enabled/disable using distance
if VERY far, hidde/destroy
IT's just their existance I'm worried about, as they'd still need to be created when loading that area -- and thus their state needs to persist locally anyway
and use a savegame to save it and restore if players comes close enough
As there's not gonna be infinite trees existing with their own states
thats what MC does, it reads data from chunk data or generates a new chunk if none exists
Oh right, I forgot about savegames mid game
you would have to rely on saving and loading
And it just saves the chunks to disk?
i said chunks because thats what MC calls them
you will have to design and write your system
Yeah, for the structures I'll prob just go with having everyones be local, and it just updates the states to everyone
not MC, it uses tons of files
a lof of json iirc
So I essentially have all intereractions as UObjects (classes that handle the cooking/breaking/crafting/etc) seperate from the actor it's used on. So that area can easily be unloaded while the cook/etc progress persists
there is a lot of ways to do so
And a TMap -- <TilePosition, UObject state>
i would just have an array of objects with a struct that holds data
Now I can easily multicast when someone cooks a porkchop or whatever, and another when it's cooked
but unsure how to repvar that
Right, and repvar the entire Array?
this was a good ressource for me
https://www.tomlooman.com/unreal-engine-cpp-save-system/
I guess it's smart enough to only replicate what changes or is added?
oh you are talking about replciation, i was talking about saving
why not a reped var ?
Yeah haha, but I'll hold onto that link for later
Because it's a TMAP of Uobjects. The campfire actor itself does nothing. But clicking it with a porkchop creates a global UCookItem object that handles all the cooking -- so the campfire can unload safely and still continue
TArrays haves issues with delta when removing/adding
when you add/remove it will consider the edited index item and all the items to the right until the end as delta
if you want big replicated arrays i would suggest FastArrays
So yeah maybe I'll have another Reppedvar just holding the items state, while the Uobjects handles all the timings and stuff
Haha exactly what I was worried about
also TMap isnt supported for replication
Yeah I know, neither are UObjects lol, hense me asking here ๐
UObjects can be
So fast Arrays are used for net officially?
then need a owning actor or component, they will use its replciation setting
some stuff works great with regular arrays
the best idea is to profile both and see
Right, just worried on that you mentioned, being able to add/remove in the middle and not replicating the rest
What should we profile to make our choice? I mean what should we look at specifically?
Make a big array and edit/add/remove like you would with your system
Do that with both versions and see results
I realize this isn't strictly about multiplayer but primarily multiplayer games deal with spectating so asking here
When I set my gamemode's spectator class, it seems that pressing ; in the editor to enter the dev camera will actually spawn the gamemode's spectator class? Making it difficult for me to navigate around the map due to my spectator's behavior
Is there a way to avoid this linkage?
isnt the dev cam F8 ?
check editor settings
maybe you can set a class there
Oh, you're right there's also F8 which remains unaffected
Well, it's two different cameras, two diff behaviors
but I guess F8 can work for now (my editor settings search attempts came up empty)
Thanks ๐
Just avoid resizing to often
if i wanted to do a little short camera cutscene when leveling up or something would i just do all that logic on that client ? like just normally play a level sequence for that client ?
hello i have created a little game (local mode only) if i want to test the game with some people with online game system. Is it possible? Or i need to deploy the game on steam or something like that?
I didn't start the online training yet but it's to have an idea of what is possible to do.
yes
if it works on LAN you can use a service like hamachi to invite your friends to your home network (dont do this with people you dont trust)
or use another computer in your house
Anyone want my scuffed ass node to get around the stupid clientside issue where playerstates aren't predicted so you have to wait on the rep down? I can open sauce it maybe if anyone actually wants it
Tried lots of other solutions over the years and annoyingly this seems like the most robust / straight forward one
But in any case useful on character when u need the PS on begin play but it's invalid - lmk if anyone wants the sauce
so it's possible with Lan, but lan is it on the same home?
Same network yes
What do I need to learn if I want to play with someone in another country?
Curious which delegates you used for it
I ended up with some chain of 3 or smth
I didn't use any delegates I just wait for it on tick
couldn't be bothered to hook into the OnRep
from C++ it's really really trivial to just override the onrep for playerstate since it's virtual but in BP it's much more annoying unless you go expose it manually
It's essentially just a fancy wrapper around set timer next tick with a validity check
Oh here i thought you went the c++ route :p
Yeah its trivial-ish to get it through c++ , they should be exposed to bp by default imo
Check out how to connect in lan
problem is also that the OnRep is only for clients but you often wanna run the same code from BP on clients and server, so this just catches both
rather than having to do any client specific binding
Is there any plugins or anything that allow FFastArraySerializer to be used in blueprints?
https://www.youtube.com/watch?v=rrGx6bwwM6U
Found this but it seems broken and doesn't fully work
What do you mean use them in BP specifically, do you mean creating them in BP?
FFastArraySerializer isn't exposed to blueprints, so I can't actually use it for replication within blueprints
You can just make your struct you inherit from it exposed to BP
But you canโt directly create a fast array in BP.
This is the part I don't know how to do, I thought structs can't be inherited from?
They can (in C++), but Iโm not specifically sure what youโre trying to ask. If you inherit from a fast array and your struct is marked as a blueprint struct, you can still use it in BP.
Youโd just need to make your setter functions make the fast array dirty as needed.
Like Fishy suggested, you can use Hamachi. It emulates a LAN over the internet using a VPN, so you can connect separate wireless networks to the emulated LAN/Hamachi network.
If you don't want to rely on Hamachi you can use a subsystem that is compatible with Steam for example.
Although, I think Steam is region locked until you pay for your own app (might be possible to bypass by changing your download region, but I can't vouch for this. Though, it definitely works to use their free testing app ID within the same region, across countries).
If you want to bind to the post replication functions you can just store a shared pointer of a delegate (to prevent copying) inside of the fast array item and then make an async node to bind it to.
I'm not really a C++ guy lol
I've used it a long time ago, and many other languages -- but that sentence was a bit much for me lol
Iโm basically just trying to say that you can use a fast array in BP, but itโs up to you to make the reflected functions to interface with it
You just canโt create a fast array in BP
Yeah that's what I was asking earlier, if there were any existing plugins that did that already
Trying to find some online info on exposing structs to blueprints and coming up with no information
Did you create a fast array in C++ already?
Like can I actually do:
struct FBP_FastArray : FFastArray
{```
?
Oh wait
Are you talking about a UObject wrapper?
No
That is correct, (besides the naming)
Thatโs the only way TO make a fast array
You inherit from FFastArraySerializer(Item)
Oh, interesting. I couldn't find any info online, and then asked chatGPT and it responded with something about cheeseburgers and cats ๐คทโโ๏ธ
Mm okay I'll try it out. Don't have C++ intellisense on VSCode, so im just poking around in the dark lol
Sounds about right lol cheeze and cats
Donโt use VSCode 
You'd prob be fine with regular Arrays aswell ๐
But VisStudio is like 18terabytes and ryder needs a subscription ๐ฆ
Just once ? Perpetual licence thingy
The issue is just adding/removing on large arrays
Resizing fast arrays can cause issues in its own way
Oh right, I guess I just don't want yet another editor ecosystem for something I'll use once per month lol
(But this is the best)
How so? It's mainly just removing items
Just dont shrink it
If youโre getting to the point where you want to use fast arrays youโll probably end up using C++ more often
Hmm, so Add to available nulls, but Resize if array is already full
That could work yeah
Thereโs lots of ways to handle fast array removal, as an example my inventory items store a handle which is essentially a reliable index I can use to reference the item, and then I just use RemoveAtSwap when I remove items, so the array only changes 2 rather then shifting the whole array and needing to send a large packet
So I donโt need to rely on the indices of the actual items themselves
What does RemoveAtswap do?
RemoveAtSwap yes , exactly
Removes at an index, then swaps the last element in its place
Optionally shrinks, if im not mistaken
Say you have an array of 500 items, and you remove number 3โฆ 497 other items now need to shift and update the array.
If you just use .Remove
(With shrink)
Yeah fo sho. And removeAtSwap will only remove the last instead
So before I dig my face into this, does FastArray behave sort of like a TMap? I read it's order isn't guarenteed. So I'm assuming it's items use some sort of GUID instead of an index?
And they constant add/remove and lose a lot of the benefit
My inventory is only 6 elements. I don't even bother with fast array
The order isnโt guaranteed, thatโs why I store the index in the item as a handle. And no itโs not like a hash map
But I do also keep a TMap on the array for fast lookup since itโs O(1)
The client just builds it themselves after every change
Same lol
Builds the 500 item tmap lookup?
That won't affect performance?
Or is that perfectly acceptable within a frame?
Na, itโs a couple cycles
Way less then it would cause to lookup an item in the array
(Without knowing the index)
meaning over a few frames?
Or you mean a single loop over the array once for the Tmap, is way better than doing it for every item lookup
Ah great, sweet lol.
I'm got a mine-craft like game where you can interact with things (imagine cooking food) on actors. The interactions are stored in a Tmap<Uobject> as the actors can load in/out but their interactions(cooking) keeps running in the background
Using .Find has a time of O(n)
So I guess the easiest solution would be a replicated TArray<StateStruct>, with RemoveAtSwap when a state is removed, and creating a TMap when the array changes for easier lookup later?
Arrays are better for iterations and keeping cache misses down to a minimum, hash maps better for lookups
Cooking uobject sounds like something youd iterate over
Yeah thatโs an option
One does not exclude the other tho. Using them in tandem can be pretty practical
Would there be a better solution? Or is that pretty ideal
Donโt get caught up in the โbetterโ solution right now, just get it working
Well it's for an infinite sized voxel game, so the Tmap stores the voxel location Tmap<FIntVector3, UInteraction> for an easy lookup on which interaction UObject is at that voxel
I've got all my online working so far, this is the last piece of the puzzle lol. So might as well do it right
Just make the fast array and then you can post it here and someone can show you how/if it needs any improvements
That itself is probably going to be a day project lol
Makes sense compared to checking alllll UInteraction objects to ser if anyone is near and should load
Yeah exactly ๐
Personally id just stick eith regular array untill proven insufficient
Odds are, if done right, its not
Give me a second and Iโll just post some code of a fast array I use
Aight, I just don't wanna get caught in a performanc eproblem and not know what the issue is
You can just copy it
Oh that would be awesome man thanks!
It's incredibly hard to find any info on extending structs online, or even fast arrays for that matter
there is a entire template in the header file
I guess I could get rider for situations like this, but atm without intellisense experimentation is kind of impossible
in source
๐ฎ
USTRUCT()
struct FNetworkManagedObject : public FFastArraySerializerItem
{
GENERATED_BODY()
FNetworkManagedObject() = default;
FNetworkManagedObject(const TScriptInterface<INetworkManagedReplicationInterface>& InInterface, const TArray<uint8>& Payload);
/** The object being managed */
UPROPERTY()
TScriptInterface<INetworkManagedReplicationInterface> ReplicationInterface;
/** Buffer of serialized data */
UPROPERTY()
TArray<uint8> Data;
void PostReplicatedAdd(const struct FNetworkManagedObjectContainer& InArraySerializer);
void PostReplicatedChange(const struct FNetworkManagedObjectContainer& InArraySerializer);
};
USTRUCT()
struct FNetworkManagedObjectContainer : public FFastArraySerializer
{
GENERATED_BODY()
/** Fast array items for networking. */
UPROPERTY()
TArray<FNetworkManagedObject> Items;
/** Stores an [object : index] map for fast look-up. */
TMap<TWeakObjectPtr<UObject>, int32> HashMap;
bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
{
return FastArrayDeltaSerialize<FNetworkManagedObject, FNetworkManagedObjectContainer>(Items, DeltaParms, *this);
}
public:
FORCEINLINE TArray<FNetworkManagedObject>::TIterator CreateIterator()
{
return Items.CreateIterator();
}
FORCEINLINE TArray<FNetworkManagedObject>::TConstIterator CreateConstIterator() const
{
return Items.CreateConstIterator();
}
private:
FORCEINLINE friend TArray<FNetworkManagedObject>::TIterator begin(FNetworkManagedObjectContainer& Array)
{
return Array.CreateIterator();
}
FORCEINLINE friend TArray<FNetworkManagedObject>::TIterator end(FNetworkManagedObjectContainer& Array)
{
return TArray<FNetworkManagedObject>::TIterator(Array.Items, Array.Items.Num());
}
FORCEINLINE friend TArray<FNetworkManagedObject>::TConstIterator begin(const FNetworkManagedObjectContainer& Array)
{
return Array.CreateConstIterator();
}
FORCEINLINE friend TArray<FNetworkManagedObject>::TConstIterator end(const FNetworkManagedObjectContainer& Array)
{
return TArray<FNetworkManagedObject>::TConstIterator(Array.Items, Array.Items.Num());
}
};```
Just mark them as BlueprintType if you want to use them as BP
Awesome thanks so much! I'll check out FFastArraySerializer.h and also study this to get a better grasp of it all
Sweet ๐
If I go with steam. If I pay. I will be able to deploy test version on it? Or it will only for finished product? Will I have a dev environment ?
why do you need to use player state and why do you need to use a widget
just spawn an unreplicated actor from player controller?
make sure it is spawned client side
Yo anyone know if there's an easy way to predictively spawn an actor, then spawn it on the server, replacing the predicted one with the real server spawned one
I know they do something similar to this with the player controller but not sure if that's a special case or not
There's information that gets checked first on the player state to determine if it needs to be spawned (i.e. If it's a new save vs. an existing one).
In theory it SHOULD be spawning an unreplicated actor through the player controller on the client. ๐ค
player state exists on server and clients
my guess is you are calling the event on the server version of player state, could be wrong
need to see exact setup
Mind if I DM it to you? ๐
yeah but no guarantee how fast i am at replying
Is there a way to set a UPROPERTY pointer to a UObject derived class to point at a uobject class in editor? Like you would for a data asset
You mean? TSubclassOf<>
No i would like to have an actual pointer, like you can have a pointer to a data asset
I want only one instance of that uobject and reference it whenever needed
Can you provide me an usecase example? Like an actor in the world? Then you have to do it at the runtime.
Are you familiar with how minecraft's inventory is coded?
There is one instance for each item, and then how many item stacks you might want, which contain a reference to the instance of the item needed
I wrote the complete use case in delgoodie's server (i see you are in that one too)
Ah, i see. In general, i think you can create a structure containing your items pointer, example:
// Rough example, for sure.
USTRUCT FInventorySlot
{
int Count;
AItem* PointerToItem;
}
// Property in your inventory class (probably an UActorComponent):
TArray<FInventorySlot> InventorySlots;
And you have to add some kind of "add/resolver" function, example:
// Rough example 2.
void AddItem(AItem* Pointer)
{
// Probably, since you are using a data asset, you can introduce some kind of item ID, as minecraft does it. You can look up for this ID in array of item structures and increase count or add a new slot if it is not there. Usually, people fake empty slots visually and do not store them as "default" structures.
}
At least i would do it like so.
I don't recommend you to keep empty-slot structures and especially do not recommend you to use 2D arrays, if you are working on multiplayer game.
Will have a look now
My problem was with the fact that you can have a uproperty(edit default only) pointer to a data asset, which you can assign in editor.
But i wanted to do the same with a uobject* instead of a dataAsset*.
The reason is that as of now, items are data assets, but i wanted to turn them into simple uobjects.
And i need it to be a pointer i can assign a default value to in editor, since i might want to specify default items for an inventory.
(Sorry my brain is so fried i cannot really explain myself)
But that is probably not doable
Thanks
It depend's on why and how you want it to be an UObject. Do you want to have an ability to use this object as item in the world, like Minecraft does it with tools, for example? Then you can just introduce a data-asset UPROPERTY in your item's class and use the created item class in the inventory system, *but it needs to be an AActor class, i think.
Minecraft does not put items in the world, it creates an item entity (which would translate to an actor) with a reference to a ItemStack.
All the "items" you see in minecraft inventory are ItemStacks which have a reference to a item class (which is shared between all stacks of the same item)
I really like just having items be structs
So since i only need at any point in time only one instance of any item class (for example i could have 20 bananas stacks in my inventory, but only one banana item would be loaded) i should probably go with data assets
But since items contain logic i was wandering if it would be better to use uobjects
+1 to Adriel. I think it's just better in every possible way. I don't get why you need them to be an UObject? Which interactions are blocked with struct-only way?
Item class implements functionality only, no data. So i think a struct would be not optimal
Anyway my question was: you know when you have something like this on a component (with UXIUItem being a data asset)
TArray<TObjectPtr<UXIUItem>> DefaultItems;```
And then in the property panel you can add elements to the array, and then select data assets from the editor?
I wanted to know if it was possible to do the same if UXIUItem was a UObject
Cause when i tried, it just did not show any asset available
But yeah i agree, i should probably change my approach to this system
Let's start with a thing that UObjects are ten times more expensive than UStructs, it's important, i think. Sorry, but i still don't get what are you trying to reference at editor level. Maybe you are looking for TSharedPtr?
I was just trying to use a UObject to cover the same exact functionality as a DataAsset, which admittedly might be not smart
But i figured out that the reason why i wanted to use a UObject instead of a DataAsset was not gonna work
i did that for a inventory system
what i did was
- spawn on client
- send server RPC with class data
- spawn on server
- send client RPC // could replace this with OnRep var to be sure to not miss
- destroy/hide client actor
Cant you just wrap the DA in a Uobject tho? Gives you the instance freedom, while still having the actual asset at the bottom?
That is what i am already doing
You can use instanced uobjects for the editor functionality (picking item ref and so on)
UPROPERTY(EditAnywhere, Instanced)
MyUObject* Item;
// Class propeprties
UCLASS(Blueprintable, EditInlineNew, CollapseCategories)
I have a Multicast RPC however it looks like it is only being executed on the server (once for each client). Am I misinterpreting this?
cpp:
void ANordicVillageBase::SetVillageOwner(AActor* NewOwner)
{
if (HasAuthority())
{
OnVillageOwnerChanged(NewOwner);
}
}
void ANordicVillageBase::OnVillageOwnerChanged_Implementation(AActor* NewOwner)
{
if (!NewOwner) return;
GEngine->AddOnScreenDebugMessage(-1, 50.f, FColor::Yellow, FString::Printf(TEXT("NetMode: %d"), GetNetMode()));
}
h:
UFUNCTION(NetMulticast, Reliable)
void OnVillageOwnerChanged(AActor* NewOwner);
GetNetMode is 1 (NM_DedicatedServer), and the debug message shows twice for each client
Is the character's control rotation safe to use within a CMC context? i.e. GetMaxSpeed()?
Seems so, nvm
ok thanks. i will test it and see if it works ๐
specify what
if you're connecting, you don't specify a map
it's just the typically IP:port of the server
though with steam/egs p2p this will be some ID-based connection string
I added MoverComponent to Pawn at runtime and getting this Replication error. Any ideas?
LogRep: Error: RepLayout->ReceiveProperties FAILED: PlayerPawn /Play/002_Maps/UEDPIE_1_L_Basic.L_Basic:PersistentLevel.PlayerPawn_0
LogNet: Error: UActorChannel::ProcessBunch: Replicator.ReceivedBunch failed. Closing connection. RepObj: PlayerPawn /Play/002_Maps/UEDPIE_1_L_Basic.L_Basic:PersistentLevel.PlayerPawn_0, Channel: 5
LogNet: UNetConnection::Close: [UNetConnection] RemoteAddr: 127.0.0.1:17777, Name: IpConnection_0, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_1, IsServer: NO, PC: PlayerControllerNew_0, Owner: PlayerControllerNew_0, UniqueId: NULL:, Channels: 6, Time: 2024.09.17-03.41.37
LogNet: UNetConnection::SendCloseReason:
LogNet: - Result=ObjectReplicatorReceivedBunchFail, ErrorContext="ObjectReplicatorReceivedBunchFail"
LogNet: UChannel::Close: Sending CloseBunch. ChIndex == 0. Name: [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr: 127.0.0.1:17777, Name: IpConnection_0, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_1, IsServer: NO, PC: PlayerControllerNew_0, Owner: PlayerControllerNew_0, UniqueId: NULL:
LogNet: Error: UEngine::BroadcastNetworkFailure: FailureType = ConnectionLost, ErrorString = Your connection to the host has been lost., Driver = Name:GameNetDriver Def:GameNetDriver IpNetDriver_1
LogNet: Warning: Network Failure: GameNetDriver[ConnectionLost]: Your connection to the host has been lost.
LogNet: NetworkFailure: ConnectionLost, Error: 'Your connection to the host has been lost.'```
Are there any abstractions out there that would allow game designers working on a multiplayer FPS-style game using Blueprints to not have to know anything about what server or client are, how variables are replicated, RPCs and co? Anything out there that makes their gameplay logic "just work" intuitively without them having to understand the underlying synchronization layer?
My understanding is that this is how some high end AAA live-service games are implemented, with the programmers hiding most of that complexity away from designers through something custom they implemented for that particular UE project?
Not to my knowledge. GAS handles a lot for the designers but the implementation of more complex abilities still needs Multiplayer Knowledge.
The problem is that in most cases it's very important to know when to use RPCs vs Variables and where to place what code. If one could hide all of that easily then we wouldn't need to learn multiplayer for UE in general.
You can only really accomplish this on a per system basis imo
Yeah, I agree, that's why I was thinking that perhaps this is doable on a per-project basis, once you know exactly what your game's needs around replication are, but it would be impossible to do in a generalized fashion, where that system would work perfectly for every game one could build with UE.
Yeah even on a per project basis it will be tricky. It's difficult to stop people from doing the wrong thing. It also costs too much time fwiw
You'd need to code a gazillion nodes and events to and then teach people to use those
At that point I would suggest that the designer learns some networking :D
I mean, this is a general question, not directly aimed at abilities
Not the entirety of an FPS game
The use-case I had in mind was mostly around designers prototyping abilities and functionality early on before it's ready to be productionalized by programmers
Yeah. I suppose this would be a "tech designer" as they're sometimes called?
The case I had heard of involved a very, very well capitalized game, so likely not feasible for 99% of studios out there.
I met a lot of designers that understood how networking works and were able to create prototype abilities just fine.
I don't think they are that rare.
okay quick question, i do not need internet or do I to connect to my game thru ue4
because i can connect just fine without internet??
just curious is all
@lusty kelp Depends a bit on what you mean.
depends, if you host it in your local network you don't need internet. if you host it elsewhere you need internet. if you use any online services that are not hosted in your networkd you need internet
i am asking i am offline when i join my game
I don't follow, sorry
okay player 1 is hosted > 2 joined thats all no network involve extra
so you run both on your local PC?
I think you are lacking a base understanding of Networking, not even related to Unreal Engine.
Trolling again
what?? i am on the game testing
A Server, may it be a ListenServer (so a Player hosting in their Game) or a DedicatedServer (so a headless process that runs without Players), has to Listen to Connections on a Port (default 7777).
A Client (Player) connecting to that Server will try to connect to <ip-address>:7777.
Now, if you would package your Game now and you host a Server (ListenServer fwiw), it will listen on 7777 for incoming connections.
By default, in most cases, this will only allow connection via LAN, because most people (you probably included) have a Router that requires opening ports (you may have heard about that concept).
Without opening port 7777 to the public internet, only PCs inside your LAN can connect to that Server.
If you'd open the port in your Router to the public, you would be able to connect to the Server from outside via the public ip address of your Router.
DedicatedServer?
Is OpenLevel triggered by a player pressing "Host Game" or similar?
yes
Then it's a ListenServer. I don't think bIsLanMatch is enough though. You'd need to add the ?listen to it
i could join without the internet, dont u need internet?
No, you only need Internet if you want to expose the Server via opened Ports (in your Router) to the public.
Inside your LAN or even the same PC you can host and connect just fine.
so if i get tthis fl them to test my game and join without internet i wont come here to be mad at you
I don't really understand that sentence. Maybe cut it into multiple parts if you struggle with English.
i meant i wont blame you for telling me a lie
Ah, would you consider it a lie if I believe it's true? ;)
( lol indeed
well off for today, thanks
im just stating fyi that u dont need internet because ue4 already have a network built for you
u dont need to migrate this that or even add extra modules
the blank template does indeed have a network source already in when u load up your game
Yeah it uses SubsystemNULL and the default NetDriver.
Which offers LAN and connection via IP over the Internet if needed.
Extra Modules would only be needed if you want stuff like Sessions over the Internet via Steam for example.
yes true but i just saying is server for example / node is for that
u do not need this Seam, or any thing fancy
u just need the blank UE4 start up
i am not using nothing like that in my ini
4.24 fyi
Hey, I'm finding that my animation blueprints aren't synced up between the client and server, which means that when I randomly choose an idle animation to play, it will play a different one on the server and client or play the same one at different times.
How would I go about syncing these between the client and server
add custom nodes
oh to answer your question @thin stratus i using keys press to host join not ui
and when i run on dedi server i can join too offline
Was this a response to me?
yeah
Can you go into more detail on what you mean? Are you suggesting making my own animation playing nodes that fire via rpc to the client or something?
(Does syncing idle anims really matter? They'd only know during lan play and even then i'd imagine it's 'meh')
Syncing time is not worth it for idle animation, I am in the same boat.
As for random idle, you can replicate the anim sequence.
Don't even need to do random seed and all that. Make the anim idle sequence a replicated variable and have the server pick the anim based on random value.
How do you replicate it?
Open your anim bp and show me your idle anim
Someone helped me on this before, I didn't know we can replicate anim seq
The idle anim in the anim bp
Go inside your state machine
Or where ever you are playing it
Just the anim player
I tried replicating time with the player btw. Painful and not worth it, end up scrapping
Don't use random seq player
You will potentially get different result on each machine
Can you drop an animation there, then screen shoot
what should I use instead? Is there a collection node with an int input that I should set manually?
Ok now from my memory, you can right click on that sequence player
Tell me what option you get
Tldr, you assign the animation from the owner of the anim instance. Not in the anim instance it self.
Abp does not replicate.
Neither of these, I'm at work so can't show but I will see if I can find the post.
@wet bridge #cpp message
Here you go.
thanks
Have a sequence player (mark it as replicated) in your player character.
On begin play, if authority, get random anim and set it to the variable.
Abp simply read that value from the character.
This way server will choose the random anim and all client will play the same anim
Yeah this is how I was thinking of doing it if I couldn't find an integrated method.
Though i might want to look into a rudimentary time sync method depending on how relevant I deem it
I tried doing that and tap out
You can get the sequence player position and advance the anim player position but it was a painful process and I can't think of a way to scale it.
Having the players playing the same random idle animation suffice for me
If an actor has bForceNetAddressable (or is basically network enabled) is it just the name of the actor that is the same on server and client? There's no kind of id or anything?
That sounds right to me. Though I haven't ever had to use that flag. So just distant memories of talks in this channel
this is a NPC spawning stuff i hjave 4x of them they all spawn the same each time ?=
i have the random but they always spawn the same ?
Where's the multiplayer part? I'm not sure why the spawn item class variable is replicated
RIP
nevermind i was being dumb
Hello, does anyone have an idea why my traving is weird on the client?
I'm not sure how I'm supposed to interpret this screenshot
Quick question about multiplayer; how does one go about doing multiplayer for xbox or playstation? I'm aquanted with Steam and EOS, but I have no clue what's involved with xbox or playstation
That's what online subsystems are for, and there are NDAs
Aye, fair enough
Essentially it would be probably C++ instead of blueprints though right? Or do they give devs plugins?
Noob questions, I know haha
Well trying to do multiplayer and online platform stuff only in BP is bad at the best of times
And you get platform plugins that add stuff to the engine. A source build is required
Aye, It's possible with Advanced sessions for P2P type stuff, basic 2 player co-op.
But yes, I can understand the apprehension to just doing in in BP
I'm gauging how limited my game multiplayer abilities are based on what consoles need haha. I'm a blueprint heavy dev
Hi, as far as I though, during SeamlessTravel PlayerState persists as well. But for me, PlayerState is null. I started to look through engine seamless flow. And I found where it's being set to null and I'm wondering, what I'm missing.
void APlayerController::SeamlessTravelFrom(APlayerController* OldPC)
{
// copy PlayerState data
if (OldPC->PlayerState)
{
OldPC->PlayerState->Reset();
OldPC->PlayerState->SeamlessTravelTo(PlayerState);
//@fixme: need a way to replace PlayerStates that doesn't cause incorrect "player left the game"/"player entered the game" messages
OldPC->PlayerState->Destroy();
OldPC->PlayerState = NULL;
}
// Copy seamless travel state
SeamlessTravelCount = OldPC->SeamlessTravelCount;
LastCompletedSeamlessTravelCount = OldPC->LastCompletedSeamlessTravelCount;
}
You can't do console OSS stuff without C++.
Roger that, thanks
Well console need you to be compliant with TRCs. This stuff like the maximum time between presenting frames, how you handle user sign-in, controllers being connected and disconnected, someone yanking the ethernet cable out mid-match, terminology
It's called Hell. Run away.
Advanced Sessions handles that well enough for Steam haha Fair enough. Multiplayer can be a pain in the butt for sure!
Thanks for answering my questions guys
You can likely do some stuff with Advanced Sessions if it's just using the OSS API
And not specific to Steam or whatever
For sure, from my experimentation, it's been working decently well, but it's not scalable and I'm stuck within the Steam architecture, or EOS. I basically need to hire a programmer if I'm lucky enough to port my game to Xbox or PlayStation (if they'll even accept my game)
Well if you get SDK access just learn the TRCs that are relevant
You may have specific UX requirements over how you handle parties and lobbies too
Going to be brutally honest. If you want to test out releasing a console game. Do it singleplayer first. Singleplayer TRCs are hell enough. Online TRCs are straight up wild.
Noob question, what's a "TRC"
Technical Requirement Checklist
Thanks for the combined knowledge guys. Now I have some research to do! Have a good day
Also don't forget about supporting gamepads
100% already am
Nope
As in still need them.
Also localization. ๐คข
DualSense has some neat features
The amount of things Sony and Microsoft don't agree on per word, that varies per language, is wild.
Steam = beginner mode
Xbox/PlayStation= hard mode
I'm slowly working my way to graduate one day, still another year or two maybe to go
Consoles in general just have a quality standard. Which is great. But it's a steep hill from PC only.
I shipped a gen8 game, thankfully most of the challenge went to an outsource team getting the thing to run
But we did the gamepad implementation
I had to do some backend DLC purchase verification stuff though
I was thinking of adding cosmetic stuff...but I'll pass on that for my first multiplayer game, I'm just focusing on co-op, friend invite only type campaign
Also don't do it on 4.27 or prior. 5.+ has so many fixed TODOs and fixes in networking code in general.
I recently found out you can crash in a Listview in 4.27 if you give it two playerstates and they null out for a frame.
One single frame
i have the node " find path to location synchronously" but i cant replicate it all works fine... but the return value of this node only run on the server? what can i do?
It seems by overriding engine's PC SeamlessTravelFrom with commenting out:
OldPC->PlayerState->Destroy();
OldPC->PlayerState = NULL;
Issue is solved, but doesn't look to me like a good solution, because from looking at git this part of code was updated 2 years ago. Doubt that it's an engine issue.
But by the look of epic comments // we don"t need the old PlayerState anymore (in AGameMode::HandleSeamlessTravelPlayer(AController*& C)), it seems that PlayerState is meant to be empty during SeamlessTravel? And I mean when you look at the SwapPlayerControllers event in BPs.
i have a replicated chaos vehicle, and i want it to block pawn's movement
right now the pawn pushes the vehicle, how do I achieve this?
Try turn the pawn collision to query only
is it a pawn or character?
how is it doing its moving?
its a pawn
how is it being moved around?
physics, a movement component, just setting position on tick, what
movement component
You can probably set its collider to query only which should make physics things just ignore it, try that
same result ๐ค
why the replication dont work for the pathpoints?
all works fine its just the node " find path to location snychronously."
is this node something special? or why the replication didnt work?
Sure it's not hitting something else?
vehicle might be hitting some mesh or something else
I have a fast array defined like this:
struct FFastArray : public FFastArraySerializer
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
TArray<FFastArrayItem> FastArrayItems;
void AddAndMarkDirty(FFastArrayItem& FastArrayItem)
{
FastArrayItems.Add(FastArrayItem);
MarkItemDirty(FastArrayItem);
}
void RemoveAndMarkDirty(int32 Id)
{
for (int32 i = 0; i < FastArrayItems.Num(); i++)
{
if (FastArrayItems[i].Id == Id)
{
FastArrayItems.RemoveAt(i);
MarkArrayDirty();
break;
}
}
}
bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
{
return FastArrayDeltaSerialize<FFastArrayItem, FFastArrayItem>(FastArrayItems, DeltaParms, *this);
}
}
template<>
struct TStructOpsTypeTraits<FFastArray> : public TStructOpsTypeTraitsBase2<FFastArray>
{
enum
{
WithNetDeltaSerializer = true,
};
};
where I use it in my class:
UPROPERTY(ReplicatedUsing=OnRep_FastArray)
FFastArray FastArray;
UFUNCTION()
void OnRep_FastArray();
The Add works great and results in the client getting OnRep called each time and having all the items added. Not shown is another function I use to modify already existing items which also works as expected.
The remove however only works if there is only one item in the array. If there are more then one item then it will remove the item on the server, call OnRep on the client, but not remove from the array on the client. So the client get's the OnReps but is still stuck with a array full of items that should have been gone.
I have poked and prodded this and I can not figure out why this happens. Any ideas what might cause this or how to debug this?
turns out it was the skeletalmesh! the capsule is actually blocked by the vehicle, thanks a lot!
Show us your FastArraySerializerItem struct
Here is a generic FastArray template you can use.
any reasons why this struct isnt replicating ?
USTRUCT()
struct FSLPreBuildingData
{
GENERATED_BODY()
bool PreBuildingModeData = false;
int32 Priority = 0;
bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess);
};
template<>
struct TStructOpsTypeTraits<FSLPreBuildingData> : public TStructOpsTypeTraitsBase2<FSLPreBuildingData>
{
enum
{
WithNetSerializer = true
};
};
UPROPERTY(ReplicatedUsing=OnRep_PreBuildingModeData)
FSLPreBuildingData PreBuildingModeData = FSLPreBuildingData();
oh i forgot to flag the props with UPROPERTY()

It looks like this:
struct FFastArrayItem : public FFastArraySerializerItem
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
int32 Id = -1;
UPROPERTY()
UMyDataAsset* DataAsset = nullptr;
FFastArrayItem() {}
FFastArrayItem(const int32 InId, UMyDataAsset* InDataAsset)
: Id(InId), DataAsset(InDataAsset) {}
bool NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
{
Ar << Id;
Ar << DataAsset;
return bOutSuccess;
}
};
template<>
struct TStructOpsTypeTraits<FFastArrayItem> : public TStructOpsTypeTraitsBase2<FFastArrayItem>
{
enum
{
WithNetSerializer = true,
};
};```
Thank you for the templates, I will compare what I have with those
does anyone know how to pack different data per client when sending a multicast from server to clients? I would like to optimize the multiplayer network by comparing the previous acknowledged data with the new one and sending the data which is changed from the previous one. somewhat like delta compression implemented in quake3 (the paragraph above the image in "Network protocol" session might explains my idea https://www.jfedor.org/quake3/)
Use a Replicated struct instead of an RPC?
replicated structs only do that automatically in c++ though right?
Think I remember reading blueprints resends the whole struct
Hmm, can't seem to find the documentation for it, but I'm pretty sure blueprint structs do not have that functionality and check/resend the entire struct regardless of what was changed
so as long as you're not using blueprint structs you're set ๐
Ah it is already a Replicated struct. I said "multicast" but maybe it's not RPC multicast. https://github.com/EpicGames/UnrealEngine/blob/a79b9cb69366c23f0f9dd1db0a9355f3764ffef3/Engine/Plugins/Runtime/NetworkPrediction/Source/NetworkPrediction/Public/NetworkPredictionComponent.h#L70
Is there a better way to handle items than to use blueprint actors? Like what about a mesh and a struct that acts as the blueprint that holds data for that mesh?
If your item needs to have a physical representation, then afaik having a base class deriving from AActor is best. If not, then you might look into how Lyra handles items
I do need physical representation but I will have a look at Lyra anyways.
nvm just now realized Replicated does process NetSerialize() per client so I can pack different data. thank you guys for answering my question ๐
if (HitActor->GetHealth() <= 0)
{
if (UPrimitiveComponent* PhysicsComp = Cast<UPrimitiveComponent>(HitActor->GetMesh()))
{
if (PhysicsComp->IsSimulatingPhysics())
{
UE_LOG(LogTemp, Warning, TEXT("LAUNCHING"))
const FVector LaunchDirection = (HitActor->GetActorLocation() - GetActorLocation()).GetSafeNormal();
const float LaunchForce = 1000.0f;
PhysicsComp->AddImpulse(LaunchDirection * LaunchForce, NAME_None, true);
}
}
}
Anyone know why this wouldn't move an actor when it's called on the server?
The actor's mesh is simulating physics, and the actor's movement is replicated.
What's the value on the server when you call add imuplse? If it's 0 0 0 then it won't move.
The value of the launch direction, or?
Well it's either that or the launch force one of those is probably null on the server. Or are you even calling a server RPC to add impulse to the server version?
In your server RPC you might have to send the client direction value idk if it'll have any stuttering issues if the server calculates direction different than the client
guys, what is the proper way of running dev with real dedicated server? I can run server instance from editor, if I run as separate process, right? So I can run two editors one runs server and another will be client that will connect to that server. Is there any easier or more correct way to do it?
You don't need two editors. It's generally advised that you ultimately package the Server every now and then, but for smaller studios, let alone single devs, that's a bit of a jump.
If you want to start a headless server without actively running the editor, you can use .bat files for that.
@subtle kernel
Basically you can make a .bat file with the path to your Engine, and the path to the uproject, and then add -server -log and such things to it.
Soo.. Iris users. Does anybody know if the "Groups" concept supercedes any "Filtering"?
Trying to mimic an object which is spatially filtered for "normal" connections, but then use an inclusive group to force them to replicate to specific connections regardless of filtering.
Documentation for Iris is actually decent (!) but doesn't seem to specify this anywhere
ultimately package the Server every now and then
That ๐ผ
That's the best way; once you know the server works you don't need to do that for testing average stuff though; but still should now and then to make sure there aren't any bugs or whatevs.
