#multiplayer
1 messages Β· Page 470 of 1
π
you could split the bool into 2 ints
or bytes for less data
0 an 1
do it manually π
Yeah that's not the point sadly
didn't u need an onrep that gets updated?
Hi everyone! I am connecting multiplayer through LAN using IP connection. On Android devices I am getting the IP to display on the host screen (so they can tell others what it is), retrieving this IP works great. On iOS though it doesn't, it's returning the MAC address instead, anyone know why iOS would be different?
Here is how I am getting the IP Address
if u repnotify a 0 and a 1, u could get away with it
{
bool canBind = false;
TSharedRef<FInternetAddr> localIp = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->GetLocalHostAddr(*GLog, canBind);
return (localIp->IsValid() ? localIp->ToString(false) : "");
}```
@west rapids The Setup was:
UPROPERTY(ReplicatedUsing="OnRep_bIsSpeedBoosting")
bool bIsSpeedBoosting;
void SetIsSpeedBoosting(bool bNewIsSpeedBoosting)
{
if(bIsSpeedBoosting != bNewIsSpeedBoosting)
{
bIsSpeedBoosting = bNewIsSpeedBoosting;
OnRep_bIsSpeedBoosting(); // C++ requires server call of OnReps
}
}
void OnRep_bIsSpeedBoosting()
{
OnSpeedBoostStateChanged.Broardcast();
}
Client calls "SetIsSpeedBoosting" on button press and replicates the flag to the server.
Server calls it too. OnRep never calls for the Client -> Delegate nevers calls for the Client
Tada, bug.
Now I moved the OnSpeedBoostStateChanged.Broardcast(); where the Manual Server call of the OnRep is, while keeping it in the Onrep too.
And limited the replication of bIsSpeedBoosting to Simulated.
did it work?
Yeah, Server and Client don't call OnRep anymore but directly the delegate.
And Simulated clients never call "SetIsSpeedBoosting" so for them the onrep calls properly
Just took a bit to notice that the OnRep isn't calling cause of the double setting
Would have guessed the Server still sort of makes the client call the OnRep
But well
hey it was a great setup
It also works as long as only the Server calls SetIsSpeedBoosting
you can defactor back to it in 4.23 π
But for Movement lag compensation reasons it's called on client too
@red musk Sorry for spaming your question away
i cant help with iOS
clueless there
i g2g tho, good luck, hope exi got some knowhow there
I wouldn't try to rely on the Subsystems for this
I would try to get the outer IP just by quickly calling an HTTP Request to something that returns the public ip
That's all I can give you, g2g now too, gotta get up in a few hours again ;-;
Feel free to just paste your question again
Cya!
so
i implemented my ammo array as a fast array serializer, even tried just a normal array
the server value changes, but client never gets updated
{
int32 Idx = Ammo.IndexOfByKey(AmmoType);
if (Ammo.IsValidIndex(Idx))
{
Ammo[Idx].RemoveAmmo(AmountToRemove);
MarkItemDirty(Ammo[Idx]);
}
}```
im pretty sure im doing it right
nvm got it working (finally)
generate project files executable from source code is asking for .NET framework 4.6.2, will it not be happy if I install the latest?
install development tools for .net 4.6.2, it's an optional feature under the .net desktop development feature
you mean in the visual studio installer right? i think i found it
yes
thx
ayyy I got baited
i had to run this in cmd apparently "GenerateProjectFiles.bat -2017" but I ran the executable
Would anybody be able to help me out with syncing up multiple moving platforms that follows a single spline?
Im just trying to sync up cable cars that automatically start moving when the match starts but as players join in it gets desynced
Hey guys,
I am using UWorks plugin, successfully created steam dedicated server
but my client not able to connect to that server
is open steam.steamServerId
or open ip:port
Hi guys, I need to do asynchronous multiplayer (kind of http request), but still there is one UE4 server and multiple UE Clients. Is there anything in place to do this? like rpc or something like that? So far Im finding all realtime examples
Just wondering if anyone had some article links or knew the magic google keywords for getting information on what sort of considerations need to be taken when designing for a 160 player cap on dedicated servers (not an mmo, just need to allow big games). I know the basic concepts of reducing traffic to/from the server but I'm not finding much about how this actually works in practice..
@alpine wagon for that, i'd hire someone who has done 100+ player multiplayer networking before for a consult
if that is a commercial project, that is
if its a hobby one, i'd divide the number of players by 10 then go from there
@winged badger Thanks though I'd figured that much out on my own. I know it's not a simple thing, was just wondering if anyone had some practical information about how they got started on this sort of problem.
problem is, i am confident i'd see the traps and what to watch out for, if i started working on that scope, as i worked
i can't list the off the top of my head tho
and you probably need someone who can
i have heard of horror stories from teams that went figuring it out as they went along
like dedicated server needing 130ms just to figure out what it needs to replicate to whom
Yeah I've heard some of the horror stories too but I'm not looking for creepy pasta links at this stage. I'm just at the information collection and assessment phase right now so what I'm hoping for is info about people who have managed it and what it took. Do you have anything like that?
that particular scenario was 50k replicated actors, 40 players, no dormancy and pre-replication graphs
don't know how useful that information is, but it does provide some insight in problems encountered at that scope
No that was pretty much useless. The key words "replicated actors" however lead me to some useful documentation so thanks for that.
Anyone had issues with FFastArraySerializer replicating junk? Server-side structs are added to the Items array, array is marked drity, and client-side replication callbacks fire
only, the struct is junk
even if i reduce it to just name, int, enum, with no custom serialization, its still junk
nevermind, bug in debug tools is the worst kind of bug π¦
Hi guys, so I'm trying to finally implement a delegate to invoke when an invite is received to a lobby from a Steam friend. Unfortunately the functions that I managed to find in the SteamWorks SDK are a bit harder to implement than I expected:
STEAM_CALLBACK_MANUAL(USurvivalGameInstance, OnPartyInviteReceived_Steam, LobbyInvite_t, OnLobbyInvite); causes Error C2059 syntax error: ')' to be spammed while building in the generated files.
Even declaring void USurvivalGameInstance::OnPartyInviteReceived_Steam(LobbyInvite_t *pParam) doesn't help. Any ideas?
for that specific callback, theres AddOnSessionInviteReceivedDelegate_Handle built in
anyway if you want to use steam's, make sure you have the includes
Alright
Here is a gist snippet of our code: https://gist.github.com/JasperDre/fa9074dace2dd95603ff1558d6197168
Are you sure FOnSessionInviteReceivedDelegate is implemented in the OnlineSubsystemSteam? I don't think it's actually invoked anywhere and just returns false.
not sure, tbh, only seen it but havent tried
OnLobbyInvite seems to be a variable generated using the STEAM_CALLBACK_MANUAL but I will give it a quick try
So OnLobbyInvite is already defined using STEAM_CALLBACK_MANUAL
Yeah the _manual macros take in extra arguments
but its a weird error and I have no idea how to debug the generated files
fascinating
I will try to clean up the uclass to see if there is something else causing this
im getting this error when clicking the visual studio's local windows debugger button on a source code build, can't find an answer in google with this particular dll mentioned, anyone's had this issue?
UE4Editor-UnrealEd.dll is either not designed to run on windows or it contains an error. Try installing the program again using the original installation media. Error status 0xc000012f.
Has anyone run across a problem with the CharacterMovementComponent where you can stay out of sync and receive corrections for every step you take?
I'm trying to figure out what makes it stay permanently desynced
Nevermind I think I figured it out, its related to some properties like ground friction or walk speed not being reset
CMC has no such issue, it's something you're doing FYI
anyone know of a resource that explains player spawning? Like player 1 spawns at a spawn point marked for player 1 and so forth? (in cpp)
I can make the player spawn at any spot I want (in ChoosePlayerStart_Implementation) what I'm really looking for is how to tell who player one is vrs the other players
reading the source code of GameMode is the best way
Hi, i try to make the player (in a multiplayer environnement/game) face the cursor in a topdown view with WASD movement.
The problem i got into is that i try multiple solution(RepNotify, make custom even with runOnServer with reliable check, ...) but when i play it's not replicate the player rotation on the second client (I play it in PIE mode with dedicated server check).
What it's weird is the first client that connect/create the session have all player rotation change correspondant of his mouse but all other player see it move but not the oritation of him -_- I do the player face mouse cursor in blueprint.
I think i miss something in the replication or somethink like the change of oriantation i do doesn't change the oritation in movementComponent, i don't know xD
yeah, never ever use GetPlayerController[0] if you don't know exactly what you're doing, and especially not on dedicated server setup
@vestal knoll
@winged badger Ohhh okay but how can i take the correct player controller, I try multiple exemple i found on internet to get the correct playerController but i always get stuck there
some object reference other objects by default
on client, GetFirstLocalPlayerController from GI, GetController from player Pawn, GetOwningPlayerController from HUD, GetOwningPlayer from any widget will get the PC
i take it your troublesome relationship is with the Pawn
so Cast<AMyPlayerController>(GetController()) will grab the controller from inside the pawn
Hooo thank you i'll try with that!!
@winged badger I try it and that doesn't really resolve my probleme xD what you gave me is for that the focused screen doesn't rotate other character but the rotation of the char isn't replicate to other unless for the first player connected to the party (I think it's because it's the one who created the party)
When i read again my message, i realize that i explain my probleme like a trash xDD
HI,
I have setup a gameserver registered with Steam, it show in steam server list,
But when any player connects to the server, player count stays zero in steam server list.
Does not affect the gameplay though but I am still curious, how to increase player count in steam server details
is there any relevancy for spawn of actors?
the same IsNetRelevantFor is used for that
so if you spawn an actor on the server, it won't tell the client about it if IsNetRelevantFor says false
then if later it became relevant, then the server would tell the client about it
Hey guys. I'm trying to figure out how to go about setting up a shared presence system for the Oculus quest. Since the world origin[0,0,0] will be different for each headset when they start tracking, I will need a calibration step(most likely using the controller on the same physical location and then storing the offset to each headsets world origin), now for my question:
When spawning enemies etc. in the game, how can I make the client compensate the replicated positions from the server?
Example:
Server spawns enemy at [100,200,50]. Client 1 has calibrated an offset of [-200,100,25] and therefor the correct location for the enemy on the client should be [-100, 300, 75]
I'm thinking adding a transform op on the client on tick is not the best solution
(and can this be more general? since everything that gets replicated with transform needs to use this compensation)
Not quite sure what you are trying to achieve.
Last time I did Oculus Multiplayer for a Client I didn't have to do any of that.
The World Origin for each player, if you aren't actively shifting it, is always 0,0,0
The Headset in VR is relative to the Pawn the Camera is on
@native moth
Maybe it's different for the Quest π€
yeah, but you have to remember this is 2 people inside quest headsets
in the same physical space
Yeah but if they are also in the same multiplayer world, why can't they have the exact offset they have in real life?
Let's say the middle of the reallife room is 0,0,0 in the game world.
If player one stands on 0,0,0 and player two stands 50 units to the left, then that should be the same in UE4 or?
because the tracking origins are not the same unless you start the quests up at the exact same physical place
Right that's a Quest thing then
yep
Hmmm
Can you manually change the Tracking origin?
so while the relative origin in side UE 4 is the same, the physical origin is not the same
not that im aware of
Do you have both tracking origins as vectors?
It might be super easy to just make UE4 shift world origin
iirc it supports that in multiplayer by now (i think)
not that im aware of no. So thats why I need a calibration step
so if both players place their controllers in the same physical place and unreals then store that transformation offset compared to the world 0,0,0
But you could also simply tell UE4 to change the World Origin for the Client, right?
As far as I'm aware, replicated locations are shifted based on that
So if you keep the Server at 0,0,0
And you update the WorldOrigin of the client to the tracking start, it should resolve itself
okay, and that world origin shift is client only right? Its not something that the server needs to be doing?
Means the Client, in UE4, will have 0,0,0 at their tracking space.
And if you spawn an actor on the Server on 0,0,0, it will apply that offset to the client
I haven't used it in Multiplayer
But it's the most straight forward approach I would say
Interesting. I thought worst case is that every single replicated actor needed to have OnRep functions that updates the transformations on clients
https://www.youtube.com/watch?v=G0WHhNQpf9I seems like this guy has it working π
Yeah it should already do that by default
hmm, at the moment I'm thinking if changing the offset inside the clients pawn would be easier
You have to see that you need to apply that offset to literally everything
If the World Origin of two players isn't the same, then you'd need to adjust every spawned/moved actor
Cause Vector(x,y,z) on the Server is not at the same location as on the client
yep
So I would really first look into the World Origin rebase, cause that's literally just one function call
Given you know the offset between the two track origins
Would need to also move/rotate the level when rebasing, but I guess thats pretty easy with some root actor getting changed
yeah, will do!
thanks for the input π
worst case, the company will have to hire someone that knows what they are doing π
I package my project as dedicated server and host works fine, but when I launch project to windows server and host it fails with lot of errors, anything important am I missing ?? my be any important step in creating custom launch profile
"lot of errors" we would need to know these to help you
But in general, the difference between the Windows Server and your PC is probably stuff like DirectX and C++ Redistributables not being installed on a fresh windows server
@timber tree
ohh
Error somthing like this
[2019.06.15-10.28.25:446][ 0]LogWindows: Error: [Callstack] 0x00007ff8ae0d9129 KERNELBASE.dll!UnknownFunction []
[2019.06.15-10.28.25:447][ 0]LogWindows: Error: [Callstack] 0x00007ff6d78d0dc7 RogueHeistServer.exe!ReportAssert() [d:\ue4linux4.22\engine\source\runtime\core\private\windows\windowsplatformcrashcontext.cpp:553]
[2019.06.15-10.28.25:447][ 0]LogWindows: Error: [Callstack] 0x00007ff6d78d33d3 RogueHeistServer.exe!FWindowsErrorOutputDevice::Serialize() [d:\ue4linux4.22\engine\source\runtime\core\private\windows\windowserroroutputdevice.cpp:79]
[2019.06.15-10.28.25:447][ 0]LogWindows: Error: [Callstack] 0x00007ff6d76ff95a RogueHeistServer.exe!FOutputDevice::LogfImpl() [d:\ue4linux4.22\engine\source\runtime\core\private\misc\outputdevice.cpp:71]
[2019.06.15-10.28.25:447][ 0]LogWindows: Error: [Callstack] 0x00007ff6d768cc19 RogueHeistServer.exe!FDebug::AssertFailed() [d:\ue4linux4.22\engine\source\runtime\core\private\misc\assertionmacros.cpp:440]
[2019.06.15-10.28.25:447][ 0]LogWindows: Error: [Callstack] 0x00007ff6d768cfa9 RogueHeistServer.exe!FDebug::CheckVerifyFailedImpl() [d:\ue4linux4.22\engine\source\runtime\core\private\misc\assertionmacros.cpp:418]
[2019.06.15-10.28.25:447][ 0]LogWindows: Error: [Callstack] 0x00007ff6db0d068d RogueHeistServer.exe!DispatchCheckVerify<void,<lambda_4e61acb446d88d7b7096d16ad721787f> >() [d:\ue4linux4.22\engine\source\runtime\core\public\misc\assertionmacros.h:162]
[2019.06.15-10.28.25:447][ 0]LogWindows: Error: [Callstack] 0x00007ff6d7984f59 RogueHeistServer.exe!FArchiveAsync2::Seek() [d:\ue4linux4.22\engine\source\runtime\coreuobject\private\serialization\asyncloading.cpp:7810]
when starting a multiplayer level at which point we can be sure that the player state is ready on a client ?
Depends where you want to know that.
In the Pawn or Controller, there are OnRep_PlayerState functions (C++ only).
The PlayerState itself obviously calls BeginPlay on the Client too.
@timber tree thats not errors, thats a callstack
and would need to see the full callstack not just that bit
ok
it starts from here
[2019.06.15-10.28.24:316][ 0]LogLinker: Error: Bad name index -1522561844/209
[2019.06.15-10.28.24:316][ 0]LogWindows: Windows GetLastError: The operation completed successfully. (0)
[2019.06.15-10.28.25:445][ 0]LogWindows: Warning: CreateProc failed: The system cannot find the file specified. (0x00000002)
[2019.06.15-10.28.25:445][ 0]LogWindows: Warning: URL: ../../../Engine/Binaries/Win64/CrashReportClient.exe "D:/PlayFabLocal/Config/PlayFabVmAgentOutput/2019-06-15T15-57-06/ExtAssets/ffffffff-ffff-ffff-bec9-01260000000083ce636d-9269-41e2-b32f-c5a34b275c9cWestUs/SH0/A0/RogueHeist/Saved/Crashes/UE4CC-Windows-3530F10348B60A9982B3E1A08AD64BF8_0000" -Unattended -nullrhi -AppName=UE4-RogueHeist -CrashGUID=UE4CC-Windows-3530F10348B60A9982B3E1A08AD64BF8_0000 -DebugSymbols=..\..\..\Engine\Intermediate\Symbols
[2019.06.15-10.28.25:446][ 0]LogWindows: Error: === Critical error: ===
[2019.06.15-10.28.25:446][ 0]LogWindows: Error:
[2019.06.15-10.28.25:446][ 0]LogWindows: Error: Assertion failed: InPos >= 0 && InPos <= TotalSizeOrMaxInt64IfNotReady() [File:D:\UE4Linux4.22\Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncLoading.cpp] [Line: 7810]
[2019.06.15-10.28.25:446][ 0]LogWindows: Error: Bad position in FArchiveAsync2::Seek. Filename:../../../RogueHeist/Content/WeaponSystem/BluePrints/WeaponSystem/BaseWeapon/BP_BaseWeapon.uexp InPos:1862289024, Size:20708
[2019.06.15-10.28.25:446][ 0]LogWindows: Error:
[2019.06.15-10.28.25:446][ 0]LogWindows: Error:
[2019.06.15-10.28.25:446][ 0]LogWindows: Error: [Callstack] 0x00007ff8ae0d9129 KERNELBASE.dll!UnknownFunction []
Ooopsπ
delete all that
your error lies here
[2019.06.15-10.28.25:446][ 0]LogWindows: Error: Bad position in FArchiveAsync2::Seek. Filename:../../../RogueHeist/Content/WeaponSystem/BluePrints/WeaponSystem/BaseWeapon/BP_BaseWeapon.uexp InPos:1862289024, Size:20708```
that means your BP is possibly corrupted
is there a good training video on using Sessions? π€
@thin stratus the thing is that I plan to have the player select object from a list and store the index of selected item inside the player state but that will happen before the player join a multiplayer game and then once he join the multiplayer game I want to get those index to actually load some visual on my UI but I tried to get the player state on the widget construct which most of the time doesn't work on client since it's not yet there and I tried to have to call a function on my widget from the begin play of my player state and it still doesn't work
Hmm, I am switching my capture points spawning to be done by my game mode, for it to be agnostic of the map that its being loaded and played. And I am having trouble syncing the server-client spawning. Here is what I do, on GM i build up an array of what and where needs to be spawned, I pass that array to the game state, which then sets that array for itself, so it can be replicated to clients, its a rep notify, so in its function I actuall spawn actor from class. but the thing is that afterwards the behaviour of the capture points doesnt work, because they are basically 2 different actors between server and client...
heh, maybe next time I should click this
It works now, but either way, what is the proper method for spawning actors, especially when peeps can join in the game at any time
if you spawn it on the server, then when the new client joins if the server thinks the actor is relevant to that player, then it'll tell them about it
you generally don't want to spawn actors on client unless it's like a predicted actor or something like that
Yeah, right now with a server spawn on GS, everything works in editor, but I guess we will see on playtests when someone joins midgame
@high current why would you spawn them on clients separately?
i mean there are reasons to do that if you want to keep them synced and not replicated at the same time
but this doesn't seen to be the case
@winged badger you mean not have them in the level to begin with?
well, if you're spawning the Actors at runtime
and they are replicated
just spawn them on server, do not spawn them on clients
new ActorChannel gets created by the NetDriver, it sends the clients instructions to spawn the actor of <class> at <transform> that has these <replicated variables>
clients receive a bunch, spawn the actor, set the replicated variables, after all repnotifies fire, they call PostNetInit, which then calls DispatchBeginPlay
so that process is far more efficient then spawning them on server and client separately, and hoping they get synced before you need them
yeah, ofc. its just that I had been working with that specific actor for weeks now, in a multiplayer enviroment, without ever replicating it, hence why I thought to enable its replication just now...
Also, if I spawn them on GM directly, they will never get replicated to client, but that is cause GM doesn't exist on client right?
no
NetDriver on server is very much aware of the GM on server
its not the local version of GameMode that tells clients to spawn the actors
NetDriver prepares the bunch for replication, then sends it across player's DataChannel (associated with the PC)
each replicated Actor has its own ActorChannel, they do not use the ActorChannel of the object that spawned them
@high current the technique to use server side only non-replicated Actors to drive gameplay logic is pretty important
example: mission system
server has MIssionManager and Mission Actors, that run the logic, spawn (replciated)Actors required for the mission, keep track of when the objectives are completed, etc...
what do clients really need to know?
where the mission is, what is the objective, and what is the status of the mission
nothing else
so you spawn some replicated marker actors, that automatically place themselves on the minimap and/or have some particle effects marking the mission area
you send a few lines of text (or datatable row name client should read the text from)
and an in32 or enum they can use to interpret which objective is currently active, and whats its state
@winged badger I knew it... its a bug with 4.15. But yeah. I am developing a game mode for Unreal Tournament, and I have been noticing replication bugs and inconsistencies with my normal UE experience, especially the fact that GM cant replicate anything. But yeah, the compartmentalizing of replication data is something I get and very much enforce everywhere. I do everything gameplay related in GM, GS keeps track of the current state if its relevant to clients, and any data needed for UI and hud of each client is in PS, I use the Player Controller to store global stuff that the player might need, so its accessible even when dead/spectating and so on.
@high current i spent quite abit of time on 4.15 doing networking, i am not aware of any replication bugs with it
Might be just the unreal tournament version then, because as I mentioned, if GM casts to something, and runs a multicast (for example on GS), or even just changes a replicated value. The multicast will not run, and the variable will only be changed for the server version of GS and wont be replicated to clients, while if you do the opposite, and from GS you cast and get a variable from GM, and then set it locally, it will replicate properly, same with events...
i would personally move from 4.15 then
if it has such bug
is there a reason you cant upgrade?
oh your making a mod for UT4
nvm
@high current the game mode instance only exists on the server, so if you call a multicast on a game mode it'd not run on the clients
unless you're saying something else
Well, actually yeah, I phrased that badly, you cant multicast on GM, thats logical, but the other thing is very much the case.
For example, I have a variable called NumberOfRounds which I have on GM, and I have to transfer to GS upon game start. If I, from GM, wait till GS is valid, cast to it and set its NumberofRounds to match GM, then GS doesnt replicate that variable to clients. But, if I, from GS cast to GM, get numberofrounds and set it to the local variable, it will be replicated to clients with no issue. Idk, I feel like the first scenario should work, and I have tested in it 4.18 and it does
and if you override init game and set it on GS from GM in the frame GS is spawned
then it will be available on all clients when GS calls its BeginPlay
I am overiding init game tho..
GameMode has a InitGameState function
Not sure if "InitGame" is meant to be that in your discussion
sorry, its in preinitialize components, but init game state override works just as well
Well in the case of 4.15 UT, it does not π¦
And weirdly there is no InitGameState here as well
I have a weather struct in my GameState blueprint set to be replicated. In my GameMode I setup some default weather condition, am I right in thinking this struct is now replicated to all connected clients?
Also, how often will this struct be sent over the network? Is it only when it changes or constantly being sent? It's something that may change every 5 minutes so sending it every frame wouldn't be required.
Afaik, this should work, and it will only be replicated when you change the variable
what is your replicated condition?
@high current Set to None I'm new to replication so just trying to test it out, I'm trying to just log the data to the screen on each client
This is in my player controller
Doesn't do what I thought it would do though, It logs everything in the server window and not on the client
That is kinda useless, if you want to check the variable, just set it to RepNotify, then a function will be created, within that function you can run the print string
RepNotify will execute the function as soon as that variable is changed and recieved by anyone who needs to recieve it
Ah ok, that sounds perfect
Are there any tips on choosing between Replicated instead of RepNotify?
Also, is the OnRep_Weather function called on each client?
yes if the client recieves the update, it is called
RepNotify is preferred over replicated only if you intend on doing any logic right as soon as you get the variable.
Thanks @high current
np
I'm trying to keep it simple to get my head around replication, for this test I just want to update the hud for each client to show the new weather, the game mode is responsible for changing the weather over time
So OnRep_Weather is where I would get the player controller and call my function that updates the UMG widget with the new values?
yes, that is correct
Hmm, wondering what is the cleanest way to do the following: event based hud, which does something when a state in another actor changes. Talking about my precious capture points again. All of their logic is based on one RepNotify. So whats better, at begin play on the version of the capture point, save the hud reference, and then on the RepNotify, just execute events from the ref. Or use Event Dispatchers? Or something else I haven't though of ofc
c++ invloved?
Nop, BP only
Curious how would C++ change the methodology, still haven't gotten into C++, but I plan to (if i want a job lol)
it has tools BP doesn't
as single manager actor for all capture points, and FFastArraySerializer for FCapturePoiintStates
its capable of per item add/remove/modify callback on the clients
which makes things a lot less messy (and effective)
Interesting, thanks for the info. And as far as BP goes, how would you handle this?
probably a component on the GS, replciated array of structs (capture point ID, status), and an event dispatcher called from onrep that HUDs hook into
its far less elegant but its still robust
and it can be done agnostic of GameState type itself, with GetGameState->FindComponentByClass<CapturePoiintManager>
so it would work for different GS types and differnt HUD types, which is a plus
anyone know if creating actor channel/new actor replication is guaranteed to happen before the replication of a pointer to this new actor occurs on the client?
disadvantage is that you'd have no idea what in array changed when its replicated, so you'd have to go thru the entire thing, but a tiny struct and im guessing 5 or less caputre points its ok
its not @manic pine
you can try mitigating that with manipulating net priority, but if you count on that and one of higher priority packets gets dropped, you're fucked
hmm so ReplicatedPointer = World->SpawnActor() could end up repping to the client, but actually repping a nullptr?
it happens frequently with APlayerState* in controllers and pawns
depending on how much stuff you have to replicate
but in those cases, do you get a nullptr rep, or no rep at all?
OnRep fires
In my case, fortunately I don't need to think about different HUDs or GSs, but what I have now is agnostic to both I guess. On the HUD (UMG) I have a initializing function which looks up all capture points present ( I could get it from GS) its all the same... That function creates child widgets according to each capture point, and gives the capture point a ref of the widget(not replicated ofc). Then on the capture point rep notify, it checks if the widget ref is valid, and calls a custom event inside it depending on the info it needs to show.
It felt weird to do event dispatchers, considering I already have a RepNotify which does the same thing...
and its a null
ugh, so onrep with nullptr
yeah, thats what i feared
maybe theres a way to force the channel to open first
RepNotifies don't really check if you have the same value now as the old one
xenonic tried the other day, apparently it did not go well
and even that, your packet can still get lost
wouldnt this be considered 'reliable' though and thus be guaranteed to be ordered?
or is that only per channel
if you're replicating a bunch of actors spawned in single frame
they will arrive on the clients in order of NetPriority
high to low
but that doesn't protect you from one of those packets getting lost
alright, thanks
its the same effect as forcing an actor channel
unreal will try to replicate them in your desired order, but...
@high current GameState does feel like the place you'd want to keep track of and replicate the score from
high packetloss settings should let me produce this behavior then ye
i am currently running an experiment with NetPriority 4 PlayerState
its been a few months and i didn't catch one occasion of it failing to arrive before the Pawn
disclaimer: the game hasn't been thru any but casual testing during the entire period
but you have tried packetloss sim then i assume
i don't entirely trust the editor there
yeah its one way isnt it
i did put in an ensure in that onrep
In theory yes, but for the capture points I skipped it and went straight to GM, with a single dispatcher which runs and event if a point has been captured. Why, cause on that event I change the game score, which only GM has write access to any way, and the score is already replicated and known to everyone in their huds
yeah not sure why they'd do it that way
probably easier
i discovered today what a joy a static delegate is for single process PIE testing
π¦
yes, it gets shared between all "instances"
haha yeah thats a fun combo
How do you deal with minor jitters when playing on a server? I sometimes get them when I stop moving or switch direction. Not all the time though. Might be a ping issue as I get them in other ue4 games like fortnite if my ping is above 80
@potent prairie theyβre client mispredictions where basically the server sends a correction because it thinks youβre wrong
If you turn on p.NetShowCorrections 1 youβll see them
And yeah the higher your ping the more potential for corrections
So is there a way to completely stop that from happening
well, it's impossible to never have any corrections, but if there's like specific actions you've added that seem to be correcting a lot, that might mean it's not implemented in a network-friendly manner
and there are some parameters you can tweak to maybe reduce frequency of corrections also
and there's tricks to try to hide it so you don't notice the corrections as much
but in a server-authority game there's always going to be corrections from the server, your goal is just to have them be low frequency at reasonable pings
any resource recommendation on setting up a database for my game?
Seems really weird that just moving around would cause corrections. I dont get them every time which makes me think it might be the server not performing well. Or my internet wifi haha
it likely isn't server performance
wifi is trash for internet
well, for gaming that is
because it's going to have packet loss and inconsistent speeds
unless you live in a place where you have the frequencies all to yourself
Or you might have custom movement in effect, do you have that?
I did make a custom movement component and it helped, I also made some changes to the config files for network and that helped a ton, but I also need to test with an ethernet cable so I'm not going to touch any code until I do that
im unfortunately away from my house for a few weeks so working on wifi haha
its 100% my wifi lol skipping all over every game xD
only its supposed to work over wifi
i was getting like 30 packet loss in fortnite so basically unplayable
Do you guys develop your multiplayer games with packet loss in mind? I'm not too familiar with packets loss, or out of order, or stuff like that. I have only taken latency into consideration.
Does anybody here have Experience with node.js? Got a question there
I have a ΓO object I declared. I woudl want to call that io objects io.emit function in other .js file. I just cannot get reference to it :/.
I used module.exports = io; in bottom of the file and required it other file : let www = require('../bin/www');
but then I type www.io , nothing comes up
did you included your other.js file?
what is www?
its folder
?
you have also var io in this file
so maybe you have same function name declared in both files
I included it in other file with let www = require('../bin/www'); www is the default file created by Express framework, where the server is started etc.
*when the server is started
It generates stuff like this.
I originally tried to start my socket.io in different .js file, but I stumbled into same problem. I could not get access to the server object that is created in www file.
so I started my socked inside www where server is declared
@worthy perch well, the main thing you can control for packet loss is making sure critical RPCs are flagged as reliable, but I mean ultimately if the packet loss is more than a couple of percent most network games are going to have a bad experience
is there anyone who is using gamelift, l would like to discuss some questions about it
does anyone have experience with amazon lambda and ue4 http requests?
anyone have any idea why the Steam netdriver doesnt want to load when i do Launch Game but instead falls back to IpNetDriver ?
yet packaged build works
nvm fixed it
Is this something that should be happening?
This is a VR Multiplayer project and most of the ms are coming from CPU Stalls while profiling that game.
that just means the thread you are looking at is idle waiting for work
find one that is actually busy
what do you guys use for backend/database?
@thin stratus just an update on the world origin stuff/rebasing... Tried making it work in the 3rd person template but it keep causing desync between client and server, so I guess thats not the way to go at the moment :P(I might be missing something though)
I have one of the usual crazy multiplayer bugs I can't troubleshoot. I overrid GameModeBase::HandleStartingPlayer() in this way ```cpp
void AVVGameModeBase::HandleStartingNewPlayer_Implementation(APlayerController* NewPlayer)
{
auto NewVirePlayer = Cast<AVVPlayerController>(NewPlayer);
// If players should start as spectators, leave them in the spectator state
if (!IsLobby() && PlayerCanRestart(NewPlayer))
{
// Otherwise spawn their pawn immediately
RestartPlayer(NewPlayer);
if (NewVirePlayer)
{
NewVirePlayer->EnterGame();
}
}
else
{
if (NewVirePlayer)
{
NewVirePlayer->EnterLobby();
}
}
}
Is Lobby is a method that checks if I'm in a specific map. When in the lobby I do a seamless travel to the real game map and this is run again, this time entering the other codepath. Now I have a problem. In my controller I have the following implementations for EnterLobby and EnterGame ```cpp
void AVVPlayerController::EnterLobby()
{
Client_EnterLobby();
}
void AVVPlayerController::Client_EnterLobby_Implementation()
{
if (IsLocalController())
{
InitWidget(wJoinDialog, JoinDialog);
}
check(JoinDialog);
}
void AVVPlayerController::EnterGame()
{
EnterGame_Internal();
Client_EnterGame();
}
void AVVPlayerController::Client_EnterGame_Implementation()
{
check(IsLocalController());
if (JoinDialog && JoinDialog->IsVisible())
{
JoinDialog->RemoveFromViewport();
}
// [...]
}
My problem is that JoinDialog, in the 2nd call is nullptr, but the widget is there on the screen. Any clue?
Non seamless travel works
and local play works
doesn't it make a new player controller object when you travel to the next level?
when you do seamless travel the controllers are persisted
I wonder if it persists all of the controllers properties or just the default ones
fact is, the widget is still there π¦
Am I wrong to assume that UStructs are replicated as a whole atomically, and not piece-by-piece ?
there is limitation to the payload size of a network packet. tho i guess this is not what you mean by your question
I mean, if I have a replicated Ustruct and I change two values on it, am I guaranteed they will be replicated simultaneously ?
Or can I get bool A first and then bool B a frame later
hope not
Same π¬
There's an atomic meta flag for ustructs iirc, otherwise I believe it's not guaranteed
@bitter oriole
Thanks
Does anyone know why my dedicated server game fails on the actual server, but works in my personal testing? I thought I just needed to check the box for dedicated server and it would run what was needed. Do I need to use the project launcher to actually compile and run a server version in the background to keep it up? And then connect to my localhost IP?
This error does not happen on my pc
Or .. I can't get it to display in the message log, and my client doesn't crash
@scenic raven one word of advice, dont handle widgets like that :D, Widgets should be handled either in local player, gameinstance or something else
something more persistant
also why is your player controller handling lobby joins?
thats the job of the GameInstance
@limber mortar you need to compile the dedicated server using the source build
and create dedicated server target
I do
I have the dedicated server running my game, people can connect and play. I have a 8 core desktop with 1080 card running the source build
I use project launcher to cook, visual studio, then package the project in UE4 source build
I'm adding new components
Well i never seen that particular error message before, but judging by the message it is something like you're running different versions of client / server and they are in a disgreement about the replicated informations.
anyone's used the VaREST plugin? I was wondering how reliable it is
Iβve got a weird issue in a UE4 replicates game. Iβve been testing in editor, and Iβve been having weird replication events where functions wouldnβt call, and other just bizarre stuff. For example, an enemy or the player will go immune to damage for a period of time. I canβt explain this, Iβve checked everything, and it seems to be a dedicated server replication issue, but Iβm testing in editor with zero ping. Is this a known thing, is there a simple fix?
It is most definitely a bug with your code, not a bug with the engine.
Could almost be a problem with you using an Unreliable RPC.
How could I try to fix that?
Thats a guess mate, you havent posted any code at all so there is no way i can recommend you to do anything.
Ok, I was thinking this had to be something simpler than that... one sec.
Take damage, which seems to not always be called
It's pretty simple, it just detemines whether to take damage from HP or shield, takes that, and then does some UI stuff and prepares to regen.
Other than that, it's little gameplay stuff that's working, when the function is called.
You do know there is already a built in Damage framework?
Yes, I do.
So why are you using your own?
I just didn't think of using it at the time. Is there something it does far better than a basic reliable event?
It provides you with much more information about the Damage, there is also 2 types of damage you can apply.
Radial and Point damage.
As long as you apply damage on the Server you dont have to worry about silly RPCs
Which means changes to Health variables can be easily replicated.
When applying that damage.
Avoiding your current issue entirely.
Ok, let me quickly switch some stuff around.
Is there a difference between "Executes on Server" and the OnlyOnServer from the default damage function?
They are both saying that whatever your calling can only be executed by the Server.
Ok, it seems switching it is not fixing the issue... My simple damage function is set to Run on Server and to be reliable, it has a priority of 3.
With zero ping time and under 50% processor usage it seems to me like this shouldn't be such a huge issue.
Regeneration is being disabled before damage, so health can't be modified in two places at a time.
Testing more, the enemy that is giving the most issues has an AOE ground attack and a projectile attack. Each on their own does not cause issues, only the two paired together. It doesn't seem like that would be enough replication to cause issues.
Thank you for your time.
question. im trying to replicate a variable for each player on the server and im wondering if im doing something wrong or if its because im testing in the editor(as dedicated) with multiple clients.
i have my variable hunger that is replicated, and a server function that lowers the variable by X amount when called
void ASCharacter::SetupHunger()//called via a timer
{
if (Role < ROLE_Authority)
{
UE_LOG(LogTemp, Warning, TEXT("Has NO Authority: %s"), *this->GetName());
ServerSetHunger();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Has Authority: %s"), *this->GetName());
LowerHunger(HungerDecrementValue);
}
}
void ASCharacter::LowerHunger(float Val)
{
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, "Before Hunger: " + FString::SanitizeFloat(Hunger));
Hunger -= Val;
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, "After Hunger: " + FString::SanitizeFloat(Hunger));
if (Hunger <= 0)
{
}
}
bool ASCharacter::ServerSetHunger_Validate()
{
return true;
}
void ASCharacter::ServerSetHunger_Implementation()
{
LowerHunger(HungerDecrementValue);
}
heres what shows up in the log and on screen when it runs. the hunger for testing is suppose to lower by 3, but its like it runs twice each time and shows the clients both having authority and not having authority(unless thats just when the client runs it and the server runs it). would testing strictly in the editor cause these results?
https://gyazo.com/755a685c87fcdd303fc2bd23d92ea2e3
https://gyazo.com/91ad564e8ccf2aa0a8df8540ef15f597
@ocean geyser HUD debug strings are shared with all viewports in PIE
So yeah that's an editor issue
derp, well thats good to know
Mostly multiplayer testing sucks in editor
what would be a reliable way to quickly test MP
Best to launch two standalone instances and have them join
thank you sir, hopefully that fixes the frustration
Anyone has experience running listen servers with seamless travel ?
with or without steam?
Doesn't matter really
Trying to understand if a listen server creating a new session should use ServerTravel, and if that works with seamless travel
Getting some weird HUD crashes
@bitter oriole
Lol sorry
I was using my phone one handed and it @ you all on its own
Not sure how
The Galaxy curved screen makes it too easy to touch all sorts of stuff without meaning to
on mobile just touching someones name inserts the @grand kestrel
even if it's arleady there
Must have simultaneously bumped his name + enter, they're both on the curved edges
Anyone got an idea on this listen server + seamless business ?
Hi! sorry to bother you but, does anyone know why characters stop replicating movement mode when they are attach to another actor? is it possible to fix that?
How could they replicate movement if they're attached ?
because that other actor is a movable vehicle, but i want players to be able to move while being inside it
and default player movement base doesnt work well
I've never used the character movement component before, but this is generally not easy to do at all
i know hehehe
@bitter oriole What do you need?
Well, I'm trying to move my travel code to seamless travel
Right, what part is not clicking yet?
But doing that crashes immediately when I create a new session as a listen server ; it looks like something really weird happened with my HUD class
Well, SeamlessTravel is only for ServerTravels
Right
Neither Hosting, nor Joining counts as ServerTravel
I am indeed using ServerTravel to move from single-player menu to listen server game level - maybe that's the problem ?
Both are HardTravels
At least I've never tried/seen someone SeamlessTravel from MainMenu to a Listen hosted game
So, if I understand correctly - ServerTravel does seamless or not depending on gamemode::bUseSeamlessTravel ?
Or does it does seamless or not depending on the URL ?
It should be Seamless Depending on the boolean
But a MainMenu GameMode is, at least on my end, never marked as seamless
Right, so I just need to uncheck it on my menu.
Connecting and Hosting are both HardTravels
Once your Server is hosting and on the gameplay level, you can start ServerTraveling
I'm aware that all server / hosting state changes need to be hard travels
I'm just wondering if I need to change that bool everytime I'm going to call ServerTravel
Since, like, going back to menu from a listen server game can't be seamless either
Or should I use UGameplayUtils::OpenLevel instead ?
I'm using OpenLevel for HardTravels, yeah
in c++ that's actually called ClientTravel
Well there's actually UGameplayUtils::OpenLevel
Which OpenLevel ultimately also calls
So, let's get this straight, ClientTravel would work for hosting a game ?
void APlayerController::ClientTravel(const FString& URL, ETravelType TravelType, bool bSeamless, FGuid MapPackageGuid)
{
// Keep track of seamless travel serverside
if (bSeamless && TravelType == TRAVEL_Relative)
{
SeamlessTravelCount++;
}
// Now pass on to the RPC
ClientTravelInternal(URL, TravelType, bSeamless, MapPackageGuid);
}
/// @cond DOXYGEN_WARNINGS
void APlayerController::ClientTravelInternal_Implementation(const FString& URL, ETravelType TravelType, bool bSeamless, FGuid MapPackageGuid)
{
UWorld* World = GetWorld();
// Warn the client.
PreClientTravel(URL, TravelType, bSeamless);
if (bSeamless && TravelType == TRAVEL_Relative)
{
World->SeamlessTravel(URL);
}
else
{
if (bSeamless)
{
UE_LOG(LogPlayerController, Warning, TEXT("Unable to perform seamless travel because TravelType was %i, not TRAVEL_Relative"), int32(TravelType));
}
// Do the travel.
GEngine->SetClientTravel(World, *URL, (ETravelType)TravelType);
}
}
void UGameplayStatics::OpenLevel(const UObject* WorldContextObject, FName LevelName, bool bAbsolute, FString Options)
{
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (World == nullptr)
{
return;
}
const ETravelType TravelType = (bAbsolute ? TRAVEL_Absolute : TRAVEL_Relative);
FWorldContext &WorldContext = GEngine->GetWorldContextFromWorldChecked(World);
FString Cmd = LevelName.ToString();
if (Options.Len() > 0)
{
Cmd += FString(TEXT("?")) + Options;
}
FURL TestURL(&WorldContext.LastURL, *Cmd, TravelType);
if (TestURL.IsLocalInternal())
{
// make sure the file exists if we are opening a local file
if (!GEngine->MakeSureMapNameIsValid(TestURL.Map))
{
UE_LOG(LogLevel, Warning, TEXT("WARNING: The map '%s' does not exist."), *TestURL.Map);
}
}
GEngine->SetClientTravel( World, *Cmd, TravelType );
}
It both ends in GEngine->SetClientTravel
So yes
As opposed to ServerTravel, which I currently use for starting the server
OpenLevel constructs the CMD/URL from LevelName?Key1=Value2?Key2?Key3=Value3 etc.
While ClientTravel needs you to construct that upfront
And ClientTravel is a bit more user orientated
calling preClientTravel etc.
Which e.g. allows you to clean up your UI
So generally speaking - I should be using ClientTravel generally, and ServerTravel specifically for the purpose of changing levels in MP
ServerTravel calls ClientTravel too (for the Clients)
But passes the bSeamless with it
Yeah
Well, thanks a bunch !
From the docs:
UWorld::ServerTravel
- For the server only.
- Will jump the server to a new world/level.
- All connected clients will follow.
- This is the way multiplayer games travel from map to map, and the server is the one in charge to call this function.
- The server will call APlayerController::ClientTravel for all client players that are connected.
Anyway, g2g take care of the doggo
The "server only" line confused me into thinking I needed it to start the server
Thanks a lot
What's the best way to go about replicating PlayerName in PlayerState to clients?
Should I create a separate MyPlayerName property that copies the value of PlayerName on server but is replicated?
Or maybe store it as a replicated property on the owned pawn instead (since it's for a name tag system in this case)
I'm assuming I can't make the actual PlayerName property defined in APlayerState replicated without changing the engine source as it's already defined
err
PlayerPrivate is replicated
and is returned by GetPlayerName() function
UPROPERTY(replicatedUsing = OnRep_PlayerName)
FString PlayerNamePrivate;```
the old PlayerName is still there
just dont use it
but use the getter/setter functions
GetPlayerName/SetPlayerName
GetPlayerName also has a way of defining a custom PlayerName
If that is ever needed
bUseCustomPlayerNames = true;
And then you can utilize GetPlayerNameCustom
We do this to maintain the default PlayerName while being able to show splitscreen player names
Very cool stuff!
@fleet raven Sorry?
I'm wondering what the point of the custom player name is
no but you can set it
Yes
FString APlayerState::GetPlayerName() const
{
return bUseCustomPlayerNames ? GetPlayerNameCustom() : PlayerNamePrivate;
}
FString APlayerState::GetPlayerNameCustom() const
{
return PlayerNamePrivate;
}
The second one you can override
oh it's virtual
Yeah the CustomPlayerName one
I guess I didn't consider that someone would use the player name for anything other than like, account name
/** returns current player name */
UFUNCTION(BlueprintPure, Category = PlayerState)
FString GetPlayerName() const;
/** custom access to player name, called only when bUseCustomPlayerNames is set */
virtual FString GetPlayerNameCustom() const;
We use it for both
It has the Steam name in it
But if you start a Splitscreen game, the names are changed to what window you have
Is PlayerName == the steam username by default if using the steam subsystem?
Yes
Great!
PlayerName != Replicated
PlayerNamePrivate is replicated
PlayerName should have just been removed
its confusing and pointless, and people could just fix there stuff
instead of having stupid bugs if you have stuff link to PlayerName in bp!
Hi! Is anybody aware of a method for multipeer multiplayer on mobile? meaning devices communicate directly over wifi or bluetooth without having to be in the same wifi/lan-network. It would be very advantageous for low latency AR shared world games. (Apple's Game Center can do that easily, but sadly the Online Subsystem iOS is an abandoned construction area since years)
dffffffffffffffffffffffffff why isn't rotation replication and smoothing at LEAST an option on pawn/characters
I'm trying to write some serverside anticheat code that stops clients from sending tons of hits in order to make their weapons stronger. For example, they make their gun fire at 3x the speed.
I have written a validate like this but it detects false positives. I'm assuming because the rpcs can get sent in bursts due to network conditions.
Has anyone done something like this, maybe some burst protection code?
bool ALineTraceGun::ServerNotifyHit_Validate(const FLineTraceHitResult& lineHit, const float ReticleSpread, const TArray<FLineTraceInfo> &bulletTraces) {
// Ensure clients aren't sending hits too quickly
const float CurrentTime = GetWorld()->GetTimeSeconds();
const float Discrepency = WeaponConfig.TimeBetweenShots - (CurrentTime - LastHitTime);
if (Discrepency > ValidateDiscrepancyAllowance) {
UE_LOG(LogTemp, Error, TEXT("Cheat Protection: Client %s is sending hits too quickly %f"), *GetPlayerName(MyPawn), Discrepency);
return false;
}
return true;
}
i mean, you can check how long did it take them to empty a clip
won't catch them every time, but it will soon enough
ahh yeah good idea
emptying a clip in 2 bursts half a minute apart wouldn't trigger the condition
@fleet raven the control rotation it does, but not actual actor rotation π¦
couple of times so far I've been bitten by a character laying down on the client, but standing up on the server o.O
How can I have all clients update their team colors on new pawns at the beginning of each round in a round based game? It works for the initial round as TeamNum gets replicated down from the playerstate and SetTeamColors gets called automatically via the OnRep function. Any rounds past that, the TeamNum is already set, so the OnRep events don't go off again, and fetching the current TeamNum on the Pawn at the start of each round only retrieves it on the local owning pawn, and for no one else
I've tried on both PossessedBy (using a Client RPC) and Restart, but it only ever updates the colors for the local playing client and not the other players
Basically I'm not sure how to get remote clients to run the SetTeamColors function, as it appears to only run for the local pawn (or if the server, everyone)
Does Restart not get called on remote characters?
Maybe I could add a replicated byte that gets incremented each round to force a fresh update and call the OnRep function? EDIT: decided to just set team colors via the OnRep_CurrentRound function instead and it works fine
@sharp pagoda do you remember what the meta flag for atomicity was ? Is it RepRetry ?
@bitter oriole "Atomic - Indicates that this struct should always be serialized as a single unit."
It's not a meta flag actually, just a regular
Great ! Thanks
My spectators are hearing a loud pop when the server changes map in Seamless mode. I've tried shutting off all of my sounds before the travel but the spectator still hears the pop. Any idea what could be causing an audio glitch on Travel?
@sharp pagoda I've never used atomic, does this mean if any of the properties in the struct change, every property in the struct gets replicated?
not sure, the docs are minimal as usual
I'm getting ready to make another attempt at addressing my error. On pawn possession the client crashes, I'm trying to incorporate a marketplace purchase but this developer did his networking different then I laid out mine. The error doesn't appear on my workstation. Does anything in this look off?
I've been told it could be because that start animation variable is showing a different value on the server and client but I haven't been able to pinpoint it yet, doing some more print strings now
do I need to rebuild the dedicated server on visual studio each time I modify the game and want to test it with the dedicated server?
er, I might have made a typo
If you accidently click something wrong in visual studio you can use the ctrl+break it should stop the compilation process
yeah
break?
pause
Yes the button is in line with the printscreen. It is sometimes labeled as pause indeed.
Sometimes i have to click on the build window (where the log is) and press the button there so it will stop
I think I'm not getting something, with the dedicated server option in the editor, how do I know which dedicated server to run
the server pasted in the packaged project works but when I try playing on editor with dedicated server it crashes
Best thing is to fix the reason for the crash
this is when I try to execute the server from the project binaries folder, the package with the server works fine tho
In Editor, you just tick the box for Run Dedicated Server.
You need to show the top of what you posted
There needs to be an actual error
Please post the proper callstack via pastebin for example
None of us can help you without that
yeah i know, its kind of random since the window closes really fast and just throws a lot of info
Log files are a thing
I think that he thinks that he needs to run the Server.exe binaries to run a dedicated server for PIE.
Yeah the window would suggest that
In Editor you indeed only tick the boolean in the advanced play setttings
when I tick the box, it doesn't open the specified level (the open level with ip node) maybe that's expected behaviour
If you tick hte box and press play, you start in the level that the editor has open
Same as without ticking the box
This is not needed
In PIE, by default, Server and Clients autoconnect
You could disable it but that usually only makes sense if you want to test the connection process
Which can also just be tested in standalone of course
I think that he thinks that he needs to run the Server.exe binaries to run a dedicated server for PIE.
This is exactly what I assumed : D
Na. PIE does that all for you
But it sadly sometimes hides some bugs that get visible later
So it's better to sometimes also test packaged
so instead of PIEing with the entry level that connects to the server I just need to open the level to test instead
Essentially, yeah.
But just by the way, there are probably ways to run a standalone dedicated server and connect to it while PIE.
But, you likely don't need to do that.
well no I was just doing it because I thought it was needed, but I played myself lul
thanks both of you
My suggestion is to never leave the PIE
In the sense of don't connect to the PIE from outside
And also don'T connect to something outside the PIE
The PIE works slightly different than a packaged game
Also PIE to PIE is bad
Just stay inside the littel PIE world and if you need to test properly, package your game
ill keep that in mind, thanks again
FYI, you have roughly 15 seconds to press your Cancel Build command before an accidental Rebuild breaks anything.
Cedric
I have an error that I don't get in standalone or PIE, but I get on my dedicated server
Which means I have to take time to package, upload, run, and then see if it works before troubleshooting again. Super inefficient, should I be trying to run a local dedicated server to recreate this instead of just checking the box?
Is there any reason an OnRep function gets called only for some remote clients but not all, even though it should be running the same code for all?
I have a round based game and the player names / team colors are replicated down at the start of each round
On round 1, a random selection of players will get the correct name / team color (sometimes half, sometimes all)
In cases where it's less than all, the second round will make it work for all
Is there any way for it to be more reliable, or some reason it's inconsistently missing?
I am playing in PIE with 100ms ping and simulating a small bit of packet variance which may be contributing to it
properties are always replicated
so unless your doing something funky, they should go through
They always eventually do
Just strangely inconsistent
Sometimes first round
Sometimes second round
No pattern- always different
maybe your changing it too early?
if the other actors havent got a channel
when round 1 starts
Yeah it might be the spawn order or something
It's being called after all players are spawned
But maybe I should delay that by a few frames or more?
Ok will do
for like 1 second
Thanks! Yeah it's just really tricky to test standalone with steam
yup
Because it doesn't let you use VPNs to simulate lag
you could always test it outside of steam
And weirdly any lag solutions I've tried don't work
Yeah that's true
@meager spade Haha that was it
Thanks a lot
When in doubt- delay!
oh sweet
I was able to get the issue to create an error in my event log
hopefully I can troubleshoot now
ok
testing a fix
yeah def test outside of PIE. Especially with multiplayer stuff
If you are doing a pre round countdown, is the correct flow for the GameMode to determine the delay, then tell the GameState to start decrementing the delay
Then the GameState decrements it and when done, calls an event on the GM to start the round?
gamestate should never tell the gamemode what to do
the gamemode should be doing the timer
and updating the gamestate
Heck yeah, I was able to fix my pawn possession problem
@limber mortar Was sleeping already, but yeah you don't have to upload the Server.
If it only happens in a packaged build you could try running a standalone version first (see the end of my compenduim on how to start a dediServer from console).
If it really can't be reproduced outside of packaged builds, then you can of course run the build on your pc
So, looking at a game server transitioning into a new level - the server loads the new level, then the hosting player (listen server here) gets the new level, and it looks like clients only start loading at that point. Is that normal ? How can I make the process more parallel ?
@bitter oriole i believe i had clients load world faster then host on one iteration (without the loading screen) then the server
can't say when they started exactly
but i am sure they would sometimes call NotifyLoadedWorld first
or NotifyWorldLoaded, can't remember that function name
You did something particular to achieve this, right ?
ran the client on faster PC
Basically what I'm seeing is, clients only start loading when the server is completely done loading
failed to compile shaders in advance with dev version
i think that applies to streaming levels
but not for the persistent
no reason to wait for that one, they have to load it anyways
I'm actually reloading the same level right now so it's even funnier
(this is all good part guesswork now)
and seamless travel on my end, for all of it
Yeah, I need to get that working too
My game mode's postlogin fires before its beginplay. Is this normal?
if yes, where should I initialize my stuff then?
like GS, so i can access its stuff
isn't the purpose of beginplay to get fired before anything else?
"fired before anything else" is a constructor
BeginPlay is when the actor enters the world
Login happens before that, for obvious reasons
Gamestate should probably be initialized by the game mode
yes but need to cast and store it in a variable
don't want to cast it again and again
Need to cast what, in which class ?
this is beginplay of GM
I access this variable in postlogin
what's a better place for this?
You can keep it there and cast in post login if you need it in post login
Is it the first player connecting ? Is it a dedicated or listen server ?
its a listen server. And yes, its the first player
Construction script might work, but I'm not even sure game state exists by then.
I'd just keep the cast tbh
Storing pointers to stuff is usually a recipe for problems
so I shouldn't keep a variable for GS?
You shouldn't keep a variable for stuff that's always directly accessible, imho
Just do a "GetGSGameState" function that returns the cast of GetGameState
got it. Thanks for the advice
@flint plaza any c++ involved?
and people have this misconception casts are expensive
casts are only expensive if done every tick
or on a really fast timer
Many times per tick tbh
yeah
people make out that casting is the worst thing ever
FVector .Size is probably more expensive than Cast!
π
I have C++ parents if that's what you're asking @winged badger
you can override AGameModeBase::InitGameState
if you're determined to have it cast then cached
but it isn't advisable?
why i overrode 2/3rds of my GM without calling Super
GameMode needs a complete overhaul
if you want to cast and cache
that is the place to do it
right after the GM inits the GS (Super call)
Awesome! thanks
void AHLGameMode::InitGameState()
{
Super::InitGameState();
HLGameState = Cast<AHLGameState>(GameState);
if (HLGameState != NULL)
{
HLGameState->SetMatchTime(MatchTime);
HLGameState->SetMatchStartTime(MatchStartTime);
// Many more...
HLGameState->SetBotDifficultyLevel(BotDifficultyLevel);
}
}
Yus
Okay so I have a menu level where I travel based on the user settings to a lobby map. Both the levels have the same game state but the variable data is not correct ( i think due to server travel). What's the best approach to tackle this situation?
How do i fix unable to load module OnlineSubSystemLAN
I added this to default engine.ini
[OnlineSubSystem]
DefaultPlatformService=LAN
did i Type it wrong?
is this the general procedure to solve my problem?
"The way I do it roughly is:
-
Before quitting the game, or loading a new level or whatever, in each players state, I gather all data I want to be saved about that player and put it in a single struct (including name, steam id, stats, progress, location, class etc etc) (lets call it PlayerStruct)
-
The server loops through each player state, gets the newly updated player struct and saves it in an array of PlayerStructs. I then save that Array of PlayerStructs to a file.
-
When a new level opens or a game is continued or whatever, every connected player checks their game instance (since clients only see their instance) and sends their own name and/or steamid to the server.
-
On the server, compare every connected players name and/or steamid with every saved index in the array of PlayerStructs from step 2. I basically get each saved player struct, one at a time, break the required info output and compare it to the current player.
-
If a match is found, send the data to the matching players playerstate.
-
Repeat from step 1 when required."
@flint plaza Menu to Lobby is a connection to a Server / Hosting, which is a hardtravel.
Nothing will persist.
Well minus GI etc.
So I should save there?
Map to Map can be done via Seamless Travel
If you have data in the PS that should persist, you can use OnCopyProperties to move them over
As long as this is an actual ServerTravel
And not a Connection/Hosting or leaving
If you need data to persist between server connections and you don't want them to cheat, you could save the stuff in a database and use the SteamID as a unique identifier yeah
If cheating is not a problem then you could just use a savegame or so
Yes I understand why my data isn't persisting
another question: if the GS and PS data persists, then in which situations does OnCopyPrperties come in handy?
PS and GS data does not persist
when you travel, it creates a new PS/GS for that level
thats why you use CopyProperties
to copy stuff over to the new state
GS doesn't have a method to move over data
It's only for the PS
Controllers have a method though
In the GameMode -> OnSwapPlayerControllers
Or so
how do you handle GS data then?
Handle how ?
Game state is the state of the game, it's not supposed to be persistent
makes sense. I'll keep that in mind
is there a way to properly replicate a random value so that each time it is the same as the other players?
using a random float in range from stream kinda works but each time i play the game the variable is the same
If you want the stream to be different from game to game, just init the seed server side, then transfer the seed to players. But I'm curious why you want to replicate a Random call
Unless it's cosmetic, you should probably calculate the random interaction server side then replicate the impact of that random, not the random itself.
(ie. Use the Random to respawn an actor then replicate that actor's position.)
Why multiplayer works when I havent code for replication? :o
You mean your lights? Are you turning them off server-side? Then it would make sense that Unreal has replication activated by default for lights. (But don't take me on it, can't remember for sure)
@waxen crest Look into having your actor's transforms replicated. It will simplify a lot for you.
No probs
@glass plaza i set the transform on server and i set it to replicate but on client it is still default value. how can i fix that?
I wanna assign team to players as soon as they join the lobby, but im not sure how to do it and where to do it. Can anyone tell me howI should proceed with it?
You can do that on PostLogin for example
@waxen crest NetRelevancy might be incorrectly set?
where do i set it?
@glass plaza do i need to make custom events?
ok i found out by myself
Thanks for taking the time to read back and answer my question Cedric, highly appreciated
@thin stratus but how do I keep track of how many players are in each team?
hey guys so I have a client (Client 1) that hosts a session and another client (Client 2) connected to his session. Client 1 is searching for a session using Find Advanced session node from the advanced sessions plugin. How can I send the session that Client 1 finds to Client 2 so he can connect to it?
@meager spade Regarding yesterday when you mentioned I should be running the time countdown timer in the GameMode and simply passing the value to the GameState to update players with (say the current elapsed of a match), does this mean I should have two CurrentTime variables, one in the gamemode that keeps track of the time being set by the timer, and one in the GameState that is replicated and set by the GameMode?
I remember this was the only reason I didn't have the timer in the GameMode before, to avoid duplicating properties
But keeping it in the GameMode does allow me to call the end game state directly, without the GameState having to say "hey the game is over!"
why two CurrentTime variables?
if you have a timer running every X amount of time on the gamemode, simply send it off to the gamestate the current time?
or something
So the GM wouldn't have a CurrentTime?
would it need one?
Well to check if time is <= 0 and end the game
i don't know how your checking for the round
ifg its a timer then no, if its on tick
then yeah
but i probably wouldnt be sending the current time as a replicated value
i would tell the clients, match is starting, this is round time, make a timer on the widget
That's why I originally had it only in the GS as it would keep track of the current time and then report when it reaches 0
then the clients simulate it
Yeah it works that way too but there's the concept of bonus time and also dilation
So things can get a bit out of whack
thats why you update the round time
and the widget checks it, finds out if its changed, then adjusts its time
i dunno, but i would be trying to simulate it rather than replicating a value all the time
albeit a bit inaccurate π
who doesn't have 0 net variance these days?
That is time going up right? So I could subtract it from the total round time on a timer in the GS?
Will probably just replicate the initial round time like Kaos suggested
And then simulate locally
thats what i would personally do
Should I do the timer in the UMG widget itself?
For sure!
thing is no one is going to be like, oh my timer says 30 seconds left but the guy im playing with says 29 seconds
little descrepencies aint gonna matter
Yeah would only really matter if you were off and tried to defuse a bomb or something
yeah but π€· you would have to handle the delay between client/server and come to a nice median, i mean you can fake it by halving the ping time for a rough guestimate, but wont be accurate cause it may take 5ms from client to server but 8ms from server to client
ah yeah true I can do that just to make it slightly more in touch
Would you then decrement the timer inside the widget itself yeah?
After receiving the delegate
wherever really
haha perfect π
That's a good point about the ping different either side btw
Hadn't considered it
Was already offsetting impact results like hitmarker by the client ping
But only one way, not round trip
So if his ping was greater than the standard offline delay before hitmarker, then he'd send the RPC instantly
(I offset the hitmarkers by a short delay like 0.15ms just to make it stand out from impacts and give the impression of some travel time)
So knowing that the time to and from server can be different, is the ping returned from the playerstate the delay to the server from the client?
Ok that works great then
So it's gonna be fairly close to the real result
Instead of a lopsided one way result
Good to know!
Sorry last thing, if I do simulate time locally on the client, can I simply keep the OnRep "CurrentTime" property in GS (Could be renamed to NewRoundTime) but only update it once per round instead of once per second?
It'll only replicate when changed anyway right so I'm still being much more efficient by updating it once per round and then simulating locally
Alternatively I guess I could replace it with a single ClientRPC that gets run at the start of each round, would either option be comparable? @meager spade
when you bind an event in a "run on server" rpc, is that event "run on server" too? or do I have to tell that bound event to run another "run on server " rpc
@red sand With an array of PlayerControllers for example
One for each team
Or, you could go one step further, if you like it nice and clean, you can create a TeamState based on AInfo (actor)
And mark it similar to how the PlayerState works
And create one per team
hey guys so I have a client (Client 1) that hosts a session and another client (Client 2) connected to his session. Client 1 is searching for a session using Find Advanced session node from the advanced sessions plugin. How can I send the session that Client 1 finds to Client 2 so he can connect to it?
@wheat eagle I believe through IP or Steam. I also need help with this.
@wheat eagle If you figure out how to do it, can you help me with it. I can help with other things in return.
I've been struggling with it for some time. Tried sending the bp session result as a parameter or replicating it and i had no success..
Client 2 will always have it set as null
if client 1 hosts client 1 creates a session
and client 2 uses find session
doesn't have it sent over by client1
@winged badger I'm trying to make a party system. Initially Client 1 and Client 2 are in a session (the party) , Client 1 hosting it. Client 1 then searches for a game (another session) and when he finds it, I want them to send the session to Client 2 so the whole party enters the match
@wheat eagle I would use beacons for that, not sessions.
Whole list of resources related to beacons pinned in this channel
this is probably the most common problem here, but i'll try anyway, i'm having an issue where an action (line trace to player, reduce health of hit actor by float) happens from Client 1 to Client 2 but not from Client 2 to Client 1
and which of those clients is actually a host, take it client 1 is listen server?
so client 1 has authority over everything
i see
client 2 does shit only locally, unless he sends a Server RPC
telling the server "hey i did this"
then server can verify, or just execute what client 2 told him to do
and then it propagates to all clients
thanks for the heads up again :P
is there a way to set session name with blueprints?
My multiplayer server build consumes 260 mb ram, is it too much ??
I have a "run on server" rpc on a widget blueprint with dedicated server enabled, when I print a string it says the origin is the client, is this expected behavior?
I'm trying to get a lunge attack animation to work but I read somewhere that in multiplayer games you can't use root animations or something? So what do I do if I want to make an enemy lunge with his animation? Do I move him in blueprint manually? That seems like a lot of tweaking and probably not looking right.
@harsh lintel doesnβt that just run if authority? That might make sense why since widgets wonβt be created on the server and the clientβs the authority for the widget
@cedar finch if itβs a server controlled enemy only, then root motion should be fine
You only run into problems if both the autonomous proxy and server are playing root motion animation, because thatβs hard to synchronize properly
If itβs just AI characters that would be simulated proxies on the clients then it should be fine
Oh ok. So I'm good. I just don't know what i'm doing then lol. https://i.gyazo.com/88b5a50238a6a90b54e4b03e7f8e1ea1.gif
That looks like you need to check βenable root motionβ on the animation
Or I think itβs βextract root motionβ
If thatβs the skeleton army content those animations donβt have root motion extracted by default
You have to extract and do βAnim first poseβ because ref pose will put the skeleton in the ground haha
This is in the animation itself, not the montage
Also the other thing potentially is in the animation blueprint make sure you have it set to allow root motion for montages
The other question is how youβre replicating the montages
Iβm using GAS so that handles that part for me
so if the client is the authority of the widget and I want to do stuff on the server triggered by a widget button I'd have to create an empty blueprint (or an actor idk) and call that blueprint's event from the widget?
@copper mango What is GAS? Also I did the AnimBP setting for Allow root motion for montages as well as checking the root motion box in the animation. Still nothing. I don't think this is the skeleton army model. Its just a standalone character. https://i.gyazo.com/2ad2dd4a347d519dc166b6cfc1eaec84.png
@cedar finch force root lock and enable root motion from montages
GAS is an ability-oriented prediction and rollback framework
you don't need it in this case
@harsh lintel Tunnel your rpcs through the player controller or player for objects that you don't own/not networked
yes
Hmmm I gotta be doing something wrong or I just don't have a proper root bone. https://i.gyazo.com/3472ba2d17372ab5d9b1a1aebfd14304.png
you should be using the epic skeleton with the root at the feet
Yea I don't have that root. I just bought the pack off the marketplace and it came this way. π¦
thanks for the answers @sharp pagoda @copper mango
anyone knows if it's okay to allow account creation on the game client or should I do it through a website? I can't really find an answer to this, most games I've playedf create accounts on a website, at least that's what I remember
i made two branches in my mltiplayer game. the first one checks if the player is overlapping a cylinder and the second one looks if the player has been already warned. if the player is not overlapping the cylinder and hasnt been warned then the game attaches a widget that has text(the warning). why in my multiplayer game when the host or client leaves the cylinder all of the players get the widget?
You could but itβs probably easier to setup the account creation flow on a website @harsh lintel
Then your client just needs to be able to securely login and thatβs it
Is the correct way to override a client RPC like so? virtual void ClientDoSomething_Implementation() override;
@waxen crest have the cylinder send a message to the overlapping player, which internally determines if they've been warned and handles the widget themselves.
ok ill try
yes @grizzled stirrup
Thanks
yeah I forgot it wasn't that simple... Ill just set up a simple registration on the client and remove it when I feel like making the website
@sharp pagoda in the cylinder I got all actors of class, ina for each loop set their IsOverlapping Bool withe the is overlaping function
*and a
the same thing still happens
so, i am currently doing some PIE tests, and my breakpoints hits BeginPlay on PlayerState twice, they have the same name, ROLE_Authority, and controller with the same name. The only difference i can spot is that one is RF_Transactional and other RF_Transient and RF_Transactional
i started play with 1 player
yet, the RPCs are flying all over the place and this situation, not surprisingly, leads to eventual crash
only one of those PlayerState's PC passes IsLocalController check
anyone ever experienced something like this, it seems crazy?
nevermind
someone accidentally checked the dedicated server flag
(for the first time in years)
wait why would the dedicated server break your game tho
it works just like a normal dedicated server
i still don't understand how the above happened
but been at weird locals snapshots for 2 hours now
explains the 2 breakpoints, not why both had Role_Authority tho
(I keep the watch window open with most common ways to get a Role from an Actor, ActorComponent, via Outer, Owner... etc)
saves a ton of time figuring out if breakpoint hit on server or client
and to answer a question why, its a setup level, and i had the PlayerStates attached to Pawn spawn some WidgetComponents
dedi crashed dereferencing one of those
well, widget inside one of those
How can i make only the player that left the cylinder get the widget, not all of them?
i dont have any ideas anymore
please
you'll have to explain your problem better then that
I have a cylinder that overlaps everything. kinda like a fortnite storm. i tried to make it so everytime a player exits its collision(is in the unsafe zone) the player gets a widget with a warning that they are in an unsafe zone. however, no matter what i try i cant make it work on multiplayer, only singleplayer
so only the human player that left the circle should see it?
if (IsLocallyController())
I'll try that
@winged badger Thanks!!!
game instance is like a widget class? the client is the authority?
so I could have a variable in the server's game instance that is set by a run on server rpc?