#multiplayer

1 messages Β· Page 127 of 1

teal frost
#

That part I'm prob doing wrong

fair latch
#

If the camera is the child of the actor it will get rotated too

#

You might be talking about something different

#

U r probably thingking of control rotation

teal frost
#

What do you mean?

fair latch
#

Spawn pawn, set rotation, get z rotation and apply it on the client z.control rotstion

#

U can look it up

#

Or better yet, try to change your character control rotation and see if thsts what you mean by "camera staying in place"

teal frost
fair latch
#

If you actually rotate the actor there isnt anything i can think of that make the camera stay in its place if its the child of the rotated actor

teal frost
#

Same which is why I'm here lol

#

I've been stuck on this prioritizing other things because of it for like a week now

fair latch
#

I still think you are thingking of the control rotation, not soo much that the camera world transform stay unchanged

smoky vessel
#

One more question, this one is not related to the asset, but as someone who knows replication well, can you provide some guidance? I started the game on two clients. The first client starts moving, and the second one follows, but the second one collides with the first as if it's a ghost. It feels like the server understands that the cars aren't moving, but the clients don't. Meanwhile, the HUD displays that it's a sports car. Question: How to replicate cars? Is there a guide or specific settings to enable for this?

sinful tree
burnt hinge
#

So i was looking at a project from a studio. Most of their server events are set to reliable. Is this good practice?

fair latch
sinful tree
#

Shooting a gun? That should be reliable.

#

Requesting to move an item in an inventory? Reliable.

sinful tree
#

Wanting to allow a client to tell the server where to move an actor on tick? Probably shouldn't be reliable on account that you're sending updates every frame anyway.

burnt hinge
#

My print strings always show client 0 only for some reason

stuck cloud
#

How would I go about showing the view of one client within another client (including some HUD elements)? Can I access HUDs / Cameras of other online-clients locally?

#

Since what I'm trying to do is turn based, I'd like to show the view from the momentary player to everyone

latent heart
#

You cannot.

#

You would have to share enough data about the players to simulate the other player's huds.

#

You can do this, generally, by separating out the "player" from the "hud" and using the huds as a viewer for a given player, not for the local player.

#

If you have logic or data stored in the huds, you're doing it wrong.

stuck cloud
#

Ok thx. The data is within the PlayerState/GameState, so that should work. The cameras are accessible tho?

dark parcel
#

Define what you mean by access, I feel like you get wrong idea of multiplayer

#

Every machine run their own instance

#

And each machine have their version of the actor/ camera

stuck cloud
#

I'd like to show to the local player, the camera that is connected to a remotely connected client.

latent heart
dark parcel
#

And what's the idea of "accessing the camera"? Like a screen grab? The camera is just a comp with setting and transform. The rendering is done by the renderer

latent heart
#

Then replicate that data to the clients.

stuck cloud
#

I think I have to create some kind of Spectator Player and simulate camera movement and HUD and then show that players view on clients

dark parcel
#

Most you can do is replicate the camera transform like suggested by daekesh. That will simulate what other client sees

stuck cloud
#

Yeah thx for the help

latent heart
#

Can the players move their own cameras?

stuck cloud
#

yeah

latent heart
#

So when a player ends their turn, it shows their viewpoint fullscreen to every other player?

#

That sounds weird.

stuck cloud
#

Yeah, but Im doing this for local multiplayer atm. So each player gets to see their cameras view fullscreen and gets the right InputMapping added when it's their turn. What I want to do in the end is mixed local/online multiplayer. So when the momentary player is not present locally, I'd like to show the view from the player that is playing on another machine.

#

I can send a screen recording, might be easier to understand

stuck cloud
# stuck cloud

So here I'm adding 3 local players and then "ending their turns" which shows the view for the next player

dark parcel
#

You made is sound like online multiplayer

#

Local multiplayer can be viewed as single player and they run using the same instance

stuck cloud
#

Yeah the thing is i want it do be mixed online/local

#

So when the turn is happening on a remote machine, I want to show the remotely connected players view for every machine that is present

dark parcel
#

Have u got split screen working?

stuck cloud
#

yeah

#

here it's splitscreen but goes to shared shared screen once the match starts

#

thats what the custom ViewportClient does (shared screen stuff)

dark parcel
#

Most u can do is replicate the transform of the camera imo

#

Sending image data is not even supported by default, if your idea is to stream what you see to other clients

stuck cloud
#

Ok cool, I think thats what I'm going to do. I'll add a locally connected "spectator" player that will simulate camera and have a HUD and show it in the right moments

dark parcel
#

U can only simulate it , yeah

#

As for the HUD, u will have to recreate it and sync with w.e the other client do

stuck cloud
#

Yeah. Might be nice, since I'm thinking about doing 4v4 and then I'll be able to customize what's shown from the remotly connected players.

#

Thx a lot for the inputs, this helpted a lot! 😊

#

I wonder how kill replay cams or play of the game replays works in online shooters, don't they have to access remote players cams?

dark parcel
#

Not at all

#

Pretty sure they just rewind back time

#

And use previous camera transform

#

As for live spectator mode, that's just a matter of replicating the camera transform

golden nest
#

I have this code. As far as I know, server does not execute rep notify and need to be called explicitly. But where should I call this rep notify? Everytime I update the value on server?

{
    OnPlayerScoreUpdated.Broadcast(PlayerScore);
}
#

Like this?

{
    PlayerScore += Value;
    OnPlayerScoreUpdated.Broadcast(PlayerScore);
}```
#

Or should I call

{
    PlayerScore += Value;
    OnRep_PlayerScoreUpdated(PlayerScore);
}```
hollow eagle
#

either

sinful tree
#

Yep. If you want something to happen when the value changes on the server, you'd have to call it.

golden nest
#

Ok, thanks ❀️

hollow eagle
#

whether you call the OnRep directly or not is really just up to you

gusty slate
#

I've only worked with replication in BP only and there the RepNotify is called automatically after the value changes, that's not the case in c++?

hollow eagle
#

if you're doing more than a simple broadcast in it then calling it directly might be better so you don't have to repeat the logic. But for this? Really doesn't matter.

hollow eagle
golden nest
gusty slate
#

It's called on listen server as well in BP

hollow eagle
#

Yes, that's a BP-only thing.

gusty slate
#

aaah I see

#

Ty

round acorn
#

in a dedicated server setup when I run a Print String on a keyboard event, regardless of which client I use to press the input event, the Print String always says "Client 0". Is this because it's executing on the client and the client, having no awareness of the server on this input event, thinks it's Client 0?

thin stratus
#

Are you testing this in the Editor?

round acorn
#

Yeah

thin stratus
#

In theory it should print Client X with X being the Client Number in the Editor

round acorn
#

yeah it's worrying me

#

I want to see a Client 0 and a Client 1 but they both think they're Client 0

#

I'm running 2 clients in a Play in Editor new window

round acorn
#

I get the reference to self then print the display name here, and you see the display names are different instances of the character blueprint but the print string says Client 0 for both

#

BP0 and BP_C_0 are the display names... which is interesting

#

got 6 instances going, as expected

#

okay yeah it's what I thought. Each client in this setup thinks it's client 0

pseudo kernel
#

Anyone have any good papers/blogs/resources talking about projectile prediction & hit detection.

I've read plenty for hit-scan and while some of them gloss over projectiles, few go into good detail.

Doing a lot of work with trying to get it to feel good for proxy clients, particularly the ones who might be getting visually hit.

frank birch
#

How would you tackle the problem of random? πŸ€”
I don't need an already made implementation, but some logic thinking πŸ€”πŸ€”
To put it somewhat simple, what if I want my character to have a critical hit chance. The random and critical hit are authoritative, but is there a way to "predict" the random crit? πŸ€”

frank birch
#

A seed at the beginning of the universe and hope to keep it in sync? If you desync the server sends you the seed and how many numbers were generated so far?

#

πŸ€”

elder sable
#

Just something deterministic

frank birch
#

You mean that in server Auth you don't even try to predict the crit?

#

Believe it or not, that's enough justification for me πŸ˜›

#

I will do my thing with the fstreamrandom thingy and if one day I need a better random I'll get some cpp implementation and cry about it

hoary spear
#

I'd hate seeing a predictive crit be wrong tho

frank birch
#

Should I grab a cpp generator to begin with? πŸ˜›

frank birch
hoary spear
frank birch
hoary spear
#

I dislike dealing with multiplayer now

frank birch
#

Did you set your tolerance value for hits? Or are you keeping the shooter game default of 200 meters?

#

πŸ‘€

frank birch
#

With midjoins

#

Both local and online

hoary spear
#

im just trying to do lazy predicted timers

#

like, not even trying to actually predict anything

#

just starting local timers

#

but then my setup doesnt work when it's not dedicated server

#

ugh.

#

bad setup, i know i know

quasi tide
#

See, the secret to making multiplayer enjoyable, is to just do co-op games and don't care if people cheat

hoary spear
#

That's probably it

#

we had a grandiouse plan of unique id's and whatnot but wth

#

if ppl wanna cheat, we'll just let 'em

#

wont lose any sleep over it

frank birch
limber gyro
#

has any 1 touched iris? how drastic are the changes to code to make it work? does any 1 have any examples?

hoary spear
#

I believe Kaos* has posted some about it

#

...and it's troubles

#

just search for it in the logs

quasi tide
#

I wouldn't bother with Iris unless you're already pretty experienced. Wait until it's actually stable or at bare minimum, usable to the commoner.

burnt hinge
#

Why do my print strings only show client 0?

elder sable
#

Hi, i have a replicated actor with a beacon client actor as net owner, but my server rpc is not triggered, any idea what did i miss or how to debug this ? I don't have anything in the logs

tall drum
#

Hey

In a replicated actor,
I set a Rep Notify on a struct TileUpdate and it is correctly updated on the client and on the server

However, my gridTiles array with Set array elem does not change the first value in my array on the client but only on the Server. Do you have any idea why?

hoary spear
#

Are you setting it on the server?

tall drum
#

Tile Update is correctly updated on the client and the server
But it does not update the same way for grid tiles (only on server)

hoary spear
#

Who's setting (or adding) to "Grid Tiles"?

tall drum
hoary spear
#

Only server can replicate to clients, so can I assume this is server only code?

tall drum
#

Yes, it is

hoary spear
#

depending on what GridTiles includes of variables , number of elements etc, it could take a while to replicate it

#

especially if it needs to resolve some hard refs along the way

tall drum
#

My purpose is to change one value at specific index tintinthinking

#

Ok, so, I cannot replicate an array? (with 250~ elem) then updating a value at specific

hoary spear
#

You can, it's just hard to say how long it would take

tall drum
#

Oh I see

#

ok

hoary spear
#

250 elements isnt a scary number, but it depends on what the struct contains aswell

#

