#multiplayer
1 messages Β· Page 9 of 1
By default for me even if I just rebuilt the engine, if I make a new shipping build it will rebuild the entire thing
12000+ files
Which is why the installed build was a great workaround for me as I never touch source anyway, just need it for consoles
Hi for a dedicated server do you pay for time or instances, like fast matches like clash royale is on average 2 minutes and fortnite on average 20 minutes
Fortnite pays more for dedicated server?
You pay for both? Sort of?
Depends on the type of server you need.
If you pay for a static server then you'll pay for the time it's running, even if there are no active instances
If you spin up dynamic servers depending on need, then you'll pay for the time that it's up and multiply that by the base cost of the processing requirements
So fortnite will pay a lot more because it needs more processing power
I need to get a player transform when a client quits game but the pawn is already invalid at logout, any ideas when could I grab it?
Can you get the transform when they press the quit button?
what if they alt+f4?
Maybe thereβs an event logout similar to event login?
Or what if you get the pawn transform periodically as a backup for the alt+f4 / power outage scenario and use quit button as default trigger?
If you're using C++ you can override this method: https://docs.unrealengine.com/4.27/en-US/API/Runtime/Engine/GameFramework/APlayerController/PawnLeavingGame/
Clean up when a Pawn's player is leaving a game. Base implementation destroys the pawn.
Both the player controller and pawn/character are still valid upon being called π
in a Dota-style game what would be a local role of a hero? SimulatedProxy?
Your hero or someone elses hero?
my
your hero is autonomous proxy. Other ppls is simulated proxy
but he is not possesed by player controller
Why not?
PC posseses actor-camera
well that's your problem lol
how so?
The typical unreal setup is the player pawn being the "thing" they control
if you want to step outside that paradigm then you're off on your own
It's doable for sure
but you'll have to manually handle some stuff for local control
well typical unreal setup is FPS
I mean if you set as the owner of your pawn your pc it can still be auth proxy i think.
I would do a moba with the pawn being the character. You can do a totally seperate camera without camera being a pawn.
I'm doing a moba with the pawn being the character as you say and the camera is in the pawn
so Owner affects role too?
and how would you do the Meepo aor ArcWaren type hero?
Depends. It'd mostly depend on if you need prediction or not I'd say.
IDK if Dota even does prediction
I know lol does but dota is a bit slower
Hey guys. So I understand roles at a pretty good level now. But I feel like thereβs still a gap in my knowledge about ROLE_AutonomousProxy. I know that the role of the playercontroller on the owning client is ROLE_AutonomousProxy, but i also heard that the character class that is possessed is ROLE_AutonomousProxy. Does that mean that anything th...
nice, thank you
Possessing a Pawn/Character has absolutely nothing to do with First Person
You can put the camera wherever you want
That's what the PlayerCameraManager is for after all
quick question, how do people make multiplayer racing games with UE? afaik, chaos vehicles dont have client prediction yet, so how do people do it? do they just write their own car physics themselves or what?
so they use chaos vehicles, but just set it to always trust client movement? or do they not use chaos vehicles at all?
people who use UE to make multiplayer racing games
Because I don't know of any yet
At least with physics you would have just trusted the client and send the server the transform for replication
+- some testing to ensure no one absurdly cheats
no, I'm just trying to understand, if someone were to start making a multiplayer racing game at the moment, what route would they take, chaos vehicles or not
Check #chaos-physics if you want to know about chaos state. I don't think UE5 gives another option or? You can write your own of course if you want.
Also depends on the racing game
F1 probably needs very specific physics handling. While other games might just wrap a sphere around the car
hmm I see
Pretty sure Jambax said HLL has client auth vehicles. (I know, not racing game, but still)
so I guess for now, you either wait for chaos vehicles to implement client prediction, or just roll your own solution trusting the client
Would probably be a headache
@chrome bay James, are you using chaos vehicles for HLL?
I know they are looking forward to the double support though. I recall James showing a video of the jitter that happens in a scope.
Yeah
yea I heard they (epic) intend to implement client prediction
Their maps are huge. My wife starting playing the game a few days ago
I've been meaning to - just...no one to play with π
at the moment they are already replicated, its just that they have no client prediction
I wonder how people did it before chaos vehicles were a thing, (physics-wise)
for vehicles specifically?
because for characters, the CMC already does client prediction
Well, it's not like it's impossible. Can just be super hard. BlueMan wrote his own vehicle physics system for example.
oh I see
hmm yea I would think so, I mean after all, there must be older multiplayer racing games made with UE
Sorry for ping, did you happen to solve this bychance? By doing the bOnlyAllowAutonomousTickPose = false; step, I get frame perfect animations but the movement is still very choppy. I haven't noticed animations speeding up though, sounds like a dealbreaker if that is the case (also on 4.27)
there is GRIP, I think they had to modify engine
hmm yea makes sense, people with just the right knowledge of physics + networking can probably implement it easily
thanks I've been through those fixes and am at this result where it's smooth animations but very choppy movement updates even at a net update rate of 60
Only when viewing a client from the point of view of a server
Clients viewing clients = fine, clients viewing server = fine
Yeah the anims aren't choppy at all anymore (even with just the bool, I noticed nothing when overriding the CMC change)
It's more the movement updates causing the choppiness now
Feels like about only 10 per second even with a net update rate of 60 and exponential smoothing
Yeah changing to exponential helped again but it's still very noticeably choppy compared to clients viewing other clients but I guess it's just one of those engine bugs we need to live with!
The only fix that does work is p.NetEnableMoveCombining 0 which forces movement updates on tick which does work but is of course horribly expensive for bandwidth
But that does bring things back to be frame perfect again
I don't have RM but I will likely just revert these workaround regardless just in case
May just try and force a much higher net update rate for player controller characters and call it a day
It's a shame, was really banking on Epic getting around to it at some point since it's been an issue for years π
Thanks for the help regardless!
Does anyone know if Fortnite pools characters?
It's been awhile, but I found think I found that doing the bOnlyAllowAutonomousTickPose fix ended up working with the exception that you can't use root motion from animations, so I ended up doing that and reworking a few animations. I don't recall ever getting any choppy movement though.
yeah this is the exact problem I was facing though >_< it's a shame it's still happening.
Thanks for answering! The movement updates may be caused by something else so will look into it
I think they are just spawned once, I dont see a reason for Fortnite to pool their characters. So far I didnt see any sign that they do any kind of pooling (other than engine's particle pooling etc) in the game too
Sounds good. Good luck!
@peak sentinel Yeah I think so too, even single character spawns cause pretty massive spikes for us though
Any chance it causing load huge amount of assets? or possibly niagara particles?
I think Kaos also had this issue
He was mentioning registering components was causing a visible overhead in the game for TRS2
FWIW, if you play Fortnite STW there are always massive lag spiked when a new player joins. Even on fairly beefy computers.
No idea what he did though. But I know he didnt use pool for characters
okay awesome, I'll check with him π
Got an answer from Epic about the development status of NPP! https://forums.unrealengine.com/t/status-of-network-prediction-plugin-looking-for-epic-response/502509/5

Neato. Just need to wait for Fortnite to need it π
Cool, so we can forget about that for now
Guess we stick with CMC and GAS prediction for now

If we're in a scenario where a player is the server, and I have something like this in ticking of my player actor:
Tick() {
if(role is Authority) {
For all players {player -> player.ClientDoSomething() }
}
}
Where ClientDoSomething is UFUNCTION( Client, Reliable ).
Will the call be executed on the player-server-authority actor too?
Question about good practices. Lets say I have data about player (for example how many times character jumped). Where I should actually hold it? In PlayerCharacter? In PlayerState? somewhere else? Keep in mind that in future there will be entire structure with data about player (like I dunno, health, inventory etc etc) instead of that simple integer.
If you're doing something on tick in a player's character as a client and you have 4 characters that are relevant, one would expect that tick to fire 4 times once for each player. The player acting as the server will be ticking ALL player characters, so if your server had 20 players, the server would see that tick 20 times, one for each player character. The player acting as the server would hit the if(role is authority) on all 20 of the characters and proceed with doing your loop 20 times, again, once for each character. So at the end, you'd actually be executing player.ClientDoSomething() 400 times per frame.
Thereby, it's better to not do the loop on the character, and instead just get a reference to the player in control of that character to run your function. This way you'd only be running player.ClientDoSomething() 20 times if you had 20 players in the game.
Hey would anyone be able to go through the setting up of a 5 vs 5 TDM gamemode
I'm struggling with setting up the teams before the round starts especially inviting people to a party and joining a match on the same team as your party
What would the count be used for? eg. Is it used as like a counter for an achievement? To control movement (eg. allowing multiple jumps) and is reset when the player lands? Is it something that needs to persist at all?
just general data that is potentially visible or affecting other players, jump counter is just example for me to learn how to do that
General rules of thumb, if it's data that needs to persist and be "visible" always, PlayerState eg. PlayerName, PlayerScore.
If it's something about a character that doesn't need to persist and doesn't always need to be "visible", Character. eg. Health, EquippedWeapon.
A jump counter is a bit trickier of a value to define where it should go as it really depends on what that count is used for.
If it was being used for an achievement type system, or your game's scoring was based on the number of times the player jumped, then you'd want to keep a continuous count, in which case, the PlayerState would probably be the best place to do it. If it was just for keeping track of how many times the player jumps before hitting the ground, that could be on the character as this value likely gets reset often, however, if again, you wanted all players to be able to always see how many times the player jumped, you'd put it on PlayerState as the data is then always available to clients to view.
thanks!
What Datura said to you, you don't loop over them, the Tick automagically does it for you. Also referring to your question the client RPC will be run on server, yes sounds weird, at least it did for me when I tested it yesterday. I always thought the listen server player had a client side, but seems like it's not, which is kinda strange tbh. But on the other side, it makes sense. That's why that player is called a server, he literally has Role_Authority everywhere, thus, if you try to do a SwitchHasAuthority for it, the Remote pin won't get execution.
You also get HUD on server, i.e widgets on server, input is also handled on server, as they exist at the level of the local controller which exists on server
That's why using SwitchHasAuthority everywhere to spawn such local stuff (HUD, UMG, handle inputs) is bad, especially when your game might support listen server setup. What you should use instead is functions like IsLocalController or IsLocallyControlled
anyone know if it's possible to pass in an options string as a command line arg/launch param? i want to launch my map but be able to change the number of expected players without having to repackage. i can do this when server traveling but unsure if i can do it by just loading the map directly
You can
After MapName you have the ? which marks the start of your options string
I guess that option is already configured. It's called MaxPlayers
but can i figure that with a launch param or something? afaik, the "additional launch parameters" from the editor doesn't allow me to
basically i'd like to be able to package the game and then run it with --expectedPlayers=10 or whatever
That's for running standalone from editor I guess right? I don't use that at all
I launch from cmd
since we often don't have enough people for a full game. currently i have to always rebuild it based on how many testers we have
yeah
Running from editor is so wacky for traveling anyways
it's terrible, i agree. i only just got it working and i highly doubt it'll continue
Well no, it's literally the same as launching from editor though you do it from command line
I'm not sure if they are any different, but you already seem to have issues with them
Already read the issue you was having last night
Editor is shitty for testing traveling
Won't rely on it
yeah I am unfortunately stuck with standalone mode due to constraints from dependencies, but like you said i'm not trying to really test it there anyway. is there a way you pass options strings from a packaged game? when you say via CMD, do you mean you have a script that runs your server or do you actually open the map manually via CMD
No it's not packaged
See example section
I'm still not sure how you do it for a packaged game tbh.
I rarely package π
i have a batch script that starts the server with a bunch of arguments. i think based on this, it should just be one more arg then. admittedly i haven't tested it packaged yet bc i just assumed (probably incorrectly) that's what "additional launch parameters" did. imma test it now
I made a client side pawn for the player to move around with (RTS camera pawn). The server doesn't recognize its movement and therefore doesn't properly manage net dormancy for all the other actors in the world.
How to make a client side pawn update the player's server-side position?
Is this like an actual RTS game? If so, I'd imagine replicated actors would always be relevant unless under fog of war, as you could then see their location if they're not under the fog on like a minimap lets say, or if you have units spread around the map, the relevancy would have to change based on if they are close to any of your units or buildings
No it's more like Rimworld, besides, even in a traditional RTS, there may be actors on the map of various types that are net dormant
Well, if it's just a matter of you wanting to move a server side actor based on the position of your client side pawn, then you could just RPC the location through the playercontroller on tick and then have the server set the server side pawn to that location.
There is a bespoke solution
I just can't remember what it is
Something about the camera manager or something
Say I have 8 players in a Map, and I want 2 of them to go to a new map, how do I get those two players to leave, 1 becomes the host of the new map
Does player A start a new session and open the next level with 'listen'? and then how do i get player B to join with
When do I use the "GameInstance Subsystem", as opposed to just using the "GameInstance"
I don't think there is a GameInstance Subsystem (singular)? There are Game Instance Subsystems, such as the Replay Subsystem.
From my understanding, I can use a GameInstanceSubsystem to create/join sessions, and then access it from my GameInstance?
Anyone know why I could be getting this error:
unresolved external symbol "public: void __cdecl FOnlineSessionSettings::Set<class FName>(class FName,class FName const &,enum EOnlineDataAdvertisementType::Type)" (??$Set@VFName@@@FOnlineSessionSettings@@QEAAXVFName@@AEBV1@W4Type@EOnlineDataAdvertisementType@@@Z) referenced in function "public: void __cdecl USessionSubsystem::HostAndJoinSession(void)" (?HostAndJoinSession@USessionSubsystem@@QEAAXXZ)
USessionSubsystem is a custom subsystem
It seems to do with the enum EOnlineDataAdvertisementType::Type but I believe I have the modules required
You most likely are missing a Module dependency in your Build.cs
I have OnlineSubsystem, OnlineSubsystemNULL, and OnlineSubsystemUtils. I looked into an old project and those seem to be the only online related modules
and CoreOnline
Look at where FOnlineSessionSettings exists, it will tell you what module its in
FOnlineSessionSettings and the enum are both under the OnlineSubsystem module
Hello, is it ok to have a replicated array and the client runs a function that modify the array, if it succeed, ask the server to run the same function, if server failed, ask the client to revert the changes? Will it break the replication of the variable?
A client cannot change a replicated variable
It can changes it on his side, without it being replicated right?
I mean only his local version
No, the server would immediately change it back. immediately = as soon as it detects the change
I have an heavy function that modify an array and need to runs on server, but client have all the necessary informations to check if it can succeed before asking the server to execute it
So from what you said I think it's fine if I execute it first on client and if succeed, ask server to execute it
Does it need to execute for you to check it?
No but it will be a duplicate of the function, with the part that modifies the array removed to return a bool
I mean you can nest the actual heavy stuff into its own function if you want to minimize duplicated code
That's what I was thinking lol
I will probably do that, thanks
Or maybe I could make the client do the heavy stuff, then send the result to the server, and makes the server only validate and set
damn that's unfortunate, it always feels werid using cmc for floating pawn vehicle movement but as network prediction for me is too complex guess it will have to do
Yop, it's also pretty impossible for anyone outside to make a plugin that integrates into everything, cause it needs engine changes
Try using smooth sync, clients can authoritatively move pawns around with smooth sync on
so smooth sync enables client authoritative movement?
yes and it automatically smooths it for other clients too
I think I would probably need to implement some extra steps there since the it's an AIController
I thought it was a player, but if it's AI then the server can run the movement logic
and smoothsync just smooths out the movement for all the clients
I've previously been using this https://docs.unrealengine.com/4.26/en-US/API/Runtime/Engine/GameFramework/UCharacterMovementComponent/bServerAcceptCli-/ for client authorative movement, and it seemed to work ok
If true, and server does not detect client position error, server will copy the client movement location/velocity/etc after simulating the move.
but I'll try smooth sync as well
Hi, how do I set server map & gamemode of a dedicated server while opening the server.exe? What arguments do I need to pass to the server.exe to directly open say LevelToOpen & set gamemode to MyGamemode?
<MapName>?game=MyGameMode
If you don't want a bloated GameInstance, then you opt for a GI subsystem
Nah, PhysX (they're server auth, we just live with the input latency)
If the pawn is client-side, you'll need to update the server with it's location and update the view location so the server knows what is/isn't relevant. Obviously that's also an extremely easy cheat though.
Unreal doesn't have multiplayer vehicles
Unless there was something I missed, but last I checked anyway
All i want to know is had anyone checked if the control rig deformations and detachments of car parts work on client and client
Cause its just skeletal mesh bone displacements
Is it possible to make a classic rts game like aoe/warcraft in ue using server-client networking model?
If I recall correctly starcraft used lockstep, would it even make sense to try implementing something like that to ue?
Pretty sure they don't, the matrix sample is a single player sample
Was never meant for MP
In a word, no
to both?
lockstep requires determinism, which unreal very much isn't
It is however server/client
And absolutely possible to make an RTS, many have done it
Control rig deformations can be replicated though?
I doubt control rig has any native network functionality
But you can obviously replicate the parameters yourself that drive it
Yeah i believe that should do the job
Same way you would treat animation usually
if you're doing it with a face though, chance of visiting the uncanny valley increases
I didn't understand
if you try replicating individual vectors for face deformation
expecially while its emoting or speaking
They won't
you are very likely to end up with an abomination on the client side, one that creeps out anyone who sees it
No im not talking about any faces of characters, im talking about the city sample vehicle deformations
The beamng thing
I still wonder why epic games has not added beam deformation ( plasticity ) physics to the engine?
Because it's fucking hard?
How hard exactly? BeamNG has it since 2013
Last i heard AMD was integrating some FEM physics
Into UE, but that was a while back and was never fully executed
I know its a car sim, but plasticity should work for any mesh. Not saying all the dev team of UE should dive into car sim
"all meshes can deform" is custom game engine territory
How much they can deform has drastic implications on gameplay and tech both
If there could be a feature ( like nanite ) where you tick and select "enable beam/plasticity" and then it would automatically create node points on the vertices of the mesh, and you could clamp the amount of plasticity, strength etc, it would be pretty okay.
You also probably want to consider that Epic is currently busy writing their whole physics engine from the ground up
Means they will add determinism for multiplayer?
no chance
Determinism isn't possible
For determinism?
Hopefully when Chaos is production ready two years from now it will be more multiplayer friendly by allowing easier rollbacks
For determinism to be remotely feasible in UE, you would need the entire engine to process all operations in fixed order - this is fundamentally incompatible with how the engine and it's networking model are designed.
Determinism also means fixed framerate, so good luck with that
So true determinism is never going to happen in UE
yeee
This is why the whole thing about PhysX being non-deterministic is nonsense, it totally is deterministic. If you run at fixed framerate and all the operations are processed in the same order - but the engine surrounding it all is not. Peoples expectations of what Chaos will do for them are terribly over estimated.
Seems like no one can create a football multiplayer game in UE
A football game would normally not use physics at all imho
Like zero
Football games are essentially pure animation work
Incredible stuff btw
What about rocket league?
It's an UE game
It's not a football game, it's a car sim
(also with extremely complex and specific networking and physics rollback etc.)
And AFAIK the ball isn't really physics based
Either a lot of painful complex multiplayer physics work, or custom movement
You can find out:
https://www.youtube.com/watch?v=ueEmiDM94IE
Painful sweaty hours of customizing the the game engine itself?
Completely custom game engine specifically built for that one game for the past 20 years
Same way Bungie works
Thats why they have determinism in physics
If a vehicle explodes and its car parts go everywhere, its mostly on the same area for all players
And again you're looking at a game where crashing vehicles into walls is pretty much the main gameplay feature
So it doesn't matter if 20 engineers worked on it full time for a decade
Which is what I would assume is happening
What I would expect from Unreal down the road is out-of-the-box physics vehicles
Now that Epic actually owns the vehicle code (remember, before it was all NVidia stuff with UObjects on top) they can actually start building a generalist multiplayer model with rollback
Yeah the PhysX parent vehicles
This is sort of a generic question. What's the difference between playing as Client inside the editor. And Running the game on a dedicated server as a Client. I have notices several time something break inside the dedicated server which work fine inside the Editor.
Well, the editor has no latency, no packet loss, and is a simulation of the real-world
Quite often you'll find things working in editor that don't work outside of it because they haven't been tested well enough, or make assumptions etc.
I have some doubt regarding InitialOnly replicated properties. Does they replicate the first time they are set? Suppose I set it after 10 seconds the match begins for the first time, will it replicate?
Ah okay thanks
If a client's PlayerController is the owner of a server-spawned Actor, and then the client locally calls SetActorLocation(..), will the location be updated for everyone? Or would I have to implement a ServerRPC?
Server RPC
I'm letting a player move the actor by click+drag, so I need it to move instantly for the client. So I have to call SetActorLocation locally ("every tick") on the client.
So I guess I will call a ServerRPC separately. However, the ServerRPC would also say SetActorLocation. Wouldn't this feed back to my own client and override whatever I do locally? Like make it jittery with conflicting values?
If so, is there a way to mark the RPC as COND_SkipOwner like replicated values?
Or would my RPC have to store the new location in a Replicated property (with COND_SkipOwner) and implement a ReplicatedUsing= which would call SetActorLocation individually for all clients?
How do you make actors spawned on the server inside a streamed level replicate to the clients?
If I spawn the actors without setting the owner meaning that they spawn in the persistent level then they replicate just fine. But if I set the owner to an actor that is in the streamed level then the spawned actor only spawns on the server.
is there any way to get session data like max players while in session?
How can I prevent a pawn from being destroyed on server when their "possessor" client disconnect?
I think you can override the reset function from aplayer controller and remove the pawnpendingdestroy(getpawn()) line.
In my design, I have 8 player hubs where 2 people can go into 'instances'...I'm stumped on how to let those two players leave and create their own session fluidly. Is there a concept of 'party' in UE networking?
Your previous message got the gist of it. Assuming listen servers, one player creates session and travels to a new game, and then the other waits for that session to be up before joining it
Okay that helps, I feel like I'm thinking it's more complicated than it is, I'll keep trying stuff π thx
What is the best way to log in CPP whether you are on a client or server and then which client? Essentially Iβm running into problems with RPCs and I want to know if Iβm calling them correctly.
Oki, thanks. Wife has a lot of fun playing it. I might pick it up when I find the time. Good work
Hey i'm trying to create a TTT gamemode, where should I be storing the role of the player (traitor, innocent etc) like which variable should i use?
PlayerState or Pawn, depending
I meant the variable I should use, sorry
Make a variable. I'd use an enum but a bool can work if it's only 2 states
ok
got it!
I've got a system for determining which player is the traitor, how can i reference all players in the lobby who are not traitors?
I have a quick question if its okay to ask here: What objects are not send to all clients?
Game Mode/Game Instance aren't shared at all. Player Controllers are only sent to owning clients. Everything else is, depending on relevancy.
thank you
You've got a GameState.PlayerArray that contains all PlayerStates. You can use to access your pawns. Also I find the PlayerState to be a better place for such property
NetMode is quite good
Or check the Roles
how would i use it?
You traverse it
You know how to traverse arrays?
For Each node is a good candidate
You are casting a player state to a pawn
Those are different types
You GetPawn on the array element and then cast it
Or you put that property on the PlayerState itself instead
Get pawn from array? I don' think i can
You can it's public
Oh no
I have another question... Where can i find info about replication priorities, in what order is object(& its data) replicated etc.
You can ask here for any vague points you find there
UNetDriver::ServerReplicateActors
Have fun
There's a shit ton of code there but read it by pieces
Wizard can I stream you my code a second
I'm not sure why but the intro doesnt work for innocents only for traitors
It randomly chooses what role you are
I prefer sticking to this channel, so others get to learn
BeginPlay fires on both server and client. You are creating UMG there which should be done only locally
You are also using GetPlayerCharacter(index) which is if not used properly can cause you an infinite amounts of headaches
So I should do something like a custom event at the enum?
I'm not sure what you're trying to do
theres an intro screen with what your role is (innocent traitor etc) for each player
It just tells u what u have to do
So that widget shows them what their role their is? And where do they pick what role are they?
Or that is done automatically?
its done automatically
with the code above
so it basically sets all players to innocent then chooses a random player to be traitor
Repnotify my dude
If you want things to recalc when that enum changes (when the guy gets set to traitor)
Right now, if you print the role in tick, is it correct?
So here's the thing. You get a random index from PlayerArray and set the property of that PlayerState to be traitor. You can do this in GameState BeginPlay (On Authority)
Then you save that index somewhere or simply traverse the array checking that you are not that index or that the property isn't to traitor (Traitor shouldn't be the first element in your enum in case it was defaulted to it)
Then you set all the other players the other role everyone should have
I would have PlayerState hold the role, not Gamestate holding an index specifying which player is that role.
PlayerState clearly has the Role
GameState doesn't hold stuff about specific players. I just save that index so it so we can tell who's the traitor
If you say let's set those who are not traitors in the BeginPlay of PlayerState (server side ofc) you have race conditions
You're going to have race conditions anyway because what if somebody leaves. Then all the indices are offset
Correct, that's why checking the property for the PlayerState is a better option
You need to have some time AFTER begin play where you choose the traitor
Unless you already chose it in some pre begin play phase like a lobby or something
There's all sorts of complications with joining etc.
Match start is probably what you want if using GameMode and not GameModeBase
Yeah it's the timing issue which is the issue here. There's a spectrum of solutions honestly, but they all revolve around making sure the traitor property is already set when you check for the other players
Oh yeah the MatchState can come in handy
this doesnt work either?
Should I be putting the player role variable there?
Is it finding out which role the player has or doing something else because it seems to just not work
you are trying to create a widget on the server which wont work.
is there some event that is fired on the server for every players begin play?
Beginplay is called for everyone that spawns the actor. the server spawns characters, which replicate to clients so the server calls beginplay, then when the character spawn is replicated to the clients they also call begin play
so in theory i need to hook in every playercontroller? thought there are some global events like compared with PostLoginEvent...
im confused what you mean by hook in every player controller. And whats a global event? OnPostLogin , along with all other gamemode events, are server only
FGameModeEvents::GameModePostLoginEvent
FGameModeEvents::GameModeLogoutEvent
these are game mode events for example that are exposed that way so plugins and stuff can easily register to them in c++.
wondered of there is more stuff exposed like this
i need to have the events on authority only
like: if some client is ready. do stuff on the server
playing around with subsystems... maybe rises the stakes^^
its on the player with the screenshot above but it still doesnt work
i see now. Yhea best way i can think of is to bind every player controller from their AcknowlegePossession.
When you have an event that says "Executes On Server" what that means is you're asking the server to process that event. If this event is contained in your character, it would only execute for that one particular character, not all the player's characters. If this was also a dedicated server, then nothing would happen as you cannot create widgets on dedicated servers. So at best, if this was a listen server, the host would be creating a widget for any client that calls the "Game Start" event.
Hey guys. I've encountered a problem where on client the PlayerCharacter moves with jitter. I made sure to have the skeletalmesh's component replication unchecked. I think that the reason because of this is because the input from client side reaches kinda late to server, or that the interval to send the input is actually low. How could I check this?
Btw, Replication Movement is checked by default, and that's what I'm currently using.
When doing client authorative movement, is there a way to increase the number of updates sent per second beyond changing the Min and Max NetUpdateRate of the character to 60.0f?
It seems to only send at a rate of about 5-10 by default (when viewed from the perspective of the server)
It seems the packets sent per second is 30 from the client even though the NetUpdateFrequency is 60.0f, is there a way to force it to send 60?
My MaxNetTickRate=60 in DefaultEngine.ini, not sure if more steps are needed
@sinful tree Is there a way I can recolour the character through blueprints?
Quick question... does anyone know if setting the location of a skeletal mesh is broken/bugged in multiplayer? I have a chair which you can sit in and spin around, but I need to move the skeletal mesh forward from the pivot point, so when I rotate the actor the player's mesh remains sat in the correct position.
It works fine for host and client relative to themselves, but they both see the other's skeletal mesh in its default transform. Even weirder still, if I do a get location on the skeletal mesh both the client and server report the same vector. So they both think the mesh is in the same place, but visually they differ.
It's driving me mad. I've tried using RepNotify, I've tried using RPC's, but it's always the same result.
This is on 5.0.3, for reference.
is there a reason why you would move the skeletal mesh rather than having a chair "actor" and moving that instead? And why would a chair need a skeletal mesh, save for maybe if it's a chair that would need to animate?
The chair is clearly a gamer chair with wheels and a flexible spine
I was thinking recliner π
Sorry let me clarify, the chair is a normal static mesh that simply rotates on its origin. I am placing the player character at the same location so that the character rotates with the chair. But, because of the nature of how you sit in chairs, you are not sat directly over the pivot point, so the skeletal mesh for the player needs to be moved forward.
Host/Client both see themselves sat normally:
But to each other they see this:
Basically host and client are both reporting that the mesh is at the correct world location if I do a get location, but in reality the opposing player sees the sitting player at the default transform
I think you should make your character a parent of the chair and push it back and it should replicate fine
I also considered rotating the player character around an axis instead of moving it to the chair transform, but that felt hacky π
I guess my original solution is kinda hacky too
any suggestions for stopping speedhackers using cheat engine?
Make your game networked with a dedicated server
And don't use client authoritative movement.
And that
If your game is p2p then you cant really prevent it you can only add code to make it more of a hassle for them like code that frequently checks other code to see if its all the right values and encrypting values so its harder for cheat engine to narrow down variables
it's dedicated, but doesn't it need to be client authoritative to be smooth?
You can use client prediction for that
Instead of the client dictating how its moving it will just "predict" that the server will let it do something and then allows the server to correct it if it goes wrong
ok but how would this look programming wise? i'm using blueprints
Use the character movement component. It has predictive walking/jumping movement built in.
yeah I know but how do I make it authoritative
It's built in to be server authoritative.
There's a setting on the CMC that enables client authoritative movement. By default its off.
this 1?
Namely these two... If these are set true on the server, the client has control of their position.
Otherwise, on the client you just use the "Add Movement Input" nodes to have the player move around.
wait i'm confused, if it's set to true the client has control?
Yep
i thought it would make it so they don't have it
it's set to false already tho, does that mean it should stop speedhacks?
How are you performing movement inputs?
using axis events on player controller, have it call event that is on a character class that does add movement input
You can always try by launching a dedicated server then trying to change your walk speed when playing as a client PIE
Ok, and do you have a decent maximum movement speed set on the CMC? If you have a very high max speed but use a slower speed for regular movement, then players could potentially move faster than expected (up to the max speed)
You change the max speed dynamically on the server (not by letting the client pass through the max speed value in an RPC?)
i do it on the client and server, so there isn't desync
Ok, but you still don't call an RPC with the client being able to tell the server what to set the max speed to, correct?
it's not a variable but it is called from the client
1 sec let me make sure
when the player hits the sprint button it sets the max walk speed on client, and then sets it on the server
i don't think that's the issue tho
the issue is that cheatengine just speeds up the tick of the game
so they go faster
But you're not passing the value from the client to the server, right?
And I don't think that's how the CMC allows movement to work. The server processes where the player is, and if it's within an expected spot based on previous moves, then it allows the movement.
I am passing the value yes
That's the problem.
that's how cheat engine works tho
You're opening an avenue for players to set whatever movement speed they want.
Doesn't matter if you have it on shift in your game. They can call that RPC whenever they want with whatever value.
i'm really not sure if that is the issue, from what I understand the way cheat engine works is it speeds up the tick of the game and therefore movement inputs go faster
The CMC on the server wouldn't allow it.
If you're doing something like this, then that is the problem.
yeah i understand that
from what I understood tho, the issue is that cheat engine speeds up the tick of the game, it's still passing the same value through, i'll give it a try tho
A cheat engine could do that, yes, but the cheat engine can only affect the client side. Even if the client has an increased number of times they're calling the movement input functions which increases the rate at which the server receives the movement inputs, that doesn't change how the CMC on the server would process the move requests. The server saves a list of valid movement inputs and timestamps of when they were received and knows how far a player should be able to move based on the values stored within the server's copy of the CMC and the previous moves.
ok I understand, thanks for the help, I hope it will work
is get local player controller from id only for local coop?
Yes for local mp
Hey guys. Having a crazy existential crisis with ListenServer Joining on Steam with a Shipping package build (Developer Builds work fine). I'm losing hair over this one
Let me give the details:
Hosting is 100% all good. There is no problems there.
When the client joins the game the first time, it's all good!
When a client exits back to the menu, then tries to join the session again, I get the good ol'
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000000
And it is like that all the time until both the host and client kills the game and tries again.
It loads the map, Everything on 'HandleNewPlayer' in GameMode is good. Loads the Pawn and Player controller... but right before Possession can occur... that's when the error happens
We are using the Advances Sessions plug-in and we are on version 4.27.2 .
I'm at a loss what to do here. Is there any 'gotchas' that stand out the reason why this is happening?
Posting the error doesnt help anyone, you need to post WHERE in code the crash is occurring.
@fossil spoke I would if I could :/ . I can't debug a shipping build that way
Fair enough, i skimmed over that part.
@radiant sun is it maybe related to the player getting their PlayerState back?
Not sure where that exactly happens but that's one thing that would be different between first time and any following joining of the same player
@thin stratus π€ ... Hmmmm would make sense. But PlayerState should destroy itself when going to a different map though? I also do notice that the Host session still thinks there's 2 people in the session (yet for some reason I don't trust the Session info when it's retrieved sometimes... it acts weird with amount of players in the session).
Say if it's the PlayerState. Should i possibly empty the values in PlayerState on DestroySession on the client? I know I've had this issue with when coming back from a map after voting in the match, the voting bools are still checked true... We are also using GAS, but this definitely isn't a GAS issue.
DestroySession is usually called locally only so that wouldn't do much. Do both players crash or only the client?
Only the Client π¦
The client's playerstate on the server will be kept as interactive by default for like 300 seconds or so. Not sure if it clears if the server swaps levels.
Since it's only the client it must then also be code that runs only on the client
If you have two clients connected and one goes to menu and reconnects, do both crash?
Good question! We can test this really fast. Will reply on the results.
Crap. Gotta make another package build quick. I made an oopsie π . I will get back to you again when it's up on steam quick
Ok soo @thin stratus ,
-Player makes host
-First client is fine
-Second client sometimes cannot connect getting that crash error
HOWEVER, The client trying to reconnect after there IS three people in the session, it only crashes that particular client
Why is your session member count not updating?
So the crashing client never even connects to the server? OP read like you get it as far as trying to possess
And strange that the second client gets the error
Even on first Connection?
So it must be code that only runs locally on a new client
If it does manage to connect then maybe something UI related?
@thin stratus
So the crashing client never even connects to the server? OP read like you get it as far as trying to possess
Yea it never gets to the view of the pawn. Sows the camera view outside the map. We spawn the Pawn via HandleStartingNewPlayer and possess then.
And strange that the second client gets the error
Even on first Connection?
Weirdly not on first connection to the Host. Only on re-connection to the host :/
If it does manage to connect then maybe something UI related?
It doesn't show the UI on second load when the crash occurs. It couulldd be... I can look further to ensure there's no crap happening there D: .
That error usually gives you quite a good indication, callstack for example
Ooh you said it's shipping build, that's a rough one
Problem is, it's a shipping build
You might need to enable logging on shipping
And maybe place a few UE_LOGs around
To see where it fails, that might also give you a better callstack or even generally a better idea of what is happening.
Yeah or maybe a different build
Pretty sure if DevEditor Build would produce that crash they would have used that :<
We have done Developer Builds and they are totally fine... which is wild O_o . Even took care of ANY sort of Access None warning and errors related to just simply entering a session π¦
Just Shipping builds are the offender π¦ .. and we need it to be shipping build
They are a lot less forgiving indeed...
Well I guess you should just start adding logs as mentioned above, like a lot of them
Pretty much to anything you execute a function on during these steps
I've tried to with the two bools that I've seen
In my Target.cs
bUseLoggingInShipping = true;
bOverrideBuildEnvironment = true;
But it will not let me build it π¦
Why not
Lemme package it with those bools and I'll show ya. It'll take a hot sec π¦
@thin stratus
Looks a lot like your plugins are playing along
Yeeee :/ ... That's with turning on those two bools in the Target.cs
Do you need the BuildEnv boolean?
let me see quick.. I actually havent tried D:
UATHelper: Packaging (Windows (64-bit)): Remove the modified setting, change <MY_MODULE> to use a unique build environment by setting 'BuildEnvironment = TargetBuildEnvironment.Unique;' in the <MY_MODULE>Target constructor, or set bOverrideBuildEnvironment = true to force this setting on.
PackagingResults: Error: <MY_MODULE> modifies the value of bUseLoggingInShipping. This is not allowed, as <MY_MODULE> has build products in common with UE4Game.
UATHelper: Packaging (Windows (64-bit)): Took 0.7990568s to run UnrealBuildTool.exe, ExitCode=6```
@thin stratus
Hm
Try the alternative they suggest
I haven't enabled logging in shipping in a while
UATHelper: Packaging (Windows (64-bit)): ERROR: Targets with a unique build environment cannot be built an installed engine.
PackagingResults: Error: Targets with a unique build environment cannot be built an installed engine.
Ah
hmmm...essentially... possibly building from source?
You probably need a custom engine from source iirc
hmmm... could just get the 4.27.2 from github and try that yea?>
Yeah that's what custom/source engine means
Basically not the Launcher downloaded one
Understood ^_^ !!! well crap π . It will be a hot minute, but I'll get back to ya on the results though π
Hi, I want the player to be able to spectate other players after he dies and also I want him to have all data of the player he is spectating, for eg health, inventory, and some other things that are replicated as OwnerOnly, Isn't there a way that spectator can have those values without setting the variable to ReplicateAll?
Hello! When building a multiplayer game with a dedicated server and all that, does every member of the team need to build the engine from source?
Just the one building the dedi
@bitter oriole do you have any suggestion?
Why are you tagging me
But they can all program functionality for the dedi?
They can't compile the dedi code
You have answered my previous questions so just wanted to tell that any suggestion would also work. Not need to be exact answer
If I don't answer I'm not gonna answer
Don't tag people to demand answers
Understood that, but can they change anything within its code?
So rude but okay
No, sorry, you are being the rude person by tagging random people on the server to notify them of the question you asked just before
Enjoy your block
They can do whatever, just not compile the dedicated code or test it
Not tagging random person. You just messaged here so don't act like you were busy. Anyways as if your block matters to me xD
Alright, understood that, thanks!
dude. the " tag " created to " tag " people, why its a bad thing now
Tagging people out of nowhere for no reason has always been rude
Exactly, some people just want to act cool as if they are very busy person
Also I'm not your "dude"
do i get banned also for saying dude lol
Just blocked
Soon he will have each and every person of this server in his block list xD
Any suggestions are appreciated. Thankyou.
Use proxy actors for those values
Override AActor::IsRelevantFor()
Make it always relevant to the owner of those values and spectating players
Option B: enjoy modifying the engine to add a new replication condition
Option A is the saner one
Or just make those values replicate to everyone
#rules number 2 btw
You act like you pay him to answer you which is not the case. @umbral horizon
Don't get the point of being an asshole here, everyone's here to learn and help each other. Be nice, be kind and enjoy working on games.
is there any known solution for this problem? (during OnRep execution on clients there's no guarantee that elements of ReplicatedSubobjectsArray will be valid)
//.h
UPROPERTY(ReplicatedUsing = OnRep_Foo)
TArray<UFoo*> ReplicatedSubobjectsArray;
//.cpp
//....
void OnRep_Foo()
{
for(auto Foo : ReplicatedSubobjectsArray)
{
Foo->Bar();
}
}
fr bruh

Weird, does the on rep get called again when they're valid?
I keep forgetting this about arrays. Do they replicate once all the elements have replicated? Or they can replicate even if an element has replicated?
I guess if the values are added in the same frame, then they replicate in the same packet?
They can replicate before their elements do
And the elements can be ready later
So like for an array of actors, you can get null values until the actors replicate
Seems to be that way, thanks. So just additional if(AreArrayElementsValid()) check should be enough, right?
I suppose yeah
Yeah that seems fair. Actors that you add to the array in the same frame, replicate in the packet and are ready in the same OnRep, correct?
You mean if an actor spawns and gets added in the same frame?
Yeah exactly
I don't think so
Only guarantee I know of is that the actor's replicated properties will all be there when the actor gets sent to the client(s)
The actor could probably replicate after the array
How about primitive types? Integers for example?
I've seen it happen a few times
I mean POD types aren't references to another replicated UObject
So when they're received, they're ready
Fair enough, thanks for the insights! Will have to play around with this more!
Is there anything besides opening my ports that I need to do to setup a dedicated server on my PC? When I set it up on localhost I can connect with no problem but when I pass my actual IP the client gets a timeout and the server doesn't get any join requests
there's a function called GetLifetimeReplicatedProps that you need to override in C++ to make replication work.
Can it be because it's a Pawn and not a Character?
shouldnt matter
try removing the override on the header file
SetReplicatingMovement(true);
Now the clients movements are on their own. Still the server can control the clients movement but I'll look deeper. One more thing though.
For example on the server I can see all 3 pawns on a location,
In the 1st client the other 2 pawns(server and client 2 are in other location) and the same for client 2.
@peak lintel just so you know, by not using the character you lose absolutely every bit of proper networked movement code
It's highly suggested to use characters for multiplayer unless you wish to rewrite the character movement component.
Thank you! I'll try to use it now and see if it replicates correctly
Maybe try connecting from a different device on your local network first and see if that works? May also be the case that your PC or a firewall or whatever on it blocks incoming connections.
I've made a server on local but still the same. I'm changing now to a character actor, to see if this works
I replied to a different problem π
Hey guys
I have a system setup where each player gets their own name (according to the phonetic alphabet) and role (Innocent, Detective Traitor etc) these are both enums, how could I make it so that when all the innocents are dead the traitors win?
The general pattern for problems like this is to check for the case whenever the data changes
so every time someone dies, check for the win condition
Character dies -> Check if number of alive innocents is < 1 -> Traitors win
Could I do it so that when the round starts it adds up all the players?
Guys, one more question please.
My movement is happening inside the tick function. Tick functions must be somehow replicated? π
I won't stop you
Idk how I would even do that, i guess like add 1 to a gamestate float for each player at the start?
The end results (positions, velocities) should be replicated. Unreal does a lot of that for you already with ReplicateMovement
What are you talking about? Just make a function to check if some team won. Then call it whenever stuff changes enough that some team could have won
It's a dragon. I'm controlling the direction with the mouse
How can i tell when the innocents have died but the traitor is still alive?
You count how many innocents and traitors are alive
you iterate over the characters
Yeah but how lol
Like whats the best way to do it
You presumably have an array of characters somewhere, or just loop over all player states and check their data
That checks their role, you also want to know if they're alive or not
but that's in the right direction
So do the above but with the "is dead?" or something
Start with the data. Make a few function variables like NumberOfAliveTraitors and NumberOfAliveInnocents. Do the counting, then once all the counting is done, you look at those 2 numbers and decide what happens (Traitors win, Innocents win, Nobody wins right now)
I'd say mess it up. Failure is the best teacher. Perfection is the enemy of progress. Keep trying things until it works. That's how learning is done.
What's the best way to set it up as a function
What do you want this function to return or do?
Is the name given at creation the only thing needed to establish a match for a net adressable mesh component?
I am creating it at different times between clients and server
Hey guys what do you think what is the most prefered way to connect to others in a Multiplayer game?
Sockets.
anyone saved this guys videos ? https://www.youtube.com/c/UnrealEngineTutorials/videos
@thin stratus Ayy!! Wanted to get back to you on the Shipping Build issue. Built from source and Yes!! It created logs!! Still a crash though, but actually something to work with to trace this issue. I have a log file if you wish to take a look?
You can post it here and ping me but I might not have time until Monday. Gotta recharge from work a bit over the weekend.
You're all good π !! I wanted to debug the problems with ensuring there's logs whereever possible on my end to pin-point this issue. If not, I'll DM you the output.
Am I right in understanding that any client action that needs to be replicated to other clients have to route to the server via a Sever RCP and then then replicate to clients either via RCP or variable replication?
RPC*** please ππ»
So a followup, seems like unless you were to build some retry behavior yourself, these Server RPCs would also likely need to be reliable and let unreal deal with retries.
I could see the value in a game specific retry since the game knows what has higher priority to retry vs Server Reliable RPC cause UE to very strictly serialize.
Nah you use unreliable rpcs all the time
not all the time but it's fairly often, like sending your aim direction for example
by the time you notice you missed one, it's too late anyway and you have 30 more
Right thats a good point, Reliable is only necessary when the RPC payload is not self contained and is not on some sort of heartbeat/frequency.
Use reliable for something that NEEDS to happen for the gameplay experience to work properly. For example: updating the score whenever someone captures the flag or respawning a player after death should probably be a reliable event.
Reliable pretty much means it will happen, eventually. So even if there's a sudden lag spike and packets are lost it should still run the event in the near future, however an unreliable event will not.
So you might think to yourself why not just make them all reliable events? Well then you run the risk automatically disconnecting the client because they are unable to process the reliable events at the same time and overflow the reliable buffer.
Sorry for the ping, can you please tell if there is any issue with client side phyx vehicles? I am currently implementing it and so far everything seems fine to me. Just in case I might miss something?
[2022.08.20-06.04.41:686][116]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/06_Maps/Multiplayer/HeadQuarters/SL_HQ_Interactive) is flushing async loading
[2022.08.20-06.04.41:697][116]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/06_Maps/Multiplayer/HeadQuarters/SL_HQ_LoadoutCharacterRendering) is flushing async loading
[2022.08.20-06.04.41:787][116]LogWorld: Bringing World /Game/06_Maps/Multiplayer/HeadQuarters/PL_Headquarters.PL_Headquarters up for play (max tick rate 0) at 2022.08.19-23.04.41
[2022.08.20-06.04.41:793][116]LogWorld: Bringing up level for play took: 0.008036
[2022.08.20-06.04.41:794][116]LogLoad: Took 0.999666 seconds to LoadMap(/Game/06_Maps/Multiplayer/HeadQuarters/PL_Headquarters)
[2022.08.20-06.04.42:157][118]LogOnlineVoice: OSS: StopLocalVoiceProcessing(0) returned 0x00000000
[2022.08.20-06.04.42:157][118]LogOnlineVoice: OSS: Stopping networked voice for user: 0
[2022.08.20-06.04.42:158][118]LogViewport: Display: Viewport MouseCaptureMode Changed, CaptureDuringMouseDown -> CapturePermanently
[2022.08.20-06.04.42:163][118]LogSlate: New Slate User Created. User Index 8, Is Virtual User: 1
[2022.08.20-06.04.42:163][118]LogSlate: Slate User Registered. User Index 8, Is Virtual User: 1
Exception thrown at 0x00007FF6F5AAD9FC in Phantom_Hysteria-Win64-Shipping.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
'Phantom_Hysteria-Win64-Shipping.exe' (Win32): Loaded 'C:\Windows\System32\dbgcore.dll'.
[2022.08.20-06.07.56:473][118]LogWindows: Error: === Critical error: ===
[2022.08.20-06.07.56:473][118]LogWindows: Error:
[2022.08.20-06.07.56:473][118]LogWindows: Error: Fatal error!
[2022.08.20-06.07.56:473][118]LogWindows: Error:
[2022.08.20-06.07.56:473][118]LogWindows: Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000000
When the crash occurs on shipping build when joining the session a second time. Is it possible it's VOIP? or is it actually a widget?? Two things I noticed:
- LogOnlineVoice: OSS: StopLocalVoiceProcessing(0) returned 0x00000000
- When a new 'Slate' user is created is right before the crash
Slate User Registered. User Index 8, Is Virtual User: 1```
The widget looks fine to me (registration at least), I'm not sure about VOIP
You do now know that it happens after the capturemode and slate user registration
So it being a widget, could be fairly possible
I don't agree with that score scenario you described. Specifically score is an authoritative state and likely lives on the GameState or PlayerState and it should be replicated to clients via variable replication. RPCs to replicate scores is just a going to complicate join-in-progress. Triggering a respawn via RPC is more reasonable (but I'd still approach that via ActorReplication) - but importantly that is still a Authority -> Client information flow.
I was specifically asking are RPCs the only way to move data Client -> Authority? And appears it is.
WRT to reliability from client -> authority, as @dark edge pointed out, RPCs that are occurring for state that can safely lose prior RPCs' payload can get away with being non-reliable. But something like client pushed this button - I see no other way than to reliably send to the Authority that client is "asking to push this button". Am I missing something?
You are right about the Score. Score is a state and state should be handled via Replicated Variables, and if something needs to happen based on that state it should be an OnRep/RepNotify.
Player input is handled via RPCs. If the input is a single button press, then it should be reliable fwiw. Info send on tick or at least very often should not.
You are also right that clients can only use RPCs to talk to the Server.
And also only on Client owned Actors
All of this can become more complex very quickly when thinking about gameplay elements that already happen on everyone, e.g. a collision. Or when talking about prediction and corrections.
But that's just a side note
yea, exactly. we try to setup as much to locally predicted when it comes to visual/audio perception. Variable replicate as little as possible and use RPCs even less. Just didn't like the behavior I was seeing with UE when client -> authority reliable RPCs serializes a lot of network traffic.
but all we have are RPCs and I dont enough time to build a ACK/Retry mechanism on top of unreliable RPCs that has more game logic context.
Hello everyone, I will be participating in the unreal game jam next week and wanted to know if it's possible to make a mutiplayer p2p game which is hosted on itch.io. Is there a simple way to set this up? I guess there is no stream or epic subsystems but asking for an ip address would lead to complications.
If you mean LAN, then yes unreal can support that out of the box, but WRT network architecture UE is completely Client/Server. You can run UE is a mode called "Listen Server" where one of the clients acts as a server as well as a client.
Yes I meant listen server, how could I connect two person for a online coop game on an itch.io site ? I know how to use the unreal multiplayer (by connecting by ip address) but is there a way to let the players join without doing the direct ip connection?
Is there a way to use some online subsystem on itch.io?
I'm not familiar with itch - but I would guess there has to be a "service" to record and advertise game sessions.
Yes! This is what I'm looking for!
You could look into epic online services to facilitate session advertisement.
AFAIK, EOS does not require hosting the game epic store to use EOS.
but I only have significant exp on Steam, so not sure how well it works.
Oh really? I'm not so familiar with online services yet~~ Thank you I'll look into it
The thing you are looking for is generally called "Sessions" and "session advertisement" .
https://dev.epicgames.com/docs/services/en-US/GameServices/Sessions/index.html
Thank you very much
oooff, looking at the API it is super involved. for a ~48hr game jam, not sure I'd bet on EOS.
I guess to use EOS outside of epic I need my own server for hosting players?
no, EOS just hosts the session record for free
Yes it seems a bit complicated for a gamejam, I'll do next time no worries
Oh very nice
a client would still host the game as a listen server, but the session record is basically list of player ip address, so relatively cheap for epic to host 1000s on a single server.
Yes, this is exactly what I was looking for
I just did not want to make my own hosting server for this
yea this is what Steam Online subsystem and EOS does.
there is a online subsystem channel here, so I'm sure more knowledgeable ppl can direct you for an API/service for game jam purposes.
There is a EOS channel also I'll ask there also thanks!
Multiplayer game for game jam is, um, bold idea. Multiplayer is inherently complex. When it works at all.
maybe if you have previous experience and had working setup from earlier games
Haha yes I know, it's just a challenge no problem. I am not expecting to finish everything I want to do in a week
I have prototypes that work in multiplayer with the direct ip connection, I just never used online services to connect :x
Good luck, you might want to use Advanced Sessions plugin.
Ok I'll take a look, already a lot of thing to try for the weekend haha
there is enough tutorials on youtube. will it work for you is different question. As I said, you will need luck.
Is it a uobject?
You can't replicate uobjects to the server. You can only "reference" them. If it was a struct, it would be fine.
Basically it doesn't work because the server doesn't have that object, it only exists on the client
The client is saying, "run this event with object equipmentsave_c_80" and the server is going "what's that then?"
oh
thank you
that explains things
since it a savegame
I know how to fix that then, since the savegame doesn't have that many variables
π
If your savegame has to be a uobject, you can create a uobject that just has a struct as its only property and put everything on that
And just sent the struct part to the server
But, again, any objects on that struct will need to exist on the server, too...
it's just a few classes
for the server to spawn
seems that I can pass that on
any idea why client set master never fires?
more context
it gets to the client set master call
then doesn't run the event on client
well, tbh I did a workaround and added a 2 second delay, seems weird to do it like this but oh well
I used this code in begin play and the game crashes⦠I know the function is an enum so how do i change from enums to strings like this example
UE_LOG(LogTemp, Warning, TEXT("GetNetMode: %s "), GetNetMode())
Is SetOwner something that should be done on server, client or both? I would assume on server, then it's replicated to client.
Yeah looks like it, thanks for the sanity check π
By default, if a pawn is unpossessed by a client, does ownership change away from that client?
Seems like you're doing it on BeginPlay, in which case your character hasn't been possessed yet. Do it on Possessed
You can't call client RPCs on actors that hasn't been owned yet (client owned)
Owner is null after its unpossessed
It is on possessed actually
I did a different way using my inventory system
seems to work now and it's cleaner
Hey guys. Quick question. Im currently working on an online pvp and the point is, I need to store the players' in-game currency somewhere across matches, like in a SaveGame instance. How can I make sure the players are unable to modify it with eg. Save file editing? Should I store the currency in a database on a centralised server with an API running, or what is the best way to achieve this?
Yes.
Are functions replicated?
Ok
Would anyone be able to help with fixing a nameplate over head which shows an enum
For me it doesn't show at all
This is for a multiplayer gamemode
I was thinking HTTP requests, because thats the easiest to implement. This way, if a player buys something from the in-game shop, they can do a call on the API, telling it to change value. Now this is a bit vulnerable, because players can just simply request the api to do something, eg. give more money. But because they are not always connected to a dedicated server, I cant just send the request through an RPC and let the server handle api communication. My idea is, the players can only lower their account balance with API calls, and only the server, with a special token can give them (at the end of a match). I know it is a bit of a weird approach, but I cant think of anything else. Is there a better way you can suggest?
Is this in your player character?
The first is yeah but the second img is the widget
yeah thats basically what api's are for. as for vulnerability you need to store all the related currency values also on the database and read from there if the player has the resources for buying.
game server can do an api call to grant rewards. I know a few games out there that does this.
as for local modifications, basically displayed currency is only for that, displaying purposes, all the game breaking things you handle it via your api or via the game server.
One example is that if you use cheat engine to modify your gold in runescape it doesn't affect anything because the server still displays the right amount
Is this in the gamemode?
The gamemode does not replicate and only exists on the server
No its in the player
Ah
Thanks. So basically to grant rewards, they have to be connected to the dedicated server (eg. when the player wins a match) so it can call the api safely. And for buying, the client can request the api. And should I store for example 'owned items / cosmetic IDs' in the database as well?
I can't see the problem with it
Check your output log for ownership issues
Something something owning connection warning or error
Yep
yeah, ideally.
It's all a back and forth between how your game works and security. However if I go to a standard mp game yeah, everything is stored on the db. There are BaaS out there that help with these if you prefer.
One important thing, the one that calls the api for granting is the server itself, not the players.
Even for purchasing items? When players are in the store menu, they are not connected to the dedicated server. The dedicated server is basically only for the actual gameplay.
ah what i meant was for things like granting items on match won. Purchasing things can totally be while not connected on a dedicated server.
@solar stirrup
Alright, thanks a lot.
Sup
It has errors but i dont thiink its related
In the widget?
Yes but be careful with that. The API endpoint will be exposed during offline play and so a cheater could keep sending POST or GET requests to obtain items or add currency etc. With my game Iβm making it so the API is only ever called from the server so it remains hidden from the players.
ERr
How do i repliciate in a widget?
but im changing the text in the widget...
Check out eXi's compendium ^^
Well then, use a RepNotify
When the value changes, update the widget
Or bind the widget to the value on the player
how?
What if I create a token only the dedicated server knows, and if that token doesnt exist in any of the requests, it simply doesnt change the values. (When granting new items)
In my instance, players are not always connected to the server
yeah that's the way I've seen it done
as for this, there's no issue with local players having access to the endpoint for purchasing since everything gets validated on the server.
Sure but if you send that access token with the request youβve already revealed it to the player.
Say you have /api/add-coins and to use it the request has a uid, and the amount of coins to add. Whatβs stopping a player from just spamming that request.
Thatβs the point im making yes, they can see the url if itβs offline
https://developers.xsolla.com/api/igs-bb/operation/create-order-with-item/ here's a baas example of a purchase
Creates an order with a specified item. The created order will get a new order status.
To open the payment UI in a new window, use the following link: https://secure.xsolla.com/paystation2/?access_token=ACCESS_TOKEN, where ACCESS_TOKEN is the received token.
For testing purposes, use this URL: `https://sandbox-secure.xsolla.com/paystatio...
Writing to the database via API should be server side but reading can be client side.
Api/add-coins is only called by the server (at the end of the match, when players are connected), sending the token (only known by the dedi server) to the api. The api validates with the token, and changes db entries). The players, when they want to spend their credits, just simply call api/spend-credits. It doesnt need a token then. This way even if a cheater starts to spam POSTs to /api/add-coins, it is not going to be validated by the api, due to the token missing
basically, yeah
Or is there a way I always connect clients to the server, so everything gets executed server side?
your reasoning is correct here.
Fuck it im going to have it spawn the players name by just spawning a seperate ui for each phonetic alphabet name
clients do get access to api calls but only the ones like purchase which are processed on the api server anyway so spam should be a non issue.
Not exactly. If the item they are unlocking is permanent then itβs effectively a database write that should also be handled server side. Whatβs stopping a cheater from just getting that item directly by altering memory and having it affect the single player gameplay experience?
If itβs only a cosmetic item I guess itβs not a big deal then but ya it depends.
I get the point. So what way should I keep the clients always be connected to the server? The dedicated servers only serve as 'matches'. Should I have a separate dedicated server everyone connects to when they are in the menus?
If you need item security then yea probably. I guess thatβs how AAA does it, csgo weapon cases happen during βofflineβ play but really the menu is connecting to a server to handle the spin and reward processing.
Thatβs why you canβt spin for cases while disconnected from the internet
Guys how can I change the widget to another widget with blueprints (this is for UMG 3d widgets in multiplayer)
u mean widget components?
Yea
speaking unreal-wise, I have to create a separate dedicated server, running as a 'main menu server', to keep players connected?
can i create a 3d widget?
oh my god this is so annoying
first it doesnt let me change the variables in the widget and show them next it doesnt let me change the ui in 3d space
how the heck am i supposed to make 3d name plates above players heads when nothing works
u want to change the nameplate widget value?
yeah
but it doesnt show for any players
i have the phonetic alphabet names assigned randomly
that works but it doesnt show on the 3d widgets
first check, if the widget itself works. set a random text and see if it is visible?
so i tried to manually create a widget for EVERY name lol
it does!!!
Im losing my mind dude
so your problem is, u cant change it during runtime?
Im not a networking genius, but maybe try to use repnotify for the 'name' variable. Then in the On_Rep, set the text in widgets
On the text one?
replicated
try changing it to repnotify
then a new function will be created
called OnRep_VariableName
then move this code inside that
Depends on your game, but that's how I assume other games handle that. You may also want to defer connecting to the server until an intent to purchase has happened, IE: the player navigates to the shop to help minimize resource usage.
but it needs to set the player name
yea
in the OnRep_, grab the var from the left, and connect it here
this will be ran on the clients
Imma try to help you in DMs, so we wont flood this channel. xd
ok
hello, is server travel working in the ue 5 editor? i think it never worked in ue 4 editor.
By server travel, do you mean join session ?
hello guys!
Im trying to create easy multiplayer coop game just for learning how to implement it into steam and how create a player account progression, like acc lvl, score etc. Do you trying to do something? May be you have any advices or helpful information like links, video etc. Will be very glad for your help!
@fresh chasm in ue 4 if you did GetWorld()->ServerTravel only the server would move to the new level. I was asking if in UE 5 it moves all the connected clients as well.
in the editor that is
Have you tried to open a new map on server? All clients should follow
I am trying to spawn an actor from my pawn in the server and it is not replicating to any client...
any idea why? π€
The spawning class has the replicates checkbox enabled and the spawning code is definitely being done in the server π€
i do it on the server and unless its a packaged build the clients dont join
its a common issue
mmh I was not aware of this, even in standalone mode?
not sure about that
standalone works fine
in documentation about server travel and seamless travel it was written, as far as I remember
the actor was replicating, it was my mesh that wasnt replicating so I couldn't see it appear π€¦ββοΈ
To implement steam check this links :
Docs: https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/Online/Steam/
Advanced Sessions Plugin: https://forums.unrealengine.com/t/advanced-sessions-plugin/30020
Video: https://www.youtube.com/watch?v=ke3kmK6bvT0&ab_channel=DraftShape-PyroDev
What's the most effective way to provide some kind of piracy prevention if releasing a multiplayer game on Steam?
Itβs there any info on iris replication thing? Iβm curious what it is
?
im making a multiplayer inventory system and my blueprint for transferring items from a container to player inventory basically removes the item index from the array on the container and then adds it to the player inventory, but im concerned that if two players take the same item on the same tick it will duplicate it
what is the workaround for this
It shouldn't.
What should pass from client to server is a request like "Move Item from Container A to Container B"
Server actually does the work.
There will always be an order to those, so the 2nd one should fail since the item should already be gone. from Container A.
this is the case even if two orders to move are sent on the same tick?
can anyone hop in a vc to see what my problem is? I am trying to replicate an object spawing across server and client but I am not exactly sure I know what I am doing tbh. Just ping or dm me if you are up for it
Yes, there's always an order to it
you aren't multithreading your inventory management
ok awesome
I dont really know anything about multithreading or its implementation
hello have any of you guys gotten Steamworks sdk and build and run SpaceWar project ?
I'm a little confused on this one:
I've set up a replicated boolean, changed on the server whenever the attack combo should start/stop (which is decided through local user input)
Now this for some reason only properly works when it is executed on server, otherwise only the clients do this combo?
void Attack();
void BeginAttack();
void EndAttack();
UFUNCTION(Server, Reliable, WithValidation)
void ServerBeginAttack();
UFUNCTION(Server, Reliable, WithValidation)
void ServerEndAttack();
UPROPERTY(ReplicatedUsing=OnRep_Attack)
bool bAttackOngoing{false};
UFUNCTION()
void OnRep_Attack();
void APlayerCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(APlayerCharacter, MeleeWeapon);
DOREPLIFETIME(APlayerCharacter, bAttackOngoing);
}
void APlayerCharacter::Attack()
{
if (!MeleeWeapon) return;
if (ActiveActionState != Attacking)
BeginAttack();
else if (bComboWindow)
bContinueCombo = true;
}
void APlayerCharacter::BeginAttack()
{
if (!MeleeMontage) return;
ServerBeginAttack();
PlayAnimMontage(MeleeMontage);
}
void APlayerCharacter::EndAttack()
{
ServerEndAttack();
if (MeleeMontage)
StopAnimMontage(MeleeMontage);
}
void APlayerCharacter::ServerBeginAttack_Implementation()
{
bAttackOngoing = true;
}
void APlayerCharacter::ServerEndAttack_Implementation()
{
bAttackOngoing = false;
}
void APlayerCharacter::OnRep_Attack()
{
if (!MeleeMontage || IsLocallyControlled()) return;
if (bAttackOngoing)
PlayAnimMontage(MeleeMontage);
else
StopAnimMontage(MeleeMontage);
}
This is all the code related to the attacking (besides the input, which is fine)
The wanted behavior would be: client does the input and attack starts instantly, the other clients/server should see this attack combo being properly replicated. And collision happens on server side (this part already works, as you can see in video) So I am basically just missing why it's not replicating from client to server but other way around works fine
I'm having an issue with setting a seed on the server which is replicated to all clients. I've tried setting it in the GameMode and then replicating it in GameState, PlayerController and PlayerState. I've also tried casting from actors in the level. The client never receives the seed value. Lastly, I've tried spawning actors using the SpawnActorDeferred (setting the seed during spawning) from various overridden functions in GameMode/GameState/PlayerState and the client seed is always absent. Can anyone point me to a simple method to get the seed replicated? I feel like I'm missing something obvious. I'm using C++ rather than blueprints.
to debug this, can you verify that just basic player movement replication is working? i.e. server is launcing as listen server and clients are actually connecting.
After that I'd double check:
- bReplicates is turned on on the AActor you are wanting to replicate.
- GetLifetimeReplicatedProps() is implemented with DOREPLIFETIME() of your replicated variable.
- Variable is marked with ReplicatedUsing=MyFunc and put a breakpoint in MyFunc to check if the value is coming down.
- Make sure all writes to your replicated variable is guarded at some level my HasAuthority().
When your message is getting to the server (ServerBeginAttack_Implementation()) you are only setting a bool and returning. you need to run the same logic as OnRep_Attack() on the server too so the server also does the logic of "receiving" the onrep.
This is a bit of a differerence in behavior compared BP, where writing to a var on the server will call the onrep for you automatically.
So you're saying I should call the OnRep_Attack in the ServerBeginAttack?
π€ that's interesting
I would call OnRep_Attack() inside of ServerBeginAttack_Implementation() after setting the variable.
Yeah so the OnRep is only called for those receiving the replicated value, not the one setting it.
If I understand it correctly
correct.
i.e. Unreal it self will only invoke OnRep on clients only.
the server needs a chance to execute the same logic too at some point.
Alright, I'll give it a shot in a bit thanks for clarifying π
That does seem to work fairly well, just have to fix a small issue where clients sometimes don't replicate π€
Oh well the server properly replicating now is most important anyway for gameplay
Thanks for the reply. Basic server setup should be fine- I get a listen server player and a client. The only thing I haven't done in your numbered list is a ReplicatedUsing. So far I've just used 'Replicated'
?
Actually, I just found out recently, that the OnRep in Blueprints get called on the server and the clients. The C++ version however only gets called for clients. Weird UE4 logic
You missed this part: "This is a bit of a differerence in behavior compared BP, where writing to a var on the server will call the onrep for you automatically. "
#multiplayer message
ahh, sorry. I didnt notice.
Ah I got ya, thank you π
Anyways, I have a question. Is there a possible 'best way' of implementing a secondary dedicated server that players will connect to, when they are in the main menu? Eg.: when the game match is running, players are connected to DedicatedServer_1, aka the main server. But when they leave / return to menu, I still want all the players to be connected to a server because they have to be able to call an api through the server if they want to do anything in the in-game shop.
I'm pretty sure it's done through restapi outside of actual game servers
I'd worry a bit about your scalability to run the shop as a DS. But if you wanna run a UE instance to run shops I'd look at UE Beacons: https://docs.unrealengine.com/5.0/en-US/using-online-beacons-in-unreal-engine/
right but that wouldn't require an API at all π
I'm trying to run in editor ListenServer + Client and getting failed check(Controller) in autospawnd Pawn's BeginPlay. Shouldn't Pawn get possesed by PlayerController before BeginPlay?
controllers are only valid on the server and owning client
Do you have better idea?
The way I've implemented shops in the past was to use a 3rd party service like PlayFab. Have not used but EOS may also support some of this.
I've got log message if HasAuthority() prints, doesn't it means Pawn is on the server?
Are you expecting it to be possessed by a player or ai controller?
player
In your game mode, is this pawn class set as the "default pawn class"?
yes
The shop is only for in-game currencies. I was thinking of using an api to manage a database containing the players in-game currencies. When a players wants to buy something from the shop, eg. cosmetic items, it will call the api to make the transaction. I only want the players to be connected to a DS, so I only have to expose the API locally to the DS. If I dont use a server, and expose the API to the clients, how can I make sure that they cant just cheat for example sending POST requests manually to it?
is this the first pawn spawned? or subsequent spawn/respawn?
I dunno about spawned, I have log in BeginPlay and this is the first one
PlayFab does have DS server components, but I'm referring to the components that deal with account authentication and validating the transaction - basically any ecommerce site. High-level, same steps you would walk through when buying something on amazon or door dash, you have to do. using soemthing like PlayFabs just makes those steps a bit easier, but still a lot of work.
Alright, thanks.
I would put a break point in APlayerController::OnPossess() and see if your controller is actually possessing something.
ok, I ran ListenServer with only 1 Player and all good, Logs:
LogTemp: Warning: BeginPlay
LogTemp: Warning: IsLocallyControlled
LogTemp: Warning: HasAuthority
But with 2 players:
LogOnlineSession: Warning: OSS: No game present to join for session (GameSession)
LogTemp: Warning: BeginPlay
LogTemp: Warning: HasAuthority
LogOutputDevice: Warning:
Script Stack (3 frames):
GameModeBase.SpawnDefaultPawnAtTransform
GameModeBase.SpawnDefaultPawnFor
GameModeBase.HandleStartingNewPlayer
Assertion failed: Controller blahblah
https://docs.microsoft.com/en-us/gaming/playfab/features/commerce/economy/quickstart
And you are on your way
ok, I'll try that
You are all in BP or have c++ access?
I am using C++ controller class
Hi all,
I have a bit of a complicated setup. I am simulating 3d movement in multiplayer and for first person player controlled units everything is fine.
For AI units, what I do is have a parent actor to which I attach the unit via AttachActorToActor. The parent unit is invisible and uses 2d pathfinding, on a flat xy plane (the floor). The child unit (the unit players care about) follows this on the xy plane but is situated vertically above.
For vertical movement of the child unit, I have a 'lock on' system in place. Once the child is locked on to a target actor, I am trying to add an appropriate z velocity component to the character movement component. I use SetVelocity on server - I am not simulating physics at all.
I am doing this every 0.2 seconds. I am seeing some movement, but the problem is, if I update the velocity every 0.2, the movement is visibly choppy looking - as if the velocity is getting reset every 0.2. I tried only changing the velocity if something changes about whether the target actor and the child actor we are moving are above/below each other respectively - eg set a fixed velocity of +300 if we are below the target unit, and a fixed velocity of -300 if we are above - this actually seems to prove that my velocity is getting reset, since when I do this I see a very small amount of movement before the child actor stops moving in the z direction.
Can anyone offer any help as to where I might be going wrong?
Nope
No guarantee and BeginPlay is called before Possessed
ok, I lied, the first Pawn get possessed, the second one is not
Doesn't matter. Do it on Possessed
in Pawn or controller?
That event is in pawn as the name suggests
You said the pawn isn't being possessed?
yes
The 2nd one
yes
Again it's not meant to be possessed
That's why there is an event called Possessed that 100% fires when the pawn is possessed
Use it instead
If that doesn't fire then your pawn isn't being possessed
I think I found the root of the problem and its my friction values
I assumed it was a networking problem
what do you mean? Remote Pawns on the Server are not possessed?
oh, I thought you meant not meant at all
ok, got it
Hi, I have a 2D top-down sprite character and I have an issue with replicating the sprite's directions to other clients. The host is the only one that replicates the directions depending on the direction properly while the other clients aren't doing that. For example when the host moves left, the sprite plays the left walking animation but when the client moves, it only plays the default direction which in my case is the walking up animation.
I run this event on my event tick
How are you replicating a client's direction to the host and/or other clients?
It doesn't work just by setting a variable to be replicated.
I have a movement input and I check which input is pressed and set the player's animation depending on that. Do I need to check the direction in a separate event to replicate it to everyone?
hey does anyone know how i can use two different third person characters for player 1 and 2
I have a submarine in an infinite sea game. I'd like to spawn Actors (mines) in areas, only where there is at least one player around, and despawn them when they leave. I don't see any design that allows that.
- I don't want clients of players far across the map to spawn mines that are spawned for other players.
- If two players are in the same area, they should see the same mines.
Is there any common pattern for this?
Set up a separate TPC class and spawn the correct character on the game mode's RestartPlayer?
Or whatever has the spawn function
You should use relevancy for that. I think there's a distance cull anyway, so look into that? (google?)
As for how you spawn mines, maybe use a sort of grid system? An octree perhaps? When a player enters a certain grid (and all the spaces around them,) mines are spawned, when there are no players within a space or two of the mines in that grid, despawn them?
Just keep a note of which grid the mines are in (possibly with a map?) and it should be pretty easy
That's not IMO the problematic part, it's really how to replicate things. Say that another players enters and needs already spawned mines, how do you make that client spawn them too?
The client doens't "spawn" them (sort of)
When they become relevant to the client, the server will tell them that they exist
And they'll pop into existence.
Ah alright so that'll be handled, that's nice. I'll google more into relevancy for the details. Thank you!
Thanks that screenshot of yours is very relevant for this channel.
That's from one of the compendiums in the pinned messages here, I think.
Sometimes I feel like an actor attached to a skeleton with bOnlyRelevantToOwner enabled.
Hello, I think that I'm missing something when it comes to replication for late joiners. Replicated actors should automatically replicate all the values (replicated ones) from server to a newcomer, right?
Right, though as soon as that actor is relevant to the newcomer
Yes, it is always relevant and owned by Player Controller on server and still nothing is send to client π¦
Don't tell me the NetUpdateFrequency is 0 and you ForceNetUpdate
Cuz that breaks things
Nope, I indeed tested this case with ForceNetUpdate but with no luck
Back with another question: how is it possible my animation and rays (event tick) are slower on server than client?
The animations are just montages getting replicated, with notifies doing the logic locally from there... π€
Starting from the server, it all runs smooth (client -> server runs slow, on fixed 120FPS)
Edit: the ray positions, event tick time and pretty much amount of calls seem to be the same from debugging yet the result is different.
Well. Is the actor itself replicating?
Do you see it spawned for newcomer? Or is it a preplaced actor?
It is spawned by server and it is visible on client. Also RPCs works so I'm kinda sure they are 'connected' π but no values set before connection are propagated to client
hey guys, I'm trying to create a join and host functionality using steam online SubSystem, but when I try to host I get some errors and warning like follow