#multiplayer

1 messages · Page 285 of 1

verbal ice
#

no

#

That's one downside of those

#

You'll want your data to contain an index of sorts if you need order @pallid stone

chrome bay
#

yup no garauntee, if anything you should expect them to be in a different order

#

fast array is optimized towards the use of RemoveAtSwap so you don't have to constantly shuffle huge blocks of memory around

haughty ingot
#

I definitely recommend reading the behemoth of a command at the top of the fast array serializer file, I’m pretty sure it mentions specifically that order is not guaranteed, as well as pretty much explaining replication in general

pallid stone
# haughty ingot I definitely recommend reading the behemoth of a command at the top of the fast ...

It does thank you. It seems using the tfastarray is not an option as I have a 400kb initialisation for it that is larger than the max 65kb you can send as a packet and needs a custom setup via chunking to send a byte array of the data. The order setup for the replication is just a black box I am struggling to understand so changes to all the stuff I've been trying after my custom intialisation don't match up :/

thin stratus
#

You probably want to post this to #1054845249945616404 instead, even though this hardly qualifies as a tutorial and is more or less an ad for your service.

You, as a user, are basically never interacting with this community. So a blog post that largely contains lists with info from official docs, links to those official docs (of which some aren't even pointing to relevant content), and otherwise just stuff specific to the service you offer, doesn't really seem all that genuine.

I don't mind companies creating blog posts in which they, additionally, point to their services. DigitalOcean, for example, has some really great tutorials. However, their posts are hands-on tutorials, with lots of steps, examples, or even full walkthrough.

The lists at the bottom of your post seem nice as a starting point, although I do have to wonder if some of these points wouldn't benefit from a more detailed explanation or even an example.

Might be worth considering replacing that blog post with a step by step guide on how to profile a Dedicated Server in general, without your service, with images showing actual problems and how to identify them, and only posting your service related info at the end, as a bonus. At that point I wouldn't even mind pinning the post.

lapis siren
quartz iris
#

Hi guys I have a mode where defenders must protect an artifact from being picked up by the attackers, the defenders can move the artifact around the Site but once they try to go through doorways it shows a red box visual indicating they cant go through the doorway with the artifact as they would be leaving the Site. This message and visual only shows for the server though, not the clients, however the clients. can anyone help me make it so it only effects whoever has the artifact carried variable on the player rather than just effecting the server?

#

This is the code which is on the doorway/sitewall

#

So i want it to show for whoever has the artifact and is walking into the doorway not just the server

dark parcel
#

@quartz iris thats an obvious wrong case of using Multicast.

#

Tell me what Multicast RPC does.

quartz iris
#

Tells the other clients

dark parcel
#

Also never cross pins like that. (The blue pin goes to other node from other events)

dark parcel
quartz iris
#

I tried the on owning client

quartz iris
dark parcel
#

Exactly

#

So what happend when a client run multicast rpc?

quartz iris
#

nothing

dark parcel
#

It will just run the function for it self at best.

#

The only way for client to communicate with server is via server rpc

#

So if you need the client to tell server to run a function then use server rpc.

#

There's no instance where client speaks to other client directly.

Unreal uses server to client model.

quartz iris
#

so server rpc to owning client rpc?

#

from the site wall bp?

dark parcel
#

I need to read again, what r u actually trying to do?

#

@quartz iris who do you want to send the msg to? Both side or just the defender or just the attacker?

#

First of all, if that's the case. Client doesnt even need to do a single thing.

quartz iris
dark parcel
#

You can just show the msg locally. Without a single networking if the artefact is already possessed by the time the client hit the overlap.

#

This will eliminate the feeling of latency as well.

#

Optionally you can have the server tell the client that posses the artefact.

quartz iris
#

so when they hit the collision i just do the code i already did without any rpcs?

dark parcel
#

If you are going with server telling client to display a msg.

Then do this.

Component overlap-> has authority (true) -> get overlapped pawn -> if has artifact -> run client rpc -> display msg.

quartz iris
#

because I need the visuals/msg to ONLY show for the player who hit the wall

dark parcel
quartz iris
dark parcel
#

So only display msg when hitting the wall only to the player that picked up the artefact?

quartz iris
#

Yes

dark parcel
#

Try that

quartz iris
#

Ok will do, thanks!

dark parcel
#

@quartz iris btw you will need the client rpc method inside your pawn.

Create a function、call it display msg that takes text.

You can then call that function as described above.

#

This way the function will only run on the owning client (owner of the pawn)

dark parcel
#

@quartz iris work?

nocturne quail
#

this SoftPtr.LoadSynchronous() will work on dedicated server?

#

for me it gives an error target file not found

#

target file is the object passed using TSoftObjectPtr

#

loaded from hard coded FSoftObjectPath

#

tested with editdefaultsonly TSoftObjectPtr, giving the same error

humble ocean
nocturne quail
latent heart
#

Is the asset packaged on your server?

humble ocean
nocturne quail
latent heart
#

If the file doesn't exist, it isn't packaged. Surely.

#

It's a dedicated server package? Or listen?

nocturne quail
latent heart
#

Package your server without pak files and see if it's there. Or use a pak explorer.

nocturne quail
#

adding that Montages folder to cooked directory list will solve the issue?

#

I think since the asset path is hard coded, the cooker ignores it cause its not referenced to any bp asset?

thin stratus
#

Could be. How are you referencing it?

#

In theory, you don't need to manually add it to the cook list if it's used

nocturne quail
thin stratus
#

Yeah you should properly reference this in an Asset and not hardcode it

nocturne quail
#

TSoftObjectPtr<UAnimMontage>& TargetMontage = StandUnEquipMontage;
GetMontageSafely(TargetMontage);

UAnimMontage* UWeaponManager::GetMontageSafely(TSoftObjectPtr<UAnimMontage>& SoftPtr) const
{
return SoftPtr.LoadSynchronous();
}

lost inlet
#

And is it a UPROPERTY?

nocturne quail
nocturne quail
lost inlet
#

well there you go

nocturne quail
#

TSoftObjectPtr<UAnimMontage> StandUnEquipMontage;

nocturne quail
lost inlet
#

why? and why are you using hard coded paths?

nocturne quail
#

If I want to make it UPROPERTY, i will just fill it in editor

lost inlet
#

the cooker won't be able to see the soft reference

thin stratus
#

Don't hardcode paths

nocturne quail
thin stratus
#

Like, this is wrong. Do it correctly and the cooker will find it

lost inlet
#

very wrong

nocturne quail
lost inlet
#

but I'm sure missty has a cracked reason for it

#

yep, there it is

thin stratus
#

Don't care. It's wrong. Do it the right way. Reference it via an Asset.

#

Live coding is irrelevant for this.

nocturne quail
# thin stratus Don't care. It's wrong. Do it the right way. Reference it via an Asset.

Ok, and this next approach is also wrong?

UCLASS()
class ARMA_API UWeaponMontageData : public UDataAsset
{
    GENERATED_BODY()

public:
    UWeaponMontageData()
    {
        StandEquipMontagePrimary = FSoftObjectPath(TEXT("/Game/Montages/StandEquipMontagePrimary.StandEquipMontagePrimary"));
    }
    
    TSoftObjectPtr<UAnimMontage> StandEquipMontagePrimary;
};

AWeapon.h
UPROPERTY() UWeaponMontageData* WeaponMontageData;

AWeapon.cpp
AWeapon::BeginPlay()
{
    if (UWeaponMontageData* NewMontageData = NewObject<UWeaponMontageData>())
    {
        WeaponMontageData = NewMontageData;
    }
}

TSoftObjectPtr<UAnimMontage>& TargetMontage = WeaponMontageData->StandEquipMontagePrimary;
GetMontageSafely(TargetMontage);

UAnimMontage* AWeapon::GetMontageSafely(TSoftObjectPtr<UAnimMontage>& SoftPtr) const
{
    return SoftPtr.LoadSynchronous();
}
lost inlet
#

lol what is going on here

nocturne quail
#

since UWeaponMontageData is NewObjected, I think it should let the cooker know its an object and exists

thin stratus
#

Don't start making up a solution for a problem that doesn't exist.

nocturne quail
thin stratus
#

What you afterwards do with the exposed soft object ptr is up to you.

#

But referencing the asset should be done via that exposed property

#

You can then pass it around as soft object ptr, or load it and use it, or load it and store it in a transient variable, etc.

sick niche
haughty ingot
quartz iris
#

I added you as a friend on discord 😄

frosty harbor
#

How does replication work inside a non replicated gameplay ability? I remember people saying that Epic doesn't recommend setting gameplay abilities as "replicated", if that's the case, how would you go about replicating a montage being played inside a gameplay ability so other players can see the animation being played?

I'm just running Net Exeuction Policy "Server Only" since it's for AI but I can't see the animation playing at all unless I replicate the ability

kindred widget
quasi tide
#

I will still mark an ability as replicated just so I can do an RPC. Target data is dumb.

exotic wasp
#

it's dogshit simple as

#

but also the only thing to use

slate phoenix
#

Why am I having these issues? I couldn’t really understand much from the server logs either.
Aren’t ISMs replicated?

quasi tide
thin stratus
#

(Which usually starts throwing warnings when standing on them)

meager spade
#

i wonder if this was attached]

#

its weird

thin stratus
#

No idea what you want to say with that.

slate phoenix
thin stratus
#

Is that done during ConstructionScript?

#

I don't know if Blueprints can runtime spawn such Components outside of it, while having them properly named.

slate phoenix
#

Functions

#

I add new Functions

meager spade
#

and datatable eek but yeah this is problematic

slate phoenix
#

I did this intentionally.
If I limit the blocks, players won’t be able to place new ones.
I set up the ISMs to be loaded from the database.

#

If I don’t use a database, I’ll need to define a new block inside the Actor for every new block.
Am I thinking about this wrong, or is this correct?

thin stratus
#

Having the blocks as (H)ISM is correct. Shouldn't be a new Actor for each.

#

It's just that I'm not sure if Blueprints can spawn stably named components runtime.

#

Might be a limitation and needs C++.

meager spade
#

why does it need to be replicated for anyway?

#

couldnt the client just know what isms it needs to create

slate phoenix
#

i make dediced server game

#

If I don’t initialize the world on the server when it opens, how will other players see it?
Or would it work if I initialize the ISM builder on the client instead?

#

Maybe it will help you understand.

#

0:15 You will be able to see and visit worlds created by other players.
Each world will have its own markets, and players will be able to farm.
For players to see each other, a new server is launched on a separate port for every opened world, and that world is run by the server.
However, because ISMs are not replicated, the blocks are not visible.

#

If there is no one in the world, the server shuts down within 15 seconds.
This reduces RAM usage and prevents unnecessary server load.
However, when someone enters the world (either the owner or a guest), the server is started again on its own port

thin stratus
#

You'd usually replicate the data that then is used to create the ISMs instead of replicating the Components.

opaque forge
#

If I have multiple pixel streaming components in a scene, does each make an individual connection to the signaling server or do they somehow share one?

boreal flicker
#

I have a walljump system in my game. The way it works is every tick it does a sphere cast, and if it finds a wall it updates the wall variable which contains info about the wall. Then when you press jump, it checks if you’re currently on a valid wall, and if so do the walljump. I have it in tick instead of looking for a wall when you jump so that effects and stuff like that can constantly know whether you’re on a wall. The problem is the client and server disagree on if a walljump happened or not, and when the client mispredicts its pretty bad. What should i do?

cosmic phoenix
#

Hi everyone
I am having an issue with UE5 Multiplayer. When a Client approaches a 'BP_Chair' and interacts with it, certain events should trigger—for example, the character should sit on the chair. My problem is that instead of the Client who performed the interaction, the Server's character is the one sitting down, even if the Server is far away or didn't interact at all. The logic is only affecting the Server. For the system to work correctly, it must affect only the specific player who triggered the interaction, regardless of whether they are the Server or the Client. Could you please help me resolve this?

nocturne quail
#

Possible to start the game in late client mode?

boreal flicker
dark edge
boreal flicker
#

i am into cmc

dark edge
#

in C++

boreal flicker
#

yep

dark edge
#

is the wall check happening in the cmc tick or outside of it?

boreal flicker
#

i overrided the jump function to have walljumps and im calculating the wall in the tick function of it

boreal flicker
#

is that bad

nova wasp
#

but I can't see what you are actually doing in the server rpc

dark parcel
#

Haven't done one my self though

nova wasp
#

only in recent ue5 versions

dark parcel
#

Github: https://github.com/delgoodie/Zippy
Discord: https://discord.gg/uQjhcJSsRG

In this video I create the Wall Run and Wall Jump mechanic. The player will automatically enter a wall run while in the air and moving parallel with a wall.

Topics covered in this video:

  • Custom Movement Mode
  • Saved Move State
  • Geometry Testing
  • Mirrored Anim...
▶ Play video
dark parcel
nova wasp
#

nothing wrong with making a game for lower spec systems but we will always assume people are talking about a version we all actually use

nocturne quail
#

well there is another way to achieve it, launch server from command line and join second client from command line lately

silent valley
nocturne quail
silent valley
#

No... the number of clients in the drop down list for Listen Server or Client mode join at the start, not late joining.

nocturne quail
silent valley
#

🤦‍♂️

nocturne quail
#

running server from editor using command line and joining it with command line early/late is more freedom

nova wasp
#

you asked directly to be able to late join in client mode, that is an example of how to late join in client mode in play-in-editor

#

