#multiplayer

1 messages · Page 697 of 1

pallid mesa
#

totally new to eos, and I see there's a channel for it. Is EOS just an intermediary between the end-platform and the game layer?

#

steam <-> eos <-> game, psn <-> eos <-> game, egs <-> eos <-> game, and such?

bitter oriole
#

EOS is a matchmaking/friends service

#

it doesn't actively do multiplayer

#

Unreal does that

#

The matchmaking part just enables NAT punch AFAIK

#

So no it's not an intermediary

pallid mesa
#

and it uses the underlying platform for this matchmaking and friends? right?

sinful tree
#

Dedicated Server or Player Starts a session -> Reported to EOS
Player Starts Game -> Looks for Servers reporting on EOS -> Gets connection data from EOS -> Connects to server

#

(from what I understand anyway)

bitter oriole
#

Not tied to any platform

pallid mesa
#

so it doesn't interop with my steam friend list, per say

bitter oriole
#

There's some interop stuff AFAIK as in you can link accounts

pallid mesa
#

ah I see, interesting. Thank you Stranger, that's all I needed to know

#

I will probably deep dive soon for learning purposes

late vale
#

3rd option aka: Hard af
But it will allow me to have everything I need right?

#

Cross-Platform, No Ports, Over 50 Player's, Etc?

bitter oriole
late vale
#

You can walk around

#

So nevermind then

bitter oriole
#

Then no

pallid mesa
bitter oriole
pallid mesa
#

ah okay thank you for the help anyways, yes I only got experience for steam development

#

but I think it's a cool skill-set to have, god knows what I'll end up doing

late vale
#

Wdym by the 4th option

#

Actually I'll just do a combo of EOS with Dedicated and Listen

#

Console and Mobile builds use Listen while PC use dedicated

bitter oriole
#

Console listen fine with low player counts

late vale
bitter oriole
#

Not the one betting my game on it, idc much, just being honest

late vale
#

Also we are planning on buying a dedicated server.

#

Gonna host like multiple different servers

bitter oriole
#

Dev-hosted dedicated servers was my option 1, yeah

late vale
#

Yeah it's like a 8 Core, 64gb RAM with what they say is 100tb Monthly Bandwidth

#

So hopefully I can host a huge amount of dedicated servers

bitter oriole
#

You can go with something like 2 cores + 2GB RAM per instance

late vale
#

If each server was 50 Players how many servers could that Host

bitter oriole
#

Four instances max, probably, so about 200, if everything's well optimized

#

Not an expert, 200 players is way more than I've ever seen

late vale
#

Does the Dedicated Server Build also contain a client?

bitter oriole
#

No, completely independent package

late vale
#

Damn and it is the same size

late vale
gaunt cliff
#

I'm trying to create a "portrait system" where in there is a render target that takes a snapshot of the character and replicates it to other clients (to be seen by the same team)

#

however the material texture doesn't get replicated properly and it shows the own user portrait instead of his team members'

#

any clues on how to replicate a render target ?

bitter oriole
#

Depends on your game anyway

late vale
#

If anything maybe just instability

peak sentinel
#

Low framerate on server affects network too

#

I'm not sure if it's same as what Stranger means but you gotta keep framerate high on server

meager wing
#

Curious about "Session Name" in the context of the SessionInterface. I'm struggling to understand the use of the "SessionName" value VS the server's actual name. Everything I've read separates them, so I'm lead to believe that "SessionName" definitely isn't supposed to represent the name of the server, but what is it intended to be then?

I've followed a few guides to make my own C++ implementation and did some reading. But everyone seems to just set "SessionName" to some default value and forget about it. Except that's causing some issues for me. Most notably, the guide I followed didn't cover shutting down or disconnecting from sessions, and as I'm trying to do that, things like DestroySession() need the SessionName. Is it really okay for the Session Name to never be unique?

I think I just have a simple misunderstanding of something basic here.

chrome bay
#

SessionName is just an internal ID to identify the session, it's not related to the display name of the Server that players see

#

It's basically always NAME_GameSession

meager wing
chrome bay
#

yep

meager wing
#

Thanks! Curious if their is ever a use case where you'd want to change it? Their are several functions that take it as parameters

bitter oriole
meager wing
#

feels quirky, but what do i know lol

#

One last question I have actually, is their a built in delegate or function that fires when the player is disconnected or the session shuts down? I tried "OnSessionFailureDelegates" in SessionInterface and "OnConnectionStatusChangedDelegates" in Subsystem. Neither seemed to fire when I triggered crashes on the host

#

could have been doing something wrong though and will revisit them if i was on the right track

golden warren
#

Hi, I have a question
Where should I use "Predict bullet path" to replicate Projectile bullet spawn transform?
"On Fire Macro" includes Spawn Actor nodes which shoots bullet

spark owl
#

does anyone have experience with time descrepency calculations to stop client side speedhacking?

#

I enabled it, changed some settings but there are still players who can use a speedhack with cheatengine

summer tide
#

So I'm setting MovementMode in OnRep via server & multicast . But the player hits water movement mode changes to swimming

errant hamlet
#

Any resources out there for Control Rig replication? I can't find anything for 4.27 / 5.0

glad jasper
#

Basically they just use open level, so I guess I could pass Paramus in the connect string but I’m wondering if there’s a way to use the game instance or another class

winged badger
#

generally you'd either setup a lobby map

#

or you'd RPC the setup data from something like PlayerState::PostNetInit to server

#

and hold off on HandleStartingNewPlayer for that player until data is received

glad jasper
#

@winged badger so if the client entry map was some sort of lobby once i connect with openlevel isn't playerstate destroyed/recreated upon joining the server's map?

winged badger
#

it is

#

if it travels to game map with the server, server will have all the setup data

glad jasper
#

i'm sure i'm going about this in a weird way, but i wanted the server to just run some map infinitely

#

and have clients connect with parameters it sees

winged badger
#

if it joins later, via hard travel, it would need to stash the setup data in a game instance subsystems or some such

#

in which case

#

then client PS calls PostNetInit (meaning it replicated to client fully), it sends a server RPC to which server responds by copying client data to server instance of PS

#

and calls HandleStartingNewPlayer for that player

#

(obviously, you need to prevent server from starting new player before it receives the client data in this case)

#

aside from that you need a way to instantiate player pawn from struct data that is your FCharacterSetup stored in PS

#

you definitely do not want to spawn a default pawn, then have it adjusted after client sends the setup data

glad jasper
#

@winged badger so i make an rpc call before openlevel? and then setup a some sore of callback/wait in handlestartingnewplayer? is there an example somewhere of this, surely i can't be the first person to have tried this?

winged badger
#

open level is not part of your flow here

#

server opens level with no clients around

#

and keeps it open, no?

glad jasper
#

yeah

winged badger
#

so after client logs in

#

server instantiates a PC

#

in PCs PostInitializeComponents, PC instantiates the PlayerState

#

both of those are replicated

#

when they are spawned on client, as dynamic replicated actors

#

they will spawn, call all OnReps, then PostNetInit, then BeginPlay

#

during PostNetInit you know your PC/PlayerState are ready to use on client, its also the first place they are

#

PlayerState is better suited to hold player setup data then the PC

#

so you use its PostNetInit to send the data

#

server RPC implementation just calls HandleStartingNewPlayer on the GameMode, after it copies the setup to server's instance of the PS

#

which spawns the PlayerPawn with correct data

#

this setup also allows you to delay BeginPlay being called on clients world until the PlayerPawn itself replicates and is ready for use

glad jasper
#

so i don't have any real form of login currently

#

the client enters the game in entry map

#

which just uses openlevel

#

as per the dedicated server doc

#

then it connects to the dedicated server

winged badger
#

you can get the data encoded in login url

#

but i generally don't like that getting too long

#

and our game has a lot more stuff to do then instantiate the player pawn before client can start playing

#

like spawn the entire level procedurally

#

so there is plenty of time to bounce the RPCs around

glad jasper
#

what login system are you using?

winged badger
#

we are using listen servers

glad jasper
#

honestly i was thinking of just using parseoption or something in initnewplayer

#

but i wanted do see if there was a better way

winged badger
#

so its sessions for us

glad jasper
#

oh

winged badger
#

but we can spawn the entire level of 50k actors procedurally on clients, network them after the fact, and have everything ready before hot joining client calls beginplay

summer tide
#

So I've OnRep function, in 1/1+ client mode, whatever inside gets called twice when I test it using breakpoints. Is that normal?

wild patio
#

this should be an easy question. is this too much data to send around to clients per tick?

#

(this is on LAN games btw)

#

i'm guessing with a max number of players being 8, probably not?

thin stratus
#
  1. Make sure to do that unreliable
  2. If it is too much, you can go C++ and compress things
#

--
Does anyone have some basics on a simple snapshot interpolation for floats?
I just have a Float Variable that is OnRep and I would love to smoothly interp between the last and the current update. I'm kinda missing how I figure out the timing on this.

Do I just make up a number that makes sense? I know the time between last and current update.

winged badger
#

i'd steal the algorithm from CMCs skeletal mesh interp

#

it seems to work fairly well

peak sentinel
#
  • disregard -
thin stratus
#

The void UCharacterMovementComponent::SmoothClientPosition_Interpolate(float DeltaSeconds) ?

winged badger
#

that one

thin stratus
#

It's sad how much stuff they require to do this

#

That plugin really needs to release

winged badger
#

it is available on 5.0

thin stratus
#

Not finished in the slightest though or?

winged badger
#

it would probably need little work on backporting and some alterations as you use it atm

thin stratus
#

Wonder how long that all takes with someone else working on it

winged badger
#

i have not read it yet, as the 5.0 hobby project doesn't have network in yet

#

and the work project is 4.27

thin stratus
#

Yeah we are mostly on 4.26 atm

winged badger
#

it has Network Prediction Insights too

thin stratus
#

Yeah I saw the videos

#

Could have used exactly that ages ago when trying to figure out where the corrections on my CMC came from

#

Man, the CMC interpolation has soooooooo many variables that are just overkill to recreate for a little freaking float I want to smooth

winged badger
#

you just need to steal a core of it

#

you don't need both linear and exponential interpolation code with configuration for both

thin stratus
#

I know I only need linear atm

#

I think I will have ot step by step recreate it an cut it apart

#

To understand what they are doing

modest yoke
#

Does anyone know the earliest point where a player's net role first becomes NM_ListenServer?

winged badger
#

as soon as world instantiates a net driver

#

that would correspond to the line in your logs "listening on port XXXX"

#