how do you know it's not being replicated ?

tall drum
#

I am verifying like this
Then I am checking the value on server and on client

I can see on server, the value changed but not on client

#

and this is what my struct contains:

#

The value that I need to update is the tile type (Enum)

polar obsidian
#

Hi, I'm trying to use replication, but I'm having a build error that says it doesn't find the replication function

I have declared the variables and functions as per the first image.
The error is in the second image.

Any ideas what could be wrong?
I tried searching for something on google, but couldn't find something useful.

polar obsidian
tall drum
#

@hoary spear Thank you for your time, I added a delay just for testing purpose and now it is correctly replicated
I have to think about an another way to change/update my value and working with array

compact flame
#

How do i replecate this?

compact flame
#

Does anyone know cuz i cant find out

limber gyro
graceful flame
#

After you set that up you can just replicate a boolean and have it call some event with repnotify like this.

#

There's no need to run anything on tick like how you've got it.

dusty river
#

I'm using the third person template. In the character blueprint I can increment an integer variable and then print it as a string. The variable is set to replicate. If the server increments the integer, the client doesn't see the change. If I set it to RepNotify, the client still doesn't see it, but if I make an OnRep function it can print the integer. πŸ€·β€β™‚οΈ

#

They're separate characters, so they shouldn't(?) share the same variable, but then I don't understand why the client is able to print the server's variable in an OnRep function.

sinful tree
elder sable
#

Hi, Can someone confirm that if i have a Client (AOnlineBeaconClient) and a Player actor with Player->SetOwner(Client); i should be able to use RPC from the Player class ?

elder sable
#

Mhh seems i have 2 differents netconnection, i guess that's why it's not working

hollow eagle
#

I'm not sure what multithreading has to do with network simulation.

#

I mean, sure?

#

Race conditions aren't specific to multithreading

#

You can have a race condition caused by networking, it's a very easy problem to run into. It just doesn't have anything to do with threading.

#

attempting to modify data in two separate operations that have the possibility of that same data being modified between them

chrome onyx
#

My inventories are server authoritative to avoid that kinda situation

hollow eagle
#

which is the bog standard cause of most race conditions

#

being server-authoritative doesn't avoid it

chrome onyx
#

It's not gonna be mt, and if your server validates data (and rejects the bad second command) it'll work

hollow eagle
#

That's still not a solution to race conditions.

#

Race conditions can be "valid" as far as the server is concerned but can result in incorrect behavior or unexpected results on clients.

chrome onyx
#

I mean it kinda doesn't matter in most cases, like if a client clicks "too late" or whatever and it doesn't work, and updates shortly after it's fine

#

The most important thing to keep in mind is that you need to handle essentially any order of packets

hollow eagle
#

Client asks to move item A from slot 1 to slot 2.
Server, at the same time, tries to swap item B from slot 3 to slot 1. Server executes before client.
Result is that item A is not in slot 2, it's in slot 3. And Item B is now in slot 2.

This is technically correct by the rules of the system. The programming error is referring to slots rather than items, but it is still not solved by being server authoritative.

#

The ideal result here is the client's move being rejected outright or item A moving to slot 2.

#

But not having the ideal result is still fully server-authoritative.

chrome onyx
#

Yeah I think both are reasonable

#

But don't end up with deleted items on server

#

Which is the original probelm

hollow eagle
#

Replace what I said with "delete item in slot 1" and you have the same issue

chrome onyx
#

Like both those cases are fine results for bad network conditions/etc

hollow eagle
#

My point is race conditions aren't solved by being server authoritative.

#

They're solved by protecting against race conditions.

chrome onyx
#

He's talking about an item being permanently deleted from swaps, which won't happen if server validates

hollow eagle
#

We have no clue how the inventory mentioned works.

chrome onyx
#

Hahah

hollow eagle
#

If only

hollow eagle
chrome onyx
#

I can say I've shipped more than one title, and I haven't had any deletion issues

hollow eagle
#

Anyway, hard to help without more info about whatever this operation is

#

What data is being sent from client to server

#

What other operations could potentially happen at the same time

#

all stuff that needs to be thought through

#

If you are, like in my example, sending slot numbers rather than referring to specific instances of items then that'd be the first thing to fix - that's fraught with problems.

chrome onyx
#

Here are some options:
Send slot indexes to swap. Server does it if it's valid, done and done. Sometimes clients will get unexpected results if other people are also messing with inventory, but you'll never have an item get overwritten or deleted.

Option 2: client sends slots + items, and if they don't match, it doesn't do the operation. It means sometimes things don't happen for the client, but again, no bad state on the server

hollow eagle
#

Though I have no idea if you are.

chrome onyx
#

Most important is that you don't dupe or delete items on server

#

Everything else is just client state that should be corrected shortly

#

Yeah I'm telling you I've shipped full ass multiplayer games lol

#

You don't need like mutexes and locks for an inventory

hollow eagle
#

Or... don't send slot numbers as the target of an operation.

chrome onyx
#

But this is the Internet and you can make your own mind up

hollow eagle
#

The race condition that results from the server swapping items at the same time as a client is something that gets solved eventually by replication, but it's also a completely avoidable problem in the first place.

#

And without being any more complex.

#

Regardless, still not any new information to go on.

#

No, I don't know your situation.

#

You haven't given enough details on how your inventory works.

#

And even in this hypothetical "eventually" is within a second or so.

chrome onyx
#

Yeah - it really does depend on how you're handling it

#

It doesn't just happen unfortunately

#

I usually use fast array rep, or in prototype cases just onrep some lightweight version of the data, so I'll get updates from the server when it changes

#

If you're relying on purely rpcs or something else it'll be much trickier

hollow eagle
#

lol ok, night.

silent valley
#

@cedric_exi

pseudo kernel
#

How accurate are the network emulation settings? I implemented a circular ping buffer and see anywhere from 20-30ms ping above what I would expect. Is that just induced added time of getting the network in/out of unreal on each end?

#

well actually it's interesting... only when the windows have focus is ping way up thonk

thin stratus
pseudo kernel
#

Yeah I can believe that, I guess it's on the game thread so it has to get down to that point, but the difference seems pretty high... now that I see the ping dropping to reasonably close levels when I don't have focus on the window, I'm suspicous

thin stratus
#

I think it's reasonably accurate

#

I implemented a more precise net clock for a MOBA last year and tested it for Cooldown stuff with NetEmulation Ping and it reported the same numbers.

pseudo kernel
#

Same numbers as in, setting the in/out time to 25 25 on each end you'd see 50ish on the ping?

thin stratus
#

Yeah, sort of. It's the time 2 RPCs take from Client to Server and back.

pseudo kernel
#

Yeah makes sense, just regular unreliable RCP, nothing fancy besides that?

thin stratus
#

Pretty sure they were reliable. We don't sync that every frame

pseudo kernel
#

fair

#

Right now I'm doing every 1 second and just waiting for the time to come back on the client but seeing weird things, gonna look into it more

#

ty

#

Honestly I'm going to chalk it up to the editor being weird when changing the emulation settings. I thought it might be that I was updating the control rotation (player looks towards the mouse) every frame, but I see expected numbers now that I rebooted the editor (within 10ms)

#

although now it's shooting back up again lol so who knows

void nest
#

Why does this return true on ai controlled pawns?

#

it says controlled by a HUMAN player. Since when is an AI a human player? xD

#

Nevermind! Was reading the wrong ref

burnt hinge
#

Is it better to replicate chaos vehicle movement via transform or just replicate movement?

#

transform should be cheaper?

chrome bay
#

That's literally what replicate movement does

burnt hinge
#

Then i don't understand why a studio replicated transform instead and has movement disabled

queen escarp
#

hey Question

#

if i wanna play a montage and on the notify begin

#

since i dont wanna RPC everything after how can i get a "Return" from the notify begin

#

this is the way im doing it now but there must be a better way ?

burnt hinge
#

put the montage and sound in a repnotify, should work

queen escarp
#

hm

#

how would id od that :/?

#

since its not a varaible

dim barn
queen escarp
#

unefficient -.-'

#

so many unecessery custom events'

burnt hinge
#

I would also like to know why my multicast is not working when set to reliable

dim barn
#

You have only 1 event for the RPC. The "continue body slam" you could remove and put the logic in the same place as playing the sound. So you basically have only 1 event. How is that many unneccessary events?

sinful tree
queen escarp
#

hmm thats acctualy a good point

sinful tree
quasi tide
#

I think, like the only reliable multicasts I do are level events (like, ending the match) and game wide messages.

teal frost
quasi tide
#

That'd be an awful experience

teal frost
#

Idk why but I read that match as ending a round lol. I'm an idiot ignore me.

burnt hinge
#

So all gameplay related server events should be reliable and most if not all multicasts unreliable?

quasi tide
#

It dependsℒ️

#

Use reliable if it absolutely has to be received, unreliable if it doesn't matter.

#

What is required or not is game dependent

burnt hinge
#

If i see actions happening on different clients like they are supposed to can i assume they are replicated properly? Idk if i'm using print strings properly

sinful tree
#

Yeah, as an example, if your game requires your player to say, hear a sound playing in order to know they can move and would die otherwise, you probably want to reliably multicast it. If it's just some background noise, it can still be a multicast but it doesn't need to be reliable.

sinful tree
burnt hinge
#

The print strings don't make sense at all. Playing on client 1 & 2 but it shows 0 on both screens

#

I see actions happening properly on both clients

stuck cloud
#

I'm trying to figure out how to communicate between server and clients. I'd like to broadcast event's when certain things change on the server and have clients add functions to these events.

What I'm thinking about doing is declaing a multicast deleagte within GameState and broadcast that event from within GameMode. The clients then add functions to the delegate. Is this a good idea?

quasi tide
#

I'm not sure what you're trying to do.

#

If you're talking about the client broadcasting a delegate inside of an OnRep, that is fine.

#

Or if a mutlicast/client RPC just triggers a delegate broadcasting, that is fine as well.

#

GameMode only exists on the server though. So client's won't even have that.

stuck cloud
#

I have GameMode triggering certain evetns. I'd like to react to those on clients that subscribe to these events. That's why my thought was to do this on GameState since its replicated on clients

quasi tide
#

They can't. They're entirely different computers. You have to use an RPC

#

On the receiving side of the RPC, you can trigger the delegate, sure.

stuck cloud
#

But wouldn't GameState exist on the client machines too?

quasi tide
#

Yes.

#

But the way you're saying what you want to do is coming off as saying that you want the client to connect to a delegate on the server. Which just is not possible.

stuck cloud
#

I'd like the clients to connect to a delegate on GameState, but the delegate.broadcast() would be done on GameMode

quasi tide
#

So use the GameState to RPC to the clients, then in that method, execute the delegate

stuck cloud
#

I still lack mulitplayer knowledge πŸ˜…