it is exactly as they say, it just makes the play button add a new pie client after the original number is created based on pie settings

toxic linden
#

Hi any one know is vehicle movement component with chaos wheeled supports replication

tidal saddle
#

Hello, im currently troubling with steam multiplayer connection. I have enabled both steam oss and steam sockets plugins. Steam overlay works, i can create session, but when i try to join from another pc nothing happens. Im using ue5.7.1 and yes, i have implemented accept invintation events, i attach all neccessary files. Any help appreciated 🙏

P.s Create session function on screenshot is not vanilla but my own implementation, which i attached in SGCreateSessionProxy.cpp

tardy fossil
#

do you have a log for the server thats hosting?

#

also i've heard appid 480 can be buggy and not work if lots of peopple are using it

tidal saddle
tidal saddle
tardy fossil
#

Error Unable to communicate with ANY of 30 Steam Datagram routing cluster. Possible problem with local internet connection? it cant connect to any of the steam routers for some reason.. maybe a firewall thing?

#

if you type ping 8.8.8.8 in command prompt, do the pings go through successfully?

tidal saddle
silent valley
#

I also recommend enabling verbose logging on these categories, by adding this to DefaultEngine.ini

[Core.Log]
LogSteamShared=VeryVerbose
LogOnline=VeryVerbose
LogOnlineSession=VeryVerbose
tidal saddle
#

but maybe it would make more sense to disable OnRep then

tidal saddle
nocturne quail
tidal saddle
nocturne quail
tidal saddle
dark parcel
#

@tidal saddle you can use struct to include your headshot data.

tidal saddle
dark parcel
#

@tidal saddle if you need more data such as vector (e.g to dictate force for ragdoll) on top of what you have right now.

Maybe just piggy back of HitResult instead creating new struct.

#

At the end of the day, does the same job imo.

rare cloud
nocturne quail
# nova wasp

just tested it and its very useful, saving lots of time

normal crypt
#

Question about RPCs: Is it possible for reliable multicast RPCs called before the client joins the game, to be received by the client once he joins minutes later? It seems to be the case in the editor, but not in packaged mode and I can't find documentation about it.

#

Simplification:

  • Host is playing alone and calls a reliable multicast on Actor1
  • Client joins the game 2 minutes later and automatically creates Actor1 locally, but isn't the authority.
  • Client receives the reliable multicast.
nocturne quail
normal crypt
#

that was my understanding too, but they seem to be queued and resent later under certain conditions in the editor.

#

I could be reading the data wrong though, will continue looking.

#

If it's the case, that's a big problem.

dark edge
#

how did client make the actor but isn't the authority?

#

or rather, show the code that ends in calling the multicast

normal crypt
#

The actor is owned by the server and the server set it to replicate, so the client gets this actor when he joins the session

#

I'm taking care of the kids, will get back to this later.

dark parcel
#

Rpc is a one time event. Any player that is not in the game will miss it.

normal crypt
#

I set the editor to spawn 2 standalone games. Then I connect them together through a listen server.

#

One of the standalone is the listen server, the other connects to it later, minutes after the RPC was sent.

#

This isn't cut and pasted code, I edited it because it's pretty complex.
`UCLASS(config=Game)
class ASprite : public AActor
{
GENERATED_BODY()

...

void SetReplicates(bool bInReplicates);

UFUNCTION(NetMulticast, Reliable)
void ReplicatePostInitChanges(...);

}
`

`void ASprite::SetReplicates(bool bInReplicates)
{
AActor::SetReplicates(bInReplicates);

...

ReplicatePostInitChanges(...);

}

void ASprite::ReplicatePostInitChanges_Implementation(...)
{
...
}`

#

And I essentially call SetReplicates on my ASprite somewhere in the code.

#

I'm going to continue debugging my issue now, if the kids go to sleep.

dark parcel
dark parcel
#

are movement input replicated?

#

I need the movement direction for the proxies.

nova wasp
#

not directly besides the velocity afaik

dark parcel
#

I see... thanks.

nova wasp
#

you can add replicated acceleration if that helps with a setting

#

you can also completely replace the onreps and replicated properties of aactor (acharacter etc) with enough cheesy macros and overrides

#

this is only really important if you need perfect atomicity though

#

for a slower paced game it won't matter though

dark parcel
#

Trying to tie this to CMC predictive movement.

nova wasp
#

ReplicatedMovementMode, bIsCrouched and not to forget ReplicatedBasedMovement

#

see PostNetReceiveLocationAndRotation and UCharacterMovementComponent::SimulatedTick

#

you can absolutely just add a cond_simulatedonly replicated property that has more context you need but be aware unless it is in the same struct (with iris) or manually serialized all at once it will be kinda arbitrary if it shows up exactly at the same time as the velocity + transform it was intended for

dark parcel
#

If I can get away with RPC, then I can just pass the direction there, but not sure if it will break predictive movement.

nova wasp
#

rpc here doens't make much sense unless it changes extremely often and also isn't very time sensitive

#

for example if it's kind of okay for it to be late or too early

#

and if it the things it changes are not very impactful

dark parcel
#

I tried to replicate via flag,
But not sure where my PlayMontage should be.

Tried to do it on BeforeMovement and AfterMovement, but it doesn't get played on other machines.

nova wasp
#

what does PlayMontage have to do with this? you said "movement direction"

#

is it a root motion montage?

dark parcel
#

Oh sorry, I'm trying to do 180 turn. But putting the multiplayer aside, I noticed that it doesn't turn the way I wanted due to TurnRate, so I figured I will need the direction input for the final look at rotation which in multiplayer context need to be passed.

#

I'm facing too many problem right now X_X.

dark parcel
nova wasp
#

root motion completely changes the entire flow

#

see OnRep_RootMotion

dark parcel
#

Pretend that I haven't said anything above.

How would you handle characters playing a montage all while respecting CMC client prediction.

nova wasp
#

the regular replicated transform updates will completely get skipped during root motion

dark parcel
nova wasp
#

it depends on what "respecting" it means

#

it's literally just onrepping the transform + velocity and movement mode then simulating it locally, then smoothing the result to hide how much it jitters internally

#

UCharacterMovementComponent::SimulatedTick is where I would look first.. I am personally not really sure exactly how sim proxy root motion works in detail

#

during root motion that will kinda replace how everything else works

dark parcel
#

should I still do it via compressed flag or not much sense to do it that way?

nova wasp
#

It depends... if it's just done locally via acceleration changing you could kinda just rely on that with some fuzziness I imagine

#

Making it a real "event" from the server will increase the chances it can miss

dark parcel
#

I tried checking speed change but other machines won't get updated fast enough resulting the condition get skipped all the time on other client.
TLDR it's been unfruitful to just apply the animation logic locally.

nova wasp
#

on simulated proxies you need to remember the mesh and actor location are entirely separate things

#

the true actor location is going to jitter

#

you can see how this actually looks if you turn on p.VisualizeMovement

#

the mesh location is smoothed and will interpolate based on a variety of settings

dark parcel
#

isn't that already handled for proxies

nova wasp
#

yes, but think about what that actually means

#

the motion you actually care about might be more the smoothed change in mesh position more so than than the raw velocity from the server

#

here is a cube on a sim proxy's mesh

#

this video looks choppy and that's not just because the recording sucks, the actual updates are very sparodic

#

I'm thinking I would personally try to consider the actual mesh to have its own velocity so to speak
of course you would need to consider and ignore really harsh corrections that skip smoothing it I suppose if those would cause false positives etc

#

honestly just trying replicated acceleration might be good enough though, I would suggest at least trying that first

#

the issues here imo is what do you do if it starts getting false positives that would never happen for the true local player

#

you could maybe have an idea of the true stage at which you did the "about-face" rotation and it was sent from the player itself from client->server as part of their saved moves somehow. You could make the sim proxies get an incrementing counter and/or a current "flip direction" as a byte or something if missing this is very bad

#

personally I would be okay with this kind of small animation flip being missed occasionally during extremely bad network situations... property replication is not a perfect series of events and probably should not be for sim proxies in most games unless the state is 100% required on all peers

#

Just remember that sim proxies do not care about saved moves, this is just a way to get that information to the server. getting that information to sim proxies has to be from something replicated on the character/a component/some rpc etc

#

which I think replicated acceleration will generally be pretty damn close to the intended movement direction while walking in most setups

#

FWIW I have not personally done that kind of turn-in-place from braking movement before so I'm sure someone else might have an evem more simple answer

dark parcel
#

All good, need all kinds of ideas atm.

nocturne quail
nova wasp
#

UWeaponManager::OnRep_CachedEquippedSlot() Line 426 and the things before it

#

not accusing you of making a mistake here, just not possible to determine what is going on inside of a null pointer/garbage memory

#

also this time I am going to suggest sharing context

nocturne quail
# nova wasp `UWeaponManager::OnRep_CachedEquippedSlot() Line 426` and the things before it
void UWeaponManager::OnRep_CachedEquippedSlot()
{
    UE_LOG(LogTemp, Warning, TEXT("OnRep_CachedEquippedSlot 1"));
    if (CachedEquippedSlot != 255)
    {
        UE_LOG(LogTemp, Warning, TEXT("OnRep_CachedEquippedSlot 2"));
        if (UCharacterAnimInstanceBase* CharacterCurrentAnimInstance = Cast<UCharacterAnimInstanceBase>(OwningCharacter->GetMesh()->GetAnimInstance())) // Line 426
        {
            UE_LOG(LogTemp, Warning, TEXT("OnRep_CachedEquippedSlot 3"));
            CharacterCurrentAnimInstance->SwitchToArmedState(GetEquippedWeapon());
        }
    }
}
nova wasp
#

this has 2 ways it can crash instantly

#

is OwningCharacter null? is OwningCharacter->GetMesh() null?

#

you need to read the current state of the memory around these lines

nocturne quail
nova wasp
#

uh... this onrep is running from an actor channel receiving replication

#

why would it being valid on the server matter to the client?

nocturne quail
#

owning character is a replicated variable

nova wasp
#

which I am mostly guessing because you did not include the context of which side this crashed on but I am pretty sure this onrep is called from a regular replication onrep

nova wasp
#

it can still be null

nocturne quail
#

server sets it

nova wasp
#

please show the state of the pointer at this line in the crash in the watch window

#

if you want help

nocturne quail
nova wasp
#

the server setting a replicated property does not gaurantee the client has it ever ESPECIALLY for a random unrelated property (CachedEquippedSlot)

#

they are two separate properties and there is NO gaurantee they will arrive in any particular order

kindred widget
#

Even if they do arrive at same time for this particular actor, that doesn't meaning OwningCharacter has arrived and is valid yet.

nova wasp
#

to fix this just don't dereference a null pointer in here and when OwningCharacter is set it also can just do the same thing as whatever OnRep_CachedEquippedSlot does to make sure the work is done when everything is there

#

this is a really common problem in unreal networking

#

you have two things that happen at random times and they need to both be there to do X, just do X in both places for whichever one happens when both are there

nocturne quail
#

yeah owning character is null

nova wasp
#

so yeah, maybe have an onrep for the character pointer and have it call
CharacterCurrentAnimInstance->SwitchToArmedState(GetEquippedWeapon());
so that it will apply the right setup when it comes in

#

or just poll for it in the pre anim tick (sometimes dumber is easier)

kindred widget
#

It's a good habit, networking or otherwise, to always nullcheck your pointers and gracefully handle their fail states. Nothing in gameplay code should be causing an app wide shut down.

nova wasp
#

this should not even be an error log, it can be assumed it WILL be null in some cases

#

replication does not care

#

ideally the stuff that expected it to be there can be done when it shows up

glass rune
#

is there a way to debug project with rider but only for example client 1?

exotic wasp
#

dunno if there's a specific way but if they are different processes you could attach your debugger to the one you want

glass rune
twin vessel
#

Where do you guys manage you ui from?

I might be super over complicating shit for myself, but basically I have a main menu, a lobby and a match level.
Both menu and lobby have access (through a ui button) to a firing range built in the level.
This means that i need to have basically the same game mode / player controller / pawn for all levels.

I guess i could put what widget to display on the HUD class and use a different one for each level. But this does not feel completely right either.

Also some ui depends on the game state, for example during the match there is a phase to select the weapons.

bitter veldt
#

hey there, im trying to make a little lobby system where players from the main menu can invite each other / create a party, and then load into the game once everyone is ready. i was wondering, what is the most ideal way for the clients to see other players names etc on UI? I was replicating a players array but noticed some issues with that

warped berry
amber vale
#

Anyone know any plugins or articles for smoothing movement on autonomous proxies? Movement corrections being performed instantly makes it impossible to have smooth player-versus-player knockback, and I'm wondering if there's an existing solution for this.

thin stratus
thin stratus
#

Well, the ones where you party up in the MainMenu at least

nova wasp
#

but they did say autonomous proxies ah. What I said there is for sim proxies (woops)

dark parcel
#

What are beacons? R they just another backend service from steam?

thin stratus
#

They come with a subset of classes, like BeaconHostState and ClientState. That are very similar to GameState and PlayerState.

#

But minus all the game related code.

#

So you can use them to have a party lead and party members in the main menu and replicate minimal data like names or what character is selected via them

dark parcel
#

0o? How does the connection established when players are not connected?

thin stratus
#

It's how, at least originally (not sure if still) the invite lobby of Fortnite works

dark parcel
#

Epic service?

nova wasp
#

interesting

kindred widget
#

