#multiplayer
1 messages ยท Page 602 of 1
GetPing() * 4
thanks for stepping in @hollow eagle ๐
i read the comment like an hour or go ore more
ran into that myself a while back, it's not at all obvious you need to do that until you look at the code...
Anyone online available to maybe help
@winged badger Hi
Are Reliable RPC's guarenteed to maintain order recieved?
nope
well i have some decent experience in this engine but trying my hand at something multiplayer, pretty much trying to get a TPS character to posses a car as well as the client im not sure what i should be doing for the client to be able to take control
ill give you a hint, a lot of games do not possess the vehicle
instead they attach the pawn to the vehicle, and pass inputs to the vehicle, whilst still possessing the pawn
anyway its 5am and i am tired ๐
so not technically possessing the pawn via the node but just passing inputs?
yes
having a pointer to the vehicle on the character
if its not null, pass inputs to it
hope u rest well dude ty for your hint ๐
and set the view target on the PlayerController to the vehicle
to use the camera on the vehicle
that is how Fortnite do it, if you ever seen or played it
super interesting i goto do some more digging into this!
@spare mortar they are guaranteed order within the same actor channel
Neat, thanks
mostly means two reliable RPCs on different actors could arrive in any order, but on the same actor it will normally be the same
I think when a pawn is possessed it uses the owning player controller's actor channel to send to server though so there may be ordering preserved between pawn and player controller as well
most surprising thing that bit me bad is reliable multicast is not reliable
it has a shorter timeout than the client timeout and can just straight up drop messages
or did in the past
In multiplayer steam game, does it require a standalone mode as well. The player could use the multiplayer option and play by himself right
Hi,
I have a problem.
When I move the client character IT update the animation but I can not see IT on the server
But if I move the server character IT update the animations and I can see IT on the client.
That's pretty normal, server is the only real place.
But I should see the client animations on the server I think
yeah they can host and play alone
@twin juniper does it downgrade perf?
for example root motion tasks of GAS is entirely constructed over CMC, so if I switch to network prediction and replace CMC then those tasks won't work.
Hey Slackers. When performing Seamless travel, is it right to expect all Widgets and references created by a character controller and attached to their viewport to persist through travel?
I am experiencing the opposite. Before travel I create a loading screen widget, being travel with server travel console command, and OnPostSeamlessTravel the character controller has no reference to the Loading Screen widget it created before.
Should I have to save that variable to Instance before travel?
@sly violet There are only few actors which persistent the travel.. umg is client only so it won't persist.
GameMode, PlayerState and PlayerController are persisted. else everything is Garbage collected so that your main match level plays smooth.
Interesting. Thank you!
Saving it to Instance then collecting it after travel has solved my issue.
anyone knows whether ACharacters move toward their velocity in server or they are just move when position is arrived from owning client ?
When i move a replicated uobject pointer from an actor component to another actor component ( both of them owned by the same actor that is replicating them through its channel ) some time it works but most of them times become nullptr
@twin juniper define "move" and what's the objects outer?
how do i do that
@winged badger i'll try to explain
i have a UObject* inside a FFastArraySerializer struct, and a base actor component with an array of that struct marked as replicated
then 2 actor components inheriting from that base actor component . (first component : a, second component: b)
for example if i instantiate that uobject on (a) then add it to the array and mark the item dirty,
then if for example i press X to transfer that uoject from (a) to (b).. i get the Uobject by index, add it to (b) mark the (b) item diry, then assign nullptr to (a) on that index and mark it dirty.
sometime it works but most of the time its nullptr for some reasons
you're using postreplicatedadd?
@winged badger nope to visual that on uumg i just broadcast a delegate from PostReplicatedChange with the index that have been changed
depending on your ReplicateSubibjects override
Change might fire with null UObject
needs to be checked
i still don't have a clear mental picture of your setup though
you have 2 identical fastarrays on 2 actor components on same actor
the fastarrayitem has a (weak, not weak?) pointer to a replicated Uobject the owning actor itself replicates over its channel
at this point im guessing inventory and quickbar/belt or some such
Correct inventory / actionbar,
No the fast array defined 1 time in the base class component im just re-using it in childs
i tried to debug but it's tough it hits
OnSubobjectCreatedFromReplication when instantiating object
and when doing the transfer sometimes it does, sometimes not
bool bWroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
if (Channel->KeyNeedsToReplicate(Items.IDCounter, Items.ArrayReplicationKey))
{
for (auto& Slot : Items.Slots)
{
if (Channel->KeyNeedsToReplicate(Slot.ReplicationID, Slot.ReplicationKey))
{
bWroteSomething |= Channel->ReplicateSubobject(Slot.Item, *Bunch, *RepFlags);
}
}
}
return bWroteSomething;
there is no subobject created from replication
or shou;ldn't be
on transfer
the object itself is not destroyed, therefore it doesn't need to be created again
if you don't have a strong pointer keeping it alive on clients though
the GC will get to it
in my opinion, you are overcomplicating the design
depends on the quantity if transferring the whole slot quantity to the other component, i just assign the same uobject ptr to the other component then assign nullptr to the source
i didn't find any easier way
assigning a null to the UObject pointer does not destroy a UOBject ncecessarily
i would run the entire thing from a single fast array
that's what i do the fastarray exists only on the base actor comp
the childs inherit
i just this function to empty the slot
Item = nullptr;
Quantity = 0;
struct FInventorySlot
{
ESlotType SlotType;
int32 SlotIndex;
}
struct MyFastArrayItem
{
TWeakObjectPtr<UObject> InventoryItem;
FInventorySlot InventorySlot;
int32 Quantity;
}
pseudocoded ofc
it feels weird your replicating the object via ReplicateSubObject
@meager spade because its slot based, and i don't want to lose the order in replication
PostReplicatedAdd adds the poitner to the not replicated TArray of inventory items
but your slot can be a index
that keeps them alive
in the same component that has the fastarray
post replicated change broadcast changes
and post replicated remove removes a single pointer to the item from the TArray
or if you prefer having 2 UObjects for split stacks
then you don't have to bother with that
@meager spade
this is my slot struct
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
int32 Index;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
class UItem* Item;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
int32 Quantity;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
class UActorComponent* Owner;
@winged badger i think its the same since the pointer of uobject is handeled by GC
i never use my fastarrayitems to manage lifetimes
nor do i
then again i dont replicate the UObject item
i create it client side via the PostReplicatedAdd
๐
what if the item has something replicated inside like a value?
replicating UObject item is okay if there is a reason for stuff to replicate via that object
that is why i have to replicate it from server
@twin juniper i don't so i had no need
but basically
jugglign several fastarrays
when you can do it all with one
just complicates your life
you just need an enum for slottype in the item to avoid it
that makes you not transfer items from array to the next
that would be pain to handle for splitting
dropping an item from inventory to action bar is just change the enum
no
you create an extra item anyways when splitting
so whats the difference there from what you're doing now
none
my quickbar/hotbar is a seperate fastarray, but it just holds ItemGuid to slot mapping
it pulls the item using the guid
from the WorldInventory array
i also allow for local mapping of slots to items
so client can drag and drop and rearrange the ivnentory
without RPCing anything to server
indeed
you can even choose not to split the items on server at all
because it makes no difference in the grand scheme of things
if client has stack of 20 rocks, or 4 stacks of 5 rocks
i mean i don't get the problem of having the same fastarray in childs its gonna be separated and the same one?
as long as quantity is synced
im not using different ones
its an extra step
extra step means extra points where your code can break
and you don't really gain anything by it
always go for simplest possible design
with least amount of network actions
what you're using now is not it
so let the client handle moving items?
as you can see you have to add defensive code for your object being destroyed seemingly at random
as long as server enfoces "you have 13 rocks"
it doesn't matter how client slots them locally
its just for his UI/Controls
the problem with that is with split u might be duplicating none existing items
if he throws a rock, the effect is the same, no matter which slot it was in
i'll show you a .gif of what's happening in ui
there are many approaches and nuances you can take
i strongly advise one component, one fastarray
^
I deleted last question, realized problem is different. Is it normal that this function prints on server?
if (GetOwnerRole() == ROLE_SimulatedProxy)
{
ClientTick(DeltaTime);
GEngine->AddOnScreenDebugMessage(-1, -1.f, FColor::Green, FString(TEXT("Client Ticking")), true, FVector2D(1,1 ));
}
Looks like PIE, so it's probably normal because there's only one engine instance
Understood thanks
You should print the current role to your logs
That's one reason I like Kismet's version of PrintString if you're going to use Onscreen messages. It'll add the machine's name to the beginning of the print.
If in my ustruct A, I have a uproperty that's another ustruct B which I want to be delta-serialized automatically by the engine, is there any operator I should override on ustruct B?
For example:
USTRUCT(BlueprintType)
struct MY_API FStructA
{
GENERATED_BODY()
UPROPERTY()
FStructB SomeProperty;
UPROPERTY()
FStructC SomeOtherPropertyOfAnotherType;
};
Yeah but how do I make sure it's delta serialized?
make your custom serializer
But a custom serializer would prevent the engine from using delta serialization
you can make your own delta serializer
Hello! Does Origin rebasing works in multiplayer?
it works
I'm looking around for the same kind of thing right now, did you happen to come by any examples?
Wait, given the above example, if FStructA is a UPROPERTY(Replicated) on some actor... and recently only FStructB SomeProperty changed... will only that be replicated by default, without having to write any custom net serializer, delta or not?
you dont use Replicated inside a struct
Yeah I meant if I have SomeActor and in it a member UPROPERTY(Replicated) FStructA SomeStruct
yes all UPROPERTIES will replicate
unless you mark them "NotReplicated"
UPROPERTY(NotReplicated)
Yeah but I mean
Suppose only FStructB changed (inside of the struct)
Will only FStructB be net serialized during replication?
To save bandwidth?
Hmmm 
Yes, I will do that and report back o7
I did not I'm afraid
But yeah NetSerialize sends everything you write to the archive everytime
Regular property rep is off when you do that
Yeah, and I assume UPROPERTYs are also automatically delta serialized if no serializer is overridden
for structs that is
Like in this example ```USTRUCT(BlueprintType)
struct MY_API FStructA
{
GENERATED_BODY()
UPROPERTY()
FStructB SomeProperty;
UPROPERTY()
FStructC SomeOtherPropertyOfAnotherType;
};```
Where FStructA is a UPROPERTY(Replicated) member of some actor
Yeah so only the changed items would be sent
Phew
Btw I found this: FGameplayDebuggerNetPack::NetDeltaSerialize
It's doing some intense stuff and I'm not really spotting any arrays involved
Oh interesting I'll check that out at some point
It's apparently using FNetFastCategoryBaseState pointers for state handling
DeltaParms has an OldState, a writer etc, I'm guessing those states can be cast to the type of the relevant struct?
Yeah I think generally delta serializing is something you need a lot of prior plumbing for
Now that I think of it though, when 'dynamic' properties are mentioned in NetSerialization.h:
and how those can't be handled by the ::Recent buffer etc, he really does mean dynamic types that change in size
If my structs however aren't dynamic - that is, eventually they are broken down to atomic properties, it will fit inside the ::Recent buffer nicely!
Which is very good for my sanity
How does the loading a saved game works in a steam multiplayer?
I got some weird breakpoints when building a dedicated server; It did not build, which is odd; as it is based on a template. Can you guys take a look at this error log to see what is wrong with it? https://pastebin.com/FTnJrSmp
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
However you want it to... steam doesn't dictate how either save games or multiplayer works because it provides neither.
To my understanding, any code/bp in an actor runs on server and clients, right?
that's an incredibly broad question
some actors aren't on the client but are on the server (like the game mode)
@lost inlet Sorry, i meant like a pawn or a character.
well you said "ANY" code, so it that can still go either way
something on a pawn in a tick function that doesn't have authority checks? yeah
Yea, for example, begin play->print string, will print the string on the client and server.
correct?
that specific example, yes
Technically won't any function/event in a pawn without authority checks run on server and client?
(Sorry if my wording is off, still learning)
well input functions won't be run on the server
@hollow eagle I meant what are the steps in loading a multiplayer saved game. Letโs say you invited ur steam friends then played the game then saved it. When you what do you do? Do you meet in a lobby then load the game?
Again, the answer is however you want to do it
You could do it that way
you could save the game to everyone's client, you could save the game just to the host's client, you could pull a halo and only save basic mission progress but no mid-mission checkpoints, you could save everything to some server you control instead of the player's clients. And then there are numerous ways to allow loading in any of those situations.
You're asking a very generic question and there's no one answer.
In Steam multiplayer one of clients will host
So the host will save the game in his computer
Ok... and? Is there a question there? It sounds like you already know what you want to do.
Itโs similar to the game grounded. I have to see how that game loads in multiplayer
Trying to see what goes behind the scene
to my knowledge there's nothing special about how grounded or similar deals with saves
it's exactly the same with singleplayer or multiplayer - someone loads a game, other people join
joining from a lobby doesn't change anything - they just join immediately rather than after the host has been playing for a bit
Ok so each client have to load the game not only the host
The save? No, only the host loads the save... other clients learn the state of the game through normal replication
I guess you could seed client state by sending the save over... but that's basically what initial replication does anyway so that's a bunch of extra work for no benefit
You still have to create session letโs say for 3 ppl which the game was saved for before loading so that other 2 clients could join
I'm lost, what does any of that have to do with saving the game
I guess I have give it a try and see how it really works
Given that ISMs do not replicate, how can I store transform data of ISMs (Instance Static Mesh) in an array/struct, Replicate array and have clients draw ISM?
Can I dm someone about playstation OSS setup? Having some trouble
Someone who is a playstation developer of course
How can I make networked movement in BP so that I avoid stuttering on the server and rubberbanding on the client?
Hi every! This exciting time for the multiplayer community! We have developed a server system that is unhackable! We can not wait to give back to the community so they can use this system to reduce server cost. Internet , in house server and power is all an indie dev needs to get started hosting an MMO RPG!
unhackable
๐ค
gonna have to qualify that statement bud, there's no such thing as unhackable.
it works through chat system on third party streaming services
example https://www.twitch.tv/mizkif
this eliminates connections to any server tied to your mmo rpg.
our system takes information from all in house servers so that players can join each other
no downloadable client needed. good luck ddossing twitch haha
Would it work for a science-based, 100% dragon MMO?
yes we are working on integrating an x box controller so players can move around
any game type you want to create in unreal engine will work with our system
you can program it to be single player to
no need to program it for multiplayer
I only have a guitar hero controller, that work? I got a kill in halo with it once.
if it works on your pc yes
So when you load a multiplayer lan/steam game and you had 3 players, do all the players need to be present in the lobby prior loading
No. Again, this is up to you to implement. You can make people join a lobby first or allow join in progress.
So you're describing something like stadia/xcloud/luna/psnow/etc. Maybe more on the side of stadia/luna.
My (and every potential client's) first question is why your system is any better than what google/microsoft/amazon/sony have done.
we give it away for free?
Good luck keeping that sustainable...
Is there a way to get a export of all associated packets for a build?
like tcp/udp packets :X
anyway to reference them at all?
What do you mean by "all associated packets for a build"? Like get a packet capture from a live game? Or do you mean a list of all the different types of packets the game can send? Or something else?
Well I'm trying to make a connection Service within kubernetes, that allow accept UE4 Connections, and relay the packet information too a Pod which will manage/maintain a virtual map utilizing a exported navimesh.
wireshark might help the counting process. But you need to look at and count your custom events
:X Trying to make scaling connections I'm not trying to hack a game, or anything
I am making one XD lol
The idea is Micro-Service(UE4 Connection Handler) -> Validation of Connection -> Direct Connection too Pod -> Pod Accepts Data -> Relays it back to UE4 Connection Handler in that play, I have a few micro-services that are managing functionality for specific events. But mostly i'm focusing on the Connection Service and Replication on a Map. For now :X Cost me like 1000usd @.@ testing a UE4 Instance on AWS/EC2 LoL
XD trying to come up with a better way, less money. LoL
UE4 Connection Handler -> Level Pod -> UE4 Connection Handler more or less :x
its nice that will all go away for us. We use twitch validation for client authentication. Our servers are in house and streamed to users so reduced server costs.
oh nice :3 rock one!
streaming will be the next cloud gaming solution
I'm trying to build a large scaliable Level.. but I realize that running UE4 as a Server itself, is just well uses alot of everything. LoL
So i'm like well. What if UE4 wasn't a single service, what if it was a collection of services that communicate via tcp/grpc/etc and if you did it that way, you would only need 3-5 services in total.
Control Service
Connection Service
Map Service
Action Service
Event Service
At least that is my concept.
omg now I love you!
but yeah back to what I was asking, anyone know a way to dump all associated packets by chance?
the idea is to use those as whitelists for validation, of packet structure, and relay that via custom interface.
you might need to dump them as they are received then set up a function to parse through the packets.
hmmmm damn ๐ฆ
I know it sucks
If I replicate variables that are only valid on the server, will clients be able to access these variables as readonly?
The fact that a variable is replicated has no bearing on its access properties.
That question makes no sense.
Can you reformulate it?
Just to note, Clients cannot modify the value of a variable on the Server directly.
They can only modify their version of that variable.
The Server can modify (through replication) a replicated variable on the Client though, when its value changes.
if you don't want clients to access/read a property, then don't use it on client, if the property can be used by client and server, make a getter function and gate the value, but then again as DevilsD says, your question is a bit nonsensical ๐
Is there a callback function for something like AllClientsReadyToPlay ?
I want to get all players at the start of the match.
Where should I try to get all players in a multiplayer life cycle?
no
you need to do that yourself
there is NumTravellingPlayers if your using server travel, but you need to handle all players ready
Quick question: Can RPCs be created in a component class or does it have to be an Actor class? I was seeing if I could create a server RPC in my custom static mesh class.
Ok. Thanks.
components can have RPCs but they go through their net owner's actor channel
Oh ok thanks @fringe dove
they are also a bit less efficient than an RPC on the actor itself, at least that was the release notes comment when they moved character movement component rpcs onto the character itself
so if you always have just one component always on the same type of actor you may favor it being there on the actor, but if you have multiple components or use it with a wide variety of actors you may still need it on the components themselves
When i rotate my player to mouse cursor it rotates all other clients
and seriously i cant replicate the rotation correctly
can anyone help me and my friend with a multi user editing problem, as though im unable to find my freinds session
Been spending my whole yesterday to implement a name tag on widget components on top of my players but can't replicate that correctly. Anyone's got a guide or something as to what to do ? Each player has their name in a save file, correctly loaded at beginplay. Best I've got is using repnotify which makes it work for all players connecting after, but the player can't retrieve the infos for the already present players.
I've tried accessing the gamestate to foreach on the names and update the according components but the names get all mixed up.
Thought the widget would be the culprit but even with a rendered text I can't make it work
Don't replicate it is the answer
All of that can (and should) be handled by clients locally
If you're doing it with widget components instead of regular 2D widgets it gets easier, all you need to do is attach one to your pawn class, assign a player state/pawn variable in the widget, then have the widget read from the player states' name
Everything you need is already client-side
or attach a widget component to the playerstate, then physically attach PS to Pawn ๐
Galaxy Brain ๐
no need to worry about PS arriving late, which it usually does, then
Hellow, does somebody know what does it mean?
LogNetTraffic: Error: UActorChannel::ReadContentBlockHeader: Sub-object not in parent actor
So i try to replicate uobject and call RPC on it. Probably the problem is that i use outer to handle replication, but i try manually define where to call this RPC. So as i result use custom property for CallRemoteFunction and GetFunctionCallspace. The reason i did this, is that the actor that handles replication can not be owned by client - only by the server, but in these uobject i want to determine on what client should i sent RPC.
At least is there other way, to separate replication and callspace of RPC ?๐
The UObject's Outer has to be an Actor
No way around that, but assuming you set the UObject up like I did here, you're good to go:
https://jambax.co.uk/replicating-uobjects/
Then you can call RPC's on it, have replicated properties etc.
Hi I started to learn replication but can't figure out how to properly setting variables on server. Am trying to create ready check where client press R to signal that he is ready. When host press R and client is ready, game can be started. Otherwise host will be informed that client is not ready yet. Here is a blueprint which does not work. After setting client ready server still see client as not ready. Can anyone help me?
Yea i know it. the problem is that an actor that is responsible for replication can not be owner by the client, but at same time i want to make rpc from its sub object to specific client. If i stay as it is, it will call Client call on every client, not at specific one. As i understand it, it happens because of this realisation in my uobject
GetFunctionCallspace(UFunction* Function, FFrame* Stack)
{
return (GetOwner() ? GetOwner()->GetFunctionCallspace(Function, Stack) : FunctionCallspace::Local);
}
So is it possible to make it work in other way?
If you call a 'Client' RPC it will only go to the owner of the Actor? Ownership is determined at the actor level
You need to override CallRemoteFunction as well
But yeah you can't make an RPC go to a specific client without using an object that is owned by that client
That's not even supported at the actor level
when you press R it is pressed on client side so this print will never be hit cos has authority will always go to remote
@open quail Your issue is that you're not checking the player's character. So your player will set that bool to true in their own character on the server, but then the listenserver player will press R and check it on their own character, but they're not changing it on their own character. You'll need to get all of the player's characters and check them on the Authority side of your switch.
The way to do it is remove the switch entirely
Just call the Server function directly
Hey there just an easy question here... how would I need to set this stuff up in order to prevent cheating ?
Doesn't appear to be anything related to Multiplayer there?
There's no replication in that image
That is what the question was :o
Needs more explanation
The Server is the only thing that should apply XP
Clients should never send RPC's to request it
I know I have to somehow check on server if the client is legitimate able to level up
Otherwise, you can't prevent cheating.
but I'm not sure how to set it up
You're thinking about it the wrong way
The Server is what applies XP
Then tells the client what their level is
The client never directly tells the server their level, nor tells it to add XP
so Gain Exp runs on server ? and multicast to the clients ?
no
And there is no way around it? Basically i've made an action system which contains actions(uobject), action manager is responsible for replication right now. So if i want it to work properly, i should make action manager as a component for player controller, for example, and pass it from certain client as an outor for u object?
There is no way around that no
There are two types of RPC for clients, Client and Multicast only.
Client goes to the owner of the actor
Multicast goes to everyone who has the actor relevant at the time
That's all there is
i mean not pc but an actor) (messed up)
A Client RPC called on a PlayerController will only go to that player yeah, they own their player controller
And it's the only player controller they know about
that sucks(
Hey uhm... can I not use the "Has authority" node inside actor components ?
TimeStamp means "GetWorld->Time" ?
https://youtu.be/JCF1LJYPjSY
It's done! Multiplayer integration of ballistics FX and Easy Ballistics!
Hi! I did it! Managed to use ballisticsFX in multiplayer thanks to magic of free ue4 plugin Easy Ballistics.
I will also upload an extended video on how the process of integration fully looked like. In this one I just showcase it and explain a ready project step by step and node by node.
As always - the example is free to download. However, you ...
Jambax, if you are here, can I ask a question? I was trying to do what you told me about smoothing bReplicateMovement, on PostNetReceiveLocationAndRotation I am logging these, and the error logs are coming from Tick. Seems like Mesh (visual) is already always "0,0,0", how can I smooth it if its already being teleported to root everytime?
Well you need to offset the mesh manually
If it's not using an absolute transform then it will just inherit it's transform from the parent
If you still want it to use a relative transform, then you would calculate the offset of the mesh, apply that and over time interp it back
So its like, when new data arrived from PostNetReceiveLocAndRot, i am saving "current" or "old" world position of mesh, and comparing with new arrived datas "new" world location, and lerping it, that way even if engine updates it, I am undoing that update with Lerp and smothly updating it because lerp teleports to "start location" before starting to process lerp operation, right?
Sorry if I am being a headache about it btw. Been trying to solve that for days. I'll try to ask minimum questions about that
Well the mesh position isn't replicated, the position is for the capsule alone
the meshes position is inferred from the capsules' position, in the case of characters, as it's attached
I've got an event that handles cosmetic stuff only relevant to the local player called on tick. I only want it to run if the actor is owned by the player. What can I use to test for this?
edit: specifically, if I want to test if a given machine owns a player pawn
Is Locally Controlled seems like a winner
Er, wait. Would it be better to mark a function as runs on owning client? My gut intuition says this means we're adding an rpc call every tick if that's the case and it'd be better to just handle it all on the client
If you mark it as "Runs On Owning client", it is an RPC
Right, and that means a message needs to be sent from the server.
If something is 100% local, it'd be better to not send a message at all, and just test "is locally controlled" instead, correct?
When and What way is best to get all the active players in the game safely without using a Callback to add a player controller to an array everytime a player is ready. All players start at the same time at the beginning, players cannot join mid game.
Iterating all PlayerState actors (client or server) or all PlayerController actors (server only)
Where would be safe to do this 100% to make sure all players are ready to play?
Define "ready to play"
Like I would be able to get all of the player controllers in one loop to store in an actor in the map.
instead of using a callback to fill an array everytime a player is ready.
basically, where would an actor in the map who exists on the clients be able to get a list of all players in the game at once and be accurate?
My first approach would be to simply always fetch the list of currently connected players any time you need it
I agree, but where would be safe to do this for an actor in the map?
What do you mean, where ?
lifecycle functions
Well, any time you actually need to use that list of players
begin play would not be safe, i don't think
Don't store
Just get the list every time
You'll worry about caching things when you're in optimization
And yeah, BeginPlay won't cut it
I agree
Also, I don't think the world is ready on PostLogin in game mode.
So I don't think grabbing actors from the world in gamemode PostLogin is safe either.
The simplest, safest, is to grab it all the time, when you need it
I need the Player Array list when the game is ready to be played, but the players become ready at different times because initialization and stuff.
Okay
Your real problem is defining "when the game is ready to be played"
So work on that first
That's a game design question
no its a multiplayer lifecycle question
No, it really is not
ofc it is, different functions are called at different times
Alright, so let me ask you one question
I need to know when its safe programmaticlly to obtain the references in a multiplayer paradigm.
How do you know all your players are connected ?
That's not an UE4 question, that's a "how does your server and session system work"
UE4 doesn't know how many players are going to connect
You might
UE4 knows how many players are connected
Players cannot join mid round as mentioned.
once the game starts, there number of pc in the game are final
See, this is why I keep telling you this a design problem
How do you know the game can start ?
life cycle functions in UE
UE4 does not handle this in any shape or form
UE defines when functions are called.
lifecycle functions.
that will determine when it is safe
So let me rephrase my question so that you understand
How are you preventing players from joining mid match ?
There is nothing setup rn to decide, I am manually deciding how many clients are connected in the editor.
You can't join programmitcally yet.
its all editor stuff by me.
Do you know how people will be joining a game server ?
In the real game ?
The point I keep trying to make is that UE4 simply does not have a concept of "all players joined"
It just does not
By default anyone can join anytime
so callbacks it is
I know there is a better way, theres gotta be
but I guess I will just have to hack together a callback system to fill the array as players become ready to play.
You have a design problem where you haven't decided what the start condition is - maybe when 5 players connected, maybe 30s after the first one, maybe a voting system
This is not a technical issue at all
btw, UE knows how many players will join because I'm setting it in the editor before I even play.
But that's 100% an editor thing
You're not even going to test your game that way, it's just a debugging tool
You should be thinking about the actual game and how do you know there are enough players
basically, its a lifecylce question I'm trying to asnwer.
And I keep telling you the very concept of "all players have joined" does not exist in the engine
So there is no lifecycle for that
I get that.
Players could be joining 10s after anyone else
They could be joining a full minute later
I have to figure out when its safest to update an array of players
Right when your game logic has started the match
Based on your game-design decision on what a match need to start
If it's a MOBA, it's probably "10 players joined and all picked a hero"
Is there a OnMatchStart - depends if you are using GameMode or GameModeBase
GameMode has a basic workflow for match states
Except you will still need to call that stuff yourself
Should I be using gamestate for this?
GM only on server, gamestate both
I need an actor that exists on each client to have a reliable array of each actor somehow.
Alright, I give up, sorry, I don't have the patience for that
and the actor is in the map when the game starts, it is not spawned.
You keep thinking this is a technical issue, but it's not
Read up on GameMode if you want to implement a match system : https://docs.unrealengine.com/en-US/InteractiveExperiences/Framework/GameMode/index.html
Overview of the Game Mode and Game State
You'll need to implement your custom logic for when a match starts, and you would set your array when you call StartMatch
When you do that, is a game design decision
So how would you fill an array for an actor in the level that exists on all clients. Would you do it via a gamestate callback or a gamemode callback?
Depends if you need the info client side or just server side.
Then put a replicated array in GameState and fill it as soon as you have called StartMatch from your code on the server
Yeah, the replicated array in GameState was something I was considering. Had it in my notes.
just wasn't sure it was the best way.
If ISMs could replicate, I wouldn't even be having this issue.
All this workaround crap is due to Instance Static Meshes.
I mean, you haven't solved your actual issue here
You solved the "how do I get the server to send the array to clients"
You did not solve "when do I set the array on the server"
Which is what you asked, and is a game design decision
So this is what I'm gonna try
I'm gonna put a replicated array in the game state and when players join, I'm going to update the game state from game mode PostLogin, when game state receives the updated player count it will obtain the actor on every client containing the ISM and do what I needed it to do there on each client.
@bitter oriole what do you think? 
I'm thinking you could simply read the array of all PlayerStates on tick and be done with it
But sure
You aware, that GameState has Players array by default which has all joined players PlayerStates?
No need to reinvent the wheel.
I'm afraid of Tick
Be sure to also update when a player quits
Yeah, that's a common problem
Get the game state, get the player array on tick, you have your safe list of all currently connected players
Not including players currently connecting
Is there anyway I we could do a voice chat?
I understand if you don't want to. its completely fine.
Nope, sorry
I understand, I would probably be able to explain my issues better, but I understand your solution. I appreciate your help!
Yes, I'm aware, but when is it safe to call that?
@ember osprey you can access it anytime
like what part of the gameplay lifecycle is it safely full of all the players, or do I need to keep checking it.
it might not have everyone
@meager spade
you need to decide that, take fortnite for example, they shove you on a server in a small waiting island
I keep saying it
once a criteria is met
This is entirely up to you
they start the match (ie time was too long or 100 players are there)
what part of the gameplay lifecycle is it safely full of all the players
There is no such thing in Unreal
I keep saying it
this is a good suggestion right here.
It's literally the thing that I can't seem to explain well enough - there is no built-in way to decide when to start a match
a delayed timer
i think i mentioned that last night also :D, but either way, check UT4 GameMode, check SHooterGame source code
i am sure they have the concepts there
This is a game design decision and it needs a game specific answer - basically wait until there are 10 players, for example
Plus a timeout to start anyway at 3v5
You said I needed to handle it myself.
I'm trying to do just that.
as @bitter oriole said, the server only knows who is connected and how many max can connect
First step : when do YOU want a game to start ?
5 players ? 10 players ?
10s after server spool up ?
I think i'm going to put a timer on begin play on the actor in the world for like 2 seconds and then get the Player Array.
hmmm
I have bIsReady on my PlayerStates and when all connected players are ready (by clicking ready on UI) then match will start. Override GameMode::ReadyToStartMatch which ever logic you need for your game.
that seems like a long time for a game start, is there another lifecycle function, like AfterBeginPlay or something?
Your timer needs to include the difference between the fastest and slowest client to load the map
damn you're right
And no, there is nothing in the lifecycle that addresses it, for the 56th time
It's a game des- you know, I'm done
If you're ever in the DFW area I'll buy you a coffee.
if you base from AGameMode, you have the concept of match states,
that you can also dabble into
right, so UT4 for example this when the state changes
waiting to start will be doing you start criteria
ah the days before gameplay tags
InProgress will be whilst your game is actively playing, etc
but this will different for every player no?
this is SERVER only
ahh
lol
@meager spade this is all related to the ISM solution we discussed a while back.
my note:
does the array have to be replicated?
I have been struggling with this since!
why can't the client have its own array locally?
why would they not?
IDK? lol
I haven't been able to get that far.
I need each client to know how many players are in the game and tell an actor ISM manager, to create an ISM component to represent each client.
its frekin' hard
then have each client sends its Player MeshTransorm (on a timer) to each connected client to draw their representation of the ISM on their local instance.
this is something the clients should handle themselves
every client knows where the player is
and can update the stuff locally
no replication is needed here, all the replication is handled already
Anyone use steam sockets? I'm seeing throttling to 10Kb/s; however I'm sure I've all the required configuration set-up (given switching in "SteamNetDriver" shows 120Kb/s on a particular game-mode we have).. is there some other option steam sockets use for throttling?
every client know where the players mesh is
hmmm...thats true.
on a timer you can simply loop through all player states, grab the pawn, grab its mesh loc, or w/e
and update the isms
wth ! is it UT4 ? why they dont use enum simply
the name based thing is cause they used the engines default GM as a base
which has MatchState defined as strings
@meager spade Ok, I'm gonna try that!
and can be extended
The GameMode thing comes from UT3 quite very directly, too
So UT4 devs were familiar with it
when is the next time you will be in Texas?
Is UT open source?
@ember osprey Probably never
I see its being shared here a lot
Yes it is
open source in the sense you can look at the code, but you can not copy or use anything out of it
Yeah, "source available" like UE
ok, since never, here ya go โ
you get one also @meager spade โ
is there any right way to exclude some components from dedicated server ?
something like bEditorOnly, but without changing source code .
because I see by default UObject has some function for that NeedsLoadForServer, NeedsLoadForClient, but there is no variable for them
does anyone know if it's possible to create a dedicated server buld without building UE4 from source
yea but its class based unfortunately, so I have to make lots of inheritance ๐ฆ
for instance I have items on the ground, on server I just need the root (scene component) but it has lots of static mesh and skeletal mesh component as child
dedicated server wont render them
which I want them to be excluded, nearly 10 000 items are on the ground
and it takes memory
and spawn cost anyway
spawn cost will be the same
I wonder why they have a bool bIsEditorOnly for editor only components but nothing for client server
๐ค
btw If I move them on server, lots of redundant children move as well
they calculate world transform and bound
If you have other stuff dependent on them then by definition you have to include them
You'll find that 'Editor Only' components can't have children that are non-editor only for example
Also I can't imagine the issues it would cause having relative transforms / attach parents being different between client and server etc... I mean have fun dealing with that mess
In the context of meshes, also need to consider collision etc.
I considered all those options, I am kind of obsessed with memory.
some game engine take 300mb for an open world map
On a dedicated server your bottleneck isn't going to be caused by a few extra mesh components
but UE4 takes 700mb for a normal dedicated server
๐
hopefully we are not using source version, I would also remove all those redundant BP multicast delegates in components
๐
things like OnClick, OnRelease, etc
๐ค
this way I guess I could save a lot
...but why
they cost almost nothing
if you don't have anything bound, it's an empty array essentially
๐ค
Can someone help me get an object pickup working with replication? I've got two problems. My basic flow is
- Walk up to an object with an interactable component
- Play lifting animation
- Anim notify triggers an event to actually trigger the pickup
I have this working so that the anim notify is gated by switch has authority and am fairly sure it's all working up to this point correctly. Then things fall apart. This is the basic chain I'm trying to do
Get Picked Up modifies some collision on the mesh of the object. Reposition Held Item for Holding rotates, attaches, and then offsets the object to look visually correct.
why? you just need to replicate a pointer in the pickupable to whatever picked it up
then they can attach, offset, and whatnot on each machine individually
Which piece of this seems off to you?
never multicast stateful changes
if i was outside the relevancy range or joined late then came near you while you're holding that itme
i'd see it on the floor
you are essentially overcomplicating it
if item has a Socket name on the CDO and a pointer to whatever it holding it
it just needs to do AttachToComponent and thats it
as for animation - use a montage, rather then animation
its easier to replicate and sync
Hold up please, I've got a handful of questions to all that haha
and its notifies fire on listen server even if the host camera isn't looking at it
Ok, one, never multicast stateful changes. What do you mean by that? I get that it probably doesn't make sense to multicast something that Sets a var (which could be set on server and replicated), but isn't your described method multicasting a command to, say, call attach component?
That is, things like changing collisions, and attaching, and whatever feel like they're stateful changes.
im not suggesting multicasting anything
im suggesting using a pointer to a component with RepNotify
when that replicates, if pointer is not null, attach and do all the other stuff
Got it, makes sense
Second q, on montages
You say they're easier to replicate, and I think I agree, but I'm concerned I'm not doing it wisely. This is my setup.
(ignore the remote thread)
Is this stupid
First one is a macro I use to play montages, always called by the server. It then passes that information through to a client.
I tried doing a rep notify setup first, where I just sent a struct with the montage info. But I ran into problems understanding how and when to clear the struct, as well as how to utilize the out pins of Play Montage if I call it in a notify.
@winged badger switching to repnotify's solved it in an instant. Thanks so much. Still curious for your thoughts on the montage setup whenever you have a minute. It does seem to work without any problems though?
we use a replicated prop
but we do it via c++ @exotic jay
we do additional things like montage catchups, etc
I m seeing this montage catchup first time.
Can you explain this please?
its timestamped, network clocks are synced, client will adjust the playerrate and/or start time if it differs too much from what it should be
if its a long montage and player becomes relevant, the player seeing it for the first time, will see the montage from the start
we work out the difference and play the montage from the correct time
so for example, our dead monsters don't get up on their feet to play death montage if you walk into pile of corpses from outside the relevancy
nor play the spawn montage again
interesting, good to know
though the most usual use case is vaulting
where players see monsters doing vault action no where near vaults ๐
or doing a random attack no where near anything
multicasts don't really cut it for that kinda thing
for the time being all my gameplay logics are derived via GAS, does GAS also have this problem?
if you use the montage node in an ability it has a kinda catch up system
but only if you use the one via Gameplay Tasks
also remember that system is highly limited
one montage only at a time, and only on the main skel mesh
maybe ill get my new montage task finished up
and release it
will this be problematic if my character have sub-skel mesh with animation?
it only plays montage on a single mesh at a time
if you run another node, it will cancel the first one
ohh i see
and you cant select what mesh
right
my new task i was working on solves this
by encapsulating that inside the task itself
not forwarding off to the ASC
do you any gist of this task? can I have a look.
no
then I will have to implement it.
I will do that, now I have problem statement and approach.
thanks a lot @meager spade and @winged badger
Hey guys having some weird behavior
I have an actor component responsible for replicating some values
For whatever reason UE4 seems to be serializing the entire component - any idea why?
Here is a warning that keeps popping up. It clearly takes a while to perform this serialization
[2020.12.21-07.45.34:056][786]LogNetPackageMap: Warning: Long net serialize: 36.619884ms, Serialized Object [OBJECT NAME HERE]
serialization seems intermittent and unpredictable
no clue why it is happening
What do the values look like ?
@meager spade is there any decent way to handle this in bp? Sounds like you could hypothetically unnormalize the starting position input and try to start it at the appropriate delta, but that sounds annoying.
set of 3 vectors
Lets say I have 4 characters, each of them has a light actor attached to their player character. I want to be able to press a button and toggle the light on and off. When I toggle the light on and off, I'd like the other players in the world to see this. Each player should manage their own light visibility state. We've started off by putting the on/off visibility in the player state and we can prove through onRep notify the value for the owning actor is getting flipped on and off and we're seeing the light toggle. However, the 3rd party individuals are not seeing any state change or light actor change on the actor that originates the event...should we be firing multicast RPCs to notify the others to update their version of my pawn? That feels weird... I thought the whole idea w/ PlayerState replication (and the associated pawn) is that this would properly sync...what are we doing wrong?
Hi guys, experiencing an issue with making my game multiplayer. I've managed to make a door 'open' correctly for all clients, and all of them have the interact function working. However...Although the door's open animation plays, and the static mesh 'swings open', the collision remains in the same place, making clients unable to step through the door. I've done a good bit of googling and haven't been able to find anybody experiencing this problem.
Note: The collision is a collision set to the static mesh itself, not a box collision or something added onto the blueprint.
As far as I can tell the statich mesh's collision should move with its position, and there's no BP function to move the collision itself. Any ideas?
The only solution I've managed to come up with is disabling the mesh's collision entirely when the door is opened...But that means being able to walk through the actual door, which is obviously not desirable.
if you rubberband on it, that means the location is desync'd between client and server
we had a fun time getting doors to work reliably in our game
This is my first attempt to wire up multiplayer in UE4 lol. There's no rubberbanding--and not even the 'server' character can walk through the door, oddly enough.
@lost inlet any possibility you could walk me through how you got it working a little?
holy fuck lol
it seemed so simple to get running based on the guides i've seen on youtube
like I said it's working other than the collision
and those guides had 0 issues with collision, it "just worked" so to speak
can't figure out why my collision isn't moving with my mesh
our doors allow you to shoot the hinges and breach the door
which is not going to be applicable to every type of game
but it's stuff we had to make sure worked over the network
ah yeah that's pretty fancy
Best one was kicking the doors in sandstorm
yes
๐
if your door just has an open and closed state without being able to be opened partially, you would just have a state variable with an OnRep
you would have to make sure any rotation or changes in collision are run on both client and server
the issue is that as far as I can tell, the collision and mesh are supposed to go "hand-in-hand"
there's no 'set relative collision', for example, as it's supposed to have the same position that the mesh does consistently
as far as I can tell there's no way to update the static mesh's collision at all--i'd have to make a box collision with blocking collision on the blueprint to manipulate it
and in the guides I've watched, they've never had to manipulate the collision themselves, it always seems to update with the door's mesh moving
hey quick question, a slider in my widget, when i click and drag it changes the float value but the slider wont move with my mouse, confused
yes but if it's desync'd between client and server then you get issues like that, that's why I mentioned rubberbanding
Do you need to save and load in multiplayer individually? Also do the players have to join the lobby prior loading as well? I have a steam multiplayer project trying to understand and get it to work. THe save and load works in standalone and 1 client currently.
what is saving anything to do with steam
sorry let's say only multiplayer nvm steam
well I know nothing about your implementation and there's probably 100s of ways of implementing a system like that
if it's just saving actors and their states and the actors are replicated, wouldn't this only need to be done once by the server?
So when I start a multiplayer I choose 2 clients, since one client will act as a server, since i'm not gnna use dedicated server
Ok so let's say the server saves and load the game. During game load do the players have to be present in the lobby and connected via session
the server should be the authority over this, there is no point loading anything on anything but the server
any state or actors the save game restores should be replicated
That I have but the second question about players being prsent in lobby
well like I said, I know nothing about your implementation. if you're using replication systems, it should be resilient enough to account for late joining
well that's definitely not enough information
I don't know what your implementation looks like
how is anything saved? how's it loaded? what does the server log look like when the client gets kicked?
Ok let me try to give you more info
So from the widget I click on load game after 2 clients have joined the lobby
click event connects to an event in my game instance
the UI is irrelevant here
there I unload lobby and load gameplay level
From game instance I call the Load Game event which is in another BP
you're not giving us any technical information of how your blueprints actually work so there's 0 way for us to help you lol
no
I think my save and load is done on server for individual only
The save system uses the player name to determine which save to load when a player joins a server.
IS this right in game instance? https://gyazo.com/4019eb7578774f8f47bb805f7518f548
rip it's BP
but the session finding stuff is pretty irrelevant for the saving/loading system
btw @summer tide i would advise NOT to use the player name
what if there are some weird chars in the name?
always use some kinda ID
oh yeah that's bad
had an incident when he tried to use the steam name for a filename in windows, did not end well
hence why i mentioned it ๐
well it was only that nobody with weird chars in steam name could save any progress
weird unicode characters in names is pretty common on steam
having to rewire that mid steam festival demo without nuking everyone's progress was a stress i could had done without
also since anyone can change their name to anything, you could also steal someone's else's save
So with this setup i'm trying to see if the player shows up. I'm running the project in two diff PC. connected to diff steam account.
After host is in lobby and the other client tries to find a game. It doesn't show up but in editor or launching the game from the same pc I see the server list
I only see the host in lan mode
@meager spade @lost inlet Do you know what's wrong? I'm still using the default coe in engine ini file.
I'm trying to test from 2 diff pc prior saving and loading i'm having issue joining the host in lobby.
thanks!
Anybody knows about Advance Session plugin?
@gleaming vector have you tested the new cmc you linked from the new networking plugin? I tried to use it in 4.26 but it just crashes for me.
New CMC? ๐
networkprediction
https://github.com/EpicGames/UnrealEngine/commit/e8ad1938cc1c8e1e2dee4b32b092c163fde580e2 you guys talking about this, right?
Yeah. I figured it wouldn't work yet but still wanted to give it a go
If anyone figures it out though, feel free to let me know :p
If you use gas โฝ, don't try it yet.
how do I serialize a float fixed and compressed ? for instance my range is -3000 to 3000 and I want it to be scaled into 8 bit.
I found WriteFixedCompressedFloat, ReadFixedCompressedFloat but if I use them with low NumBits I get compiles error
The easy way is to re-range the float from 0-255 using FMath::GetMappedRangeValueClamped
then static cast to uint8
and vice-versa for unpacking
I was doing something like that but it did not support sing
looked WriteFixedCompressedFloat source and it seems complicated to me,
It's not for ranging floats, it's just for compression for lower accuracy
uint8 Compressed = static_cast<uint8>(FMath::GetMappedRangeValueClamped(FVector(-3000.f, 3000.f), FVector2D(0.f, 255), SomeFloat))
Compression is as easy as that
float Uncompressed = FMath::GetMappedRangeValueClamped(FVector2D(0.f, 255.f), FVector2D(-3000.f, 3000.f), SomeByte);
I am a bit of a newbie here so maybe this is a silly question.
From reading EXI super-duper-compendium I understand that GameMode only exists in the server and contains the game rules.
However, some of this rules must be known by clients... what is the correct way of doing it? ๐ค
Writing it to the player GameState on connection? ๐ค
thx โค๏ธ
more silly questions: If I have an event marked as "run on server" (an RPC, right?), should my client code (say, a player input) check that it is indeed a client and not authority before calling the other event? ๐ค
riiiiiiight, has authority is to double check before running a multicast ๐ค
hi , a beginner question.
i wanna make mobile multiplayer game using listen servers
how can i do it for free ? what should i look for
i think steam subsystem isn't for mobile
as far as I understand, either you use a network subsystem (like steam, facebook, or something you coded your own) or ask the user to punch in the ip adress of his friend ๐ค
is there any free subsystem that i can use for mobile
a quick google search spewed this: https://redpointgames.gitlab.io/eos-online-subsystem/
no idea how good or bad it is ๐คฃ
Use Epic Online Services in Unreal Engine! With support for authentication, friends, sessions, parties, presence, stats, achievements, leaderboards, Player Data Storage, Title Storage and peer-to-peer networking, this plugin has what you need to build games on top of EOS.
Here you can find some of the classes that exist, Google, Amazon, Twitch...
https://docs.unrealengine.com/en-US/API/Plugins/OnlineSubsystem/FOnlineSubsystemImpl/index.html
I am changing the player collision response to a layer.... from the client.... and the server doesn't complain 
this shouldn't work...
@frank birch What machine is actually executing the change?
client ๐
(i use a print string right after and it says client)
but the server doesn't correct my physics object 
I am doing a "semisolid" platform, I set the player collision to ignore the semisolid layer depending on his speed and other stuff
it works, playing as client, however.... why? 
(I am using unreal's character)
Why would I be getting this error sometimes? It's rare
[2020.12.22-17.33.32:447][718]LogNetSerialization: Error: FBitWriter overflowed! (WriteLen: -1, Remaining: 7628, Max: 7628)
[2020.12.22-17.33.32:447][718]LogNet: Warning: Can't send function 'Server_SendMove' on 'CDTurretReplicator /Game/Maps/Deadwood_TestMap.Deadwood_TestMap:PersistentLevel.CDWarhawk_0.ChassisComponent.Turret.TurretReplicator': Reliable buffer overflow. FieldCache->FieldNetIndex: 2 Max 4. Ch MaxPacket: 1024
[2020.12.22-17.33.32:458][719]LogNetSerialization: Error: FBitWriter overflowed! (WriteLen: -1, Remaining: 7628, Max: 7628)
[2020.12.22-17.33.32:458][719]LogNet: Warning: Closing connection. Can't send function 'ServerUpdateState' on 'CDTrackedMovementComponent /Game/Maps/Deadwood_TestMap.Deadwood_TestMap:PersistentLevel.CDWarhawk_0.MovementComponent': Reliable buffer overflow. FieldCache->FieldNetIndex: 3 Max 4. Ch MaxPacket: 1024.
Seems to happen on initial join. Then, the client gets kicked out shortly after
Is it possible to stop PIE from calling BeginPlay?
As far as I can see, they more or less enforce it
Are you sending RPCs on tick or something?
What actor or class are you trying to prevent from running in the editor?
Well, logcally, BeginPlay doesn't call before the Game starts
If you delay the start, it shouldn't call BeginPlay
But PIE is like "Hey, lemme call it anyway."
But why would you want Begin Play to not be called?
Because the game hasn't started yet
void AGameModeBase::StartPlay()
{
GameState->HandleBeginPlay();
}
void AGameStateBase::HandleBeginPlay()
{
bReplicatedHasBegunPlay = true;
GetWorldSettings()->NotifyBeginPlay();
GetWorldSettings()->NotifyMatchStarted();
}
That usually handles that
But StartPlay isn't called yet, cause Delayed (as wanted)
But PIE is calling BeginPlay through a second code path
...
FGameInstancePIEResult UGameInstance::StartPlayInEditorGameInstance(ULocalPlayer* LocalPlayer, const FGameInstancePIEParameters& Params)
Hi. I have a question. I will be working on creating simple 4 players multiplayer game. Only playing with friends, nothing huge. I don't want to host dedicated server online, therefore I want to go with Listen Server, so one of the clients hosting the game. That's not debatable, that's the system I will be going with, I know its pros and cons.
My only question is.. do I need to ask my internet provider to grant me public IP, or should it just work using my public ip right now?
By public IP I mean that normally within your household broadband, you cannot normally host servers until you specifically ask your internet provider for it, and pay extra or have business network.
Is that the case with listen server for UE4 as well, or should it just work(maybe UE does some magic)?
If I need that public IP, then how do other games do it, so that they have listen server or peer-to-peer connections directly between players, without them needing external IP?
By public IP I mean that normally within your household broadband, you cannot normally host servers until you specifically ask your internet provider for it, and pay extra or have business network.
Ehm
ListenServer can host without that
Just need a proper NAT PunchThrough + MasterServer
e.g. via Steam
No need for a public IP
You can't get a static one in Germany unless you are a business :D
@atomic vale you will want some sort of NAT punchthrough. Usually your OnlineSubSystem handles that.
@atomic vale for testing you can just forward the unreal engine ports and direct connect to your IP address.
yeah most ISPs won't care if you're running a small server on your network, especially if it's not being accessed frequently. It's only when you start to get into having major traffic into your home would they care that you're hosting something.
Does any 1 know if theres a way to detect if steam is active, be it through c++ or BP?
Yes, but it requires you to implement Steam's online subsystem.
If you create a blueprint function library you can do this:
.h file:
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Online.h"
#include "OnlineSubsystem.h"
#include "ThirdParty/Steamworks/Steamv147/sdk/public/steam/steam_api.h" //This line may need to change based upon what version you have
class IOnlineSubsystem;
/**
*
*/
UCLASS()
class GASDOCUMENTATION_API UGDBlueprintLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
// Retrieves the current Steam session ticket available on the PC.
UFUNCTION(BlueprintPure, category = "Steam")
static FString GetSteamSessionTicket();
}```
.cpp
#include "GDBlueprintLibrary.h"
FString UGDBlueprintLibrary::GetSteamSessionTicket()
{
if (SteamAPI_Init())
{
IOnlineSubsystem* OnlineInterface = IOnlineSubsystem::Get();
FString SessionTicket = OnlineInterface->GetIdentityInterface()->GetAuthToken(0);
return SessionTicket;
}
else
{
return FString(TEXT("0"));
}
}```
If it fails to get the ticket, steam is not open and online and will return "0"
May need to change the class name declarations in the .h to fit your project too.
You will also be able to call "Get Steam Session Ticket" in blueprints as well to get the value.
ty
did a bit of diging in google and found a simpler solution with the advanced sessions plugin which i alredy have
if u do "get steam persona name" and it returns 0 then steam if not running
Nice, probably does the same kinda call.
Yes, I have to send turret data to replicate every tick. One for each client to send up and then there is logic to receive data on the simulated proxies.
It floods the network, especially if you're doing reliable calls.
the work around is turning out to bee to messy might just have to use ur solution
Don't send a reliable call every frame. Mark control variables as non reliable.
This is my implementation:
void Server_SendMove(FCDTurretMove Move);```
So it already is unreliable, not sure why I would get Reliable buffer overflow. on that function call then
What do you mean to set control variables as non-reliable? I thought you can only set functions to be reliable/unreliable
I mean sending over dynamic analog things like aim rotation or input vector or whatever. Anything continuous
wont calling init on steam again cause issues?
To be honest, I'm not sure. In my use case, I'm only calling it on a client PC and using the session ticket. I don't use any other Steam API functions.
i cant even compile ur code lol
its complaining about a bunch of unidentified stuff
guess i will google it some more
This tutorial tells you how to set up whats needed to get the session ticket, but in my case I used my blueprint function library instead of creating a C++ character
https://www.youtube.com/watch?v=4CgeAxiS19s
This tutorial is for those that use a backend service (usually a plugin), such as GameSparks or PlayFab and want to get Steam Authentication working in Blueprints. Also, sorry about window being cut off to the left, doesn't affect tutorial at all Please consider supporting me with as little as a dollar a month: https://www.patreon.com/victor...
@winged badger @lost inlet
Ended up using in-editor features.
The Switch SDK has a input keybind that you can change the actual physical mapping of those buttons, so they work in the menus as intended without any extra code involved. Just got to map the actual in-game keybindings when the platform is the switch and that's it
Thanks. So what I did now, I integrated minipnpc library into UE4 to port forward, and it works, forwards all ports we need just fine, but there is additional issue. Everyone can easily connect to me, but if anyone hosts they can't connect to him. In other words, only I am able to host, nobody else. We tried disabling firewalls, port forwarding manually, nothing seems to work. I have no idea what's different about my network. None of us have business network. None of us applied for public ip, yet only I am able to host properly. Master server is something I'll add later, at the moment we just want to connect by sharing our IP
The minimum amount of steps necessary should just be to have the project, and forward the ports. Are you sure those ports aren't blocked when your friend hosts?
Well, I am never 100% sure about it, but I did set up port forwarding for them myself, and I think it should work just fine
Maybe lack of NAT punch is what's missing?
Just forwarding has always worked for me. How are they joining?
simply by open xx.xx.xx.xx
we always use standard 7777 port
And it works immediately when I am hosting. Although I am in UK and they are in other parts of Europe
But whenever anyone else is hosting, nobody can connect to him, even me
problem is normal routers use NAT to map incoming stuff to the correct device
you connect using the IP, the router needs to make sure it gets to the correct endpoint, this is the main disadvantage with home networks and a single IP. You will need to use something that sets up a punch through, so it goes direct to that machine. You really don't want people to have to adjust there router settings for your game, which is why things like Steam, setup a nat punchthrough and you can connect in mostly all cases (there are exceptions of course)
Yeah, I don't want players to play with any of this stuff, which is why I integrated UPnP NAT-PMP library o port forward all of this automatically. But that doesn't seem to be enough. I need to educate myself on the NAT punchthrough.
But since our game will be 100% deployed on Steam... do you recommend using existing Steam libraries for this?
I am not going to use dedicated, just listen
yeah we just use steam, not had any major issues or reports of people not being able to connect
So steam libraries actually provide API to do the punchthrough as well as the master servers?
we dont use master servers
we use steam lobbies
and this provides a way to list games, etc players can join
That's great. But is it all compatible with UE networking? Or do I have to use some kind of steam networking system to run the game? I am guessing that steam works simply to figure out what port router chose to send packets outside the NAT, and then just populate it through that servers lists?
steam does it all
you don't connect using IP
this is what a lobby looks like with steam lobbies
But it's still using UE networking then?
You have the option to use steam sockets as the netdriver.
yes we use steam as the netdriver
When turning on the steam OSS I believe it turns on steam sockets by default
Cool! I'll try educating myself on that steam net stuff tomorrow ๐ Thanks for clarifying that for me!
steam is not too bad
this is how you connect to the host when using steam lobbies UKismetSystemLibrary::ExecuteConsoleCommand(this, FString::Printf(TEXT("open steam.%s"), *GetCurrentGameLobby().LobbyOwnerIDString), UGameplayStatics::GetPlayerController(this, 0));
you don't use IP's (you don't know IP's)
Nice one! Thanks a lot. Does it provide option to put password in a lobby or something like that? Or is it already something to implement ourselves?
not sure if there is a password system in steam lobbies
i don't remember ever seeing one
this should be something that is trivial
Because I would like to be able to only join session with our friends, not particularly having a whole list of available sessions
you can store lobby data, which can be a password, upon connecting if that value is non-empty, then you ask them for the password
then compare, if its wrong, don't join
like i would do this in the server browser
before attempting connection
you click on an entry, it checks for password, shows dialog, match password, reject or accept
Yeah of course, that just introduces risk of cheaters joining the session, if password is verified locally
would probably want to store the password encrypted
and only match encrypted versions
you could have the client send the password over to the server/host when they join, server kicks them if it doesn't match
it's not like you lose control over the game when you are using steam lobbies
right, that sounds good
plenty of ways to do it
either prejoin
or whilst joining
i would likely do it prejoin
Cool, I need to see how that whole thing is handled, then I will definitely pull something out
You helped me a lot. Thank you
Hey I'm really stuck with something and I have spent a lot of time looking for workarounds but found nothing suitable.
I'm trying to find out if there is a way to use something similar to Instance Level (by name) to spawn a copy of another level at a specific position in such a way that it is replicated to the clients (Which is not the case for that function). Do you guys know of a way to achieve that/work around it?
hey guys i wanna ask is there getping() fucntion equivalent in bp?
or its this replicated variable one
Is it possible to replicate some actors only to specific clients?
without manual RPCs
thats my current setup right now
@round roost override IsNetRelevantFor in C++
and you can adjust who will get it
GetPing just returns Ping
in BP you just use Ping, C++, you use GetPing
in the character?
what you mean?
the actor you don't want to replicate to specific players, you have to override its IsNetRelevantFor
How can i make smooth replicated movement in BP's? Everything i try to do ends up rubberbanding the client or not updating to the server/ other clients.
@heady python What kind of movement?
character movement. WASD and jumping/crouching
Should be pretty smooth by default. You're just using AddMovementInput for WASD right?
Jumping should also be replicated fairly well with the Character's Jump/StopJumping functions, and I recall there being a default crouch function as well. If you haven't changed any settings, these should all function fairly decently over network.
what's the best way to get network stats and debug?
And also getting variables from a weapon to the HUD? The HUD sees the weapon reference on the client, but the values all read 0, despite being replicated
weapon can just register with the HUD
on BeginPlay or some such
if its Owner is LocallyControlled
The HUD has the weapon reference on the Client.
I've set it up so that when the weapon fires or one of the variables is updated, it calls an event dispatcher.
The HUD has bound an event to those dispatchers, so that when the the weapon fires, I can pull the reference to the weapon and get the variable, then pass it to the ammo counter.
The event dispatcher doesn't fire on the client though. So I have a second event on the character that calls the update on the HUD. This event does fire every time I shoot, but the ammo count reads 0 every time.
the ammo and dispatchers are set to replicate, and the weapon firing and variable updates occur on the server, called by a Gameplay Ability.
have you verified the client has good ammo counts?
you can access the HUD Actor easily, from anywhere that has world context
GetGameInstance()->GetFirstLocalPlayerController()->GetHUD()
what i am suggesting is trying to inject the weapon dependency into the HUD, and then having the HUD instantiate your weapon panels after receiving it
rather then relying on order of replication for that reference to be good at the time you do the delegate bindings
The reference is set when I equip the weapon
And I can verify it's always a good reference
on start of the game, if weapon is spawned at runtime
I am finding that the Client is not getting good values for the weapon, they take a while to sync up