#multiplayer
1 messages · Page 86 of 1
do i have to cast to the level blue print or something to properly obtain the ref?
its weird though cause the camera was working
got it workin.
I don't think you need to cast anything there.
The camera ref is from the level which you put it in the map.
i got actor of class and it worked
anyone else had issues with the Pawn's OnRep_PlayerState on simulated proxies?
like it's not being called sometimes
does APlayerState::CopyProperties get called on the client?
I have read about multiplayer basics, from types of servers to how they communicate with clients. Additionally, I have also made an online game using only python and got the server-client relationship to work by hosting a dedicated server. I want to do the same with unreal engine.
I have a rough prototype of a game but I can't really test much or continue development because everything depends on it being online with 2 players (most logic will have to be refactored once I make it online so I should start with it being multiplayer).
I want to make a dedicated server, and have most logic run on the server. I only use BP's.
To start; How do I create a dedicated server so that 2 players can join a server and play a simple 2D top down game?
I'm only about 95% sure. But I don't think it does. At least from what I can tell, all three of the code paths that call it all originate from GameMode
Yup, I've checked and the breakpoint doesn't hit 😦
Game instance for storing persistent client's data it is then
to start, you need to compile unreal engine source. the binary doesn't allow u to make dedicated server builds
then you need to decide if you are going to manage the server yourself (either manually by logging into the server and opening the .exe or through some scripts)
or use a managed service like AWS gamelift or microsoft playfab
since you are starting out, just use manual deployment. your isp won't let u host on your own computer so u need something like an EC2 instance
then follow this guide to make the build: https://docs.unrealengine.com/5.1/en-US/setting-up-dedicated-servers-in-unreal-engine/
gameplay side you said simple 2d top down game so it should work out of the box in terms of movement
after the server is up and running, open the game client, press ` and type in "open" followed by the IP address of the server
In Actor_BP, when I overlap a Box, I want the operations to run only for those who go inside that box. The "Is Locally Controlled" and branch method worked. So now the Print String is only reflected to the person who enters that box.
But when I do a visibilty operation it doesn't work. The visibilty works for everyone. I chose "Owner Only" for RepNotify, they didn't work either.
Any recommendation?
So let's say user 1 enters into the box, Visibilty just turns disable for him, so the system works fine. But when the 2nd user enters that box, Visibilty is opened automatically in the 1st user.
Pretty odd.
If you just want the visibility affects the local player, you don't even need to set it by server. Just simply local set it hidden, that's all.
Yes, I did that at first, it didn't work. After that I tried the RepNotify method. In fact, the system is working, so when I enter it, visibility is turned off locally. But when one is inside that box and the other one enters, visibility affects everyone. So the closed visibility is opened again.
Does it work for local player just set it on off?
Visibilty system works fine for local player. So it disables when I go inside, it opens when I exit, and that's what I want.
It also doesn't affect others, the system is fine and local.
But if someone else enters that box while I'm in that box, visibilty is opens for everyone.
I mean you don't need anything from server, like replication or RPC because you just need it to be local right?
For instance, I have my view and you have your view, we are different clients, is this exactly you want?
Oh, I mean this system doesn't work.
So you have the actor and the component replicated?
Help, my clients connecting to another player start as spectators… I tried everything I could but to no avail. Yes, I checked the start as spectator box in the gamemode but it’s inactive. The thing is I have no spawning logic, the engine has a default player pawn but it will keep spawning the spectator. Thanks in advance.
Pawn is replicated, but Actor_BP (which I enter) is not replicated. Frankly, I don't know how to Replicate this fixed object. Am I going to do a spawn operation on the GameBase side?
That's weird. The actor is not replicated so it should always work individually. Did you spawn it or placed it in the level?
I just placed it on the level.
So not spawn
No spawning, no replicating, it should be like the single play game😅 The graph you said not working is?
Character_BP is replicated but Actor_BP (box) is not replicated, no spawing, just placed it on the level 😅
It looks nothing wrong. But are you sure your pawn instigator is valid?
You can make it more explicit that I just want the pawn and the pawn is local controlled.
all actors placed on the level are loaded on clients from the package as long as bNetLoadOnClient is true (it is by default), and while not replicated, they are all net addressable
How can I do this?
And how can I do this too? 😅
Cast the others is a player pawn and if it is, get the controller (usually if it exists, means it is local controller, lol)
Hey Guys ok so i have an "item" on the map when a player walk close (collides) it should do stuff. the problem im having is when im colliding im casting to player player Bp from collidings actor, but it gets called on All clients Player Bp hence alot of null errors from those parts
how can i choose wich player bp only to cast from ?
to*
check if its LocallyControlled
Yeah, feels like similar questions being asked at the same time from different channels
well it felt more like a multiplayer room question hence i dident get any answer from the other channel 😛
how do i check if its locally controlled
drag it from pawn and search is local controlled.
from other actor ?
or
something like this :/ ?
hmm seems to work 😄
also when destroying Actor it still leaves the collision in world do i need to destroy the actor on the server only or also ?
like why is this happening ?
Usually the object needs to be replicated, and destroyed only on server.
erhm ok,
cuz mine wont dissapear
or it dissapears but hte collision is still there :/ ?
If it is destroyed the collision should be there, but if it is just hidden, could be possible
oh its the is locally controlled thats whats messing with it
i think you need to destroy it with the multicast RPC
oh yeah true
in my topdown game, i dont want my mouse to click through a player capsule i disabled overlay events and made collision query only but it still lets the click go through the capsule when i click a player and my character starts running to them
Hey Guys, I have a weird issue with blendspace locomotion animations. When i test it in editor all works perfect and when testing via steam the server sees the client animations slower, like, way slower! Although the velocity values are the same. tested it via print string, i dont have a clue anymore whats the issue. Anyone stumbled upon this?
Unlike regular animations, ListenServer ticks the anims of clients via the move rpcs. So if you have less frames or longer duration between those rpcs (ping) you might see some strange behavior. You can try emulating network latency in the editor
Hi guys, is the dedicated server optimized by default to only compute relevant things?
For example, if I have built the server and it is on my AWS, is it also going to waste computing power on simulating physics, and so on?
It will run the code that it´s written, it probably doesn't run graphics stuff but if you need CPU optimisation I'd say that needs to be handled manually, because Unreal doesn't know what is relevant or not for your game
Because our game is heavily relied on physics and the CCD in unreal is not taking into account the angular velocity we had to tune the async tick to about 620hz, does it mean that the server will also run this simulation?
by the way the ball isn't replicated if that matters, the simulation runs on each machine
I think so, if your game relies on physics then the server also does. 620Hz is a crazy update rate, unreal server runs at 10Hz iirc by default
Valorant run at 120Hz iirc, but I can imagine that needed lots of work
Yeah, we will eventually have to re-create the collision algorithms from the source code, but at the moment our game isn't reliable for anything less than that
if Im doing the steam listen server method, is there any way to set up a play test without it being published on steam?
I thought that the async tick is irrelevant to the server, isn't only the replication tick relevant for the server?
what is a replication tick? Physics can tick async but that's still gonna happen on the server (that's one of their usages, to have more deterministic simulations in multiplayer)
the replication tick is 120
It's a VR game so the client does the collision detection and updates the server about the hit
the server is not deciding on the hits, the ball isn't replicated
but I'm not sure if the server will simulate how the ball moves just like the other clients do
Somebody with experience in multiplayer physics should jump in but I'd asume server runs physics too
It does
Why aren't you just substepping instead of trying to run the game at over 600Hz?
ye makes sense
does Chaos substep too? I thought it just did an async tick
are there any good tutorials for settings up hosting with steam, every one I can find is a real mess
Same thing started happening to me when I upgraded the project from 5.0 to 5.1 without any other changes. If playing as ListenServer and simulating lag, other clients animations are playing in slow motion and choppy. Clients see each others animations correctly. Might be worth checking what happened to CharacterMovementComponent or AnimInstance between 5.0 and 5.1.
I was hoping that 5.2 will fix it, but it didn't so haven't looked what causes it yet...
Oh, wow! Well, it makes sense i couldnt find any help with the problem, seems to be a new one. Sadly, i didnt find any fix yet, also.
@rapid sky @cinder quartz again this has been a thing for a very long time
ListenServer doesn't tick anims for simulated clients. It only updates them when a Move comes in via RPC
There is some location smoothing iirc but I don't think the anims are smoothed
No, this is different. Client animations are running in slow motion, like play rate 0.5, baywatch running and it didnt happen in 4.26, 4.27 or 5.0
You need to change a few things and override some CMC function to get this to happen on tick
Hm. Okay
for me it started happening when going 5.0 -> 5.1. the choppiness was always there for listen server, but the lowered play rate wasnt
tho it seems to work correctly when not simulating lag, so no idea why it is like that
more ping = more slowness
yes, play rate seems to be affected, super weird.
just tested on fresh, new 3rd person template 5.2 version. Also happens there when enabling network emulation with bad condition, the client is running on slow motion on hosts screen
Got any links/info what those few things are?
I just set up hosting and joining in my project, now how would I go about testing that with someone else? as far as I know its gonna need steam or something right
Thanks. The comment says in ACharacter::PossessedBy "If we are controlled remotely, set animation timing to be driven by client's network updates. So timing and events remain in sync.". Why does listen server need special things to stay on sync but dedicated server doesnt? Animation events will still fire on dedicated server right?
dedicated server does not play animations
listenserver does
there is no visual rendering
it still has to keep track when animation events fire?
yes it runs the events
but it doesn't do any rendering
so it doesn't need to be as precise
its weird, but it is what it is
oh so the comment just means "keep visuals and events in sync"
yes
kinda strange it isnt a toggle in engine, I mean the fix is 5 year old and still applies lol
we hit many pitfalls with listen server
but we solved a lot of the animation issues like the slow mo
would it be practical to start dedicated server in the background and connect to it?
if your game is going to use dedicated servers
just use play as client in the editor
it will spin up a dedi server
I mean in a released game, let's say I want my game to be multiplayer with steam friends, but don't want it to be listen server. So If I start a game, my game would start a dedicated server and join it locally and invite my friend to it
no
your friend or you would need to launch the dedi server
then you connect your clients
to that server
is there any other know issues to listen servers other than animations?
for a small game, its easier just to run listen servers
dedicated servers is a big thing
not really
i mean sure there is some nuances, doing dedicated server stuff is easier for mp
listen server, you need to ensure stuff happens correctly, else things break (like doing x on the client but forgetting the server)
like playing montages, etc
then you have the fact listen server has all client, so things like GetPlayerCharacter static is a no no
I can confirm that the reddit fix fixes the animation play rate issue.. and those smooth listen server animations look great!
I'm not too sure If I'm going about this in the right way, but Im trying to create a respawn mechanic where the player can pick up a cube, take it to a respawn point and the dead player will respawn, currently struggling on the first hurdle of the player picking up their respawn cube, so what I've done is I've stated in the First Person Player blueprint, when dead, spawn the cube and store their player controller, here is an image of that in action:
I've then stored that information on the respawn cube from the spawn node:
At this point, it works, the text above the cube shows the name of the player who it belongs to, Then I use a line trace to pickup the cube and store the players controller inside a variable in the FPS controller, but for some reason on the print string, it prints nothing, as if nothing is being stored in that controller
If anyone has any experience in multiplayer and can guide me in the right direction that would be a huge help
Question about RPCing
if this is a variable and that variable is replicated how do i need to tell the sercer/other clients when the value is changing
do i need to cast to server>multicast and then set the change
or just server or
could someone explain really simple why/how
Client wants to do a thing -> tells server (Run on Server Event) -> server sets replicated variable -> now everyone knows about it
Ok so multicasting is only for sounds speciall effects basicly ?
Maybe some more stuff but yeah don't bother with multicasting for the core of your logic
Replicated variables with RepNotify are super powerful. Learn them and use them.
I was gonna say, he needs to use set w/ notify tho, right ?
Depends on if you need some logic to run whenever it changes
Sometimes you do, sometimes you don't
Repnptify gotcha ill look into it
Why store the player controller, if you don’t mind my asking?
so how do I set up the steam stuff
is it even possible to use their servers on a game that’s not published there yet?
That was the only way I could think of doing it as the player controller contains the custom events to spawn the player
So does the player's pawn turn into some ghost type thing when they die or do you remove the pawn and spawn some different pawn for picking up the cube?
What is the player "driving" when they are dead?
This is the initial part of their death, a spectator gets spawned to which the currently owning controller of the FPS character possesses the spectator, a ragdoll effect happens to the players mesh then, like in the screenshot before, after the spawning of the spectator, the cube spawns
This all happens when the players health reaches 0
Once it reaches 0, Spect_Mode is called
ok so they change pawns
just call RestartPlayer or do the equivelent when they bring the cube to the thing
This code should live in gamemode
Hey mr gamemode, i died xd, give me the ghost pawn now plz
Ah I see
Also
How will the cube know to bring that player back when they deliver it to whereever
@dark edgein case of changing the bool on server do i need to change it localy also or only on server ?
that's the whole point of replicated variables
server sets it, everyone else gets it updated automagically
ah ok
Well if you’re not destroying the actor you can prly still use overlap events on it
That trigger a function within that player’s bp
If ded 💀 and cube is touching me 🤚, bring me back to life
At least, in theory😅
Oh yeah, why didnt I think of it that way haha
Hello guys how are you doing? I have a question I want the server to know what is the value of the variable "attack anim1" which obtains its value from a struct. I replicated the variable and also RPCed the function where it gets the value. What am I doing wrong or what can I do to fix it? thank you so much.
You should Run the Custom Event (RunOnServer) on the PlayMontage side you aldready added. Then this variable should work RunOnServer. So add variables to the input of the events, connect these variables to the animations you want to run.
Hello. I have a question about movement replication for anyone who can help.
On the server, I'm using the AddActorLocalOffset node. Now, despite ReplicateMovement being unchecked, this movement is still visible on the client. 🤔
Does anyone know how movement could be replicated without ReplicateMovement being checked?
Any advice would be appreciated. 🙂
Cheers.
On the server
How do you know you're on the server?
And how does the actor get spawned? Is it just a plain actor? or a character with a CMC?
The answer is that relative location of attached actors is replicated it would seem. 👌
how do you play test a project with other people before its published? if Im using the steam method, wouldnt it need to be published or something?
You can package your game and distribute it that way.
wdym
Upload it to steam. Give your team dev keys or other people playtest keys.
you don't need to publish it, you can playtest it as long as everyone as a steam account (and it works properly)
ah nice
Ive set up the joining and hosting already, but how do I get that to use steam?
if you have it setup properly, and have the steam subsystem enabled correctly, you should be able to host and join with no issues
I used the default session nodes but not sure what the steam thing is since I enable the plugin but dont know what next
somehow I remember getting the overlay working years ago
theres something in the .engine or that you have to add to enable the subsystem. Cant remember it off the top of my head though
you mean this stuff? https://docs.unrealengine.com/4.26/en-US/ProgrammingAndScripting/Online/Steam/
An overview of Online Subsystem Steam, including how to set up your project for distribution on Valve's Steam platform.
yeah that's it
I recommend watching some tutorials, multiplayer is a tough process
yeah as I said earlier all the tutorials are a mess
joining and hosting works on the same network already
If you have everything in the .engine, and the steam subsystem plugin enabled, then the issue is your blueprints
once you have those 3 things working, you'll package the project and have everyone test it out
no I havent even gotten to that stage because apparently I have to set up the whole steam page now or something
No you don't need to set up a steam page
You'd send the packaged project to your friends, and they'd open the game up from the file
I know but I cant see any other way to access the thing I need to download
What're you trying to download?
on this page it immediately says to download the thing
Oh don't worry about that yet. That's for actual release and isn't needed for playtesting
so where would I get what I need for the rest of whats on this page
scroll down to "finished settings"
you can copy that, its the basic stuff of what you'll need for playtesting
yeah I thought that
my defaultengine ini has a lot of stuff already so do I take all of that out?
yeah nothing
and this is enabled?
yeah
Try exporting the project and launching it from the file exported
if that doesn't work, create a blank project and just add .engine stuff + subsytem
wheres that
on the dropdown to select in editor, standalone, etc its at the bottom
I looked there but I dont have those options
Did you select advanced settings
would it be this
4.26
Try searching up "auto connect" in the search bar up at the top
just this
yeah, overlay shows in packaged game but also now it cant start a server
In this video we take a look at the finished project and step through each of the features that will be covered in this series. We show our functional Main Menu and its options, a lobby where players can chat with one another and select their characters for the game, some server options such as changing the map or match time as well as the abili...
here follow these vids, theyre very simple
try making a basic host/join project before you do anything big
I did, I just said that already works on the same network, I can join "myself"
just not now that its using steam
It could also be something with your blueprints too
are there not steam specific nodes?
not necessarily steam specific I think
you're using bp yeah?
The basic "host session" "join session" "find session" should work for you
oh, it DOES let me host now? a minute ago it was doing nothing
I assume you cant connect to yourself with steam though?
ok thanks for the help guys, Ill see how it goes now
so you either run a server or run the client iirc
its a bit shit
maybe you can run the server and client together, but i gave up with steam a while ago (steam's backend)
EOS is the way forward
Multiplayer overall is a beast to take on, make sure you've got some knowledge of bps before you start a multiplayer project
it'll stunt your growth
Ive been using unreal for 6 years lol
played around with a little bit of replication once
oh wow
i started game dev 5 years ago
Oh nah you'll be fine then. I think ue5 is good for multiplayer right? -- might be wrong though, heard some good things
at the ripe age of 32 😛
I imagine ue5 would be overkill for this game, graphics are cartoony and Im hoping to optimise it well
yeah Id like to try someday, but I dont even have the space for it right now actually, and not sure anything I make will need such a huge engine
there's a whole new replication model with Iris, but it is still really new and experimental
Ah that's what it's called. I don't really know much about it to be honest, just heard that some people were liking it
There's a good guide/explainer here on it https://dev.epicgames.com/community/learning/tutorials/Xexv/unreal-engine-experimental-getting-started-with-iris
I’m 2 years behind lol 😅
that link really explains very little about Iris
If you're struggling with current networking for Unreal, don't even think about Iris.
This variable (array of structs) is set to replicate but inside a spot where I need it to replicate it says "None"
The little white marks on the node indicate it is marked as a replicated variable. You cannot change it where you're looking as you aren't in the class where the variable exists.
Ah, roger... wish it would say it's replicated at least.
Having the strangest issue where the array is not replicating, or does not appear to be
the server's version of the array has the item, but the client never receives that version
then when I transfer to my inventory it's like, oh... yeah here you go
The client somehow knows items were made and they show up in the inventory as essentially blank items, but of the correct type
all the client is receiving is the very basic slot struct, not the rest of the item
til I drag/click to add to my inventory
This right here is where I am somehow not able to replicate the "Item Struct" to the Inventory Content array
Set Array Elem is setting Item Type, Item ID and Quantity but that struct is left behind
@round acorn was it you that was doing a damage numbers widget over an actor’s head a while back ? Sorry to derail 😅
I dunno what's up with this but when I multicast the update to the inventory content array it works fine... why can't I just rely on the server replicating the values to the clients?
erm, yeah I did that a long time ago
Is that a RepNotify array?
For sanity, set the array* with itself after calling the set array element node
Curious, what does that do?
Maybe fix your issue. I had issues in the past with some of the array altering nodes not triggering certain replication features. It's mostly the OnRep part, hence the question, but can't hurt trying
Yes
Ok so odd question here. I have requested an API for some data, on the dedicated server, and I am firing an event on the client. That part is working, however, the data I am passing back to the client is null. Is there some 'replication' thing that I should be aware of? I am trying to send a VaRest Json Object to the client. Or should I just move the request to the client instead?
At least for OnRep it solves the issue of not causing the OnRep call
I assume some code is tied to the Set node that the other nodes don't cause
In BPs that is
no dice, but multicasting the Set Array Elem works just fine... I don't get it
Hmpf. Sorry. Hoped it was a similar issue
UObjects don't replicate by default.
Is there a way to tell if I am exceeding the max bunch size on replication?
Try sending the JSON as a string instead @storm zinc
Logs I would assume @round acorn
Ahh ok. I will try that.
assuming that would be a warning or an error, not seeing anything re: that
@round acorn so you have any conditions on that array replication?
no conditions
If you tick the UI refresh on the client, does it then start working?
Maybe some sort of race condition?
that was what I thought too but no, it stays the same... til I run the function to take an item from the container inventory to the player inventory and then the server gives me the item in all its glory
Hm sorry, not sure the at then moment. 🥲
Will head back to bed. Woke up from some random a** nightmare. Hope you figure it out. Probably something small.
Appreciate you helping out! I'm gonna use the multicast crutch for now lol
Kinda silly question, but have you tried restarting the editor?
haha yeah a few times
How are you relying on your UI to update in general? Are you using binds to read the data from the inventory?
binds yeah
but I print stringed the client's copy of that inventory array and it was empty
I mean wtf... it's set to replicate and it's just not replicating
it's running on a Server RPC and I've confirmed the RPC is executing
alright yeah I still got nothing
Does the array live in a component?
got my friend to open it and we both tried hosting and nope nothing shows up
Yeah, Inventory System - which is set to Replicates
I'm doing this updating of the array from a different place though, the Item Data Component
(which is a component owned by the same actor that owns the inventory system component)
It doesn't really matter, as long as the original outers replicate you're fine
I tried serializing the whole thing to see if I was overloading the network but that made no difference
I vaguely remember a very odd issue of having only 1 property in a component doesn't really replicate that property
But adding another property will make it replicate
ah I almost forgot how much of multiplayer is "why doesnt this thing work when I literally went through every step"
Not sure if the other property needs to replicate or not (most probably yes)
And it's really odd and even rare?
Never happened to me
Maybe because I don't have components with 1 replicated property?
My Inventory System Component has 4 or 5 replicated properties (prolly 4 of them aren't actually being used though lol)
Yeah maybe it has to be set even
Because I tried making a new property and using that instead (didn't work of course)
Not really sure about the specifics
But you can try it
Literally a boolean that you set to true on beginplay
And that it replicates ofc
there is a bug where property replication fails
oh set replicates specifically
with 1 replicated property
lol
not sure I understand the way this bug manifests
so is there anything specific that I need to add for steam servers? hosting and joining myself works without it I set that up
you have a component on an actor and the component has one, and only one, replicated property? and that fails?
yes
we experienced this with 1 replicated prop
where replication would be, lets say, intermittent
and actually in the editor itself I can still connect to myself just fine
interesting that I think I'm only actually using 1 replicated property here on this component (there are others but they aren't in use)
but in the packaged project it uses steam and nothing happens
feel like that might be an #online-subsystems thing
Do you need to set that replicated property you added at runtime? Or you don't need to? @meager spade
So for example EpicFailsAgain=false
that wouldn't necessarily look like this, for us BP plebs?
Nah
that's inside my inv sys comp
I mean, I just added it, it wasn't there 5 mins ago. Aye properties
this?
You should make sure this is ticked
Was it resolvable by adding another replicated property into the component (e.g. that bool)?
I'm gonna try that even though I already have a couple other replicated properties, gonna do some experiments
lol editor crashed when I deleted a variable with 0 references project wide
gotta love it
Just in case you guys are curious what it looks like in action...
Is there anything wrong with calling a function within a Server RPC?
No?
I'm doing Server_GenerateLoot (RPC) and within that calling Generate Loot, which is a function in that actor's event graph.
That's the flow
And it does a lot of random generation in there, server side. Stores all of that in a struct, inside a struct, with quite a few other structs inside that even.
Doesn't matter
Server RPC is running on the server
That data you pass is what actually transmits across the wire
If I update the Array of Structs in that server RPC I shouldn't need to pass it anywhere though right? It's set to be a replicated property.
So anything after the execution pin is running on the server
I mean, the Server does indeed get passed the correct array of structs
the right instance
And it updates the value in there in that Generate Loot function
And I would think it should just replicate from within the Server RPC
Is that just... not the way it works?
Because when I pass this new item to the Multicast it works like a charm
Replicate from within the RPC? No. It may change a va lue on the server and that will eventually be replicated to clients.
But it is in no way instant.
This is the part I am not clear on tbh
If the server updates its copy of a replicated variable doesn't it immediately (like within a few frames... maybe a second or two) start trying to update client versions?
(Granted, there's always lag to consider)
- Client tells server "hey, here's a value" using an RPC (because replication doesn't work client to server)
- Server checks value and updates its settings
- Server then either (or maybe both):
- Uses regular replication to update the clients (eventually) about this change (99.9999% of cases)
- Sends a multicast rpc to immediately inform clients of an important change (0.0001% of cases)
Makes sense, and what I understood
But I'm waiting several seconds and this data is not replicating, but with a multicast it replicates instantly
(well, close enough)
The replication part isn't instant. Property updates are queued and sent based on priority.
It shouldn't take a few seconds, though.
Right but it's just... never getting there
Is the property actually set to replicate?
BP or c++?
BP
Is the component set to replicate? Do other properties on the component update?
yeah the component is... other properties, not sure. I believe a repnotify is working for sure
Repnotify... of what?
full inventory transfer completion
What I mean is, if repnotify is triggering then something is replicating. What is it and what object is it on? Is it on the component that should be updated with this troublesome value?
I just built a little test to see if the component is replicating
and it's... not working in one instance
Meaning?
not sure which instance of this component yet, but one of them (of 4) is not receiving a replicated bool
Are you creating any of them on the client?
Like creating them at runtime instead of at design time?
mmm, no not on this testing I don't think
Be sure 🙂
oh lol hmm
this might be an issue
4 instances of the component
3/4 are getting the server replication of the bool
1/4 is not, the top one
They don't look like components.
Also PlayerStateCharacter is... a bad name.
okay so that 1/4 false was a pawn that I'm loading from a level instance to do my character preview (it's a janky test setup)
so that wasn't the issue
Okay.
If it's a character preview, it shouldn't be on the server, surely?
It's just client side visualisation?
like I said, it's janky lol
yeah
I just dropped my character BP into the level for testing of the camera setup
Ah okay.
Component is definitely replicating
hi guys, im using server travel to move my host and clients from the lobby to the main map but i get this error, i thought I was doing this right
I type Host into console and get the error in the picture, doesnt work when running the game standalone if i run in editor, works fine, i move levels with no problem.
the code runs as i can see the prints on the screen
sorry to interrupt the above convo
relevant code:
void UPuzzleGameInstance::Host()
{
UEngine* Engine = GetEngine();
if (!ensure(Engine != nullptr)) return;
Engine->AddOnScreenDebugMessage(0, 10, FColor::Green, TEXT("Hosting"));
UWorld * World = GetWorld();
if (!ensure(World != nullptr)) return;
Engine->AddOnScreenDebugMessage(0, 10, FColor::Green, TEXT("Changing maps"));
World->ServerTravel("/Game/ThirdPerson/Maps/ThirdPersonMap?listen");
}
What value isn't updating, what are its settings and how are you changing the value?
Is that a packaged game error or PIE standalone?
packaged game sorry
It's likely that level just isn't being packaged.
A text-based link like that in c++ does not mean the map will be packaged.
You should add it to the list of maps to be packaged in your packaging settings.
hmm ok, ahh ok just to confirm this is how u package?
I would say so, yes.
The packaging settings might not be there, but in your project settings.
yepyep
Also #packaging
does client authoritative movement work for pawns that are owned by the client but not possessed?
does anyone know the bottleneck for scale when replicating a lot of attributes in PlayerState (like in the default GAS setup)?
is it server CPU/mem, server kbps out, client kbps in?
i currently have a GAS on playerstate, which replicates all player attributes to all players (since playerstate is always relevant)
and im planning for 20 players in my game
was wondering if to support 20 players i can just get a bigger instance
instead of using a replication proxy
You could have a thousand players and probably not have a memory issue.
The important part is how often those values change, not how many there are.
CPU is likely going to be the limiting factor here.
But as with anything else performance related, you really need to profile it.
^
As performance encapsulates everything.
Sure you can target specific parts, but its only going to be in relation to the whole.
Profile, optimize, profile again.
i mean with memory side of things, just ensure the dedi server isnt't loading things its never going to use or need to use
If you are using gamelift or the service like that, you can save money as well if manage these kinda of data transferring smartly😛
Im working on respawning the pawn after death. In the Gamemode I am creating a new pawn and on the controller calling Possess(). Where on the new pawn can I run code post possess. I tried in PossessedBy() however this gets called before the controller does SetPawn and this messes some thing up for me. Is there any other function that gets called?
OnPossess?
There's also ClientAcknowledgePossession or some such.
You'll have to look for the specific function.
Saving Money and Gamelift cant go together in the same sentence 😛
It's sad but true🙈
Hiya!
Is there any way to apply force to CMC in a way that doesnt break clientside prediction?
Physics is always going to break clientside prediction 😛
That's just a facetious reply, don't worry. 🙂
thought so- then, if i want to add any sort of movement that is not already native to CMC, i'll have to roll my own solution with my own clientside prediction?
You can add your own custom movement modes to the CMC.
I have zero experience in that (or the CMC in general) though.
Oh, really? I didn't know that. I'll do some digging.
Thanks for the info!
np
Check the pinned messages in this channel.
I was just about to say there's bound to be tutorials!
There are plenty of resources on how to add your own advanced mvoement modes to the CMC
Mind you, they can get complicated.
As the CMC is no walk in the park.
The CMC is a bloated mess of horribleness you mean! 🙂
Isn't that just Unreal in general though?
Need to keep with the theme!
hi guys, im trying to allow my players to set their name via a console command, it works but only works for the clients
viewport game is the listen server/client
the game in the small window is my client
the viewport game ran the command to set the name
im doing something similar for health, just setting health on the server side and it replicates to all clients but on the widget im using the native tick function
my understanding was taht if you run code outside IsLocallyControlled and GetLocalRole() == ROLE_Authority it runs on both clients and servers and but it doesnt seem to function that way
- sorry for the ant sized text
void APlayerPawn::OnHealthUpdate()
{
//Client-specific functionality
if (IsLocallyControlled())
{
}
//Server-specific functionality
if (GetLocalRole() == ROLE_Authority)
{
if (CurrentHealth <= 0)
{
bIsDead = true;
APlayerStateWarlocks* PlayerStateWarlocks = Cast<APlayerStateWarlocks>(GetPlayerState());
if (PlayerStateWarlocks != nullptr)
{
PlayerStateWarlocks->SetIsPlayerPawnDead(true);
}
Destroy();
}
}
}
void UHealthBar::NativeTick( const FGeometry& MyGeometry, float InDeltaTime )
{
Super::NativeTick( MyGeometry, InDeltaTime );
if ( !Owner.IsValid() )
return;
HealthBar->SetPercent( Owner->GetCurrentHealth() / Owner->GetMaxHealth() );
FNumberFormattingOptions Opts;
Opts.SetMaximumFractionalDigits( 0 );
CurrentHealthLabel->SetText( FText::AsNumber( Owner->GetCurrentHealth(), &Opts ) );
MaxHealthLabel->SetText( FText::AsNumber( Owner->GetMaxHealth(), &Opts ) );
}
void APlayerPawn::OnPlayerNameUpdate()
{
if (GetLocalRole() == ROLE_Authority)
{
// UPlayerName* PlayerNameLabel = Cast<UPlayerName>( PlayerNameWidgetComp->GetUserWidgetObject() );
// PlayerNameLabel->SetName( PlayerName );
// // ue log player name
// UE_LOG(LogTemp, Warning, TEXT("PlayerName: %s"), *PlayerName);
}
UPlayerName* PlayerNameLabel = Cast<UPlayerName>( PlayerNameWidgetComp->GetUserWidgetObject() );
PlayerNameLabel->SetName( PlayerName );
// ue log player name
UE_LOG(LogTemp, Warning, TEXT("PlayerName: %s"), *PlayerName);
}
In order for the server to know anything, the client has to send an RPC to the server. The RPC can include the name you want, and when you are running on the server it can set the value so it replicates to everyone.
hmm yeah that makes sense, but i can see the player name being set
im using onrep
// player name replicated
UPROPERTY(ReplicatedUsing = OnRep_PlayerName)
FString PlayerName;
UFUNCTION()
void OnRep_PlayerName();
void OnPlayerNameUpdate();
You may see it locally as clients can change their variables as they like, but in order for it to be replicated to everyone else, it must be set on the server, and any value you want the server to know about must be passed through an RPC.
hmm ok
my command is this
void UPuzzleGameInstance::SetPlayerName(const FString& PlayerName)
{
APlayerController* PlayerController = GetFirstLocalPlayerController();
if (!ensure(PlayerController != nullptr)) return;
PlayerController->PlayerState->SetPlayerName(PlayerName);
// get the actor and set the name
APlayerPawn* PlayerPawn = Cast<APlayerPawn>(PlayerController->GetPawn());
if (!ensure(PlayerPawn != nullptr)) return;
PlayerPawn->SetPlayerName(PlayerName);
}
my understanding is that the onrep would run
UPROPERTY(ReplicatedUsing = OnRep_PlayerName)
FString PlayerName;
but youre saying the command is local/on the client so the server doesnt know and therefore on rep doesnt run
is that about right?
Correct.
so i gotta RPC the setting of the name
You need to RPC that you want the player's name to change, then have the server set it. Once the server sets it, the OnRep should fire on clients when they receive the change.
ok thanks outof these two... i wanna do the second one?
i take it you cant* do it like this
UFUNCTION(Exec, Server)
void SetPlayerName(const FString& PlayerName);
Yep.
You may also want to do some sanity checks on the name before setting it too, like make sure it's not too long, not too short, etc.
sorry i edited my comment, can or cant you? cause i got a red underline haha
bah im silly
Oh oops, uh should just be UFUNCTION( Server )
ya i can just have two functions
Then you also need to use this when defining the function in order to actually set on the server.
SetPlayerName_Implementation(const FString& PlayerName)
Also... It can't be done in the game instance.
It probably should be in the PlayerState.
oh no 😦
You can store the name locally in the game instance, but you must pass it to the server on a replicated actor that is owned by the client - playerstate makes sense since you're dealing with playerstate data anyway.
yep makes sense
do i need this? SetPlayerName_Validate
forced me to add reliable
UFUNCTION(Server, Reliable, WithValidation)
void SetPlayerName(const FString& S) override;
validation just mean what you said before? here is where i check if too long etc and return false if it's doesnt fit the criteria?
No one uses the Validate function. Just return true. If you return false it will kick the client that tried to send the RPC iirc
Also, the GameMode has a ChangeName function. Once you are on the Server side with your RPC it's probably best to just call that
yeah i did notice that, i was using that for a bit, not sure how or why i switched to my own 😂
Validation is just for something anti cheating. If you are running a listen server, it doesn't really need to do
hmmm so
void UPuzzleGameInstance::SetPlayerName(const FString& PlayerName)
{
APlayerController* PlayerController = GetFirstLocalPlayerController();
if (!ensure(PlayerController != nullptr)) return;
PlayerController->PlayerState->SetPlayerName(PlayerName);
// get the player state warlocks
APlayerStateWarlocks* PlayerStateWarlocks = Cast<APlayerStateWarlocks>(PlayerController->PlayerState);
if (!ensure(PlayerStateWarlocks != nullptr)) return;
PlayerStateWarlocks->SetPlayerName(PlayerName);
}
this is working..
UFUNCTION(Server, Reliable, WithValidation)
virtual void SetPlayerName(const FString& S) override;
void APlayerStateWarlocks::SetPlayerName_Implementation(const FString& S)
{
// get player pawn and set name
APlayerPawn* PlayerPawn = Cast<APlayerPawn>(GetPawn());
if (PlayerPawn)
{
// log to see if running
UE_LOG(LogTemp, Warning, TEXT("PlayerName: %s"), *S);
PlayerPawn->SetPlayerName(S);
}
}
this is working and printing..
but the name wont change in the UI, the code below isnt running either
void APlayerPawn::OnPlayerNameUpdate()
{
if (GetLocalRole() == ROLE_Authority)
{
UPlayerName* PlayerNameLabel = Cast<UPlayerName>( PlayerNameWidgetComp->GetUserWidgetObject() );
PlayerNameLabel->SetName( PlayerName );
// ue log player name
UE_LOG(LogTemp, Warning, TEXT("PlayerName: %s"), *PlayerName);
}
}
makes sense, eventually this will be dedicated server but good to know what it does
You are checking authority and getting UI, but UI is only on client.
It's not working because you're checking GetLocalRole() == ROLE_Authority. That usually means only on sever.
Exception would be if this is running on a client spawned actor.
The thing you need to do is set the name variable replicated and OnRep event to change the name for your clients.
mm yep makes sense
so when... the name changes for client x i want to change the name in theui for all the clients so just do it for all clients not on the server
yeah of course! that makes sense
Additionally, you're setting the playername on the playerstate. Why would the OnPlayerNameUpdate() run on your pawn?
hmm the pawn has the reference to the UI
ahh im so confused now
The UI should just reference the playerstate 😉
mmmm
that is so much better
so fuck off all the pawn code for player name and just get the UI widget to check the player state for the name
Basically. If the name tag will only ever be used on player characters.
how do i trigger the ui to get the player name, though? there is the tick function... but... seems heavy handed
Well, you could create a delegate in your playerstate that you broadcast when the OnRep is fired.
On Construct of the widget, you can get PlayerState, cast to your custom playerstate, bind to the delegate, and also read the current value.
Bindings are simple enough, but those act like tick too.
You might have a race condition though between Character and PlayerState. You will need to make use of the OnRep_PlayerState function of the Pawn to ensure the PlayerState is valid when the UI spawns
Multiplayer is so much fun.
Yus. Can be happy they use cpp
We usually have a parent widget that has the whole "Is my Pawn and PlayerState valid?" System setup and just provides a function when everything is valid and available for child classes.
haha i had that in a dota mod i did for the exact same reason
That's for HUD but would work very similar for a WidgetComponent widget
alright thanks guys, i wont bother you anymore ill have a tinker
Just keep in mind that if you work with more than one replicated actor that it's best to ensure one doesn't exist before the other. Here that's character vs PlayerState
tbf this is so much better then unity MP
Does Unity have their native module for MP? It is removed IIRC
It does
i tried mirror (third party) for a bit but theyre coming out with their own native module soon IIRC
bah, im getting the same behaviour as before, i switched to doing it all on the widget and player state but again the client shows the change and the listen server doesnt
void APlayerStateWarlocks::SetPlayerName_Implementation(const FString& S)
{
PlayerName = S;
}
bool APlayerStateWarlocks::SetPlayerName_Validate(const FString& S)
{
return true;
}
void APlayerStateWarlocks::SetPlayerNameWidget(UPlayerName* pnw)
{
PlayerNameWidget = pnw;
}
void APlayerStateWarlocks::SetPlayerNameOnPlayerWidget()
{
APlayerPawn* PlayerPawn = Cast<APlayerPawn>(GetPawn());
if (!PlayerPawn) {return;}
if (!PlayerNameWidget){return;}
UE_LOG(LogTemp, Warning, TEXT("PlayerName: %s"), *PlayerName);
PlayerNameWidget->SetName(PlayerName);
}
void APlayerStateWarlocks::OnRep_PlayerNameCustom()
{
SetPlayerNameOnPlayerWidget();
}
void UPuzzleGameInstance::SetPlayerName(const FString& PlayerName)
{
APlayerController* PlayerController = GetFirstLocalPlayerController();
if (!ensure(PlayerController != nullptr)) return;
PlayerController->PlayerState->SetPlayerName(PlayerName);
// get the player state warlocks
APlayerStateWarlocks* PlayerStateWarlocks = Cast<APlayerStateWarlocks>(PlayerController->PlayerState);
if (!ensure(PlayerStateWarlocks != nullptr)) return;
PlayerStateWarlocks->SetPlayerName(PlayerName);
}
void UPlayerName::NativeConstruct()
{
Super::NativeConstruct();
if ( !Owner.IsValid() )
return;
APlayerState* PS = Owner->GetPlayerState<APlayerState>();
APlayerStateWarlocks* PlayerState = Cast<APlayerStateWarlocks>(PS);
if (PlayerState)
{
PlayerState->SetPlayerNameWidget(this);
}
}
at the end of the day right... a player uses the command to change their name, the UI for all clients needs to update, my code doesnt do that haha but i dont know exactly how todo it
Out of curiosity. How come you don't use PlayerState's already set up naming?
discovered it half way through this 😂 ill switch to that after this, this is good at learning networking a bit
if that makes sense
I dunno how it only changes the client 😦
What calls this? UPuzzleGameInstance::SetPlayerName
hm spawning actors from the "level bp" has to be casted to the server right ?
thats not automaticly ?
since its from the level
or u cant rpc from that side right :/
You can't really do this.
void UPlayerName::NativeConstruct()
{
Super::NativeConstruct();
if ( !Owner.IsValid() )
return;
APlayerState* PS = Owner->GetPlayerState<APlayerState>();
APlayerStateWarlocks* PlayerState = Cast<APlayerStateWarlocks>(PS);
if (PlayerState)
{
PlayerState->SetPlayerNameWidget(this);
}
}```
The playerstate may not necessarily be valid at the time that the widget is constructed, and you don't want to get the owner of the widget as that will always be the local client's player controller.
UFUNCTION(Exec)
void SetPlayerName(const FString& PlayerName);
the client via console
yeah i figured... so what do i need to do. i need to... get all the widgets? or tell the client to get the name of all the players and update the widget?
Ah. That's why then. That code would only run on the client.
yeah but the other client gets the update
if that makes sense
in my picture the viewport/editor is the listen server the small window is the client and i run the command on the editor
hmm ok, how do i force it? haha if thats the right word
i know what im doing isnt right i just wanna see if this will work cause i think it should?
im ignoring the race condition for now
You'd have to feed in a reference of the pawn the widget is on to the widget itself. Once the widget has the pawn its on, it can grab the pawns playerstate and then you can get the value.
Again, with the playerstate being valid at the time you're doing it of course 😛
You can call the OnRep directly on server, but it's not wise. And to fully answer the question I have to critique that the Playerstate should not know about the widget.
yeah 100% agree the playerstate shouldnt know about the widget
im getting all mixed up with where i should do what
The Setting code, and the OnRep should both be calling a delegate broadcast. The widget should be bound to that.
playerstate has the name
ah there it is, i dunno what a delegate broadcast is and how to bind a widget to it, lemme look it up
Check out DECLARE_DYNAMIC_MULTICAST_DELEGATE
oh god this looks complicated, ill learn about it, ok thanks
// This gets declared just after your #includes in your .h
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnPlayerNameChangedDelegate);
//Later on in your class definition
public:
UPROPERTY(BlueprintAssignable)
FOnPlayerNameChangedDelegate OnPlayerNameChanged;
//.cpp
void APlayerStateWarlocks::OnRep_PlayerNameCustom()
{
OnPlayerNameChanged.Broadcast();
}
As for binding in the widget... Umm.... That part I'm not great at. XD
At least not in C++.
i do this in player state?
haha all good i can look that up
Sure
The binding you can just do in the widget's Construct.
PlayerState->OnPlayerNameChanged.AddUniqueDynamic(this, &ThisClass::MyFunctionIWantToCallWhenThisRuns);
hm spawning actors from the "level bp" has to be casted to the server right ?
thats not automaticly ?
since its from the level
or u cant rpc from that side right :/
its only visible on 1 client
RPCed. You can't cast to the server. Technically you cannot cast "to" anything.
I don't know what you mean by "casting to server" but I believe it should be "spawning from server". If your actor is replicated then it'll be visible to the clients
The level blueprint effectively runs on both the server and client independently.
The events that can be triggered within the level blueprint can also happen on both the client and server - for example, Begin Play will fire on both.
If you ensure whatever event that is driving the spawning is running on the server, by using something like a Has Authority check, then only the server should be running it.
You cannot send a Server RPC through the level blueprint. Server RPCs can only be sent on client owned actors, such as their controlled pawn, the player controller and playerstate.
yeah thats what i mean
like for now im running a tic for every 20 sec spawn an actor
but it only shows on 1 client
As Datura suggested if you use HasAuthority check you should be able to make it spawned in Server so it can replicate to others
Do you have any checks or branches before the spawn node?
no
Tick should also be running on both server and all clients, so it should actually spawn one on server, which should be replicated if the actor also is, and then on all clients locally
yeah thats why its strange
i mean this is how im spawning on the level Bp
this should be replicated right
Well right now this should spawn the actor on server and on all clients. And if the actor is replicated, the one created in server should be replicated to all which would cause clients to have 2 actors
But it might also prevent the client ones from spawning since the collision override rule is set to not spawn and you're spawning them at the same location
Why are you not using the spawn zone actor for spawning them?
Also, you don't need to replicate the spawn zone actor, just use the Is Server node to make sure you are the server and then start the spawn
@agile loom whats that
@upbeat basin oh ok so what i should use has authority?
ok so im using a dedicated server tbh dose that matteR ?
Yes
The zone actor is not replicated, but the actor that we spawn is replicated
Everything.
Generally speaking. Level blueprint is the very last place you ever want to do anything. There's almost always a better place for it.
In your case. Lets say you make a second level and want to spawn stuff in places. Wouldn't you rather just drop some new zones in and be done? Or would you rather have to open the level BP and recode all of this for a second time?
hm true
No. Spawning stuff should be server only from beginning to end, unless a client influences it (chooses what to spawn)
you know what.. i missed a replicate the actor on the item itself-.-'
ok so another issue or rather tip im doing a kinda "duel arena" thingi so i need a win condition the first "player" to reach 20 kills the player kills is variable stored in the player BP but how would i set that up ? in the game mode or something ? how would i check each player who was the most etc ?
hi guys, i have a delegate that is mostly working but its not calling the function i specified.
void APlayerStateWarlocks::OnRep_PlayerNameCustom()
{
// console log player name
UE_LOG(LogTemp, Warning, TEXT("Player name changed to %s"), *PlayerNameCustom);
OnPlayerNameChanged.Broadcast();
}
i have confirmed this runs when i change the player name via a console command
but then
void UPlayerName::SetName()
{
UE_LOG(LogTemp, Warning, TEXT("UPlayerName::SetName()"));
// get player name from player state
APlayerStateWarlocks* PlayerState = Cast<APlayerStateWarlocks>(GetOwningPlayerState());
if ( !PlayerState ) {return;}
FString PlayerName = PlayerState->GetPlayerNameCustomTwo();
PlayerNameLabel->SetText(FText::FromString(PlayerName));
}
void UPlayerName::NativeConstruct()
{
Super::NativeConstruct();
APlayerStateWarlocks* PlayerState = Cast<APlayerStateWarlocks>(GetOwningPlayerState());
if ( !PlayerState ) {return;}
PlayerState->OnPlayerNameChanged.AddDynamic(this, &UPlayerName::SetName);
UE_LOG(LogTemp, Warning, TEXT("UPlayerName::NativeConstruct()"));
}
SetName() is not running, i have confirmed NativeConstruct() is running at startup
the UPlayerName Is a widget above my characters head that displays their name
Datura and Authaer thanks for the help before!
I Have this logic for respawning my player character. Right now i try to make this suitable for multiplayer. My problem now is that it wont work on clients, it only does on the server. the server event runs on the server, and the other event is a multicast
what doesnt work now is that the rotation gets reseted to face always in the positive x direction for all clients.
here is the logic for that
Is the problem that the rotation of the spring arm (which are used for the calculation of the rotation) are not synced? or replicated? Setting the springarm to replicate didnt solve this tho.
Chances are likely that your OnRep is running before the widget's construct. Generally you will need to bind stuff and then call the same update function in a lot of multiplayer situations.
Also for your delegate. Two things. Use AddUniqueDynamic instead of AddDynamic. This ensures only one binding even if you remove and readd that widget for some reason. It'll ensure in editor at least if you try that. And a nice thing I prefer is using &ThisClass::SetName as I tend to copy bindings or move them around at times. This makes it easier just to know you're generically calling the function in this class and not have to always write out the class name.
awesome thanks for the tips
Chances are likely that your OnRep is running before the widget's construct. Generally you will need to bind stuff and then call the same update function in a lot of multiplayer situations.
I thought so as well but.. since its a command i can run anytime, it should be ok, see the log and the time between when the player name is set
void APlayerStateWarlocks::OnRep_PlayerNameCustom()
{
// console log player name
UE_LOG(LogTemp, Warning, TEXT("Player name changed to %s"), *PlayerNameCustom);
OnPlayerNameChanged.Broadcast();
}
the on rep is running
Right. But breakpoint your OnRep and the Widget Construct. I'll bet your OnRep runs first.
Your Construct event just needs to call SetName after the delegate binding.
as in in here? UPlayerName::NativeConstruct() ?
Yeah
hahah bro, what the heck
on play/spawn the name is set to my desktop.. no idea why im not calling that command, i call the command via the console to set player name to 123 and it doesnt call the delegate
haha
That's normal. That's Null OSS. If you use Steam or EoS, or any console OSS like Xbox or Sony, it'll set the name automatically to your Username there. Null randomizes a name like that.
How are you getting that though? Your code from above those get that name.
the desktop name? or the 123?
im setting the 123 via a console command
void UPuzzleGameInstance::SetPlayerName(const FString& s)
{
APlayerController* PlayerController = GetFirstLocalPlayerController();
if (!ensure(PlayerController != nullptr)) return;
PlayerController->PlayerState->SetPlayerName(s);
// get the player state warlocks
APlayerStateWarlocks* PlayerStateWarlocks = Cast<APlayerStateWarlocks>(PlayerController->PlayerState);
if (!ensure(PlayerStateWarlocks != nullptr)) return;
PlayerStateWarlocks->SetPlayerName(s);
}
Did you override that in your playerstate?
hmm not sure what you mean, this is the playerstate code
void APlayerStateWarlocks::SetPlayerName_Implementation(const FString& S)
{
PlayerNameCustom = S;
}
bool APlayerStateWarlocks::SetPlayerName_Validate(const FString& S)
{
return true;
}
void APlayerStateWarlocks::OnRep_PlayerNameCustom()
{
// console log player name
UE_LOG(LogTemp, Warning, TEXT("Player name changed to %s"), *PlayerNameCustom);
OnPlayerNameChanged.Broadcast();
}
UFUNCTION()
void OnRep_IsReady();
UPROPERTY(ReplicatedUsing = OnRep_PlayerNameCustom)
FString PlayerNameCustom;
UFUNCTION()
void OnRep_PlayerNameCustom();
UPROPERTY(BlueprintAssignable)
FOnPlayerNameChangedDelegate OnPlayerNameChanged;
UFUNCTION(BlueprintCallable, Category = "Gameplay")
FString GetPlayerNameCustomTwo() const { return PlayerNameCustom; }
Okay. That explains how that's working. But your config function isn't running now?
yep so
{
// console log player name
UE_LOG(LogTemp, Warning, TEXT("Player name changed to %s"), *PlayerNameCustom);
OnPlayerNameChanged.Broadcast();
}
this runs when i console command 'SetPlayerName 123'
but this doesnt
void UPlayerName::SetName()
{
// if ( !Owner.IsValid() )
// return;
// console log
UE_LOG(LogTemp, Warning, TEXT("UPlayerName::SetName()"));
// get player name from player state
APlayerStateWarlocks* PlayerState = Cast<APlayerStateWarlocks>(GetOwningPlayerState());
if ( !PlayerState ) {return;}
FString PlayerName = PlayerState->GetPlayerNameCustomTwo();
PlayerNameLabel->SetText(FText::FromString(PlayerName));
}
but SetName() must be running cause its changing my name to desktop etc right?
It's at least running once.
yep
the listen server / editor
wait wait
UFUNCTION(Server, Reliable, WithValidation)
virtual void SetPlayerName(const FString& S) override;
shouldnt this by client -> server?
It will run even on a server. It'd just run locally on a listenserver.
I'm not sure why your OnRep isn't running then. 😦
guys how would i track number of players in game ?
well there’s literally a get current players node or something for the default subsystem
but idk if that works with everything
This doesnt seem too complicated. Still im not able to find the solution, anyone?
Chances are you're trying to rotate a pawn using ControlRotation. Need to set that instead of the actor's rotation most likely.
yeah i tried some more, cant figure it, probably too tired haha thanks for your help ill try in the morning
Hope you get it. 😄 Is a weird bug. Probably just overlooking something.
yeah 100% will see it tomorrow haha
No need to track it yourself. Make a simple function to iterate over the GameState's PlayerArray and add to an integer if the PlayerState's IsABot function is false.
The set control rotation is only available on the controller
I should probably move my rotation logic to the controller then right? or just set the control rotation inside the pawn via a getter of the controller?
would it be a bad idea to have fast moving projectiles? I know projectile movement replicates, but I can imagine fast ones breaking a lot
and might not even need projectile movement component if they just travel in a straight line
so I’m wondering if there’s any kinda hitscan fakery for really fast projectiles that would work
Any particular reason? Like what's your biggest gripe with Steam backend? Annoying to test?
I'm not 100% sure what all you need to run on all machines. The ControlRotation just needs to be set on the owning client of the pawn.
IE, you can do a IsLocallyControlled check and if yes, GetController->SetControlRotation
Hi guys! Can someone please give me some advice? I'm having trouble loading game saves when connecting to a dedicated server. My logic is as follows - clients select a character class, this class is saved using SaveGameToSlot then the client connects to the server and the selected character class is spawned on the map. The character spawn function is created in GameMode and is called using RPC on the controller, I also run LoadGameFromSlot on EventBeginPlay in the controller and get the saved character class which I then set for the spawn function. If I run the game in the engine everything works fine, but if I run the server and connect to it as a client then my character class variable is not passed to the spawn function. Any help would be appreciated. Here's a log of the spawn error on the server:
LogStreaming: Warning: LoadPackage: SkipPackage: /Game/AdvancedLocomotionV4/Blueprints/CharacterLogic/KokoTeam_Characters/ALS_ForestKid_Koko (0xBF1C553CD651EE0D) - The package to load does not exist on disk or in the loader
LogNetPackageMap: Warning: UPackageMapClient::InternalLoadObject: Unable to resolve default guid from client: ObjectName: /Game/AdvancedLocomotionV4/Blueprints/CharacterLogic/KokoTeam_Characters/ALS_ForestKid_Koko, ObjOuter: NULL
LogBlueprintUserMessages: [Combat_PlayerController_C_2147482465]
LogBlueprintUserMessages: [DCSGameMode_C_2147482489] Spawning:
LogScript: Warning: UGameplayStatics::BeginDeferredActorSpawnFromClass: can not spawn an actor from a NULL class
I think your issue is related to the character not loading correctly. Package error maybe, not sure.
Thank you for your reply! I also think the character is somehow not loading correctly or getting lost somewhere, but I still can't figure out what's causing it. How can I check if it's the packages?
I'm not sure. I'm not used to having that kind of issue with hard pointers to classes. :/
What would be better? Through the structure?
Not sure. Your server seems to be the one with the problem. But does your client have access to the class? You don't have any checks to see if the class is valid before the RPC
Yeah, thanks! I'll check it out.
game state - get player array - get array length
i dont know what you want to tell me with this
I don't think he replied to the correct person.
i replied to the wrong person, sorry
I found some more about this set control rotation, but the documentation is 'short' and im not quite sure how the control rotation effects the pawn itself.
Either i use it wrong, or it might actually not apply to my situation.
This is how i used it:
I tried it on all replication modes which did not do much of a difference. The Pawn just wont rotate
I solved it on a different way now, can someone rate this? I basically calculated the rotation beforehand, and then applied it on the multicast. This takes more bandwidth i assume, shouldnt matter tho if its only once every few seconds, right?
That's for me, I suppose? )
That'll be perfectly fine. And Control Rotation is normally used as the "View direction" of a player or pawn. You need to have the checkboxes set for it in your pawn though. Like Use Controller Rotation Yaw, etc.
The function that contains the play anim montage already has replication, I just need to make the server find out the value of the variable that contains the reference to the animation that is going to be executed, which comes out of a struct of the sword
Hi does anyone have a good resource to learn about peer to peer in unreal?
unreal does not support p2p without you writing your own custom netdriver (and no, there aren't really any resources on that)
the closest is listen server, which I'd normally recommend, although you still have to deal with NAT issues, relay servers, matchmaking server etc
Hi, since yesterday my game is returning NetDriverListenFailure when I create a session only on shipping and only deployed on steam.
I've deployed a development version and it works fine.
I think it's happening on UWorld::Listen
Strangely yesterday steam updated Microsoft VC Redistribute when I opened the game on a version that were working fine.
I also rolled back the game to previous working versions and all of those are now showing the same behaviour
I will try disabling SteamSockets and shipping it to see if the pluguin is the problem. Anyone else is having this?
hope not, or we will have angry players :p
Sadly it must be only happening in my project
Are there mechanisms to replicate a variable only to a specific client? What about sending an RPC from server to a specific client?
I'm working on looting and XP, and need to send info just to specific clients. IE: How much XP the client has gained, dropping pickups that only they see, etc.
i mean this would be a rpc
why would you use a replicated prop?
unless you maintained an array of the players and there stuff
Prop for persistent items on the ground. IE: Diablo style loot
XP is an ephemeral event that would make sense as RPC
yes but you would send an rpc with the items to spawn
and client just spawns the stuff locally
or w/e
Ah, I was thinking a fast array of items with ID, position, etc, that the client can use to indicate when they pick them up
or if they are replicated pickups, you could set owner to the person who needs them
then mark it OnlyOwnerSee
And then also having the item actors spawn locally
🤷
Interesting. This still replicates to everyone though, right?
I was thinking of IsNetRelevantFor
(as long as your not using repgraph)
I shipped the game without SteamSockets, it's working again.
we use steam sockets just fine
Wait I haven't used RepGraph yet. I thought those were the same
With net relevance I could assign a "Loot Rep" actor to each player and send data that way?
I don't know why them
I only use Sockets to get server latency for the server browser
So now what, no more ping column ?
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/SteamSockets.SteamSocketsNetDriver",DriverClassNameFallback="/Script/SteamSockets.SteamNetSocketsNetDriver")
[/Script/SteamSockets.SteamSocketsNetDriver]
NetConnectionClassName=/Script/SteamSockets.SteamSocketsNetConnection
ConnectionTimeout=80.0
bNeverApplyNetworkEmulationSettings=true
InitialConnectTimeout=120.0
NetServerMaxTickRate=60
bClampListenServerTickRate=true
MaxNetTickRate=60
KeepAliveTime=0.2
MaxClientRate=120000
MaxInternetClientRate=120000
RelevantTimeout=5.0
SpawnPrioritySeconds=2.0
ServerTravelPause=4.0```
bEnabled=true
SteamDevAppId=XXXXX
bAllowP2PPacketRelay=true
P2PConnectionTimeout=90
P2PCleanupTimeout=1.5````
this our setup, and steam sockets works fine
obvs i marked out the app id
Yeah, I forgot how to code block
!NetDriverDefinitions=ClearArray
!+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemSteam.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/SteamSockets.SteamSocketsNetDriver",DriverClassNameFallback="/Script/SteamSockets.SteamNetSocketsNetDriver")
[OnlineSubsystem]
DefaultPlatformService=Steam
bHasVoiceEnabled=true
PollingIntervalInMs=20
[OnlineSubsystemSteam]
bEnabled=true
SteamDevAppId=XXXXXX
SteamAppId=XXXXXX
GameServerQueryPort=27015
bVACEnabled=1
P2PConnectionTimeout=90
bInitServerOnClient=false
[/Script/OnlineSubsystemSteam.SteamNetDriver]
NetConnectionClassName=OnlineSubsystemSteam.SteamNetConnection
[Voice]
bEnabled=true
[Core.Log]
LogOnline=All
LogOnlineGame=All```
This is mine defaultengine.ini
You don't know how stupid I feel right now
you running dedicated servers?
p2p
right so why do you have bInitServerOnClient set to false?
Oh
I will try right now, thanks.
And now Kaos owns 20% of your revenue 😀
hey all, so I have been messing around with my first project, noticing that my UI gets added more then once. I'm doing something pretty simple with it if anyone has tips for this please feel free to let me know
Code example:
` if (ScoreUIWidget != nullptr)
{
ScoreUI = CreateWidget<UScoreUI>(GetWorld(), ScoreUIWidget);
if (ScoreUI != nullptr)
{
ScoreUI->AddToViewport();
}
}`
Unfortunately, it didn't help
Question for multiplayer people: one of my colleagues has been trying to integrate Valve's sockets into Unreal, it's working (for example, a replicated object moves on both client and server). However, there's an error that is hard to solve/figure out, related to UConnection.cpp, lines from 4594:
// Detach old player if it's in the same level.
check(LocalPlayer);
if( LocalPlayer->PlayerController && LocalPlayer->PlayerController->GetLevel() == PC->GetLevel())
{
if (LocalPlayer->PlayerController->GetLocalRole() == ROLE_Authority)
{
// local placeholder PC while waiting for connection to be established
LocalPlayer->PlayerController->GetWorld()->DestroyActor(LocalPlayer->PlayerController);
}
else
{
// tell the server the swap is complete
// we cannot use a replicated function here because the server has already transferred ownership and will reject it
// so use a control channel message
int32 Index = INDEX_NONE;
FNetControlMessage<NMT_PCSwap>::Send(this, Index); //this gets triggered and causes the error
}
LocalPlayer->PlayerController->Player = NULL;
LocalPlayer->PlayerController->NetConnection = NULL;
LocalPlayer->PlayerController = NULL;
}
The logs print an error message: recieved invalid swap message with child index -1, which is likely caused by the fact that the previous code is triggered.
It seems something related to the custom socket implementation that is missing, but we cannot find a cause or solution
is it best practice to add any UI only on the server?
UI should not happen on the server
Doesn't UI only have reference on clients?
It's a client-side thing, ideally detachhed as much as possible from gameplay logic
Wat
That's like.... The opposite
glad I got a response 😆 ty
Do you mean "show certain UI only on LISTEN server"?
my original post was talking about how I seem to be getting more than one UI being added to the viewport, trying to figure out how to get that down to one
post found here
That's a widget
More than once per client window you have open, or more than once TOTAL?
need to know whre it is being called and if you are not spawning more than one of the object that contains that code
potentially per client, the code is being called on BeginPlay on my Character class
you probably want an if (IsLocallyControlled) condition (pseudo-code)
Bad news, it didn't worked.
might have to turn logs on
but it works fine for us, so not sure what your issue is :/
ok thanks, I tried that but I get a nullptr error somewhere else when I do this, think I just need to do some more debugging
probably in the character instances that don't get the widget created you are not checking for null when trying to access those
Wait, should I remove this too from the engine.ini?
DefaultPlatformService=Steam
bHasVoiceEnabled=true
PollingIntervalInMs=20```
IMO. You should avoid doing any sort of widget creation outside of the AHUD class unless you explicitly know what you're doing. There is one AHUD per local user per machine. So stuff done here is only for a single player.
I'll definitely test around it, thanks for the advice, I totally skipped over using !IsLocallyControlled bc it was "working" without it lol
be sure to check Authaer advice above, according to your case it may be an easy change
oh thanks, that's actually huge
I'm assuming that I can attach that to the HUD Class in my custom GameModeBase
I needed this lol TY all that contributed
"The best way to get the right answer on the Internet is not to ask a question; it's to post the wrong answer."
damn I should have done that
Funnily enough - I actually had a talk with Cedric not too long ago. I came to the conclusion that it's a bit annoying to do things all in the AHUD. At least for me. A vast majority of the time, I'm routing through the PC for pretty much anything anyway.
AHUD just serves as a widget holder.
And the PC is just telling it to show/hide or w/e.
It's like extra indirection for the sake of indirection
I don't like putting things in the Controller. It has enough work as a networking hub and a control delegator. And you can very easily make a precasted static to get your HUD.
same for me
although I still end up using PC as the dump of every general functionality sometimes
Pretty much most communication to the player ends up going through the PC (at least not like...character related stuff)
Like "PC - show this widget"
Or w/e
Well if you want to get HUD you need to get PC anyway iirc
So, for me, it's not a matter of accessing the HUD itself - it's just a lot of things end up going through the PC anyway (rpc wise)
I just made a new GitHub branch for this. I did a lot of workarounds and learning to try to get the UI to sync up between clients
I'm working on a project right now that has a 20k line PlayerController.cpp file. 2600 line .h file. And that's only one part of it's C++ hierarchy And the BP for it is stupidly massive. I really do not like anything more in the PC than there needs to be. 😂
but if I can make it more simple to have just 1 version of the UI for the rest of the development - that'd be ideal
Well your PC be morbidly obese already, it’s understandable 😀
What could be reason shipping dedicated server doesn't work? And how to use -log on on that? Development server works 100% and I can play it others can play it.
I just don't think there is that great of a solution honestly. Because PC is a convenient place for a lot of client specific RPCs
yeah I get it. Ours is not that big but still bigger than I'd like. We have manager actors owned by clients to do RPCs etc so it's not even that necessary for multiplayer
Funny enough you know the project I'm talking about. I just realized you were in their dev discord today. 😄
ohhh xD
🤔
Ye I just playtest
Oh - so Max > Duro confirmed?
^^
Time to make a PC-like actor, specifically for client-specific RPC calls.
I was even there when he got hired at Ironward 😭
also now that I have your attention just in case
any clues
Oh gee - look at the time...
😄 Nah. Duro's cool. I did take your advice on interaction components.
points at #online-subsystems and runs
it's our custom subsystem 😭
I haven't messed with steam sockets unfortunately.
The good news is that if you removed it, you wouldn't get the error anymore.
INDEX_NONE is -1 by default I believe.
Don't know what that line is even doing and I'm not at my computer that has UE, so I can't dig either
ui will forever be my opp
i want to give everyone the same view as soon as this level starts but this does not work... Using the get player controller i can only reference 1 player, How should i go about referencing all players who start this level
Are you possessing a default pawn of any kind?
thirdpersoncharacter, i can make the characters view with the camera using something like "5 "key event, but i want this to happen automatically
Yeah. Sec. There's a setting somewhere that will help if memory serves.
I think bAutoManageActiveCameraTarget. Turning this to false should avoid calling SetViewTarget on your possessed pawn.
what the hell are you doing in playercontroller?
Don't ask me. 😄 You want to see my personal project's PlayerController.cpp?
AShooterSurvivalPlayerController::AShooterSurvivalPlayerController()
{
PrimaryActorTick.bCanEverTick = true;
}
void AShooterSurvivalPlayerController::BeginPlay()
{
Super::BeginPlay();
if (IsLocalController())
{
if (UCommonUIActionRouterBase* CommonActionRouter = GetLocalPlayer()->GetSubsystem<UCommonUIActionRouterBase>())
{
CommonActionRouter->OnActiveInputModeChanged().AddUObject(this, &ThisClass::HandleCommonInputModeChanged);
}
}
}
void AShooterSurvivalPlayerController::HandleCommonInputModeChanged(ECommonInputMode NewInputMode)
{
if (NewInputMode == ECommonInputMode::Menu)
{
FlushPressedKeys();
}
}```
This is how much I adore using my playercontroller.
I don't remember off hand. But I don't think the BP for this even has anything in it.
How do you handle say, opening the inventory? @kindred widget
(Assuming it's not character specific obviously)
Or say, you interact with a keypad and the server has to tell the client to show the keypad UI for example
Inventory is an easy one. I have a player specific interaction component on my player pawn that does a few hotkeys. Really need to set up some real inputs sometime though. 😄
Don't even care about HUD there. Interaction straight to widget.
Yeah - I realized the inventory probably wasn't the right UI thing to pick 😅
my code is nightmare fuel to most - I add the UI and update the UI in the Character class. With the support of the GameStateBase
Well - it depends™️
after earlier convo I am reevaluating it all
Like - updating the UI when you shoot your gun for example, I can understand why you might tie that into say the player class
(Not saying that's how you should mind you)
This layer stuff looks like it was ripped from Lyra 😅
Local interaction is done. I use it currently for opening inventory screens to other items. Server interaction I'm still working on. I have two interaction components. One is on my player, that does the actual interaction. Since it also has access to ServerRPC from the owned player. The other is a component with a softpointer to a DA that I put on interactable stuff. It stores whether I need to RPC or can interact locally. I get entirely around dealing with interfaces doing this.
Kinda. It's a part of CommonGame. Fun setup. 😄 You have to hardcode a config setting because they messed up setting it up in their developer settings.
Er. Sorry. Brain failed. You have to hardcode it because they DIDN'T use a developer setting. It's just a config in a UGameInstanceSubsystem
I mean, in general, what in the fuck is requiring 20k lines in playercontroller.cpp?
spaghet?
I know a good small part of it is UI handling. Only reason I've personally been in there. Just a lot of stuff.
Me after struggling to make a simple health bar in multiplayer
So the DA driven component, your DA has some flag that says local or rpc? And then you just do an if check probably. Is there anything else in the DA?
Inbefore: "Instanced UObject"
Component has the boolean. I need that without loading the DA. DA is for UI. I load it in a widget to get name of the thing. And plan is other related info I might show on a small info card when looking at something.
So what flips that bool?
Say you have two things, one requires an RPC and one doesn't.
What flips it?
It's set on the instance.
The interactable instance?
Or you place it on the interactable's component. Then when you go to interact, you grab that component and then check it
For instance an actor I want to interact with to show an inventory. I don't want to RPC, it's false. I'd set it to true for a lightswitch. Actor class handles the interaction through Started, ongoing and completed delegates from the component.
Right, so my latter.
So your system is as follows:
- Component on anything that is interactable. It is here that you set if it can be local or not.
- When something interacts with something else, locally, you check if it can be done locally or not and if local, proceed, if not, route ServerRPC through the interacting actor
Yep
I find this approach nice so far. And I'm hoping it'll be easy to integrate with AI. As they can bind the delegate callbacks for completed and such as well in their AI tasks.
And the DA contains the widget class for the given UI. So nothing really holds references to UI itself.
Are you a fan of creating/destroying widgets when they're no longer needed? Or you a show/hide kind of programmer?
Yeah. Or it will. Still working on that one. Been debating if I want to go with a listed view of fragmented widgets that hold specific like data, or a single more specialized one per actor type.
Somewhere in the middle. Pool when it's worth it. Actually CommonUI's Stack does this for you. 😄 And I've started using Listviews and Tile.. whatever they're called a lot more due to just being able to throw an array of objects at them.
I've been seeing people talk more about fragments lately. Should probably look at Lyra to see what's up
They're just smaller data assets meant for a specific small subset of data. Like in my case, instead of having one tooltip widget with it all set up to display for one actor. I could use like a health display fragment that has a specific small widget for displaying health. Another one that has a small widget for displaying maybe durability. Another one that houses a name/description/icon. And then I could just iterate over these DAs, create their widgets, populate them from their data, and put them together in a VBox dynamically.
which class is best to update/initialize UI within the HUD class?
You can initialize most of it on Beginplay.
In the Character class? Not seein a BeginPlay in the HUD class but could be wrong
You create a child of AHUD?
ya
It should be there as a greyed out node. Alternatively right click the Graph and just start typing it.
doing it in C++ but ok I see the override works - thanks!
Don't forget the Super call.
perfect got the first part working - thanks!
Can anyone suggest a good pattern for handling UI updates in response to updating an array on the server? For example, if I start a quest and add it to a TArray of active quests on the server, which is replicated to the client. I could use the OnRep of the array to broadcast a multicast delegate for anything that was interested in the update (aka a quest log UI widget), but it wouldn't be able to have info on which element in the array is new/updated. If I call a client RPC I can easily pass the info on what changed down to the client and include that in the broadcast, but the underlying TArray may not have replicated yet at that point, right?
I can think of plenty of non-performant ways of handling it, I was just hoping there was a more elegant solution I'm missing
To get anything better, your array would need to be a FastArray. They have item specific local callbacks.
Got it, thanks, looking into that now!
If you don't want to adopt fast array, don't forget you can pass the "previous" value to the OnRep callback and do comparisons yourself
void OnRep_TheArray(const TArray<FWhat>& PreviousValue)```
Yup, that was on my mental list of 'doesn't feel quite right' solutions, thanks 🙂
An acceptable middle ground for the case of a small array, and then use FastArray for the bigger/more important cases
I'd say it's fine honestly. You can set a flag per-element when it's serialized client-side if you just want to skip through quickly
Honestly though, probably easier to just tell the UI "the array changed" and let it handle any rebuilding etc.
TArray still has some replication advantages over Fast Array, but FA does have nice QOL stuff
I have a question, im pretty new to UE5 replication, but i've got an object that gets instantiated by the player on begin play. That actor is set to replicate, but my problem is it seems to be making duplicates of the object on the client side no matter what i do. Any thoughts?
Aye, it just hurt me a little inside to rebuild the whole UI component based on a change instead of just the piece I needed, if I could help it
yeah that's fair. An easier way to do quick comparisons, would be an incrementing counter
Depends how expensive the comparison actually is ofc
Hard to beat a straight up memcmp
Is it creating a copy on the server, replicating that down, and the client is also creating its own copy?
I think thats whats happening, yeah
Most likely, all connections are creating their own local actors
- you get the bonus one on clients when the servers' version replicates
Make sure you guard the code spawning the actor behind HasAuthority() or some suitable check, and make sure clients don't have authority on the spawning actor too (e.g, it's not a non-replicated actor itself)
follow up question, the player needs to store a reference to the object that it creates, so will this reference be properly set in the case of a client that doesn't have authority?
i guess, should the variable be replicated?
oh huh, nevermind just tested it out and it seems to be working properly now
tysm!
actually now there are different problems but i'll give it a good shot at solving those before i post here more
So long as the reference to it is also replicated, that will work
Note the actor actor may replicate before the reference is updated however
The reference will eventually update, but just note that because the two actors replicate independently, you can't garauntee which will replicate first
Ive stopped work for the day, but I was encountering an issue that may be similar to this, the instantiated object for player 2 on the server wasn't replicating movement even though it is set to do so. I think it's because the reference isn't set properly, but I'm unsure why it would do this since it's just make player->create object and assign it to a variable as a reference, which is replicated
And it moves on the client side, but yeah, not the server side
Yeah none of that should interfere with movement
If it moves client-side, it's because the client is moving it locally most likely
Yup that's the case
The Server should be the one moving it, and all clients will receive that
Then I think I understand how to fix it, this is really a server authoritative architecture huh? Thanks again, hopefully I can get it working tomorrow
Yeah. Ultimately you can do whatever you want to your local instance, the client could even choose to ignore what the Server tells it to do - but ultimately if a client wants to mess with something it's not authoritative over, it must ask the server to do it
And the Server checks the request and applies accordingly
(you can skip the checking part just to get it working, but that's where the security stuff comes in etc.)
Yeah there's so much with networking that I've not even touched, even when I was doing my own stuff or working in unity, being an indie makes thinking about everything overwhelming at times but I'm sure it'll become easier as time goes on
Finally builded the source code and got the log from the shipped game
[2023.05.25-03.24.19:978][523]LogNet: ReplicationDriverClass is null! Not using ReplicationDriver.
[2023.05.25-03.24.19:978][523]LogNetCore: DDoS detection status: detection enabled: 0 analytics enabled: 0
[2023.05.25-03.24.19:979][523]LogSockets: Warning: SteamSockets: Cannot get information on an invalid socket handle, returning null
[2023.05.25-03.24.19:979][523]LogNet: Warning: Could not create socket for bind address 76561197992543984, got error SteamSockets: setsockopt SO_BROADCAST failed (0)
[2023.05.25-03.24.19:979][523]LogSockets: Warning: SteamSockets: Cannot get information on an invalid socket handle, returning null
[2023.05.25-03.24.19:979][523]LogNet: Warning: Could not create socket for bind address ::, got error SteamSockets: setsockopt SO_BROADCAST failed (0)
[2023.05.25-03.24.19:979][523]LogNet: Warning: Encountered an error while creating sockets for the bind addresses.
[2023.05.25-03.24.19:979][523]LogNet: Error: InitBindSockets failed:
[2023.05.25-03.24.19:979][523]LogNet: Warning: Failed to init net driver ListenURL: /Game/OnlineSystem/Lobby/Maps/Lobby?listen:
[2023.05.25-03.24.19:979][523]LogNet: Error: UEngine::BroadcastNetworkFailure: FailureType = NetDriverListenFailure, ErrorString = , Driver = GameNetDriver IpNetDriver_2147482417
[2023.05.25-03.24.19:979][523]LogNet: Warning: Network Failure: GameNetDriver[NetDriverListenFailure]:
[2023.05.25-03.24.19:979][523]LogNet: NetworkFailure: NetDriverListenFailure, Error: ''```
I think I found the error from the log
I compared with the Stand Alone log and I think I located the problem: Unable to load SocketSubsystem module STEAM
hello hello, me again with the same problem and some progress
command/exec function to set playername called by the player at runtime via console
void UPuzzleGameInstance::SetPlayerName(const FString& s)
{
APlayerController* PlayerController = GetFirstLocalPlayerController();
if (!ensure(PlayerController != nullptr)) return;
AGameModeBase* GameModeBase = GetWorld()->GetAuthGameMode();
if (!ensure(GameModeBase != nullptr)) return;
GameModeBase->ChangeName(PlayerController, s, true);
}
onrep playername change in player state
void APlayerStateWarlocks::OnRep_PlayerName()
{
Super::OnRep_PlayerName();
OnPlayerNameChanged.Broadcast();
}
player name widget binding
void UPlayerName::NativeConstruct()
{
Super::NativeConstruct();
APlayerStateWarlocks* PlayerState = Cast<APlayerStateWarlocks>(GetOwningPlayerState());
if ( !PlayerState ) {return;}
PlayerState->OnPlayerNameChanged.AddUniqueDynamic(this, &ThisClass::SetName);
}
void UPlayerName::SetName()
{
APlayerStateWarlocks* PlayerState = Cast<APlayerStateWarlocks>(GetOwningPlayerState());
if ( !PlayerState ) {return;}
FString PlayerName = PlayerState->GetPlayerName();
PlayerNameLabel->SetText(FText::FromString(PlayerName));
UE_LOG(LogTemp, Warning, TEXT("Player name is %s"), *PlayerName);
}
problem in picture, i run the command on the listen server and both actors get their name updated to same thing .. but on the client no change is detected
You have SetPlayerName set as replicated?
no
UFUNCTION(Exec)
void SetPlayerName(const FString& PlayerName);
its an exec function
i think we spoke about this last time and you can't replicate it i think
Ok, so Game Instance is not a replicated actor. Game Mode only ever exists on the server. You're not RPCing anything.
mm ok gameinstance != gamemode
but is game instance server only? or for each client?
each client right
Game Instance is a unique actor for each "instance" of the game running. When you start the game up, Game Instance is loaded.
mmm makes sense ok, so sorta of client only
No
GameInstance is literally the game's instance. Only your pc can access it.
So you must send the RPC through an actor that is client owned, like the playerstate, playercontroller, etc... Once running on the server, then you can access GameMode.
GameMode is for server only things, like validade if a player died or spawn things
oh godddd haha i understand what youre saying ok let me try something
I advise you to check the epic documentation about the hierarchy
ughhh
APlayerStateWarlocks* PlayerState = Cast<APlayerStateWarlocks>(PlayerController->PlayerState);
if (!ensure(PlayerState != nullptr)) return;
PlayerState->SetPlayerName(s);
then what?
trust me, ive done a lot of reading and watching haha
I think the Player's name can be accessed in the PlayerState easly
Your SetPlayerName() on playerstate then can call the GameMode function to set the name.
in the onrep in player state? i call gamemode change name>
If you're trying to use the Game Mode's ChangeName() function then you'd have whatever RPC call that function.
OnRep == The variable change was received on clients.