Gears of War was one of the first majors to use it. I think one of them still does.

thin stratus
#

That's up to you. Beacon connections are just socket connections. It's the same as normal connections, just more lightweight

#

You can create a special session in your backend to handle them

#

Steam has the PartySession name for it as opposed to GameSession

#

EOS, no idea

dark parcel
#

So are most of the heavy lifting already done in the steam interface for Party Session?

thin stratus
#

It's the same concept in the end. The session backend just communicates the address to connect to

kindred widget
#

It's worth noting that you don't need to use the OSS specific stuff for them.

thin stratus
#

Don't know. I only ever used normal sessions but as PartySessions for them

kindred widget
#

They're just an actor basically that can send and receive RPCs from the server without going to the map. No replication.

thin stratus
#

Yeah OSS/Backend and Beacons are two concepts

#

Similar to how OSS/Backend and connecting to a server are two different things

thin stratus
#

Don't need to connect and travel to then learn that someone else connected faster

dark parcel
thin stratus
#

There are probably plugins but natively they are c++ only iirc

kindred widget
dark parcel
thin stratus
kindred widget
#

Similar. And no replication. All RPC based.

thin stratus
#

Been way too long

dark parcel
#

btw I got a question about Turn Stop movement.

kindred widget
#

Maybe. I could be going off of old info. I didn't test that, just the RPC bouncing.

dark parcel
#

So I finished a mechanic to turn 180 degree for the character, but I end up using RPC and montage as opposed to including the info in SavedMove.

#

is this not recommended? I always thought RPC for movement related is probably a bad idea. But I see ALS community version handle turning replication with RPC too.

#

trying to take a video atm.

thin stratus
#

No idea tbh. Never touched ALS or had to implement a 180 degree turn

#

I would probably just handle that in the CMC directly. Maybe by using ControlRotation or adding something similar.

#

Probably needs to be predicted. If it's driven by player input then it shouldn't be too difficult to just do it in the CMC

dark parcel
#

I tried to just locally check the deceleration but can't get it to work for Sims proxies because they don't update fast enough =(.

#

and my attempt on predicting it also failed.

nova wasp
#

My take earlier was to use replication acceleration or just add a new sim proxy only thing for it but an rpc might be more than good enough if it ends up timed okay

thin stratus
#

If the RPC is only for the SimProxy then that's probably ok

#

I don't know enough about 180 turns tbh

dark parcel
#

well it goes like this.

Autonomous do 180 turn -> Tell server to 180 Turn -> Multicast

#

kinda eww, but coudln't get it to work other way atm.

thin stratus
#

SimProxies are a problem in all those things. Flags that can be missed usually need to be a uint8 that gets increment instead

nova wasp
#

May I ask how it actually works math-wise when simmed locally? This is partially me wanting to try it myself more than just helping I guess

#

I always imagined it was some kind of like acceleration threshold that eventually locks you into a little turn-around move

thin stratus
#

Yeah. You have three values to work with I guess.

#

InputAcceleration, so input direction times acceleration.

dark parcel
#

in my case sim just not behaving the same. For example, I calculate speed locally to do a stop animation when sprinting.
But sim doesn't update the value fast enough that it skips the check.

Ideally, I just want to rely on acceleration / speed that I can calculate locally. That way I don't need to care about networking.

thin stratus
#

Acceleration itself (current one).

#

Velocity, also current one.

#

If I hold W along the X axis it would be some (X,0,0) input acceleration

#

And then some resulting current accel and vel

#

If I then hit S suddenly, it would still be the same velocity start of that frame

#

But input accel now points opposite

#

Which is a good point to notice the 180 turn I guess

#

Since CMC doesn't replicate shit to SimProxies, they only get the final velocity I guess.

kindred widget
#

I'm confused. Isn't this mostly just a root motion montage?

thin stratus
#

So gotta replicate some incremented uint8 flag in the character to indicate the turn

thin stratus
#

RootMotion takes too much control away and is too stiff

dark parcel
#

initially I don't want to use root motion because I want some slide effect like ice skate. So trying to rely on acceleration / deceleration for the effect.

#

but I end up with root motion anyway. Skill issue.

thin stratus
#

Players with gamepads could do 170° turns

#

You also lose a lot of control with the RM approach

#

Not saying it can't be done with RM

#

But then that also needs to be the exact result you want

kindred widget
#

Yeah I was just thinking the quick spin around effects some games have. Probably falls apart if you do it slower than a quarter second or so.

thin stratus
#

If you notice the turn you can just play a root motion montage, sure. And you can use some motion warping to fix the cases where players trigger it from gamepad and didn't do an exact 180 turn.

kindred widget
#

And the sliding kills that idea too.

thin stratus
#

MotionMatching is a perfect system for this if it wouldn't be so damn fucking expensive

#

Like you don't even need to use it for the whole animation locomotion

#

Can just feed it some reference point calculated from the input and use that grab the best montage with the best start time of that montage to get the perfect result

dark parcel
#

tried with 400 ms, doesn't seem breaking yet. But working outside the prediction system, I am not sure if I'm going to get issues in the future.

thin stratus
#

Mid 180 turn you do another 180 turn? MotionMatching can pick the best matching montage for that too. Sadly expensive and needs tons of animations

nocturne quail
#

why is OnWeaponReplicatedNotify not always broadcasted for late clients?

void ACharacterBase::ServerPickupWeapon_Implementation(UWeaponItem* WeaponItem) 
{
    if (!WeaponItem || !WeaponItem->WeaponClass || !WeaponManager)
    {
        return;
    }

    FActorSpawnParameters SpawnParams;
    SpawnParams.bNoFail = true;
    SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
    SpawnParams.Owner = this;
    SpawnParams.bDeferConstruction = true;

    FTransform Transform;
    if (AWeapon* Weapon = GetWorld()->SpawnActor<AWeapon>(WeaponItem->WeaponClass, Transform, SpawnParams))
    {
        const FName EquippedSocket = "Equipped_Gun";
        Weapon->FinishSpawning(Transform);

        Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, EquippedSocket);
        WeaponManager->SetWeapon(Weapon);
    }
}

void UWeaponManager::SetWeapon(AWeapon* NewEquippedWeapon)
{
    PrimaryWeapon = NewEquippedWeapon;
    OnRep_PrimaryWeapon();
}

void UWeaponManager::OnRep_PrimaryWeapon()
{
    OnWeaponReplicatedNotify.Broadcast(PrimaryWeapon);
}

void ACharacterBase::OnWeaponReplicatedNotify(AWeapon* Weapon)
{
    UE_LOG(LogTemp, Warning, TEXT("OnWeaponReplicatedNotify broadcasted"));
}
#

ServerPickupWeapon_Implementation is reliable
and DOREPLIFETIME_CONDITION_NOTIFY(UWeaponManager, PrimaryWeapon, COND_None, REPNOTIFY_Always);

tardy fossil
#

probably binding the delegate after onrep is called

#

onreps can get called before begin play

nocturne quail
nocturne quail
#

its like failing 1 out of 5

tardy fossil
#

stick a debug log print in the onrep and right after the delegate is bound and see whats going on i guess

dark parcel
#

Print on tick to check if you actually get the right value? Its probably just race condition.

nocturne quail
nova wasp
#

just bind to it earlier I guess

#

beginplay is relatively later in the lifecycle

nocturne quail
nova wasp
#

as ultimately the onrep triggering is random... may as well just call the function you were binding for when you first bind to it if it has a meaningful value when you first see it

#

also as I mentioned earlier, if (WeaponManager) can silently fail if the weapon manager is null but if it's a default subobject it might never really matter

dark parcel
#

I dropped like 40 items in the map and the on Rep got called in batches

bitter veldt
fallen fossil
#

Roles question.

If LocalRole is SimualteProxy, then can we distinct if this Actor/Pawn is controlled BY server or* Other Client?
🤔
cause it looks like I have to check this other way

dark parcel
#

What do you mean by server of other client?

#

There is the server and there are client / clients.

#

Sim proxies are other pawn that you dont control.

Lets say 3 players, i am the listen server, john is 2nd player, mary is 3rd player. Each of us controll a character.

In my machine : my role is authority over all the player character.

Meanwhile in john computer : my character is simulated proxy, mary character is simulated proxy. His own character would be automous proxy because he controlled it.

In mary computer : john and my controlled character is simulated prozy. Her own character is autonomous.

amber vale
# thin stratus CMC corrections are smoothed fwiw

Simulated proxies are smoothed, but autonomous proxies aren't—at least not with a default configuration. If you're a client and the server corrects your movement, you're instantly teleported to the server's location. Looking at the CMC's code, variables like Network Smoothing Mode, Network Max Smooth Update Distance, and Network Simulated Smooth Location Time are only used when correcting simulated proxies.

fallen fossil
#

cause I guess ListenServer is Player

bitter veldt
# thin stratus Party Systems are usually done via Beacons.

Do you know if Beacons work fine in 5.6 with Steam? I'm searching around in the Discord and it seems like people were having issues - also saw this forum post 🙁 https://forums.unrealengine.com/t/online-beacon-compatibility-with-steamsocket-plugin/2665805

Epic Developer Community Forums

Hi, I’m trying to use the Online Beacon plugin. In Lyra’s Steam\DefaultEngine.ini, I noticed a comment stating that SteamSocket doesn’t currently support beacon connections. Is that still the case? If not, I’m testing this in UE 5.6 with the SteamSocket plugin. I was able to establish a host connection, but I’m unable to get the cli...

exotic wasp
#

I wouldn't be confident in it existing yet, though

#

You should probably just have a bind function that immediately broadcasts the initial value

#

Or something along those lines

viscid obsidian
#

will the CharacterMovementComponent automatically run PerformMovement() witht the same input vector for consecutive ticks if multiple ticks worth of time have passed on the client framerate?

#

Or am I supposed to implement my own tick cycle?

nova wasp
#

it works in a while loop and has settings for min/max ticks iirc

#

I am unsure how it handles extreme cases with keeping input or not (I would assume it keeps it)

thin stratus
#