#

Maybe I have to do one more round of research πŸ˜„

quasi tide
#

They are entirely different computers

stuck cloud
#

Ok thx, yeah then I'll do some more reading first

sinful tree
#
Server: Broadcasts Delegate on GameMode
Clients: Cannot "Get" game mode to subscribe to the delegate being called.


Server: GameMode calls a Delegate on GameState
Clients: Receive nothing as they don't know that there was any broadcast as it wasn't communicated to them VIA RPC that it should happen.


Server: Calls a multicast RPC on the GameState
Clients: Receive the multicast RPC notification, they can react to that multicast call however you want.  If they bound to a delegate on the gamestate the multicast could call it here for each client to then respond to.
stuck cloud
#

Cool thx a lot. Then option 3 is what I want. I'll do some research πŸ‘

boreal scarab
#

Working through some basic multiplayer stuff to get a grasp on it. I made this simple blueprint.

I basically have a barrel that after 5 seconds will fire an impulse from a Radial Force Component, and I have a few boxes that react with physics that will be knocked away.

What's happening is everything seems to be replicating properly, except the boxes reacting on the client. Meaning the boxes get knocked away on the server but not the client.

What could I be missing?

#

(red is server executed, blue is client)

hoary spear
#

(When setting lifespan, you dont need to destroy )

boreal scarab
hoary spear
#

Yepp

#

As long as lifespan is > 0

boreal scarab
#

okay cool thanks for that, that's good to know

#

Woah that was actually the problem! I guess it was getting destroyed before the client had a chance to apply physics

hoary spear
#

I'd never imagine destroying the actor after an RPC was 'queued' would somehow stop it from executing

#

then again, i've never had that scenario (yet)

boreal scarab
#

Hm.. yeah and actually now that I think about it, it wouldn't be a timing issue either because I was destroying after 2 seconds anyway. I wonder why calling destroy breaks it..

hoary spear
#

huh ?

#

you were instantly destroying

boreal scarab
#

Ohh right right heh yeah of course

#

I'm just setting the lifespan

#

and then destroying

hoary spear
#

^^ exactly

#

I also think your "Explode" event could be directly replicated

#

and SetLifeSpan would just be set right after Set Timer by Event

boreal scarab
#

Hmm how do you mean "directly replicated"? I guess my understanding was this is how you replicate events. You trigger them on the server and then multicast them to clients. What's the more direct way?

hoary spear
#

That is correct,you trigger them from the server,

#

and the server in this case is starting the timer

#

and is also firing the bound event (Explode)

#

thus, if Explode were set to multicast, it would just be the server calling a multicast

boreal scarab
#

ohh I see, so there's some way to make an event itself multicast? When I select the event these are the only details I see:

dark edge
#

Also try just applying impulse to things directly, see what that does

hoary spear
#

kinda feels like a bug to me πŸ˜„

boreal scarab
hoary spear
#

I get paid for my paint skills btw

#

/joke

hoary spear
#

the red wire

#

then re-select the node

boreal scarab
#

ohhhh got it

#

ah neat! Is there performance benefits to that? Or just makes the blueprint easier to follow?

hoary spear
#

no performance gain to talk about

#

less nodes is less nodes πŸ˜„

#

so readability yeah

boreal scarab
#

haha fair enough πŸ™‚

boreal scarab
hoary spear
#

looks about right to me atleast

#

well

#

except

#

Lifespan must be > Timer

#

so 2 is not enough πŸ™‚

#

5 is probably πŸ˜›

#

or 6

#

6 would be equal to what you had

boreal scarab
#

that's what's confusing to me, because it looks functionally the same as the last one, but SetLifeSpan appears to be called "more immediately"

hoary spear
#

guess that's a drawback of doing it this way

boreal scarab
#

ahh okay, so when is it called in the first one?

hoary spear
#

Yeah, because lifespan is set at the same time as the timer starts, instead of after the timer has executed it's delegate

hoary spear
boreal scarab
#

ohhh got it got it, that makes sense

#

okay. Well I copy pasted to make my change anyway. this blueprint is supposed to be an example for me later so its good that I can demonstrate both ways of doing it. Thanks πŸ™‚

hoary spear
#

You should also take notes about how to do this statefully

#

Like for a door that opened

#

RPC's only fire on clients that are currently within relevancy range

#

so if someone was outside this range, and stepped inside, the door would not be in the actual state that it should be

boreal scarab
#

Yeah, I have an example of that but its using C++ to replicate an bIsOpen property on a treasure chest I have, and then when it changes I fire an RPC to set the door hinge at the right place

#

is that kinda what you mean?

hoary spear
#

the bIsOpen should just be replicated with OnRep tho

#

no RPC

boreal scarab
#

ah yeah you're right, I'm looking at my diff, my RPC was for an interaction component

hoary spear
#

perfecto

#

there's a diff in c++ and bp OnRep tho

#

apparently OnRep for bp's fire on server aswell πŸ™‚

#

which doesnt happen in c++

boreal scarab
#

Heh yeah, found that out the hard way too :p

hoary spear
#

same .. annoying πŸ˜„

boreal scarab
#

haha well cool, thanks for the help! I'm sure I'll have more questions but I think I'm good for now πŸ™‚

hoary spear
#

No worries, forge ahead!

steel vault
#

Anyone happen to know why OnActorHit is called properly on the owning client and AutonomousProxy but not on any of the simulated proxies?

#

I would think a simulated proxy hits things and triggers as well. I'm trying to play a montage when the actor hits, and it works for everyone except the simulated proxy. Wondering why the simulated proxy isn't triggering that same event

#

This is happening from a Gameplay Ability as well

shell leaf
#
void UCombatComponent::EquipWeapon(AWeapon* WeaponToEquip)
{
    if (Character == nullptr || WeaponToEquip == nullptr) return;

    EquippedWeapon = WeaponToEquip;
    EquippedWeapon->SetWeaponState(EWeaponState::EWS_Equipped);
    const USkeletalMeshSocket* HandSocket = Character->GetMesh()->GetSocketByName(FName("RightHandSocket"));

    if (HandSocket)
    {
        HandSocket->AttachActor(EquippedWeapon, Character->GetMesh());
    }
    EquippedWeapon->SetOwner(Character);
    Character->GetCharacterMovement()->bOrientRotationToMovement = false;
    Character->bUseControllerRotationYaw = true;
}

