#multiplayer
1 messages · Page 590 of 1
if the RepNotify was sent out more then a second or two ago
requires having a float timestamp paired with whatever is in your RepNotify
and syncing server time
or you can go for distance check
if your NetCullDistance is 15k
and your sound goes 10k
yeah distance check should looking like a better solution.
it doesn't have to play if the local player is in 10-15k range
FastArraySerializer if you want client to predictively add elements.
@meager spade Thx for the reply, though I'm struggling to find any useful data on FastArraySerializer. What is its intended use and purpose?
server only checks elements are the same. Server doesn't check if elements inside hasn't changed.
@meager spade I didn't fully understand this either. Why is it relevant which checks the server does? Isn't the issue how client is receiving the data?
Solution found @winged badger nothing related with having mesh on map, need to uncheck "Net load on client", so actor can be unspawned as well.
that is generally not great
static actors are generally lighter on the network then dynamic ones
So i should avoid net load ?
any paper on the subject ? struggeling to found any ressource on this point.
Anyone seen any examples of client authoritative physics being implemented in multiplayer games? Like cars you can get in and control in a game or game balls you could catch and throw? I know Fortnite implements this type of system on their vehicles but I haven’t been able to turn up any examples on how something like that is done.
DoHayes no, but you have Smooth Sync plugin who is designed to do thing like this.
oh, client authoritative, my bad.
I think there is AVS or something like this on the marketplace (free) who have a template with client autorative vehicule.
let me found this, one sec.
not sure if it's client authorative but in my memory, yup.
@rotund topaz It's hard to do due to the unpredictability of fully physics driven gameplay vs something like a character capsule's movement. Client authoritative would be a misnomer, what happens when 2 clients disagree about the motion of a shared physics interaction? That's the hard part.
each of us driving our own cars around is easy. What happens when we collide is not.
Yeah I’m just trying to wrap my head around that concept. Everywhere I look I see people saying it’s very hard, which is understandable. I just can’t find any examples of where people have tried haha
Fortnite is all client auth
Yeah I saw that being discussed on the forums. I just can’t find any examples of that type of system.
Anyone got any idea why after I disconnect from a server a specific server is not showing up anymore, to disconnect I use UGameInstance -> ReturnToMainMenu
@meager spade I don't play fortnite so idk how the vehicles are used, but what does it do when 2 vehicles collide head-on? Each client would think the collision happened at a different location. Just sync with server at that point?
iirc from the UDN post i saw, collisions are handled server side
with some checks
i think the client feeds its data to the server
(the driver of the vehicle)
Does anyone know why SessionInterface->DestroySession(GameSessionName); is not working as expected? The thing that doesn't work is GameSessionName if I type in the name of the server directly DestroySession works fine.
GameSessionName when I try to print it my game crashes, is there a chance that I need to set it when I join the server?
When working with CMC - if I want to change a value at runtime, say, max speed, should I change it on server and client? Since it client predicts? Or just server and let it replicate down
What I would do (correct me if I am wrong) you would send the request to the server and then if needs be multicast it to all the clients.
So it is correct to effectively set it on both?
if its MaxSpeed I would say send it to the server and then to the client that requested it only as the other clients don't really care about it
@red musk I'm fairly certain that setting max speed on the server will replicate it out. Try it, it'll take you two seconds to test
It does replicate it - my question is more around best practice on, if the client is doing a thing that will change the max speed, is it better to RPC to the server, and change it only there, and let it replicate, or to change it on client as well as RPC to the server - so that the client predictive side is slightly more in sync?
I.e. trying to avoid micro jitters from server position correction
I'm not super experienced with the CMC specifically
@red musk locally predicting a Sprint is a little trickier than that
Yeah that is what I am experiencing, it is micro jittering - I guess a better question is, what is the better way to locally predict a sprint?
The correct way to locally predict the Sprint is somewhere out there, I remember seeing some implementations. If you wanted to just work without jitter and don't care about latency and activating the sprint, just setting it on the server will work
Hij
How long does it take to make a login system to go online into your game just like an mmorpg ?
Anywhere from one day to one year, depending on your experience and budget.
anybody knows by chance what is the tag i have to add to the macro if i want a member of a struct to not being replicated?
just can't find it now but i read something like that can be done
I am trying to figure out the settings in the editor so that IsLocallyControlled will return true on the player. As of now, the ENetMode returns dedicated server. Do I need to setup the editor to manually connect so that its treated as the client?
a dedicated server can never be IsLocallyControlled.
What i want to know is the fact that for it to work, I need to manually connect to a dedicated server so that the editor is a client?
IsLocallyController will always return true for Pawn possessed by the local PC
and never on dedi
not sure what you're asking here
So when I start the editor, based on my network settings it creates a dedicated server and client for me to connect. when I check the pawn to see if its local controlled its false. I know that a dedicated server is never local. what i am asking is how do i let the editor act as a client not as a server
What version on you on?
4.25
The dropdown next to the "Play" button, click it. At the bottom, you can change the dropdown of the Net mode to "Play as client"
Then you should be connecting as a client. The tooltip for that literally says that it makes the editor a client and a dedicated server gets launched in the background for you to connect to.
not while single process is checked
@meager spade i meant by not replicated is, when you replicate a struct the entire struct will be replicated, i just get a compiler error if i put the replicated tag in the struct members macro, but iirc there should be a way to set some members not replicable, but it might be for uobjects instead
I said that...
hmmm i thought u wanted to ask for clarification since u posted a question mark after 😅
Ah I see whoops
thx then
Hi there, does any one know a cool way to get UDP into Unreal? working with 4.26 at the moment.
How do you mean? All network communication in UE4 is UDP
Unless you explicitly create a TCP socket
how would i read a udp package from a specified IP with an Blueprint?
What are you trying to do exactly?
There's nothing relating to sockets that's exposed to Blueprint AFAIK
i got a camera which sends its Pan/Tilt via udp messages and i want to read those values
You can't do that in Blueprint for sure, at least not with base engine
There's a UDP/TCP socket plugin you could try
do you have a name of the plugin?
Hey guys do you know how to implement multiplayer with login systems , database system , scalable servers with advanced match making , party system , profile systems and anti - cheat system
Can anyone advise where I should create a Session in a Dedicated Server build?
I understand if I was hosting a Listen server I can create the session based off user input, but for dedicated server that starts up straight away where should I put the call to Sessions->CreateSession() ?
nvm I think I found it in the ShooterGame sample - override AGameSession::RegisterServer()
@random compass you’ve basically asked how to make a game in one question. There are marketplace assets you can buy that do this for you if that’s what you need. If you don’t want to do that I advise breaking down your question into it’s parts and seeing if you can find tutorials on YouTube for each piece
How do I replicate an actor's world location?
@plush wave bReplicateMovement true
Hmm but even with that on, when the actor's location is changed on the server it does not rep to the client
Is your actor set to replicate?
actor is definitely created on Server only, and replicates to the client ok, just not updating the position when it is moved by the server?
Hello everyone, I am facing a problem you may have already encountered. In a multi 1v1 game when the client logs in he spends a short time in position 0,0,0 (he looks like he possesses the pawn spectator during this moment) before he plays the pawn and my fade out animation after loading is done.
My problem is that he sees the 0,0,0 position of the map and so he is above the level which I don't want.
Do you have a solution ?
I have tried what I found on the internet including this:
But the begin play of the playercontroller is broken before the end of its execution when it plays the spectator during the short time and I don't have time to dull the camera.
If you have an idea ... I'm a bit blocked (I'm in blueprint)
Build powerful visual scripts without code.
there is an option in PC
AutoManageActiveCameraTarget, and its on by default iirc
when its on, Unreal aggressively sets the view target to what it considers a start spot for that PC
until the Pawn is possessed
Thank you for your answer, i have try to set this option to false; but i don't see any change in my game... Should i do somthing else ?
you can alternatively leverage it
if you have a camera actor
and set it its AutoActivateForPlayer
(1 camera per player required here)
When a player joins a session, is the default behavior for that client to follow the server in level travels?
unreal will agressively set view to that camera until possession is done
also overriding chooseplayerstart, as its ultimately creating a camera at your first chosen start spot
usually takes a little tinkering to get it right @wet cliff
@plush wave most forms of travel will send a client RPC that will cause client to hop along with server
if it doesn't, it will disconnect
But for an RPC to occur, you have to be connected to the server in the first place no?
Guessing this is what "joining the session" is. Connecting to the server?
Thx @winged badger But I think that the problem must be different because when I try what advise me on, I don't see any improvement in my situation.
In fact, when I spawn in the map as a client, before I own my pawn I am not a spectator if I don't tick the box "Start players as spectator" in the "game mode".
I simply spawn in 0;0;0 (i don't know who i am ... no pawn in map) and even if I try to make a fade camera at 0 at that moment (even if I disable my pawn creation to test) there is still a frame where I can see the level.
I do my fade in the PC begin play but it doesn't seem fast enough.
if you possess the pawn right after login/post travel
client will have pawn on begin play
My pawn creation as well as the possess are done automatically by the gamemode based on the player start.
You suggest me not to use the UE standard routine and to make them spawn and then possess manually with custom code?
I don't use after login atm
your problem is i believe
server rpcing the view target
before your pawn repliocates]
Do any of you guys have your code setup to use Sessions in normal PIE multiplayer testing?
e.g. if you start in Client mode do you have the server create a Session and the client join it?
In an ideal world I'd hook these up but I don't really know what mechanism PIE uses to create Client, Server and make client automatically join that server...
I have dedicated server creating a session ok now, but only if I untick Use Single Process
so I need to hook a different function for Listen testing in PIE (and Client testing in single process)
This is a problem that exists in the engine? because when I make a blank map with the default gamemode of UE4 it also exists.
I put down two playerstart and start a two player game.
-->The server no problem it possesses the pawn immediately.
--> The client goes through 0,0,0 for 1 frame before having his character created and possesed (maybe replication time, but i want to hide this clipping frame).
Do you still think it's the server sending an RCP request in that case too ?
I'd suggest doing what many games do, bring up a black UI screen and fade it once everything is setup 🙂
or leave the loading screen up until it's ready
I am in VR and use splashScreen to do that, but when i pop in my new map splashscreen depop automatically :p Because of this ugly frame when i don't posses anything ...
I think you should investigate popping the splashscreen manually
even if you fix the player spawning you can still get ugly pop in of dynamic objects
better to hide it until all actor channels are synced or something like that
splashscreen should stay "on" even if i change map ? with Open level node.
I am using listen server, so i don't know about your issue, sorry :/ i don't have custom code for that UE is doing everything alone.
Is ClientTravel() non-seamless?
btw if i set client fps to the same as server tickrate,
@fervent spoke did you make physic and render independent ? Did you manage to fix your physic tick rate ? How can you be sure that clients will be able to run the FPS rate you have fixed?
I think you should chech "SubSteping" keywords and try to fix you physic tick rate instead of your FPS rate.
Hi, I need your help guys. How to make replicate count down timer ?
hello guys, is it possible that in a cameramanager BP class, a mesh is not getting drawn but is actually in game.. I attached it to the root of the camera manager
Anyone seen any examples of client authoritative physics being implemented in multiplayer games? Like cars you can get in and control in a game or game balls you could catch and throw? I know Fortnite implements this type of system on their vehicles but I haven’t been able to turn up any examples on how something like that is done.
@rotund topaz Are you working on a Netcode like the one implemented in Rocket League (with an input buffer and clients predicting physic with a rollback system)?.
@wind oasis Probably just replicate a float value. Set it to negative something by default. When you want to start the timer, set set the float as GetGameState->GetServerWorldTimeSeconds + CountdownTimerDuration. Do what you need on repnotify, or have client side ui poll the value often to decide what to do.
I will try that
It'd be the most precise timer from server to client because that value should be synced. Alternatively, you'd be relying on something like a multicast which potentially fails from dropped packets, and suffers from latency. So one person's timer could finish a half second or more before another's. With a replicated float someplace like GameState, you just have to set it once, and on RepNotify, check if the float time is greater than the current server time. If it is not, don't bother spawning a timer since it's passed. If it is greater than, just set up a small tear off UI widget that can tick update your widget based on the ReplicatedFloat - ServerTime for remaining time left on the timer.
@bitter talon yes, that would be fine for what I am doing since I don't have many actors to worry about in a given game.
I just cant seem to find an unreal example of something like that
Is there a way to check if a FOnlineSessionSearchResult is a Dedicated or Listen server??
I know there's this session.Session.SessionSettings.bIsDedicated but I doubt this is the way to check it.
what makes more sense - for a player controller to implement prediction on whatever it was controlling, or have the controlled actor implement it?
When doing void OnRep_SomeVar(int32 PrevVar); , does the client use its previously replicated value of that property for PrevVar?
As in say the server changes the var twice in a row in one frame for some reason to two different values, the client will still pass in the last known replicated version of the property and won't know about the "actual" previous value that the server changed twice in a row?
Just wondering, if I create a session how can I grab the session itself, I have an IOnlineSessionPtr but not sure what I can do with it.
@bitter talon i don't have substepping on
i have a theory i need to test though
@grizzled stirrup if server changes the variable twice between updates
client will only get the last update
will have no clue the first one even happened
doesn't even have to be same frame
Any idea why I can't find any more sessions? I changed nothing in the code and when I started it game on both laptops (on one I crated a server) (the other is to find the session) the result was always empty.
It worked yesterday night before I went to sleep.
how can I measure the delay between when a client to server packet was received by the server, and the server's next tick?
e.g. the player can shoot on any of their own frames, a hit is told to the server (event: execute on server), but the server can't do anything with it until a server tick. how can i measure that delay? the duration of time after lag and before next tick.
i can do things like send the clientside time of the shot, but i'll never know if the server and client clocks are actually syncd up
i was thinking on beginplay i can have the client send its time, and then on a shot send the time of the shot, and just subtract one from the other to see how much time elapsed, and use that to compare with the server's clock at the time of the beginplay... but then i have the problem of the server not actually knowing what time the beginplay timestamp was received, since it can only check its own time on tick. so i always have this +/- server tick inaccuracy on timing things coming from the client
i guess i could have the server ask the client for its time on beginplay, adjust by lag, then i know when the client sent that message relative to the server tick (accurate to +/- a client tick). then later when the client sends a timestamp i can compare with that
is there a more accurate or easier way to do this?
just doing a "get real time accurate" on the server and subtracting it by the "get real time accurate" done on the client seems to give a good result, but i haven't tested on a real network connection with multiple PCs and i'm afraid the clocks could be out of sync
but if the server can just measure its own delay between receiving a packet and reaching its next tick, that would be a lot better
Any idea why I can't find any more sessions? I changed nothing in the code and when I started it game on both laptops (on one I crated a server) (the other is to find the session) the result was always empty.
@hidden thorn For F**K sake, I forgot to start steam 🤦♂️
@winged badger Regarding the PrevVar that gets passed into the onrep function- does the client pass in his previously replicated property or does the server also replicate the server's previous value?
Probably the client passes in his previous value to avoid the sever replicating two properties instead of one right?
@grizzled stirrup I don't have a multiplayer project set up to test it out, but it should be fairly easy to find out. With the actor that has that repnotify, set it's netupdatefrequency to like 0.2. It'll only replicate every 5 seconds. Make a quick keypress that tells the server to increment the variable. Log both the PrevVar and the replicated normal Var on rep. Wait for it to log, press the key twice within five seconds to increment the value twice. If PrevVar is what the first Var's rep logged, it's just the variable from the last time it changed.
@grizzled stirrup it will be previous value from the client
Ty both, makes sense!
How to get IP and Port after I open level with ?listen parameter?
Hey guys, has anyone had this issue where clients instead of going to the default map, directly went to server map, without even joining the server, they just browsed what server map they have ?
something deep down is telling me that I should extend player controller and implement prediction functionality there rather than directly on my player class, can someone please save me some time and convince me why that may not make sense?
is Print String behavior prints the string for all Players/Clients' screen on Listen Server, even though the Print String is meant for 1 player only?
for example, if 1 player gets the Print String message, the rest of the clients/players get the same too?
is this how Print String behaves normally?
@unkempt tiger You mean on your pawn class?
@unkempt tiger It really depends on what you're predicting. If it relates to the character, you should probably do it in the character or one of it's components relating to the prediction feature.
@sacred spire Yes that's how it behaves normally. Ignore the fact that it prints on all screens and focus on what machine it says it's running on at the beginning of the print.
I am testing locally, opening the local host, i need to disconnect the clients from the server, Any one know how to do that ?
You mean like kick them from the session or you want them to disconnect when you close the session?
I want to kick them, but there is no session, i have done everything from gamelift, but i want some functionality to test locally.
anyone feel like helping me out with a collision issue I have? It's triggered when I unmount and makes me fall through the ground.. (only on multiplayer. sp works just fine..)
@tranquil yoke What do you mean there is no session? When you try to kick them it tells you there is no session? Also are you using Null or Steam subsystem?
I am using null subsystem. I am using gamelift as my server, but inorder to test locally, i just open local ip address for testing
@hidden thorn I dont have concept of sessions when testing locally
So you have a dedicated server to which you connect and you want to kick players
Blueprints or C++?
Hmm I really can't remember, from what I am seeing is that AdvancedSteamSession does the following to kick the player GameMode->GameSession->KickPlayer(PlayerToKick, KickReason); When I tried it in blueprint GameSession doesn't seem to expose KickPlayer but I do remember there being a Blueprint version of GameSession I think the best bet for you would be to check out the Western multiplayer maybe, not sure if its different when using Dedicated servers as I've never used them myself.
What's the null subsystem? Never heard of that before
Does anyone know if it's possible to join a Session via IP address?
I can join a game just fine via IP address but can't figure out how to connect to the Session (so voice works etc)
I'm using Null OnlineSubsystem
Anyone correct me if I am wrong but I am pretty sure that's what is called.
Inside the config file you have the following
[OnlineSubsystem]
DefaultPlatformService=Steam
OR
[OnlineSubsystem]
DefaultPlatformService=Null
When using Null you are basically using ue4 system, I can't really explain it as I don't full know what it does differently but all I know is that is UE4 SubSystem and you would use that to connect to the same session locally.
@silent valley You're asking if you can join via IP but then you're also saying that you can join a game just fine via IP but can't connect to the session. That doesn't make much sense, which one is it?
Well the terminology is confusing I admit. It's possible to connect to a game via IP address without using the Online system.
However if you want server browser, or voice chat, etc then you actually need to use the Online Session system.
A multiplayer game != online Session
to connect to an IP you just call open <ipaddress> but this will not join a Session. Joining a Session is usually done by calling FindSessions and then choosing one. But can't get the IP address from the search results.
the "null" subsystem is just a super simple join-over-IP implementation that doesn't really use any kind of online back end
But it allows you to test, especially in editor for example
Session Results contain the connection string. when using 'null' it's probably just an IP address
on steam it's steam.##########
With #### being the server ID. Steam connects you via the master server
Thanks @chrome bay - does the Null subsystem work online (i.e. is there a built in master server) or just LAN?
should be able to
I already have my dedicated server running on AWS
and I know the IP which I can connect to, but how do I join the Session...?
Using the session interface you just call join session
But you can't really join a session with the null subsystem, I don't think it supports them fully
Things like "Find Sessions" etc won't do anything
Since there's nowhere to register your session online
yeah.. it's working ok on my single machine but makes sense if it's LAN only
yeah the sessions side of it is LAN only IIRC
so I need to use a 'proper' online subsystem then...
yeah, no escaping that unless you want to build your own master server backend
Probably do-able but meh.. indie multiplayer is hard enough as it is
ok, I've been putting off implement the Steam backend because I don't want to make day-to-day development more difficult. is that something I need to worry about?
Implementing steam takes a few minutes if that, the engine basically already has all the major stuff you need
in the past I've had problems with Steam, like unable to start more than one client on a single machine
yeah you can only have one client per machine
You can get around it by using a virtual machine IIRC
But yeah to really test it, you need multiple boxes
does PIE client/server testing work ok?
PIE client/server just uses null subsystem
ah ok, regardless of what I've setup in the ini file
yeah. to test steam properly really you need to package, distribute to a couple of boxes then get them to connect to each other (or your online server)
but tbh, if you've already done the session stuff everything else is seamless
ok great, thanks for your insights. It's hard to find good information about this kind of thing.
ShooterGame is the best example
Has everything you need
There's also the "Multiplayer Shootout" demo or something that uses sessions
In theory if you enabled steam on that project it would work too
yeah there's a lot of code in ShooterGame tho and I'm not sure how relevent some of it is nowadays
I have been grabbing bits and pieces from it to get the basic Session stuff working on Null
and hopefully, like you say, if it's working on Null then switching to Steam might mostly just-work! 🤞
If I open a level with the parameter "listen", what do I need to do next so that players can connect to Steam? I do not use online subsystem
bool bCanBind = false;
TSharedRef<FInternetAddr> localIp = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->GetLocalHostAddr(*GLog, bCanBind);
FString LocalIPString = localIp->IsValid() ? localIp->ToString(false) : TEXT("");
FIPv4Address m_IP;
FIPv4Address::Parse(LocalIPString, m_IP);
uint16 ServerPort = GetWorld()->URL.Port;
SteamUser()->AdvertiseGame(k_steamIDNonSteamGS, m_IP.Value, ServerPort);
open <ipaddress>
But if I don't have an open IpAddress
u mean from C++, or you don't know the IP address?
You need to setup Steam online subsystem and call FindSessions on the client to enumerate available games to connect to.
This will handle NAT punchthru etc
No, I wrote my own steam lobby system, now I need to transfer the ip and port for players to connect to it, but I don't know the ip and port how to get it?
You can't connect to a steam game without using steam sessions
Steam doesn't give you the IP or port
It gives you a master server string
the master server then connects you
@dark edge Yeah my own character class (that derives from the pawn class), @kindred widget I'm predicting character state - movement, held weapons, pretty much whatever is 'attached' to the character, thanks for replying!
@chrome bay How can I do this without an online subsystem?
when I want a client to call a function for everyone on the server do I have to wrap that function around a ServerRPC or is there a simpler way to do this
there is no simpler way as far as I know
😦
@meager fable EventClient -> Call Server
EventServer -> CallMulticast
EventMulticast -> Spawn Emitter (for example)
it is literally the same thing that he send 😄
Do you guys think that a Physics-based 3rd Person Shooter-like game with the players being marbles (like Marble Blast Ultra or Monkey Ball) would be too complicated to be realistically possible? Only physics involved would be the physics of the balls and any cosmetic physics, most other things wouldn't use physics for the most part.
If it's too much of an undertaking, I'll just look to simulate physics with a CharMovComp like how they do with Wrecking Ball in Overwatch.
I have a good feeling that I'l have to use standard Character Movement, which is fine. Most sources say don't mix Physics-based movement and Multiplayer, so I'll just go with the simpler option to keep the pressure off.
One day, perhaps one day soon, we may have the ability to do physics-based multiplayer movement without too much effort. All hail the network prediction plugin, first of its name!
@unkempt tiger why would you put all the prediction code in the controller class and not in the pawn? That doesn't make any sense.
@dusk spire its just a wrapper around UClass*
@winged badger but what would that mean about how much to replicate it?
in bytes
so wait it is just a pointer?
yes
so 4-8 bytes?
well, full path on the first go
NetGUID for every subsequent one
same as any asset pointer
16 bytes (4*4)
basically what i want to do is make an item that i just store in a struct, which has the properties that can change, like number or quality, and all other stuff which would not replicate, would be stored in one actor if it is needed, so i store the subclass to spawn that actor, and a pointer to the spawned actor
maybe if i replicate the spawned actor itself, then i don't even need to replicate the subclass, only the pointer to the spawned
Should client actors communicate with GameState or the GameMode when the state of the game needs to be checked/changed? For example, if I was creating a multiplayer pong clone the match score would be stored in GameState (or a score on the PlayerState). Now when the ball actor hits a kill volume the game state needs to change by adding a point to the match score. Should the ball actor get the game state and send it a message (rpc) to update the score and check for a win or should the message be sent to the game mode where the game mode then update the score and checks for a win?
if you replicate the actor, its class goes with the first bunch
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ItemData, meta = (AllowPrivateAccess = "true"))
int32 num;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ItemData, meta = (AllowPrivateAccess = "true"))
int32 quality;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ItemData, meta = (AllowPrivateAccess = "true"))
class AInvItem* InvItem;
UPROPERTY(NotReplicated, EditAnywhere, BlueprintReadWrite, Category = ItemData, meta = (AllowPrivateAccess = "true"))
TSubclassOf<class AInvItem> InvItemType;
so this in a struct would work
right?
so server got the subclass it spawns and client gets the pointer
or should i store an id instead and look up from a table? 🤔
cheapest way to replicate
is each item has a FGameplayTag ID
which is also a Rowname for its entry in a DataTable
then you get everything for a single int32
I am working on Steam OnlineSubsystem but is there any guide on how to use dedicated server with Steam?
I have AWS instances running my dedicated servers, will Steam just work if I enable it? 🤞 😺
Do I need a Steam user for them?
Do I need to install Steam on the instance or can I just run the package as normal?
I'm setting my a replicated dynamic material variable like this
its happening on a server RPC event
and then in my multicast play material blend the HandCurrentDynMaterial is none on the client side
how is it possible with a replicated value? Shouldn't it always be equal to what it was set on the server?
The variable is set and get only once so nothing can possibly override it
and the actor is set to replicate
my bet is the multicast arrives first
when the prop is not replicated yet
if you send the values in the multicast im sure it would work
UMaterialInstanceDynamic does not replicate
if your client knows the material asset it needs to create DMI
ohhh okay
you only need to replicate the parameters
if it doesn't then original material asset as well
so I'll just set it on a multicast node
multicast also seems wrong for this
would rep noti be better?
ah yeah i forgot relevancy
So replicate the regular material and create the dynamic material on a client?
well if you don't change the original material then you don't need to replicate that
i think
I change it and then create a dynamic material instance based on it
then yeah
Hey everyone! I got a question for the multiplayer pros: How would I handle collision, hit detection if the player is Prone? I imagine just changing the animation to prone doesnt change much right? Would I need to build a Custom Character Movement component so the player is accurately colliding and hit detected in a multiplayer game?
Honestly, it's usually more trouble that it's worth for attempting
Just set the capsule to be small, and leave it at that would be my advice
But yes the alternative, realistically, is a custom implementation for character movement
So if you set the capsule small will the legs and body sticking out on each side still collide with the world and get hit detection?
I think hit detection is about hitting the body parts, not the movement capsule
That Capsule is used for collision and whatnot.
ok so then, hit detection will work but unless I add collision boxes and logic to the parts of the body outside the capsule it will not collide?
Rephrase that since Hit detection != collision
If you want the character to collide as if it was a capsule on it's side, then you will have to modify the character movement component. It doesn't care what the collision of the mesh is, only the capsule / root component matters
Right. Thats kind of what I thought.
Do you think I could get away with adding collision boxes to the parts of the character mesh that are outside the capsule, and use those to collide with the world if in prone?
Ok. So my Custom CMC would have logic to change the size of the capsule into a horizontal lookin capsule or someting?
you're gonna want a custom player movement solution and use a horizontal box/capsule with a non-identity rotation that you sweep with
If it's any consolation we don't bother with any custom prone collision in HLL
we just set the capsules height to match radius
Using an elongated capsule comes with lots of other issues, like first-person view players getting confused as to why they can't move
@fierce oriole Why do you need the extra boxes? So as not to rotate while prone and rotate the legs through a wall, or?
Yeah and arms through walls and objects
@unkempt tiger ok I need to brush up on C++ then huh? lol
Easiest way in single player to manage that is with a few traces just before the rotation addition to AddControllerYawInput. Limit how much yaw can be added to a call. But that's difficult in multiplayer since that's called on a client. Possibly easy cheating.
It also doesn't feel good for FPP Players who feel like they can't turn or aim anymore once they're up next to a wall
choose the practical way and do what @chrome bay is suggesting, unless your game is a prone simulator
Yeah Im coming to this conclusion lol
trust me it seems like a good idea until you realise it isn't 😄
i can only see it working with a third person game where its clear what your characters legs are hitting
I am implementing OnlineSubsystemSteam and I have a Dedicated server running locally and I am launching a Development game on the same machine, but the game is not getting any Sessions back from the FindSessions.
I stepped through Dedicated server and everything seems ok.
Any ideas?
Can I run steam dedicated server and client on the same machine?
IIRC you can't, I was never able to get them to connect
the steam client doesn't for whatever reason let you connect to your own IP effectively
ok thanks
That being said I also was never able to "find" sessions on steam to another PC on my network either
I had to connect to it manually
but your code worked over the internet?
yeah
damn that makes it a bit tricky 😅
Yeah it's a bit of a pain to say the least.
I think its a port issue iirc. did you try changing the listen port? you may need to setup port forwarding?
That latter part might be something specific to our project
But for the life of me, I couldn't ever get steam to show me the session in our browser
So just had to get the connection string and join via the console
e.g. using open steam.#####
huh... where do you get the connection string from?
So when you launch the server with the -log suffix so you can see the log, it will log the session ID once you host it
and you can copy it from there
I modded our engine a bit to make it easier to read
I'm not seeing anything in the log, but you think in the OnCreateSessionComplete delegate I can log it maybe
That's what I've done yeah
I did it like this to make it readable:
FString IDString = session->GetSessionIdStr();
IDString.InsertAt(5, TEXT("-"));
IDString.InsertAt(10, TEXT("-"));
IDString.InsertAt(15, TEXT("-"));
UE_LOG(LogOnlineGame, Warning, TEXT("HR String: [%s]"), *IDString);
#endif```
Makes it easier to read and enter, as it converts something like 90133455734458697 into 90133-4557-3445-8697
cool, one more question do I need to do anything with the session name?
Currently I'm just using NAME_GameSession
nah just use that
ok and grab the NamedSession in the callback and get the sessionID from that
awesome, thanks man I owe you!
nps
@chrome bay I am logging out the session ID from dedicated server and it looks good.
When I call open steam.<my sessionID> from the client I get some weird log errors and it fails.
LogOnline: STEAM: Adding user 4689287018169106727:7777 from RegisterConnection
LogNet: Game client on port 7777, rate 10000
LogOnline: STEAM: Removing P2P Session Id: INVALID[0x4113B1B2B7D20127], Channel: -1, IdleTime: 0.001
LogOnline: STEAM: Closing all communications with user 4689287018169106727
LogOnline: Warning: STEAM: Steamworks SDK warning: [S_API WARN] CloseP2PSessionWithUser() failed, invalid steamID [U:65:3083993383]
where 4689287018169106727 is the session ID (not the user)
not sure to be honest, welcome to the hell of digging through log files 😄
It might be worth enabling as much log verbosity as you can and/or stepping through code in VS
but ofc if you are connecting to a server on the same machine, it will more than likely not work from experience
can't step into Steam online plugin for some reason :(
ok I just wanted to check that open steam.SESSIONID is the correct console cmd to use
or if there's any docs about this cmd, or even how it gets routed to the online SS
Hey Jambax. Do you happen to know what could cause a typical FPS camera to jump a bit when going over or under 0 pitch level? Seems smooth between 90 to 0 or 0 to -90.
But when crossing about 0 it kinda jumps.
Asked this earlier but it might have got lost, I'm trying to figure out if clients should tell the game state something happened or the game mode. I've found numerous posts about this but they all seem to say different things.
Should client actors communicate with GameState or the GameMode when the state of the game needs to be checked/changed? For example, if I was creating a multiplayer pong clone the match score would be stored in GameState (or a score on the PlayerState). Now when the ball actor hits a kill volume the game state needs to change by adding a point to the match score. Should the ball actor get the game state and send it a message (rpc) to update the score and check for a win or should the message be sent to the game mode where the game mode then update the score and checks for a win?
@kindred widget possibly a gimbal lock issue I suspect
GameState @haughty estuary
Clients can't access the Game Mode
via rpc* ??
no clients can't call RPC's on the gamestate
The server should be what increments the score
Yep that makes sense, so how does the client tell the server to inc the score?
I thought I could have a run on server event in the ball actor that is called when it's killed
@silent valley UGameInstance::HandleOpenCommand() is what parses and deals with the open console command
Well a client wouldn't tell the server to increment the score, the server would just do it
because everything would be tracked server-side
Ah, I see
same as with killing it
I need to get out of my web development mindset
So, I should switch on authority in the ball actor, if it has authority then inc the score in the game state
well, call a function on game state that does what it needs to do
or should i call a function on game mode
So, having code like this in the Ball actor is what I thought I needed. The EnteredGoal event is fired when the ball collides with a the volume box, the last hitter is updated every time the ball bounces of a players paddle.
@haughty estuary technically game mode and game state could both work. I would prefer to have the logic live in game mode and have game State just be a container for, well, State
So the game mode would then validate the goal scored and update the state accordingly? I somehow thought the game mode was responsible for the flow such as start in the waiting state, transition to playing when 2 players have joined, transition to end state when a player has won and it's responsible for the rules of the game such as a player wins when they reach a certain score
But the actually score management might have been shifted to the game state object instead of using the game mode which would then have to delegate to the state object to update, but I'm more than likely thinking about this wrong or the documentation isn't sinking in so well
I know its a long shot and I am sort of already presuming its a big NO but gonna throw it out there anyway. Using the Steam OnlineSubsystem is it possible to create a cross-platform game between Desktop & Mobile (Ignore console) This is for ListenServers not Dedicated
does steam support mobile?
if it does, then sure, if not, then no.
If you need cross platform, consider EOS
Idk what EOS stands for but don't type it on google 🤮
I personally would assume that if you have steam installed on your phone it should use that to talk to the master server and join you on a server (But this is besides the point)
Also what is EOS ??
Ah interesting, won't be using it as its not what I am looking for. I only asked because I was curious how it works and how one would do it, I don't need it for my game or anything.
Aside from that does anyone know why when I set SessionSettings->bAllowInvite to true, the session can't be found anymore?
or just click the channel below this one 😄
I saw it, but my question is more about if people did something like that themselves
I was just wondering if I can run CreateSession&StartSession asynchronously as right now when I press the button to create a session it freezes for about 2-5sec and then I am into the session.
Hey go you know how to add voice chat for free like a plugin or something else?
EOS will soon support (if it's not already) voice chat
Hi, how to i hide an actor from a specific player?
The rest of the players should be able to see it
@mighty zinc What is the object? What is it's general relation to things?
Its like a tunnel
So when the player passes thru it
It should be hidden from that specific player
Can the player go through it multiple times?
Yes it's like a tdm
I mean, hiding it on the client would be fairly easy. Just a little vector math based on the owning client's character in relation to the tunnel entrances.
That wouldn't stop them from being able to go back through it on the server though. Not without some form of one way collision or something.
I Transform Modify (rotate) my spine instead of using an aim offset, with TryGetPawnOwner -> GetControlRotation. Works smoothly when looking around
HOWEVER, if I use a variable from my character that is set to ControlRotation every Tick to rotate spine, I get bad stuttering when looking around
BOTH methods should be exactly the same. But one causes this horrible stuttering
Does anyone know why? There must be something really strange about how Animation Blueprints function
Hard to say without seeing it. I don't remember why, but I had some issues using Control rotation. I had to switch to BaseAimRotation.
I'm still just getting started with multiplayer thought I would start simple but already I'm failing 🤦♂️ I setup a simple pawn that changes material when pressing the space key then started up a listen server and a client. I can see the two pawns are spawned, when pressing space on the listen server i see the change is visible on the both instances but when pressing space on the client the change doesn't seem to be shown on the server instance. I'm using multicast which I thought would work but obviously I'm wrong. Could someone spare a couple minutes to help me finish this test correctly please. I've uploaded a video of what I'm seeing and the blueprint graph responsible https://s3.eu-west-2.amazonaws.com/hendore.com/videos/replication.mp4
@haughty estuary Can't replicate from a client. Your Spacebar should call a Server RPC. ServerRPC event should call multicast.
Actually ideally, server RPC should set a variable and replicate it and the repnotify should change the material, just to keep state safety.
ah ok so I have to create a couple of events for this to work?
Just a server rpc.
Does that mean change from multicast to run on server?
For both BecomeEnraged and CalmDown?
The way it works is that the client presses a button, the event fires on their machine, Clients can only ever communicate with the server so you call a server RPC. Server can then update the state on the server, and either replicate values back, or call multicasts to all clients.
@haughty estuary Try something like this for starts.
@kindred widget I was about to post basically the exact same thing lol.
Ah ok so even though the static mesh component is setup to be replicated, when the server changes the material that change wasn't replicated so I have to create a separate variable for this to handle the notifications?
Nah, don't replicate the mesh. Leave it to the clients to change their own state based on replicated properties as much as you can.
Ah ok that's a fair point 👍
Also, especially for state based things, don't multicast. Multicasts aren't updated past their initial send. Replicated variables are always updated when the actor becomes relevant to the client.
hey do you know how can i make a voice chat without using the steam subsystem?
@kindred widget thanks bud the replicated variable works perfectly, I was just being dumb thinking the static mesh component being replicated should have been enough, thanks for the help.
Is it best practice to always prefix those rpcs with Server?
the server and the client doesn't show the same hp ,so sometimes the client has a little health but on the server its shown as 0 how to sync that ?
only multicasts
how can it send client and server rpc's if its not owned by anyone? (well technically its owned by the server..) so listen server maybe able to recieve/send rpc's from it. but other clients, no.
😄
any client/server rpc must go through an actor which has an owning connection to the one doing the RPC call. Like weapons in my game can send server/client rpc's but only cause its owner is the player who has the weapon
GameState is fine with replicated data
(properties, etc)
that is it's purpose.
RPC's will have to go through like the PlayerController
which is where i do most of my RPC stuff
@dull lance like give an example.
Good luck, that sounds extra f*****.
Yeah to me stuff like Gizmo handles and all that should be routed through the controller. You think about it, they are the controller, while the world and the game state are the model/view
When I print my character's ControlRotation in tick and EventBlueprintUpdateAnimation, the values are different if I am moving my mouse fast enough. Why is this?
If the animBP ticks right after the character, shouldn't the control rotation stay the same?
i'm trying to do prediction of ability costs (not using GAS). my latest idea was to have predicted costs and gains stored on the client, that each had an ability cast ID that they were the result of, then when the server confirms that cast ID as either a success or failure, I can update my resource to no longer reflect the costs/gains associated with that Id. I'm not sure how to cleanly do this, however, as the ability system is pretty self contained and resources are their own thing. While it's pretty easy to set up an array of structs representing the costs/gains tied to ID numbers, there's no way to know that when the server confirms or denies a cast, the replicated resource value I have is pre-cast or post-cast, since i don't know whether the resource replicates first or the cast replicates first
that might be a bunch of gibberish, but mostly i'm just wondering how you guys cleanly handle prediction and rollback for something like resource costs and cooldowns
How can I make a client possess an actor which was spawned on the server?
So it replicates to the client?
But isn't the client essentially possessing its own pawn?
Oh then can you help me solve this.
So let's say a client wants to change their pawn into something else.
At runtime.
How exactly should they go about doing that.
So its replciated to other clients as well?
Yes but it's not really a change it's more like a .
Destroy the previous pawn.
Create a new pawn.
Possess it.
Oh okay
Yes
that happens on the server
But does the server call possess?
Hmm should the server grab that clients
player controller
and call possess on it
For that pawn?
I understand that much. But if the server wants that client to possess the newly created pawn. It can't call possess on its own player controller.
It has to grab that clients yes?
That's exactly what I said...
". But if the server wants that client to possess the newly created pawn. It can't call possess on its own player controller.
It has to grab that clients yes?"
The server grab's the clieitn's (JohnnyXD) player controller
And calls possess on it.
Oh
I misswrote that
It meant to write
It can*
Not it can't
That was a typo on my part
not your fault
sorry
But yes that helps a lot thank you
Now the question is, how does the server grab that client's player controller.
I'm thinking the best way would be to grab its player state,
Grab its unique id from the player state
Then iterate my player controller list on the server
and if the state unique id matches,
That's the player controller I need
Because I don't believe Pawns and player states have a player controller reference
oh okay thank you!
is it a good idea or bad idea to replicate a struct that represents what the client needs to know of an object rather than replicating the object itself? i'm using this kind of setup right now for stats, where the server has an actual stat object that internally handles any modifiers and changes, calculates its own value, etc., and the client is just getting a replicated struct with the current value and the stat tag. I'm also planning on using it for resources (mana, energy, etc.), where the server has a resource object that handles spending and gaining resources, modifying max and min resource values, and handling its own cost modifiers, while the client will again just get a replicated struct with current, max, min, and tag instead of the whole object. are there any issues with this? is this something you guys would advise for or against?
@vivid seal that is fine unless you overcomplicate your life with it
also, if your object is replicating the struct
you're still replicating the object itself
so it comes to convenience when it comes to your code, it won't save you much (if any) network resources
The object replicating the structs is basically a manager component, that just replicates the state of each of its managed objects as a small struct instead of replicating the objects.
if you're replicating them outside the object
then savings can get significant
provided your small struct has a weak pointer to the object and it inherits from FFastArraySerialierItem
because in that case you get a working push model
For stats, I have a StatHandler component that is responsible for spawning and initializing all the Stat objects on the server. It also handles all addition and removal of stat mods. It uses a FastArraySerializer to replicate the state of each stat object to clients, who basically only have a map of Stat GameplayTags to current state structs.
thing is
you get significant gains
only if your manager component does the entire replication for an Actor
as then that Actor doesn't have to be replicated at all
and as such doesn't need to be evaluated for replication at all
which makes your network respond far better with 300+ replicated Actors in the world
I wasn’t aware components could do anything with replication without their owner replicating
they can't
but if you have an Actor that needs to replicate just a few stats
and nothing else
then a specialized Actor can do all its replication instead
in any case, if you're replicating min, max, current
you can pair a FGameplayTag with a compressed vector
instead of running 3 floats
How do I get a compressed vector? Is it it’s own type separate from FVector, or do I need to call some kind of compression function on an FVector before it replicates?
FVector_NetQuantize are derived from VEctor
so
you can use them the same as FVector
they just have NetSerialize function overriden
and you toss your min into X, max into Y, and current into Z, or w/e
Okay cool. I will check that out tomorrow. Right now I just have a struct that is a GameplayTag and 3 floats.
i use NetworkManagerActors
to replicate my Interactable Actors in their entirety
a larger map will have 1500-1800 or so Interactables
NetworkManager has fastarrays that know how to replicate contents of interaction components
and they can carry a little extra data for payload specific to Actor - in my case a uint8
when server changes the state of the Actor it updates its NetworkManager struct
fastarray replicates that
and callbacks on clients apply the changes
Actors themselves are responsible for encoding and decoding their custom payload into the uint8
result being that instead of replicating 1500 interactable actors
i have 16 network manager actors spread evenly on the level
NetworkMangers register with the GameMode
and Interactable Actors ask the GameMode for their closest NetworkManager when they start
and turn off their replication (they work just fine when set to replicate without network managers too, btw)
What kind of game are you working on that has that many Interactables? Sounds like a ton of stuff
tactical co-op shooter
it has power relays, terminals, doors, lockers, barrels, pickups...
(you can pick up and throw a barrel at someone)
That sounds like an incredible amount of work. I’m making basically the simplest version of my original idea that doesn’t completely lose what I was going for and it’s still taking me months just to get the basic systems working in a way that I can extend without breaking or forgetting how it works.
i actually got the network managers working in 3 days
How long have you been coding/doing game dev for?
15/4 years
could anyone explain to me why my RTC calls don't work when they're in an actor component??
that first print string is triggered, the second and third are not. And RTC calls from my player controller f.e. do work
@thick jungle Is both the component itself and the actor that it's on set to replicate?
I didn't know they had a separate option for it. Thought only the variables. Where do I set that?
this?
awesome! thank you! 😄
I've got 1 other bug in the unmounting code (multiplayer-bug-only) which causes me to fall through the ground. Any chance you might have an idea of a solution for that too?
For a character class?
yeah
Never ran into that myself. Only initial consideration is that something is wrong on the server machine. CMC would snap the client back if they fell through only, so it's likely there's a hole on the server, or the character has been teleported down just enough the capsule doesn't collide with the terrain anymore.
CMC moves via sweeping the character capsule, so if you teleport it even a couple units down, and it's now overlapping the terrain, it'd fall through.
but that is something I did think of, yeah. Hence the 2nd layer of debug terrain ;p
Hmm. Might be possible that there's another collision setting issue. Might try adding in setting the collision's channel profile or block all channels thing just to test. Is this running on all machines as well?
@kindred widget
yeah, the function call is replicated on client and server, as well as all other clients. I'll verify that though, good call :)
I didn't quite understand what you meant with the other 2 comments
@thick jungle Try setting these as well. Just to be 100% certain that the collision channels are set back up correctly.
thanks! I'll give this a shot
Hello! Multicast events not being fired too far from casting actor. Always relevant already checked. How to fix?
Reliable?
yes :/
I don't think it has something to do with relevancy..
Are you sure you are calling the multicast from the server / RPC
Yes. Whenever i try to change the Skeletal Mesh or Material of a SkeletalMeshComponent it just doesnt work. Calling Multicast from server being reliable. Work fine when close to the actor
Wait what? haha it works when you are close? but define close haha
Is this just for testing, or are you trying to set something up? Because changing skeletal mesh and materials sounds like state, which should probably be changed in a repnotify of a replicated value instead of multicast.
Well, i've a big map with some spawn points. When the client1 spawn far from client2 and the client1 change his SKMesh the client2 do not see this change when get closer. When this change is made closer(when client2 is seeing client1 for exemple), client2 see this change.
I'm actually trying to set this up, it is not a test. Do you think repnotify will make this?
Yeah, definitely not a multicast thing. Go with replication for anything that needs a state change. Multicasts are generally for one time things that never need to be considered again.
Yeah makes sense, i'll try. Thanks for your attention!
I'm sure there might be more, but I have yet to come up with a great use for multicasts beyond something like a single fire UI event that all clients might need to see at that brief moment that'll go away in a second, or maybe something like doing a small emote that only plays for a second. Replication is almost always the way to go.
multicasting is useful for a lot of things no? you could perfectly send a multicast MULTI_ChangePlayerMaterial(Player* pPlayer, "materialindex?");
but I'm a noob so don't listen to me xD
btw, if you do rely on automated replication for material changes etc, you have to check the replicate component checkbox of that skeletal or static mesh I think
check that too @viscid escarp
Nah. Just make the actor with the mesh replicate a property like an int or enum. And make a repnotify function for it. Whenever that int or enum changes, let the client change their own mesh/material.
The component itself doesn't have to replicate then, just the actor with both the property and the component.
The problem with the multicast is that the server will run that from objects, and if it deems that the client does not have relevancy to that object, it won't get the multicast. Also clients who join in after the multicast won't get the state change without a complicated setup of the client asking the server for the update. In the end, it's much easier just to replicate a single property that can drive the changes on each machine, and be the only thing that the server needs to update for each client when it's relevant.
how to get SteamAuthSessionTicket as FString?
TArray<uint8> TicketArray;
uint32 TempCounter = 0;
TicketArray.SetNum(8192);
HAuthTicket SteamAuthTicket = SteamUser()->GetAuthSessionTicket(TicketArray.GetData(), 8192, &TempCounter);
TicketArray.SetNum(TempCounter);
ANSI/UTF8_TO_CHAR?
though I don't think auth tickets are strings
not sure why you wouldn't just use the OSS for getting this
hi somone know how to chek if object is local or not ?
if you have authority over an actor then it's "local"
please refer to the most basics of networking in UE4 here: http://cedric-neukirchen.net/2017/02/14/multiplayer-network-compendium/
though I do hate that this guide calls C++ "UE4++"
i know but i try to send rotation of mesh to server and client is controlling the server 😄
and server cant move
Just wondering if its normal when running a listen server to have a fairly big frame drop, if I spawn on the map in the editor I get around 34-40fps, if I create a session and travel to the map It drops to 14-25
no
Also when I had another client join my session it dropped from 80-90 down to 60-70 (This was at High Scalability, the top one was on Epic Scalability)
you will get a performance hit from a bunch of players being in your listen server game though
since you are the server and you have to process everything they send to you
that's why you use the profiler
I can image that one, just can't see being able to host a server with more than 5 people if it dropped by 20fps with One 😄
Are the Sessions crossplay if I were to make the game for Windows and Android?
when makeing a multiplayer do you require an api
I have a dedicated server that works and people can join. When they open the game and press the join button for a regional server the widget sends them to the IP and we connect
The level rotates between maps with a console command and everything works
I want to limit players to 20, do I need to implement online session nodes, or can I just add this to the server config easily?
What do you reckon is the issue here: It's a car racing game, using the CMC. I rotate normally, everything is fine on both client and server. However, I increase the turn rate when I apply a boolean value (handbrake) that runs on the client. When the car rotates with this, the CLIENT jitters, but the SERVER handles it smoothly.
Is it that my handbrake value should be running on server as well, you think?
Car racing is usually done client authoritive iirc. So the approach of using a Character with a CMC would already be sort of wrong.
In addition, most movement logic that originates from key presses has to directly go through the CMC via flags that are send to the server and saved for replaying the moves on the client. BPs can't achieve that and will always have to fight with corrections and stuff
And yes that means that probably 99% of UE4 tutorials of Sprinting in BP only are not correct and will cause corrections on start or stop sprinting (just as an example), however they are correct in the sense that there is no better way in BPs.
You can pass along ?MaxPlayers=20 when opening the level and when server traveling.
does anyone know a tutorial on how to make a gamemode selection? so like TDM, 1vs1 and so on
how can I get rid of the error "No owning connection for actor XXX. Function XXX will not be processed." on a character? My regular actor already works, but the character one doesn't
@thick jungle Are you trying to call an RPC on the character, or?
yeah
If you're trying to server RPC from it, it sounds like you haven't set that client's player controller as the character's owner on the server. Or the controller hasn't possessed it.
correct, cus it's an NPC
that first screenshot gets called correctly on the chest, wrongfully on the NPC
the 2nd screenshot is the error
The shortest explanation is that you'll need to call server RPCs from a client owned actor. This is done to prevent other players from cheating and using other player's actors for server input.
Depends. What is the use case? Is this like a line trace to hit an object and then interact with it?
it's an initialization function for the NPCs inventory
What initializes it though. What causes the client to care about the inventory in the first place?
Event Begin Tick from the NPC_Master
Why not just make the inventory replicated if clients need to see it?
cus that didnt work either
But that's exactly what replication is for. Letting the server tell clients what properties something has. All you have to do is set the inventory on the server.
if it's actually replicating, then yes
but right now my NPCs aren't replicating??
I am using that RPC call as a plan B / check for when replication works
I tried setting it to replicated, but it didn't work
Then they can't call RPCs to begin with even if they were owned by the client. If you have a non replicating actor, that is spawned on both client and server, they have no way to know how to connect those on both machines.
in fact, my current server version is still set to RepNotify, which also doesn't work
yeah, you told me about this checkbox 2 days ago
but that only fixed it for the Actor chest, not the Character NPC
Is the NPC placed in world, or spawned?
Just checking that replicated checkbox and setting an array to replicate will set that array on all clients. Worth noting that you also have to set that array on the server whenever it's altered.
odd... cus that's what I Have
Are you setting the array only on the server via RPCs from the client owned character or controller?
Well, setting it any way on the server, but if it's altered from a client, that is the only way to do it.
definitely not from the client-owned character or controller
this is an NPC that has absolutely nothing to do with a player
but yes, I'm setting the array on the server, and trying to get the data onto the client one way or another
Okay. Lets back up a step. If you have it replicating and you set the array only on the server. Does a client see the same thing? Is the array replicating correctly initially?
on the chest, yes
on the NPC, no
Same inventory component?
yes
No instance values for the component changed between the chest and NPC?
Neither are set to be client owned either?
not client-owned no
the only values that are changed are the ones inside the itemcontainer itself
everything else stays the same
it seems to be a UE4 thing with regards to how characters are handled??
I can pretty much promise it's nothing with character class. I did the same thing with a networked inventory component. I had the inventory component that was just a replicated array of structs. Added to any actor that needed an inventory, chests, shelves, characters, etc. What would happen is my UI would specifically reference the PlayerCharacter on that machine, get their inventory component, and use that component to call server RPCs. Then the server version of that client's inventory component would do the actual work of moving the struct values around based on the inputs from that server rpc. The array would be changed, and all clients could see the results from replication.
@kindred widget how did u replicate the size of your inventory? or it doesn't have max size?
also does the items in your array lose their order when changed?
Player's Character's InventoryComponent technically, which is owned by the Player's Controller via owning the PlayerCharacter, so yeah.
@analog locust Not sure if there's a max array size, haven't been crazy enough to try to hit it. Order should remain the same unless you're doing the fastarray method. But if you're doing that, usually you're using an index for each array entry or you don't care about order.
My replicated inventory was nothing more than an Integer, Byte, and Enum(Byte). Integer was for ItemID, Byte was a durability/stacksize, and the Enum was for item quality. So three properties in a replicated array of structs.
I do care about order, what i'm trying to do in my inventory is :
- fill the replicated Array with eg. 30 elements ( or empty items ) some how i need to set that number of elements when filling the array so clients don't go over that size that i set
that should happen when player joins or begin play - then i fill a Map on client side from that array
You could just set the replicated array on the server to a size of 30 at start, or even in the editor. Then for UI, check if the item is valid, if not show an empty space. Then instead of Add/Remove, use SetArrayElem for setting items or clearing them.
can you use your pc or rasberry pi to create a multiplayer game?
You use data assets for your items too ?
Setting the elements specifically would keep it from resizing the array with Add/Remove. Be easy if you wrote some small wrapper functions for setting the array's items. Like.. Take an index and an item for adding to the inventory. If index is >29 don't add it, etc. A lot of logic to work around with inventories.
the array never resize
since what i do is
assign item pointer when adding
nullout pointer when removing
so what about inventories that aren't the player's character's inventory?
you can put in player state or player controller if you want it to be persistant
@analog locust Nah, like I said, the inventories were just simple look up and operation data for the items, and all of the other stuff. Used Actors for weapons, UI Icons, Offsets for attachements, Item Names, Item stack sizes, etc. All of that was done in a datatable, and that datatable was dumped into the GameState as an array. Non replicated array, Clients and server set up their own array for use. Server for moving items around with stuff like max stack size and attachement, and clients for icons and other stuff they needed for UI.
Isn't that the same situation for UDataAsset
but at least makes it easier if you change something between folders eg. images or static meshes it updated automatically in a dataasset
in a datatable u do that manually
@thick jungle Same as the player's. The point is to use the same component on all of them, but only the player character's component ever actually does anything more than sit there and replicate it's inventory. Your UI uses the player's inventory component to tell the server that it wants to move stuff, or add stuff, because the Player's inventory component is a part of the player's character which is client owned.
@analog locust Probably. I'm unsure since I haven't really used DataAssets that much. At the time I just needed a simple look up table that any machine could use to look up item stats via the replicated ItemIDs. DataTable seemed easy enough to use for it. Quickly got annoyed at the speed through and started dumping the table into an array and wrote all the getter functions in the gamestate for easy access since any machine can just GetGameState.
right.. so it doesn't use any RPC calls, and instead only uses that Replicates tag? And that DOES work for your NPCs?
@analog locust I think items should be loaded in game mode since its gonna be the same for every client
@thick jungle The Player's version RPCs. You have to call ServerRPCs from the player's version.
well, fuck... no way I can call RPCs from a non-player actor then?
okay.. so RPCs don't work, but does "Replicated" do work then..?
In short, Unreal Networking is simple. Server has authority and should have control over most data that needs protected or needs syncing. It usually does this via replication of properties. Clients can do anything they want in their own world, but any replication will overwrite it. Clients have to affect the 'real' world via RPC, and they can only ever do that from a client owned actor, which by default is the PlayerController, and it's Possessed Pawn.
that all makes sense
So. If you want to affect an NPC that you do not want that client owning, that NPC needs to be affected via the Controller, PossessedPawn, Any actor that the server has set to be owned by either of these things, or a component from one of these owned things.
that is a good idea to work with items id's
so that would mean I'd still need to do the RPC call on the PlayerController, right
so RPC calls as a fallback are a no-go
any clue why the RepNotify ain't working?
@thick jungle is your npc that has inventory need to replicate to every client on the server?
Repnotify won't work unless you change that property on the server. RPC from the player's owned inventory component.
I really absolutely wanna avoid using the Player's controller though...
basically, yeah? I need to retrieve the inventory when the NPC is spawned
and that Replicated / RepNotify checkbox doesn't do the job..
So don't use the player's controller. Use the client owned version of the inventory component that is likely on the controller or player's pawn/character.
Why don't you make the npc as an acotr with a skeletal mesh and some anims
then do a netmulti cast
idk how the player controller is invloved
you mean instead of a character make it an actor?
I wanna NOT involve the player controller hahah
but so far UE4 seems to be forcing me..
yeah..
Being a character has no bearing here. I promise you.
then wth is going on Q_Q
the chest works..
same code
same settings
like, RPC calls on that chest actually worked too
What do you mean on the chest? As in the client chest can tell the server chest to do something?
"Use the client owned version of the inventory component that is likely on the controller or player's pawn/character."
Uhhm, that sounds like it could work?? Feels dirty though, lol. Particularly if the current player wouldn't have an inventory (one of our races has none)
BP_Chest_Master has an inventory component.
BP_NPC_Master has an inventory component
Chest's RPC calls and replication works
NPC's RPC calls and replication does not work
You're either networking differently from the chest, or the client owns the chest somehow.
o.o uhhm......... I mean... they're both the same component, both set to replicate the actor, and they're both placed in the editor
would that cause me to own the chest as the first PlayerController spawning?
Is it a Listenserver?
If it's a listenserver first player controller is also the server.
Which by default owns everything.
it should be a dedicated server, but I don't really know how to check
pretty sure I set it up at some point
if it were a listenserver though, I'd also own the NPC no?
Should.
I can try and add the component to another character as well as an actor and see what happens, but you seem to be quite sure that shouldn't affect it
But I can promise you that it has nothing to do with the character class. I had three different AI running around doing things, four different containers, and two crafting stations. All using the same inventory component. And I did nothing more than add the component, set it to replicate, and check that the actor it was attached to was replicating.
honestly, that gives me confidence I should be able to get it to work ;p
but you did say you were using the player controller to send data over??
Nah. I had the component on the player's character, since I wanted to leave it on their body when they died for retrieval. My UI literally just called GetPlayerCharacter0->GetInventoryComponent Because on any client, Character0 will be their owned character if their controller currently possesses a character class.
So my UI had direct access to the component that was doing the RPCs with that simple call.
right
so according to you, having any actor set to replicate, with the component set to replicate, and the ItemContainer variable being replicated too, it should work?
Should very well work for replication. If you want to test it really quick, you could empty out all of your game inventories with a simple input test.
Your inventory array is set to RepNotify, right?
In the component I mean.
hmm how does this work : COND_InitialOnly
it's really confusing
yeah, it is. I'm running a new build now with RepNotify and a proper Print String and all. Hopefully I'll get some data
@thick jungle Do something like this from your player controller, and run it from a client window. In your Repnotify, Print the length of your inventoryarray. One press should make every client and server print 0 for every inventory component in the world.
If that works, your replication is working fine.
UKismetSystemLibrary::PrintString(this, FString::FromInt(InventoryArray.Num())); if you're in CPP
Isn't it supposed to send on the initial bunch when Initial Only Condition?
you're a hero 🙂
It doesn't send to other clients i guess with that condition
@analog locust
@analog locust Initial only as far as I understand only ever gets sent once to a new connection. I've never used it personally but my understanding is that if you have a property set on the server, and one client joins, they'll get that replicated to them. If it changes on the server, and another client joins, they'll get the changed value replicated to them, but the first client would still have the original value.
Yes that exactly when im trying to do
i wanted to set it only once it will be the same for all clients and i don't want to change it later
but when i press M only the server has the value
Was it set to 3 before that client joined though?
It won't replicate to existing connections once changed. So it'd have to be set on the server before any client connects if you wanted all of them to have the same value.
Oh i should call it before
You should call it from begin play probably
LoadGame of that string is either not valid, or is not of type PlayerSave
try saving on a non-zero-index?
Game\Saved\SaveGames
you can also check what save files are created when you run your game, to see if any other save is using the index you're using
@bitter oriole Hey Stranger, I got a question and I need someone with expertise, you'll probably know how to do it instantly xD
@kindred widget thanks! it hasn't solved it yet, but I got a step closer 🙂
@kindred widget found it.. I think anyway
turns out that the NPC initialization call wasn't triggered on the server 😛
whats the difference between a host server and dedicated server ?
oow
so what if i want my server to run night and day ?
this can be used for dedi right ?
how does runescape works then ?
Well Runespace is using a different infrastructure that allows them to not have to be restarted as often or they have a way of swapping, I am just spit balling here, haven't even played the game so not entirely sure what how it works.
dam
doing a whole day for nothing then xD
is there any login system tutorial were i can login like runescape maybe ?
@twin juniper runescape is a custom game lol
made with a custom infrastructure and engine
yes but the inlog can be the same right ?
steam is okay for me only that i can have my map running online with players
u shouldn'
why ?
im not so sure this is something ur able to do
might want to start with a smaller game within your skillset
and work up
otherwise u might give up when it gets too hard
ow i can do it all now, the only thing is i dont know how to set it up to go online
dont know how to start it all up thats my only problem
but you don't know how to do it all lol
i built a login system using a ruby on rails project
why not try and setup a website using a web framework like Django or Rails with devise
and then send http requests to authenticate the user account
and store a token on the local machine of the client
that is a webapp right ?
no
its not an app
its a web framework
you could use something like json webtokens
to authenticate player login
i still think it might be better for u to start out on a smaller game project than the size of runescape @twin juniper
perhaps u could work on ru nescape private servers
i used to do those when i was like 14
its a good learning experience
What do you mean it can run 2-3 days before restart ?
I really can't remember what was the method called but once I am in a session, how can I travel to another level and bring all the connected clients with me?
is it server travel/client travel?
DedicatedServers simply can't run without being restarted once in a while.
So it is a ListenServer, the server itself uses ServerTravel and the clients use ClientTravel, but I am unsure once I started and traveled to a map, how can I go to another one.
ServerTravel is what you use to travel with Server and Clients to the next Level.
Is that just because of memory leaks lol
a Dedicated server SHOULD be able to run indefinitely
Yeah but some games do maintain them weekly (restart)
2 days is kinda short
period
No, hopefully not. It's because of Timers that count up over time and being float based.
At my previous job, we had webservers running for over two years on client machines
Great, but we are talking about UE4's Dedicated Servers
Doesn't matter what you had before
Oh ok, so it brings all the clients when ServerTravel is called, also are options such as listen still requred?
No, only on the first call, which doesn't need to be a ServerTravel anyway
dang
good to know that about ue4 dedicated servers
I already said, it's because of Timers that are counting up (GameTime) which need to be reset once in a while.
Floats become pretty inaccurate over time otherwise
ah
would a solution then be to simply just reset those timers at the end of a game match for example?
unlike pubg servers
or if u dont need them, to completely turn it off
PUBG Servers are basically turned on and off every match
This is also not a UE4 problem. Lots of DedicatedServers have to be restarted after some time
Most hoster do this every night
I see, I do remember I was using OpenLevel before. So in that case you're saying if I have to go to another level I would have to call ServerTravel if I am the Server and then for every client call ClientTravel?
If you call ServerTravel, the Clients will follow, yes
Should be a SeamlessTravel if possible
Ok that's what I thought, but your reply kinda threw me off 😄 So in that case are options still required listen??
Only on the first OpenLevel call
void AGameModeBase::ProcessServerTravel(const FString& URL, bool bAbsolute)
{
#if WITH_SERVER_CODE
StartToLeaveMap();
UE_LOG(LogGameMode, Log, TEXT("ProcessServerTravel: %s"), *URL);
UWorld* World = GetWorld();
check(World);
FWorldContext& WorldContext = GEngine->GetWorldContextFromWorldChecked(World);
// Force an old style load screen if the server has been up for a long time so that TimeSeconds doesn't overflow and break everything
bool bSeamless = (bUseSeamlessTravel && GetWorld()->TimeSeconds < 172800.0f); // 172800 seconds == 48 hours
[...]
}
Just as an Example
So basically it fully breaks SeamlessTravel after 48hours
@quick flint
You have to implement your own solution for Persistent game modes with unreal ?
Unreal's Dedicated Servers are something you use for games like Unreal Tournament
And maybe for stuff like Fortnite, where you kill them after every match and pull them from some pool you have to setup yourself
Everything that goes beyond that is usually stuff you would use something else for
And maybe some survival games where you restart the server every night
@quick flint Not sure if it is being handled differently but have a look at SpatialOS: https://improbable.io/blog/spatialos-gdk-for-unreal-launch.
spacial os pricing starts to change as you get more players
Aws is way better and can be scaled depending on online players
almmmmost got this 'follow the thing your grounded on' all working but when rotation is applied its not quite right, its kinda working but not following exactly anyone see the problem offhand? I'm terrible at this kind of math lol
// if its a valid ground actor, and the last frame had the same ground.
// we get the difference between the old transform, and the new transform
// and apply it as an offset.
if (newHitResult.GetActor() == hitGrounded.GetActor() && hitGrounded.GetActor()) {
FTransform newGroundTransform = hitGrounded.GetActor()->GetActorTransform();
FVector diffLocation = newGroundTransform.GetLocation() - groundTransform.GetLocation();
FQuat diffRotator = newGroundTransform.GetRotation() - groundTransform.GetRotation();
diffLocation = groundTransform.GetRotation().RotateVector(diffLocation); // <- not quite right
SetActorLocation(GetActorLocation() + diffLocation);
SetActorRotation(GetActorRotation().Quaternion() + diffRotator);
UE_LOG(LogTemp, Warning, TEXT("Location: %s"), *diffLocation.ToString());
UE_LOG(LogTemp, Warning, TEXT("Rotator: %s"), *diffRotator.ToString());
groundTransform = newGroundTransform;
}```
What is this for? Like if a moving ground actor moves, the actor on it moves with it?
yup, exactly
which it works fine if the ground has no rotation
and the player standing rotates there feet to aling correctly, but the 'diffLocation' isnt rotated correctly using the transform
its probably something obvious lol
oh crap, I just noticed I posted this in mp, meant to post in cpp 😐
my bad
Do you only care about moving the actor's location, or affecting it's rotation as well?
effecting its rotation as well, that works actually
the problem is as the ground rotates, the location is offset by the rotational relative space
Is it okay to setup replicated variables on the char movement component
i was reading the code and it looks like it has absolutely no replicated variables by default
it puts everything into ACharacter
and it doesnt even have any RPC's
it calls all RPCs on the "CharacterOwner"
Array can be replicated but a TSortedMap which is implemented as a sorted TArray of TPairs can't be replicated ?
@quick flint better to setup RPCs and replicated vars on Actor only, it uses less bandwidth at least
me too xD
I have this code here, that the client is supposed to use. It should hit the MovePlayerGrapple Client, but it doesn't and instead it takes the authority route instead
why?
because who called the function doesn't have authority ?
That's what I thought but I have an authority check when that function gets called
MovePlayerGrappleLoop is a timer by event that's activated in AttachTheGrapple/AttachTheGrapple Client
Hey everyone I am new here so i wanted to ask you guys to help me explain how can I create a multiplayer in UE4 with blueprints. I want to create a small shooter type game that i can play with my friends online
Use a switch has authority and ray traces
Shooters are easy, it's only when your start doing fancy movement (like in my case) and crap where replication gets hard
you can try to line trace on client and just verify data on the server
i mean if your grapple uses some kind of line trace
or spheretrace
yeah it does
oh so what you're saying is that I should have some grapple movement manager on the server side?
i don't think i've seen a grapple in a multiplayer games
so my player points and basically does "I want to grapple here" and the sever moves them there?
depends on how your grapple works
you can do a trace by channel or something on client side then verify the data on the server to teleport the player there
or you can do trace on the server instead
so if the client is not actually allowed to do the action or tries to cheat it will teleported back to previous position by server correction
alrighty
that makes sense I'll go ahead and do that.
It shouldn't be hard to do right?
Just an interface call to some manager and the server does a multicast when doing the movement?
why would you need a manager?
you can do this in the player BP?
I'm not sure how to do that in the player
so authority switch after the line trace, the authority then calls a multicast event whcih uses a vector from the line trace. What does remote call?
a normal grapple function
before you call it switch has authority then call it
I see. I'll go ahead and try that approach out thanks!
hey folks, any clue how I can replicate my character rotation? I have custom gravity in my project, so AddControllerYaw doesn't work as it should. SetActorRotation doesn't seem to replicate properly even when ran on server either
I think the problem is that it's trying to go to the custom rotation and the already replicated movement
Dumb question but, when using the "open" command, is there a syntax for specifying a non-standard port?
guessing its IP:PORT ?
that's exactly right
no
strange
because
I'm trying to update my HUD
in tick
and other players actions are affecting my listen server's hud
So I thought a work around would be
check if the current pawn is equal to my local player controller's pawn
Is it possible to replicate skeletal Mesh ?
and if it is, then update the HUD
workaround would be to stop using GetPlayerController[0] hooked to RPCs
I didn't though.
pretty sure you did
Pretty sure I didn't
its practically only way to cross wire the HUD
I did this
GetGameInstance()->GetFirstLocalPlayerController()
Unless that's what GetPlayerCOntroller[0] does
it does, some of the time
So this is inside my tick function.
const FTimerHandle& Timer = VzPlayerState->GetTeleportTimer();
float Remaining = GetWorldTimerManager().GetTimerRemaining(Timer);
float Truncated = std::truncf(10 * Remaining) / 10;
AVisibilityZeroHud* Hud = GetGameInstance()->GetFirstLocalPlayerController()->GetHUD<AVisibilityZeroHud>();
if (Hud != nullptr) {
Hud->FillTeleportBar(1 - (Truncated / 20.0f));
}
}```
And when another client for instance triggers an event, this gets exeucted.
And my own listen server's HUD
gets overwritten with that data.
So I assumed maybe I should check
if the pawn is equal
yeah, but thats not your HUD tick
to my player controller's pawn
Oh yes it's inside my player character.
Should I do it inside my HUD
That would be better I suppose.
and inside every instance of every player character of every client