(not saying you are wrong, but wouldn't be the first time that someone states something that they were also not sure about in the end. Will probably check the code once more next week when I have my PC set up again)

thin stratus
thin stratus
#

Aka to have a bit more precision for collision and such

viscid obsidian
#

Are we not supposed to change the parameters of the character movement component? I don’t see anything in the docs about the networking accounting for changes in configuration of the movement component across different ticks

nova wasp
thin stratus
#

E.g. the WalkSpeed variable is usually quite set in stone.

#

You can alter it via some OnRep property in the character, but that might lead to a few corrected frames

viscid obsidian
#

So what’s the intended flow for defining a bunch of custom moves that may be similar to walk or sprint or jump in nature but have slightly different mechanics?

#

Im not sure what the intended extension point of the system is

thin stratus
#

Inherit and extend where needed.

viscid obsidian
#

So we would inherit the component and add potentially more modes or parameters?

thin stratus
thin stratus
#

Extending movement is usually a matter of inheriting and adding your own stuff in c++

viscid obsidian
#

Adding more parameters and modes doesn’t sound too bad because it should be mostly independent from the awesome framework unreal provides

#

I’ll be sure to take a look at the pinned examples. Thabks for the help!

thin stratus
#

Server doesn't tick client movement after all.

#

Client sends RPC with all input data and the delta time and server performs the move when receiving the RPC

#

Server frame rate doesn't really matter due to that

viscid obsidian
#

Doesn’t the client send on a fixed tick rate?

thin stratus
#

No

viscid obsidian
#

Oh really they send by frame? That’s odd to me

thin stratus
#

CMC uses an "independent" frame rate.

#

Each client uses their own frame rate.

#

Above 60 FPS it will try to combine moves.

#

That concept is also the reason that animations can look choppy on listen servers when it views other players.

#

Cause the pose of the skeleton is ticked via the same RPC on the Server to ensure animation and movement events are in sync.

viscid obsidian
#

Do you know how the independent frame rate is different from a fixed rate?

thin stratus
#

Question doesn't necessarily make too much sense

#

It's in the name what the difference is

nova wasp
#

the cmc kind of just has timestamps in each sent move

nocturne quail
#

other option I can just add this function to AActor and override it in the Character class

#

this will be the case if I really want to avoid the cast, but I will not since this is not a rapidly call operation

dark parcel
nocturne quail
dark parcel
#

What do you have to lose

nocturne quail
#

cast exists to access a member once and save it cache it for later use

#

in my case I am not saving it since character can have many weapons and players can join/leave

#

so the old cache can be invalidated or crash if not refreshed

dark parcel
#

Btw for your on rep condition rat race, maybe you can just use a boolean as a state to see if the required component already initialized.

#

Use it to determine wether to call the onRep or not.

#

Kinda see this pattern in GAS when addressing race condition

nocturne quail
#

that's a great idea, maybe will consider it if things gets complicated again in future

desert breach
#

Hey Devs, I've a Pickable actor which I spawn on server and is replicated. It has Collision , Mesh and Audio Component, I wanted to play the sound when some player pawn touches it, So I used a client RPC to execute the call. The call is executed however the sound doesn't play.
However when I try to do it in single player it works fine .
Here is the .cpp
`void ABasePickable::ClientPlayPickupSound_Implementation(AActor* OwnerActor)
{
UE_LOG(LogGOG, Log, TEXT("Inside Client RPC call"));
// Only play if this client is the one who picked it up
APawn* LocalPawn = GetWorld()->GetFirstPlayerController()->GetPawn();
if (OwnerActor && LocalPawn && OwnerActor == LocalPawn)
{
// Play sound directly without spawning actors
if (PickUpAudioComponent && PickUpAudioComponent->Sound)
{
UGameplayStatics::PlaySound2D(this,PickUpAudioComponent->GetSound(),1,1,0,nullptr,nullptr,true);
//PlayLocalPickupSound();
UE_LOG(LogGOG, Log, TEXT("Playing Audio Cue"));
}
}
else
{
//UE_LOG(LogGOG, Log, TEXT("Owner Actor Not Same"));
}

}

void ABasePickable::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (CollisionActor == OtherActor )
return;

if(CurrentPowerUpActorState == EPowerUpActorState::PickedUp)
    return;

if (OtherActor->GetClass()->ImplementsInterface(UPawnInterface::StaticClass()))
{
    CollisionActor = OtherActor;

    if (GetLocalRole() == ROLE_Authority)
    {
        FString compName;
        OtherComp->GetName(compName);


        FString enumName;
        const UEnum* WeaponStateEnum = FindObject<UEnum>(this, TEXT("EPowerUpType"));
        WeaponStateEnum->GetValueAsString(InventoryInfo.Item_WeaponType, enumName);
        enumName = enumName.Mid(14);
        //UE_LOG(LogTemp, Warning, TEXT("PickedPowerUp is %s"), *enumName);

    //    UE_LOG(LogTemp, Warning, TEXT("On Server, found  %s"), *compName);
    //    UE_LOG(LogTemp, Warning, TEXT("Overlapping Pickable!"));
        if (UVehicleBlueprintFunctionLibrary::GivePowerUpToThisPlayerController(CollisionActor->GetOwner(), InventoryInfo))
        {
            //UE_LOG(LogTemp, Warning, TEXT("%s Powerup To: %s collided with %s  component"), *this->GetFName().ToString(),*CollisionActor->GetFName().ToString(),*OtherComp->GetFName().ToString());
            APawn* PlayerPawn = Cast<APawn>(CollisionActor);
            if (PlayerPawn)
            {
                AController* PlayerController = PlayerPawn->GetController();
                if (PlayerController)
                {
                    ClientPlayPickupSound(PlayerPawn);
                    UE_LOG(LogGOG, Log, TEXT("Calling Client RPC"));
                }
            }

`

here is the .h
`UPROPERTY(Category = Pickable, EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
class UAudioComponent* PickUpAudioComponent;

// Add RPC to play sound on specific client
UFUNCTION(Client, Reliable)
void ClientPlayPickupSound(AActor* OwnerActor);`

``Typically an Client RPC should be called on the client which is colliding, and then there I picked the objects audio component to play it.

Its not playing the sound, however the function executes, what is wrong I'm doing ?

dark parcel
#

@desert breach where do ClientPlayPickupSound lives?

#

Mind you client rpc only gets called if the actor is owned by that specific client.

#

So if the client rpc function lives inside the PickupActor then you are not doing it right as the server owns that replicated actor.

#

You can have the function in object the client own.

By defauly, its the player controller, character and player state.

#

I say controller make the most sense here. And if you dont want to bloat your controller, make an actor component, have the function inside the actor component then attach it to your player controller.

#

Heres what you can do.

Create a client rpc function in player controller.

Call it Client_PlaySound. Input is USound and just do PlaySound2D(InSound).

Now in your pick up actor.

1.On picked up / overlap.
2. If authority
3. Get overlapped / interacting character -> get controller -> cast to your controller and call client_playSound.

Done.

nocturne quail
dark parcel
nocturne quail
dark parcel
#

Guess not important enough if missed

marsh niche
#

Hi everyone, I'm running into a strange desync issue on Quest 3 (Client) vs Tablet (Server).

I am loading multiple small sub-levels using a ForEachLoop calling Load Stream Level (by Name).
To prevent freezing the HMD, I added a 0.1s Delay between each load (see screenshot).

On the Client, some Static Meshes inside these streamed levels appear displaced/offset.

  • The Server sees them correctly.
  • It is intermittent (happens randomly to different objects).
  • Meshes are set to Static mobility.

I suspect the Delay + LoadStreamLevel is causing a Race Condition where the actor's transform replication arrives before the level is fully initialized on the Client.

Question:
Has anyone experienced this offset with streamed levels? Is FlushLevelStreaming the only way to fix this, or is there a better way to chain level streaming in Multiplayer without freezing the VR headset?

Thanks!

lament flax
#

so there isnt any proper real time replciation on the world ?

#

the game state server delta is very rought, when emulating bad net conditions i can get 0.5s late time

#

it seems it doesnt try to simulated past time but only some smooth/sync when the var is replicated, i might have to do a custom solution

dark parcel
#

@lament flax simulate past time? R u trying to get the network clock or something?

lament flax
#

i just want an elapsed server world time a minimum accurate on the clients

dark parcel
#

Yeah thats the article i would go for if you want to implement your own.

#

Was gonna link the firsf one.

#

I dont think it can get any better. It just send burst of rpc and calculate the average. You can modify the frequency of the rpc being send.

There was complain with player state server time due to player state having low net updats rate in the past but some people say it has since changed.

Ive already copy paste the code from the first articlr so i never use the one on player state.

lament flax
#

i was using time to have server and each local client simulate passed time to basically move a platform

#

but since any ssolution requires RPCs anyways, i might just go for the classic transform replication for my platforms

dark parcel
#

Well if all the machine can agree on the same time then the platform can be simulated locally.

Provided that the platform always move in the determistic way.

nocturne quail
hoary spear
#

Interaction sound sounds like a local thing to me

dark parcel
#

I have it as client rpc atm as server is the auth for picking up item.

hoary spear
#

Ah ofc

#

For others to hear

dark parcel
#

I can just force play the sound locally on interact but that will be premature if there is delay since server have to give the green light if the item is picked up or not.

The moment my interact data is removed from replication. The sound also plays.

hoary spear
#

You dont predict the pickup?

dark parcel
#

You can translate the platform based on the time.

You can always apply correction too since tou try to sync the time 24.7.

Better than syncing all platform. And as a bonus, the platform would be on the same position even other people have significant delay. Not sure how that will play out with cmc prediction movement though.

dark parcel
#

What if other people picked it up? Do we have to snatch it back from the player 🙁

hoary spear
#

Yuss!

#

Uno reverse

#

Buut i suppose you could wait. I do that too atm, but its instant anyways since i just test local atm

#

Was thinking of dealing with it later if it gets annoying

orchid latch
#

Hi, I'm having a rather difficult time trying to solve a crash issue after updating our project from 5.6 to 5.7.
For our game we use listen servers and SteamIP net driver (with the correct location of the net driver change in 5.6: +NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/SocketSubsystemSteamIP.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver"))
After the update to 5.7 we could no longer play our game over the internet, LAN was fine.

I tested out SteamSockets net driver (+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/SteamSockets.SteamSocketsNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver"))
It crashed due to SteamSockets seemingly not supporting non-seamless ServerTravel (https://issues.unrealengine.com/issue/UE-239936)
So I enabled seamless travel for our Lobby and Game gamemodes and added a transition map. It works, we can now play our game over the internet.
However, if we want to restart the game map, all clients crash.
Call stacks seem to indicate that some Niagara hooks into Chaos are the cause, but what I can do about, I don't know.
We have tested this with an empty map to make sure our maps aren't doing anything weird.

We are restarting with the ServerTravel ?Restart option, same as the RestartGame AGameMode function does.
The host is launching the Lobby map with the ?Listen option.

All of the testing for this is done via a packaged development build on Steam using our Steam app ID.
In PIE this all works ok (using net.AllowPIESeamlessTravel 1 to enable seamless travel in PIE)
We are using the standard distributed Unreal Engine builds via the Epic Games Launcher.

Unreal Engine

Welcome to the Unreal Engine Issue and Bug Tracker. You can check the status of an issue and search for existing bugs. See latest bug fixes too.

#

The last thing from the client before crashing (crash seems to happen after the transition map and going back to the game map):

[2026.01.12-15.30.15:452][ 53]LogWorld: SeamlessTravel to: /Game/Maps/Map_EmptyPlane
[2026.01.12-15.30.15:467][ 55]LogWorld: BeginTearingDown for /Game/Maps/Map_EmptyPlane
[2026.01.12-15.30.15:472][ 55]LogWorld: UWorld::CleanupWorld for Map_EmptyPlane, bSessionEnded=false, bCleanupResources=true
[2026.01.12-15.30.15:473][ 55]LogSlate: InvalidateAllWidgets triggered.  All widgets were invalidated
[2026.01.12-15.30.15:507][ 55]LogAudio: Display: Audio Device (ID: 1) registered with world 'Map_Transition'.
[2026.01.12-15.30.15:510][ 55]LogAudio: Display: Audio Device unregistered from world 'None'.
[2026.01.12-15.30.15:519][ 55]LogRenderer: Forcing update for all mesh draw commands: SkyLight real-time capture change
[2026.01.12-15.30.15:531][ 55]LogUObjectHash: Compacting FUObjectHashTables data took   0.64ms
[2026.01.12-15.30.15:534][ 55]LogChaosDD: Creating Chaos Debug Draw Scene for world Map_Transition
[2026.01.12-15.30.15:534][ 55]LogStreaming: Display: FlushAsyncLoading(664): 1 QueuedPackages, 0 AsyncPackages
[2026.01.12-15.30.15:535][ 55]LogStats:     SeamlessTravel FlushLevelStreaming  -  0.000 s
[2026.01.12-15.30.15:562][ 55]LogWorld: Bringing World /Game/Maps/Map_Transition.Map_Transition up for play (max tick rate 300) at 2026.01.12-15.30.15
[2026.01.12-15.30.15:562][ 55]LogWorld: Bringing up level for play took: 0.027264
[2026.01.12-15.30.15:562][ 55]LogWorld: Sending NotifyLoadedWorld for LP: LocalPlayer_2147482468 PC: BP_GamePlayerController_C_2147481819
[2026.01.12-15.30.15:562][ 55]LogNet: Verbose: NotifyLoadedWorld Begin
[2026.01.12-15.30.15:562][ 55]LogNet: VeryVerbose: GetFunctionCallspace RemoteRole Remote ServerNotifyLoadedWorld
[2026.01.12-15.30.15:562][ 55]LogNetTraffic:       Sent RPC: BP_GamePlayerController_C /Game/Maps/Map_Transition.Map_Transition:PersistentLevel.BP_GamePlayerController_C_2147481819::ServerNotifyLoadedWorld [39.4 bytes]
[2026.01.12-15.30.15:562][ 55]LogNetTraffic: VeryVerbose: Sending: FOutBunch: Channel[5] ChSequence: 324 NumBits: 315 PacketId: 0 bOpen: 0 bClose: 0 bIsReplicationPaused: 0 bReliable: 1 bPartial: 0//0//0 bHasPackageMapExports: 0 NetTokensPendingExport: 0 
[2026.01.12-15.30.15:562][ 55]LogNetTraffic: Verbose: UNetConnection::SendRawBunch. ChIndex: 5. Bits: 315. PacketId: 13134
[2026.01.12-15.30.15:562][ 55]LogNet: Verbose: NotifyLoadedWorld End
[2026.01.12-15.30.15:562][ 55]LogWorld: StartLoadingDestination to: /Game/Maps/Map_EmptyPlane
#

The crash call stacks aren't always the same, here's two I've seen:

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff

ntdll
Dolly!Chaos::FEventManager::UnregisterHandler() [D:\UnrealEngine\Engine\Source\Runtime\Experimental\Chaos\Private\EventManager.cpp:42]
Dolly!UNiagaraDataInterfaceChaosDestruction::BeginDestroy() [D:\UnrealEngine\Engine\Plugins\Experimental\ChaosNiagara\Source\ChaosNiagara\Private\NiagaraDataInterfaceChaosDestruction.cpp:333]
Dolly!UObject::ConditionalBeginDestroy() [D:\UnrealEngine\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp:1295]
Dolly!UnhashUnreachableObjects() [D:\UnrealEngine\Engine\Source\Runtime\CoreUObject\Private\UObject\GarbageCollection.cpp:6158]
Dolly!UE::GC::PostCollectGarbageImpl<1>() [D:\UnrealEngine\Engine\Source\Runtime\CoreUObject\Private\UObject\GarbageCollection.cpp:5773]
Dolly!UE::GC::FReachabilityAnalysisState::PerformReachabilityAnalysisAndConditionallyPurgeGarbage() [D:\UnrealEngine\Engine\Source\Runtime\CoreUObject\Private\UObject\GarbageCollection.cpp:5970]
Dolly!CollectGarbage() [D:\UnrealEngine\Engine\Source\Runtime\CoreUObject\Private\UObject\GarbageCollection.cpp:6216]
Dolly!FSeamlessTravelHandler::Tick() [D:\UnrealEngine\Engine\Source\Runtime\Engine\Private\World.cpp:8824]
Dolly!UEngine::TickWorldTravel() [D:\UnrealEngine\Engine\Source\Runtime\Engine\Private\UnrealEngine.cpp:15563]
Dolly!UGameEngine::Tick() [D:\UnrealEngine\Engine\Source\Runtime\Engine\Private\GameEngine.cpp:1873]
Dolly!FEngineLoop::Tick() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5829]
Dolly!GuardedMain() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\Launch.cpp:190]
Dolly!GuardedMainWrapper() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:123]
Dolly!LaunchWindowsStartup() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:277]
Dolly!WinMain() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:335]
Dolly!__scrt_common_main_seh() [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
kernel32
ntdll
#

and

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff

Dolly!UNiagaraDataInterfaceChaosDestruction::BreakingCallback() [D:\UnrealEngine\Engine\Plugins\Experimental\ChaosNiagara\Source\ChaosNiagara\Private\NiagaraDataInterfaceChaosDestruction.cpp:1922]
Dolly!UNiagaraDataInterfaceChaosDestruction::PerInstanceTick() [D:\UnrealEngine\Engine\Plugins\Experimental\ChaosNiagara\Source\ChaosNiagara\Private\NiagaraDataInterfaceChaosDestruction.cpp:2492]
Dolly!FNiagaraSystemInstance::TickDataInterfaces() [D:\UnrealEngine\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraSystemInstance.cpp:1875]
Dolly!FNiagaraSystemInstance::Tick_GameThread() [D:\UnrealEngine\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraSystemInstance.cpp:2605]
Dolly!FNiagaraSystemSimulation::Tick_GameThread_Internal() [D:\UnrealEngine\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraSystemSimulation.cpp:1348]
Dolly!FNiagaraWorldManager::ExecuteSimulations() [D:\UnrealEngine\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraWorldManager.cpp:1755]
Dolly!FNiagaraWorldManager::Tick() [D:\UnrealEngine\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraWorldManager.cpp:1615]
Dolly!FTickFunctionTask::DoTask() [D:\UnrealEngine\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:349]
Dolly!TGraphTask<FTickFunctionTask>::ExecuteTask() [D:\UnrealEngine\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:697]
Dolly!UE::Tasks::Private::FTaskBase::TryExecuteTask() [D:\UnrealEngine\Engine\Source\Runtime\Core\Public\Tasks\TaskPrivate.h:519]
Dolly!FNamedTaskThread::ProcessTasksNamedThread() [D:\UnrealEngine\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:791]
Dolly!FNamedTaskThread::ProcessTasksUntilIdle() [D:\UnrealEngine\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:691]
Dolly!FTaskGraphCompatibilityImplementation::ProcessUntilTasksComplete() [D:\UnrealEngine\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:1604]
Dolly!FTickTaskSequencer::ReleaseTickGroup() [D:\UnrealEngine\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:1035]
Dolly!FTickTaskManager::RunTickGroup() [D:\UnrealEngine\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:2129]
Dolly!UWorld::Tick() [D:\UnrealEngine\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:1743]
Dolly!UGameEngine::Tick() [D:\UnrealEngine\Engine\Source\Runtime\Engine\Private\GameEngine.cpp:1883]
Dolly!FEngineLoop::Tick() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5829]
Dolly!GuardedMain() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\Launch.cpp:190]
Dolly!GuardedMainWrapper() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:123]
Dolly!LaunchWindowsStartup() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:277]
Dolly!WinMain() [D:\UnrealEngine\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:335]
Dolly!__scrt_common_main_seh() [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
kernel32
ntdll
desert breach
amber vale
thin stratus
#

It should always be parented to the Mesh

#

For that very reason

twin vessel
viscid obsidian
#

This is in regards to extending the CharacterMovementComponent to support more movements

normal crypt
#

In the editor though, the authority will NOT force your copy to tick.

#

It's also not happening in every situation. I didn't debug this enough to figure it out.

verbal ice
#

Multicast RPCs can be queued in very specific scenarios

#

generally when the actor isnt available on a client yet

#

but is about to

#

afaik

#

that's about it

amber vale
twin vessel
amber vale
twin vessel
amber vale
eager spindle
viscid obsidian
#

when extending the CharacterMovementComponent, is the idea to override Getters like GetMaxSpeed() GetMaxAcceleration() so that we can adjust simulation parameters deterministically based on boolean state flags?

thin stratus
warm willow
#

guys, is it expected behaviour that notify is not firing on listen server when adding a tag to container, client is firing; But notify is firing on server/client when setting a container variable

thin stratus
#

The problem is how OnReps work in Blueprints.

#

In C++ they don't call for Servers. The reason they call for the Server in Blueprints is that they are sort of "Property Changed" notifiers there.

#

But the whole thing is coupled to the Setter. The Add node doesn't trigger it.

#

Best thing you can do is probably set the container with itself in that case.

warm willow
#

thanks

#

now i see container is just array inside

thin stratus
#

Yeah, but that doesn't even matter that much. It's more the K2 node that is the Setter I believe

warm willow
#

So maybe Epic should in Add gameplay tag func make array dirty? or it would not work in BPs anyway?

#

thats what i was doing in c++ but I only tacked cpp replication

thin stratus
#

Idk what trigger the OnRep logic exactly

warm willow
#

push replication or whatever

thin stratus
#

Could be that it needs to do that but might be a special function call in the K2 node

#

Yeah it's not about push replication

#

You are getting the onrep on the client after all

#

Something inside the Setter triggers the changed notifier.

warm willow
#

Got it

thin stratus
#

Again, in C++ OnReps don't call on the server to begin with

warm willow
#

I know, you have to manually call func

thin stratus
#

You can have a Single-Player game and use the OnRep as a Property Changed notifier in Blueprints in theory. Not that you should

warm willow
#

but its magic automated in bps

fallen fossil
#

Is Struct Property replicated as whole or only its child values per change?

chrome bay
#

child values

#

almost all properties replicate as deltas

modest crater
#

Unless you implement a custom net serializer for your struct (just making that distinction for anyone else who might read this and not realize)

grizzled garnet
#

UE documentation mentions a Remote RPC alongside server/client/multicast. I've never seen this before, is this something new and from what version of UE?

nova wasp
#

It's new in 5.5. I have not tried using it yet personally

fossil spoke
#

From what I remember its possibly related to the experimental server meshing (cant remember its proper name).

fossil spoke
#

I feel like it was related to that

#

I could be wrong

rare cloud
#

from my understanding it's like you have an identical Server and Client RPC, you can use Remote and it will be call on the other side

#

but the use case seem niche

fossil spoke
#

It could very well be just a convenience like that

#

Might not be tied to anything in particular

#

Though they wouldnt have added it unless they had a reason to

#

In the MultiServer paradigm I wouldnt be surprised if it has something to do with like "local" authority for a particular server instance in relation to another instance next to it.

#

🤷

#

Server instances need a mechanism to talk between each other without a Player involved.

#

Might be related tothat

#

"If I am a Slave instance, send this to the Authority, if I am the Authority, send it to Slaves"

#

🤷

#

Tracking down the commit that it was introduced in might give clues

nova wasp
#

remote object is kind of the term here

#

basically every single TObjectPtr has code now that considers remove objects

dark parcel
#

How would you check if a controlled actor is controlled by the listen server?

#

GetNetMode() it is.

verbal ice
#

IsLocallyControlled()

#

with IsNetMode(NM_ListenServer) if need be, or just an authority check

dark parcel
#

IsLocallyControlled just check if the actor is controlled by local controller.

I need to check if the character is owned by the listen server.

#

all characters will return authority on server machine.

#

To put it into context, I am dealing with interaction on server side.
With lag in mind, I will tolerate extra interaction radius when interacting character is owned by a client.
But for server, I want the radius to be checked as is because server have no delay.

#
if (InteractingCharacter->GetNetMode() == ENetMode::NM_ListenServer)
{
                
}

Not sure if this is even right 🤔

#

Perhaps I don't think clearly...

#

i can probably do the opposite. Check if the controller is owned by a client, otherwise it's the server.

#

Get Remote role or something.

#
if (InteractingActor->GetRemoteRole() == ENetRole::ROLE_AutonomousProxy)
{
                
}

maybe this?

verbal ice
#

Why even bother

#

I'd use the same leniency on the server, it just doesn't matter

#

IsLocallyControlled just check if the actor is controlled by local controller.
So what do you think that does when the local controller also has a net mode of ListenServer

#

:p

dark parcel
#

I'm getting hit too much at the gym lately.

verbal ice
#

haha

#

but yeah I wouldn't even bother

dark parcel
# verbal ice but yeah I wouldn't even bother

my test still early and I never get into the stage for a playable demonstration but you don't come across any issue when the character is at the edge of the interaction distance?

I don't want to have a scenario where the player is at the edge of the interaction radius, have the interaction data prompted as it was about to leave / enter the interaction radius and server go sike, you are off by a few units so you don't get the item.

verbal ice
#

No I meant I wouldn't bother removing the leniency for the listen server

#

Might as well keep it the same for everyone

#

@dark parcel

dark parcel
#
// Called on server.
    if (ACharacter* InteractingCharacter = Cast<ACharacter>(InteractingActor))
    {
        if (!bInteracted)
        {
            const UAGInteractionComponent* InteractionComponent = Cast<UAGInteractionComponent>(InteractingCharacter->GetComponentByClass(UAGInteractionComponent::StaticClass()));
            float _distanceToInteractingActor = (GetActorLocation() - InteractingActor->GetActorLocation()).Size();
            float _interactDistance = InteractionComponent->InteractionRadius;
            if (!InteractingCharacter->IsLocallyControlled())
            {
                // If interacting character is owned by client, allow tolerance for the interaction radius.
                _interactDistance += InteractionComponent->ClientInteractionRadiusTolerance;
            }

            // Check distance between the fragment and interacting character.
            if ((GetActorLocation() - InteractingActor->GetActorLocation()).Size() <= _interactDistance)
            {
                
            }
        }
    }

Thank you for the help btw, as this function is called on server, I can just check with IsLocallyControlled as you say.

nova trout
#

Is there a proper way to use ans in mp? I PIE with 1 instance in Client Net Mode, I expect ANS end to be called 2 times but its being called 11 times instead. I have no idea why and how to solve this.

dark parcel
#

I have no issue with ANS in multiplayer. Perhaps show what you have.

nova trout
dark parcel
#

Can we get the ANS logic?

nova trout
dark parcel
#

Also if you want to call this once per notify why are u using ANS instead of Anim Notify

#

Oh you want begin and end, nvm.

#

So the ANS pnly calls set state. I cant see any code that link it with your combat component.

#

If the reload weapon is the issue, show the ANS for that.

nova trout
#

reload weapon probably has the same behavior, I tested this with another ans end and it has the same issue.
When I put a debug point on notify begin or notify end they being called more than they need to be called.

dark parcel
#

Go to your montage and open the detail panel.

#

Screen shoot it

#

Theres montage tick type or something like that.

#

Or something that is called que.

#

Try swapping what ever you have right now, see if it helps.

#

I gtg sleep, if that dont work. Hopefully someone else spot the issue.

nova trout
dark parcel
#

Im sure its somewhere there, if not check the doc and figure out where to change it.

#

Also just because u running 1 instance of client, there is still the server.

nova trout
#

yeah ik

#

thats why I expect 2 calls

dark parcel
#

Yeah try changing the montage tick type. I know it calls more than required.

#

Iirc shouod be branching.

#

But swap what ever you have right now.

viscid obsidian
#

This is the best resource I've come across for extending the CharacterMovementComponent: https://youtu.be/urkLwpnAjO0?si=Cpfou99a1LZs50Zm

https://discord.gg/uQjhcJSsRG
In this video I am introducing a series I will be making which explores the character movement component and how you can extend it in depth.

0:00 Intro
1:00 What is the CMC?
2:00 Do you need a custom CMC?
5:35 What does the CMC provide?
7:10 Outro

▶ Play video
#

the framework unreal gives out of the box is great. in Unity it took me like 3 months to make the same framework from scratch

#

That said, I understand why Unity doesn't

dark parcel
#

Does unity even have multiplayer out of the box? Thought you have to download plugin or roll your own.

viscid obsidian
#

NetCode for gameobjects is probably what you're thinking of

nova trout
#

Thank you a lot ❤️

fallen fossil
#

so is

UGameplayStatics::GetPlayerController(GetWorld(), 0)

reliable to get host PC in ListenServer case?

#

not sure if I tagged, did not mean to do it

warm basin
#

What is best way to create loading screen with readyup/wait for players. It means if all players accept after map load, screen is removed and game starts

silent valley
dark parcel
quasi tide
#

Loading screen is just a widget you slap to the viewport.
It's not

#

Loading screens in Unreal are deceptively more complicated than what they friggin' need to be.

#

Sure - you can probably throw a widget on the screen and add it to the root and all that. But that has issues (that elude me right now, busy at work). The most common approach, that has been pretty successful, is hooking into UE's movie player. I know - doesn't make a whole lot of sense. But one of the big reasons is because when it gets created and destroyed and when it gets called. Also it is on a different thread if I recall.

dark parcel
#

I may be wrong but I think exi says, even lyra loading screen isnt truly async?

#

I probably just havent encounter future issues yet.

humble idol
#

For hard travels, I don't think you can use widgets, you have to run a "movie" or image on a separate designated thread.

dark parcel
humble idol
dark parcel
#

If its a raw ptr then yeah they get destroyed on world change.

humble idol
dark parcel
#

Yes

humble idol
#

Hmmm, that's interesting. I'll have to try it.

dark parcel
#

Survive both level. I spawned mine in subsytem and make it shared ptr.

#

Async load level then open level (hard travel)

#

Only fade it out after conditions are met in the new world.

grizzled garnet
#

When a client joins a multiplayer match, does the player's state get spawned before or after the level's actors have spawned?

fossil spoke
#

On Clients, its arbitrary because its created through replication.

grizzled garnet
#

ok tldr I need some way to defer spawning the player server side until functions client-side complete, like loading a sublevel. An actor is handling the sublevel loading manually, and not all levels require a sublevel and the actor.

I'm suspecting replication should handle the sublevel to the client, so I suspect currently with the sublevel not yet loaded then the server is spawning players before it's loaded, which I could handle via the gamemode searching if the actor exists and waiting until they've completed their task before spawning players

latent heart
#

Or spawn players in a temporary "spectator" pawn until things are ready for everyone.

grizzled garnet
#

I have an actor which does that (gametype, which not to be confused with gamemode, handles how gameplay occurs including spawn rules) but in my current code its not finding the actor which it needs to wait for

#

oh, the issue is because the gametype actor is in a different always loaded level, so the ugameplaystatics::GetAllActorsOfClass isn't finding the actor

nocturne quail
#

what should I choose for a stuff like shrinkable bluezone that covers the whole map and resize over time
Subsystem or Actor with few components ?

Responsibilities of the bluezone system:

1: Dealing damage to players
2: Bombing a random point in available playzone
3: Generating a random airdrop point
4: Spawn airdrop plane that move towards airdrop point, when it is reached drop an airdrop package

latent heart
#

If it needs a visual representation, an actor. If it's just a map thing, a subsystem is probably fine. You could do both. Have the subsystem spawn the actor.

#

Map = minimap / map overview.

nocturne quail
latent heart
#

Seems fine.

#

Though I'd probably have just thr server spawn it and have it replicate.

#

In case you want to transfer any data about it.

nocturne quail
latent heart
#

Yes, but that subsystem is going to spawn one on both server and clients. Unless the subsystem is only created on servers...

nocturne quail
#

it does all other stuff like

-- Global state management (current zone phase, timers, damage)
-- Damage calculation and application to all players
-- Zone shrinking logic and timing
-- Random point generation for bombing/airstrikes
-- Airdrop scheduling and coordination

fallen fossil
#

I need to validate one thing.

Does Multicast runs locally if actor does not own connection ? 🤔

latent heart
#

Correct

torpid storm
#

Anybody here who has got far enough to be hosting dedicated servers - are you opting for the -nothreading option?
I think traditionally it has been used to allow for more servers to share a single machine, but it implies that the server would need to run at a lower tick rate, plus I'm unsure how well things like HTTP background tasks work in that scenario.

fallen fossil
exotic wasp
#

many games are made to run on a single core or even be on a shared core. all depends on how the game was made and how difficult it is to run

#

even with threading on there are ways to force a program (like your server) to run only on assigned cores

torpid storm
#

I'm not really asking for advice, just to get an idea of what people are doing. By default UE spreads things over a small number of threads, and obviously on a server the render thread can be ditched which reduces the count further, but it's not 1. So I'm curious how people are approaching this.

silent valley
lament flax
copper raft
#

heyy guys, do i need to set input mapping context to work on multicast if i want to switch them when enter in a vehicle? i tried to ask google gemini but he said input mapping needs to run only on owning client, but when i'm trying to do how he said nothing works, with multicast works fine but when my car starts to go, my second player from passengers seat starts to changing his location when vehicle is moving

#

i tried to make this event, but i don't understand why it shows Enhanced Input Local Player Subsystem is not valid

tardy fossil
#

players possess the vehicle right? i'd switch the input context in the pawns SetupPlayerInputComponent function which gets automatically called on the client

copper raft
#

if i call this event after possess node, all works fine, but i don't understand why gemini said to use run on owning client because is better

copper raft
tardy fossil
#

no it'd be inside the vehicle class.. in c++ i'd use SetupPlayerInputComponent() but im not sure about blueprints.. maybe client restart? i just know you dont need to use an rpc

dark parcel
#

Especially a multicast to setup an input of a client. That make 0 sense.

copper raft
tardy fossil
#

yeah input context is completely local so it doesn't exist on the server... server only cares about the data sent from whatever those inputs are doing locally

copper raft
#

omg, i just changed the possess node after call Client_SetupVehicleInput node and now works fine😅 , and i spent 3 days on this thing😵‍💫

gritty mason
#

Hi guys! I have a strange problem. I develop a listen server multiplayer game in 5.4 and when the players arrived in the Lobby everything is fine ,they can control the character but when we go to the game map, the client can not control the character, the character controller is None, the client doesn't see the host character when the host moving around it. I use seamlesstravel and bdelayedstart. What could be the problem? I've tried almost everything. GameMode and GameState is the same, in the character Blueprint the auto possess player is Disabled.

nocturne quail
#

if you run a timeline on both server and client to set transform of a UStaticMeshComponent, why both desynced?
generally both should have the same transform for the mesh! but they don't 🤔

nocturne quail
#

the issue was server first set transform and than client is trying to set it also, in result client get stuck cause server is again applying new target scale...
solution was to set the UStaticMeshComponent replicated and let the server set its transforms

nova wasp
#

and yeah of course if they are both fighting over setting it the last one will apply... if you need a separate local only value make a separate thing

#

replication is not going to send at a perfect framerate either so you can safely assume it will jitter without local interp

nocturne quail
nova wasp
#

edited some spelling mistakes, very late for me so I gotta go

#

"server first set transform and than client is trying to set "

#

they are separate machines... what else does the server do to send the result to the client? what is actually "synced" at all besides the timeline starting?

nocturne quail
#

yeah it was started in beginplay

yeah this is what log says at least, first server started than client started

nova wasp
#

I would suggest using a visualization like vislogger

#

instead of logging transforms... that is very hard to read

#

at least for me personally

nocturne quail
nova wasp
#

that is the context you left out that makes what is happening here a lot easier to figure out

#

remember: we can only see what you type into the messsage

#

or is that what you changed after the original message? either way I can't assume the transform is replcated based on the first question but oh well

#

with this stuff It's really dependant on what the goal is imo... For example arguably you don't need to know about the true end position if the start position + start time is known and decently synchronized on both sides (accurate server time etc)

nocturne quail
nocturne quail
nova wasp
#

I don't know what "the client" is in relation to a random static mesh

nocturne quail
#

static mesh is visually represent as a wall for client

nova wasp
#

why is the wall moving? is it the zone edge?

nocturne quail
nova wasp
#

that would have helped to know earlier because I think that kind of thing is going to change very slowly over time and in a consistent way

#

you only really need to send when it starts and the client just needs to represent where it is going visually imo but if it changes speed/direction often it might be worth keeping realtime

nocturne quail
#

it moves to a random point and scaled down
red circle is server transforms, which don't match to the client transforms

nova wasp
#

all they need to do is share the same known min/max size and their time along it

nocturne quail
nova wasp
#

I don't recall saying this is an rpc (in the sense it's only sent once ever)