void UCombatComponent::OnRep_EquippedWeapon()
{
    if (EquippedWeapon && Character)
    {
        Character->GetCharacterMovement()->bOrientRotationToMovement = false;
        Character->bUseControllerRotationYaw = true;
    }
}```

Why are the two expressions in the OnRep function only executed on the player that has equipped the weapon. I thought that OnRep was executed on all clients, meaning if one player equips a weapon (the server for example), then the clients (who may not have eqipped a weapon) will also execute ```Character->GetCharacterMovement()->bOrientRotationToMovement = false;
        Character->bUseControllerRotationYaw = true;```
sinful tree
shell leaf
#

Ahh thankyou for you response @sinful tree! Can I ask why the code from the onRep function is repeated in equip weapon? If the character rotation method is set from the server, why do we also need to set it locally once equipped weapon has been replicated?

sinful tree
#

ie. Doing it on the server, then doing it again on clients could be required in order to have the desired result.

#

It's a little bit extraneous as there's no failure condition, so once it's done once, it'll always be like that anyway, so it's a bit strange.

elder sable
#

Hi
If this is working from a "Player" actor :

Cast<ANVBeacon>(GetOwner())->ServerRPC();

I should also be able to call RPC from this "Player" actor right ?

sinful tree
#

Not necessarily. If the player actor isn't replicated, then they wouldn't be able to RPC to the server. It can still have a valid owner which could be a replicated actor which is owned correctly to allow the RPC.

#

Otherwise, yes.

elder sable
#
    bReplicates = true;
    bAlwaysRelevant = true;
    NetDriverName = NAME_BeaconNetDriver;

So it should work with this

#

My server RPC (from the player actor) is not called but i can't find the problem then

fiery wadi
#

Hi, I am trying to modify the first person template to basically have the gun pickup available to both players and then they can shoot each other with it this is working for server but not for client , the client seems to be teleported upon firing not sure why though please? πŸ™‚

floral snow
#

Greetings guys!
I am encountering weird replication issues where my component wouldn't replicate a property for some reason. I am sure i just missed something obvious, but i honestly can't spot it after about an hour or so. Here is a code snippet of what I am doing:

.h
class UTestingReplication : public UActorComponent
{
GENERATED_BODY()

public:
UTestingReplication();
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
void BeginPlay() override;

private:
UPROPERTY(Replicated)
TObjectPtr<AActor> HelpMe = nullptr;
};

.cpp
UTestingReplication::UTestingReplication()
: Super()
{
PrimaryComponentTick.bCanEverTick = true;
SetIsReplicatedByDefault(true);
}

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

DOREPLIFETIME(ThisClass, HelpMe);
}

void UTestingReplication::BeginPlay()
{
Super::BeginPlay();

if (GetOwner()->HasAuthority())
{
FActorSpawnParameters ActorSpawnParameters;
ActorSpawnParameters.Owner = GetOwner();
ActorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

const FTransform SpawnTransform = GetOwner()->GetActorTransform();
HelpMe = GetWorld()->SpawnActor(
AActor::StaticClass(),
&SpawnTransform,
HoverboardActorSpawnParameters);
}
}

Would anyoine be able to spot what i am missing?
Thanks

#

The Autonomous Proxy never receives the replicated value of the UPROPERTY

fossil spoke
#

Well you are just spawning an empty AActor???

#

Thats not going to Replicate

#

Because Replication isnt enabled by defualt on AActor

floral snow
#

OH

#

this is a dumbed down example, but you are still right

fossil spoke
#

Why are you spawning an empty AActor?

floral snow
#

no i am not lol

fossil spoke
#

You are

floral snow
#

just stripped down

fossil spoke
#

AActor::StaticClass(),

floral snow
#

no what i am saying, this is not the actual code from the project

fossil spoke
#

πŸ€¦β€β™‚οΈ

floral snow
#

anyway, you are right, i don't think i am setting the actor to replicate

fossil spoke
#

When asking for help, always post the EXACT code...

floral snow
#

nda bound

fossil spoke
#

Then just redact it, dont put something in its place that would cause extra confusion

floral snow
#

got there at the end, thanks!

unkempt tiger
#

is this a correct mental model of how the replay system works?

#

As in the replay system should simulate incoming RPCs?

latent heart
#

I'd have thought the replay system would simulate regular replication, not rpcs.

unkempt tiger
#

Well that's alarming πŸ˜„

lost inlet
#

Replays do record multicast RPCs

#

You can override the replay (spectator?) player controller if you want to record RPCs sent to it into the demo. iirc ShooterGame did that

#

The replay system wouldn't send RPCs back to the server though @unkempt tiger

latent heart
#

Ah. I thought he meant it would somehow work exclusively on rpcs.

west lintel
#

Hi, I'm trying to use Lyra to make a multiplayer PvP game. Preferably build on top of it, edit the default blueprint to replace Lyra with own BP, change a few game modes etc.
Any suggestions/guidance on where to look and where to start?

hollow eagle
#

You need some way to uniquely identify a specific item. In Lyra that'd be the item instance, in some other system it could be an id of some sort. The important thing is that the id is both unique (for the current inventory at least) and unchanging - that way when the client says "do X to Y" the server knows exactly what it is the client wants to do.

#

Right now you're open to a bunch of different race conditions because if a client says "move item in slot A to slot B" the item the client thinks its moving may already be elsewhere by the time the server gets the command, and the server won't know that the operation it is about to do is the wrong one.

#

A guid would certainly meet that criteria

#

so you could say "move <insert guid here> to slot A"

#

the guid uniquely identifies an item to move, and the slot uniquely identifies a destination. There's no chance of a race condition unless your behavior depends on slot A not having an item in it already.
The solution to which depends on what you want to happen - you could simply reject that action, you could swap the item slots, or something else.

#

Sure, but you still have a single slot that it "starts" in, yeah?

#

So there isn't really an issue with what i suggested then

#

Not really. You have some complications around making sure there's room for the item or w/e but you have that regardless.

#

You do have a choice of what to do when the server finds something in the way, though. You could reject the move, you could swap item positions (which could still result in rejecting it if the swap isn't possible), or whatever else.
Something you will need to deal with is re-marking the item as dirty even if the server rejected the move.

#

Assuming you've predicted the movement on the client I mean

#

If you don't predict anything then there isn't really a problem here. If you do then you need to mark things dirty even when the server hasn't done anything because the server needs to re-send the existing data to correct the client's prediction.

#

Let's say the client moves item A to slot 2 and the server rejects this.
The client now has item A in slot 2 because it mispredicted the movement. The server isn't going to correct this because as far as it's concerned nothing has changed.
Since you're using a fast array serializer the fix is easy - simply mark both slots as dirty even though nothing moved as it will have the server re-send those items.

#

correct

#

just something to keep in mind for the future

#

something else to keep in mind is that the order of fast array items isn't guaranteed across the network. If you need to maintain a consistent order then items need to store their own index into the inventory.

#

one of the guarantees fast array replication gives up is ordering unfortunately

latent heart
#

If you have to change the index property on everything after you delete or change item orders, are you really saving anytihng with a fast array serializer?

#

Well, some of the time, I guess.

hollow eagle
#

you don't have to re-index everything

#

you also don't have to physically move the structs. You just set their new index values.

latent heart
#

I'm saying if he wants to maintain an inventory order.

hollow eagle
#

given that what was mentioned was an inventory that represents actual space, that's not an issue

#

i.e. you can have gaps in the indices

#

so inserting an item in between other items doesn't involve re-indexing everything

latent heart
#

But he's also literally just complained about it not maintaining order πŸ˜›

hollow eagle
#

probably because there were actual gaps in the array serializer

#

that sounds like whatever operation you're doing is just wrong then

#

though you'll still need to fix everything mentioned

boreal scarab
#

Is UE's OnRep_ supposed to automatically handle not calling itself on the same client if the property value is still the same, to prevent the "double spawning" problem?

hollow eagle
#

yes, that's why REPNOTIFY is a thing

boreal scarab
#

hm. Okay.. mine's not doing that, and I'm getting double spawns on my client. sec lemme just verify that I'm not crazy

boreal scarab
hollow eagle
#

ctrl+shift+f "NULL object, place a breakpoint, see what's calling it

boreal scarab
#

The double spawning only happens if I set bReplicates = true in my projectile base. What's a good way to figure out what's calling the constructor of my projectile twice on my client?

hollow eagle
#

err, that sounds like you're spawning a replicated projectile on the server and separately spawning it on the client

boreal scarab
#

well this is the code that spawns it. StartAction is 1:1 with that projectile spawning.

bool UARLActionComponent::StartActionByName(AActor* InstigatorActor, FName ActionName)
{
...
    if (Action && IsValid(*Action) && (*Action)->CanStart(InstigatorActor))
    {
        if (!GetOwner()->HasAuthority())
        {
            ServerStartAction(InstigatorActor, ActionName);
        }

        (*Action)->StartAction(InstigatorActor);
        return true;
    }
}

So if I'm the client, then I just call ServerStartAction, and then I call StartAction locally immediately to spawn my projectile. Calling that sets bIsRunning = true; on the action, which is replicated.

void UARLAction::OnRep_IsRunning()
{
    if (bIsRunning)
    {
        StartAction(nullptr);
    }
    else
    {
        StopAction(nullptr);
    }
}

But OnRep shouldn't be called because bIsRunning should be true on the client already

hollow eagle
#

err, no

#

you spawn the projectile on the client, sure. That projectile is not replicated because clients can't spawn replicated actors.

#

The server then runs ServerStartAction which I assume also ends up with a projectile spawning, but this one will actually get replicated

#

so now you have two projectiles, one spawned by the client and one spawned by the server. But the server's is replicated so the client sees both.

boreal scarab
#

yeah the server one is just

void UARLActionComponent::ServerStartAction_Implementation(AActor* InstigatorActor, FName ActionName)
{
    StartActionByName(InstigatorActor, ActionName);
}

hollow eagle
#

in the end you're running the spawn code twice. Once on the server, once on the client.

#

The OnRep isn't running twice.

boreal scarab
#

ohhh.. The server will call (*Action)->StartAction(InstigatorActor); which will spawn it for the server and also replicate it for the client

hollow eagle
#

yes

boreal scarab
#

okay.. yeah that's bad. What's best practice to handle that? I do need it to replicate because there could be multiple clients

#

but I need it not to replicate on the.. original client

#

instigating client?

hollow eagle
#

you do though, because the server may correct the position

#

one solution to this is to have the client send an id it generates with the request to spawn a projectile. It stores the id on the locally predicted projectile, and the server uses the same id when spawning its own projectile

#

when the client receives the server's version of the projectile, it searches for its local version with the same id and deletes it, letting the server's projectile take over

#

to make things even more lag resistant you can have the client interpolate the server's projectile between the position the old predicted projectile is in to the server authoritative position over a short period. UProjectileMovementComponent does have some tools for doing this but there's little to no documentation on it.

#

to be clear, the projectile movement component has utilities for interpolation/smooth movement. It doesn't help with prediction ids - that's up to you.

boreal scarab
# hollow eagle one solution to this is to have the client send an id it generates with the requ...

okay, yeah conceptually that sounds reasonable. I'm gonna try and implement that first part and iterate on it with interpolation next. First I have a couple questions

"have the client send an id it generates with the request to spawn a projectile".

What would an implementation of this look like? (not looking for actual code just conceptually I'm a bit lost on the mechanics). For example, where would I store that ID? Would I need a list of "in-flight" projectiles? Currently I don't have any stateful objects that represent a "server" or "client", I'm just checking with HasAuthority, do I need to move away from that?

"when the client receives the server's version of the projectile"
What do I hook into to "receive the server's version of the projectile"? Is there some sort of replication overload I can use? Or I guess at what point can I do that check?

hollow eagle
#

What would an implementation of this look like?
you could have a subsystem that stores the list of client-created projectiles and the ids. The id can be a simple number that increments every time a new predicted projectile spawns, it doesn't have to be unique across the whole game - only unique to that specific client.

What do I hook into to "receive the server's version of the projectile"?
BeginPlay of a projectile. If the owner of the projectile is the local client and you don't have authority then you check for a locally predicted version of the same projectile.

#

so... log them? Not sure what the question is there.

boreal scarab
hollow eagle
#

You could. You could use a literal subsystem as well.

boreal scarab
#

It says its lifetime is tied to its parent, so if I want it to exist as long as the client exists, would it be LocalPlayer or GameInstance?

hollow eagle
#

this would make sense as a world subsystem

#

projectiles aren't going to last past the lifetime of a world after all

boreal scarab
#

Okay.. how many instances of the UWorld are there? Would there be one per client?

hollow eagle
#

yes

undone notch
#

hi

on aws gamelift how to set the session keep active for 20 minutes aftern then its terminted

any blueprint are there ?

boreal scarab
# hollow eagle yes
// In ARLActionComponent
StartActionByName(Name)
    static int64 Id = 0;
    if not FindAction
      return

    if HasAuthority
        ServerStartAction(..., Id++)

    StartAction(..., Id)

// In class UARLAction_ProjectileAttack : UARLAction
StartAction_Implementation(..., Id)
    
    WSS = SomewhereGlobal->GetWorldSubsystem()
    Projectile = CreateProjectile(Id)
    WSS->TrackProjectile(Id, Projectile)

// In AARLMagicProjectile
BeginPlay()
    WSS = GetWorldSubSystem()
    if (AARLMagicProjectile* Projectile = WSS->FindProjectileById(Id))
        Projectile->Destroy()

Am I grasping the general idea?

hollow eagle
#

yes but Id++ here is incorrect

#

you're passing an Id, then incrementing it. Which means the subsequent StartAction is using the next id.

boreal scarab
#

Ah yeah you're right. I want to increment it with the conceptual "request". So the batch of client/server StartAction, I'll fix that.

BTW is PlayerState an okay place to own the world subsystem?

hollow eagle
#

err, own it?

#

the world owns it

#

that's why it's a world subsystem

boreal scarab
#

Ah okay. I think I don't know enough about subsystems. I love benui but his subsystem page is basically a dictionary definition haha. I'll find docs for it

hollow eagle
#

I get the impression that you're asking for where to create the subsystem. The answer is you don't, subsystems are created automatically by the thing that owns it.

#

And the world owns world subsystems. They are created automatically and you don't do anything to manage them.

#

With the slight exception that you'll want to override the DoesSupportWorldType function on your subsystem so that it only gets created in PIE and Game worlds, for some asinine reason it defaults to also being created in editor viewports if you don't.

boreal scarab
#

Okay so you create a subsystem class that inherits UWorldSubsystem and has the API for adding/removing, and the (I'm guesing TArray) container. How does your derived world subsystem get created though?

hollow eagle
#

automatically

#

subsystems are created automatically by the thing that owns it.

#

you don't do anything

#

the thing that owns the subsystem automatically pulls the list of all subsystems of the type it cares about and creates instances of them

boreal scarab
#

it just.. looks through my project for anything that derives from UWorldSubsystem?

hollow eagle
#

yes

#

and you retrieve that subsystem with GetWorld()->GetSubsystem<UMySubsystem>()

boreal scarab
#

wow. that's pretty neat! How granular do you typically make them? I'm guessing they're not too expensive. Would.. "ProjectileTrackerWorldSubsystem" be too granular? Or would you have a broader "state tracker world subsystem" or something

hollow eagle
#

that's really up to you

boreal scarab
#

okay, cool

twin juniper
#

Wait so if there is the subsystem class exist somewhere, it would be auto created without any link? That sound like magical stuff

boreal scarab
#

and then I think last question i have is, how should I store the Projectile and ID pair? If this were std c++ I'd just store std::vector<std::pair<Projectile*, Id>>, but I'm wondering if that's safe with Unreal's objects. Like.. I guess can I store a AActor* that points to the Actor* that SpawnActorreturns? Or do I need to do something special

hollow eagle
#
UPROPERTY(Transient)
TMap<int32, AMyProjectile*> IdToProjectileMap;
boreal scarab
#

Okay. Yeah I thought about using map but.. it'll be such a small list vector is usually faster anyway. something something cache invalidation

#

wait what's that Transient flag?

hollow eagle
#

just means that the property won't be saved into anything (like a blueprint or anything else using reflection to serialize data). It's not strictly necessary because nothing should be trying to serialize a subsystem, just a good habit to be in.

boreal scarab
#

Got it, good to know. Thanks again!

boreal scarab
#

btw, is this only a problem because this particular action spawns a game object that has replication? I'm thinking of instead of sending an ID into my StartActionByName, having my ActionBase class have a bRequiresPrediction property. Then if that's set, instead of calling StartAction(Instigator) it'll call StartActionPredictive(Instigator, ID). This way its more explicit as to who has to care about managing these IDs and stuff

elder sable
#

Hi, is it possible to get the previous value after a repnotify call ?

fossil spoke
elder sable
#

How ? (i'm in c++)

fossil spoke
#

void OnRep_MyVar(VarType OldMyVar);

#

void OnRep_MyInt(int32 OldMyInt);

elder sable
#

Oh !

fossil spoke
#

For example

elder sable
#

Thanks ! πŸ™‚

fossil spoke
#

Unreal auto fills the first param matching the var type thats replicated

elder sable
#

I see, never saw that yet, very useful ! :p

fossil spoke
#

Keep in mind, if you are calling the OnRep for the Server, you will have to then manually pass in the old value

elder sable
#

Yep, thank you !

pseudo kernel
#

When considering RCP vs Prop Replication, is one typically faster to update than the other, assuming no packet loss / etc?

#

(Update on the receiving clients)

fossil spoke
#

Depends

#

Mostly on the amount of data

#

But you should not be choosing one over the other based on some preconcieved notion of "speed".

pseudo kernel
#

Yeah I guess that makes sense

#

I'm struggling to predict projectiles and make them feel good for both clients so my brain is going in weird places 🫠

fossil spoke
#

Generally the idea with predicting projectiles goes something like this.

#

Client spawns a "Fake" version locally, while sending a request to the Server that it needs to spawn a replicated version.

#

When the replicated version from the Server comes down.

#

It replaces the "fake" one on the Client.

#

This way the Client has immediate feedback (predicted projectile), while also allowing for maintaining Server authority (the replicated projectile)

pseudo kernel
#

So I had that working pretty well and turned that off for now, I guess my main problem is making it "feel" ok for the client potentially getting hit

fossil spoke
#

What do you mean?

pseudo kernel
#

Sometimes the projectile visually doesn't hit me, so figuring out a system where I can fix/fake that

#

Actually, I have an image

fossil spoke
#

You may need to advance the Servers projectile based on the ping of the Client that created it

pseudo kernel
#

hmm that's a good idea I haven't tried yet

fossil spoke
#

Look at the Unreal Tournament source code

#

They predict projectiles.

pseudo kernel
#

I played around with advancing the projectile based on the local client difference

fossil spoke
#

Its an old implementation, but the bones are there.

pseudo kernel
#

Ohh, that's a solid idea

#

I'll look into that ty

fossil spoke
#

πŸ‘

pseudo kernel
#

I'm new to unreal and was feeling fairly confident until I started working on predictive netcode

#

but it's fun to have actual hardish problems to solve

fossil spoke
#

Are you new to game dev/multiplayer gameplay programming?

pseudo kernel
#

yeah

fossil spoke
#

Generally the advice is to start on something simpler than something like predicted multiplayer projectiles

pseudo kernel
#

Yeah I can start to see why

fossil spoke
#

Until you get grasp of most of the tools available to you

pseudo kernel
#

I read a bunch about common hit-scan implementations and it seems a lot more straightforward

fossil spoke
#

Well yeah, hitscan simplifies a lot lol

pseudo kernel
#

I think the visual feedback of projectiles makes it difficult for me

#

I kinda had an idea to use predictive roll-back on the client to tell a "point of no return" where I have high confidence a projectile would hit me and there wasn't anything I can do about it, then I'd be able to fake it a little bit

#

so I mostly implemented that, but still it didn't line up as well as I would have hoped

fossil spoke
#

Just make sure you arent trying to bite off more than you can chew at this early stage.

pseudo kernel
#

Yeah it's something to consider

#

I think I've learned a lot so far, might try to make a melee system which I think would be a lot easier

fossil spoke
#

πŸ‘

gusty slate
#

Hello,
Any suggestions on how to replicate an Instanced static mesh that'll contain a couple hundred trees?

#

Should I for example periodically update an array of Instances and their transforms which is set as RepNotify?

thin stratus
#

Probably because you are doing it too early

thin stratus
#

You can then alter the actual ISMC with the callbacks that this thing provides

gusty slate
#

I see, thanks Cedric πŸ‘

thin stratus
#

I mean, possessed is server only

#

If you have a ListenServer, then that's fine

#

OnRep is theoretically also fine. Can you break point it to see if the PlayerState is actually valid?

#

Although

#

It would crash if not

twin juniper
#

i use listen server

thin stratus
#

Are you setting the Owning Player properly on the Wiget itself?

twin juniper
#

i just do this

#

in the character BP

thin stratus
#

And what calls that?

twin juniper
#

my character blueprint begin play

#

it's worked fine in single player

gusty slate
thin stratus
#

My general suggestion for UI that relies on Pawn and PlayerState is:

  • Create Delegates in your C++ PlayerController for when the Pawn and the PlayerState become valid/invalid
  • Call those in Possessed and OnRep_Pawn/OnRep_PlayerState
  • Create a C++ UUserWidget that acts as the base for widgets that rely on those two or any of the two
  • Ensure you add those Widgets inside the PlayerController and set the "OwningPlayer" of the CreateWidget node to "this/self" and then bind in the C++ Parent to the Callbacks
  • Expose some BPImplementableEvents for when Pawn and PlayerState changes so you can use them in your Widgets
#

That doesn't work, BeginPlay is too early

#

Your Client won't have the replicated PlayerState at that point if they just joined

#

You either have to do what I wrote above, or ensure you create the Widget when the Player has all required info

#

Also craeting it like this will create it once for every character on every player

#

So if that's an actual UI Widget, you will have that x times for x Characters, overlaying

#

You need to ensure you only add it for the local player

#

Which is again better done in the PlayerController

#

If you do the list I wrote, you can add the widget in the BeginPlay of the PlayerController, with an IsLocalPlayerController check in front

twin juniper
#

Okay, i got it, bind a delegate so it can wait till the right time

thin stratus
#

Yeah you want to additionally call the BPImplementableEvents once when binding

#

In case the values are already valid

#
void UPlayerWidget::NativeConstruct()
{
  Super::NativeConstruct();

  ASomePlayerController = Cast<ASomePlayerController>(GetOwningPlayer());
  OnPawnChanged(ASomePlayerController->GetPawn());
  OnPlayerStateChanged(ASomePlayerController->GetPlayerState());

  ASomePlayerController->OnPawnChangedEvent.AddDynamic(this, &ThisClass::OnPawnChanged);
  ASomePlayerController->OnPlayerStateChangedEvent.AddDynamic(this, &ThisClass::OnPlayerStateChanged);
}
#

With OnPawnChangedEvent being a multicast dynamic delegate with one param APawn*

#

And the PlayerState one similar

#

That code there is pseudo code that I wrote just here, no clue if that compiles

twin juniper
#

okay, thanks u cedric

thin stratus
#

But the file where that is delcared has a huge comment tutorial

#

So just read that

gusty slate
#

Alright ty

thin stratus
#

FastArraySerializer.h:127 or so

#

Actually the whole file is one big tutorial

somber ivy
#

What`s the best way to make a synchronised timer that works with late joiner like a 30 second timer in a game lobby that start when at least 2 player are ready ?

