#multiplayer
1 messages Ā· Page 710 of 1
I'm having trouble with multiplayer in my game. Unreal Engine/Steam related.
Using the appID 480 (default, for Spacewar) we can have multiple players connect in a match and everything works as intended. Changing 480 to our own appID, the multiplayer stops working and we can't get two players to connect. We're changing the appID in the "DefaultEngine.ini".
Can anyone help, please? I can provide more info if needed, I just wanted to keep this message as short as possible.
Is that really a appID you got from Epic or Steam (Forgot which one will give it out).
I'm not really deep into this, but i've read that Epic provides us a developer ID everyone can use, but for the real game you'd need a own one which you'd get
Yeah we have our own appID given by Steam. We paid for the "Steam Direct Fee" in September and got one
In that case i'm not knowledgeable enough xD
Do actors replicate when spawned as deferred or do they replicate once they are finished spawning?
no š
clients don't have deferred spawns and don't call FinishSpawning for actors that are spawned from replication
they do everything up to and including running construction script
then all replicated variables are set, and all OnReps are called
I'm not sure that was his question.
after that comes PostNetInit call
and then BeginPlay
ah right
not sure about that, but easy enough to test - put a breakpoint in SpawnActorAbsolute (all replicated actors go through this on clients), spawn it on server, do not call finish spawing and see if the breakpoint hits
Is there any way to work with steams API in development, without having to yknow pay $100 and get your game on steam?
Yes, just use the default 480 id
i know that im replying 2 days later but whatever, how exactly does this work? does the server just pick a new port each time or?
aight
Gamelift showed this error when creating fleet.
An error occurred (FleetCapacityExceededException) when calling the CreateGameSession operation: Unable to reserve a process on fleet. (No active and available server processes found on the fleet)
Anyone know about that?
Probably want to ask on a Gamelift Discord
invite link?
Are multicast RPCs ignored on a dedicated server?
Shouldn't be
Wait shouldn't be as in they would run on a dedicated server?
It doesn't seem like they do
As in it does when a listen server host is present but doesn't when I "Play As Client" which simulates the dedicated server
AFAIK they should follow the same rules as listen server
Strange... not sure why it'd differ here
Ah it seems in this particular case, I've tied some logic into the number of spawned niagara components on an actor, I assume dedicated servers completely don't spawn niagara components at all?
I'll decouple the logic to reference a separate int instead
Yeah they don't create them, nor audio components IIRC
Hi Guys !! , Sorry ... I have a question.
I have a list that shows information based on the players on the map. I want it to be updated when a player enters or leaves the map. Is there an event that is triggered when this happens?
GameMode has functions when a player joins/leaves the game, if that's what you mean.
OnPostLogin & OnLogout
TY
Ty
Hello! I am getting this error: NULL GameState when trying to spawn spectator!
Can someone help me?
Is it possible for the sender of an unreliable RPC to miss it? I understand how clients over network might, but I imagine the sender would send the call out to other clients and then just run the intended function itself. Is this accurate?
hi for using 3rd party database like dynamodb do i still need to have savegame_bp?
define the sender. i assume your referring to the server?
In my case yeah it would be server. I would assume if server sends an RPC to all clients, it would have no need to send one to itself (if that makes sense) and therefore doesn't have to worry about reliability.
Yeah, no risk of it being dropped
The server will just run the RPC function
If there was a button to remove the widget from the player, how could I do this only for the player that pressed the button rather than all the players in the lobby
Widgets are clientside only so just do it.
what's a good way of doing user interaction? Like I press e to "use" things, like a storage box or a door? I have the basic system down but I want a solid multiplayer solution. If I have a storage box, obviously it has a widget that pops up with what's inside. Do I send my use request to the server which does a trace then tells the client "all good, open this widget and populate it with this data"?
is aws a good back end server to use on unreal ?
Yes. You can do a line trace or however you may be detecting the actor to interact with, and call an RPC to the server with reference to the actor. The server then can validate if the actor is within range, etc. and can call an interface to perform the interaction event with the actor and possibly the player controller that is performing the interaction with it so it can then RPC back whatever is necessary back to the player.
Thanks, this is sort of what I had in mind except my current implementation doesn't have the player send the actor, both server and client end up doing the line trace
Can do it that way too, works the same.
Good in what way?
beginner friendly and pricing tbh. cant afford to pay 3000dollar fee if thats what aws asks
I would do the selection of what actor to interact with on the client, then do an approval check on the server.
In our project we do a sphere trace then select based on dot product and distance.
Don't put the cart ahead of the horse. Do you really think you'll have the player base to need that? That's like 100k concurrent players.
Hi, one question to those who are more experienced with mp on ue4.
It's said that ue4 is not good for mmorpgs, but i just saw that Lineage2 is made with UE4 and it hold up quite a big amount of players while doing ok.
am i missing something?
Using Unreal Engine doesn't necessarily mean using the full feature bundle that ships with the engine, they might very well have done their own networking architecture
see spatialOS for example
But yeah given the default Unreal Engine environment, in which a single server holds your logic and data, you won't be able to scale much in terms of CPU time
bandwidth isn't really the problem here
Anyone actually making an MMO has enough programming know-how on their team to make it work.
If you don't have at least 10 million to spend on development, get the idea of an MMO out of your head. It's not going to happen.
Building an mmo requires a massive amount of custom networking (and other systems) that very few engines provide. Unreal won't hamper you, but it isn't going to do anything like that out of the box. But no other general purpose engine will either.
it's very complicated and the amount of tech stack and knowledge needed is great
Ah, it's this time again.
yuup
Just curious, not trying to make one l2
i already made the prototype of a fake mmorpg and it works okey
o7 aight comrade, just think that mmos are the pinnacle in terms of networking challenges š
The moment the moment gameplay in the context of a single player isn't the hard part. The hard part is the massively multiplayer bit. A single player game with wow or Eve or realm of the mad gods gameplay would be a cakewalk in comparison.
That was my experience so far, way harder to do something when trying to enable some sort of multiplayer interaction
Another thing i can't wrap my head around is things like rune scape.
Let's say you don't want to make a big mmorpg, but something like rune scape in the old days.
With all the advancements in technology, is it still more costly to make it?
so... if you create an engine in which you will deal with light-entity data oriented specifically towards your purpose and distributed enough to handle gameplay... you could instance zones per server and do what-so-called server streaming
like... there are tons of implications that numbering them all is impossible
good thing nowadays is that there are services that you can pay for that simplify your task
for example, aws back in the day didn't exist
Hi im trying to get the instigator/Owner of the projectile but when the projectile is looking for the instigator it comes out as none is there a part I am missing to get the owner of the projectile so the server knows who killed who the death counter works, i just cant seem to find the killer!
RuneScape wouldn't be nuts to make but you'd need some good talent for the back end. Def not a no budget indie project.
Hey. Does anyone know of a good tutorial for Multiplayer using dedicated servers which includes Spawning a Player with correct ownership, correct way to spawn widgets on clients, etc. I understand a lot of the terminology and have Cedric's network compendium practically memorised but I keep running into issues with what should be basic stuff. Cheers
are there any good sources on multiplayer (i've read the basic one)?
or does the ue engine handle this? (obviously you need to use api of provider, steam/epic etc)
@junior totem start here https://docs.unrealengine.com/5.0/en-US/networking-and-multiplayer-in-unreal-engine/
it is rather basic though
damn i only have 9 mil :(
If I create an object with a "stable name" on a client & send a request to the server to create an identical object with the same stable name, will the client's object automatically sync-up/get swapped with the server's object when the server tries to replicate it?
I'm curious if I can use that flow to spawn an object on the client immediately so I can pass it around to other functions without having to wait on the server first?
Ok so, I have a collection system I made. However I am having problems with the client to the server replication. The Player controller detects the interaction key being pressed. and sends it to a custom event that runs on the server. Which connects up to cast to the object as replicating to server. Then inside of the object, it casts to the gamestate to subtract from a number for the UI and game info. Then visually it hides the object, then after 2 seconds, it removes it from the server, then that calls to removing multi
Hey guys I posted a job in #freelance-jobs if anyone is interested. Just needing help setting up multiplayer server hosted on google cloud vm.
Hi, let's say I want to do a climbing animation
I probably should use root motion for it, and probably I want the animation to play immediately, with client-side prediction, not waiting for the server to confirm that I will do the animation, because it would look nasty on pings like 50ms and more, and even on lower pings it would make the movement less fluid
So I set up it like that
Event Climb(not replicated)- do the anim montage and then call ServerClimb
ServerClimb(ServerRPC) - call MCastClimb
MCastClimb(Multicast) - if(!locallycontrolled) do the animmontage
But it makes my animation jittery on higher(30ms+) pings on clients.
If I remove the primitive client-side prediction algorithm:
Event Climb(not replicated) - call ServerClimb
ServerClimb(ServerRPC) - call MCastClimb
MCastClimb(Multicast) - do the animmontage
It still jitters on clients, not even less
So i'm out of ideas how to do that without location jitters :c
Is root motion prediction only implemented well in GAS?
(or does it jitter even there? :c)
I think my problem could be solved if I could somehow turn off position correction temporarily, but idk how to do that without turning off the whole movement component (which happens when I turn off replicate movement, and whole sequence fails on client's side and everything desyncs)
i have a multicast blueprint event which is definitely being called on the server but the client never receives it. do multicast events only get called on players who own the actor or something?
Hi, So I am building a lobby and noticing that, upon connecting, a blank (no Name) entity is always part of loop of game states. What exactly is it (immediately after host connects, and persists when updated with child)?
you should be able to put a breakpoint in the part of your code/blueprint that populates the lobby and find out what it is
Won't do me any good, I know "what it is" in the sense that its coming from the foreach loop of player... oh shit. did not decrement last index, thats def it.
yup that did it. gosh im retarded.
You have been invited to join #pretendevs
lol
gamestate is attached to gamemode, but I want some network variables (playerstate) attached that work between level switches (game mode switches). how does one migrate specific player state like this?
CopyProperties
If the client isn't relevant for the actor the rpc is being invoked from then that's reasonable
How do I know if I'm relevant? I'm standing right next to it so it's not a distance thing
Pinned messages, especially Cedric's compendium
IsRelevantFor
It's not always distance, but yeah shouldn't be that then prolly
Hmmm. How are things like doors normally done? Because that's what I'm trying to do. Player interaction is sent to the server then multicast to animate
Look into Udemy's courses you might find something you like, and hey practice makes perfect!
Multicast wouldn't be a good idea. For players that are not relevant you will have a door closed for them when they become relevant
Multicast isn't for state changes
It's for transient stuff
I'm not sure I understand
So you would replicate that instead
Let's say you have a player that is far away from that door, i.e not relevant. Then when he becomes close to that door after it got opened by someone else, he would still see it as closed
The reason is that you multicasted that door open instead of replicating it
Oohh I see
Multicast just isn't for state changes
So I'm guessing when a client becomes relevant they get all the stuff replicated to them
Correct
Gonna have to move you to 51%
Ok, using the advanced sessions plugin and trying to do a seamless server travel. This used to be working with Open Level, but I needed to switch. Server can host, and transitions to the correct map. Client can view hosted session, and calling Join Session returns TRUE. However, despite returning true, it never transitions to the new map. If I click the join server button again, it will now return false. Any idea what causes such behavior?
I had multiplayer setup and working with a game Iāve built. Im using a vm instance server with GCP⦠for some reason I recently started getting this error when I log into my game.
āError: Client : Outdated clientā
Im not that familiar with this since I wasnāt the ones that setup the server. The guys I hired I canāt get ahold of. Does anyone know what this means?
Just going out on a limb, but that sounds like the unreal build on the server is newer than your unreal build of the client. I would try rebuilding your client with an up to date version of unreal
Means different game&server version
That's kind of something you should know
You have to update the server with the client
Id immagine you could get it from the command line on the server
Both client and server should be compiled at the same time, from the same engine with same project
probably something like --version
Ok got it⦠Iāll compile both and update the server and see if that fixes it
Generally speaking you need to update the server every time you change anything to the game
hmmm...
this makes no sense:
// server
[2022.04.28-08.15.18:537][148]LogLoad: Game class is 'MyGameMode_C'
[2022.04.28-08.15.18:537][148]LogStats: SeamlessTravel FlushLevelStreaming - 0.000 s
[2022.04.28-08.15.18:537][148]LogWorld: Bringing World /Game/Levels/CharacterSelect.CharacterSelect up for play (max tick rate 0) at 2022.04.28-03.15.18
[2022.04.28-08.15.18:537][148]LogWorld: Bringing up level for play took: 0.000285
[2022.04.28-08.15.18:538][148]LogWorld: Sending NotifyLoadedWorld for LP: LocalPlayer_2147482558 PC: PlayerController_2147482525
[2022.04.28-08.15.18:538][148]LogNet: Verbose: NotifyLoadedWorld Begin
[2022.04.28-08.15.18:538][148]LogNet: Verbose: NotifyLoadedWorld End
[2022.04.28-08.15.18:538][148]LogWorld: ----SeamlessTravel finished in 0.10 seconds
// client
[2022.04.28-08.18.30:250][758]LogScript: Script Msg: Found a session. Ping is 53
[2022.04.28-08.18.30:250][758]LogBlueprintUserMessages: [UI_JoinGame_C_2147482502] Data Refreshed.
[2022.04.28-08.18.34:928][263]LogOnlineSession: OSS: Join session: traveling to 192.168.0.200:0
[2022.04.28-08.18.34:928][263]LogBlueprintUserMessages: [UI_SessionButton_C_2147482500] Succeeded In Joining
[2022.04.28-08.18.34:929][263]LogNet: Browse: 192.168.0.200:0/Game/Levels/MainMenu
[2022.04.28-08.18.34:929][263]LogInit: WinSock: Socket queue. Rx: 32768 (config 32768) Tx: 32768 (config 32768)
[2022.04.28-08.18.34:929][263]LogNet: Created socket for bind address: 0.0.0.0 on port 0
[2022.04.28-08.18.34:929][263]PacketHandlerLog: Loaded PacketHandler component: Engine.EngineHandlerComponentFactory (StatelessConnectHandlerComponent)
[2022.04.28-08.18.34:929][263]LogNet: Game client on port 0, rate 100000
Any issue?
When the client connects to the host, the host correctly server travels, but the client travels to the wrong map (main menu)
Why would the host travel when a client connects?
im not sure what you mean, this is not a dedicated server, the host does the server travel, and it also goes to the correct level
What I'm asking is why a host would travel when a client connects
That seems absurd
unless you mean they join the lobby
no, it travels before the client connects
Can't read that. but have you checked "Absolute"?
yes
wait, absolute is not seamless?
ah, I thought when I switched from OpenLevel to ServerTravel it was making it seamless
odd, I just repackaged with setting that to false and it still took me to main menu
The most likely explanation is the travel is failing for whatever reason so clients are being kicked to the default map
OpenLevel is a hard travel, and ServerTravel with "Absolute" checked is also a hard travel
I just realized I did not recompile the script after the change. trying again.
Also bear in mind that seamless travel does not work in editor, you'll need to at least run it as standalone
that makes sense now, Each version of the game i make i need to update bboth
nope, still no
yeah , I am packaging and running it from the folder
and using ~ showlogs to view logs
You might need to attach the debugger and figure out why it's kicking you back to the menu
Build a DebugGame package not a shipping one to get some useful logs. May also want to enable more verbose logging
But in the server log there should be some disconnect messages at least
hmm, connected a new client to the server and did showlogs and oddly no logs appeared on the server.
Are you sure they're actually connecting at all?
And are you packaging a shipping build or something?
its packaging as Debugging, and I am sure its connecting because I see its connecting to the session.
sorry, Development not debugging
So they're joined and in the same level as the Server?
All good, shouldn't matter too much so long as it's not shipping
yes, it joins to the session.
and if I call the join again, it says "cant join twice"
Cool, and you can see the server/client in the world?
For travel to work, the players need to be both connected to the session and in the game world
"and in the game world", both go to the main menu, on the "host" (peer-to-peer) I launch a session, and it moves the host to the correct next level (the player select). On the client I then click "join", and the session pops up (find session), clicking it calls "join session", and after a few seconds of that join it goes to the main menu
Okay that's where it's going wrong then, during the join
but join returns "success"
Given that it's advanced sessions and I've not used it, I can't say what it might be - but do you know what online subsystem you are using atm?
I'm not 100% sure if the "default" subsystem that the engine comes with fully supports sessions
what online subsystem? not sure. I would assume its default, though I did subclass all the necessary classes and gave it a transition map, etc.?
Are you sure there's no game logic thats accidentally causing the client to go back to the main menu also?
shouldn't be, this was working with OpenMap
im not noticing any errors in the logs, but I can't fully debug the blueprints due to needing to use the packaged version.
Ah the glory of BP.. okay so I think it's working with OpenMap "IpAddress" since the "Default" subsystem that comes with the engine doesn't fully support sessions, you would have to use something like the Steam online subsystem to benefit from sessions.
The default subsystem is just a simple "connect via IP address" setup, but server travel (with absolute unchecked) should work with connect over IP
yikes, I really don't want to limit this to steam.
[2022.04.28-08.47.20:828][967]LogScript: Script Msg: Found a session. Ping is 33
[2022.04.28-08.47.20:829][967]LogBlueprintUserMessages: [UI_JoinGame_C_2147482502] Data Refreshed.
[2022.04.28-08.47.28:190][773]LogOnlineSession: OSS: Join session: traveling to 192.168.0.200:0
[2022.04.28-08.47.28:191][773]LogBlueprintUserMessages: [UI_SessionButton_C_2147482500] Succeeded In Joining
[2022.04.28-08.47.28:191][773]LogNet: Browse: 192.168.0.200:0/Game/Levels/MainMenu
[2022.04.28-08.47.28:191][773]LogInit: WinSock: Socket queue. Rx: 32768 (config 32768) Tx: 32768 (config 32768)
[2022.04.28-08.47.28:191][773]LogNet: Created socket for bind address: 0.0.0.0 on port 0
[2022.04.28-08.47.28:191][773]PacketHandlerLog: Loaded PacketHandler component: Engine.EngineHandlerComponentFactory (StatelessConnectHandlerComponent)
[2022.04.28-08.47.28:191][773]LogNet: Game client on port 0, rate 100000
Yeah, so it's joining the session, but just going right to the main menu
LogNet: Browse: 192.168.0.200:0/Game/Levels/MainMenu
note: itss technically coming FROM the main menu as well
BTW the session stuff doesn't limit you to Steam, but for "sessions" stuff to work you do require an online backend service of some kind, such as Steam, or a relevant Console platform etc.
Im curious as to why that would be the case. I mean, I understand you would need that for certain authorative stuff. But mearly to do a servertravel?
ServerTravel itself should work fine with the connect over IP stuff you've been using currently
like this is lan.
Yeah that's fine. Sessions is the whole "online backend" concept, but if you just want simple LAN/join via IP, you don't have to use it. The "OnlineSubsystemNull" which is the default seems to have some really primitive support for sessions, but it looks like it's sending you to the wrong map when joining
I figured steam / etc only came into place when you needed to poke through firewalls
Steam comes into place if you want to do anything online essentially
Or anything that integrates with steam features
right
ok, so is there something other than none I can use? would this be a platform bug?
Probably just a bug in the "Null" subsystem. My advice right not would be to just not use it, unless you're comfortable with C++, can move the plugin into your project and fix it up. I'm just taking an educated guess atm btw, not 100% sure this is actually the problem
For all I know it could be the "Advanced Sessions" plugin causing it
im comfortable enough with C++
It could be something as simple as the plugin isn't actually attaching the map in the travel URL
When the client joins that is.
if I use the steam subsystem, I am tied to steam correct?
Hi quick question about dedicated server, is it a best practice to have 2 projects ? One for client and one for server or have both in one project ?
You don't use the Steam subsystem, you use sessions - the beauty of it is that Steam vs say GOG or console is mostly a .ini change
You need to have it a single project
Server and game are the same thing with different build options
Hmm, I might try writing a BP C++ helper to expose JoinSession. I am fairly sure Advanced Sessions plugin is just a thin wrapper over the existing subsystems, but as you said its possible they messed that up.
If you use Steam specifically, then yes. But the Subsystem API is designed to be platform-independent.
AS is indeed just a Blueprint layer that simply exposes the generic session system (and it works)
What you would not be able to do, is have one user using the Steam subsystem, and another using another platforms system.
They wouldn't be able to connect to each other, and then you've entered the realm of cross-platform which is not something you can really support in Blueprint alone.
EOS is supposedly meant to tie all these subsystems together under one, but that's a whole other ballgame again
I have no problem going into C++ land, provided I don't need to implement the kitchen sink. I have regularly been writing BP-C++ helpers.
There's a lesser-known "Multiplayer Shootout" sample on the Epic marketplace/samples tab, it would be worth checking that out and seeing whether they use the session stuff in editor. If they do, and it works, it's probably a problem with that plugin.
Your problem is not an Advanced Sessions bug, that much is safe to say imho
This one
Only goes up to 4.24 however
Cross-Platform play means you either have to build you own backend and create a subsystem wrapper for it, or do what most others are doing and try to make sense of EOS
Sessions never work in-editor, do they?
what is that analysis based on? Just the fact its well recognized?
- I am not in editor.
The plugin does essentially nothing more than forward the API to Blueprint
There really isn't much that can go wrong
thats what I would have thought, but something clearly is, and in a weird way. My code is pretty straightforward.
LogNet: Browse: 192.168.0.200:0/Game/Levels/MainMenu
This message makes it quite clear that the players are joining the session then for whatever reason, they are entering the main menu. That to me indicates that the map name hasn't been properly attached to the session join URL.
Since they should be joining your "character select" map, whatever that is
yes, and the host DOES join it.
Assuming that's what map the Server is in
The low-res Blueprint screenshot you shared wasn't readable but the URL looked wrong and I didn't see the session search part
I'll try to make it bigger.
Here is the travel:
Here is how session is created:
Okay so for the record, the multiplayer shootout sample does use sessions, and joining works fine in standalone
What's UseLAN here?
Here is the how it joins to session:
This is how it's hosting
What's the search code like?
Should be OpenLevel, anyway
what should be open level?
I thought open level was not seamless?
You cannot do seamless
OpenLevel will take the Server to the level immediately, that part is fine.
Why can I not do seamless, thats what this was about, I had it working in non-seamless
Transitioning from single player to listen, and connecting to a server, have to be non-seamless
ServerTravel will take users that are currently in that level, to a new level, without disconnecting them. That's what you use Seamless travel for.
Only travel for connected players and once you are a server can be seamless
And you haven't shown the session search on client
That could also be wrong
you mean my listing of sessions?
I mean the search that yields the session you are joining at all
Alright
I'd start with a much simpler setup that joins the first search result directly in the callback, but looks fine overall
Fix the travel
The Session System in Unreal Engine 4 gives you access to many powerful online features such as the server browser, setting a maximum player limits, setting private and public slots and much more. Using this system is very straightforward and only takes a few blueprint nodes to get working. In this guide I will show...Read More
server/client here
No need to make it complex, that's 4 nodes on each
the reason I pulled openlevel and switched it to server travel is because I need to move the "clients name" from the main menu into the character select.
it works fine with openlevel, but I cannot move any variables to it.
You have to use OpenLevel - like Jambax said, it simply is required
ok, so then how can I populate some sort of constuctive state at the beginning of the server?
like, after session population but it moves map? Keep it in gameinstance raw?
Game instance is one way to have persistent data
so what would be the best way to immediately send certain state right after it connects?
like, what I am tryign to do is fairly simple, I want to rid the long machine names and allow lan users to supply their own name and player color before logging in (saving it locally between gameplays). not authorative, just something to make getting into a game easier. But once its in there, it needs to not change (so be in playerstate on the server)
What do you mean, "send" state? Send from what to where?
send from "gameinstance" to the "playerstate" so that the "lobby" has data that was set pre joining the session
I want to rid the long machine names
Your online susbystem will provide the platform name
allow lan users to supply their own nam
Change the name variable in playerstate with a server RPC
for point 2, "where", logically speaking
ok, so instead of sticking it into the player state, I need to stick it into the game instance and copy from game instance to player state at indeterminate point.
You can also append the players name to the join URL IIRC
It's not really indeterminate, it's simply fairly game-dependent
Just implement the feature
Or let the players use the Steam name
(Which will work out of the box, again)
Well only if you use Steams subsystem ofc
is there any documentation on all the features of the join URL? I could not find any
Doubt it tbh š
You can append "options" to it in the ?Key=Value format
But again BP gives you limited options
yeah, I realized that when I saw openlevel in comparison to the server travel, but beyond "Listen" I didn't grep anything
well no, it exposes that string to you completely
if it can be passed through the url I think we can pass it through
do you know roughly what portion of the source this would be in?
probably something nearby IOnlineSubystem I am guessing?
It's somewhere at the game layer, just having look
Ok maybe I'm going mad
It's been a while since I looked at any of this.
Okay the Key is "Name"
AGameModeBase::InitNewPlayer is what parses the options
unless, this is code we specifically added, which it might be
But yes by default, that name is set by the OSS from the users' profile name
Which doesn't exist in the "Null" subsystem ofc
is there a way for me to switch on the subsystem so that it only implements this logic for null subsystem? just as a cross platform possibility?
There is not
If you want cross-platform, you're only real option currently is to try and make sense of the Epic Online Subsystem which attempts to tie all the online services together
AFAIK platforms like GOG don't have an online game backend service
NULL isn't usable in real world anyway
So you'd need to either rely on another, or build your own
GOG does
They even have an Unreal OSS plugin
Ah nice
Well they did 5 years ago, anyway
Cross Platform is a world of hurt. Frankly it's not worth bothering with unless you're on console
Crossplay is dumb
Or unless you want to force everyone to use either a) your own login system or b) Epics
And there's plenty of reasons not to do either
Good luck having your game update at the same time for every platform
We've got Crossplay on console, but we've taken approach A
On PC we did the sensible thing which was to just ship on Steam
The most irritating thing about Crossplay is how players are almost expectant of it to work now, but don't realise what a massive minefield and effort it is to actually support.
And the reason they have to create a new user account for every company that launches a game
The most irritating thing .. is .. players
would be nice if a standard STUN/TURN system was created for p2p, using something akin to DNS chains for authenticating users against a domain/service provider.
chain of auth I mean
sadly it'll probably never happen
I'm sure somewhere there's a guy screaming "blockchain" into the void
of course it wont, everyone is trying really hard to sell authority as a service
(Unpopular opinion but platforms are fine)
platforms ARE fine, but some form of basic interopability would be nice.
EOS is supposedly supposed to be something like that, but to my knowledge it unites everything under an Epic account, so it's really just more of the same.
Of course it's more of the same
But honestly, cross platform on PC isn't worth the hassle
Assuming you even get enough players for it to become a talking point in the first place
well its real usefullness would be more in the area of niche games to begin with
where platform splintering hurts
The problem is that player identity is a much more complex concept than people make it sound like - from achievements, to matchmaking, to avatars, "inventory" concepts - if you want a common API you end up with something quite minimal. Steam's got a great player identity system and being unable to use it because you want say, EGS compatibility, is just sad
but frankly the auth problem isn't just a games problem. google, meta, they are all doing it
well right, we need a higher level very simple system. a platform publishes a list of usernames and a public key next to them, allowing you to verify ownership of an id at a domain (cesar@steam) by checking the platforms sig, and then a STUN/TURN protocol that provides reachability.
people will roll their own VOIP using turn
everything else, platform services, chatrooms, etc can be black boxed, but main reachability and identity issues can be solved.
is post_login called on every server travel? or just the initial room they log into?
I have an actor in my scene in a multiplayer game. Is it wise to store a variable "Owner" that's the PlayerController? Can this be accessible by other clients?
You can define an owner if you want, but other clients will never have any controller but their own, so a reference to another controller will fail
The problem isnāt the variable
The controller itself does not replicate to other clients
So you could say that the other clients will get the variable sent to them, and it will point to nothing as far as they are concerned
so anything that inherits playercontroller will not replicate no matter what I do?
I donāt know about āno matter whatā
Wow you're right, I just checked
But Under normal circumstances it wonāt work. The player state is what you are looking for
All players have access to the player state of every other player
but if I did do this on the server, I'd have access to it right?
Yes the server has access to everybodyās player controllers
so using a playerController to mark an owner of an actor is a mistake then
if I want to use it on other clients
If you want other clients to know what the owner actor is, then yes
If you want a player to be the actual "network owner" of an object, the very top of that owner chain MUST be a player controller
yeah so it's like, when I roll a dice, and I move to a spot, I want to know about everybody else on that spot
but so far we've been using playercontroller to represent the owner of the actors on that spot
š¤¦āāļø
Yeah, clients only know about their own controller
You should switch all of that to player state
Or Pawn
Pawn is usually the physical representation/avatar of a player in the world
Player State is persistent information that can be access all the time, but is usually pertinent to the player themselves, such as their name, score, level etc.
yeah I liekly want player state here. because I intend to manipulate the player state as the final outcome
but man I have to refactor so much
I knew this...what a silly mistake
if I really wanna save this, I could do all my ops on the server and data back to the owning client
but what a headache
Realistically this sounds like something that belongs in the game state
Hard to say without knowing more though
@chrome bay so basically, when I arrive at a tile, I get to pick any other player with an actor (house) on that tile and take something from them
so I need access to what they own, and their name, and what I own
so that I can show it on the UI and do the transfer
So you want to know who owns the house essentially?
yup
If that's the case, the house having a replicated "owner" property which references a Player State makes sense
yep. Actually to make it simpler, I thought I could just have a replicated player Guid, (which is inbuilt into playerstate)
but the problem is now I have to refactor everything š¢
The simplest way is the player state ref itself
Using the player Unique Net ID directly is quite rare
It's also much more costly to replicate
Since internally they are usually quite lengthy strings
how is player state not more expensive? isn't it bigger and an actor by itself?
An actor reference will replicated as a UObject Network ID
Which is 32 bits
You're not replicating a complete actor when you reference it, you're replicating a reference TO an existing actor which replicates independently
what does "replicates independently" mean? Don't you still have to send info about the actor over the wire? (such as its rep variables/repnotifies? Or are these separate too?)
Also movement, position etc
The actor instance is replicated by itself
When you create a reference to that actor in another actor, the reference is what is being replicated - not the actor instance
Replicating a reference to an actor costs very little
So say my actor is at position (x,y)
If actor moves to position (x1,y1) on the server, you're saying the actor (which is replicated) the reference (obviously) does NOT change, but the transform is now propagated to every client?
is it possible to get the connection that called a server RPC?
You are refering to an another object only
@grim valve It will always be the Owner
Only the owner can call a Server RPC
this is fair. I mean I do understand how referencing/pointers work so I know what you mean
but I just wanted to clear up the idea that the instance (on the local client) is still tlaking to the server to pull the latest transform/variable/whatever else is replicated
It is yeah
but ok, good to know that I can hold a ref ot these actors with minimal overhead
The Server checks if properties have changes (at the end of the frame), then sends any changed properties to clients the actor is relevant for
so then could I use gameinstance and a server RPC on it to pass specific information from the client to its playerstate?
@chrome bay what I am thinking for a temporary refactor is: Keep my existing code as is, but where I am setting the house owner (i.e playercontroller), I will also set a houseowningplayerstate, and use that for now
I wouldn't even do that, I'd just set the existing "Owner" property.
but I am using the owner everywhere (i.e the player controller) to do several operations everwywhere. thakfully all of them are happening on local client
If it helps, the Player Controller is the "Owner" of the Player State
But instead of replicating multiple properties that are essentially all doing the same thing, you may as well use an existing one
And cast it to the required type when needed
what does this mean? i didnt understand
then I am at a loss at where I can make this pass of information. I can't put it in the gameinstance because its local only, I cannot put it at the playerstate because its owned by the server, I cannot put it at the start of the level because its owned by the server?
All actors have an "Owner" property built-in, which is replicated. The actor which is the "Owner" can call Server RPCs
anything else seems to be open to abuse by other client connections
You can only call Server RPC's on Actors which you "Own" - which by default is your Controller, Pawn and Player State
PlayerState is client owned.
wait, you own your player state? I thought the server did?
Same as PC, possessed pawn
The Server has Authority, but you are the "Net Owner"
All of those actors are ultimately Owned by the Player Controller
Which is what determines whether you can call a Server RPC on something or not
What do I pass to SetOwner though?
@near bison The PlayerState
Each house can be "Owned" by a Player, and all other players can also determine who owns a house
so the actor who owns the House is...somebody's PlayerState? Is that how it is?
Yes
Why not just have a variable called PlayerState and replicate that instead š
Because why replicate two references?
You already have an "Owner" property
Which also comes with the benefit of a) being able to call Server RPC's on the house if they need to, and B) being able to replicate properties ONLY to the owner of the house
AActor
Just Actor
Any actor can own any other actor
If the root of that ownership chain is a player controller, that player can call Server RPC's and receive "Owner Only" properties
so getowner is then the immediate owner of an owner tree?
"Owner" is just a property of AActor
so basically now, there will be 2 "owners" of this house. 1) this owner I set, 2) the actual playercotnroller itself (who can make server RPC calls)
There will be one owner. The PlayerState
The PlayerStates "owner" is the PlayerController
Thus you have a valid ownership chain
Has anyone else found this "bug" in UE5 yet? Create an empty map, run a PIE session with a listen server. BeginPlay will run on both client and server. It seems such a major issue that I am starting to think I must be going crazy as nobody else is shouting about it, but I have not modified the engine š
It's no different to how when you spawn a weapon, the "Pawn" is usually the "Owner" of that weapon
Isn't that intended. BeginPlay runs on every connected client + the server (For an actor)
BeginPlay has always run on both Client and Server
Yes but I am a listen server there is only one machine
Then it will run once
It doesn't š
I doubt it, there is only one instance
is the immediate owner of playerstate always the playercontroller? Or is there depth?
how would I refactor what I currently have then? I'll show you an example
always
Unless you decide to change it, but that would be odd
That is what I mean when I say I must be going mad
nah, want to know if I can rely on it
You can
eg: like this
what changes here? HOwner here is the PlayerController
ok, so then the way to get data reliably and securely into playerstate, is to create a SERVER rpc on the playerstate with the data you want to pass on it, and execute it?
so I do HOwner -> GetPlayerController?
HOwner->GetOwner->CastToPlayerController
And then cast it to the?
ok
Isn't HOwner already a ref to the owner? Why HOwner -> GetOwner?
If you want to send data to the Server from the Client then yes
Get rid of HOwner
Use "Owner"
Cast it to a Player State when you need it
Or make a "GetOwningPlayer" function on the house that does that for you
or player controller when I need it? (i.e locally or on server)
The Owner would be a PlayerState, you can't therefore cast it to a Controller or it will always fail
But you could also add a "GetOwningPlayerController" function, which gets the player state, then the controller from that
you see why this is flawed then
because I can't get easily get the playercontroller locally or on server
You can
And generally it's PC -> PS, it feels weird to get PlayerController rfrom PlayerState
Like this?
I mean I know what you mean, that playerState will instead be my PlayerState
In that case yes then
There's even an existing node for "Get Player Controller" from the player state it seems
ok
I'm just straight up having a bad time
have to refactor like 10 files now
Would've been so much easier if I was writing code
Blueprint sucks for Multiplayer, period
You have less than 10% of what is actually available
why though, what would you say is so bad?
I mean aren't all the APIs I need available?
The vast majority of the core networking stuff is not exposed
Various events and properties that are critical to avoiding bugs are not available
Such as?
Too many things to list. No fast arrays, no custom serialization, much of the gameplay framework is not fully exposed, missing callbacks for important events etc.
what the most reliable way to get the immediate, local player state?
- state of the local player?
Get the local controller and get it's player state
can you give me an example of missing callback for important events? I don't want to dig myself into a hole continuing with BPs
ok then lets go further up, whats the most reliable way to get the controller? Is that always index 0?
Blueprint RepNotify's also don't work properly
yes. index has nothing to do with clients. it's for split screen, which u dont need to worry about
on local client you'l lalways get local play4er controller
First major BP networking wall I hit was that there's no delegate for AGameStateBase::AddPlayerState. Makes tracking new players in UI difficult.
Do you mean it gets called on server too? (I've seen this bug)
Not only do they get called on the Server (which is blatantly wrong), they get called when a client changes a value locally
You also have no way of getting the "previous" value of the property unless you manually cache it
yeah I've noticed this too. In Unity I remember always having access to the prev value
Whereas you can in CPP
But TL;DR, BP only has the most basic stuff exposed, and some of it is not exposed well
Due to silly legacy decisions
This absolutely sucks. This is something that you should expect without thinking twice. We always have an OnPlayerConnected callback we can wire up in Unity, that's the firrst thing all network libraries wire up XD
From what I've seen of C#, if you can use Unity, UE4 wrapped C++ is fairly similar once you get used to Engine stuff. Really not worth avoiding. Even less so with UE5's new Livecoding.
unreals C++ is pretty nice in spite of its intellisense woes
It's also why you see BP games doing this a lot, which is a good way to get yourself shot
GHAHAH i've done this quite a bit
plus you can do most stuff in BP and delegate certain things to a C++ helper library
I switched from that to just calling an event
but still fairly bad...because I expect that delegate to be availalbei n the first place
And that's really what I mean, a lot of this event stuff isn't easy to implement properly in BP
Networking in UE is inherently subject to a lot of race conditions and getting around them is much easier in C++ where you have a defined order of things
And access to everything you need
You totally can make a MP game in BP - but I couldn't recommend it
Realistically, Unreal's core framework makes perfect sense if you just keep in mind the perspective that it was created to serve the purpose of a simple online shooter game. There has been a lot of features and stuff updated, but that core default framework still sorely reflects that fact.
no I actually quite like the framework. It gives me a mental model to have in mind on where I can place things
that isn't the rpoblem
(to me at least)
The Framework is good IMO
this I'm concerned about. I'm already seeing some of these race conditions
Has a bit too much legacy stuff still hanging around, but it's a sensible way to approach things
GameModeBase and GameStateBase are fine, no nonsense at least
But yeah race conditions are something you have to deal with whether in CPP or BP, but it's easier in some ways to deal with them in CPP and handle them better, simply because you have access to everything
Tell you what...I have decided
I'm probably gonna finish this game in BP only. Along with the lobby system wired up to playfab and everything
That'll get me really familiar with all the APIs I need
Then if I need to switch, should be easy
Few days worth of work
BTW this is just my suggestion and more of a "what I would do" but that doesn't mean what you want to do won't work
Just coming from a "best practice" POV
Yeah I don't want to go through analysis paralysis
I'll spend the next couple days thinking bp vs c++, won't get stuff done. waste of time
I'll finish in BP
For sure
Very close to finish line
So im making a snowball game, and i would like for the snowball to have a red trail if the enemy is the instigator of the projectile and a blue if it is a teammate in BeginPlay. I reckon the beginplay fires once for each player controller, is there any way to get like the local controller of the actor?
The best way would be to assign a replicated "team" property to the snowball, then when it replicates, determine whether it's "friendly" or "enemy" to the local player
And change the colour of the particle accordingly
(FYI - this is another pet peeve of mine, the "Instigator" property should be an actor - not a pawn)
Yes that is kinda what i am thinking, i use the instigator's team and want to compare it to the local player. but how can i fetch the local player on the snowball actor?
Just use the GetPlayerController node with 0 as the index to get the local player
hm i tried that, maybe i did wrong elsewhere then š¤
i am doing GetPlayerController(0) then GetOwner and cast it to my character
A player controller owns a character, not the other way around
A player controller has no owner
AutonomousProxy? RPCs? DOREPLIFETIME_CONDITION? ya'll too good for bit banging or smthn
Is there a question there?
Gah, so apparently my clients PlayerState does not exist on its event beginplay of the room its joining.
cast fails for it
(but works for host)
Yeah, this is one of those "race condition" issues I was talking about. PlayerState will be received by the Client at some point, but you don't know when exactly
The same goes for any replicated actor
The only actors that are garaunteed to exist when BeginPlay is called are the GameState and the PlayerController
is it guarenteed to be there at some point? or is it "probably" going to be there at some point (ala could an errant disconnect leave it in a state where beginplay is called but state never exists)
For PlayerStates you will definitely receive them eventually, as they are "always relevant" as the engine puts it
ok, so its at least managable
Unless something has gone very wrong of course, but it's probably completely FUBAR at that point
is there something exposed at C++ here that would make this easier?
(either alogorithm, not easier to code)
obviosuly there is the naive delegate -> while/tick -> delegate
For C++ yes
You could override the controllers "OnRep_PlayerState" function
Which will be called whenever it's PlayerState property replicates
any reason I could not subclass that exposing it as a UFUNCTION?
You can't expose an existing function as a UFUNCTION
But you can create your child class and call another UFUNCTION
well no, but I can delegate it
so what I am implementing is the virtual void in Controller?
that has no arguments?
oh wait, so its not the level I would be subclassing , its playercontroller.
yeah
hmm, yeah I see what you mean about it not fitting BP entirely, this is hard to conceptualize.
do I even know what my level is going to be at the point of that call?
Depends how you're doing everything ofc. UE has a pretty "framework", it's just figuring out what generally belongs where
Level BP for example is very rarely used for actual game logic, it's usually something level-script specific
Like IDK, opening doors or triggering a cinematic
what I have been doing thus far is implementing stuff in BP, and then refactoring those out into BP helpers in C++, or subclassing where necessary.
the problem is I don't know unreal well enough and BP really helps "guess" the framework since your intellisense bindings suck.
yeah intellisense is shockingly useless with UE, if you want to do C++ a plugin is really an essential investment
VAX, R# etc.
I do like that I can double click most BP and it brings me to the C++, and then I can read the impl
I feel I'm repeating what I just said in the other channel but getting to grips with the "gameplay framework" is probably the first step
And bear in mind Multiplayer makes everything harder
If you don't know UE that well yet, starting with MP is not something most veterans would advise
Of course, ordering of things is the hardest part of CS, especially if your not liberally using locks everywhere
You are probably right, I have a few decades of coding under my belt though so I figure I can weasle my way around.
you have an advantage over most starters tbh with just that
But UE has a very defined "structure" whereas I know other engines are much more of an open sandbox
Not working with that structure can result in bumping up against it
Yeah, I feel that.
Also very worth checking out Epic's sample projects
They aren't perfect but some of them are very comprehensive
Lyra is the latest one but IMO it's very hard to approach for a newcomer, ShooterGame is a very comprehensive example but quite dated (predates UE4 even), but there quite a lot of smaller samples too
I'll certainly take a look
Is this the correct way to get actual ping?
UFUNCTION(BlueprintCallable, BlueprintPure)
float GetActualPing() const { return GetCompressedPing() * 4.f; }
Yeah, it's more accurate as it's direct from the net driver
The packed one is for general display purposes I guess, e.g. UI
Gotcha, thanks
ExactPing is only populated on server + owner IIRC
When the host is also a player, is there a way to distinguish between it acting as a server and acting in the context of a client?
this is in the context of multicast RPC
what
So check if it's a listen server pretty much?
if(GetNetMode() == NM_ListenServer)
if(GetNetMode() == NM_Client)
I dont have the money for a udemy course unfortunately. But I will continue to watch 80 billion youtubee videos regardless :p
GetNetMode() != NM_DedicatedServer should do it really
I used to have a whole bunch of useful macros that did that.
Oh I actually think it should be != NM_Client. FSR I thought he said "listen server", but he said "server"
Oh yeah again "the host" lol
I had a macro like IsNetworkServer() which checked hte right NMs. Made code a lot more clear.
I remember someone here said he's going to make some macros so it eases up the process. Yeah looks like a thing to consider!
I wonder if I can find them somewhere...
No. I mean the ones I made like 10 years ago.
Ah haha, good luck finding them 
There were on pastebin somewhere.
https://pastebin.com/5unJW5d7 š Code bad, but you get the idea.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
š
Use rider
Can't believe I used NULL urgh.
pls haha, that's why the initializer we spoke about was going to be such a great idea
Dont worry, no matter how much you try, you cant write worse code than Epic ever
An innocent NULL should be fine š
Pretty sure you can use your own account service, at least it's advertised that way.
Hello sorry. I have a problem and I don't know if I'm missing something. I have a vr project that is multiplayer. At the moment everything is working fine but in the main menu when I invite a player I get an extra pointer that I assume is that of the extra player, the problem is that when the invited player enters the host can no longer interact with anything in the Menu , the menu is a widget of an actor in the world, and it is not replicated. Isn't it supposed that if I don't reply, I shouldn't be affected by the other players?
The extra pointer does not move so the guest moves the control and it just comes out pointing to a button, which is the only one that works for the host. The guest doesn't see extra pointers and can interact with all menu buttons
what is the ""Correct"" way of making a UI only lobby?
Making a empty lobby map with an empty pawn, with a lobby gamemode and make only UI? š¤
or is there anything else for gathering players before a match start?
I've seen many solutions in the maketplace but I can't afford to buy them just to see how they are doing things š
yep, just create a level for it
you're on the right track, you have bugs/quirks in your replication, and what's running on the server v. what's running on the client, probably
so it's a common multiplayer bug, but you've gotta narrow it down in your code a little more, at least enough to show Discord a blueprint or something
Looking for opinions on replicating a lot of moving AI agents. I want a lightweight way to replicate these suckers, but am concerned a naive client side lerp to destination (based on last servertick and last known position) will still lead to issues.
Here's the scenario:
- I have 1000+ agents, moving along precalculated paths on a terrain.
- Agents tick at variable rates, between 0.1s to 0.5s, depending onhow close to the player they are. Ticks are aggregated and distributed in a round robin method like sea of theives.
- Cosmetically, they lerp using instances and a vertex shader translation trick, so no matter the tick rate, they move and animate smoothly.
- Agents do have GameplayAbilitySystem components for attacks.
- Agents can suddenly stop for avoidance, or being ordered, or stunned on hit.
Thoughts?
no, basic custom pawn, movement is basically an interpolate vector
I've got 2500 of these moving on a quest2, so the movement aint an issue, but I'm trying to feel out if this can be done in an MP scenario without the overkill of a CMC with network prediction (which wouldnt be viable anyway)
Brute force would be just sending out the transforms at a variable rate, but I don't know enough about the internals of the network prediction interface, or even if its needed in a scenario like this
Well prediction doesn't really matter nor make sense since they are agents, which presumably means the player is not moving them directly with input
Hmm - I wonder if anyone has contemplated the idea of making a more lightweight CMC š¤
Movement replication by default pretty much does exactly that, the position is a property, and clients get occasional updates about their position. It's up to the component to "smooth" the movement between updates
Players can move select squads of these agents, but thats an order ontop of the same sorts of, "lerp along this path to this location" that all the other agents do anyway
Yeah so prediction doesn't really make much sense IMO
thats what I was hoping to hear
RTS games generally just use deterministic movement
if only we had deterministic lockstep, oh well š
If you're moving the actors yourself (i.e. they are kinematic) you can sort of simulate it
right, the agents know the path, when the server gametime ticked, the speed and where they should be
If they know the path, and they are just interpolating along it, it should be easy
so clients should be able to predict in sync with the server - most of the time
Replicate the path points and the current time along the path or something
Or an "arrival" time with a synced clock
yup, thats what I've been thinking too. Last question ... for this to work I need to sync the gametimes of the clients and server, any special things .... yeah
any special things needed there to get a synchronized clock?
well you can never achieve perfect sync, but you can get reasonably close
perfect sync is impossible
whats a realistic expectation?
you can get very close, within milliseconds probably
good enough for me
so not enough for differences to be noticeable
AGameState::ServerWorldTimeSeconds is a very basic attempt for a synced clock but it does have some issues, and will jitter up/down as the ping changes so it's often better to just roll your own ping/pong clock
I did come across this: https://medium.com/@invicticide/accurately-syncing-unreals-network-clock-87a3f9262594
When implementing real-time network multiplayer in a game, one very important tool is a reliable network clock.
Good to hear I've been on the right track
But tbf, just replicating the path points (at generation time) then a float which is the "time along path" should be good enough
and just add a layer of interpolation to hide the jitter
Thanks a bunch for answering my questions!
would it be cleaner to generate the points along the path on the server and let unreal handle replicating them out?
i'm asking as a newbie, i'm surprised the solution is that complicated, if it makes sense
yeah that's what you would do
what is the clock part for?
do the navigation server side only, replicate the points (theoretically wouldn't be many of them), then have a time along the path
The clock is just an alternative approach, say you wanted to give an "arrival time" or something.
Lots of different ways to approach this tbh
gotcha
There's two possible approaches I was thinking of. On the server I can calculate a destination point along the agents path (like a carrot), and replicate that periodically. Its very possible that destination point wouldnt need to be refreshed more than 0.5s. Or I could replicate the full path and let the client simulate it out fully.
I'll likely try both.
Thanks for the reply
If I have a function on the PlayerController, how can I multicast it from the server? Or should I be doing that on a function from the pawn?
i dont remember if the controller exists on the server but if it does u should be able to do it from the controller
player controllers exists on both server and client
u call a server function that then calls the multicast function in the server
basicly ur telling the server controller to run a multicast
thats what im doing currently but obviously I need to get the player controller reference to access the function, and all I can find is GetPlayerController[0] which seems to work on one client but not the other
Where are you trying to do this from?
the dedicated server
i think u can pass the actor reference on the server function
@granite joltAll the clients need to know is their state or the games state, whether it's waiting or not
Put bIsWaiting on Gamestate with a repnotify
If it's the state of the game
if it's a player state then guess where to put it.
Who's doing the waiting, everybody/entire game or just a particular player?
that should work too, never used on rep notifies tho
RepNotify is the shit
do the notify only gets called when when the value changes?
Ye
When a player joins, I spawn a WaitingWidget that tells them they are waiting for more players. When all players have join and bIsReadyToStart is true, I multicast a function to remove that widget and start a timer widget on all clients
Nah, you have a state of some sort (I think it's already baked in)
Repnotify State
if state = waiting, show one widget
if state = countdown, show the other
if state = playing, show the other.
Now it'll just work, and a late joining player won't miss the Multicast
is there any adavantage to using notifies vs a regular replicated var?
do they work diferently at all?
It's a replicated var that fires a function when it changes
so bandwith wise they are the same?
yes, but bandwidth is also absolutely nothing unless you're changing a property literally all the time
i tought they were diferent
If you were changing from waiting to countdown like 30x a second then maybe think about it but even then it's nothing. Think of how much bandwidth movement is.
i need to read the compendium again, kinda rusty
When in doubt, repnotify.
For a binary door:
Don't multicast OpenDoor
instead...
repnotify on bDoorIsOpen
that way, when someone joins later, they see the door open
or if they come in range from outside of relevency range
If you were to multicast instead, a player might see the door shut on their screen but it's open on server or vice versa
RepNotify = for state changes
Multicase = for one-off events.
@dark edge I setup the repnotify but im getting the same issue. Its only executing the function on one playercontroller. I checked for local controlled and it was false so I'm probably just accessing it wrong.
There are separate instances of player controllers for each client and they are only accessible on each individual client and the server, so one client is not able to access another client's player controller as it doesn't exist on their end. When you set a variable on the server for one of them, it'll only be setting on one specific instance of the player controller and only that one player controller would receive the repnotify.
You likely want to use something on the gamestate or on the playerstates to keep track of who is ready.
yeah I looped the PlayerState array and got the controllers from there and it worked. But Im not sure a repnotify is the best place to have a loop like that
What's doing the waiting, the game or a player?
WHy are you putting these state variables on a playercontroller?
im not
basically the server is waiting for the game state to move from WaitingToStart to InProgress, then removes all the player controller based widgets that say "waiting for x players" and starting a countdown for the race to start
Widgets are clientside only. The local clients should be swapping them out based on the state variable. The server should do nothing but change some state variable.
thats what im doing
Is there a way to visually see what blueprints/code will be include or excluded for a client/server build
@chrome bay James, where does the UHT_WorldEventManager inherit from? I'm looking to implement it myself
I want to make sure my "server" blueprints for authentication logic are not within the client build
I am stumped, I have a collection system I made. However I am having problems with the client to the server replication. The Player controller detects the interaction key being pressed. and sends it to a custom event that runs on the server. Which connects up to cast to the object as replicating to server. Then inside of the object, it casts to the gamestate to subtract from a number for the UI and game info. Then visually it hides the object, then after 2 seconds, it removes it from the server, then that calls to removing multi
Casting is not "talking" or "communication"
Exactly what mechanic are you trying to implement? The player collects the collectible...when?
Player collects collectable when pressing E in the collision box. Then it displays on a widget and the variable is subtracted from gamestate. Once it reaches 0 the game is won
The whole system works fine in the server. But clients only work on their end
OK I'd do it like this.
Player presses E -> Run on server event.
The RunOnServer event detects if a collectible can be picked up. I'd just do a box/sphere trace for objects but you can do it however.
If picked up, update a value on Gamestate
widget just hooks into GameState.
Why not send an RPC back to the client for immediate update and confirmation that they did it?
A variable updating on the gamestate could be due to any other players?
Or some other random occurrence.
Interact code inside of player or the collectable
Hey, so I have a pickup system where players can pick up and hold items and then drop them somewhere else. It works perfectly, however it acts strangely when the object has physics simulation on. I would only need physics on when the item is not being held. Where and when am I supposed to disable and enable the physics sim? Or am I doing it wrong?
Disabling physics sim when the object is picked up works, but when I try to turn it back on again the other player can't see them carrying it until they drop it again.
Uhhh I think I got it to work. Nevermind lmao
The object jitters a little bit though when it's dropped Edit: Nevermind... Fixed that too kekw
alright, can someone have an idea how to solve root motion jittering issue on clients with even slightest bit of ping(20ms>)?
Can I somehow turn off character movement position correction temporarily?
the player on the left is server, the player on the right is client with 50ms of ping
server doesn't jitter the location, the client does shake really bad
(for reference, he doesn't shake when the lag simulation is turned off)
if they represent some state replicate through variable if not rpc with array of floats is fine
Depends on what You want.
Will all those float values be used every RPC? Or only a few of them?
If yes, then I would pass them as an array or a struct (Both are good if you're considering adding new floats in the future, structs are better if You have difficulties with knowing which array element goes where, Arrays are lighter).
(And As Thompson Said, if they represent only some kind of state, replicate them through variables)
Hmmm, kinda reasonable, a pretty good practice even, I think
then yeah, struct would be fine, array as well
structs would be easier for you to read, arrays are lighter afaik though
no problemo m8, good luck!
how susceptible is ue4's multiplayer to cheats?
an incredibly vague question
the same as every other well written netcode- depends how You implement stuff on it
hm
well as far as im aware i have little to no impact on the server itself, i can just build it and make variables/functions/classes(?) replicate
you can send RPCs, so you can do stuff on the server
So You can implement stuff the way every important thing is checked on the server and then the result is replicated, or you can check stuff on clients and then send RPCs with the result praying no one cheats the result locally
And you can do stuff the way everything is checked both on client and server, but is it worth it? Depends on use case
Simplest example:
You want to tell everyone your nickname
Cheatable way: You ask the server(by an RPC) to tell everyone that Your name is X (this doesn't have to be true) and the server tells everyone your name is X
Non-cheatable way: You ask the server only to tell your name. Server then checks your name and it turns out your name is Y. He then tells everyone your name is Y
I mean, the non-cheatable way is still cheatable if the server wants to cheat as well. Then you can do more validation between client and server
if i just have a Replicated Uproperty can it easily be manipulated client side?
uproperties usually replicate from the server to a client(unless specified otherwise)
if You change a replicated uproperty on a client somehow, then it won't be visible on the server anyway, and on other clients as well
(If done not by the game itself, it would probably even disconnect the session, but i'm not sure about that)
there are few places where the uproperties replicate from clients as well and those are player state objects I think, but you need to read on that more if You need more knowledge about it
Can you provide me with material
Please advise, best way to transfer data between LocalLevel(main menu) and MainLevel(Server)
SeamlessTravelTo
https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/Networking/
And about this specific topic:
https://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf
and by reading that again, I might be wrong on the client replication part of Player states, but yeah, it's a simple topic with many nuances
In blueprint, if I have a repnotify variable, is it possible to get the old value?
Uh, UPROPERTIES never replicate from client to server
Only way to do so would be via a Server RPC
Not sure but try adding an input to the rep notify function
The type should be the type of the property you're replicating
That's how you do it in C++, so it might also work in Blueprints
Thanks I'll give it a go
blueprint can't do it, it doesn't even really have an OnRep
its a property changed, not a replication callback
so if you need an OldValue, you'll need to cache it at the end of OnRep function
@plucky prawn
sup. im trying to do a multicast with an FName but i'm consistently getting Illegal name (length > NAME_SIZE). can anyone point me in the right direction? it's driving me mad
hi, is it possible to change server default map by launch parameter?
"game.exe -map=Map_Room2" something like that
It's telling you length of your FName is bigger than the maximum allowed length which is NAME_SIZE
Yes, see examples: https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/CommandLineArguments/
I was reading through the resource "UE4 Network Compendium by Cedric eXi Neukirchen" (very insightful) but I was left a bit curious about the relationship of replication and inheritance. PlayerState, for instance, is modified by the server and replicated to everyone. But does this impact the DEFAULT REPLICATION behavior of a variable I add to the class? Lets say I add "PlayerColor" to the player state, and set it from the server. I do not modify the variables replication, aka its set as "None" (the default). Is it replicated (because PlayerState is inherently replicated)? And similarly, if a I take something that is not replicated (lets say UMG, which exists soley on the client) and I set a variable to replicate, whats its behavior?
lol
yes, this is obvious
but im passing a name
basically im trying to attach a component to a socket
so i'm passing a socket name
but the component isn't attaching. when i stop the breakpoint, it's telling me that the FName is invalid. it's odd, because there's two calls that are happening and in one of them FName is correct
anyhow, i'll figure it out eventually
Attaching is server only
You shouldn't be multicasting it either
cool yea i realized that by googling. so i made the function server only
i think my fname is not getting serialized correctly, so im gonna try passing an fstring now
im gonna lose it. i dont understand why this child actor is not attaching on the autonomous proxies
It shouldn't be
If you don't have the Replicated flag on your properties then you'll end up having two different instances of that property on server and client if your class exists on both. For example PlayerState exists on both server and client, so setting the value on the server won't sync to clients(vice-versa is always true). For UMG classes, they exist only on client, so having the Replicated flag won't make any difference. The property will be ONLY on client.
Ok, so to make sure I understand what you just said. The default, no matter what, is if not explicitly made to be so, variables are not replicated. Replication is then further RESTRICTED by the parents replication properties. Sound about right?
my sword is on the floor now so i'm now making negative progress lmao
Correct, default is NotReplicated
what about RPC, is this bounded under a similar thing? If I were to put, say, A server only replicated RPC call on a UMG blueprint (oh the horror) how would such behave?
For the RPC to be processed, the actor must replicate
this won't work, in the constructor there is no owner etc yet. you should put initalization code into either begin play or InitializeComponent (you need to set bWantsInitializeComponent or smth like this to true in the constructor)
UMG don't, so the RPC would be dropped probably
ok! let me try this
i'm getting No object initializer found during construction
ohhhh wait
i see what i'm doing wrong
alright... so i've done this:
you btw can post code with
```cpp
my code
```
so you don't need to send images all the time.
sure
void UGearComponent::InitializeArmor()
{
const auto Owner = GetOwner();
if (const ACharacter* Character = Cast<ACharacter>(Owner))
{
const auto MeshComponent = Character->GetMesh();
Helm->SetupAttachment(MeshComponent);
Chest->SetupAttachment(MeshComponent);
Legs->SetupAttachment(MeshComponent);
Arms->SetupAttachment(MeshComponent);
Shoulders->SetupAttachment(MeshComponent);
Belt->SetupAttachment(MeshComponent);
}
}
but now i'm getting this crash
if (ensureMsgf(AttachParent == nullptr || !AttachParent->AttachChildren.Contains(this), TEXT("SetupAttachment cannot be used once a component has already had AttachTo used to connect it to a parent.")))
{
hm possible you need to call this in the constructor, I think there was another function for runtime
lol
(note not call the GetOwner stuff, just the SetupAtachment
ah
wait
you don't know the mesh yet xD
why don't you create the mesh on the character it self?
lol
ok, so everything was working fine before. the only issue i was having was replication to autonomous proxies
i'm going back to the commit where i had this working, one moment
i'm pretty sure i found the bug
LogClass: Warning: Property GearComponent::MainHandWeaponItem (SourceClass: GearComponent) was not registered in GetLifetimeReplicatedProps. This property will not be replicated. Use DISABLE_REPLICATED_PROPERTY if not replicating was intentional.
LogClass: Warning: Property GearComponent::OffHandWeaponItem (SourceClass: GearComponent) was not registered in GetLifetimeReplicatedProps. This property will not be replicated. Use DISABLE_REPLICATED_PROPERTY if not replicating was intentional.
this would explain why the socket function was returning NAME_None
going to add it to GetLifetimeReplicatedProps and we should be gtg
out of curiosity, do you need morph targets on you mesh?
If I call an event set to "reliably replicated on server" from a client (eg bound to a UMG form, calling an event of such on its playerstate), will it run on both the client and the server (original + replicated) or just the server?
if not, I might would look into MehMerging as it has a less render thread cost with modular characters and you basically are not limited to a specifc number of meshes
out of curiosity, do you need morph targets on you mesh?
not sure what that is, and i'm not sure what MeshMerging is
hmm at least a server RPC is only executed on the server^^)
MeshMerging: combining multiple skeletalmeshes into a single mesh at runtime
By server RPC you mean Replicated set to "Run on Server" correct?
I mean a remote procedure call setup in code, so a function called form a client for example and executed on the server
gotcha, yea ill look into that once i figure out why this code isn't working
Yes that's what it is in BP
ok cool so everything is attaching fine again, still having the same issue. ultimately the issue is that the server AttachToComponent just doesn't seem to be working. it only works when i call it on the client. if i remove the client call and only call the server, it doesn't work. i'm replicating the child actor, but i'm unsure if that even matters
void UGearComponent::AttachWeaponToSocket(const UWeaponItem* WeaponAsset, UChildActorComponent* WeaponComponent,
const FName Socket)
{
if (const auto Character = GetOwner<APlayerUnit>(); Character && WeaponAsset && WeaponComponent)
{
ServerAttachWeaponToSocket(WeaponComponent, Socket);
}
}
void UGearComponent::ServerAttachWeaponToSocket_Implementation(UChildActorComponent* WeaponComponent,
const FName Socket)
{
if (const auto Character = GetOwner<APlayerUnit>())
{
WeaponComponent->AttachToComponent(
Character->GetMesh(),
FAttachmentTransformRules::KeepRelativeTransform,
Socket
);
}
}
UFUNCTION(Server, Reliable)
void ServerAttachWeaponToSocket(UChildActorComponent* WeaponComponent, const FName Socket);
technically this should work
i can also confirm that ServerAttachWeaponToSocket is getting called
just for readability, don't use auto or at least auto*
Where is a child actor in your code?
also I can't see the client call
Have anyone tried to implement kill cam kind of a thing using DemoNetDriver? My player being disconnected from GameServer although I use in memory streamer to record and play the replay. Is there any more setup I should be doing to keep the players connected to GameServer while the replay is playing?
the child actor is being made in the component
it's made when the component is constructed
so what exactly is not working. from the code it seems you just change the parent in the hierarchy, but you don't update the position
void UGearComponent::AttachWeaponToSocket(const UWeaponItem* WeaponAsset, UChildActorComponent* WeaponComponent,
const FName Socket)
{
if (const auto Character = GetOwner<APlayerUnit>())
{
WeaponComponent->AttachToComponent(
Character->GetMesh(),
FAttachmentTransformRules::KeepRelativeTransform,
Socket
);
}
}
client-side code. works fine. no issues. obviously, no replication. only works on controlled pawns in each client.
void UGearComponent::AttachWeaponToSocket(const UWeaponItem* WeaponAsset, UChildActorComponent* WeaponComponent,
const FName Socket)
{
if (const auto Character = GetOwner<APlayerUnit>(); Character && WeaponAsset && WeaponComponent)
{
ServerAttachWeaponToSocket(WeaponComponent, Socket);
}
}
void UGearComponent::ServerAttachWeaponToSocket_Implementation(UChildActorComponent* WeaponComponent,
const FName Socket)
{
if (const auto Character = GetOwner<APlayerUnit>())
{
WeaponComponent->AttachToComponent(
Character->GetMesh(),
FAttachmentTransformRules::KeepRelativeTransform,
Socket
);
}
}
server side equivalent. doesn't work. neither the controlled pawns or their proxies are working.
the ServerAttachWeaponToSocket function is getting called
and all of the arguments are correct
well you remove the calls on the client. I don't think attechment is replicated, you need to send an multicast to the clients to apply the change
I don't think attechment is replicated, you need to send an multicast to the clients to apply the change
this contradicts @fathom aspen , but i'm literally about to do a multicast and call it a day
this is driving me up the wall. there is a thread online that says that technically you don't have to do a multicast and just attaching on the server will do
\o/ I just remember there were issues with actor attachment and multiplayer, but no idea. I use just mesh components and set meshs as I need for weapons
and I also do this on the clients based on equipment data I replicate, as the server doesn't need this information at all
š„³
you might need to check what happens if a client discoveres the actor later, if then the attachment is working correct or if you need to send it with the initial bunch
we will cross that road when we get there, but ty for your help
That's correct. That's why I don't use Child Actor Components, they can be nasty
Attaching regular actors or components this shouldn't be an issue
i need to create the weapon actor whenever a player equips it
how else would i do it if not a child actor?
I am curious about the case of gracefully handling host disconnect where it would be preferable to make another peer a host as well as allowing saving/loading online play. Judging from the way the API is laid out I assume this feature is not baked in. I am thinking about doing something like creating a pawn for the host, which acts as the "true" gamemode, a sort of game-mode-proxy, keeping track of peers in it and replicating, combined with a deterministic "choose next host" feature, and then having the new host take automatic posession of the actor. Does this sound like it would work, conceptually speaking, or is there blockers I am not aware of or a better way of accomplishing this?
Nah, there are fundamental changes needed for this to work - without engine changes you need all players to do a hard travel with loading screen and full reset of the level
?
Just spawn an actor and attach
Are you using ChildActorComponent?
That would not be problematic necessarily, this is not a realtime game (its a board game). I am fine with kicking them to a trans screen which says host was kicked.
im much more concerned about a network blip causing a 2 hour board game to be destroyed and not recoverable
That part isn't hard really, just store the game state on clients in game instance or something
thats not replicated though, nor is game mode (for different reasons) thats why I was talking about using some sort of replicated pawn acting as a proxy so all clients have a full non-authorative copy of the state of the game.
The GameState exists for this
But the game state will be destroyed by clients when the host dies
So each client should then copy the data to their game instance
(or any other persistent-across-levels object)
ah got it, I was confusing gamestate with gameinstance
You need to use both
thats true, I could probably get away with an autosave list. the only issue with it is it still needs to be able to automatically try to connect to a previous peer it determines would be the next host, as that sort of connection information is not really something you want to persist for a number of reasons.
The auto connect part is probably not a great idea for a number of reasons - just let players arrange a rematch
That's way more complicated than the actual game-side logic needed to resume
Fair enough
Literally what Adriel told you. Spawn the actor and attach it
Yes
Yeah, i corrected myself later
Optimization purposes
Yes, so it's more performant to have the distance squared rather than a raw distance value?
Yes, so they don't have to do sqrt operation and then compare to not squared distance
Yea, but my question why the length is determined by a squared value
To calculate vector distance you do sqrt (a^2+b^2) they omit the sqrt operation and compare to squared distance instead
Oh, yea.. I forgot about that 
I'm dumb
Thanks! š
I am building a lobby with a player select screen. you know, one of those old fashioned ones where the players have a grid and each pick a different avatar. part of this means I would like players to see in realtime what other players are selecting. Obviously the UMG for lobby is unique per client, so ,y thoughts on making this work is to have a pawn per player which proxy-drives the UMG. Would this be the correct - or a correct - approach to this? Or is there something better.
I am having extreme difficulty testing and diagnosing causes of lag, because I am testing hosted local on my home computer and large part of the lag seems to be coming from the fact I have multiple windows open.
That's fairly normal and you can only do such testing with two computers
well you just need to replicate the players current choice and then read this in your UI. If the players already are connected to your server, you can just put this in the player states for example.
because they screwed up when coding that in
should had been NetCullDistance with NetCullDistanceSquared being set when NetCullDistance is changed
That would be amazing
reading a 9 digit number in that tiny box is always annoying
When is the pawn actually assigned? I have PostLogin, and I can set the default pawns in the game mode, but I don't see an event I can't find a hook for this. I would like to set some variables before spawning the class (or right after), based on the "slot number" they were assigned at login.
override HandleStartingNewPlayer
don't call Super
(Parent if BP)
and spawn your Pawn by hand, setting whatever you need along the way
does OnComponentBeginOverlap not get called on the server?
like i can see OnComponentBeginOverlap getting created on both the client and the server but then the server doesn't collide
My Level instances don't replicate in UE5. Is this as intended, an engine bug or I am doing something wrong?
Is it wise to have an actor owned by another actor that's the playerstate?
totally fine
yeah,implementing what you asked me to yesterday, just wanted to clarify
I have a gamestate which is meant to spawn my actor in BeginPlay but it's not getting spawned. My GameMode is set to use that gamestate, and my world is set to use that gamemode.
Do i have to explicitly spawn GameState in GameMode?
Or is it a bad idea to spawn an actor from gamestate?
Hello! I'm trying to fire an anim montage on death. If the client dies, the anim montage node fires on both client and server at the same time, but there's a delay before the animation actually plays on the server.
In the video you can see when server character dies, both play fine. When client character dies, server animation is delayed even though the node is fired right away.
Should things like 'add controller yaw input' be done on the server? I thought character movement component handled it all
question. any idea why this is not appearing on the client? im spawning a static mesh and attaching it to a scene component on my actor. the actor and the component are set to replicate, the server sees it spawn and it just does not appear on the client. works fine for the server