#

clients also can receive world time from the gamestate (via requesting it or replicating it down etc)

#

this is not needed though since there will only really be 1 of these and it being ~100ms off is not the end of the world

nocturne quail
nocturne quail
#

I am sure it can be further improved, but it works perfectly at least

nocturne quail
#

I think I have to move this new system to the gamemode sybsystem, and use instance AInstanceStaticMeshActor for visual effects

#

AInstanceStaticMeshActor->UInstancedStaticMeshComponent supports runtime scaling/repositioning?

nocturne quail
# nocturne quail

one more optimization, these don't needs to be replicated, they will be the same as targetposition and targetscale in the end

    FVector NewPosition;
    FVector NewScale;
dark edge
#

CenterPosition and StartTime is enough

nocturne quail
#
USTRUCT()
struct FBlueZoneSnapshot
{
    GENERATED_BODY()
    FVector Position;
    FVector Scale;
    int32 PhaseIndex;
    float Timestamp;
    float ShrinkProgress;
    FVector BomberTargetPosition;
    bool bIsRedZoneActive;
    bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess);
};
#

I would like to further optimize those replicated vectors, is it possible to apply bit packing on them? its a crazy idea but if it is possible and will work it will be a game changer!

#

these

    UPROPERTY(ReplicatedUsing = OnRep_TransformState)
    FVector TargetScale;

    UPROPERTY(ReplicatedUsing = OnRep_TransformState)
    FVector StartScale;
    
    UPROPERTY(ReplicatedUsing = OnRep_TransformState)
    FVector TargetPosition;

    UPROPERTY(ReplicatedUsing = OnRep_TransformState)
    FVector StartPosition;