tranquil yoke
#

Put timer on Server

#

Do something when Timer Ends, like blocking New Players to join and start the game ?
@somber ivy

#

You should make the timer parameter replicated only if you need to show it to clients, otherwise state should do the trick.

somber ivy
#

ok thx

teal frost
#

I have a system that you make a pregame lobby then the host moves everyone into the game mode.
Once in the new game mode how do I ensure all players from the lobby are connected? Right now I have an incredibly janky and slow system that checks the logged in controllers and sees if it changes within x seconds if it doesn't it launches the game.

It takes like 30+ seconds or so for a match to start after the host logs in. I feel like for what I have, it's incredibly slow. I had to slow it down due to slower connections not connecting in time to receive the start command.

#

anyone have any insight or sources for learning?

round acorn
#

I don't understand why this is happening - maybe I don't understand how CMC works for simulated proxies? In this watched variable the Client 0 and Server both get the vector value from Get Current Acceleration. The simulated proxy (Client 1's version of Client 0) gets no vector data from this at all.

#

Yet the simulated proxy of Client 0 is moving around on Client 1's screen.

#

This is running on Tick in the character bp and the execution is firing. It's just not pulling any value.

#

And it appears the simulated proxies don't use the full host of movement functions that run on the autonomous proxy and the server

#

And Get Current Acceleration appears to derive from inputs, which is maybe why a simulated proxy is getting nada.

serene kestrel
# round acorn I don't understand why this is happening - maybe I don't understand how CMC work...

By default, the acceleration is not needed to show simulated proxy movement (technically velocity isn't really needed either but can be useful for visual effects). If you do want the acceleration, take a look at the Lyra starter project, their CMC does the extra work of replicating an acceleration value to use for various animation cases (at least I think Lyra does this from my memory, I could be wrong about that)

zenith wyvern
#

I spawned a large number of actors on the server, and i have their meshes max view distance very low and I can't see any of them, but my FPS is still hovering around 10-15 with them just being in the world. What's the proper way to handle this?

#

I attempted to remove always relevant (cant ever see them even close), and use net cull distance (no impact)

serene kestrel
zenith wyvern
#

I'm assuming it's just large 0(1) every tick on actors that client knows exists, even if mesh doesn't render

#

so i assumed or hoped it was a network issue of relevance

serene kestrel
#

It's going to be hard to tell without knowing what your actors are doing on the client, it could be rendering, could be ticks, could be something else, the profile will help reveal that

zenith wyvern
#

can you point me in the direction of some reading on that?

#

or am i good with 'tutorial profile channel'

serene kestrel
#

There's a discord channel for profiling in this server, I'd check what they have pinned there first, using Insights is generally straight forward but if you've never done profiling before, just googling some docs would be good as well

zenith wyvern
#

oh

#

you meant discord channel

#

i need more coffee

fiery wadi
#

Hi I am trying to modify the FPS template for a simple 1 v 1 shooter, i have set it up so the server can "see" the hit traces and register the hits but the client cannot see the line traces at all ? is this because i have the line traces to only run on the server??

hoary spear
#

Sounds like a plausible reason

fiery wadi
#

this is my current setup

#

I guess i need a ClientFire custom event and use a Authority on the Shoot input (just trying to make sense of how this MP stuff actually works) XD The server applies a decal on hit of something but the client can do the line trace as the server reports hits but does not place a decal for client hits.

#

but then i was thinking if i use a authority that means only the server will process fire and check if the player has ammo to fire and allow the firing if ammo is available and if i do a clientfire that will be letting the client check if they have ammo which could be exploited correct?

sinful tree
# fiery wadi this is my current setup

The spawning of the decal is only for the local machine which is denoted by that little display icon on the top right of the node. If you want the decal to only display for the owning client of this actor, then yea, you'd want to do a Run On Client RPC. If you want all clients to see the decal, you'd have to use a multicast.
I'd also recommend against having a run on server event calling another run on server event as theoretically that can allow a client to call the second one without the first being executed which you might not want.

fiery wadi
#

ah ok thanks!

#

so if i wanted to use a multicast i would need to create a new custom event called "Spawn Decal " and then choose Multicast for it to appear on all clients?

boreal scarab
#

In real prod code, how do people generally go about executing Server requests?

Do people just

if (!GetOwner()->HasAuthority())
{
  ServerStartAction(InstigatorActor, ActionName);
}

Or is there usually some sort of wrapper that encapsulates the server call in a Request object that has at least an ID so it can be contextualized in client responses?

fiery wadi
#

So if i change the ServerFire to Multicast does that mean that the server and clients should all be able to do line traces over the place and register hits?

sinful tree
#

You also don't necessarily need clients registering the hits.

fiery wadi
#

ahh ok so how would i do a server check if client has ammo before allowing fire? this is a bit confusing at first XD

sinful tree
#

You already have it.

fiery wadi
#

oh ok

sinful tree
#

But then you're relying on the client to tell teh server how much ammo they have...

fiery wadi
#

but then only the server sees the line traces?

#

oh what would be a better way plz?

sinful tree
#

Have the server control the ammo variable and read from the server's copy of it.

#

In other words, don't pass the value through the RPC.

fiery wadi
#

that makes sense, so i guess the only question left is how i do the line trace so all can see πŸ™‚

sinful tree
#

"Seeing" the line trace doesn't really matter as it is only a debug feature. On your multicast you would spawn some sort of particle effect or what have you so people can see the actual effect.

fiery wadi
#

ahh ok thats true.

#

thank you so much for your help

urban vessel
#

Does anyone know of a way to implement host migration in a multiplayer arcade style game? If the host leaves I don't want the game to end prematurely.

graceful flame
urban vessel
#

I saw that one. Doesn't work with UE5 IIRC

#

Trying to avoid dedicated servers.

#

Only because of price. It would be ideal if a game could just migrate to one of the clients but I'm not sure how realistic that is

graceful flame
#

It’s a problem that makes a lot of sense. If the host is where all these important state variables are kept and the host suddenly leaves then all that data is lost.

urban vessel
#

Yeah I know. I'm thinking maybe something like shadow hosting on another client at the same time, but that, if possible, still could be an issue.

#

I have read some about EOS + sessions but as far as I understand (which isn't far right now) that still requires dedicated servers, right?

graceful flame
#

EOS is an #online-subsystems which comes with a bunch of free features but I don’t think host migration is one of them. You don’t need dedicated servers for EOS. Should also mention it has its own channel #epic-online-services

urban vessel
#

Well right, same as steam subsystem right? But for the purposes I want to use them they're no different than steam.

#

My purpose meaning migrating the host if the host leaves. I guess like a p2p setup?

graceful flame
#

I dunno I haven’t used it before might be better to ask in that channel.

urban vessel
#

Cool, thanks for the help

dark edge
#

It's a 2 part problem.

  1. Make sure enough state is on the clients to be able to reconstruct the server's view of the game
  2. Make sure all the clients can somehow keep in touch after the server goes kaput.
#

Assuming you have some way to synchronize data so clients can find the new server in the case of a failure it probably isn't insanely hard.

urban vessel
#

From a high level I was planning a shadow copy of the server on another client. Not really sure what the implementation would look like or if it's even really possible.

#

I suppose I could have clients store stateful information of themselves and then pass that all back into a new server.

dark edge
#

That or maybe each team knows their teams state at some interval

#

if you're worried about info leaking

#

It could be as simple as a savegame MyLastState

#

and a pre-set order for clients to fire up as server

#

Server shits the bed
Whatever the first client was fires one up
Everyone else finds it through some mechanism or key that was shared in 1st session
They log in
They send their state
???
profit

#

exact perfect state would be hard but the basics wouldn't be too bad

urban vessel
#

Yeah I see what you're saying. I'm not sure if it fits well with what I want to do though. You can imagine the game I'm building being something like fall guys.

dark edge
#

fall guys with listen server will already be hard enough

urban vessel
#

Would have to be a seamless transition and I don't think this is that.

dark edge
#

oh seamless is a whole other animal

#

good luck with that lol

urban vessel
#

Yeah I'm thinking dedicated is really the only option.

dark edge
#

Not worth the trouble for a small operation IMO, even the big guys can barely do it. Seamless that is

urban vessel
#

Yeah but in an arcade style game with anywhere from 10-20 players per lobby... Idk how else you'd do it really other than dedicated

#

PlayFab has a host migration setting, so maybe that

#

PlayFab seems like a decent option in general but then setting up their OSS just seems like a whole other monster. And dedicated is just so much $

#

Other option being transition to hosted lobbies instead of a MM system. Don't love that though

dark edge
#

I mean if you're trying to make a matchmade game then you'll already need some servers so just do it

#

I'm going for the TF2 / GMod model where you can just listen host or host your own dedicated

#

My code is bad enough as it is, I don't want any of my code able to run up an AWS bill

urban vessel
#

Listen host is what I have currently

#

By MM I really mean just faking MM by using listen over steam

#

Click TDM and get sent to a lobby. The problem is if the host leaves, right? Then the lobby crashes for what- 19 other people?

dark edge
#

I mean that's life

#

with 20 people you'll want dedicated

#

now whether you host or community hosts is up to you

#

I'm lucky that my project makes sense with an always-up server

#

a bit like garrysmod

#

while nobody "hangs out" in a COD server for example

urban vessel
#

Yeah. I'm thinking maybe moving off steam SS and into PlayFab. They offer automatic listen server migration if a server dcs. It's hard to tell what services you have to pay for though.

#

Do you use a hosted dedicated server site? I can't find one that's not crazy expensive.

keen hound
#

Though I'm going for a community hosted

urban vessel
#

Nice, I'll check that out. I've looked at PlayFab, gamelift, and IBM but they all $$$

keen hound
urban vessel
#

I'm not even sure tbh. Ideally a listen server with host migration capabilities but that's not baked into UE

#

So I'm thinking dedicated or playfab are my only options

#

@keen hound can you host dedicated servers of a new game on pingperfect? I just see current games

hollow eagle
urban vessel
#

Tragic

fossil spoke
#

Also you arent going to get a session management service for free...

#

Or without work.

#

You can utilize the EOS backend

#

But you need to provide the Servers

#

Dedicated or Listen

#

If you go Dedicated then you obviously need hardware to run them on

#

And a martialling system

#

Otherwise, pay the $$ for Gamelift/Playfab etc and have all of that solved for you.

urban vessel
#

Yep, looking into dedicated as it seems to be the only option! You guys have all been very helpful. I'll let ya know how it turns out

quasi tide
#

Does anyone know how much overhead component replication/RPC actually is?

fossil spoke
#

Which is attached to every packet

serene kestrel
quasi tide
#

I'm not worried about it, as an FYI. Just curious, that's all.

fossil spoke
#

The CMC avoids it because its a critical pathway.

#

The CMC uses RPC proxies on the Character

#

So it can avoid the overhead

#

Since it sends lots of RPCs and its a critical feature, its worth the trouble.

quasi tide
#

Yeah. All this I understand. I was just more curious about any hard numbers and what not.

humble wadi
#

Hey there!
Has anyone used root motion animations extensively before in a networked environment?

I've been researching the topic for quite some time and figured that either I'm doing something completely wrong, or the engine just cannot handle these root motion animations deterministically to ensure that both client and server play the root motion the same way.

Let me give you a brief description of what I'm trying to do and what I've tried so far.

So basically, the concept is really simple. I have a character that uses Unreal's CMC (so moves with client-side prediction). The client controlled player has the ability to fire a "dive forward" ability/action predictively. When he does so, a simple forward dashing/diving animations plays out. No rotations, nothing, just simple forward movement. The server follows up when it gets the latest move/update from the client and executes the same ability/action to do the same and plays the exact same animation with exactly the same parameters.

The animation itself is wrapped in an animation montage, the sequence that plays in the montage has root motion enabled.

What puzzles me the most is that at the end of the animation (or sometimes midway through it), the client receives net corrections from the server and I can see a tiny snap on client-side.

I've tried:

  • routing all this through the CMC's prediction framework with compressed flags triggering the animation montage
  • encapsulating the dive action in a gameplay ability and ensuring that it plays on both client and server (ability was local predicted for client)
  • firing the animation while being stationary so my initial position should not be the cause of net corrections that occur midway through or at the end of the animation (I even tried the dive AFTER I got a net correction so I made sure that I'm in a position that is 100% valid from the server's POV).

All this, makes me think that RM animations are just non-deterministic and they'll always differ.
Any clues?

#

Extra note: the character/anim bp is set up to play root motion from montages only (obviously).

queen escarp
#

hey giys

#

im seting a static mesh inside a function thats being called on the server

#

the print is print that it has a "new" mesh"

#

but its not updating on the target for some reson :/ ?

winged badger
#

generally, you'd want to put that static mesh into an OnRep variable in the actor that owns the component, then set the mesh from OnRep itself

queen escarp
#

hmm

#

aye i think it could be related to this tho

#

this inside a Widget

#

how do i get the Owner of the widget something '

dull tulip
#

Hello,I have a Question.
We are currently developing a two-player shooter game, but the character animations are not synchronized.
It is working fine on the Client, but the server side behavior is not in sync with the client side.
Does anyone know of a solution to this problem?

dark parcel
#

@dull tulip seems like your variables are not set to replicate?

#

and I'm not sure with Multicast to update, I think you just need to replicate the variable and update the value on server

fiery wadi
#

Hi, wonder if someone can explain me what would happen if you done this ?

dull tulip
#

@dark parcel
Thanks for the reply.
Replicating the variables did not change the result.
It should be facing the same direction as the camera it is facing, as shown in the image, but it is not working correctly on the Client side

dark parcel
#

@dull tulip I have little to no experience in multiplayer but I think you should not update with multicast. Doing so will update the value to all machine.
I am suprised if the animation not janky because as you move, the server will keep sending you the previous value you sent.
The problem should be more apparent if you emulate lag

#

Anything movement related imo, client set their values locally, then send an rpc to server. The server then replicate the data to other machine (other proxies) where they can interpolate to the value they received

dull tulip
dark parcel
queen escarp
#

im trying to pass a Widget reff thru the server is that not possible :/ ? anyone know

chrome bay
#

no

#

Server doesn't (and shouldn't) care about client widgets or UI

queen escarp
#

bahhhh

#

ok just to be clear

dark parcel
#

Picture this, if you multi cast.

You move 10 Units , few ms later server receive your data, then it replicates to all client
Since it;s multicast, you get the values back again. At this point you might have move anotehr 5 units, but then you get the values back again so you get rubber banded back.

queen escarp
#

im trying to send a reff of this "Self" widget to the owning client so i can get variables from inside that widget thats all but thats not allowed ?

chrome bay
#

no

queen escarp
#

hmmmm

chrome bay
#

And it doesn't make any sense. Widgets only exist on the client machine

queen escarp
#

yeah

#

but i made it so when u

#

ill just show u 1 sec

#

my items i pick up from the ground gives the player a "Widget"

#

and when equipping that the widget got variable stats inside that needs to be sent to the server so it updates

#

but im getting access none from the widget

#

and i think its weird since the owning client owns the widget and got the varaibles, why would he be able to send information about that widget to the server :/

#

hmm when i said it i was acctualy able to solve it

chrome bay
#

The widget isn't replicated or created by the Server, it's created by the client, so it's impossible for the Server to know about it or do anything with it.

queen escarp
#

yeah so the problem was i tried to fetch the info from widget on the server side wich cleary dont owkr

#

yeah exactly

#

but if i get the info from the widget on the client first then send it to the server

#

thats what i did wronfg

chrome bay
#

Yeah that's what you need to do

queen escarp
#

yeah cool, however one small issue left

dull tulip
dark parcel
queen escarp
#

im changin static mesh and i get prints from both target , new mesh

#

but nothing happening :/

#

tried server & Rpc even tho components are Replicated

dark parcel
#

@dull tulip I can recommend you a FPS tutorial that goes over setting up shooter game, but it's in cpp and cost some money

#

but the breakdown and the wisdom is worth it imo

dull tulip
dark parcel
#

forgot about that part

queen escarp
#

visual studio is free

dark parcel
dark parcel
#

one example is the character movement component. Adding functionality like crouch or sprinting would probably require you to write some code

dull tulip
# dark parcel forgot about that part

I guess that means multiplayer development is harder than it seems.
Is it likely that blueprints alone will not solve the problem you just mentioned?

dark parcel
#

@dull tulip depends on the scope of the game

#

if you can give up on the fancy movement

#

you can use the current Character Movement Component as is

#

multiplayer development is hard, replication is the easy part actually

#

you have to deal with client prediction, rewinding, Server auth, etc

#

and that's crucial in FPS game

#

but for something like turn based game or Card game, you can probably still make a playable game using bp alone

dull tulip
dark sandal
#

hey i need help, I was testing with net emulation to simulate high ping and no matter what the clients that are moving arent being smoothed on the server, So they are really choppy and teleporting to where the client is

thin stratus
#

Reason is that they are ticked via the ServerMove and not per Tick

rocky knot
#

Hey, what are the main components a programmer should learn to do in c++ regarding multiplayer ? Thankyou!

winged badger
#

find network compendium link in pinned messages on this channel and read it @rocky knot

dark sandal
tardy fossil
#

yea thats a bit too choppy imo

#

you dont happen to have your character movement component tick rate set manually to something do you

unkempt tiger
#

Anything I can do manually record an event or some kind of data during replay capture for better replay construction?

#

I have a custom method for maintaining a synchronized server time seconds clock on my player controller, but since it uses normal (non-multicast) RPCs, it's not being recorded by the replay system

thin stratus
# dark sandal aah is there no work around?

C++ with some ugly overrides, but the code change since I originally did that so I can't really guide you on anything.
The gist of it is that the Character sets a boolean in the Poccess function iirc that disables the ticking of the mesh.
And in the CMC it then calls TickPose from the Move RPC

#

There are reasons for this, but I honestly never understood it

young spoke
#

I'm getting a libcurl 65 error when sending a http POST from my server using unreal's HTTP module

LogHttp: Warning: 0x5bcc2f93200: request failed, libcurl error: 65 (Send failed since rewinding of the data stream failed)

from the libcurl message info cache, i can see the TLS handshake was completed. anyone know how to fix?

young spoke
#

nvm figured it out

zenith wyvern
#

I want an object to vanish when a character is near it, only for that character. I've got an on begin overlap on the object (which has a ref to overlapping char). Do i need an RPC on the player/controller to handle SetVisOnActor and to call that from the obj?

#

with RunOnOwningClient

unkempt tiger
cold magnet
#

Is trying to get references directly from a widget blueprint impossible when it comes to replication? What's the general flow for populating data on the clients widgets? I'm assuming using replicated variables and manually populating widgets from their owning actors and not from the widgets themselves?

sinful tree
# cold magnet Is trying to get references directly from a widget blueprint impossible when it ...

Widgets aren't replicated, so it's impossible to reference them across the network.
You'd need to replicate the data in a replicated actor and have some means of updating the widget when the new data arrives.
A good way of handling this is to have event dispatchers that your widgets can bind to and you call those event dispatchers in the OnRep functions of RepNotify variables passing along the new value into the dispatcher call.

#

For a quicker set up, you could just set up value bindings in the widget itself which attempts to retrieve the value on tick from the source, but this would still require those values to be replicated on a replicated actor.

serene kestrel
teal frost
#

There needs to be a meme here for cruising through developing multiplayer games on ue then crashing into a wall labeled latency

#

Anyone have any learning resources regarding movement and latency for unreal

serene kestrel
#

What aspect of it specifically, that's a deep rabbit hole

young spoke
teal frost
# serene kestrel What aspect of it specifically, that's a deep rabbit hole

Anything and everything I guess.

Specifically what started my leap into the hole

Test 1: everything is smoothish at 60-70ping from friend.
Test 2: game is unplayable because any client over 30 ping now teleports everywhere as well as (now fixed) but could flood inputs despite the checks i originally had to stack abilities before the server could tell them they were on cool down lol.

#

Went back after fixing the input flooding to Test with network emulation active, same thing client becomes unplayable for some reason.

Also to note
Playing the game on my 8 yr old half running laptop at 20 ping it works as it should

serene kestrel
#

Are you using unreal's default CMC or have you customized it? Sounds like maybe you have if you're doing some custom networked input scheme

teal frost
teal frost
serene kestrel
#

The default CMC shouldn't be completely unplayable with a bit of jitter/packet loss. What are your test settings?

teal frost
serene kestrel
#

Do you run into the same issues if you play on a local server with the same simulated settings? Could be that the steam public server is adding additional jitter/packet loss

#

What is your forced move threshold time set to?

teal frost
teal frost
serene kestrel
#

Try running it on your laptop and use the NetEmulation settings to add in some latency and see if the issue happens

dark parcel
#

for CMC you want to work with FSavedMove

#

most tutorial you found in youtube covering "sprint" in multiplayer with bp is fake and doesn't work in the real world where lag, no matter how tiny exist

quasi tide
#

About the only tutorial I've seen online that covers it is on Reid's channel

dark parcel
#

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

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

β–Ά Play video
#

should be the most informative for CMC

serene kestrel
#

^ If they're routing the sprint through the compressed flags it should be fine

teal frost
# dark parcel https://www.youtube.com/watch?v=urkLwpnAjO0&list=PLXJlkahwiwPmeABEhjwIALvxRSZkzo...

Thank you. I'll give that a watch in just a bit when I have a chance. I learned what you mentioned in your last comment the hard way last night.

Just really confused why things were smooth one day, then showed the true face last night. However, going forward I'm gonna do all network relevant testing with some form of emulation.

Hopefully this is just another hill to climb over and learn. Cause so far seems pretty daunting.

dark parcel
#

you should always emulate lag when developing multiplayer

#

the perfect world where network plays in 0 ms doesn't exist

#

even 5 ms, already make your movement jaggy if not done properly

serene kestrel
#

Movement is one of the harder things to get correct in multiplayer scenarios because even minor disagreements can be brutal to player experience since the camera is often tied to character movement

dark parcel
#

the video I sent cover everything you need to know with cmc

quasi tide
#

When I finish my mechanic/feature - I always test in 0 latency to make sure things are designed/functional the way I wanted. Then just go to normal emulation settings and then go to the worst one.

quasi tide
#

So - I do a lot of testing to address issues. Before I even package the project and test on a live network.

#

Because packaging and distributing and getting people together for testing is just a dang slog

dark parcel
#

Yup, take ages to test even with a laptop next to me

teal frost
#

I'm learning all this the hard way I suppose. This is the first time I've tried to move something to be tested. I thought the network smoothing etc was more or less what the network prediction would do. As well as the proper way to test things etc. Also had a funny lesson on setting logic up for the client to run and server to correct yesterday lol.

serene kestrel
dark parcel
#

some part of CMC obviously already implement it

#

but anything else you do, eg Shooting bullet, reloading, damage, etc will require work from your end

teal frost
dark parcel
#

well my brain not big enough for MP too

upbeat estuary
#

It's quite bottomless tobh

teal frost
dark parcel
#

i'm about to start my self

teal frost
dark parcel
#

Single player stuff

#

my Multiplayer project still stuck in character customisation and loading screen

#

about to finish so I have to deal with movement soon 😱

#

What MP game are you making?

teal frost
#

Well best of luck in your endeavors then. I'm pretty sure you will get it figured out quickly.

teal frost
dark parcel
#

I'm learning GAS for my RPG game but I don't know how much I can do in MP

#

always open to revert back to SP

#

I think if my game didn't work out I can fallback to turn based

teal frost
#

I think you will figure it out. Imo what I've learned so far on replication/multiplayer-networking, other than this movement stuff recently, isn't too bad once you get past the initial trial and error bumps.

#

i say the trial and error bumps because when you're making your stuff it's easy to get lost in what the tutorials are trying to impart on you sometimes.

quasi tide
#

Turn based games are so easy to network. I wish that was what I was working on.

humble wadi
# serene kestrel This is quite curious, I would maybe have expected option 1. to work without cor...

Odd as it may seem, it happens with 0 net correction too. Can confirm that both sides are playing the anim with the same params (play rate, delta time, etc.).
Even delgoodie (guy with really good tutorials about the CMC) was puzzled as to why these corrections happen with something simple as a forward dash, and so on. I'm starting to think it might be related to floating point errors or something as logs seem to indicate that when client and server are playing the root motion montage, they're both progressing the animation at with the same delta time (I believe server uses client's delta time to progress the anim at the same rate/steps). Then when the delta translation is extracted, for that tiny part of the montage, it continues on next tick. So what I'm seeing after some time, is some divergence in RM extraction start and end positions but the error is sooo small (in the 0.0001 range), that it might be irrelevant, idk.

I've tested this in a clean project as well, the issue seems to happen there too.

unkempt tiger
#

So after some research I couldn't find how to properly get a correct 'ServerWorldTimeSeconds' during network demo playback, so I ended up having to modify engine code and put float GetDemoServerWorldSecondsAtStartOfRecording() const { return ReplayHelper.PlaybackDemoHeader.ServerWorldSecondsAtRecordingStart; } inside the DemoNetDriver (with the corresponding ServerWorldSecondsAtRecordingStart member inside the FNetworkDemoHeader struct, so that I can then add it to the final GetServerTimeSeconds getter...

Can anyone confirm that this is indeed necessary, and that indeed there is no better solution atm in the engine that I might have overlooked?

queen mortar
#

Hey I have a problem where Media texture won't play on different computer. I have a mechanic where you have security cameras and when you switch between them a sort of "tv static" video plays. I tried testing it with my firend, but when he tries it, the "tv static" just doesn't work, but for me it is working fine. No matter if I'm client or listen server. Also when I try testing in ue on client, this error keeps popping up. Accessed None trying to read property. Node: Add to Viewport. Because the static screen is a widget

serene kestrel
magic vessel
#

I'm trying to replicate a UObject within an actor component but I cannot get it to replicate properly

UCLASS(Blueprintable, BlueprintType, Abstract, meta = (DisplayName = "CustomObject"))
class CUSTOMSYSTEM_API UCustomObject: public UObject{
    virtual bool IsSupportedForNetworking() const override { return true; }

    virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

    UPROPERTY(Replicated, VisibleAnywhere, Category = "Custom")
    TEnumAsByte<ECustomStatus> CustomState;
}

void UCustomObject::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    UObject::GetLifetimeReplicatedProps(OutLifetimeProps);
    DOREPLIFETIME(UCustomObject, ECustomStatus);
}

How I am instancing the Objects:

UCustomObject* CustomObject = DuplicateObject<UCustomObject>(Base->GetCustomObject(), this);

    if(!IsValid(CustomObject ))
    {
        UE_LOG(LogTemp, Error, TEXT("CustomObject is not valid"));
        return;
    }

    InstancedObjects.Add(ProgressObject);

    // AddReplicatedSubObject(ProgressObject);
    OnRep_InstancedObjectsArray();
#

I'm authoring the objects in the editor and using them as a base for the duplicated objects

carmine canopy
#

You must replicate it manually through owning actor channel (the objects' outer must also be set to the same actor)
In owning actor or component owned by the actor, you can replicate it in UObject::ReplicateSubobjects function by calling Channel->ReplicateSubobject(MyObject, *Bunch, *RepFlags);

#

You can check how GAS is replicating the attribute sets
UAbilitySystemComponent::ReplicateSubobjects

cold magnet
#

What is the generally idiomatic way to update connecting clients with stuff that's already set on the server? OnRep_Something doesn't trigger when the client connects because it already happened on the server before connection

Nvm I'm dumb, my actor's Replicates was false πŸ₯±

somber glade
#

Weirdest thing. In a listen server situation my host has just stopped executing 'on post login' for itself. It executes it when the client joins, but not when it starts the session in pie. This has been working flawlessly for a week, and all of a sudden it stopped working a few minutes ago

#

I hooked up a print to on post login and it only fires once for the client. I have video of this working only a couple days ago. What could possibly stop the hosts player controller from calling on post login?

somber glade
#

if i start it as a listen server with 1 user, the server does run post login. server + client and the server doesn't run it for itself. this project is haunted.

latent heart
#

The server doesn't log in to itself...

#

Post login is called when a player joins, for that player. Be it remote or local.

#

A dedi server has no player, so nothing is called for it.

somber glade
#

I'm talking about on post login on the game mode.

#

I do two things on post login, assign a player area and a colour. That's been working fine for host and client and has just suddenly stopped.

#

In this situation, it starts a 'server' and this prints once, for the server. If I change this this to two, it starts a server and a client and only prints once for the client. It wasn't doing that yesterday.

dark sandal
real ridge
#

Anyone used new online services from unreal which came with unreal engine 5.0? just curious I am still at EOS buy may change if there are any advantages

magic vessel
#

So after some experimenting, I have realised where my code is going wrong. The duplication of the object for some reason means that it won't replicate

// This works but the variables will not replicate yet
    UObject* Object = NewObject<UObject>(GetOwner(), Objective->GetObject()->GetClass(), NAME_None, RF_NoFlags, Objective->GetProgressObject());
// This won't work
    UObject* Object = DuplicateObject<UProgressObject>(Objective->GetObject(), GetOwner());
pseudo kernel
#

Should I expect PlayerState->ExactPing to read out ~140 on local players with this setup?

teal frost
# pseudo kernel

I think when I ran 60s across the board it said my client ping was like 180-240 lol

pseudo kernel
#

Ok cool so it's not just me

teal frost
#

Dunno how this works exactly so idk if it was reading accurately or not

pseudo kernel
#

Maybe your numbers make sense if its set to both clients and server?

teal frost
pseudo kernel
#

60*4 would be like 240

teal frost
#

Makes no sense to me. I gotta dig into the documentation or something about that feature tbh.

teal frost
# pseudo kernel 60*4 would be like 240

I don't think it adds all 4 values
At least to me logically I believe it's supposed to fluctuate between the min and max
And add together the out and in values of each occurrence for the actual ping

pseudo kernel
#

Well if the target was set to clients + server then I'd expect the delay to be applied on both

#

but in this case it's just set to client and im still getting 140 where I'd expect closer to 100

teal frost
pseudo kernel
#

yeah for sure

teal frost
#

But just play with it til you get it where you want

#

Try the 0/1 like I did see If you get the same results I did.

pseudo kernel
#

I'm guessing I can at least trust PlayerState->ExactPing on the client?

teal frost
#

I think it put me at 80

pseudo kernel
#

10 is putting me at 61 rn

#

40-60

teal frost
pseudo kernel
#

I saw UT uses it for prediction so I'm guessing shrug

#

I had my own ping that accumulated 10 seconds and dropped outliers but I was wigging out since it was still off

#

then this is also off, but even more off, probably because the averaging is different

#

but I guess yeah you have a good point, I'll just play with numbers until it reports what I want for the in-game ping...

teal frost
#

Yeah, could be.
I know there are plenty of features in unreal that don't mesh together like they should be expected to.

teal frost
pseudo kernel
#

Yeah good idea to look into

#

ty

#

Setting 10-15 for min/max on in/out for both client and server gets me to 100ms so w.e.

teal frost
#

Nice. Well hopefully it holds up the way you expect. Best of luck on your project πŸ‘

quaint rain
#

Could use some advice: I'm trying to determine where to build my on-kill logic. Things like awarding player xp & calculating loot drop. Would that sit on the player pawn or the game state, does it matter?

fossil spoke
#

Those are like very different things

#

Awarding XP and doing Loot Drops are totally different

#

We set up an custom "Awards" system which designers can create any type of award they like, which Players can attain for different things (like Kills, even deaths for particular reasons).

#

An Award can give the Player XP

#

It even handles doing UI stuff

#

And playing Sounds etc.

#

It sits on the PlayerState as a separate encapsulated component.

#

The Server issues Awards, they get replicated down (via just an incremented integer).

#

At the end of a match, all the Awards are "counted" and that becomes the final XP amount for that Player

#

They also get sent to the backend by the Server to calculate rewards and update player records etc.

quaint rain
#

Oh cool, that sounds pretty clean. Thank you!

pseudo kernel
#

@fossil spoke Taking it back to the projectile conversation from the other day, I read through the UT source code and got some good ideas on how they've decided to handle things, so thanks for that tip πŸ‘

#

One thing I couldn't really understand is whether or not UT silently suffers from phantom hits, both on the shooting client and the client getting shot. Maybe it's just less obvious in an FPV but it didn't look like they were doing anything there - maybe their custom movement comp / prediction is just good enough to avoid that case a majority of times

fossil spoke
pseudo kernel
#

I saw they have rollback for hit-scan definitely but projectiles, I'm not too sure

fossil spoke
#

It likely does something for Hitscan shots

#

But not for Projectiles

pseudo kernel
#

yeah

#

I almost wonder if in a top-down game it's better to not predict since it's more obvious on having phantom hits, then maybe I can just make it server authoritative and make the hits "look" good when / if they happen

#

I guess if the projectiles are in the past a little bit I get more time to smudge it when the server decides there's a hit

fossil spoke
#

There is really only so much you can do.

#

Are you expecting having players with high ping differences playing together a lot?

#

Seems like you would want to prefer them be closer

pseudo kernel
#

I was trying to target having like 100ms ping be playable

fossil spoke
#

Which drastically reduces the need to solve that issue

#

This is a lot of the reason why Region locks exist

pseudo kernel
#

yeah true

fossil spoke
#

You just simply cant get around the physics of the issue

pseudo kernel
#

yeah

fossil spoke
#

Generally, you usually target the best play experience for the Player doing the actions

#

And then limit the ping differences

pseudo kernel
#

makes sense

#

Ever thought about things like adjusting the hitbox on the server based on movement?

fossil spoke
#

How would that work?

#

Thats the same as rollback

pseudo kernel
#

Yeah that's where my brain stops, it sounded like a cool experiment but it's just a shittier roll back

fossil spoke
#

Just buffer old positions

#

Rollback on the server and check against whatever it is that needs verifying

pseudo kernel
#

Yeah I have that in, just need to use the saved positions

fossil spoke
#

Honestly, unless this is a fast paced competitive shooter, you wont need anything more complex than a simple rollback for hitscans

pseudo kernel
#

Was trying to do a top/down style moba game, maybe something like battlerite

#

so proabbly wont have too much hitscan besides melee attacks