#multiplayer
1 messages · Page 191 of 1
oh I know
ffs
yeah I mean in all fairness that video probably gets you where you want but yeah terminology lol
yea
I'm almost done with multiplay replication shit
then i can finally work on art assets
nice
yessir
im working on a quiver system in multiplayer
like bows and arrows?
and getting annoyed cause everythime I think im done I think of something i wanna add
yep yep
this is why i have a production document on my gdd in notion that's basically a priority list
character physically pulls arrows out of a quiver
i put down the bare minimum of what i consider each system to be as "done"
then make a priority list of the systems
yeah I need to flesh mine out more lol im pushing for an alpha test soon.....maybe
as long as it works, it's done - Cat
I wish I could work like that lol
"it's a prototype dont worry" - tomtom
here's my priority list rn
- PlayerController
- Design player controller with actor components in-mind
- Be cautious of replicating via steam
- Inventory
- PlayerStats
- Multiplayer
- Basic Lobby
- Basic Main Menu
- Mission System
- Choose randomly between Extraction, Tasks, and Collection
- Mission Rating Subsystem
- The results screen
- Class Selection System
- Change special slot in PlayerController’s inventory
- Procedural Interior
- Majority already made, needs specific design adjustments (1 entrance, 3 exits)
- Needs five different interior modular components
it's very cague
vague
but i break it down further below that
and this is different from a feature list
my feature list is probably twice as long lol
Do you really need to care about how the PC is replicated via steam?
oh yesd
very much so
depending on how you want to couple your features with how you want your player to interact with them
like for example
i have been stuck on getting my dumb fucking inventory system working and replicated
(been posting that here for the past 3 days)
and it really depends on what you want the pc to interact with
same but what's the thing to do with steam
I don't know if it's any differnt between the different online subsystems
But Steam has stuff that relies on your unique net id which is from on the player controller
player controller --> unique net id --> steam profile information (like your avatar picture, username, etc)
yea, I'll just go through the SDK and read a lot about it soon
advanced steam sessions, the plugin at least, doesn't have that great of documentation
yea id rather read the steamworks api
API or SDK?
uh
all good
yea sorry my brain is fried lol
the recent culprit in a bug
can yall guess what it was
not connecting exec pins lol?
yes 🙃
been there xD
i double checked after testing the feature haha
man, the amount of deep diving ive been doing trying to grasp which method of replication/renotify/ROS stuff..
What might I be missing?
Client0/server can perform an action that sets the location of a scene actor that both client 0 and 1 can see.
Client 1 can perform the same action of relocation the scene actor but only client 1 sees it, but client 0 cannot.
Since it is the location that is not replicating, I thought checking movement would work.
Setting relevence to true didnt seem to work either.
Only the Server can make changes to Replicated properties that Clients will see.
Clients cannot change properties on other Clients.
Since the Location of an Actor is a Replicated Property.
Only the Server can change the Location and have it update on all Clients
Client 0 changing the Location of an Actor will only change it for that Client
Client 1 will not see the change
Unless the Server makes that change.
Ah. Okay. That does make sense. The calls are coming from an actor component attached to the player controller.
Do I:
A) scrap the actor component and move all logic to gamestate? or
B) add server calls within game state that the actor component calls out to?
Well depends entirely on what you are trying to do.
Why do you think you need to move things to the GameState?
A couple of reasons ( please audit my thinking)
Because it relates to the way the scene looks.
Gamestate is shared and accesible to the players
and gamestate itself can have a ROS call, I cant seem to get actor components to do that.
Unless its fine to call it from the player controller.... as a server action.
What do you mean by ROS?
Run on Server
making a custom event set to run on server & reliable in this case
Right
So the PlayerController can do those as well.
The PlayerController is the net connection between the Server and a particular Client
So it can do both types of RPCs
Any Actor or Actor Component that is either attached to or is owned by the PlayerController can also do both types of RPCs
The Controlled Pawn for example
Or the PlayerState
These arent the same Actors as the PC
But they are owned by one.
Which means they can make RPC calls.
Oh, for whatever reason I thought the Actor Component couldnt do that. but it was because I was trying to edit Interface functions and mistook it as just any events.
Have you read the Network Compendium? It sounds like you havent. It is the first pinned message in this channel.
You should read it over a couple of times.
Awesome. Okay. This may work then. ill give that a go and wrap the calls I need into a server called event.
I have read portions maybe twice only now, and eatched a couple of videos in general
the image is fuzzy but its all coming together.
Will do!
Thank you for the concise help by the way. I appreciate that.
Wrapping the logic into a server call within the actor component worked.
Still reading the compendium but glad that got me a step forward.
Thanks again
Anyone have any resources on writing your own net code and standalone servers? Been dumpster diving around the internete, and there doesn't seem to be a lot on that topic
Hey I have a replicated variable that is invalid on client, how can I fix that?
Board.h
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = Board)
TObjectPtr<UBoardContext> BoardContext;
Board.cpp
pieceActor = GetWorld()->SpawnActor<AActor>(actorClass, transform, params);
IPieceInterface::Execute_SetBoard(pieceActor, this);
Figurine.h
UPROPERTY(Replicated)
ABoard* Board;
Figurine.cpp
// called on server
void AFigurine::SetBoard_Implementation(ABoard* board)
{
check(IsValid(board));
check(IsValid(board->BoardContext));
Board = board; // PASS
}
// called on client
void AFigurine::OnBeginHover(AActor* touched)
{
if (!isTemp)
{
check(Board);
check(Board->BoardContext); <==== KABOOM
Board->BoardContext->ShowPieceInfo(position);
}
}
UObjects don't replicate without extra work so unless you've followed this guide, it won't work:
https://dev.epicgames.com/community/learning/knowledge-base/7y39/unreal-engine-using-the-replicated-subobjects-list
ah ok I have googled it but never found anything about it
If it's an actor, just use an Actor Component and save yourself the trouble
BoardContext I mean
Oh that I can't multiple boards can have the same context
it didn't crash but i got booted to main menu, for some reason some code is repeating
ZenLocal: Error response received from PutCacheRecords RPC: from POST http://[::1]:8558//z$/$rpc -> 507
I used this code:
if (IsValid(Board))
{
RemoveReplicatedSubObject(Board);
}
Board = board;
AddReplicatedSubObject(Board);
same for BoardContext on the other side
it looks like it made the event trigger for everyone but i had set the figurines as replicated already
it seems that it fires beginplay everytime it is added to the list
nm it's caused by another actor XD
Ok it looks like I need more stuff like IsSupportedForNetworking
Thanks for the help
That’s the issue yeah. The default nodes don’t do anything I can’t recalll why. There was a fix on a discord I was in but most of the time the recommendation was “just use advanced sessions”
advanced sessions is also old
not sure if that still work
that plugin is like for ue4 lol
My error was caused by this, it popped in the logs when i switched from PIE to standalone: Warning: Property Board::BoardContext (SourceClass: Board) was not registered in GetLifetimeReplicatedProps. This property will not be replicated.
However I learned about replicatedsubobjects so it's all good 🙂
best to ask in #online-subsystems
ok
Ok, I solved my issue with the replicated Subobject, however this subobject also contains a replicated subobject, where am i supposed to go from there? It crashes at first invocation of that subobject on client?
I've tried to change the first subobject to actor but then my first issue came back
Can I go AddReplicatedSubObject(Subobject1->Subobject2) ?
Hi everyone. I want to create my custom Channel to transfer specific commands over network
UCLASS(transient)
class DLCORE_API UDLCommandChannel : public UChannel
{
GENERATED_BODY()
protected:
virtual void Init(UNetConnection* InConnection, int32 InChIndex, EChannelCreateFlags CreateFlags) override;
virtual void ReceivedBunch(FInBunch& Bunch) override;
};
I initialize a connection to listen server
void NotifyAcceptedConnection(UNetConnection* Connection) is triggered and then I try to invoke a SendBunch in my custom channel that is opened on the connection, but client doesn't receive anything
Can someone help me with this? Maybe I missed smth in channel configuration or in network connection process. Thanks
Is there a way to execute console commands on the dedicated server? Can I manually tell it to call a function without going through a client?
I'd like to do something that lets me warn players that the server will be shutting down in 5 mins. Stuff like that that needs to be manual. What's the best practice for that?
One way is to create a special debug file that would be read by the dedicated server and then manualy add command there
you can use luau or some equivalent scripting ability
Or you can open a separate debug port on the dedicated server and write a special debug application
Interesting. Ok thanks
It'd be nice if there was some way to create an interface of some sort. I realize the whole point of a dedicated server is that it runs in the background with no viewport, but a barebones menu with buttons would be really cool. Am I asking too much?
you can create a debug client
UIpNetDriver can be a starting point to investigate unreal network code
it won't be a simple task
Gotcha. Yeah, may be a project for another day then. I'll bookmark this though. Thanks!
if you need a quicker solution I recommend to create a simple class that reads data from the debug file and interprets commands you write to
for example: open a file in shared mode, poll every second a text in that file and if you add some text through text editor, read that command and clear the file
Yeah, that sounds like it'll work for the time being. Thanks
This is what RCON is isnt it?
I haven't found RCON implementations out of the box for unreal engine dedicated server. Do you have any examples? I would be grateful
its old - but this: https://github.com/yas-online/UE4-DedicatedServer
to be honest I havent tried - but its on my list of things to muck around with...
Oh awesome!!! I'll check this out!!
Good job this lies and the rcon module does nothing
It's not that hard of a thing to even implement, and I've done websockets and the source engine protocol
not sure if this is worth doing but I was trying to create different components in an actor depending on if they are client or server. Really in this case the server only needs a sphere component.
Problem is I can't seem to GetInstigator()->HasAuthority()) in the actors constructor
is that too early?
It's actually crashing when starting the engine so wondering if it's trying to build the default object and checks for instigator
Hey guys, i have a security concern you guys might be able to give a hand.
So i have a skill tree, close to how the skill tree of path of exile works, with nodes and all that stuff, im thinking about passing that skill tree as a connection option, how carefull do i need to be security wise with that information? do i have to validate the thing in the server or is it safe to passin the connection options?
If you didn't validate, then you could potentially have players sending what could be invalid builds, with only the "best" nodes being specified without any prerequisite nodes.
What info is server side at that time?
thats what i was thinking
none
Validating that it's a valid tree is pretty simple, but validating that the character should have that many points is not.
Someone has to be the authority over what lvl the character is
And what they're allowed to actually have.
to validate im gonna need to pass the info to the gamemode class and that info is all in BP do i was hoping there was a better way
they are allowed to have 20 nodes
What's stopping me from generating a valid max level character and sending that?
well if some one cheats and has 20 nodes when they are suposed to have 10 its not a big deal since they are all gonna have 20 eventually
Yeah, but in the case of PoE, you need to select several +Attribute nodes to reach some of those other special nodes that give some really nice bonuses.
ye thats what i am concerned about
I mean if it's not a problem then go with it. If you're ok with anyone being able to basically say "yup I have a max level character" then that's simple
so far the tree is made in a way that u can either have 4 mediums or 1 big and 2 mediums i think
so i could validate through that
Validating the tree is simple, but you have no way to know if the client leveled a legit character or just created a maxxed out one.
And without validating the build server side, someone could have 5 big and 15 mediums
i realy dont wanna redo the whole tree in the gameMode calss manually
yes that would be the issue
the tree is made in UMG, so all that info inside a UMG called "SkillTree"
the tree itself should be modeled in data somewhere (as a graph)
UMG should just be a VIEW of the tree
"Sending a tree" should be as simple as sending an array of node IDs or node names or whatever a node is.
ye thats what i figured
then you can validate by pathing to the nodes from the start point and confirming that they have the amount of points they should and that it's connected.
the hard part is validating that they got that character legitimatly and didn't just say "yup i got a max level character with this gear with all max level rolls, yup, sure do!"
theres no gear, its a shooter with a PoE tree
I got a question for you since I'm interested in sockets and web app, Is it a must to learn? and will it help me understand some network stuff under the hood in unreal?
As long as you're ok with trusting the client about how many points they have then that'll work.
shouldnt be much of an issue, if they send more than 20 nodes i will just discard the extra ones and they will be forced to have 20
leveling shouldnt be that much of an issue aswell
like league eventually everyone will reach lvl cap
so its ok
yeah if the leveling process is basically a tutorial and not the bulk of the game then sure, go for it.
sending your tree would be the equivelent to sending your choice of hero in Dota. You can't really cheat at it, it's a wide open choice.
whats bothering me is having to pass all that info to a graph in c++
adjacency list
how many nodes do you have total and on average how many connections does a node have?
let me check, usualy its 2 connections but they can have up to 4 i think
i didnt know what an adjacency list was but i think i implemented it, at least it looks like it by wikipedias description
Super simple example.
The tree DATA looks like this:
1, 2
2,3
2,4
4,5
3,6
That represents a tree with those connections. 2 is a branching point with 3 neighbors.
Say you can only have 4 nodes and everyone starts at 1.
MyNodes = 1,2,3,6 is a valid tree.
MyNodes = 1,2,5,6 is not
theres a base UMG node with an array of connections that are other UMG nodes
Yes that's trivial.
Your immutable tree data is a big adjacency list or neighbor list of node IDs.
the players current tree is just an array of node IDs
then u recursively find the path to an "origin" if u want to turn it off or check if there is a connection to turn it on
IWantToChooseANewNode
if NewNode is a neighbor of any of my CurrentNodes (lookup in immutable tree graph representation)
yay
else
bummer
this looks like a good solution, so u just run all the nodes and check if they are neighbours
hell just store it in the order they pick them then that's your tree
to validate
for each node in Player.Tree
Is this node a neighbor of a previous node?
naw
kick
Sockets are just a means of connecting things. You can communicate whatever data you want over the connection and have either side perform whatever actions based on what is sent, including broadcasting messages to all other sockets. It probably won't help you much with learning Unreal's networking on account that most of what you interact with in programming with Unreal's networking is on the Application layer of the OSI model whereas working with a socket is on the Session layer (not to be confused with the concept of "Sessions" that is normally passed around in this Discord, they're two different things), or perhaps even the Presentation layer.
The difference is, if you're making your own socket server, you're basically contstructing what those actual messages are that are going to be sent over the network. With Unreal's networking, these messages are already created for you, but you're basically constructing the data that is used to determine the content of those messages.
they can start from 3 diferent locations
at any time
so that might not be a solution
that'll take special handeling or just make those 3 implicit hidden "neighbors" of a phantom root node
basically node 0 is special and you always have it and its neighbors with the 3 start spots
everyones tree starts with 0
so 0,1,2,3,12,13,14,15 is a valid tree if
0,1
and
0,12
are in the immutable tree representation
I've seen OSI and the layers a little bit
i will think this over, i will still need to put that info somewhere and its not a small tree
I believe there's still a way to go into the files and find how these messages are created (even if they are are created for you)
i might check if there are any odd combinations like more than 4 medium nodes or more than 1 big node
i rly wanna avoid putting that tree down again
Im having an issue with making a replicated container using blueprints. When the player controller interacts with the container, a BPI is used to make changes to the container as server. I'm using a struct array variable to hold the container inventory, I set the size of the array when player interacts for the first time, and I'm using a for loop to add random items to a temporary local array. After the loop is over and the array has its inventory items I set the real replicated variable "S_InventoryItem" Array with the local "lS_InventoryItem" Array. This is only updating the servers array though, the client continues to have a null array. I've tried many different ways to send to client through server or multicast after the server picks a random name from the datatable. Is there something obvious that I'm missing when it comes to using a struct array with replication?
Would that work well? (recursive function)
UPanelWidget* UInventoryWidget::RecursiveChildsFunction(UPanelWidget* CurrentPanel)
{
if (CurrentPanel == nullptr) { return nullptr; }
if (CurrentPanel->HasAnyChildren())
{
for (auto CurrentWidget : CurrentPanel->GetAllChildren())
{
RecursiveChildsFunction(Cast<UPanelWidget>(CurrentWidget));
}
}
else
{
UInventoryCustomSlotWidget* CustomSlot = Cast<UInventoryCustomSlotWidget>(CurrentPanel);
if (IsValid(CustomSlot))
{
InventorySlots[CustomSlot->Order] = CustomSlot;
}
}
return nullptr;
}
are you asking this for the tree?
not exactly but this function go through a tree and check for each of them
i can paste my solution here if u want, i did it in BP tho, as a rule i do everything UI related in BP
sure
so its 2 functions and i am aware it could probably have been one if i put more tought into it
first one gets all the connected nodes of the node u clicked
and then they go into the recursive function and try to find root
@limber gyroIf you store the nodes in selection order it's even simpler
just for each node, check if it's a neighbor of a previous node
does that work with branching paths?
make 0 a neighbor of the 3 starting spots and also a neighbor with itself and it'll work
yes
simplest possible tree that meets your specs that I can think of.
Here's the neighbor list:
0,0
0,1
0,2
0,3
1,4
2,4
3,4
that's 3 starting spots (1,2,3) with a central node connected to all 3
0 is the hidden root node that everyone always has by default just to make the multiple starts work
doesn't work!
there is no order tho, they can go in circles for example
That's fine
im failling to see how that aproach would work
i wish i had a few more points of IQ lol
I'll draw it, sec
so you can see that 0,2,4,3 is a valid tree
but 0,4 is not
just go down the list in order and see if each entry is a neighbor with one of the previous entries in the list
but say for example, if the player sends me a list with 2 and 4
they are both neighbours of each other
and they would validate each other
but the tree wouldnt be valid
0 is implied and always the first node
its the hidden root node to allow for different start spots
ok so 4 and 3
well exactly, but we are only checking for neighbours right?
yes but you'd fail at the 0,4 step
0
0 is neighbor with self so ok
4
4 is not a neighbor with self or 0 so not ok
kicked
ok so the tree would only fail if i any node had no neighbours
but the good one:
0
0 is neighbor with 0 so ok
3
3 is neighbor with 0 but not neighbor with self so ok
4
4 is neighbor with 3 but not neighbor with 0 or neighbor with self so ok
this is not the tree you drew but imagine something like , 0/1/4/5
so 0 and 1 validate each other and 4 and 5 validate each other
thats the order you picked the nodes in
but its stilll not valide
you check each picked node vs all previously picked nodes to see if its a neighbor with at least one, if it is, continue, if not, fail
same test when picking
you wanna pick a node? well, is it a neighbor with a previously picked node? If so, then go ahead, if not, nope
AHHHHHHHHHH
now i get it
i was looking at it the wrong way
your validating fro mthe bottom not the other way around
yeah just confirming that the passed over tree is a valid sequence of picks
ok that actually helped a lot
this line is what made me finally understand
thanks
same test when highlighting nodes you can pick
your save game is just NumNodePoints + Array<NodeID>
as far as the tree is concerned
its effectively pathfinding by checking if you can get to a known good path (the previous nodes)
the only issue would be passing them in order which shouldnt be too hard to do i think
im gonna let this simmer a few days while i finish my node icons and see what i do
i tought about encrypting my node ID's but the client would have to have the key for encryption and that would defeat the porpouse no?
and the mirrors of course. That's the neighbor list representation
ive never explored encription before
you will be cracked day 1 by anyone who cares to do it
rip haha
but it should be simple to store CurrentLevel somewhere
hell it could be an achievement, I saw someone used achievements as a save system before
ideally this info would be stored in the server and just fetched there but i dont have a proper backend and i dont think steam has support for that
what is a server in this example?
could just do serverside everything on each server whatever that looks like, just like Minecraft
if it's just level though, achievements can do it lol
Is thre a way to print debug information about each actor channel? I'm trying to figure out an issue where I think a component isn't replicating but there's no debug info apart from the channel this object should be replicating over
Imo it's a total waste of time as long the data used is stored locally
Anyone that knows what their doing will hack the game anyway if it's worth their time
unless you have a good anti cheat
Need a team to write that and also still not worth it if you don't have proper backend
ex: valorant
Your data is not stored locally
At best local settings is like controller and display settings
ok I've found the issue which is for non-actors, dynamically created objects aren't created client side unless created client side. Now, would it be better design to set up this to multicast a creation function, or treat these objects as actors, if I want them to be replicated at all times to all clients? This is player data I'm trying to replicate, set up to be attached to the game state so that if a player disconnects the data doesn't get deleted.
Also if a player joins in a game after which an object was dynamically created, is that object automatically created or would there be some way to get it to get created on the client?
I think the approach I'll use is this: set the data attached to player states, so it's created on default when the player joins; game state grabs a reference of that object, which I think wouldn't get GCed when the player disconnects; if player reconnects, a function will update server-side from the saved reference of the object to the new object in the player state so it's identical, then replace the old reference
I set up the uobject to be replicated
Well then you must not have done it correctly?
uobjects get replicated, except if dynamically created, as per the docs I read more carefully
if dynamically created the client needs to manually create the object first
"Dynamically Created" as in not dynamically spawned, but rather dynamically constructed?
You have half the picture here.
called in NewObject instead of CreateDefaultSubobject. Created/constructed in runtime
yeah thats the idea, https://dev.epicgames.com/documentation/en-us/unreal-engine/replicated-subobjects-in-unreal-engine shows updated steps/info
Learn how to replicate UObjects in Unreal Engine.
Effectively you need to use an Actor to do the replication for you.
If you are following that guide, you have missed something.
I set the game state (an actor) to do the replication
the issue I found out is as in the doc guide: "The owning actor on the server uses a replicated object reference to the subobject. This object reference is valid on the server since it creates the object, but the reference is null on the client. The replicated reference remains null until the object is created and the reference is mapped."
Client will create the object if it never existed
weird because that's not the behavior I'm seeing. In a simple test I made a blank uobject with a replicated variable, and in my game state's tick function said for it to create a new object of that class (if invalid) and set it to a replicated tobjectptr, and increment the variable. When NewObject is called under HasAuthority() I see the replicated reference client side set to nullptr, and the warning "UActorChannel::ProcessBunch: ReadContentBlockPayload failed to find/create object." showed every tick. When it's not HasAuthority() NewObject is called on client and server and the warning is gone.
I have a variable on an actor that is being replicated with a rep notify. Right now the notification function just prints a message to the screen to show where it has been called (server or remote). It is only being called on the server though. The remote is not receiving the notification. How can I debug this? This is not behavior I expected to be possible.
Can you post your codee
I'm not sure which code to post.
Show where you change the value of the variable, show the OnRep.
First images shows where the variable, InvItem, is set in BeginPlay.
Second image shows the OnRep
Note: the Item type is a replicated UObject defined in C++
UObjects are not replicated
Literally see the conversation above
We talked this over with another user
But I defined the needed functions
virtual bool IsSupportedForNetworking() const override { return true; }
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
Its not that simple...
And if it isn't replicated, then why am I getting the OnRep called on the server?
Please read the guide that was linked
The server always calls the OnRep in Blueprint when the Set XXX node is used
uobjects can be replicated, it requires setting up an actor to replicate them tldr (and osme other stuff)
Then perhaps the piece I am missing is setting up the actor.
but uh new issue related, I'm trying to get the uobject created on all clients via NetMulticast, and the multicast is only running on the server? the function is in the player state which is replicated to all clients, and its call originated from HandleStartingNewPlayer in the gamemode (so server-side)
Oh the jambax article. And the unreal docs article. I have read them both. The one thing I am NOT doing from there is overriding ReplicateSubObjects. That's because I am trying to make this something that can be added to a BP actor and not require the Actor to be defined in C++. Am I trying to do the impossible here? Is a C++ Actor subclass really necessary?
Replicating UObjects is not possible in BP alone
Read the guide.
You cant just simply skip steps because they dont conform to what you want.
OK then. I've been barking up the wrong tree.
I'm going to have to rethink my entire design then
For pretty much 90% of multiplayer stuff, you are going to want to do it in C++
Blueprint is just not extensive enough.
I might be able to use ActorComponent as my base class instead of UObject. There's actually a certain logic to doing it that way anyhow, but it creates other problems since I need to be able to store the data from the component even when the actor is not instanced in the level. And I need to do it in a way that is still accessible using it's special accessor functions. Time to ponder
It is said that one learns from one's mistakes.
I've been doing a lot of learning lately. 😄
It never stops
How do I go back in FBitNetWriter and rewrite something?
Say I wrote var1 then var2, But now I want to go back and rewrite var1 to another value
What are the basic steps for replicating a widget to each client and host? So for example, I have this current flow:
- On PlayGameMode:
- BeginPlay --> On_MulticastStartClassSelection (Multicast custom event)
- For each PlayerController in AllConnectedPlayers, call On_ServerAddClassSelectionWidget
- On_ServerAddClassSelectionWidget (runs on server) on PlayerController:
- Call On_ClientAddClassSelectionWidget
- On_ClientAddClassSelectionWidget --> Create ClassSelection Widget --> Add to Viewport, set ref, set input mode as UI
for some reason, when i test this on a standalone it works fine. however, when i test this when the host and client are connected, it doesn't replicate for either
Here's what it's suppose to look like, this is for the host on a standalone
but it doesnt' show the widget at all when a client is connected
You need to read the eXi pin again on multiplayer guide;
- Widgets dont replicate.
- GameMode does not replicate
no i get that, but the issue is that the widget isn't showing at all
even when I add to viewport on the controller
but youre saying the gamemode doesnt need events with like "run on server" and such?
because it's already on the server 🤦♂️
It only exists on the server
what about for multicast?
I see
your "yelling" something to clients and no one is listening
cause they dont have gamemode
so i would just call each other client directly through connected playercontrollers
why are you calling anything? Just get the controller to add the widget based upon its own class?
well I want each client to see that widget, then see each client interacting with their widget
Controllers only exists on server and their respective player.
So you do something roughly like:
PlayerController::BeginPlay()
{
if (! IsLocalController()) { return };
/// Add widget here
}
That's semi-psdueocode - you get the rough idea
np - and honestly - re-read eXi's guide and Wizard cells guide 2-3 more times over 2-3 more days - I'm still reading them from time to time - there's so much knowledge you cant take it all in on just a few passes
gotcha, i shall study it
How do I make a client send an event to the server in a blueprint when the client isn't the owner? I'm well aware this isn't the standard but for one small part of my game it has to be done.
You would need to manage that through the PlayerController
BP_Lift would need to call an RPC that exists on the PlayerController.
Clients effectively make all RPCs to the Server through their PlayerController.
The PlayerController is the "NetOwningConnection".
All RPCs are routed through that.
Ok makes sense, thanks for your help. I'll try that route. If the players hack it it doesn't matter it won't effect the other players play sessions.
Sweet, it worked. I never would've figured that out. Thanks.
To resolve "Error: Only Local Player Controllers can be assigned to widgets. PC_Lobby_C_2147478133 is not a Local Player Controller"
do I just need a check for "is local controller" before creating the ui widget?
it's somewhat confusing since im adding in player controllers on post login
PostLogin is on the GameMode
The GameMode only exists on the Server
yes
Therefore it is a terrible place to be adding UI elements to Clients
Infact its the entirely wrong place to do it
sorry I might have misworded it
basically i do
On Post Login --> Spawn Player
Spawn Player is attached
Ok?
You should use the HUD class instead for something like this.
But yes, in this case, you just need to check for Locally Controlled
Since BeginPlay is called in all network contexts
hm okay, I was confused since I thought "self" would do that on the locally controlled-self
ah i see
Its trying to setup UI on the Server
okay, thank ya
self is the current Object in the current context
A PlayerController exists on the Server and the Client that owns it.
self is different for those 2 contexts
As they are different Objects on different instances of the program
so shouldnt it do it for all in each context or would it not do anything at all when it encounters an error on "not a local pc"
LocallyControlled means its the PlayerController for the machine that has control over it.
IE: the Player who is playing
right
Which is the only context you should be making UI in
I'm trying to understand the flow of how the server inits a player controller, then the pc adds its widget
The Locally Controlled context
I see
Since UI is only relevant to the local Player
so begin play will be called by the server too, but local controlled context check is needed for ui
on the two contexts
Hey so If i want to get an actor through the gamestate so I can store a reference to it, how would I go about this in a networked environment?
I have this code
playerManager = GetWorld()->GetAuthGameMode()->GetGameState<AATGameState>()->GetPlayerManager();
But I get an error when a client joins the server as it doesnt seem clients know about the world.
Post the Error
Post the full code
Not a snippet
At minimum you should post the entire function scope
will do
The world is returning a null pointer. But I know GameState is stored on server and clients, however I am unsure to access it client side in c++. Or maybe I am going about this wrong.
Exception thrown: read access violation.
__imp_UWorld::GetAuthGameMode(...) returned nullptr.
The world is fine.
GetAuthGameMode is returning nullptr
Because the GameMode only exists on the Server
ahhhh
BeginPlay is called in all network contexts
You should always check your pointers before using them.
so how would I access gamestate without the gamemode?
The World has access to the GameState
You should also be setting bReplicates and bReplicateMovement in the Constructor
Not in BeginPlay
good catch thank you
Hi everyone. What is the recommended way to handle third party APIs that will be called on the server?
Is it okay to package the keys in the server build, or should I route the calls through my own server that calls the third party APIs?
Or, should I fetch the keys at runtime? I'm not sure. Any help would be appreciated!
If the Server is never distributed to Clients, then you should be fine to retain it in the package.
Okay, got it. Do you know how to specify that the keys should only be packaged in the dedicated server build? Should I handle it with C++ macros, or maybe put them in some sort of string table that I specify not to be included in the client build?
Wrap them in an #if UE_SERVER
Great, will do. Thanks
Hi so I am curious what the best way to deal with this is, its a bit of a complicated system. If anybody has the time, any advice is appreciated.
I have a player manager actor storing a list of activeplayers.
I have an interactable actor which uses this playermanager to check if any players are overlapping
If there are any players overlapping, loop through them and determine if any are currently interacting.
I have replicated the playermanager and replicated its activeplayer list property
I have replicated the interactable actor and its overlapping player list property
I have replicated the player and replicated its interacted bool
It seems both these lists are replicating fine, but when I try to access the players interacted bool in the interactable actor even though it is replicated I only get a response from the host client. If player controllers of non-host clients are in the list their interacted bool is never set to true.
at the end of the day It seems a bool on a client side is not being replicated on the server side is my theory.
so player->Interacting() on line 71 returns the Interacted bool from player pawn which IS replicated.
If player controllers of non-host clients are in the list
@tired current You aren't replicating PlayerController Arrays, are you?
Or store the Boolean on the PlayerController, or anything PlayerController that is accessed by SimulatedProxies.
Also, just fyi, the setup you have is somewhat redundant. Why do you need to loop over every Player to figure out if they overlap the Interactable?
You can just maintain the List on the Interactable via Begin/End Overlap events ON the Interactable.
thoughts?
EFTRUintType GetSnuggestFitFromValue_uint(uint64 _val)
{
if(_val < std::numeric_limits<uint8>::max())
return EUint8;
if(_val < std::numeric_limits<uint16>::max())
return EUint16;
if(_val < std::numeric_limits<uint32>::max())
return EUint32;
// Else we just assume this is the best fit.
//if(_val < std::numeric_limits<uint64>::max())
return EUint64;
}
EFTRUintType SerializeIntToSmallestType(uint64& _val, FArchive& _ar)
{
bool bIsWritingDataToArchive = _ar.IsSaving();
// Start with biggest size and work our way down.
EFTRUintType fittingType = EUint64;
if(bIsWritingDataToArchive)
fittingType = GetSnuggestFitFromValue_uint(_val);
// Either has already been updated from above if we are writing to archive, otherwise this updates that enum value.
_ar.SerializeBits(&fittingType, 3);
switch(fittingType)
{
case EUint8:
_ar.SerializeBits(&_val, 8);
break;
case EUint16:
_ar.SerializeBits(&_val, 16);
break;
case EUint32:
_ar.SerializeBits(&_val, 32);
break;
case EUint64:
_ar.SerializeBits(&_val, 64);
break;
}
return fittingType;
}
usage so far is something like
uint64 v = playerPoints;
FTR::Networking::SerializeIntToSmallestType(v, _ar);
if(!bIsWritingDataToArchive)
{
playerPoints = v;
}
doing it because I am storing it as uint64 but dont want to replicate that whole size if I dont need to every time the players points update
Hello, here is the situation: in my lobby, I have a game mode and in this game mode, I have set the default pawn to NONE. When the scene starts, the camera is in the ground. How can I set a view angle for all the players in the lobby?
I guess this is somewhat smart. I could do something similar for the DeltaSerializion stuff I did to NPP.
At the moment the programmer would define the int size matching the property num.
But I can't comment on how "correct" it is. I'm sure there are UE versions of the std functions for example.
Do you have a playerstart?
yes
@thin stratus please i need help
Try adding a camera actor?
I've already done it
it doesnt work
The way I usually do this is via the PlayerCameraManager.
You can make your own as a Blueprint, the same way you can create PlayerController etc.
You set the Manager class in your BP_PlayerController (it has a property in its ClassDefaults, similar to GameMode).
Then I make an Actor that has a Camera Component on a SpringArm, optionally letting it rotate around its own center.
I place that into the Scene.
In my BP_PlayerCameraManager, I then override the UpdateCamera function (not sure the exact name, but you can return Location, Rotation and FOV) and do a (here very okayish) GetActorOfClass(MyCameraActorBPClass) and feed the return the Location and Rotation of its CameraComponent (World). That will however make it so that you ALWAYS have that Camera, even if you have a Pawn. If you want that to only happen if you don't have a valid pawn, you can get the "ViewTarget" in that function and check if that casts to your Player BP Class without failing.
That's a bit more involved setup, but gives you as much control as you need.
An alternative is to set the ViewTarget to the CameraActor somewhere on BeginPlay
That skips the PlayerCameraManager setup, but I can't promise that you won't have a small duration in which the camera is in the ground again.
SerializeIntPacked is available too
I think SerializeBits is already somewhat doing well there too.
Good day. I ran into a problem that my Dedicated Server, which works together with the Steam API, does not see the server anywhere, except for the local server. I looked on the Internet and was informed that most likely the problem is related to the ports that I opened.
However, I was unable to solve it. Tell me exactly where the problem is.
with FastArray, when using MarkItemDirty, can i just pass a ref to my item struct, or should i use Add_GetRef
from what i found i should use Add_GetRef when marking item dirty if its a add, and a regular item struct if i modify an item
also, in the source code, its says to use MarkItemDirty when modifying an item (in the "how to use" big comment)
but in the MarkItemDirty function description, its says "add or change"
what?
"what" on what sentence 😅
not sure what your asking
why do you need Add_GetRef when marking dirty
sorry im a bit confused at what you mean
i am using this when adding something
FPGFastSlot NewSlot = FPGFastSlot(SlotVisibility);
if (IsValid(Item))
{
NewSlot.Item = Item;
}
Slots.Items.Add(NewSlot);
Slots.MarkItemDirty(NewSlot);
but i just found a code snippet where some guy uses Add_GetRef
void MyActor::AddItem() {
FExampleItemEntry a;
a.ExampleFloatProperty = 3.14;
a.ExampleIntProperty = 1234;
DeltaTest.MarkItemDirty(DeltaTest.Items.Add_GetRef(a));
}
you shouldnt use the ref for marking dirty
okay
it has issues with the address
example i do
MarkItemDirty(Players[Idx]);
// server calls "on rep" also
Players[Idx].PostReplicatedAdd(*this);```
all though this can work
this reminds me a question i had in my head, if im the listen server PostReplicatedAdd doesnt call ?
FBlah& NewEntry = Entries[NewEntryIndex];
MarkItemDirty(NewEntry);```
looks like thats why you call it
and is how i usually do it
yes those callbacks are client only
but i hackily call it on server
to reduce code paths
i also call PreReplicateRemove on server BEFORE removing from the array
ig now i need to find out how do i emplement the struct functions in my component
eh?
like, when PostReplicatedAdd / PostReplicatedChange is called, do something in the inventory component (where the FFastArray is stored), to do stuff like calling a delegate used by the HUD
didnt find anything on google this past few days
never worked with callback function in struct before
how to "know when and what" some fucntion got called
what do you mean when and what
oh, so i just go to cast ?
well you said the fast array has a ptr to the object that holds the fast array ?
: OwningInventory(nullptr)
{
}
FAresInventoryList(AAresInventory* InOwningInventory)
: OwningInventory(InOwningInventory)
{
}```
// Replicated list of items
UPROPERTY()
TArray<FAresInventoryItem> Entries;
UPROPERTY(NotReplicated)
TObjectPtr<AAresInventory> OwningInventory;```
i hold the OwningInventory
from this message i thought you meant that it was "by its own" holding a ref of the owner
i didn't thought about actually adding my ptr in the container
{
FAresInventoryAddedMessage Message;
Message.OwningInventory = OwningInventory.Get();
Message.Instance = NewItem;
Message.ItemDefinition = Entry.ItemDefinition;
Message.NewCount = NewCount;
Message.ItemEntry = Entry;
UGameplayMessageSubsystem& MessageSystem = UGameplayMessageSubsystem::Get(OwningInventory.Get());
MessageSystem.BroadcastMessage(AresInventoryTags::TAG_Message_Inventory_NewItem, Message);
}``` we broadcast using the MessageSubsystem, ``` if (ChangedIndices.Num() > 0)
{
if (OwningInventory->GetQuickBar())
{
OwningInventory->GetQuickBar()->ForceLocalUpdate();
}
}``` we also update the quickbar if the inventory changes
{
Super::PostLoad();
if (!IsTemplate())
{
InventoryList.OwningInventory = this;
}
}```` we assigh it here
not sure how much more i can help you
{
for (const int32 Index : AddedIndices)
{
FAresInventoryItem& Entry = Entries[Index];
UAresWorldItem* Instance = CreateOrFindItemInstance(Entry.ItemDefinition, Entry.ItemGuid);
if (Instance)
{
Instance->UpdateFromInventoryItem(Entry);
ItemInstances.AddUnique(Instance);
}``` we run through everything locally and create instances and stuff
on the client
im curious, why a message and not a delegate ?
cause messagesubsystem is really nice, and convienient
Hey guys. I’ve been scouring the interwebs for a breakdown of how to invite friends to my session through the Shift + Tab Steam Overlay - lots of games simply allow you to right click a friend and send an invite through the overlay. Most tutorials etc implement a custom friends list and dont use the Steam overlay.
Do you guys have any pointers in the right direction? I’ve looked around for a marketplace plugin that covers the above, but can’t really find it. Is there a particular reason why most tutorials avoid the Steam overlay?
could use delegates sure, but no need
okay
@dusky yokenot sure what you mean, you see the invite option right in the steam overlay?
and it does nothing correct?
if i set a ref to my comp in FFastArraySerializer, how can i access it from FFastArraySerializerItem ?
why do you need it from the item?
what is the in on the post and pre functions?
this is the item, the serializer is passed in.
void PostReplicatedAdd(const FMySerializer& InArraySerializer);
so you have the serializer..
I’m just researching now before starting anything, but essentially I want my players to be able to launch their session and then invite their friends through the Steam Overlay and into their game save. I don’t wanna make a lobby where players wait to group up and then launch in - I want players to be able to join their friends solely through the Steam Overlay so they can connect while host is playing
its nothing special
if you have a session, and its public
the invite option will be there
but you do have to use SessionInterface->AddOnSessionUserInviteAcceptedDelegate_Handle(FOnSessionUserInviteAcceptedDelegate::CreateUObject(this, &ThisClass::HandleSessionUserInviteAccepted)); to handle the session invite request
and stuff
its not for the faint hearted, but there are plugins like Advanced Sessions for steam, and stuff
though we don't use such plugins, as we have our own custom system
Alright, so I assume thats why most titorials just cover lobby setups 😅 Advanced Sessions does the above?
are you using the dedicated server on a different network/IP than your PC? i.e. if they are both at your house, Steam doesnt like that
assume so
never used it
what is the signature like? I suppose it's not as simple as joining a session thru the data passed by the delegate?
It is
Thanks for the response! So I am replicating arrays of pawns, which are owned by the player controller. Is this bad? The character movement component should already be a simulated proxy no? I will try to store the bool in the player controller though. But I feel this might not solve the issue as the pawn should be owned by the player controller.
I have tried this way before, if I am iterating over the list on tick and modifying the list in overlap events it’s possible to modify the collection while iterating over it.
So I have multiplayer set up in my Voxel Terrain project. I've got the server spawning chunks around each player, and then the players spawn only the chunks that they need. There's an issue however, and that is that the chunks that the clients stand on are technically not the same as the ones the server has, and vice versa (they each spawn their chunks locally)
I thought at first that I could ignore this issue, as it plays mostly fine, however, I get these warnings almost constantly.
I just need a little help understanding the reason behind this issue. Is it as simple as me changing my code to replicate the server's collision chunks to the client? Or will I still get the same issues, as it is a procedural mesh?
Might want to give this a read. Should fix up the issue. https://vorixo.github.io/devtricks/procgen/
Basically it's because whatever you're spawning that the player is walking on isn't net addressable.
Much appreciated
I asked this another time, but I'm looking for second opinions:
What is the recommended way to handle third party APIs that will be called on the server?
Is it okay to package the keys in the server build, or should I route the calls through my own server that calls the third party APIs?
Or, should I fetch the keys at runtime? I'm not sure. Any help would be appreciated!
Are you planning on distributing the server build?
Not at the moment.
At all. If so, don't package the API keys, lets people start doing whatever they want with them.
Right. Hm... so really, if you ever plan on distributing the server, you're forced to route them through some other server
Yes, if you want to remain in control, you don't give it to them. They can request something from you, then you can verify if they can make such a call, then you can call the API yourself.
Got it
Do you have any recommendations for accomplishing that? I was looking at AWS Lambda, just having a Python function that makes the API request & returns the result to the client
Authentication. However, you can't expect to have anything 100% fully secured if you give access to it.
Let's say at some point you release a server build to the public, and you're expecting that the server build would make calls to your Lambda function that modifies a database of some kind - prepare to have all player profiles potentially wiped or modified by bad actors, as anyone could get their own server, and then start making calls to your API "on behalf of" any particular player. Even though you didn't distribute the API keys, you still allowed something (the server) that you don't have a good way of authenticating to make a request to your Lambda function, and your Lambda function would call to the third party API to do something. You wouldn't necessarily want server owners to create accounts to be able to play your game and make the requests.
One alternative is to only allow players to make requests for themselves as you could authenticate the users, but that doesn't guarantee that they're not submitting bad data for themselves - like I could make a request indicating I scored 500 kills this one session, but I actually didn't kill anyone. Again, it's difficult to control what data it is they send and sure you can clamp some values, but it can be difficult to know what is valid or not based on what kind of data you're trying to use. So this is better in a sense that the worst can happen is that a player could modify only their own data rather than everyone's data, but this may also mess with how you may potentially want to be monetizing things or completely break your game balance, or just overall ruin the experience for other players due to a player effectively "cheating".
The only way to remain in full control is you can't have anything you don't control make any requests. You control the game server, the players authenticate with the game server, the game server makes the requests. Now you know exactly what it is they're doing, you can validate properly, and since you control the data of the game server, you know exactly what values should go to your lambda function.
Got it. Thanks for the help!
Any one has already tested to split client & server into different project?
To what end?
i dont want to share server blueprint into the client 😕
You can choose what you include in the client build. Though, if it needs to be referenced by a client in some way, then you'd need to include it.
As an example, you can exclude all server related game modes. You'd still need some game modes for any client maps (like the main menu)
There is a macro in c++, but in blueprint there are no option to do not compile it to client
Yeah I getcha. There's nothing like that available in blueprints. If your concern is to exclude the code from clients for certain blueprints, then you should probably move that blueprint code to C++ classes so you can lock it to the server.
Dumb question: If I have 100 actors that replicate 2 arrays of 4 object will my latency take a huge hit
i have no gauge of how much data can be handeled over a network very new to this
Profile it and see. My gut tells me probably not unless you happen to be changing all of those arrays on tick or something extremely quickly.
Also @sinful tree i've seen i can create same project name, one for client and another for server, and export map to server, and keep server logic on serv and it can works, can do you think?
what if I iterate through them on tick
is there a way to test lag in editor?
like can I artifically lag the server?
Iterating over them isn't the same as replicating them. If you're iterating over them in blueprints it could be causing a slight impact on account that loops kinda suck in blueprints. If it was in C++ probably not at all.
this is very helpful thanks. Bassicly I check on tick if I need to modify them, and then do it if I do need to. But the modifying doesnt happen very often.
I wouldn't think so.
What's the concern with having that extra server code on the client?
Its logic to save/logs infos to database ect...
yeah so that you wouldn't want to include in your client logic at all. You'd use game mode or other classes that you don't export to the client build.
You wouldn't have your character class directly call to add to the database.... You could make it request to the game mode to save the data for example.
Then you just exclude the game mode from client builds, and the client won't have it.
Yes, but anyone that have my client, can make a private server easly by reversing it
That is my pain point 😦
No they can't. They don't have your game mode, they wouldn't know what logic you're using.
All that they may know is that a call is being made to the game mode to save from your character, as an example.
game mode is compiled in blueprint
You can exclude game modes from client builds.
If the concern is with the maps, your maps can have no game mode set, and the server when being launched can be told what game mode to use.
You can pass around a base game mode class that may have the references to the functions and events you need to use in your game modes but you don't have to have a class that actually has the logic included with them.
Am I missing something simple, or over thinking.
How to replicate the existence of foliage instances?
Replicating a big array of like current instances seems bad and will nuke the network when a user joins?
and, having some like multicast events, and hope it stays synced also seems like a sub-par idea, given what happens when a user joins later?
hi guys i need some help on some general concepts. if i have a gun which has a function shoot which does all the line traces and muzzle flashes and what not inside the bp of the gun itself. im calling it in the player bp (shoot function). now if i want to replicate this for multiple players would i have to make the server events on the player bp or the weapon bp ?
You'd want like 2 new events.
(in order)
- Input -> request shoot (do any ammo checks, against wall, ets that would prevent the firing)
- ROS -> request shoot (do the same exact thing as above, so now the server double checks)
- Multicast -> actually shoot (do visuals, then apply damage/ use ammo)
- Gated by server -> consume usage (This can be put into 3. if you want, but it would just be the server consuming ammo, firing/ doing damage, and etc.
You can technically have this on the player, but 99% of the games I know do it on the weapon
Hey gang, what is the recommended reading these days if one is to start exploring integrating one's multiplayer UE project with Steam (and possibly EOS down the line)? Is there a go to guide or github page that folks get sent to when they want to learn more about this, at least as far as the latest 2024 best practices are concerned?
I just kinda threw stuff together until it worked, and searched up any of my issues.
Just to read 20 links, and only 1 had the answer.
read pins
I did, I wasn't able to find anything steam-specific on there as far as implementation guides go, but it's entirely possible I missed something obvious. Any chance you can point me to the pinned post that you have in mind?
do you know how networking work with unreal?
I wouldn't oversell my expertise, but likely just enough to be dangerous.
Steam is probably the same as always
ListenServer you are probably good with just your own AppId and that's it.
Native SessionNodes can probably do the tricky. AdvancedSession for more settings, or C++ for sanity.
Wouldn't it be better to code it yourself without a plugin so you learn more?
Not everything is worth learning
Otherwise I could argue that you shouldn't use UE and just code the engine from scratch too while you are at it
DedicatedServer, idk tbh, needs source anyway. I think some of the properties to get the Server to properly show up can now be done via Target.cs changes, but haven't done that in a while
EGS/EOS is a bit of a different story I guess. I don't think there is a fully functional subsystem for it atm? Not sure. There are plugins that integrate it fully or you can do it yourself via Epic's SDK.
I dont find the AdvancedSession plugin
There is also a layer of crossplatform where you could use Steam just for the EAS part for authentication
It's a community plugin
where can I find it?
Idk, google?
I did and not found it
Don't know what you do wrong, I can find results for it just fine. ¯_(ツ)_/¯
I was briefly taking a look at the guide in https://www.youtube.com/watch?v=E2okoXqsXNc and he recommends https://github.com/Risensy/Steam I believe. I'm also making a little progress through Stephen Ulibarri's multiplayer shooter course and there's some Steam coverage there too.
Ultimately I'm hoping I'll find something that will abstract over Steam/Epic with one single solution so that maybe I can get cross-store play out of the box, but that may be too optimistic
That GitRepo even uses AdvanedSession fwiw
Don't know why they didn't link it to the actual repo instead of reuploading it
There is #epic-online-services to look for some stuff regarding EGS
Roger that.
Yeah
this works for steam or unreal or both?
It's an Unreal Engine Plugin
All it does is expose Session Nodes with more functionality
The underlying code is still the same
but I thought it was for steam?
It might have a Steam related module for some more steam relateds tuff
But the base is just the OnlineSubsystem
Online subsystem include steam
Yeah, the plugin facilities the creation, editing, starting, and closing of online matches/ servers to join.
Just like the base engine has, just a ton more BP accessible values.
(Base UE has a super generic "create session", but the plugin adds a create session, with player count type, name, settings, sort of stuff)
Yop, I still like to do this rather in C++, but for BP only people it's probably even required by now
Epic will never improve the base nodes
Then you still get trolled by old C++ code, even with the plugin.
I troubleshot an issue for like 3 days.
Was the dumbest thing, but I fixed it
Does the same overachrching things.
But, you can see it has a ton more values.
That be steam related, or just generic like "server settings"
None of that is specifically Steam related
The interfaces affect Sony, Xbox, etc.
I think it has a Steam related module that might have some more steam specific functions
But for that there was also SteamCore
Yeah, it does.
But, even on this generic node, you have comments specifically for steam
Is there any way to override the WithValidation behavior or am I stuck with the player getting instantly kicked out if he fails the validation?
void ServerTestFunction(int32 AddHealth);```
I don't think so. The whole point of the validation is to check to see if the player is sending something completely unreasonable, in which case you'd know that they're spoofing values, hence, when you return false, they've failed validation and it boots them. If you're wanting to do something else with them, then you don't necessarily have to return false - you could have the validation do other things and just return true.
How awful is it really to go back later and enable replication for a mostly-Blueprint game? I don't plan to have any crazy movement modes like flying, parkour, or spider climbing (yet), but I see they're working on this Mover 2.0 thing, so I'm trying to weigh [starting replication early for sanity's sake] against [making it single player and potentially changing that later if movement replication becomes substantially easier to implement].
What do you have besides walking and jumping?
Presently nothing. I'm early enough that I'm still working on the procedural dungeon generator.
Eventually I'll probably add Crawling, Climbing, Ledge Grab while Falling, Running, and a Dodge/Roll.
You'll probably be looking at C++ for a lot of that
if you want to use CMC and have it be butter smooth
I guess that figures. Would those movement types be built entirely in C++, or does the C++ just handle the multiplayer aspect of them?
Let's put it this way...
The CMC doesn't have everything exposed to blueprints that you would need to change to be able to properly implement and replicate new movement types. It's not just about the "multiplayer aspect", it's just the CMC itself wasn't built to directly support new movement types in blueprints, whether single player or multiplayer. You can create custom movement types in C++ and then use them in blueprint, but unless you've created what they actually need to do in C++ utilizing the CMC's functions, then it's not really working with the CMC.
An alternative is to not use the CMC at all, in which case you can make your own movement component from scratch, and potentially make it entirely in blueprint, however, performance and network usage would be higher as the CMC has some nifty tricks it uses for compressing the data that is sent every frame for movement and you can't do the same kinds of tricks in blueprints alone, and you're talking about trying to remake a 13K lines of code component in blueprint just to get it to the point of working as Unreal currently has it with client prediction and smoothing, gravity, checking step heights, crouching, jumping, etc. - but nothing else extra like your additional movement types.
Another alternative is to use some other third party movement solution, which I can't really speak to. Some claim to be able to properly replicate custom movement and be fully blueprint accessible, but I can't speak to the validity of their claims as I've not used any myself.
Mostly C++ as far as using the CMC goes. You could maybe put some logic in BP but it'd be kinda pointless
I've grossly misunderstood the CMC. Haha. Thanks for this.
Theoretically, if I can find a few existing CMCs that support movement modes similar to what I'm looking for, I should be able to reverse engineer and combine them, right? At the end of the day it's just a function/plugin?
If you don't want to get in the nitty gritty of C++ movement code just find a solution that works out of the box for your use case
As far as how bad is it to go back and reimplement the multiplayer part of it? Well, movement is something you want done right - you don't want jittering and rubberbanding but you usually also want quick response for your player so their movement doesn't feel sluggish on their end. This involves client prediction, and managing how the data is sent, and how the server detects and corrects issues with the movement. It's not strictly impossible to do after the fact, but it's usually better if you know the constraints of your system and design your moves within those constraints rather than building your movement unbounded, then trying to build a new framework and having to change everything else to fit within the constraints of the system.
In terms of finding other movement components that have the features you want, not likely. Most plugins for movement out in the wild aren't meant for multiplayer or aren't replicated properly (ie. using blueprints with the CMC). Or again, they're their own system entirely, in which case they may not use any of the same logic so it'd be hard to integrate everything, though you would get a picture of what they do.
I'm fine with C++. I wouldn't say I "know" any languages, but I have my Bachelor's in CIS and am stupidly good at debugging and reverse engineering all languages. I can't write for shit though, which is why I love Blueprint.
Not sure where I'd look though if I'm not trying to dole out hard cash.
Do we think their implementation of Mover 2.0 (and related) will dramatically change the amount we need to interact with the CMC during development?
Sounds like you want to avoid cpp but I don't think there's alternative when it comes to networked movement
I just want to avoid writing something from scratch in C++. If I can get an example or template with at least one properly networked custom movement type I can probably figure out the rest.
Who would even suggest writing from scratch, that's just reinventing the wheel but worse.
Look up delgoodie cmc video, it adds sliding, wall climbing, vaulting etc.
Haha I literally just found that playlist 5 minutes ago and bookmarked it for later. I feel like it was way harder to find than it should've been. Good UE tutorials seem scarce.
(Or I just don't know what I'm searching for yet)
Had a hell of a time finding a solid dungeon generator tutorial too.
do things by yourself then lol
Gotta learn it before I can do it! I learned what they did and am now making my own more powerful version.
true
Hey guys, does the new system Motion Matching work with multiplayer?
No
Not until 5.5
I’m sure you could get it to work but 5.5 they officially supporting it
lol, we gotta wait till November or something
Probably XD
From what I've been told, most of the benefits of Mover 2.0 is still within C++ territory but from what I understand, it is supposed to help move things to blueprint, while also being more modular and not necessarily strictly tied to a "Character". Essentially, it's supposed to be a new iteration of the CMC, hence why it's called "2.0". I haven't done a ton of research on it myself though, so take what I say with a grain of salt.
Maybe I'll just try to hold off on my movement stuff for as long as possible LOL
simple question, how large scale can handle one server, if i manage on it, only players positions & skills/hits ?
Yeah just T pose it. That’s what call of duty does 😂😂😂
Highly depends how optimized the code is and how big your server is
For real though, just disable physics and increase speed, right? LUL
PRECISELY
Just positions? Or positions + physics and math like walking?
Anywhere from 1 to 1000 depending on what you're doing and the average relevancy count. If you have to ask the question, call it 20.
no physics
walking means controll the speed?
is it EVE online where everyone is a pointlike mass in space or is it on a map with collision geometry?
Collision, i think i'll let it on client
anything beyond 20 clients in BP only would be pretty tough I'd guess
maybe 50
Epic does 100+ in Fortnite but they know what they're doing
allegedly
crazy, and alternative is to make our own server ?
you'd be making your own server anyways....
i see but even if i make UE dedicated server with using well multithread ? it will be fast limited ?
but they dont do 100+ in Fornite with only BP - its c++ driving the main parts
UE is single threaded. It offloads certain workloads to different threads.
Hey so I am trying to modify a bool stored on a client from a server owned actor, but the bool does not set on the clients even though it is called in a server rpc
server rpcs run on the server
Show your code
Is the Actor Replicated?
PlayerCharacter.cpp
void APlayerCharacter::Server_PickupItem_Implementation(ACarryableActor* itemToCarry)
{
if (CarryingItem) {
return;
}
CarryingItem = true;
carriedObject = itemToCarry;
//HolsterWeapon();
itemToCarry->Server_OnPickedUp(carrySlot);
//ShootReleased();
}
InteractableActor which calls that above method
void ACarryableActor::OnInteract(APlayerCharacter* player)
{
if (!player->IsCarryingItem()) {
player->Server_PickupItem(this);
LastCarryingPlayer = player;
carriedState = ECarriedState::Carried;
}
}
Hold on Im still trying to wrap my head around everything this is prolly not be enough info
From the way it reads, at least to me, is that your player is trying to call a server RPC on a non-owned actor. Which is not allowed.
ahh that could be it
so would that item not be owned by the server?
initially it is placed in the world, but it does get attached to the character when they pick it up. Would that change its ownership?
Only if you set the ownership.
so then it should still be owned by the server right? Because initally it is placed in the level which to my understanding makes it owned by the server
nvm i was wrong with that last message
I wouldn't use a separate bool to verify if something is being carried either. You have the variable "carriedObject" that if contained nothing would also indicate that you're not carrying anything.
Makes things a little easier to manage, not sure about solving the issue.
yea didnt solve issue. forgot I was using it for other things too so gonna leave it for now.
Im just throwing RPC's at it and its getting fixed lol. Not sure if im doing things the wrong way...
UFUNCTION(Server, Unreliable)
void Server_DropCarriedItem();
void Server_DropCarriedItem_Implementation();
UFUNCTION(Server, Unreliable)
void Server_PickupItem(class ACarryableActor* itemToCarry);
void Server_PickupItem_Implementation(class ACarryableActor* itemToCarry);
UFUNCTION(NetMulticast, Unreliable)
void Multi_PickupItem(class ACarryableActor* itemToCarry);
void Multi_PickupItem_Implementation(class ACarryableActor* itemToCarry);
UFUNCTION(Server, Reliable)
void Server_OnInteract(bool interacting);
void Server_OnInteract_Implementation(bool interacting);
UFUNCTION(NetMulticast, Reliable)
void Multi_OnInteract(bool interacting);
void Multi_OnInteract_Implementation(bool interacting);
I fixed the issue but I have like 4 rpcs.
is it generally recommended to start using C++ for multiplayer games as early as possible? so far I've been prototyping in blueprints, but I get some large road blocks every now and then with replication
probably more so an issue with my knowledge on multiplayer logic than blueprints vs c++
@gloomy axle If you are serious about multiplayer, you will learn and use C++
what's one of the key differences C++ has for multiplayer development?
While it might be possible to make a multiplayer game entirely in BP, you will be extremely limited.
There are many features available in C++ that are not in BP
Push Model for example
Its a CPU optimization for Replicated Properties.
Just the number of functions that arent available in BP which really assist in managing things critical to most multiplayer games is enough of a reason.
I think one of the biggest issues I have right now is simply being able to understand how to effectively communicate logic from client -> server -> other clients
A question of design. Is it really necessary for an inventory system to be replicated? All actions on the inventory have to go through the server anyway, so would it really be that much overhead to fetch the inventory contents from the server when displaying it? Is there any real benefit to replication for an inventory?
Effectivness of how to do a particular thing a lot of the time comes down to what you are trying to achieve.
i just went over a replicated inventory system
basically the only things i replicated were the slot of which the player is on and the item on that slot
so that means i had to replicate when the player would change slots with the scroll wheel
and when the player picked up or dropped an item on that slot
Im not sure I understand the question. How is "fetch the inventory contents from the server" different from replicating the contents of the inventory?
I don't know what you mean by changing slots but it sounds like it might not apply to my system
imagine lethal company
I mean fetch it only when it needs to be displayed to the player rather than keeping it constantly in sync
how you scroll on a hotbar
and depending on if the next slot selection has an item, show or hide it
If the Player only knows about whats in their Inventory when they view it, how do they make use of anything in there?
For a hotbar I would expect a bit of data duplication to be needed
Replicating an Inventory is effectively a one time cost per Item anyway, its not a constant ongoing cost.
If no items change, then there is nothing to continue replicating?
yeah, so what i replicate is:
- the scroll number index
- the item in that slot
so this way other clients will know what slot the player is on for item visibility and itneraction
I don't. I'm asking if there's really any performance difference.
right now im trying to "replicate" ui actions. i say replicate in quotes cause widgets cant be replicated, but i want to show the interaction of another player on the same widget
similar to a voting screen
Then it sounds like the answer to my question is that it is not really necessary to replicate it.
Sure, its not necessary. But it solves a lot of problems if you do.
Implement the "fetch" system as you see it in your mind. Then every time you hit a roadblock, think about how a Replicated version might have avoided that issue.
I'm just brainstorming ideas right now. My inventory system was working fine right up until I wanted to support dynamic properties on items. Like a percentage condition for the current quality of sword or something similar. Ever since then Things have been getting hairy. I think I really need to rethink my fundamental design for dynamic properties,
Ok well straight up, you have identified a roadblock that a Replicated system wouldnt run into.
Since, everytime an Item has something changed about it. That change can be instantly pushed down to the Client natively
You dont have to reinvent the wheel with a "fetch" system to handle that special case.
Performance comes with tradeoffs.
Everything is about tradeoffs
Multicasting things like "OnInteract" and "PickupItem" is likely the wrong way.
Well it actually is a roadblock with the replicated system I currently have. The dynamic properties are currently defined as an array of instanced structs, but Because they are not directly attached to an Actor I have been struggling to replicate them
you should replicate the item disappearing in the world though, however you approach that
Properties of Items should be on the Items.
The Inventory itself should be owned by an Actor
The Inventory would replicate the Item through the Actor
Here
Check that out
An Item system I did with Instanced Structs
Fully network replicated
Completely free plugin.
The inventory is. But the inventory has an array of structs that each represent an item. Each of those structs has child structs. The array of dynamic properties is a few levels deep
I'll check that out
so to be clear you destroy the item on pickup, then recreate with that struct?
I destroy the Actor on pickup and store the struct that defines it's properties
And to complicate things further, the item itself can be a container with it's own inventory
why
maybe make this a linked list sort of struct?
Oh of I didn't have to deal with Unreals reflection system I think this would be easy. But reflection and garbage collection are getting in my way too. Like if I could have a pointer to a USTRUCT that would solve my problems but that seems to be forbidden
Do you have a use case for Items that need a nesting depth greater than 1?
howcome u say this?
Yes. A bag inside a box inside a chest for example. I suppose I could limited the levels of nesting but it's the first level that's causing problems right now, and really only since I tried to add dynamic properties. I think I need to revert back to the pre dynamic code and come up with a different design entirely because that was working with reflection and unlimited nesting. Something Ive done since then is tripping me up
Wouldn't it be simpler to have an actor with an actor component containing those dynamic properties, then just getting a ref to that actor in the inventory?
Then I would have to keep the actor alive even when it is stored away
Fair enough use case I guess.
not necessarily, you can either hide it or just get a copy of the class for reconstruction
I currently store the class, destroy the Actor on store, and recreate the actor when dropping an item
Because anything stateful shouldn't be in multicast.
Multicast rpc may get dropped and guaranteed to not run on non relevant players and players that yet to join the game.
Use multicast for fire and forget events like playing a special effects. Read the pinned resource for info. Multicast is always used in the wrong way by people who just started doing multiplayer.
I'm sure datura is being diplomatic, I would just honestly say it's 100% the wrong way.
Thanks for the explanation! I don’t doubt it’s the wrong way I was just curious why so I know how to fix it. In this scenario, should I be using a repnotify for something stateful like this?
Repnotify is just a function that is called when a variable is updated. So it's useful to do something when client receive an update from the server (replication take place)
It really depend on the design of your game but normally when picking up item, you can just run it on server
Ahh I see. So run on server is not a fire and forget as much?
Do what ever you need to do on the server side. Such as validating the pick up item, adding items to the player inventory etc
When the server add item to the player in it's world, if the item is a replicated variable, client will eventually get the updated value
The on rep then can handle stuff like updating UI on client side
Read the compendium, it explains what RPC is all about.
Multicast RPC runs on every machine, but now ask your self. What happend if you let's say play a dance animation using multicast when I'm as the player have not join your game?
The event only gets called on current relevant/connected players . So when I join your world, your character will not dance in my screen.
So in short , is something need to be synchronise in every machine? If the answer is yes. Never use multicast , it's a sure fire way for bugs and misery.
Ohh shit I see thank you for that example. I have read the compendium lol but I need to read it again and again it seems as I start putting things into practice. I really appreciate your explanation in this scenario this makes a lot of sense. Also I love you red panda pfp.
Yes the common advice is to read it 4 times and another 4 more if not understood. It kinda take me a dozen of time before finally clicked
Had to do a lot of testing as well 😄
so quick question, if I have an actor that is on the server but its ownership transfers to a client, how would I ensure it stays replicated on all clients? would I just need to setreplicates to true again?
What do you mean its Ownership transfers to a Client?
I parent it to a playerpawn
ill drop code
void ACarryableActor::Server_OnPickedUp_Implementation(USceneComponent* carrier)
{
if (carrier == NULL) {
return;
}
PhysicsComponent->SetSimulatePhysics(false);
FAttachmentTransformRules rules = FAttachmentTransformRules(EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, EAttachmentRule::KeepWorld, true);
PhysicsComponent->AttachToComponent(carrier, rules);
SetActorLocation(carrier->GetComponentLocation());
MeshToHighlight->SetRenderCustomDepth(false);
}
No where in that code does any transfer of ownership occur?
A literal transfer of ownership would need a call to SetOwner
hmm well maybe I am thinking of it wrong, I attach it to the playerpawn, and it stops replicating its postion on all the clients and server
Well if you are attaching it, its going to take on the location and rotation of the attachment...
Did you set bReplicateMovement?
yes
i do this in the constructor
bassiclty the position does not update on the clients but it does on the server
I dont want to use a multicast for this because it is not a fire and forget situation
Sorry the other windows are so tiny.
Can someone let me know if this flow seems right?
On my PlayGameMode:
- BeginPlay -> StartClassSelection
- OnClassSelection
- For each connected PlayerController, call On_ClientStartClassSelection from the PC
- On_ClientStartClassSelection is a custom event that has "run on owning client"
- on On_ClientStartClassSelection:
- Call StartClassSelection on the PlayerController
- Adds widgets
go to 10 seconds
I forgot to set replication on the component I was attaching it to lol.. thank you for this statement
omg
my AllConnectedPlayers array wasn't actually adding the PCs 😭 i set the logic up wrong
My OnPostLogin doesnt seem to be adding the new player controller when a person connects?
it's confusing since it does spawn the player
ok so, found it this works differently when using seamless travel
for some reason
i need to use the HandleStartingNewPlayer instead of PostLogin
because technically the player already logged in?
@gloomy axle Correct
Seamless Travel does not call OnPostLogin
Because the Clients are still there, they are just moving to a new level.
yeah, it is called "travel" I just didnt know about the HandleStartingNewPlayer event
Generally speaking you dont normally keep a list of the "Connected" PlayerControllers.
The GameState already has a List of all PlayerStates
You will typically use that list, since everyone has it.
and I can ref the game state in the game mode since it can be called on the server right
makes sense
If you need to iterate over all PCs, you would just use a GetAllActorsOfClass
i changed it so I Get Num Players node, then a for loop calling to get the player pawn based off of the player index
like this
Steam on LAN?
I haven't managed to get steam to work on my LAN (dedicated server on 1 PC, client on another).
But I have been thinking that if I use my dedi's public IP (and set up port forwarding), then providing my router supports NAT loopback, I should be able to connect my client to the public dedi IP.
Failing that I could run the client on a VPN.
In fact in both cases I might be able to run them both on the same PC (VPN would require split tunneling).
Has anyone tried this?
(during dev it will be very convenient if I can run my dedi and client on the same PC)
I choose not to use listen server. Cleaner architecture with dedi + client, and I need to test that code
i gather many people struggle to get steam to work on LAN
isn't what you're doing technically a listen server setup? since you have a server on one PC, with other clients connecting to it
if you're all on separate machines with separate steam accounts it should be fine?
steam on LAN just seems not to work. Null subsystem works fine. It might be some security constraint
@chilly haven I doubt it works, but have you tried running Steam in offline mode?
That's the only way I could use LAN with listen servers, but I haven't been able to do it with dedicated servers yet. Your setup might differ from mine though.
the dedi doesn't require the steam client, so that's not the issue
he meant your client trying to connect i think
well i need sessions interface to find the dedi and join it
I'll see what happens with offline mode tho
yeah I want to work on steam functionality with easy iteration
Actually, you don't need to use LAN to do this, if that's the reason you're asking about LAN. I thought maybe you just wanted the functionality for gameplay reasons.
I want to get steam working with sessions, without the hassle of uploading builds all day to an external host. Hence if I can get steam to work on LAN, or better on the same PC, I will be happy. I tried and the packets simply don't get from client to dedi. Hence asking about workarounds.
Hmm, alright. I guess if you're using EOS it might react differently, but Steam doesn't seem to mind the server and client coming from the same IP.
I've been testing dedi on the same machine on different networks, but I just use Advanced Sessions.
oh so you use VPN?
No VPN
2 network cards, bind to different ones?
Just one nic
but ... same machine on different networks
I mean
Testing works on more than one network, at different houses
Sorry for the confusion
ah ok. well I'll try my 2 network tricks then i guess
DediServer can in theory be tested on the same PC with Steam. Just 2 player probably won't work
Dreiserver ?
Dedi
I cant seem to call this function on the client. It runs on the host, but calling it on a client doesnt make the widget visible.
The flow is basically:
- On my game mode, for each player in player array from the game state
- get the player controller, get controlled pawn, cast to the pawn, call the function on the image attached
any clues?
the "Opening CS UI" doesnt print out on the client either
Why do you need is locally controlled there btw
Client only know their own player controller
yeah, but this is to check against server context
Wdym
well
checking against server context?
pawns with player controllers have client and server context
this makes sure it's the client context
by asking if its locally controlled
you always want to check if its locally controlled for widget changes
No locally controlled just mean if the object is controlled by the local machine
Regardless server or client
Okay but you still need to check it for widgets
Well it's got nothing to do widgets, though maybe you can have it there since the server have copies of everyone controller
?
maybe i am misunderstandingl but the client can't access the playercontroller of other players, right?
Client only know their own controller
So no, they can't access other players controller
Info is Pinned in this channel
because it sounded like he was trying to do this on the client? "On my game mode, for each player in player array from the game state
get the player controler"
yep
i was trying to tell the server to tell the player controller to do this
essentially
i did get it working btw, just had to change the On_StartClassSelection event to multicast
so it executed on each client
Why not just do client rpc?
Probably explained why it didn't work earlier for you
Because you are running it on server instead of the client machine for the loop
you mean by doing on server event -> call on client event -> do client event?
U don't need server events, the game mode is already server only since it only exist on server
yeah
From game mode, loop the players, for each of them run client rpc(start class)
U already doing that
i was trying to call the client event
Just change the rpc to client instead of multicast
In plain English, the instruction is.
As the server, loop thru everyone controller. For each controller, run Start class in controller that exist in client machine
yes that's what I did
Well not earlier if u have it as regular function instead of client rpc
I think there's some miscommunication here
If u are doing regular function, what u are doing is
Run the function for the controller in the server side.
Which won't work because it's not locally controlled (just to name one mistake)
I'm gonna start driving home but you do want to avoid multicast unless you know what you are doing.
Keep what you have before but run a client rpc. If that work just use that.
alright have a safe drive
you want to understand what multicast is and isnt. Not use it if you know what your doing
it is a way to tell everyone to do something, its not a way to keep something synced up
since this is similar to a voting system, it'll be better to tell everyone to "start voting" per say
Yes could tell everyone the voting session started
but ya probably want the votes to be rep notify
in this example of course XD
yeah it's on rep notify lol
Hello, i wanted to know if there is something that i should activate to see this in lyra while debugging blueprints. So i know if the node is called in the server or client. It doesn't show while debugging in the lyra project and can't debug multicast events.
does the experimental physics prediction plugin work with wheeled vehicle pawns?
yes, more info here: https://vorixo.github.io/devtricks/phys-prediction-use/
i got a question
im updating in a FastArray 3 entries, the thing is, when i call an RPC to go to the client side of my comp, the FastArray got 6 entries (looks like its the 3 original i added (3 empty), and then the 3 "updated"
am i doing something wrong in the "mark dirty" process ?
Screen 1 : items added on server
Screen 2 : items updated on server
Screen 3 : on client right after rpc
RPCs vs properties don't apply in any particular order
No guarantee that change has been applied by the time the RPC is processed client side
Hello can someone tell me difference between a party system and a lobby system? In both we can invite players but does in lobby we create a session and in party system we don't?
It's more terminology IMO. Lobby is usually a collection of random players, Party is usually a group of players travelling between other sessions/lobbies as a group.
the thing is, if i am early before rep, i should get 3 empty entries
if i am after the prop rep, it should still have 3 entries with updated data
here there is another issue, that causes the fast array to ADD entries instead of UPDATING entries
// add entry code
FPGFastSlot NewSlot = FPGFastSlot(SlotVisibility);
if (IsValid(Item))
{
NewSlot.Item = Item;
}
int32 Index = Slots.Items.Add(NewSlot);
Slots.Items[Index].SlotIndex = Index;
Slots.Items[Index].PostReplicatedAdd(Slots);
Slots.MarkItemDirty(NewSlot);
// update entry code
if (Slots.Items.IsValidIndex(SlotIndex))
{
Slots.Items[SlotIndex].Item = Item;
Slots.Items[SlotIndex].PostReplicatedChange(Slots);
Slots.MarkItemDirty(Slots.Items[SlotIndex]);
}
Hard to really know what you're doing but why are you calling PostReplicatedChange() PostReplicatedAdd() etc. yourself?
The problem is here
Slots.MarkItemDirty(NewSlot);
i am using a listen server
its a way to make the function called on listen server to
You're marking the original version of the slot as dirty, but the one you added to the array is a copy of that slot with it's own data, so it's not dirtied and has no valid replication ID
This is much cleaner:
NewSlot.Item = Item;
NewSlot.Index = (Slots.Num() - 1); // Eww but ok.
Slots.MarkItemDirty(NewSlot);```
what does Emplace_GetRef do ?
Constructs the item in the array and returns a reference to that item
Add_GetRef does something similar but Add always invokes a copy.
okay
That stuff aside, you need to mark the item that's actually in the array as dirty, not the original 'NewSlot' variable you copied into array
i see
i could of do the same thing that when i update the entry ig
thanks for helping
The Update is fine because you are accessing the array directly
But I strongly oppose calling PostRepAdd/Change internally for the same reason I don't like people calling OnReps manually
okay, ill maybe change that
i quite dont understand why using Emplace instead of Copy
How can i kick a player from the session if i am hosting the session as a dedicated server?
so in games like Fortnite,pubg when they invite a friend to squad then is it making a party or a lobby session? does it create a listen server for its friend to join him?
how u can host a dedicated server?
simple
build a dedicated server, and host it
no i mean dedicated server is hosted by a 3rd party sites like aws and u can join it like any other client
i thought only listen server can be hosted
i am using my own linux vps box to host
and yes using a static ip address with open ports
oh
and using 333networks heart beat to connect clients
by sending that player to a different session or log him out
how much time it took u too setup ur dedicated server?