dark edge
nocturne quail
#
USTRUCT()
struct FPackedVector
{
    GENERATED_BODY()
    
    uint32 PackedX : 24;  // 0-16,777,215 cm (167km) map support
    uint32 PackedY : 24;
    uint32 PackedZ : 16;  // Usually 0 for blue zone
    
    // Unpack to FVector
    FVector Unpack() const
    {
        return FVector(
            PackedX / 100.0f,  // Convert cm to meters
            PackedY / 100.0f,
            PackedZ / 100.0f
        );
    }

introducing custom vector for this specific task

#
    void Pack(const FVector& Vec)
    {
        PackedX = FMath::Clamp(FMath::RoundToInt(Vec.X * 100.0f), 0, 0xFFFFFF);
        PackedY = FMath::Clamp(FMath::RoundToInt(Vec.Y * 100.0f), 0, 0xFFFFFF);
        PackedZ = FMath::Clamp(FMath::RoundToInt(Vec.Z * 100.0f), -32768, 32767) & 0xFFFF;
    }
    
    bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
    {
        bOutSuccess = true;
        Ar << PackedX;
        Ar << PackedY;
        Ar << PackedZ;
        return true;
    }
#

and finally

USTRUCT()
struct FOptimizedZoneUpdate
{
    GENERATED_BODY()
    
    uint8 Flags;

    // Only send what changed
    UPROPERTY()
    FPackedVector Position;
    
    UPROPERTY()
    FPackedVector TargetPosition;
    
    UPROPERTY()
    FPackedScale Scale;
    
    UPROPERTY()
    FPackedScale TargetScale;
    
    // Phase index (0-7 fits in 3 bits, but using 4 for safety)
    uint8 PhaseIndex : 4;
    
    // Shrink progress (0-100%, 7 bits = 128 values)
    uint8 ShrinkProgress : 7;
    
    bool HasPositionUpdate() const { return (Flags & 0x01) != 0; }
    bool HasScaleUpdate() const { return (Flags & 0x02) != 0; }
    bool HasTargetUpdate() const { return (Flags & 0x04) != 0; }
    bool IsShrinking() const { return (Flags & 0x08) != 0; }
    bool IsRedZoneActive() const { return (Flags & 0x10) != 0; }
    
    void SetHasPositionUpdate(bool bValue) { Flags = bValue ? (Flags | 0x01) : (Flags & ~0x01); }
    void SetHasScaleUpdate(bool bValue) { Flags = bValue ? (Flags | 0x02) : (Flags & ~0x02); }
    void SetHasTargetUpdate(bool bValue) { Flags = bValue ? (Flags | 0x04) : (Flags & ~0x04); }
    void SetIsShrinking(bool bValue) { Flags = bValue ? (Flags | 0x08) : (Flags & ~0x08); }
    void SetIsRedZoneActive(bool bValue) { Flags = bValue ? (Flags | 0x10) : (Flags & ~0x10); }
    
    bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
    {
        bOutSuccess = true;
        
        // Always serialize flags
        Ar << Flags;
        Ar << PhaseIndex;
        Ar << ShrinkProgress;
        
        // Only serialize what changed based on flags
        if (HasPositionUpdate())
        {
            Ar << Position;
        }
        
        if (HasScaleUpdate())
        {
            Ar << Scale;
        }
        
        if (HasTargetUpdate())
        {
            Ar << TargetPosition;
            Ar << TargetScale;
        }
        
        return true;
    }
};
rare cloud
#

free code, let's go

nocturne quail
#
uint32 ABlueZone::PackPosition(const FVector& Pos) const
{
    // Pack position with 1cm precision
    // Map is 800000cm (8km), so we need 20 bits per axis (0-1,048,575)
    // We'll use 21 bits to be safe (0-2,097,151)

    int32 X = FMath::Clamp(FMath::RoundToInt(Pos.X * 100.0f), 0, 0x1FFFFF); // 21 bits
    int32 Y = FMath::Clamp(FMath::RoundToInt(Pos.Y * 100.0f), 0, 0x1FFFFF); // 21 bits
    int32 Z = FMath::Clamp(FMath::RoundToInt(Pos.Z * 100.0f), -1024, 1023) & 0x7FF; // 11 bits

    // Pack: 21 bits X | 21 bits Y | 11 bits Z = 53 bits total
    // We'll split across two 32-bit values
    uint32 Packed = (X & 0x1FFFFF) |
        ((Y & 0x1FFFFF) << 21) |
        ((Z & 0x7FF) << 42);

    return Packed;
}
error C4293: '<<': shift count negative or too big, undefined behavior

🤔

rare cloud
#

oh and also << 42 can't be possible for a 32-bit integer

#

even the comment talk about two 32-bit "We'll split across two 32-bit values"

nocturne quail
#
uint32 ABlueZone::PackPositionX(const FVector& Pos) const{
    // Pack X and part of Y into first 32 bits
    // X: 21 bits (0-2,097,151)
    // Y_low: 11 bits (lower 11 bits of Y)
    
    int32 X = FMath::Clamp(FMath::RoundToInt(Pos.X * 100.0f), 0, 0x1FFFFF);
    int32 Y = FMath::Clamp(FMath::RoundToInt(Pos.Y * 100.0f), 0, 0x1FFFFF);
    uint32 Packed = (X & 0x1FFFFF) | ((Y & 0x7FF) << 21);
    return Packed;
}

uint32 ABlueZone::PackPositionY(const FVector& Pos) const{
    // Pack remaining Y and Z into second 32 bits
    // Y_high: 10 bits (upper 10 bits of Y)
    // Z: 11 bits (signed -1024 to 1023)
    // Remaining 11 bits unused
    
    int32 Y = FMath::Clamp(FMath::RoundToInt(Pos.Y * 100.0f), 0, 0x1FFFFF);
    int32 Z = FMath::Clamp(FMath::RoundToInt(Pos.Z * 100.0f), -1024, 1023);
    uint32 ZPacked = (Z < 0) ? ((~(-Z) + 1) & 0x7FF) : (Z & 0x7FF);
    
    uint32 Packed = ((Y >> 11) & 0x3FF) | (ZPacked << 10);
    return Packed;
}
nova wasp
#

this kind of packing into 1 32 bit doesn't make as much sense to be as two 16 bits

#

depending on the ranges

#

most integer types in unreal are serialized around the idea of them being a lower range of values

#

from what I can tell from the source

#

but at this scale it won't matter much to shave off 4 bits

nocturne quail
nova wasp
#

that's good because it will all arrive at once

nocturne quail
vocal current
#

If you're using NetSerialize then there are already some custom ways to serialize vectors, if I remember right

#

As opposed to the default Ar << MyVector

meager spade
#

you can searchfor NetSerialize

#

we normally do like FVector_NetQuantize& ReplicatedLocation = ReplicatedLocations[i]; ReplicatedLocation.NetSerialize(Ar, Map, bOutSuccess); if we dont need precision

#

theres FVector_NetQuantize, FVector_NetQuantize10 and FVector_NetQuantize100

#
 *
 *    2 decimal place of precision.
 *    Up to 30 bits per component.
 *    Valid range: 2^30 / 100 = +/- 10,737,418.24```
#

for example

nocturne quail
#

I will do it next time when I will need it for sure

meager spade
#

these can reduce rep sizes

#

we have done in the past, where we exposed normal FVector for gameplay

nocturne quail
#
// server sets it and calls onrep.
FZoneSyncData NewSyncData;
NewSyncData.PhaseIndex = NextPhaseIndex;
SyncData = NewSyncData;
OnRep_SyncData();
    
void ABlueZone::OnRep_SyncData()
{
    UE_LOG(LogTemp, Warning, TEXT("OnRep_SyncData called - Phase: %d, HasAuthority: %s"),
        SyncData.PhaseIndex, HasAuthority() ? TEXT("Yes") : TEXT("No"));

}

it only logs called by server, no idea why

meager spade
#

but made it not replicated, then handle the rep via a quantized and set back to the normal property

#

this way to the end user, its just an FVector

#

you really should avoid server calling OnRep_ like that

#

you should make intermediate functions

#

that OnRep and server called, like a shared path

#

i really hate people doing OnRep_Blah on the server side path

#

its ambiguous

nocturne quail
meager spade
#

yes

#

cause the issue is, OnRep == Client callback when property changes

#

if server ends up calling it, its really hard to debug

#

it becomes a nightmare

#

i can look at my callstack and be like "Thats server side"

#

but if i see OnRep_ to me its client side

#

but if server is calling OnRep then thats not client side..

nocturne quail
#

Adding an intermediate now, if it fixed, it will make my day 😄

meager spade
#

whats the issue anyway

#

i didnt read

#

also this is wrong

nocturne quail
#

the onrep only calls by server

meager spade
#
    // Pack X and part of Y into first 32 bits
    // X: 21 bits (0-2,097,151)
    // Y_low: 11 bits (lower 11 bits of Y)
    
    int32 X = FMath::Clamp(FMath::RoundToInt(Pos.X * 100.0f), 0, 0x1FFFFF);
    int32 Y = FMath::Clamp(FMath::RoundToInt(Pos.Y * 100.0f), 0, 0x1FFFFF);
    uint32 Packed = (X & 0x1FFFFF) | ((Y & 0x7FF) << 21);
    return Packed;
}

uint32 ABlueZone::PackPositionY(const FVector& Pos) const{
    // Pack remaining Y and Z into second 32 bits
    // Y_high: 10 bits (upper 10 bits of Y)
    // Z: 11 bits (signed -1024 to 1023)
    // Remaining 11 bits unused
    
    int32 Y = FMath::Clamp(FMath::RoundToInt(Pos.Y * 100.0f), 0, 0x1FFFFF);
    int32 Z = FMath::Clamp(FMath::RoundToInt(Pos.Z * 100.0f), -1024, 1023);
    uint32 ZPacked = (Z < 0) ? ((~(-Z) + 1) & 0x7FF) : (Z & 0x7FF);
    
    uint32 Packed = ((Y >> 11) & 0x3FF) | (ZPacked << 10);
    return Packed;
}```
#

you dont want to be backing your vectors like this

nocturne quail
#

this only logs has auth yes

void ABlueZone::OnRep_SyncData()
{
    UE_LOG(LogTemp, Warning, TEXT("OnRep_SyncData called - Phase: %d, HasAuthority: %s"),
        SyncData.PhaseIndex, HasAuthority() ? TEXT("Yes") : TEXT("No"));

}
meager spade
#

but why this weird packing

nocturne quail
#

UPROPERTY(ReplicatedUsing = OnRep_SyncData)
FZoneSyncData SyncData;

nocturne quail
meager spade
#

what you using instead?

nocturne quail
meager spade
#

doing what locally

#

show the code

#

cause im lost

nocturne quail
# meager spade cause im lost

I was doing it for replication purpose to make the packets smaller, but now clients are simulating the timeline locally

nocturne quail
#

I was doing all that custom serialization to minimize this load

void ABlueZone::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);

// OPTIMIZATION: Only replicate to simulated proxies (clients)
DOREPLIFETIME_CONDITION(ABlueZone, TargetScale, COND_SimulatedOnly);
DOREPLIFETIME_CONDITION(ABlueZone, StartScale, COND_SimulatedOnly);
DOREPLIFETIME_CONDITION(ABlueZone, TargetPosition, COND_SimulatedOnly);
DOREPLIFETIME_CONDITION(ABlueZone, StartPosition, COND_SimulatedOnly);
DOREPLIFETIME_CONDITION(ABlueZone, NewScale, COND_SimulatedOnly);
DOREPLIFETIME_CONDITION(ABlueZone, NewPosition, COND_SimulatedOnly);
DOREPLIFETIME_CONDITION(ABlueZone, bTransformRep, COND_SimulatedOnly);
DOREPLIFETIME_CONDITION(ABlueZone, BomberTargetPosition, COND_SimulatedOnly);
DOREPLIFETIME_CONDITION(ABlueZone, ServerSnapshot, COND_InitialOnly); // Only for late join

}

#

now using this synced with the game time

void ABlueZone::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
    DOREPLIFETIME(ABlueZone, SyncData);
}
USTRUCT()
struct FZoneSyncData
{
    GENERATED_BODY()

    // Phase timing
    UPROPERTY()
    int32 PhaseIndex = -1;
    
    UPROPERTY()
    float ServerStartTime = -1.0f;
    
    UPROPERTY()
    float Duration = 0.0f;
    
    // Geometry
    UPROPERTY()
    FVector StartPosition = FVector::ZeroVector;
    
    UPROPERTY()
    FVector TargetPosition = FVector::ZeroVector;
    
    UPROPERTY()
    float StartScale = 0.0f;
    
    UPROPERTY()
    float TargetScale = 0.0f;
};
halcyon ore
#

Hey all.
I have a weapon system.
Its a weapon actor attached to the player.

I'm having an issue, where the server tries to replicate the weapon actor, before the player/ owner.
(even with the use owner relevancy or whatever)
This appears to be, because the server thinks the client knows about the owner, but just doesn't. (since at the end of the day, its a distance check)

Is there anyway to change this, so the server/ client both know there owner is valid?
Or, do I just need a begin play loop, waiting for a valid owner?

#