you can just run a level in listen mode, Ctrl+Shift+F the log text in the IDE and breakpoint the line printing the log

#

figure out the exact moment via callstack from that breakpoint

modest yoke
#

It looks like whenever WorldContext.PendingNetGame is set with a URL containing listen

quasi tide
slate basin
#

hey, anyone know why beginPlay isn't called on my client

sinful tree
slate basin
#

on any actor that is spawned on the server and replicated

sinful tree
#

Is the actor close to where the clients are?

slate basin
#

it's the owning clients character

#

tried it on the weapon that's given the character as well but none of them call Beginplay

rancid orchid
#

Hey guys, anyone had experience with using a character movement component and pushing physics objects smoothly across client and server (or faking it)?

#

(Or any tips advice would be helpful currently getting jitters, on clients, and weird rubber banding on physics objects when more lag is applied)

wild patio
#

i'm very curious about an answer to this

glad jasper
#

how do i test client entry from a client map to a dedicated server map in the editor?

grand kestrel
#

Is there a function/event for actor becoming relevant (or not relevant)?

sinful tree
grand kestrel
#

@sinful treeany chance you know if replication occurs prior to begin play?

#

Or if replicated properties can be from before it lost relevancy

sinful tree
#

The server always contains a copy of the actor as it is and all variables that it knows about. When an actor loses relevancy on a client, that actor is destroyed on the client.
When an actor is becoming relevant, it only does so because the server is replicating it again to the client, and any replicated variables that actor has would come along with that replication.
eg. You have a replicated actor that is moving around the level on its own with AI. Your client sees it in the world and knows where it was, but moves far enough away that it loses relevancy. The actor no longer exists on the client, but the server is still simulating it, so it continues to move around. Your client moves in closer and it makes the actor relevant again, but it would then spawn in on the new position that the server has, not what your client had.

grand kestrel
#

Yeah, but if there's a UPROPERTY(Replicated) float Foo = 0.f; , and client loses relevant actor, and server sets Foo = 639.f while client does not have actor, when actor becomes relevant again is BeginPlay() going to be called while Foo == 0.f or Foo == 639.f or is there a chance of either

sinful tree
#

It would be 639.

grand kestrel
#

Ah that works perfectly, thanks 🙂

sinful tree
#

When the client spawns the actor again, it is only doing so because the server is telling the client to spawn that actor through replication, and it feeds the replicated variable it has about that actor.
I imagine if you have a ton of variables on that actor there could be the chance where the actor is spawned and begin play could fire before all replicated values are received. but I'm not sure - that's a bit more advanced into how the engine works than I know.

grand kestrel
#

Hmm I'll fix it if it breaks 😄

#

Presumably attachment replication would break if this was a thing

dark edge
#

Your onrep would just do

OldValue = NewValue
NewValue = IncomingOnrepValue
thin stratus
#

Ah

dark edge
#

Exponential would be a lot smoother and pretty much work the same just smoothing the first time derivative of Value. Compare lines to a spline

thin stratus
#

That's the level of "Basic" I was hoping for haha

#

The thing I'm trying to smooth is just an incrementing float value

#

Basically the distance along a spline

#

So clients see it moving smoothly

#

I would love to read up on this in like a basic blogpost with examples and such. Not sure I'm just not using the right words, but most I could find is physics based blogposts that go way too far.

dark edge
#

Look at the old physics replication stuff too. They do some tunable exponential stuff there.

#

Seemed simple enough at first glance.

#

The stuff misspelled as "Physic Replication Settings" in project settings.

thin stratus
#

But that's about auth physics movement and I kinda know the theory behind all of this already

#

I will try to absorb the equation you posted

#

Does DeltaTime go in there somewhere?

#

CurrentTime

#

I guess

#

What is New vs OldTime though? Last Time a Server Update came and also CurrentTime?

#
OldTime = OldValueServerTimestamp
NewTime = NewValueServerTimestamp
CurrentTime = ClientTimestamp (already incremented by current frames DeltaSeconds?)
#

Something like that?

dark edge
#

Yeah those would be the times corrosponding to those value points.

#

You basically want to always interpolate along the line between the last 2 points.

thin stratus
#