(Also, specifically just the clients, server always has a valid owner, not like the owner var just isn't set.)

split drum
#

Hello, I'm new to Unreal and Multiplayer and have been having an issue with my RPCs in my Listen Server game.
I have a function that spawns a debug sphere in front of the player.

UFUNCTION(Server, Reliable, BlueprintCallable)
void Server_SpawnDebugBall();

UFUNCTION(NetMulticast, Reliable)
void NetMulticast_SpawnDebugBall();

UFUNCTION(BlueprintCallable)
void SpawnDebugBall();
void AFourManScrambleCharacter::NetMulticast_SpawnDebugBall_Implementation()
{
    SpawnDebugBall();
}

void AFourManScrambleCharacter::Server_SpawnDebugBall_Implementation()
{
    NetMulticast_SpawnDebugBall_Implementation();
}

void AFourManScrambleCharacter::SpawnDebugBall()
{
    FActorSpawnParameters SpawnParams;
    SpawnParams.Owner = this;
    FVector SpawnLocation = ItemSpawnPoint->GetComponentLocation();
    FRotator SpawnRotation = ItemSpawnPoint->GetComponentRotation();

    AActor* SpawnItem = GetWorld()->SpawnActor<AActor>(SummonItem, SpawnLocation, SpawnRotation, SpawnParams);
}

I have a key-input that runs Server RPC in my C++ code. While I'm playing as the server, it will spawn the ball for both the server and the client. But when I press the button as the client it only spawns on the client

#

As well I tried hooking it up through blueprints instead. Of the three methods on the right, the top one is the former I had just mentioned. The middle one, (which you can see implemented in the bottom left), will spawn two balls in front of the calling player, and the bottom one, which just directly calls the Server RPC function, will work correctly, spawning a ball in front of the appropriate player on both the client and server.
Can anyone help me understand how these variations are happening?

crisp shard
#

when it comes to equipment / itmes that you can equip, would it make sense to "pool" these actors? seems like it would make sense in the way i understand the benefits of pooling. i suppose same would go for item drops in general, like if you were to "drop" an item, this is current an actor, but not sure if there's a way to make it not a full blown actor , as in most cases, it's just pointing to a single int32 value which is just an index to the actual item to pickup. if i made them non-actors somehow (and stil could interact the same way), then i'd think pooling would make sense

#

i've also considered the issues of equipables being pooled as they would be replicated actors, and having those just sitting not used also seems like it could be unnecessary, but yea curious on what somet akes on pooling things like item drops or equipment like weapons that would be effectively spawned and despawned potentially frequently (equip / dequip, etc, or dropp item -> pick up item)

halcyon ore
#

To me personally.
Pooling doesn't make sense for stuff like that.
It also very much depends on the game.
You say, your items are an index to the actual item.
But, it may not be like that for some games.

and, then like you say for replication.
That just an extra actor that exists for no reason.

Pooling I feel like only makes sense, where an inventory is sorta locked.
Think looter shooters.
You don't have like 30 guns.
You have like 5 static ones.
Pistol, machine gun, melee, grenade, idk. 😛

#

You could also conceal the pooling/ loading in the unequip.
Sure, that still the "issue" of entire actor creation and shit.
But, thats 1 gun, compared to like 100 bullets, from a machine gun, or something.

crisp shard
#

that makes sense, will most likelly avoid the pooling for equipables. for item drops tho, im thinking of instead of spawning the item, have a single actor item drop manager or something w an item struct that can replicate the Item id and it's location... which in my head i think would work, but not sure about if multiple were spawned at once or something how it would handle that but maybe i can do soemthing like that for items. but could prob just keep them actors too (if single items). loot chest/storage boxes would remain actors as they aren't something quickly destroyed

halcyon ore
#

The way I kinda see it.
In more dynamic games, a weapon/ tool, could be 50 different things, or just do nothing at all.
While most shooter games (arma, looter shooter), you kinda only can shoot a million bullets.
But, a survival game, could have shovel, pickaxe, sword, full auto gun, primitive crossbow, bow and arrow, nothing.
Theres so many possibilities, you'd be pooling like 50 extra weapons/ actors.

I do agree, that some sort of item drop manager could work better, especially with such basic item drops like you said.
Could also instanced static mesh it, and lookup the drop, based on the instanced index.

crisp shard
# halcyon ore The way I kinda see it. In more dynamic games, a weapon/ tool, could be 50 diffe...

yea 100p when you describe it like that, it would be a nightmare pooling all the different possiblities lmao. i also like the ISM approach or even a simple niagara to represent it via sprite, could put that on the itme manager, then just do a "distance check" to the location to pickup the item, as i most likely will not be using collision on these, that would prob do more harm than good. and distance check could just pick up items by closest / most relevant

halcyon ore
#

Yeah, it very much depends.
I could never use just a basic int32 var, for my items. lol

crisp shard
halcyon ore
#

Oh, I see. 😛
I thought your items were legit just a int32, for an index on array, or some DataTable. lmao

#

Why have a int point to the item, and not just the item in the dropped item.
Out of curiosity?
Is that just how you designed your game, or did you have some performance, or like networking in mind?

crisp shard
# halcyon ore Why have a int point to the item, and not just the item in the dropped item. Out...

tbh i just thought it would be easier to replicate and send around a int32 and then do the heavier strcut work later when needed rather than it's full item strcut, but it may very well be unnecessary but all my items have an ID which points to the struct in a datatable. in fact, i most likely convert it in the pick up logic of the actor version rn, immediatley , so it is probably unecessary lmao, but again, that variable is just replicated so i thought it would be a bit more efficent, and i wouldn't need all the extra info other than it's visual representation

#

im def always thinkinga bout performance, but given that im using zero new tech (no nanite, lumen) on forward rendering, and have essentially zero shadows/lighting, i prob have plenty of room lol

#

and all my charcters/items are sprites, so dont use skeletal meshes at all

#

biggest bottleneck is probably just the size of the world

#

and im not currently using world partition (at least i don't htink i am)

halcyon ore
#

I tried like 5 different methods for my complex item replication.
None of them worked.
So, it was either low level, custom replication channel.
or, RPC spam.
I chose RPC spam. 😛

crisp shard
#

i have some functions that i set to reliable after realizing GAS abilites are reliable by defualt (at least as far as i understand them)

#

i dont use GAS tho ( i did for a month, never again... unless...)

halcyon ore
#

RPC spam.
RPC for item add, item remove, item move, item drop, item changes.
Recently did custom serialize shit, so I can pass var changes around as bytes, rather then 1 RPC per possible var.

#

Its the only way I could really find to do it.
Got some smart people here, but all the methods they suggested would not have worked.
(This is only like 50% of my RPC's, for my item system.)

crisp shard
#

all reliable lmao i love it

#

i never used reliable casue i thouht it was "bad" then like i said , once i realized how GAS worked, i was kinda pissed casue i could've had so much easier logic by setting some things to reliable. of course, they are "gameplay critical" things (that's the term i've heard)

halcyon ore
#

Yeah.
If you need it to happen.
Such as item moves, then reliable makes sense.

For instance, player movement isn't reliable.
Cuz, while it could be seen as "critical", it also interpolates, so whatever var it recieves, will account for the lack of other RPC's it sends.

#

RPC's also help, for the 4 different ways my items can replicate.

halcyon ore
split drum
#

Oh! So I just call the "NetMulticast_SpawnDebugBall"?

halcyon ore
#

yeah

#

Implemetation is like the I recieved the replication sorta stuff.

split drum
#

Ah gotcha gotcha!

#

Thank you 🙏 It worked

fiery wadi
#

Hi, can someone explain why the 1st controller Controller_0 doesnt spawn a character but the 2 conneccted clients do please? Even with the breakpoint Controller_0 never even triggers the Set Actor Location, I did consider destroying the Pawn and then trying to spawn a new one and assigning the Owner of the new pawn to the ConnectedController but feels a bit odd to destroy a character just to create another.

fiery wadi
#

Nvm I forgot I overrode CHoosePlayerStart which was returning nothing....

halcyon ore
#

Reposting this, cuz now its hidden behind all these other messages. 😛

I have a weapon system.
Its a weapon actor attached to the player.

I'm having an issue, where the server tries to replicate the weapon actor, before the player/ owner.
(even with the use owner relevancy or whatever)
This appears to be, because the server thinks the client knows about the owner, but just doesn't. (since at the end of the day, its a distance check)

Is there anyway to change this, so the server/ client both know there owner is valid?
Or, do I just need a begin play loop, waiting for a valid owner?

(Also, specifically just the clients, server always has a valid owner, not like the owner var just isn't set.)
Thankfully its not exactly a critical issue right now, so i'm not in a rush to care about/ fix it. 😛

viscid obsidian
#

for extending the CharacterMovementComponent: when networking one off events like a dash, should we extend the SavedMove struct to auto replicate, resulting in larger bandwidth per frame, or should we just send a one time ServerRPC to replicate?

nova wasp
viscid obsidian
#

right that's what I was thinking, for some reason the tutorial i was following used an rpc. maybe he just wanted to show how you could do it for some reason you needed to

nova wasp
#

using an rpc will basically mean doing it outside of the cmc by turning off corrections during the ability etc (if it ends up causing corrections)

#

but you can try that if it seems easier

viscid obsidian
nova wasp
nova wasp
nova wasp
#

but honestly you might be able to spam extra fvectors in there and never really care if bandwidth is never under pressure so profile it I guess

halcyon ore
nova wasp
nocturne quail
#

what happens if an actor in world call ForceNetUpdate(); when it is loaded for late join client?

nova wasp
#

I assume it would replicate stuff regardless of net update rate/prio? Are you not seeing it arrive on the client?

halcyon ore
nova wasp
#

I'm honestly not sure if forcing an update matters for late joiners

nocturne quail
#

seems like it needs to serialized forcefully

nocturne quail
#

I was doing it cause to test it to see if the actor will sync the late joiner in the current state of the actor

nova wasp
halcyon ore
#

Not sure I follow?
It’s just easier to put it all in an actor for my brain.
Rather then some comp on the player, and some fake actor weapon.

nova wasp
#

oh absolutely lol, I'm definitely going to agree it is easier to understand on a human level to have it just be a thing you can click on in the editor that says it has x and a mesh

#

I am not sure actors can "require" other actors to show up first in normal replication

#

I'm kind of surprised them being attached doesn't influence it or something (assuming they are)

#

So if anyone knows more than me free free to chime in but I don't really use this approach so I am unfamliar

halcyon ore
#

The issue I guess is.
The server doesn’t check if the client knows of the actor.
So, at the end of the day, even if there attached, it still does a distance check, for replication.

#

Cuz, it influences it by using the owners relevant function.
But, of course if the client doesn’t have a valid owner, it doesn’t care for that.

nova wasp
#

so the relevancy is getting stuck?

#

I wonder if you can make it use the attach parent for relevancy

halcyon ore
#

The issue is.
It does use the attach parent.
But then just becomes a distance check.
And is purely a server only thing, so the server doesn’t know if the client knows of said actor, just that it’s within the rep distance.

#

Hence the issue.
The weapon replication is received/ calculated first, before the player, cuz the server doesn’t actually know/ check that the client knows of the player

nova wasp
#

So what happens? does the weapon appear at world origin for a split second?

#

Could you not just have it hide itself until the parent shows up if you know it has a parent? Not sure

#

ofc if you intend to ALSO have weapons that don't actually have any parent on the server (dropped on the floor) you would need to consider that state too I guess

halcyon ore
#

I haven’t checked that honestly.
But, not sure.

The issue isn’t showing, it’s that’s the owner ref is invalid, so begin play fails.

Hence my potential thought of looping for valid.

nova wasp
#

you can keep the logic in the weapon

#

just have the character appearing find any weapons it can see attached to itself and call the weapons init thing

halcyon ore
#

Right, yeah.
That very well may be what I need to do.
I was just hoping to keep it a bit fully self contained.
I just like that.
Even for the super basic “player finds weapons”

Unless someone else sees this.
I’ll just end up doing that. lol

nova wasp
#

it is not self contained unfortunately

#

if you want you could make a simple interface or something to hide the weapon from the character

#

fwiw there might be a nicer setup here, I'm mostly just guessing on this working and you might find inside of the AActor beginplay it might not see attachments yet etc

a delay one frame in a loop is very sad but sometimes can avoid headaches with stuff you can't listen for

halcyon ore
#

Oh, no an interface, or reference isn’t the issue.
Just more personal design method of self contained stuff.
I don’t like having required secondary code, or multiple copies of code.

So far UE replication has been fucking my personal design method. lol

nova wasp
#

Maybe the weapon actor can override it changing what it is attached to?

#

to react to the owning character appearing etc

halcyon ore
#

Oh, that’s valid.
I didn’t think of that.

nova wasp
#

not to skip calling super:: here, but to just know when it happens

halcyon ore
#

I’ll need to check for a func when I get home.

#

Yeah.
Thankfully I don’t plan on doing other shit with the weapons.
It’ll always be equipped.

nocturne quail
#

that trick actually works to make late clients sync with the current replicated state by using the server world time

 FBlueZoneSerializedSyncData NewSyncData;
 NewSyncData.CurrentPosition = LevelCenterPoint;
 NewSyncData.CurrentScale = FVector(Scale, Scale, Scale);
 NewSyncData.TargetPosition = LevelCenterPoint;
 NewSyncData.TargetScale = FVector(Scale, Scale, Scale);
 NewSyncData.PhaseIndex = -1;
 NewSyncData.ServerStartTime = DoTimeTravelInServerWorld(); //replicated
 NewSyncData.Duration = 0.0f;
 NewSyncData.ServerShrinkProgress = 0.0f;

 ZoneSyncData = NewSyncData;
 void OnRep_ZoneSyncData();
#

now if the bluezone in any phase, late clients will join the current phase, duration, scale, location synced

#

and the best thing its now one time notify, and client simulate their state locally based on the synced data they recieve

nova wasp
#

The hard part is making sure the time is closely synched but for something that moves slowly it being slightly off might be perfectly fine. The cool thing here is the amount of data is just the start and stop

nocturne quail
#

if it will be, I will slow them down also 😄

nocturne quail
#
LogTemp: Warning: [CLIENT] Received zone sync data - Phase: -1
LogTemp: Warning: [CLIENT] Setup - Progress: 0.00, Duration: 0.0
LogTemp: Warning: [CLIENT] In shrink delay - starts in 0.0s
LogTemp: Warning: [CLIENT] Starting shrink
LogTemp: Warning: [CLIENT] Starting timeline - Progress: 0.00, Remaining: 0.0s
LogTemp: Warning: [SERVER] === Phase 0 Announced ===
LogTemp: Warning: [SERVER] Starts at: 11.1 (current: 6.1, delay: 5.0)
LogTemp: Warning: [CLIENT] Received zone sync data - Phase: 0
LogTemp: Warning: [CLIENT] Setup - Progress: 0.00, Duration: 120.0
LogTemp: Warning: [CLIENT] In shrink delay - starts in 5.0s
LogTemp: Warning: [SERVER] Timeline started
LogTemp: Warning: [CLIENT] Starting shrink
LogTemp: Warning: [CLIENT] Starting timeline - Progress: 0.00, Remaining: 120.0s

late client 1
LogTemp: Warning: [SERVER] Timeline Progress 0.15, Duration: 120.0
LogTemp: Warning: [CLIENT] Received zone data on join
LogTemp: Warning: [CLIENT] Setup - Progress: 0.16, Duration: 120.0
LogTemp: Warning: [SERVER] Normalized Artifect - Progress: 0.17, Duration: 120.0
LogTemp: Warning: [CLIENT] Starting timeline - Progress: 0.17, Remaining: 101.5s
#

one more thing I think I need is to make server just lerp from start to target without timeline

viscid obsidian
#

what do i do if i want to see logs from both the client and server? right now im only seeing logs from the client and I'm running with 2 players in viewport while playing as Listen Server.

nova wasp
viscid obsidian
nocturne quail
viscid obsidian
nocturne quail
#

when you run as client it automatically creates a dedi server for you and client connects to it

#

than you can click late client to add more clients

dark parcel
nova wasp
#

that is local role only

#

just because you have authority does not mean it is the server (locally spawned things would have authority etc)

#

it is still useful to see local role but it would make more sense to consider that together with the local netmode from GetDebugStringForWorld

nocturne quail
nova wasp
#

the one downside is in some cases it might be too early for it to see the debug string but that is quite rare

nocturne quail
#

that's a good note

viscid obsidian
#

is world time used as a synced clock between client and server

#

even though they are not at the same time at the same point

nova wasp
#

basically it is not quite close enough for some things so the alternative is to replace it or have a simple rpc back and forth to constantly update it with simple math (running ping average that deltas the local one)

#

it depends on what the timer is used for though because incoming replication data is always in the past (well, from it)

halcyon ore
nova wasp
#

neat, I hope that works

halcyon ore
#

It does.
Already tested

boreal flicker
#

I’m trying to make a sprint mechanic in my game. Sprinting costs stamina, and the way I have it right now is that it consumes stamina in the sprint phys function, and if there’s not enough stamina it exits sprint to another movement mode. However, I noticed that clients consume stamina about twice as fast as the server, and I think it's because of replaying moves. I wanna just not consume stamina if we’re replaying moves, but I don't know how to know if we’re replaying moves from the phys function. Should I not be changing variables in phys functions at all? Should I be doing that in a different function? If so which one?

dark parcel
silent valley
nova wasp
#

it won't be close enough in some case unfortunately but it will work for simple stuff that doesn't need accuracy

#

definitely easier to try that first and then change it if you find jittering stuff etc

viscid obsidian
#

sorry to bother yall again, I'm misunderstanding something about the CMC. I thought that on autonomous proxies, we run movement logic then build a saved move, which we then compress and serialize into NetworkMoveData, which gets sent to the server and rerun on the same movement pipeline. My confusion stems from how the server takes the NetworkMoveData and reruns the code. Is it true that when the server recieves the NetworkMoveData, it doesn't rebuild a saved move and use PrepMoveFor() to update the CMC state, but instead relies on manual setting of CMC state from NetworkMoveData?

coarse patrol
#

were u able to fix this?

copper raft
#

how to fix bugs with other player location when a car is moving? movement is set to None, collisions are disabled, attach actor to component are all snap to target, weld simulated bodies tried to enable tried to disable, nothing changed, and why works fine on driver screen? passengers screen only have this problem

copper raft
#

all this is inside run on server event

nocturne quail
#

are you attaching to socket?

copper raft
#

this inside OnRep_IsInVehicle, inside player character blueprint

copper raft
nocturne quail
#

try ignoring the vehicle collision channel when attach to vehicle

#

and disable physics simulation

copper raft
nocturne quail
copper raft
nocturne quail
#

first try on server if not work do it on multicast

nocturne quail
copper raft
#

im not using multicast at all

nocturne quail