I think the CMC actively replicates the Time to the Client (not sure how that stays in sync, given that's a second OnRep value)

dark edge
#

That might be overkill as you're caring about clientside smoothness

thin stratus
#

Do I make the whole thing a struct and send the Timestamp to the Client alongside, or is it the Time on the Client when the update arrived?

dark edge
#

I would just record time on client for this but there may be reasons to sync it

thin stratus
#

Yeah CMC does more, they make sure you aren't ahead too much and stuff like that

#

But hard to understand from just the math they throw at me

dark edge
#

Hell you can prolly just finterpto towards the last data point you have and it'd probably work fine.

thin stratus
#
if (TargetDelta > SMALL_NUMBER)
{
    // Don't let the client get too far ahead (happens on spikes). But we do want a buffer for variable network conditions.
    const float MaxClientTimeAheadPercent = 0.15f;
    const float MaxTimeAhead = TargetDelta * MaxClientTimeAheadPercent;
    ClientData->SmoothingClientTimeStamp = FMath::Min<float>(ClientData->SmoothingClientTimeStamp, ClientData->SmoothingServerTimeStamp + MaxTimeAhead);

    // Compute interpolation alpha based on our client position within the server delta. We should take TargetDelta seconds to reach alpha of 1.
    const float RemainingTime = ClientData->SmoothingServerTimeStamp - ClientData->SmoothingClientTimeStamp;
    const float CurrentSmoothTime = TargetDelta - RemainingTime;
    LerpPercent = FMath::Clamp(CurrentSmoothTime / TargetDelta, 0.0f, LerpLimit);

    UE_LOG(LogCharacterNetSmoothing, VeryVerbose, TEXT("Interpolate: WorldTime: %.6f, ServerTimeStamp: %.6f, ClientTimeStamp: %.6f, Elapsed: %.6f, Alpha: %.6f for %s"),
                    MyWorld->GetTimeSeconds(), ClientData->SmoothingServerTimeStamp, ClientData->SmoothingClientTimeStamp, CurrentSmoothTime, LerpPercent, *GetNameSafe(CharacterOwner));
}
else
{
    LerpPercent = 1.0f;
}
thin stratus
#

Cause UE only has the CMC and maybe the ProjectileMovementComponent for this.

#

+- that plugin

dark edge
#

Looks like they only do lerp as well

#

Physics replication has a fancier version

#

Not the plugin, the old system

thin stratus
#

Didn't even know we had physics replication

#

Thought any default actor just sets the transform it gets from the server

dark edge
#

Ya no prediction tho. Just smoothing and interpolation/extrapolation

thin stratus
#

Fair

dark edge
#

So yeah it looks like the CMC does exactly what I posted but limits extrapolation and passes over timestamps.

thin stratus
#

They have an extra part for Extrapolation

#

Actually

#

Nevermind, that was somewhere else, the extra part was Exponential smoothing

#

I just notice I can't do this without C++, cause the OnRep in BPs doesn't give me the OldValue

#

ffs

dark edge
#

LMAO I'm trying to look up the source code for the physics replication and found some comments from myself. Not a lot of people messing with it I guess.

thin stratus
#

Then I need another variable I guess

#

So the Replicated one and the a saved version of it locally

#

So RepFloat NewFloat OldFloat

OldFloat = NewFloat
NewFloat = RepFloat
#

Guess that' works

dark edge
#

Ah yeah because your NewValue is already overwritten when the onrep fires

thin stratus
#

Still annoying, why can't they add that pin -.-

#

Yes

dark edge
#

Same reason server onreps fire in BP and not C++. Just unreal things

thin stratus
#

Yeah well, the reason is that BP OnReps are "Your varibale changed" and not "You received a net update of that property" to put it simple.
I know that part. Screams for a PullRequest

peak sentinel
thin stratus
#

Yeah I'm moving a mesh along a spline and I want server and Client to match.
And there are probably a gazilion ways to do that, like just refreshing the position based on the RepNotify every few seconds, but I wanted to try and just smooth the DistanceFloat

#

Solution + learning it

#

And yeah, naming was mainly for making sure I get what Adriel means

#

They are called a bit different in my code in the end :P no worries

peak sentinel
#

So this works with FVectors since ClientData->MeshTranslationOffset is a FVector but if it can work (or can be translated to somehow) with floats I recommend using this type of interpolation because it works best among others in different network conditions:

// Smooth interpolation of mesh translation to avoid popping of other client pawns unless under a low tick rate.
            // Faster interpolation if stopped.
            const float SmoothLocationTime = Velocity.IsZero() ? 0.5f*ClientData->SmoothNetUpdateTime : ClientData->SmoothNetUpdateTime;
            if (DeltaSeconds < SmoothLocationTime)
            {
                // Slowly decay translation offset
                ClientData->MeshTranslationOffset = (ClientData->MeshTranslationOffset * (1.f - DeltaSeconds / SmoothLocationTime));
            }
            else
            {
                ClientData->MeshTranslationOffset = FVector::ZeroVector;
            }

(CMC line 7452)

thin stratus
#

Yeah the Offset is previously calcualted though

#

Which is more or less what I posted before

#

It's not just line 7452

peak sentinel
thin stratus
#

That's why I wanted to start simple

#

I'm still wondering what exactly CurrentTime is @dark edge

#

In the CMC, they increment some float on the ClientData each frame

#

Which sounds like just GetWorld()->GetTimeSeconds() with extra steps

#
void UCharacterMovementComponent::SmoothClientPosition_Interpolate(float DeltaSeconds)
{
    SCOPE_CYCLE_COUNTER(STAT_CharacterMovementSmoothClientPosition_Interp);
    FNetworkPredictionData_Client_Character* ClientData = GetPredictionData_Client_Character();
    if (ClientData)
    {
        if (NetworkSmoothingMode == ENetworkSmoothingMode::Linear)
        {
            const UWorld* MyWorld = GetWorld();

            // Increment client position.
            ClientData->SmoothingClientTimeStamp += DeltaSeconds;
#

The code actually looks awfully familiar... I looked at that stuff before when I coded a new CMC for a networked Hovermovement

#

Which was a nightmare during that time ;_;

#

Hm okay, CurrentTime is not TimeSeconds :D

#

Shouldn't CurrentTime be the LerpPercent?

#

Client 1: OldPosition: 1551.935181 | NewPosition: 1562.111084 | OldTimestamp: 4.092935 | NewTimestamp: 4.127709 | PositionDelta: 10.175903 | TimestampDelta: 0.034774 | TempResult: 292.627106 | CurrentTimestamp(?): 4.163205 | Result: 2770.20166

#

TempResult is the two deltas divided. CurrentTime seems wrong

thin stratus
thin stratus
#

Fell back to using a normal FInterp for now, using delta seconds on the equation for currentTime works, but it's funnily enough less smooth than just FInterp

#

Will look into a proper solution at some point

meager wing
#

does UE_LOG() work with a multicast? I can't get multicasting to work at all for some reason and im at the point where you start to question everything lol

latent heart
#

What does UE_LOG have to do with multicasts?

meager wing
#

Nothing really, just trying to trigger a log on the client for bug testing

latent heart
#

If it compiles, it will work.

#

Whether the function that it's in is being called or not, that's another question.

meager wing
#

Calling DestroySession() from a widget button press, the multicast is being called on the host, but nothing happens on the client

#

Thought i had a pretty firm grasp of this stuff, hoping im just forgetting something stupid

latent heart
#

It might be that the game instance isn't replicated to the clients? They each have their own? Shrug

#

Do you have any other RPCs on your game instance that actually work?

meager wing
#

This is the first one, been working on lobby stuff

latent heart
#

I'd wager (but I don't know, I haven't worked on MP games in a while) that hte Game Instance obj isn't replicated, so you can't use it for RPCs.

#

You might want to move that to your gamestate class

winged badger
#

GI is not replicated

latent heart
#

GameInstanceObj->GetWorld()->GetGameState<AMyGameState>()->Multi_DestroySession()

#

Something like that.

meager wing
#

Yeah that would make a lot of sense actually

#

goddamn it lol thanks guys

winged badger
#

there are more elegant ways to do this then a multicast

meager wing
#

I figured their had to be

winged badger
#

as generally, host nuking session results in clients doing a visit to main menu

meager wing
#

yeah, i removed all the features from the fuctions while I was testing, but they'll be booted back to the multiplayer menu

winged badger
#

so, just having destroy session connected to the MainMenu BeginPlay eliminates the need for the MC

#

there is also a way to handle it via network error handler

meager wing
#

That's a good point, if the client uses steam to join and not the play button the session won't be destroyed though yeah?

winged badger
#

if host destroys the session, it will get destroyed

#

because steam doesn't really react instantly, its good to clean up on clients

meager wing
#

Ah okay, I was under the impression that clients had their own local sessions that needed to be destroyed on disconnect

winged badger
#

but for production level with listen servers, you generally want to connect the network error handling into this

#

"Connection to host has been lost." and "Host has quit the session." message as you end up in main menu are not exactly the same

#

with first players blame your crappy connection code, with second host is an arsehole and you're blameless

meager wing
#

true lol, I'll move things over to GameState and start building some stuff.

#

Which handle are you referring to btw? OnSessionFailure?

winged badger
#

this is kinda one step at a time situation

#

and i don't have time to check the error handling code now, don't remember it off the top of my head

#

but it can be done, something to put a mental note for

meager wing
#

alright, thanks

vital bramble
#

Hey! it is normal that when OnRep_PlayerState is call, the player state can be retrieve from the Player Character, but not from the controller, which is still nullptr as this moment ?

thin stratus
#

Different Actors might replicated in different intervals. If the OnRep_PlayerState doesn't call in the Controller, then I would not assume it to be valid.

vital bramble
#

Hum ok, didn't realize there is also OnRep_PlayerState in the controller... So I need to use the one from controller if I want to be sure that player state is valid to be retrieve from controller right ?

thin stratus
#

Yop

vital bramble
#

Ok thanks, I'm still fairly new to the whole gameframework, it is a best pratice or a callback which basically in a multiplayer environment say "Controller is ready to be used, and everything is linked together" ?

thin stratus
#

No there is no such callback by default

latent heart
#

You can build your own one by checking things in onrep functions. Probably a good idea to check in beginplay too.

vital bramble
#

Ok, basically you would have for example booleans which check if player state and player character are nicely assign to the controller, and then when all bool are true, simply trigger the function which should be trigger when everything is setup ?

winged badger
#

so when first OnReps fire from the PC, PS is practicallyt guaranteed to have not replicated yet

#

when the PS Actor's NetGUID is resolved, another OnRep should fire in the PC though

vital bramble
#

I think I'm not yet enough advanced to understand, when OnRep occurs, it means that the variable has been replicated from the server to the client right ? How it is possible that "it is pratically guaranteed to have not replicated yet" ?

spark owl
#

is there anyway that I can stop people from using cheat engine to speedhack on my game?

chrome bay
#

Character Movement has speedhack protection build in

#

It's not flawless though

winged badger
#

PC has to replicate its pointer to PlayerState, but as replicated memory address is meaningless, it replicated a network identifier, or NetGUID

#

for the client to resolve that NetGUID, the PlayerState Actor itself has to have replicated as well

#

so you end up in a situation where PC has a valid NetGUID for the PS, but the PS Actor itself has no yet been spawned on the client, as the packet instructing client to spawn the PS replicated Actor did not arrive yet

vital bramble
#

oh yeah ok, and where I can get the information that the PS Actor has been properly replicated and spawned ?

spark owl
winged badger
#

so

#
OnRep_PlayerState()
{
  if (PlayerState)
  {
    do onrep logic
  }
}
#

as it can be a nullpointer when it gets called, which you can usually just ignore

vital bramble
#

Ok, I've been logging the main network callback in order to understand, which give me this :

LogTemp: Error: PossessedBy - Character - Server Side
LogTemp: Error: SetPawn - Controller - Server - BP_PlayerCharacter_C_0
LogNet: Join succeeded: MSI-XXX
LogTemp: Error: SetPawn - Controller - Client - NULL
LogTemp: Error: SetPawn - Controller - Client - BP_PlayerCharacter_C_0
LogTemp: Error: OnRep_Pawn - Controller - Client
LogTemp: Error: SetPawn - Controller - Client - BP_PlayerCharacter_C_0
LogTemp: Error: OnRep_Pawn - Controller - Client
LogTemp: Error: OnRep_PlayerState - Character - Client Side
LogTemp: Error: KO
LogTemp: Error: OnRep_PlayerState - Controller - Client Side
LogTemp: Error: SetPawn - Controller - Client - BP_PlayerCharacter_C_0
LogTemp: Error: SetPawn - Controller - Client - BP_PlayerCharacter_C_0
LogTemp: Error: Acknowledge Possession - Controller - ?? - BP_PlayerCharacter_C_0```

I don't see two calls for the OnRep-playerState - Controller, it is normal ?
Controlle refers to callback in PlayerController when Character refers to callback in PlayerCharacter
winged badger
#

it can happen

#

especially if your level is more or less empty

vital bramble
#

Yeah it is

winged badger
#

less actors to replicate = can actually fit all of them into a single frame of ServerReplicateActors

vital bramble
#

Oh yeah ok ! And why do I receive that much "SetPawn" callback ?

winged badger
#

it won't be the case when there is plenty of stuff to replicate

#

because both server and client run SetPawn

#

its called from both Possess() and OnRep_Pawn() in the controller

#

hint: that also makes it a great place to do extra Pawn initialization that both server and client need to do

vital bramble
#

Oh yeah ok, and also a great place to ensure that my pawn linked to controller is created ?

#

or OnRep_Pawn is better for that case ?

#

Also, which OnRep_PlayerState has to be taken in consideration regarding the actual overall replication stuff ? The one in PlayerCharacter or the one in PlayerController ?

bitter swift
#

If we were to make a spike trap (a simple static mesh that moves up and down) and we need to make sure it's synched for all clients and server, what we be the best way to do that?
RPC calls are not sufficient, because there might be a lot of latency.

I was hoping for a way to have the spike trap operate locally, but with a synched timer of sorts. Any ideas?

bitter oriole
#

For what it's worth, actual synchronization may not be desirable

bitter swift
#

I wonder how they do this in other games.

chrome bay
#

Probably an extremely simple replicated counter for each time it goes up

bitter oriole
#

If the trap triggers at real world time 1 and the player avoids it at time 0, but the information takes 3 time units to reach the server, the server will consider the trap triggered

chrome bay
#

If we're thinking fortnite traps

bitter oriole
#

But in that scenario the player should not trigger it

chrome bay
#

Also remember everything the trap effects will be behind the server by the same time, so it's not that big of a deal if it's latent

#

If anything it's preferable

bitter swift
bitter oriole
#

Yes, but like I explained, you probably don't really want that

bitter swift
bitter oriole
#

You want for the server to process the game logic in exactly the same way as on the remote client, timing wise - this is why shooters routinely let players shoot others behind wall corners

#

So if the player avoids the trap locally they should also avoid it on the server

chrome bay
#

Getworld->Timeseconds is local to your world time, and syncing it perfectly is physically impossible

bitter swift
chrome bay
#

I do wonder how many problems would be easier to solve if perfect clock synchronisation was possible

#

FU einstein

#

But the clients can still control their own overlap logic and tell the server "I took damage" - they can't, because then they can just not send that event to avoid damage

#

That's how cheating starts

bitter swift
chrome bay
#

It's still not good practice

#

Why send an RPC for something the Server can figure out itself

bitter swift
#

If players cheat, that's fine. It's not important for this project.

bitter oriole
#

You can do everything client side if you want but this is also perfectly doable with server side logic.

  • use shared world time for the trap
  • consider how long the input takes to travel (ping / 2) and on the server, when processing damage, run the logic on the trap's state for that time.
chrome bay
#

It also doubles the perceived latency

bitter oriole
#

Think really hard about latency and how long the game will take to react visually and effects-wise

#

Put it on paper with graphs

bitter swift
winged badger
#

https://www.youtube.com/watch?v=h47zZrqjgLc good relevant talk @bitter swift

GDC

In this 2011 GDC session, Bungie's David Aldridge discusses the programming that drove Halo: Reach's online networking.

Register for GDC: http://ubm.io/2gk5KTU

Join the GDC mailing list: http://www.gdconf.com/subscribe

Follow GDC on Twitter: https://twitter.com/Official_GDC

GDC talks cover a range of developmental topics including game des...

▶ Play video
pallid mesa
vital bramble
#

I don't get what's the difference between OnRep_Pawn and AcknowledgePossession ? Is OnRep_Pawn call when the Pawn is replicated to the client but may not still be possess by the controller ? (Basically just spawned ?)

modern cipher
#

I think you answered ur question

dark edge
# bitter swift If players cheat, that's fine. It's not important for this project.

Remember there are 3 views to consider. Player A, Player B, and Server/Host/Player C. By definition they can't all agree on everything unless you DON'T do prediction. Every local player is in the future relative to the server, and sees OTHERS in the past. Even if you perfectly synced a traps movement on all 3 views, they wouldn't agree on where the characters are, leading to the local player seeing other players run through traps.

rapid tide
#

does anyone know if there's a limit on the maximum number of players on the same game server supported by UE5 ? I'm asking for an MMO, to see what viable solutions for the server are if we're building it with UE5. A custom game server would be much more costly but that's what we're leaning to right now.

modern cipher
#

i think its still the same single server architecture

dark edge
modern cipher
#

idk if they working on anything new

vital bramble
# modern cipher I think you answered ur question

ok thx haha, I've another question, I've develop my logic to happens in OnRep_PlayerState & AcknowledgePossession, which works great for client, but not in a standalone non-multiplayer environment, where should I consider place my logic for that case ?

dark edge
#

If you don't have $1M to blow don't make an MMO lol. At least not a traditional one. Something Dark Souls like with in/out multiplayer would be much more feasable.

rapid tide
#

the company has millions

#

that's not the issue, we just want to understand if UE5 supports it or we have to build a custom backend

#

i mean not backend per se, just the game server

#

the backend will be custom

modern cipher
#

afaik unreal can only build mmo clients but not the server

dark edge
#

Anything beyond Fortnite is probably unexplored territory.

modern cipher
#

you can check out spatial os if you want

dark edge
#

Spatial OS has a few Unreal projects hanging around i think

lusty sky
rapid tide
#

yea, but still thank you for the response

tawny nova
#

like what makes it an "MMO" for you? getting as many people into one live server, or having a persistent sort of world

rapid tide
#

think Black Desert Online

#

so, yea

tawny nova
#

right so.. most of those players are not on a single server

rapid tide
#

true, you can shard every zone and instance and city

tawny nova
#

the economy is global, but that's why they have channels too

#

yeah

#

it's just about how you set up that infrastructure, UE can certainly handle any one instance as well as anything

#

i've always heard that's actually why BDO doesn't have flight or teleport, to make sharding easier, heh

rapid tide
#

interesting

#

thanks for the insights

golden warren
#

Hey, How can I fire "Run on server" event with "Remote Client"?

thin stratus
thin stratus
dark edge
#

I'm so glad I'm doing 0 prediction in my game

#

It's a slowish vehicle game tho so it can work

thin stratus
#

I don't think there is another solution to games like this

#

The Killer sees the survivor in the past. When they are jumping through a window, they are already further on the local survivor side

#

If you use the survivor or the server location, it would feel shit for the killer, who would try to hit and always miss

#

But yeah, kinda the same problem as you would have with trying to headshot a moving target

golden warren
thin stratus
#

That code should be fine

#

But the owner of that component has to call the code

golden warren
quasi tide
#

Do you understand ownership? Exi's networking bible covers it.

#

An object can only call a server rpc if they are the owner of the object. So, if the server has ownership of a door, a player can not call a server rpc on it. The player would have to call a server rpc on itself that would then reach out to interact with the door on the server.

golden warren
#

hmmm...
Well, if I want to do calculate only in client and then replicate client result to server, how to do?

thin stratus
#

Kiiinda like you did it

#

I mean you call "Predict" on the Server, which doesn't really make sense

#

You would call predict first, then pass the SpawnTransform to the Server

#

Which is of course an open gate for cheaters

summer tide
#

So I have this in a function running in tick. Do I have to set CurrentRotation using ServerRPC? It doesn't work properly in 1/1+ client.

CurrentRotation = FMath::RInterpTo(CurrentRotation, TargetRot, World()->GetDeltaSeconds(), 2.f);
ServerSetRotation(Char, CurrentRotation);```
thin stratus
#

Hm, pretty sure remote clients don't have ControlRotation

#

Try GetBaseAimRotation maybe?

#

Given Ride is a Pawn

#

Theoretically you don't need to use an RPC here, since most of the data should be available to everyone

summer tide
#

I got it to work by setting the CurrentRotation using ServerRPC.

summer tide
gritty phoenix
#

If I spawn a replicated actor on the server, that is async loaded from a data asset on the server - what should I be doing on the client(s)? If anything? To make sure the spawned actor is loaded into memory on the clients?

thin stratus
#

iirc it sync loads it on the clients

#

I looked into that already once hmpf

gritty phoenix
#

thanks - i suppose that is better than the client crashing, although its not optimal..

#

how did you end up solving it in your case?

#

i'm thinking server passes a list of spawnable actor class soft refs to client on begin play and each client then triggers its own async load?

light iron
#

Oh I just realized that eXi wrote the compendium I read through almost half a decade ago now. 😂

#

Good stuff man

#

Unfortunately that studio went defunct and I left development for several years.

#

Playing catchup on all the new tools, they're pretty nice.

pallid mesa
#

half a decade ago sounds like a lot and it's just 2017 😭

#

I'm getting old

verbal tendon
#

I feel like a decade ago was not longer than a year past

#

time flies as you get older

#

In comparison to the grueling seemingly endless days in the school system .... 🤣

thin stratus
mystic saddle
#

is it a bad idea to save players transform by using save game to slot node ?
Is it better to use a database like mongodb to save players information for a multiplayer game ?

sinful tree
# mystic saddle is it a bad idea to save players transform by using save game to slot node ? Is...

Depends on the game - if you intend on allowing players host sessions or other third party entities host your servers then you need to use a save game, otherwise you'd need to have some kind of authentication system that verifies what server has access to read/write what data or someone could easily scramble your database contents.

If you intend on hosting all the servers for the game internally (ie. you control all the servers), you could potentially still use a save game but it makes less sense as you wouldn't want multiple servers having to access that single save file - it's probably better to use a database.

mystic saddle
sinful tree
#

Well, your only slow part would most likely be loading any data or doing extensive queries. The only database loading that would be of concern is if a player is joining the game - and I can't imagine it taking more than a second or two to retrieve whatever data it is you need to get your player in the game, unless your server / database have really bad available bandwidth and latency between them.
Saving shouldn't impact anything, only update dirty fields, etc. and when it saves, it should be completely transparent to your players anyway (ie. they don't have to wait for anything when saving).

mystic saddle
sage isle
#

I have made a dedicated server, built from source and got it all working, and I am trying to get some kind of way for creating the session and joining the session. I made a widget where I can search for sessions of the game but my question is this. I want it to be a true dedicated server meaning it can run even when empty, and from what I have seen create session requires it to be called from a client as if it were hosting. So how do you go about creating the session from a server itself? Like having the server register so that people can find the server even if there is no one else on.

plush otter
#

I have a question about player state. How does the NetCullDistanceSquared setting affect player state?

#

The player actor is destroyed when out of distance. What about associated player state? My experiment shows the other state is at least still ticking

fossil spoke
#

The PlayerState is the state of another Player as seen from other Players. It is important that it always exists, so you can know important information about each Player (like score, kills, deaths etc etc).

sinful tree
sage isle
#

but the create session node uses the player controller to establish it, am I able to just leave that blank?

warm sequoia
#

@fossil spoke Hey, do you know how it is possible that I can join other players on the game I am making even though they don't have my project files? do they have some ID in the code that is the same as me?

fossil spoke
#

You might have to reword that question, not exactly sure what you mean.

#

Do you mean to ask, how can they still join you even if they have out of date files for the same game?

warm sequoia
fossil spoke
#

You would have to setup some sort of Version system that rejects them when attempting to connect, or filter out servers that arent the same Version.

#

This isnt something that comes out of the box with UE.

#

You need to set that up yourself.

warm sequoia
#

but is there a way that I can just change something in the code that makes this version its own identity?

fossil spoke
#

It is its own identity, but that doesnt stop people joining.

warm sequoia
#

well they cant join since its a different version, but there names appear and it fails to connect

fossil spoke
#

Well that goes back to what I said earlier about setting up a system that filters out Servers that arent on the same Version as the Client.

warm sequoia
fossil spoke
#

Not really, it depends on how your game displays Servers to join.

#

You may need to setup Online Beacons to gather the Version information from the Server.

#

Or it may need to be exposed as an Option as part of the Server list request.

warm sequoia
#

I think it needs to be exposed as an option

#

what would i change in the options part?

fossil spoke
#

Im not sure, its usually going to be specific to how you have setup your game, perhaps google how to expose it as an option first?

fluid summit
#

Hi! does anyone know if there's a way to use Navigation on Client? the AI only works on server so far

lost inlet
#

well it's literally a checkbox to allow navigation data to be loaded on client, but you should never trust your clients to do AI workloads

lusty kelp
#

so this is where i can ask a question?

#

Umm hello?

lost inlet
#

Don’t ask to ask, but that also depends if it’s to do with multiplayer networking or not

somber glade
#

if we have pushtotalk=false do we still need to 'start network voice' once on the client, or is it assumed to be capturing audio and sharing it immediately?

lusty kelp
#

it indeed does

#

can u connect locally to the same map around the world per say?

#

asking for a friend

#

using ip

#

I know it may be a simple google answers but can't seem to find

thin stratus
somber glade
#

I have a button bound to start networked voice, so I can see if works before or after

somber glade
#

seems like neither did

vital bramble
#

Hi ! Is it an equivalent to virtual void OnRep_PlayerState() override; on server side please ? i'm trying to make my game possible in Play as standalone & play as client, et I would like to export the logic I've in OnRep_PlayerState, into a similar function for standalone which I get it right, only get callbacks that comes from server side ?

sinful tree
vital bramble
#

I've check in source code, and override the "InitPlayerState" which seems to also works, it is a good way to do it ? Which basically spawn the player state only if it is not a NM_CLIENT

finite pendant
#

I am attempting to replicate this animation asset pack that I bought (that I didn't know was not network replicated). However I am new to all of this. Any advice or help would be appreciated. Simple Movement Ability System is the name of the asset pack.

wraith pebble
wraith pebble
finite pendant
wraith pebble
# finite pendant I am attempting to replicate this animation asset pack that I bought (that I did...

If you really enjoy a difficult challenge, then go for it. But otherwise, it might be best to cut losses and find a networked one. If you are up for the challenge, here is an excellent tutorial from Rama about adding custom character movement. It's all in c++ of course - this stuff can't really be done in blueprint. https://nerivec.github.io/old-ue4-wiki/pages/authoritative-networked-character-movement.html
The tutorial might be a bit old but it's a really good primer.

#

Yep - generally, the animations should just be a client-side response to replicated/networked data.

#

Haven't looked at the pack yet but 'Simple Movement Ability System' sounds like a lot more than an animation pack.

finite pendant
#

It's actually both movement and animations

wraith pebble
finite pendant
wraith pebble
# finite pendant I will see what I can do and if I make any progress then I will update

If you're set on networking this in blueprint, my advice is to break it into small chunks. Just focus on one movement ability first and go through the whole process of getting it networked. Once you get one working, doing others will be easier.

Spread the movement ability you tackle first out into different categories: 'the input', 'the mechanics' and 'the FX'. These different sections all have different ramifications for networking.

The Input: this is where you catch the input and trigger the movement ability with it. This happens on locally controlled client (or server if hosting as listen server).

The Mechanics: This is the actual movement part. Like setting the actors location, ect. For this quick and dirty implementation, you can probably just do this stuff on server. (in a proper implementation in code, you'd hack into the saved moves system so you could run the mechanics part on locally controlled client and server in parallel.)

The FX: This is any animations being played, sounds played, particles, screenshakes, rumbles, ect. Anything all clients will care about but a dedicated server would not care about.

Once you've divided the whole movement ability up and know which parts belong to which category, you can string them together with RPCs (custom events set to run on server, multicast, or run on owning client).

So the input will lead to a run on server RPC, so we can do the mechanics. While we are on server, when we need to do the FX, we use a multicast RPC so we can do the FX.

That's the quick and dirty version. If there's not any net lag, itll work
pretty good. If you add net lag, you may start getting net corrections.

jolly siren
#

How does the engine net serialize a struct within a struct by default if you don't specific a NetSerialize?
I'm just trying to replace the default behavior in my custom NetSerialize for a field. Looks like Ar << X works for simple types like float.
But not sure how to add the default behavior for something like a FDamageEvent

marble gazelle
#

Per default it will iterator over all UPROPERTY fields and call Ar << Value I think.

#

ah now I got you

#

there is a function that does that. give me a sec, need to find my code^^

#

So what I do is:

void foo(FNetDeltaSerializeInfo& Params)
{
  FStructName MyStructInstance = /*...*/;
  Params.Struct = FStructName::StaticStruct();
  Params.Data = &MyStructInstance;
  Params.NetSerializeCB->NetSerializeStruct(Params);

}

This is the simple solution which won't ensure Actors are mapped properly. If you need to replicate actors / objects stuff with Guids, you need to write more code and also provide a GuidReferencesMap and then create a FNetBitReader and pass it to FNetDeltaSerializeInfo::Reader
Maybe do some String search on this and look for examples in the source code

I'm not sure how this looks for the non delta veriant, but I'd assume similar^^

jolly siren
#

Hmm okay I was expecting a one liner. I can probably just do Ar << DamageEvent.DamageTypeClass for now since it's really just a one property struct.

marble gazelle
#

well you could, if you implement the operator^^

chrome bay
#

The network archives have overrides for UObject* and FName which use the Package Map to serialize object references so it'll work fine

#

Just make sure you don't use Shared Serialization

#

If you wanted to be more explicit you can do PackageMap->SerializeObject(xxx)

marble gazelle
#

are we talking about an UObject or a UStruct?

#

as I don't think SerializeObject will work with a struct.

chrome bay
#

with UObject yeah

jolly siren
#

I'm just trying to replace the default net serialization for a struct (FDamageEvent) within a struct. Since I defined my own NetSerialize for the outer struct to do some other packing.

chrome bay
#

Just Ar << TheObject should work fine

#

See FHitResult

marble gazelle
#

This only works, if ther is an operator<< defined for the struct

jolly siren
#

Right, it's not for FDamageEvent

chrome bay
#

But you are serializing the object no?

#

DamageEvent.DamageTypeClass

jolly siren
#

That's what I was going to do yeah since I didn't know a generic way to replace the serialization of the entire FDamageEvent struct

chrome bay
#

yeah that will work

#

Assuming this is inside bool FDamageEvent::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)

marble gazelle
#

I think there is, could you check the UStruct functions?

jolly siren
#

ah no I was going to do it in the outer struct netserialize

chrome bay
#

I'm not sure i follow

marble gazelle
#
struct Outer
{
  Inner MyInner;
  float SomeValue;

  bool NetSerialize(...);
};

this I think

chrome bay
#

If you mean can you serialize internal properties of Innter in Outer::NetSerialize() then yes that will work

#

None of the internal properties of Inner will use default serialization once you define NetSerialize() for the outer anyway

marble gazelle
#

I'd just look into using FNetDeltaSerializeInfo::NetSerializeCB->NetSerializeStruct ^^

jolly siren
#
USTRUCT()
struct FHitInfo {
    GENERATED_BODY()

    UPROPERTY(Transient)
    uint8 ActualDamage;

    UPROPERTY(Transient)
    FDamageEvent DamageEvent;

    bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) {
        Ar << ActualDamage;

        // TODO: how to serialize damageevent like engine already was?
    }
}
marble gazelle
#

or the non delta equivalent if it exists

chrome bay
#

Ah yeah kk, I see what you mean

#

Yeah unless DamageEvent has it's own NetSerialize already, you have to serialize it manually

marble gazelle
#

you should be able to call the engines generic version

#

I just can't remember how it was called and if it was part of UStruct

#

(so the static class)

chrome bay
#

You can do this, but it only works if you've defined NetSerialize

        {
            DataStruct->GetCppStructOps()->NetSerialize(Ar, Map, bOutSuccess, GetMutableMemory());
        }```
marble gazelle
#

because you can serialize by reflection I think

#

na, you don't need net serialize for it

#

otherwise the relfection based serialization wouldn't work

chrome bay
#

Reflection based doesn't do it that way it does it per-property

#

And has the shadow state

marble gazelle
#

which is reflection

chrome bay
#

This is what I do for my polymorphic wrapper:

{
    DataStruct->GetCppStructOps()->NetSerialize(Ar, Map, bOutSuccess, GetMutableMemory());
}
else
{
    void* MutableData = GetMutableMemory();
    for (FPropertyValueIterator It(FProperty::StaticClass(), DataStruct, MutableData); It; ++It)
    {
        const FProperty* TheProperty = It.Key();
        if (TheProperty->PropertyFlags & CPF_RepSkip)
        {
            continue;
        }

        void* MutablePropertyData = const_cast<void*>(It.Value());
        TheProperty->NetSerializeItem(Ar, Map, MutablePropertyData);
    }
}```
#

Slightly different use case though, but AFAIK there's no static default for Net Serialize, just the optional override. At least there isn't a serialize function that takes a PackageMap which you need for GUID's

jolly siren
#

okay cool, makes sense. Thanks for the help guys

jolly siren
#

When I serialize my struct myself it shows as a single property when network profiling, but when I let the engine do it it shows many of the members of the struct individually.

#

I wonder why that is

chrome bay
#

It just serializes as a blob so it doesn't have any property headers etc.

jolly siren
#

Makes sense, I somehow managed to make it 3 bytes bigger though

chrome bay
#

Yeah that's pretty common, it'll always send everything you serialize

#

The only real reason to use NetSerialize() is if you absolutely need replication of the struct to be atomic or if you can pack it smaller

pallid mesa
chrome bay
#

As in whenever you receive an update, you can guarantee all properties are up-to-date

#

Or at least, you can garauntee that the struct won't be in a state it was never in server-side

#

Default serialization doesn't give you that garauntee

pallid mesa
#

right

#

thanks :)

#

so essentially, partially "updated" due to net priorisation?

verbal tendon
# pallid mesa so essentially, partially "updated" due to net priorisation?

Yes and no. It's the core of how the Unreal networking is setup. All replication is load balanced, priority just means it's less frequently out of sync with the server as it'll be updated more often. You can't increase net priority to a point where it would eliminate the underlying properties of the system.

chrome bay
#

It's more of a packet loss issue

pallid mesa
#

totally lost? won't it be received at some point?

chrome bay
#

You might receive one change, but not the next, but the one after

verbal tendon
#

Think of it like this

chrome bay
#

If those changes touch different properties, the struct could be in a state client side that never existed server side

pallid mesa
#

yeap I get that, but the client will receive the server struct at some point, right?

verbal tendon
#

At some point, yes

chrome bay
#

yeah it will update eventually

verbal tendon
#

There's no guarantee for when that point is and in which order the various properties will be synch'd

pallid mesa
#

oki, so atomicity basically ensures that updates will come to the client all together

chrome bay
#

yep

pallid mesa
#

but i suspect this atomicity introduces some extra overhead?

#

yes, defo I mean

#

xD

verbal tendon
#

Yup 🙂

chrome bay
#

Yeah, generally it's more costly because the whole thing has to be sent rather than deltas

pallid mesa
#

oki perfect, thank you :)

chrome bay
#

Bit of a head scratcher when it happens still

#

But just have to be mindful of it

pallid mesa
#

Yeah It's expected

chrome bay
#

If all properties are updated in the same network frame, that's fine ofc

pallid mesa
#

I didn't know that implementing NetSerialize() ensured atomicity :0

chrome bay
#

yeah, well everything you write into the archive is sent

#

if you did your own internal delta serialization, you'd have the same problem

#

any packet loss between deltas could incur that issue

#

Unless the engine had some sort of buffering system that only applied packets in order and queued them, but it doesn't - presumably would be uber costly and add more latency

shadow aurora
#

Okay so my gamemode has a variable number of people in it (on each team) that sort of drop in on-start. What sort of options do I have for evenly spacing players out around player starts? Because I don't want to have a player start for each person, and if I don't do that then sometimes players will spawn basically on top of each other which isn't great.

#

My initial thought was something along these lines, where I calculate x number of spawn points around a player start with a radius determined by the number of players and then spawn them there.

chrome bay
#

You are supposed to have a PlayerStart for each person, that's how it works

#

You just choose one when spawning a player

#

The point of the playerstart is to garauntee nothing will intersect when spawning

shadow aurora
#

Ahhh, so in games where the match size is variable, would the best approach be to dynamically spawn in the correct number of player starts?

chrome bay
#

You don't, you just put in the maximum you could need into the level

#

You can spawn them at runtime if you want, but the point of them is to be a pre-calculated spawn position

shadow aurora
#

Hmmm okay I'll have to think on that a bit

fluid summit
lost inlet
#

well if allowing the client to move pawns is not particularly damaging to gameplay then it should be fine

#

but you'll have to build something to allow that sort of control

fluid summit
#

yeah, as long as the burden is not on the server side, those pawns are just for visuals. i'm going to check what can be done

lyric skiff
#

Simply put I want to hide this particular pawns health bar when i'm possessing that pawn, this works to hide it but doing the reverse does not work. ie unpossessing does not bring it back. any input is appreciated

#

I would like it to function normally for other players who are not possessing that pawn

sinful tree
# lyric skiff Simply put I want to hide this particular pawns health bar when i'm possessing t...

The Possess and Unpossess events only run on the server and as such, there's no point in sending RPCs to start with (ie. get rid of the first events called directly after the Possess / Unposses)
The unpossess part doesn't work because the client likely only had ownership while it was possessing the pawn, and once unpossessed, that ownership was lost, so the RPC won't properly fire. This means you want to perform the visibility change prior to the unpossess.

dull tinsel
#

Anyone have any idea what would cause this? [0303/002355.674:ERROR:network_service_instance_impl.cc(263)] Network service crashed, restarting service.
[0303/002701.225:WARNING:dns_config_service_win.cc(700)] Failed to read DnsConfig.
[0303/002701.228:WARNING:dns_config_service_win.cc(700)] Failed to read DnsConfig.
[0303/002712.447:WARNING:dns_config_service_win.cc(700)] Failed to read DnsConfig.
[0303/002712.449:WARNING:dns_config_service_win.cc(700)] Failed to read DnsConfig.

#

Steam session is failing to connect when I try to host a game

lyric skiff
#

k that worked thank you

modest mountain
#

Hey guys we've got a weird problem, in our multiplayer game our first person animations are playing on the server fine - but our third person animations aren't playing at all. It's firing in simulation, you can see something is happening - but the animation itself isn't playing.

edgy flower
#

and only one of my characters spawn

dark edge
#

@shadow aurora you can just override choose start position, you don't need to use an actor for the start location

mystic saddle
#

i want to get the email of the player or his unique id in order to know the player and get him from my database how can I do that ?

elder sage
# shadow aurora Ahhh, so in games where the match size is variable, would the best approach be t...

you can use however many player starts you want, including just one, and it won't cause any issues when spawning multiple players at a time. If you're trying to individually choose which PlayerStart to spawn each pawn on, you should override FindPlayerStart in the GameMode and then set it up to determine the appropriate player start with whatever method you'd like. Without overriding, it's just random

somber glade
#

Can we use built in unreal voice system or 'advanced voice' provided by advanced sessions for voice chat on a local dedicated server (one running on the local lan, everything still has internet access if relevant). I'm trying to get this setup for a couple Quests, and running into issues. The dedicated server is working without problem. We've added these entries: ```[Voice]
bEnabled=true

[OnlineSubsystem]
DefaultPlatformService=Oculus
bHasVoiceEnabled=true``` I am going to try it with NULL instead of Oculus just to see if it makes a difference, I previously didn't have that line in there. And we've tried it both with pushtotalk=false and =true. I've tried it with and without setting up a voip talker. We've requested android permissions for record audio and allowed that in the HMD. Nothing is coming out either headset. If anyone has been successful setting this up with a dedicated server, I'd appreciate any information. What google has told me is that some people mentioned that it worked for them with a listen server, but then it wouldn't work on a dedicated server. Then came that dreaded 'oh I fixed it' message and it's been years of silence with no further explanation. This is 4.26

upbeat basin
#

So just want to confirm, my replicated variable on gamestate may not be replicated yet on the construct of a widget that's added to the viewport on player controller beginplay, right? So I should be sure the value is replicated before using it?

somber glade
#

Yes there may be a delay between when it is set and when the client receives it. We just ran into that issue where we set a variable on the server and then tried to run a function on the client for a visual thing and the client didn't have the replicated variable right away. Even in a lan setting which is going to be faster than across the internet.

elder sage
upbeat basin
elder sage
#

I'll make an example

upbeat basin
#

I guess I get your point, my variable is basically gamemodes, but as an enum so that I don't have reference to the class itself, whenever I want to do something gamemode specific. I guess for your example I could set it on beginplay by getting the current class to set both server and client and let the server correct it, if necessary

elder sage
#

specifically if you need to access the value immediately or you want to ensure that no network corrections happen you'd do what I'll show you here

#

this will always be corrected because the server is authoritative

#

this will also be corrected because the client may not know its value has been set before that value is used by the client, causing desync

#

this is the "best of both worlds" approach, as the client will set its own value, as well as telling the server to set the value. The client will be able to access that value before it replicates, and the server will not correct the client as the values are the same

#

does that answer your question @upbeat basin

upbeat basin
past seal
#

hi guys im trying to make a player ignore other players collision when it dies so that they can walk through. The gamestate is notified by a delegate when a player dies so i thought i could use that but it doesnt seem to happen on server or client at all.

glossy veldt
#

Hey guys i have thr following problem. In my Multiplayer FPS if the listen server character spawns clients cannot hit him, but after he moves his character they can. Server cannhit just fine even if he has not moved yet.

#

@past seal i am not sure what you want to achieve

past seal
#

When a player's hp drops to zero i want other players to ignore it basically

#

so they can walk through that player

glossy veldt
#

Then you should disable collision on the capsule after the character dies. I am not sure how your setup is but you should not need to go through the game state

past seal
#

I made a new object channel called "Ghost" and i made the player capsulecollision and mesh ignore ghost object types collision. Then when the player dies i set collision respone to Pawns to be ignore and their objecttype to be ghost

glossy veldt
#

And on the mesh of course

kindred widget
#

Yeah, Gamestate doesn't need to be involved in this in any way.

glossy veldt
#

I think it woulf be easier if you unpossess the character and spawn a special ghost character for your player. Or a spectator pawn if they should be able to fly trough the map.

past seal
#

i guess, its just that i use a delegate from code that gets called when the HP goes below zero. this delegate can be called anywhere its just that i need to have access to all players

kindred widget
#

All characters don't need to care if one died.

past seal
#

i have a spectator pawn, its just that i dont want the actual mesh to be destroyed. i just want it to ignore collisions

#

but the collision didn't replicate when i tried doing it in the playerBP

glossy veldt
#

If you unpossess the mesh wont get destroyed. You can then make it a ragdoll for example

kindred widget
#

CharacterA gets shot, CharacterA takes damage, CharacterA checks it's health, if health below or equal zero, play death function. Death function sets mesh collisions etc, sets replicated property to notify client instances that it's dead, OnRep of those instances sets the same collision properties and states. Now CharacterB who has had no idea any of this could ever happen can walk through CharacterA

past seal
past seal
glossy veldt
#

Hmm then you have to follow what Authaer wrote. Thats basically how i would do it

past seal
#

ty guys 😄

glossy veldt
#

No problem

#

@kindred widget any idea about my question?

kindred widget
#

Not sure, that's an odd one. Do you have any sort of validation code running that checks if hits are valid or?

glossy veldt
#

Yeah. I have

#

I guess the listen servers position does not get replicated initially but i dont know why

kindred widget
#

Might try just returning true in it to test if that is the cause first.

past seal
glossy veldt
#

Aight eill try later when i am at home

#

I will try that later thanks Tobias

peak sentinel
#

Hey sorry for necro but since you're active on #cpp I thought I could ask now, is that 'bolt cycle' state predicted? If yes, how to handle desync on server since after bolt cycle player can shoot the weapon and muzzle location/rotation can be different between server and client due to bolt cycle animation

chrome bay
#

Kind of. It's the same state-machine system the shooter weapons use, so we just make efforts to keep them in sync or correct them if it somehow goes wrong. Wouldn't do it this way out of choice though, the shooter game weapon implementation sucks a lot.

peak sentinel
#

Alright, thanks

thorny saddle
#

hey folks

#

in MMO game

#

how can save current data in ue4?

#

i mean when MMO server restart or get some update

#

the data saved

#

like RUST game

#

or conan

#

how they save this data?

#

like building

#

player lvl

#

ownerships

#

clans

#

inventory

#

chest

#

any idea?

chrome bay
#

Pay to host a persistent data server somewhere that stores this data, get your game to talk to it.

kindred widget
#

Generally speaking, the knowledge of handling backend databases comes with the territory of knowing how to implement the framework. Most of which has nothing to do with Unreal. You can sort of fake this in Unreal without a backend using SaveGame files as long as all of your servers run on the same system.

#

There is no difference between multiplayer and singleplayer data saving. It's all the same, just depends on where you need to save what. If you're unfimiliar with SaveGame objects, I'd check them out in a non multiplayer manner.

thorny saddle
#

not ue4 save

#

i know api

#

i can code django

#

but i don't know how can recognize this player is who in multiplayer

#

you know what i mean ?

chrome bay
#

Depends. If you have your own database you probably need your own player account system.

#

Sometimes it's sufficient to use the same unique ID as the user account from whatever other online service you are using, e.g. steam

#

But if it's cross-platform, you need your own user database.

thorny saddle
#

and can use this id on ue4?

chrome bay
#

Steam has a unique ID per account yes

thorny saddle
#

or its private id

chrome bay
#

You can

#

But obviously if you want to use a different platform as well, it won't work

thorny saddle
#

but if i have my own acc system i can even cross platform it

#

yes?

chrome bay
#

Yup

#

You would likely have to have your own

kindred widget
#

I do not miss web development classes.

chrome bay
#

And building that kind of system and infrastructure is outside the scope of UE / this discord

thorny saddle
#

i know

#

ue4 can request to api?

#

i mean cpp can

#

but ue4 allow us to use it?

chrome bay
#

sure

#

Can do whatever you want

thorny saddle
#

nice

#

thanks 😁

thin stratus
#

I mean, Terms and Conditions apply :D

kindred widget
#

If it can be dreamed in 1s and 0s, you can do it.

burnt tundra
#

Hi guys trying to follow tuts steam integration why is this error popping up I don't understand on "servertravel" parameter

pallid mesa
#

or do I need to implement NetSerialize() to ensure atomicity and thus onreps can be trusted?

chrome bay
#

the latter

#

Onrep is called whenever a change is received

pallid mesa
#

Thank you James! Makes sense

verbal tendon
# burnt tundra

You probably want to brush up on C++ basics, you're using ' which is for single characters. " is for string

ancient badge
#

Hello, i hope someone can help me.
I try to explain what i have setup.
I have 9 Fields, like tic-tac-toe the game.
I put a card in the middle top and one in the middle left. That cards are green. When i put a Red Card in the upper left corner the other two cards should turn red.
But for some reason only the green card on the middle left turns red, but onyl for the client. For the Server (whos a player) both turn red.

How the change for the color works is same for each field.

I tested it on other field too. Same problem. Only the second field gets changed.
I tested if maybe the specific field in the middle top row is faulty, but if i only try to change that it works.

If you like you can come too my twitch stream and i show you.

shut gyro
#

Is there a way to detect if the host (listne server) has force quit a match?

ashen stone
#

How do i run a game in dedicated server mode?

#

Do i need to build unreal from source?

chrome bay
#

yes

ashen stone
#

is not running with ~-server~ working?

finite kettle
#

Hello,
if I have two actors where one cannot exist without the other, can I somehow force the engine to always replicate them together over the network? Thanks 🙂

chrome bay
#

If you want to build a dedicated server to run outside of the editor, you have to build the engine from source

#

Since the engine itself has to be compiled in Server mode.

ashen stone
#

this is sad

elder sage
hallow acorn
#

hey guys, hope everyone's day is going great 💙 wanted to ask, I'm trying from one player POV force another player move near him (somewhat like a charm) but SimpleMoveToLocation seems to be causing issues (for example, the affected player moves suuuuuper slow, even though it's speed isn't chaning) that can only be checked on Build.. do you guys got any other method in mind to achieve the same thing? thanks! 💜

elder sage
#

you're moving it from the host, right?

#

if it seems like the actor's position is being corrected, you may need to adjust where you're running that from

hallow acorn
elder sage
#

I can't remember if multicasts do that

hallow acorn
#

yup, multicast calls on server and on every client

elder sage
#

is the mulitcast being called by the server?

#

clients can't multicast

hallow acorn
elder sage
#

sorry that was for the other thing

hallow acorn
#

hahah np

elder sage
#

does it do something different, depending on which PIE's version of an actor it happens to?

#

I've ran into something where either the host or client works fine and the other does not work

hallow acorn
#

that's the weird thing.. on PIE it works perfect but on Build is where the bug happens

elder sage
#

have you tested it with every combination of client and server?

#

you need to run 3 viewports and do server -> client, client -> server, client -> client

#

I'm trying to remember what exactly caused an issue like that for me

#

it was something relating to the players not all logging in at once, because that's the main difference between PIE and a package

#

I've never used AIMoveTo for something that isn't explicitly an NPC, so it might just be something with that. Maybe try a pawn that isn'

#

t controlled by a player controller as well?

hallow acorn
hallow acorn
#

u got any suggestion on how do something similar?

elder sage
#

no tbh

#

I think what you're doing is fine, but if it were me I'd try to narrow down the issue as much as possible

hallow acorn
#

thanks anyway haha 💙 at least im sure I'm not crazy haha

elder sage
#

troubleshooting 101 is making sure it's not your character controller overriding it, probably

plush otter
#

the key status is local only right?

elder sage
plush otter
#

at some point I want the server instance to know if the local controller has a certain key down

elder sage
#

you'd make a custom event or function that's called by the server to run on the owning client. Just use that to return whether it's held or not

#

would it not be on the client?

#

inputs aren't replicated so the client has to be called to test for it

plush otter
#

but in this case how would the server know the return value of IsM1Held

elder sage
#

it seems bootleg but I think this is most efficient?

plush otter
#

yeah I think it could work. Or maybe when client presses and releases, send rpc to server.

elder sage
#

it depends on how often that would happen honestly

#

you wouldn't want to constantly tell the server that it's held if it doesn't matter

plush otter
#

yeah

#

I need this with a charging skill.

elder sage
#

like if you're seeing if you're holding forward during a crouch to produce a slide, do not rpc every time "forward" is pressed

#

if it's a key that's used less often, it does not matter

plush otter
#

ah it's just the key to trigger that skill

#

say C key

elder sage
#

so you're checking if the key is held though?

plush otter
#

not something so often like forward

#

yes

elder sage
#

but you're activating it with an event, right?

#

just plug the input event into an rpc and have another on "released" then

plush otter
#

right

elder sage
#

I'm suddenly forgetting how to do it, but you can plug multiple exec pins into one event and control a bool with a flow control node

#

may not actually be more efficient though

#

well either way you would just do something like this

plush otter
#

sure

#

can get it to work. thanks

elder sage
finite kettle
elder sage
#

otherwise I don't really get what you're trying to do

finite kettle
#

But that doesn't solve anything, because they don't have to be replicated in the same packet. I need them to go "together" over the network

elder sage
#

I guess I don't understand what could be so sensitive that it requires it to happen at literally the same time

#

if anything, you should build it in a way that has a contingency for if a packet drops or something

finite kettle
#

Yes, but in this case that is exactly what I wanted to avoid 😄 Thanks anyway. I think I've already found my answer => it's not possible https://forums.unrealengine.com/t/replicate-multiple-actors-in-order-or-at-once/149272

elder sage
#

basically what you're asking for would be simultaneous computation / sending multiple things at once over a network stream, and that just isn't technologically feasible

#

I'd say that whatever it is, there's probably a way around such a strict requirement

nimble trellis
#

Ok so I have a game mode that is incrementing an integer variable of its own by 1 every tick. And all of the clients are updating their own integer every tick. The idea was, if the indexes never matched, it'd mean there was network loss/ping issues or packets being dropped or something? But other than at the very beginning, they stay in sync no matter what I do. Even if I use Net PktLag or Net PktLoss they permanently stay in sync when i fully expected them to break. Any ideas? I was in the process of doing rollback netcode for an FPS game and I figured I wanted to get this desync stuff working first. Any ideas why they ARENT desyncing?

summer tide
#

What are some network commands to network perf or profile it?

sinful tree
#

You may want to ask for assistance in #ue4-general or #ue5-general. This channel is for multiplayer related questions where your issue appears to be with launching or setting up the engine itself.

ashen stone
#

Sorry

#

Is calling AddMovementInput on PlayerController worse than on Character?

#

Can it add rubberbanding?

ashen stone
#

The problems was on RVO AVOIDANCE..

undone halo
#

anyone have helpful sources on client side prediction for blueprints?
currently my problem is using a timeline to apply an offset on a mesh. client offset is not smooth.

ashen stone
#

Just use gaeplay ability system

#

gameplay ability system

mellow cipher
#

LogOnlineSession: Warning: STEAM: Failed to initialize game server with Steam!Has anyone gotten this issue when trying to host in UE5 Preview 1? Starting to investigate it but just checking if this is a known issue

mellow cipher
#

Update, adding this to defaultengine.ini fixes it:

bInitServerOnClient=true```
Seems like the lobby/internet switch acts differently.

UE4.26:
```if (!NewSessionSettings.bIsLANMatch)
        {
            if (Session->SessionSettings.bUsesPresence)
            {
                Result = CreateLobbySession(HostingPlayerNum, Session);
            }
            else
            {
                Result = CreateInternetSession(HostingPlayerNum, Session);
            }
        }```

UE5 Preview 1:
```if (!NewSessionSettings.bIsLANMatch)
        {
            if (Session->SessionSettings.bUseLobbiesIfAvailable)
            {
                Result = CreateLobbySession(HostingPlayerNum, Session);
            }
            else
            {
                Result = CreateInternetSession(HostingPlayerNum, Session);
            }
        }```
mellow cipher
#

What I've ended up doing is instead of that defaultengine change, I've just added bUseLobbiesIfAvailable to AdvancedSession's CreateSession so I can go back to using lobbies. Hopefully that helps anyone if they need to search that error.

Update: Apparently the updated AdvancedSessions has this bool already

undone halo
eternal canyon
undone halo
#

like for example a sword moving to a certain location?

#

oh nvm let me test some things

nimble trellis
#

Does anybody have any advice for someone whos at wits end trying to get basic client side prediction/server reconciliation to work in UE4 for an FPS game? I've read pretty much every source I can get my hands on, and I'm still struggling very badly. I've had to redo this about 30 times at this point :c

#

I know roughly what I need to do in pseudocode but am struggling very hard with the semantics of applying it to UE4/UE5.

ashen stone
undone halo
ashen stone
#

What are u tryng to do?

undone halo
#

trying to spawn an actor and move it to a location a character line traces to

#

it works but on the client its not smooth which is a given because i don't know how to work in client prediction

terse talon
undone halo
plush otter
#

With any lag simulated.

livid tangle
#

I need help with something. In the game that im working on, i made a spectating widget, but the game is multiplayer and when one person dies

#

it gives it to both people

vast ledge
#

what's the best way to give a player enhanced input context? (both way to call it and best class location)

gritty pelican
#

hello, can i skip Actor replication for some clients, uses AActor::IsNetRelevantFor?

#

for example, i won't create copy of projectile for local player, only for remote and server players

sinful tree
livid tangle
sinful tree
#

Perhaps change your Die event to not be Run On Client, and create a separate Run On Client event that you can call from Die that will create and display the widget. So then it would go something like:
Overlap > HasAuthority (Authority) > Cast > Die
---> "Die" Event on Character (will be running on the server still) > "DisplayDieScreen Event (Run On Client)" > Spawn & Possess your Spectator Character
---> "DisplayDieScreenEvent" > Create Widget, Add Widget to Viewport

dense sundial
#

Why might one extend the character movement controller vs using custom movement modes for a networked game?

terse talon
thin stratus
# dense sundial Why might one extend the character movement controller vs using custom movement ...

Generally speaking, extending the CMC (CharacterMovementComponent) is required whenever you need things to be predicted for the local client.
A custom MovementMode is just a part of the CMC, which can and cannot work without extending the CMC.
If the MovementMode you make isn't relying on input of the Player, but is rather naturally entered (e.g. by walking into an overlap), as well as naturally left (e.g. by moving out of an overlap), it probably works just fine.
If however the MovementMode is entered by key presses (e.g. Space to Dash), then you need to do a bit more than just add a custom MovementMode, so that the Player, when replaying moves, knows that they dashed etc.

#

But that's a very general answer and as with all things, it depends on what you are doing

wild patio
#

Does anyone know if the built in Character class in UE4 has special behavior for replicating the player mesh?

#

I was having the craziest replication issues while trying to replicate some bone positioning on client and server. The character player mesh was jittering between proper position on server, and some previous position. I added in a new player mesh and had the exact same code operate on that mesh, issues completely gone.

#

I spent about an entire week working on every possible solution, and the only thought I have is that the world transform of the player mesh in character is somehow being handled by the class

#

In a way that any other mesh on the actor isnt

#

I tried changing engine versions to see if it was specific to 4.22. but exists in 4.26 also. i suppose i could file a bug report, but thought I'd ask here

dense sundial
# thin stratus Generally speaking, extending the CMC (CharacterMovement**Component**) is requir...

Thank you for this! I guess I'm still wrapping my head around the correct way that custom movement is handled generally. I've seen the approach of creating an overridden version of Saved Moves and Prediction Data and then using movement modes to handle states for syncing appropriately but I thought that these could work independently of each other for a bit there (as in an either or sort of thing) but I think I get now that these really are 2 sides of the same coin

dawn ledge
#

How do you setup a local multiplayer game? I want players to be able to press start on their controllers as soon as they are plugged in. Am I just suppose to spawn a bunch of player controllers and keep them alive even if they arent playing?

dark edge
#

Or create player. Something like that

dawn ledge
#

Yeah I know how to create a player. I need to know when

thin stratus
#

In BPs I would probably pre-spawn the Player(Controllers) and then listen for Inputs in there

#

In C++ you can probably listen to the Inputs without a PlayerController, but never done that

wild patio
#

is there no event for when a new input device is detected?

dawn ledge
#

Im in c++. I found the core delegate for controller connection changes. But it doesnt provide anything for connected controllers prior to game launch

thin stratus
#

Can't you grab the input from the ViewportClient?

#

Not sure if that requires a PC

plush otter
#

I've just started looking into character movement component for implementing smooth character movement.

#

Also, the root motion task doesn't work with passive movement like server initiated knockback.

terse talon
terse talon
terse talon
#

But just for that

plush otter
terse talon
#

A few cases I am using currently are:
Knockback
Dodge Roll
Dashing
Moving closer to target when attacking

#

All of those I've used the constant force one if I am not mistaken, tried others and they felt problematic in some situations

plush otter
#

Yeah. I hope they can be fixed. The functionality is very useful.

thorny saddle
#

hey folks

#

i just wanna get some advice from you

#

how can make clan

#

in mmo server

#

where should this info and data stored

#

is it ok to have an actor on map and it replicate info to all

#

or any better idea?

shell forum
#

Depends on how many clans and players you have

#

If you have 1000s of clans in a true mmo then probably better to store it on a server database and only load when necessary.

thorny saddle
thorny saddle
#

i mean UFUNCTION(Server) can't return anything

#

it just can be void

wild patio
#

@thorny saddle building the server for an MMO, and then the client for an MMO is a massive amount of work. if you wonder at some point why you aren't getting responses, it's because the answers you need are found in multiple books worth know knowledge that just simply can't be covered in the scope of this channel.

#

following a tutorial like this first is a good start: https://www.youtube.com/watch?v=PAs-9KGlVJc

In this training series we will be taking a look at a step by step process to build an MMO in UE4. MMO's are very complex and take dozens of people working together to complete, but by the end of this multi-part training series you will have a simple MMO demo that you can package up and play with friends. You will also have acquired a basic kn...

▶ Play video
#

once you've built the beginning of a prototype, it should be much more clear what you need to know to take it to the next level.

dawn ledge
#

I think I am just suppose to create all the player controllers that are allowed to play locally at once, even if there is no physical controller connected

plucky prawn
#

is there a correct way to have replicated spectator pawns? im using ASpectatorPawn but im thinking of just using my mob/ACharacter class instead

plush otter
#

Hello, I tried to copy and test Dodge function of AdvancedMovementComponent and see the exact problem mentioned in this issue section

#

Is there a way to fix this now?

#

The way it's done is to set Velocity in the OnMovementUpdated function.

#

but apparently simulated proxies don't handle the end point well

terse talon
nimble trellis
#

Would anybody have any advice for how to implement rollback netcode in UE4/UE5 in BP? In it's absolute most basic of basic forms? And ideally, it would be a client-server model, not P2P.

plush otter
mellow solstice
#

Hello, I implemented the in-memory streaming for doing a kill camera however the vehicles are jittering in the replay. My implementation is a custom movement component based on the ChaosWheeledVehicleComponent which replicates input given by the user and simulates forces directly on the physics body. I am slighly at loss how to improve this, would I need to predict/interpolate/smooth movement?

thin stratus
thin stratus
#

it's either Listen or Dedicated Server. Which both are Client/Server models

#

I'm not sure how easy it is to implement Rollback stuff in pure BPs.

#

In theory, without spending too much time thinking about any issues that could arise, I would think it's possible.
But BPs have a very limit access to data types and methods of those. E.g. lots of stuff the CMC does for rollback/correction uses datastructures that aren't available to BPs, but maybe they can be worked around or so.

thin stratus
mellow solstice
# thin stratus So this is your custom implementation for replay or does it use UEs code?
plush otter
thin stratus
plush otter
#

all of them are causing roll back on simulated proxies. I guess it's by the nature of their interpolation method.

thin stratus
thin stratus
#

Lemme read up on this for a second

#

Uuh level duplication

#

How much RAM do we need for our game?
YES

mellow solstice
thin stratus
#

It’s also worth noting that when calling these major tasks (SetUpKillcam, KillcamStart, ShowKillcamToUser, and HideKillcamFromUser), they are deferred until the next tick using a task queue.

#

Can have a lot of reasons

#

Performance or making sure the last frame fully ended

mellow solstice
thin stratus
#

It’s also worth noting that the original implementation of this feature was handled by duplicating the entire UWorld, with replays being played back in the duplicated world. This is the same method used by Unreal Tournament.

#

Yo, whole UWorld. Gotta love early UT code

#

Okay, so what I see in your video is basically the duplicated level (aka fancy level streaming), with the real level briefly hidden.

#

And then playing back whatever was recorded on the Cars

#

How exactly are you feeding in the data to fake-drive the cars? Does the provided system do that for you?

#
void UKillcamPlayback::QueueTaskForNextTick(const FKillcamTaskDelegate& Delegate)
{
    // Can't add to the task list while we're  processing tasks.
    check(!bIsRunningTasks);
    DeferredDelegatesForNextTick.Emplace(Delegate);
}
#

The comment answers the "why having to offset it by a frame"

mellow solstice
thin stratus
#
    if (GameInstance->GetWorldContext() != nullptr && GameInstance->GetWorldContext()->WorldType == EWorldType::PIE)
    {
        UE_LOG(LogKillcam, Log, TEXT("UKillcamPlayback::PlayKillcamReplay: Killcam playback is not supported for PIE."));
        return;
    }

#

Sad

#

Also, unrelated. FString(__FUNCTION__) is handy if you don't want to type that by yourself

#

And yes, I know, this is Epic's code, not yours

nimble trellis
#

@thin stratus thank you. a lot of people have been telling me it couldnt be done in BP. and ive been at this for weeks, binging and reading as much as i can on rollback netcode and struggling horribly with it. sorta just reached a dead end

thin stratus
#

Aka, even if you can pull it off, it might run like dogsh't

nimble trellis
#

i can explain each step (i believe?) in pseudocode, but i just dont know how to apply it in practice. ive tried using structs to store locations/velocities, or even input bools, but nada.

#

how is a struct in BP different from a struct in c++?

thin stratus
#

You can't override or implement functions for example

#

E.g. NetSerialize

nimble trellis
#

cant i just make my own inferior versions of the functions i would need? and just play it by ear and see how it runs?

#

or would that just be harder than learning how to do it in c++ at that point

thin stratus
#

Well, yes and no

#

New, generic functions you can probably make on your own in some function library

nimble trellis
#

like, ive used UE for a very long time, but i only ever went into c++ when i ABSOLUTELY had to.

thin stratus
#

But things like NetSerialize are overrides

#

You can't do that outside of c++ basically

#

But that's also more for performance and stuff

#

So it's not required, but kinda is

nimble trellis
#

i see. i actually even checked out that resource that the UE devs mentioned in that network fundamentals vid the other night. i was hoping they woulda covered this topic, but apparently it was too advanced for the stream

thin stratus
#

It's generally adviced to do this in C++, due to the amount of things you simply can't do in BPs

nimble trellis
#

they mentioned you in it. the ven diagram was pretty helpful to visulize things that you made

thin stratus
#

The VEN Diagram is not mine :P the Compendium just includes it to be comprehensive. There is a source link to it.

#

But yeah, thanks

nimble trellis
#

would you still advise me if im 10000% more comfortable in BP? i mean the way i see it, if im strugglign to even get this pieced together in BP.. an environemnt im WAY more comfortable in, arent i basically doomed if i try this in c++?

thin stratus
#

@mellow solstice Are you sure the code in the MovementComponent is the exactly same running when playing? I assume you aren't possessing the Car when replaying, so you probably aren't an Autonomous Proxy for it?

#

I can't really help despite pointing you to breakpointing the code or printing some stuff to see what actually happens in the movementcomponent when replaying

#

I know the CMC has custom Replay interpolation

thin stratus
#

BPs are very basic and originally meant to help designers create quick systems without the need of a C++ programmer.
They evolved into some mess that can do a lot of things, but has a lot of limits that some people reach sooner than later.
Multiplayer is one of the bigger limits, where BPs just don't have the required resources to create everything you need.

#

I basically would not advise creating a complex multiplayer project without knowing C++

mellow solstice
nimble trellis
#

i mean the problem is, at least in BP, id be likely to follow along with what you were saying. but in c++, even if you were on a call with me/screensharing, i think the sheer scale of doing this on c++ would basically doom me. i know VERY basic c++, but i doubt i knwo enough to make a rollback system in c++

#

and certaintly not well enough to understand GGPO

thin stratus
thin stratus
#

Saying "I can't do this in C++ right about now, cause I don't know C++, so I have to do it in BPs." doens't make this any more possible than it is

#

The Engine is a C++ engine with BP support. If you want to make a game as a programmer, C++ is more or less a requirement

#

If you don't have the skillset yet, sit down and learn it

nimble trellis
#

well i feel like i have been learning a lot the last few days about rollback netcode and netcode in a more general sense. im just worried id be spreading myself a bit thin is all

thin stratus
#

There are tutorials, courses, etc. to learn ue4 c++

mellow solstice
thin stratus
#

Well I can learn a lot about colors and yet I can't paint

#

You gotta learn how to paint to use the color knowledge

#

So you gotta learn how to do C++ to use the netcode rollback knowledge

#

But again, amybe it's possible in BPs

#

I would not try it though

nimble trellis
#

hm. i suppose youre right. it just sucks. my best friend was trying to talk me out of this from the start basically saying "if you are trying to make netcode even remotely good enough for a fast paced FPS, GL HF cya in 5 years LOL"

#

im starting to see why he said that

thin stratus
#

Yeah, this is already tough for peeps that can use C++

#

You can learn a lot via UnrealTournament or by researching other UE shooters, like Valorant

#

But even they had to change a lot about the Engine to get everything working perfectly

#

And they are a team of veteran defs with probably more than one C++ capable programmer :P

thin stratus
nimble trellis
#

yeah.. well thats pretty demoralizing, but i appreciate the brutally honest answer

thin stratus
#

Unless one is talking F1 levels of precision when driving it