#multiplayer
1 messages ยท Page 229 of 1
I did something similar for a Dark Souls like invade system for a client a few years ago.
Every player was basically a ListenServer and the Session information kept track of if someone is available to be invaded or not.
If you wanted to invade, it would trigger a Session search and join a Session and the player (as every player is a ListenServer), then updating the Session info that the player is currently being invaded. When leaving the invaded player, the player that left would open their own level as a ListenServer and re-create their Session so they can be invaded.
Players could then turn that off by either having them re-open the level without listening, or by simply updating their Session to not be open to invade.
You just have to use what is there in a bit of an abstract way, but should be possible.
Only thing you gonna not get is a "seamless" transition.
The player who joins will get a "loading screen" in UE.
That you can only avoid if you also take care of the whole connection and replication process fully yourself.
That I was worried about, was hoping seamless server travel without hiccups was easily doable
No, not at all.
Seamless like the server meshing in star citizen?
SeamlessTravel, the term itself within Unreal Engine, just means that WHILE a Client is connected, the Server can travel to the new map, parking the Client on a TransitionMap that is very small (basically non-existent for loading times), so the Client doesn't have to disconnect and reconnect.
Connecting and Disconnecting in UE is a HardTravel
Aka, whole World is shut down and recreated.
yeah pretty much, I don't want the player to know he's being connected to someone
Yop, not possible with standard UE networking.
Only thing that comes somewhat close to that are Beacons.
But those aren't meant to be used to replicate whole worlds and actors.
Oh alright, maybe not exactly what i'm doing, i'm having one dedicated server per subregion of my map in my game world to allow for more players
(Will have as its a rather complex system i dont need for the first alpha)
Withing UE's networking you have certain limits. You have ListenServer and DedicatedServers.
And connecting and disconnecting to and from those are HardTravels. Server itself traveling to a new Map, with or without Clients being on the Server, can be Seamless.
DedicatedServers and the general baggage of bandwidth of UE itself also limits Servers (realisitically only DedicatedServers, as ListenServers are potentially bound by player hardware) to roughly 100 players, which can be less if you have other stuff going on.
So even if you were to put players onto DedicatedServers per region, you'd have a hard-limit at around 100 players, after which you need another server for that region.
If you want to avoid those limits you either have to replace Unreal Replication system, use a third party system that maybe does that already, or not use UE.
oh well, my dreams are shattered ๐
Even on a good dedicated server the hard limit is 100 ?
You can probably host more if you have the funds to pay a really really really beefy machine and ISP
But realistically, yeah, 100 is roughly the sweet spot.
I can just make more subregions and even with the subregions i intend 100 is fine though ๐คทโโ๏ธ
Fortnite and PUBG did a lot of fighting for that.
100 is also only realistic if you use ReplicationGraph
But sometimes there might be a lot of players in a subregion for events
Or in the future Iris fwiw
You gotta remember that UE's origin are Arena Shooters
Unreal Tournament to be specific
Iris will just be toggling a switch somewhere to use it?
Maybe
Right now I doubt it. We added it to a ~100 player game a couple weeks ago and it was a lot of work
What did you have to do? Maybe i could start building with it
It's specific to each Game. Can't share any of that.

It will still not remove the 100 player limit. You would probably get as far as with ReplicationGraph
If you need more players, replace UE's replication system or UE entirely. It is what it is.
ReplicationGraph is the built in thing right?
It's part of the Engine, yes.
Needs C++ of course
But any dev talking about 100+ players should not use Blueprints only anyway
Absolutely impossible given the overhead of the ByteCode VM of BPs
Oh it isn't the thing with RepNotify's, multicasts etc ?
No
Aren't they compiled to C++ ?
No
They are compiled to ByteCode and executed in a VM
That VM is written in C++, but it's no where as fast as actual C++ compiled to low level instructions
ReplicationGraph is its own System used to sort Actors into Buckets for better management of relevancy.
Basically a system made to save bandwidth
And CPU fwiw, as they are evaluated differently.
Oh that sucks i thought they were compiled to C++. I wasnt gonna use them much anyway
You should use them, at least for the leaf classes to set up default values and what not
But computation heavy stuff and core logic should be in C++
Is this your first project automate ?
A BP only MP game with 100 players is a bit to big for a first project
Nope i was just heavily fucking misled ๐
I didnt really like them for logic stuff since i dont like drawing
I always end up doing ugly spaghetti
And the control flow feels weird
I wouldn't call that a project at all. BP only 100 players is not a thing.
Wdym im working on a BP only MMORPG 
If i want it BP only i will need 5000 subregions of 10 players max
And get 1 fps /s
Hey man, no worries, & thanks for sharing thoughts. I tried this in addition to some other recommended variables I looked up:
net.ResetAckStatePostSeamlessTravel=True
net.FilterGuidRemapping=False
net.ForceRebuildPackageMap=True```
No luck yet, but I'll try digging out what the source of this is. Could be an engine race condition with the client connecting sooner than expected, I'll handle that use-case just in case & also clear my experience files to see if those make a difference (would indicate a component having bugs). Thanks for all the input!
Man, I hope you are aware of the costs to hosts those servers
The costs of that can easily finance a whole project alone
I wont really have 5000 servers
But yeah since you said its 100 max, i will need more than expected
Well 1 server holds 1 game
have you checked if this is a common Lyra bug that others experienced?
There is a Lyra specific Discord you can try
If you want multiple games at the same time (like 100, wich is very low) you will need a hundred servers
Or 1 big machine running those servers
You know what you actually need?
A player base.
And that is the thing that usually 99.9% don't get
I would be really mad if i only get 50 players on the map at max ๐
But ill let exi tell you how this works
No players, no matchmaking, no opponents
100% bots 
Well you got some marketing to do
Well i want one map, but i cant have one server host a huge map of 1000/500 players max, so i must split it into subregions of the map, each hosted by one server
Like the fire nation capital is its own server
100 Player game without funding (multiple thousands per month for just the Servers) and without a team to support the game at a rapid pace is basically just another "I make an MMO."
It is what it is
And from all the peopl coming here trying to do that in the past 10+ years, we have heard back from a whooping 0.
Yup it is an hard project, i have time and a team though
That's more than most have.
But do you have money ?
Before the Servers are even important, the money has to go into a massive sinkhole for marketing.
The "mmo" subregions part is the last thing i will do, first i'll get the most interesting for the player bits out like the combat out and publicly testable to market
The stat is around 40% of the budget of a game is in marketing, idk if you can confirm that
Also is there a way to stress test the servers? I cant open 100 clients on my machine and i dont have 100 machines
You can't just add making something scale to 100 connected clients later... Performance is not a thing you just fix later
Services with bots should exist
Idk, depends heavily on the game, but I can tell you that without Marketing, the chances of anyone knowing about your game are basically 0.
And even with marketing the chances that anyone even picks up on it are still really low.
After all one is competing with AAA studios that push their marketing everywhere for amounts none of us can pay.
You can pray a streamer plays your game
Yes of course i'll make sure it scales and do benchmarks accross the way, i'm the first to say "optimize later" is stupid. What i said was that i was gonna do the subregion system near the end because it's complicated and players care less
A single influencer posting about a game or playing it can easily reach 20-30% of the budget of smaller singleplayer projects.
Idk if lethal company did any marketing, probably some luck
You can't take those as examples
The games that are found by chance and then go viral are 1 out of hundred thousands
Yeah ik, just asking
Just look at how many games release per day on Steam
There will be, my game is the perfect streamer game, games in the same genre have thousands of people watching each night
Go to the Upcoming section and look at all games and scroll a b it
Not a great idea to gamble on being picked up by YouTubers I guess lol
And then if you plan to do EA, yo uaren't even in that list
(Of course i will still need great outreach but we have a marketing specialist on our team with like 10 YOE)
You are in an extra list for EA only that is 2-3 menus away on Steam
And there you still have ~20 game per day that release
Yeah but how will it know about it ?
Good question, it's not my job
Sounds good, but in practice, you are competing with those same games :P
Which sounds less ideal to me.
They are easy competition IF we can do what we want to
Question: can you force packet delivery to happen early in the frame? I have things I want relayed out that might be sensitive enough to care about the 15ms savings ( I might be misunderstanding something about how packets are formed here fwiw)
A lot of these games are slop that have been made in a month by a brazilian guy using Godot
Not really
But yeah i saw good, polished, finished games be obscure
There is a lot of great indie games that released
Each months i hear of new inteeresting ones
And yet, they take away visibility from your product.
Yeah I think it's a fair assessment to say they are mostly not exciting projects but there are still an insanely high amount of competitive titles
It's truly bonkers how spoiled for choice we are for better or for worse
Depending on the things you want to play I gues :p
Puh, doesn't the whole replication stuff only tick at the end?
Yeah... Which I was hoping I could do an extra pass on early in the frame
It's possible I could just do a "fake" tick that doesn't do anything but tick the net driver quickly
But I doubt that would be useful
Does GAS have good replication speed? I've heard a bunch of good things about it
What does replication speed mean?
Like it doesnt take too much bandwidth
It depends on what it has to send and many dozens of settings
And what YOU want
As usual: Depends.
Fortnite uses it, so it's okay for 100 players fwiw
But you gotta profile and optimize as usual
All is easy in MP until you optimise and considerate bad ping
real
Another input buffer spam problem I have
I wonder how low is their ASC overhead since they have 1 per tree
No, you can use Bots for CPU testing fwiw, but that's a lot of time invested into creating good bots.
For Bandwidth etc. you gotta test with real players.
The ones in the trees are lazyloaded
They don't even exist if you don't hit the tree
They spawn the component at runtime ?
Yes
I have to send essentially the same data to the server (~60 bits per) which describes a series of similar inputs
The obvious answer is custom delta to me but I wonder if I can make buffers of this that delta out of the box
I think Iris serialization could get close but I don't know if I can just make a different value the "previous" rather than per connection storage
It's exactly the same thing actually
I just want to know how i have 100fps when we are 40 players in the last Fortnite zone
We had to apply Delta Serialization for that, as it was way too expensive
I will take a look at that as it's probably got some great ideas I Miss
I'm in the process of fixing that lol
Yeah, delta diff them
Send 1 input and the rest only as deltas to that one
Reconstruct on the other side
There is another trade off that you need to consider
DeltaSerialization per Client means you have to serialize some data (not the Input fwiw) x times.
While that reduces Bandwidth, it increaes CPU usage
Which is usually more important
The amount of data is insane for my initial snapshot though... I am in the process of fixing that too as it's unsustainable to spend 2kb on one thing out of thousands
Serializing all data once and sending it x times is more bandwidth but way less CPU usage
Cpu usage here is not likely to be a concern... It's not a lot of information
Is it a cpp or UE limitation that the minimum size of vars is a byte ? (And not a bit for bools)
It's like 8 bits and some floats
Hardware
CPU limit
Unreal can pack bits
Yeah thats useful
Packed bools are great but you must be careful to not treat them like pointers in external libraries
Like imgui
There is overhead involved ultimately. Serializing bunch of data once and taking the bandwidth hit can be better
Especially with a lot of players
Idk why im excited to finish all the systems i need to work on optimisation
Over the network fwiw bools become 1 bit
The overhead of counting up duplicate bits is probably less than spending 4 packets to send one buffer imo lol
Automaticly UE does that ?
No proof on my part but it's not zip compression
Yes!!
I can only tell you that for 100 players we had way more CPU than bandwidth issues.
And it was a clear save on ms
Unreal serialization will do a lot of clever tricks with basic types
Uint32 will be packed into less bits if it is smaller
I have cried a bit when looking at FQuat replication
But larger ones (much less likely, 99% of the time you are in the 4 digit range) take one or two more bits
It's doomed with floats
You do gotta specifically call the function for it though
Honestly one massive mistake in my opinion is replicating roll over and over
Stop sending something that never changes aaaah
For an frotator
False
It will pack for you in rpc params at least
Well, yeah but if you override the NetSerialize call and just do << MyUnit32, it won't
I'm talking about 0 custom net serialization types and rpcs
And netserialize is partially deprecated in Iris for the others reading
But it's still needed when using replay demo driver replication or old actor channels
I can share some net serialization example traces but I am too lazy to get up
Uint64 doesn't pack though to my annoyance
Argh
Fwiw with what I'm doing relying on the built in stuff is silly anyways lol
I've been tinkering with sending floats on a grid hash where everything in the packet position wise is in a certain range
It's a bit cursed as it gets better the less precision there is lol
I want to forbid the players from being near world origin now
0-1 has far more information than 1000-1001 in floats
Thats floats for you ^
Cant specify precision pre send ?
Id prob try and send them as ints with some agreed upon precision
Meh you've probably considered that and 15 other avenues already ๐
There is only so much you can save if you need precision
Even if you send it as an int, and maybe support two decimal point digits worth of precision, you will still quickly run into multiple bits needed
How much reallllly needs so much decimals tho?
I need perfect precision unfortunately for some things
Unless something is stupidly large and everything makes a dent, it'd be hard to tell 0.001 delta rotator for example
A lot of things probably don't, but those are usually already ints
Thats fine ofc, if you need full precision then thats what you send
If you have numbers changing per frame it can be important
For typical snapshot style you should 100% crunch them as it's very hard to tell 1cm apart
If you have some resource that refills and the player needs to be able to execute them with .1 or 0.01 precision, then yeah
Can be a lot of smokes and mirrors
But if you need a float, you probably use 32bits in the end anyway
One funny example is the CMC timestamp negotiation
It sends them as 3 second offsets that wrap around and never goes beyond 3 or so iirc
Yeah that's why NPP FixedTick was a lot more comfortable
Insanely complex to read but it makes sense
Why use server seconds that could climb to 10k something and lose precision when you have a shared base offset?
Thats the agreed upon precision part, bring along what you need and ditch the rest
Yeah my point is just that if you need the prevision you will use a float anyway
Like, ints with 16 bits only reach 65k numbers
And that's without any extra decimal points
I'm tempted to try fixed point positions to forgo some wasted space
Glad to hear it compressing bools to bits atleast
Is it smart and re-orders the data if needed?
Guess it requires proper ordering
idk what it does without overriding NetSerialize
Might just go through the properties based on reflection order
maybe it does something smarter somewhere
Member descriptor creation
If you override NetSerialize it#s up to you
I have yet to delve into that..
Seems its mostly packing data into some byte array for transmission?
Pretty much like we do in our modbus library then
Your goal is to derive something useful out of as few bits as possible by doing the exact same sequence of reads and writes on both sides
If you send a lot of stuff that never changes, it's for example smart to think about any kind of DeltaSerialization
Sometimes variables also have context
The actual result of compression is a bit like deciding how to encode what to skip into a field
E.g. if you do X you need Y, but if you don't do X, you don't need Y, so you can skip serializing it
For example hit results send a bit for each field
If a bit in the dozen or so is 0 they know to skip that type serializing
So for example no float vector needed = 1 bit in the stream
That simple change reduced bandwidth by 50+%
True = read the next piece assuming there is a vector
False = skip entirely assuming it's not there
There is another level to this, but that is often overkill, which is per property delta serialization
Not really needed for almost all basic types though
Iris does some of this automatically
Yus
Which is very very finicky fwiw
Well, with its really nice NetSerializer code
FastArraySerializer should do that too
And in theory the Struct Serialization should also not send the whole struct, not sure anymore
They don't give callbacks like fast arrays though so they are still useful
Also on top of it all
You can oodle compression packets entirely into a dictionary
Yop, we implemented Iris a couple weeks ago
Which is kind of outside your concern with in-code serialization fwiw you aren't really calling into oodle things as much as turning it on
The biggest annoyance was fixing gameplay code that magically worked before
The onreps are dastardly
Order in which things are replicated was also freaking out
But they do an amazing job faking the same patterns of actor channels
Considering how much changes
But Iris in 5.4 has a lovely little bug in its filter
Don't know if they fixed it by now
When they calculate all the Locations and Distances (in a pack of 4 objects at a time), they forgot to add a world location at some point
WorldLocationA - (Direction * Distance)
While it should have been WorldLocationA - (WorldLocationB + Direction * Distance)
Took a while to spot that in this annoying Vector4 code
We had some good debugging in the end to visualize all the priority values, otherwise we would probably not have noticed for a while
Getting that visualization up and running fast is often key ๐
I always end with a bunch of draw debug crap all over the place
Wish there was something allowing you to just.. enable it on vectors and transforms and such
Hm yeah we only used the VLogger of UE
The rest was done "outside" of UE
Despite the occasional draw debug of course
Just like "watching" variables
But those are temp debugging things
They have built in debugging object info but it's a bit hard to use
And Idk if it includes spatial priorities
@ashen plume && @dark edge You guys are heros. Turns out this was absolutely some kind of corruption to my character blueprint when the custom character component was introduced. I still have my CMC on my c++ but after deleting my corrupt blueprint and deriving a new one and setting things back up, I can now officially say this is working proper now with every testing setup. PIE and on my dedicated server. Thanks for your paitence fellas, you guys are GOATS.
anyone know why this could be happening? im not replicating the mesh or the capsule either
Anything in the log? Does this happen everywhere?
i havent check the log and yeah it sorta happens only when i play a build/on standalone window as client
works perfectly when i play in viewport
Are these visuals attached to the capsule or the mesh?
same thing w this auto fire timer
yeah its the basic fps template
You'll have to check the logs then. No clue from just the video. Looks like it's corrections
That was an OR question
capsule
I haven't touched a template in a long while.
I know that only the mesh is properly smoothed, so attaching them to that could help. But despite that, no clue atm
im unable to understand why my clients are working weird as hell, the auto fire timers dont stop on key release/ this weird jitter
imma try
Did you maybe put a reliable RPC on tick or so?
nope no reliable RPCs on tick
so its doing this weird thing where on double click it creates another timer and idk why cus i put bools to check and not allow
the order is simple yet messes up mouse press-> reliable rpc sets bool to true, reliable rpc calls server start fire..
mouse release-> reliable rpc sets bool to false, reliable rpc calls server stop fire
server start fire-> makes timer and fires whilst checking if bool is true, if false then calls server stop fire
server stop fire-> clear and invalidate fire on server
however im starting to feel like it happens in the interval of the initial fire and the delay between that to starting of timer (time of firerate)
turning off component replicates on all my components fixed it but i presume thats not how it should be so ill try to figure out if its my hitbox capsule colliding with my ground or my spring arm having lag or whatevers
weird question, if the actor is set to replicate does it replicate all its components on its own?
this was camera lag on spring arm
There is absolutely no reason to set a component to replicate if it doesn't have any replicated variables or RPCs
The majority of components is usually not set to replicate
Including the CMC iirc, as that routes its RPCs through the character
ah i see, interesting.when you mean they have RPC'S you mean as actor components or them being used in RPC'S
Them having their own RPCs
fucking again, seriously
Using them in RPCs should work just fine without replication as they are stably named by default
i see, damn networking always seems to surprise me
Any idea why?
That always seemed so weird to me that the coupling is super tight like that
to make auto fire// should i start timer on client and let every fire event be on server or should i start timer on server (this im unable to get it to stop for clients properly)
It's not trivial
They say in the comments of the CMC if I recall. But to save on bytes for replication.
The best feeling general form is that you fire on client instantly but the server also does it
There's some stuff about burst counters too floating around
but dont we only want the server to perform the hit
the issue im having is, isnt calling a server rpc for every shot heavy?
How fast you shooting?
that's not too heavy compared to all the other info streaming into the server
the bad part about shots is that missing a shot is very bad
while missing a frame of aim direction isn't
I think thats the motivation behind burst counters
whats a burst counter?
this seems to be only for the fx, am i right?
I want to print the name of the person talking in the game on the screen but it doesn't work. does anyone know how to do it?
yee it is
Nowadays I imagine most people are just using gameplay cues, but ๐คทโโ๏ธ
Can't really avoid the client -> server RPCs for each shot
If they are reliable they can't be dropped
If they're unreliable they will be
Firing a weapon is an important event, it should generally be reliable
i see, then my old system was working just fine ig
ive been mainly confused on whats a better approach to handle this
no specific resources online either
HLL did 100 players and every shot was a reliable RPC. Worked fine
but it again confuses me, if i have a minigun which fires a lot of ammo and in very little delay like 0.013 smth then what would i do? still the same or ?
You don't just send a reliable RPC for when you start shooting, and one more reliable RPC for when you're done shooting? 0.17 sec delay sounds like an automatic weapon
0.013 would be too fast
No because your clients aim won't update on the server fast enough. Shots will go in the wrong direction
i was sending a reliable RPC for individual Fire event before not start and stop
Start Stop doesn't really work anyway
yeah it doesnt seem to
Oh I guess that makes sense if you're worried about upmost accuracy
Unless you do what Unreal Tournament does, and have a very tight coupling between movement and weapons
not necessarily just want to know if what i was doing was right/ wrong
But that's a twitch shooter and targeted 120hz servers
usually people refrain from using reliable RPCs and it scared me to have a fire func reliable since i know thats a lot
i wanna know how UE did their minigun
it seemed burst
ish
What's UE?
UT sends start and stop RPCs as unreliables, and sends those RPC's multiple times to account for drops
We use the method of 1 reliabel RPC when we start shooting, and 1 when we stop. So far no one's ever complained about their shots feeling off, but it's a 2v2 game with very low traffic
But Weapon firing is tied directly to character movement, so when you fire a shot, CMC is forced to send a move to the Server
oh damn
Unreliable's are used for start/stops there because they won't block other interim RPCs, but they have a custom ack protocol
im trying to do the same right now but client releasing the mouse isnt being registered properly on server
so using reliable RPCs on timer to shoot is fine? even if i have lets say 20 players?
Well you should definitely take jambax's advice. But if you do it the way I'm doing it, both start and stop should definitely be reliable
yep
had them on reliable and used bool to set too, didnt work
But a 0.013 fire rate is pointless unless you server is running at 100hz
ill use jambax's advice and go back to the old method i was using then
nah it was just an example i set to know
i dont have any gun firing below 0.14 afaik
For reference in HLL we had guns firing with a rate of 0.05, which was the max we couild support given the 20hz servers
Well, there are ways to do faster I guess, but we didn't need it
But each shot was a reliable RPC that included the shot origin, seed, and direction
i did play HLL, didnt see any issues with the firing yeah
And that scaled to 100 players, though I doubt it'll perform well if everybody was doing it at once, but you can't create that in-game so meh
time to revert back to the old method, you got a working example so why not ig
best to worry about this stuff when it's actually a problem. far too easy to overthink it
i guess i can use the burst thing for fx and RPC for the main shot
yeah thats the issue, i keep overthinking if i might cause issues later down the line
And if your game is a shooter, sending movement and firing RPC's probably account for most of the outgoing bytes
in which case you can just refactor it later
hmm everyone gives this advice- to wait for the problem and solve it later
I imagine that worked well because the game is almost entirely shooting? I'm trying to imagine that setup in a 100 player survival game . I wonder if that would hold out
it just feels weird so i ask and look for better solutions
Guess the methods would really depend on the game
If you think that Fortnite does all it's stuff via gameplay abilities, which is one of the least efficient ways to do anything really, they get away with it pretty well
Pretty much
i never used GAS sadly, been stuck to 4.26 w this project, didnt touch GAS w my newer projects
so idk much about it or how inefficiant it is
this yeah, but then i bet theyd use methods like that burst method or replicating their own objects or other stuff
It's decent enough, but it's a blunt tool
but that idk, i just worry before i get the problem, guess thats the problem
ah i see
@chrome bay thank you for the help
just my past experience ofc. Others may have different views
anything helps!
oh yeah, im curious- whats seed here if you dont mind telling?
uint16 I think
Seed for bullet spread RNG
Server and Client know what the next value should be, so it's a sort of shitty anti-cheat as well
ah interesting
If you need a time-sensitive buffer of inputs sent from client to authority does reliable make sense there? Right now I just spam send an unreliable with all un-acked pieces and it works alright as the size is small
I would rather waste a tiny amount of bandwidth than risk these being late
It's a bit similar to CMC move sending I guess
I want to print the name of the person talking in the game on the screen but it doesn't work. does anyone know how to do it?
sending raw text over the network is a bit wrong here unless it's actually impossible to know what it is otherwise on the receiving client
also I have no clue what part of it doesn't work... we need more info than that
does it not send anything at all? does it not send the right info? does it get stuck?
wouldnt it be the opposite
as youโd be waiting for the original rpc before the others can be used
wait unreal reliable rpcs are ordered correct? cause if so then it would be worse for time sensitive things sent consistently
I think them being ordered is in some ways actually useful for me as I can't "skip over" missing pieces but I don't really know what reliables do in practice... I don't know if they wait for other reliables to read on the server first or if it's per-type
My setup now works just fine and I can compress the hell out of it so I see little reason to change I guess... just wondering in case I am missing something silly
compared to typical game traffic this seems kind of okay but it won't be this small forever ๐
this could easily be compressed to be half the size too
the original rpc isn't waited on for unreliable, it's if you get the information for frame Id X from any of them and then that ack is sent back in the form of the latest known frame from your client
it doesn't matter if that's packet 1 or 4 from the perspective of the client or server, the point here is to avoid the situation where they get dropped and you have to go ask for it again in another round trip
I should probably add some timeout where if the number does't go up after like ~3 seconds you can assume you are probably toast
I might be missing something about how rpcs work but afaik it doesn't order unreliables or wait for them besides the target object resolving
which on the server is just the player controller, it's already chilling there
ERemoteFunctionSendPolicy ๐คฏ
holy shit, this might be exactly what I need
shaving ~10-16 ms off of latency for rpcs (assuming it actually is faster in a linear way and not dying to routing on the network etc) is bonkers for me... thank you Epic
this might be worth a pin lol
I have to figure out how to actually use this first lol
It requires either using Iris or Repgraph
ah the documentation is waay off, it's UReplicationSystem::SetRPCSendPolicyFlags
Do folks know what these columns mean in the network profiler's main tab? Couldn't quite find anything in the engine source, nor online to grok this.
MS = Time in milliseconds spent processing.
MS % = % total of amount of milliseconds spent.
KB/s = Kilobyte /s (Average amount of kilobytes/s for this event)
Bytes = Total number of bytes sent for this event
Count = Number of times this particular event was called.
Update HZ = Number of updates per second for this event.
Rep HZ = Number of replications per second for this event
Waste = Data prepared for replication but isn't sent either due to relevancy or priority.
Saving this into my records, thanks so much ๐
Is there anything visual in the profiler that can help me detect if, for example, I've reached a point where thing start to break down? E.g. I've maxed out the packet MTU and now updates are being dropped because there's just not enough space per packet to fit them in, so some things are not receiving timely updates?
We're in a situation where we have a ton of moving actors in a certain area of the map that are all transmitting their position at the same time, so I wouldn't be surprised if those transforms being constantly sent to clients would hit some limits.
@vapid gazelle I wonder why you aren't using Unreal Insights
That has a Network tab too if you enable tracing for Net
That would also have visuals to show you the bandwidth usage etc
Going to look into that next, thanks for the tip. I think I landed on the network profiler first before I read somewhere that it's been superseded since by Unreal Insights, womp.
Hi, say on the client I load a FprimaryAssetId async, then I get the primary data asset object, so it's loaded on my side. I then pass the FprimaryAssetId to the server which will replicates down the AssetId, and in the OnRep method I do load async the Asset. I wanna know if it is good practice or useless or else ?
seems like a lot of extra work when the server can just replicate the loaded asset pointer
hello everyone hope all of you are doing great. I have a question and some problem if someone could help me please.
I have two roles in my game will be assigned randomly so I'm trying to make for each role their logic , so I decided to be a different USceneComponent and in that add it's logic and it has USphereComponent but a lot of errors poped up .
is't a corret way or there a better way ?
also does anyone got the error ?
trying to bind OnComponentBeginOverlap
in begin play
about this I fix it by checking the Sphere Pointer .
You could do that, yes, but in theory, if you need the asset available in that moment anyway, you can just replicate the loaded asset pointer, forcing the client to load the asset directly. If that asset causes a hitch, then you have too many dependencies anyway.
Yeah you don't need to check the this pointer. You would already get a crash when the caller tries to access the instance.
In theory, you also don't need to check the Sphere pointer, as you could "expect" that to be valid if it's a Subobject created in the constructor.
Might be worth putting an ensure or even a check on it if you really think it SHOULD be valid.
Also please use if (IsValid(XYZ)) for UObject pointers and not just if (XYZ). UObject pointers can be valid but point to an object that is marked for being destroyed next GarbageCollection cycle.
thanks for the advice
about the sphere I put under it a check(Sphere);
and still keep me crash , I don't why
If you crash you should share the crash message and callstack with us
it was working until I moved the functions to USceneComponent that will be child to this ( character), but doesn't work so I return it
I don't know what you mean with "moved the functions to USceneComponent"
`Assertion failed: Sphere [File:C:\Users\yahya\Documents\Unreal Projects\EscapefromFreezing\Source\EscapefromFreezing\Private\Characters\GameCharacter.cpp] [Line: 67]
UnrealEditor_EscapefromFreezing!AGameCharacter::BeginPlay() [C:\Users\yahya\Documents\Unreal Projects\EscapefromFreezing\Source\EscapefromFreezing\Private\Characters\GameCharacter.cpp:67]`
Show me where you declared the Sphere variable and where you create the component
like I have some functions need to be done for a specfici role in my game , I have two different role.
how to manage for each one has it's own logic ? I used USceneComponent will be turned depend on the role
By utilizing Inheritance usually.
in the construct
AGameCharacter would be the parent to AGameCharacter_RoleA and AGameCharacter_RoleB.
the roles will be assigned randomly also when the players already spawned
Well then it would just be an enum with RoleA and RoleB
And you'd set that whenever the role gets assigned
And then switch on it in your overlap
Or wherever you need it
I'm using Enum for the roles , but I thought by the time will be messy
Please use TObjectPtr<USphereComponent> Sphere if possible.
Won't fix your issue
It really depends on what your roles should all be responsible for
I can't suggest anything without knowing that
An enum sounds reasonable
The check after the if is not needed. Either you check, or you do if (IsValid(Sphere))
the roles control the players interact and attacks, mostly like how DBD but the roles are random
For now just stick with the if
Right, I would probably stick to the enum, and in cases where it's clear that RoleA gets different things than RoleB, I would probably spawn something runtime that handles that
Interaction is probably easy enough to handle with the enum
Attacks sound like you could grant those types of attacks when the role is assigned
actualy I think yea, also when it needs to be in different scripts then I will do it, but for now keep with Enum
Why the Sphere crashes, i don't know. You seem to be creating it correctly in the Constructor.
You aren't using LiveCoding or (worse) HotReloading or?
You have a BP child of that C++ AGameCharacter?
yea
I would suggest you create a new one and try that out.
You might have managed to break your BP
I have an enemy driven by a behavior tree that automatically follows me. At its begin play node, I linked LinkAnimClassLayers, but strangely, only on the client side, the enemy plays running animations normally when following me. On the server or in single player mode, it only stays idle and moves towards me. Why is this? Why does the delay on the client cause the Anim state machine to start correctly? Is this related to PossessedBy?๐ค
Post whatever logic you have please
i want to play a small sound instrumental song when the game starts, this song might change later depending on the game mode. Calling the "play sound" node on the gamemode blueprint only works for the server, where would be the best place to call this?
gamestate?
well i dont want to make a derived BP just to call a sound and i dont want to make that sound play from c++ either, is there a more handy place?
Leaving this here for anyone experiencing this problem. The core problem is about the GameState remaining null & never getting replicated no matter how long you wait after Seamless Travel. I'm working within Lyra & using GameStateComponents.
After a deep dive, & long story short, I cannot trust any replication-related operation to be conducted during or before all clients spawn in after Seamless Travel. This appears to progressively get worse as multiple seamless travels chain together. I have a player initialisation system which ensures that all replication-related operations are performed after all clients have fully spawned in & possessed their pawn in the map. When replicated components exist, it appears that if the client initialises a version of it before the server can (race condition with joining the destination map first), the server doesn't validate nor replicate the updated version of the GameState. Hence, the solution is to put all of that logic after everyone successfully spawns in.
For easier searching, I'm leaving one of the logs here:
LogLoadingScreen: GameState hasn't yet replicated (it's null)
Heya, bit of a cross post, but was hoping someone had a c++ / BP for a multiplayer projectile that uses GAS. essentially, cast fireball GA, spawn Niagara travel almost instant in direction til it hits an actor or reached a distance.
Problem I have is replicating the Niagara system to clients. Projectile component does its thing right.
I requested a steam playtest codes how my team redeem them from here ?
Your Team shouldn't need playtest codes
The usual way is to properly add users to the organization. Then will then have access to the dev builds
When it comes to making custom pawns, is the recommendation to make a custom movement component that handles all the network issue cases and predictions, or do people tend to just try and hack the cmc to work with the custom pawn?
I wouldn't use the cmc for pawns.
You could try Mover 2?
Or just make your own.
Depends how complicated you need your movement to be...
Is mover2 stable atm?
We don't have a problem with it, but plenty of people in here complain about random stuff.
Last I checked it was experimental and in active development so I'd be worried about it just completely breaking
What I've done with an update
We've been using it on 5.4 exclusively.
Enhanced Input was experimental from like 4.26 until 5.3, just for reference.
I think now it's still just beta?
Can't remember if it's beta or full release but yeah ei was experimental for ages
It relies on NPP which is quite expensive atm, if your game is networked then thatโs something to consider
(Network prediction plugin)
How expensive is it compared to cmc?
I donโt have exact figures but it sends a lot of extra data each NPP tick to account for any gaps in packets that might occur (it has bad reconciliation logic atm an no one is actively fixing it on the main branch)
Are we talking expensive on bandwidth or computationally expensive?
Computationally
Yeah stupid auto correct got me
I was talking bandwidth
Here was jambaxs take and he had actual experience on a project with it
Fair enough!
Ye, itโs just something to consider.
Itโs a shame because NPP has really nice comments and I like how it was written but itโs just abandoned :/ (at least right now, there was a minor update but more to be done still)
What would you recommend for a push/pull physic system ?
For now im just planning on moving the actor and let them replicate its position and rotation
UGrabberComponent UPhysicsHandleComponent or something exists, not sure if its networked like that though
Could use advice if folks have a sec. I'm trying to trace my network stats so that I can analyze them in Networking Insights part of Unreal Insights. I've been able to have the tab appear, but there seems to be no data in it. I'm pretty sure I'm not running this correctly inside of my editor.
Am I missing anything obvious here?
did you read the documentation for how to use network insights?
you probably want -NetTrace=4 -tracehost=localhost -trace=net,default,task
also each new pie session will spam new connections
Yep, that's how I got this far. Looks like it might not be possible to pass those arguments from inside of the editor, the editor has to be started with them to begin with from VS/Rider. Haven't had to do that before, trying to figure that out now. From Reddit:
I had and it was running but the network insights tab was missing. The problem was that using the in Edit Preferences/Play/Additional Launch Parameters section, the command "-NetTrace=1 -trace=localhost -trace=net -networkprofiler=true" didn't work. I had to put them in them inside rider for when it called unreal. That was under the (game name).vcxproj.user file.
yes... this is a startup argument for the application
I bought this project on Multiplayer lobbies to learn from. when remaking it, I found that my disconnect has some bugs in it, I've now made it a near spitting image of the one I bought. What could cause his to run so soothly while mine has weird bugs? I didn't show it but after you kick the other player in mine, the other player cant rejoin no matter how many times you refresh the sessions. No idea what's causing that either.
could it be because they are using "Game Mode Base" and i'm using "Game Mode"
Which one is the intended, first or second?
The first one. I bought "Simple Multiplayer Lobby" and it works exactly how i would expect. When a player is kicked the player name is removed. On the second one (mine) when the player is kick, the names double up for a moment.
i know i'm not providing any blueprints to help out but i'm hoping its just a setting or a game mode or code that could do that.
The names doubling up seems like a mistake in the widget for not cleaing the old entries, and some code causing an update to run that repopulates it?
it only happens on the client too.
Does the widget clear the entries before adding new ones?
it does in the code. I closed the project I bought and tried it again with just mine open, I dont see it happening anymore. Maybe my computer just isn't strong enough to handle to unreal projects open at once.
Is there an easy way to tell if the server is struggling with transmitting as much information as it would like to to an individual client just by looking at the packet size in Networking Insights alone? E.g. I'm noticing that at the client's join time there's a quick burst of packets up to about 1024 bytes, and I'm wondering if that means that in practice the server will try to cap packet size at 1024 and after that it saves the rest of the payload for later?
I haven't found clear answers online unfortunately, it's about 64K for UDP in general, but that's without taking in consideration the fragmentation of the packet while in transit in order to fit into that network's MTU. I've seen 512 mentioned as well. The closest I've found in the source was:
/**
* Values used for initializing UNetConnection and LanBeacon
*/
enum { MAX_PACKET_SIZE = 1024 }; // MTU for the connection
enum { LAN_BEACON_MAX_PACKET_SIZE = 1024 }; // MTU for the connection
but also there are places that multiply that value by 8, so I'm not clear if that means the max is not actually 1024 bytes
OutgoingPacket(MAX_PACKET_SIZE * 8)
Curious if anybody knows for sure.
@vapid gazelle keep in mind that 8 bits is 1 byte. Multiply by 8 could just be conversion
Yeah, fair enough. I figured those were bytes, but maybe not ๐ฎ
So far I've yet to see a single packet go over 1024 bytes, but I haven't run anything particularly taxing just yet.
Also interesting note from the docs:
The reported size of each packet is before compression, so the actual data on the wire may be smaller than what the report shows.
Yeah
Most of the expensive stuff are naked floats and initial class replication
Otherwise you usually barely reach 1k bits, let alone bytes.
Depends on what you are all doing of course
The thing I'm trying to test right now is having like 100 AI Actors that are constantly moving on the server, with their position actively replicated to the client many times a second, and trying to figure out how heavily that's taxing the network. I'm not too worried, but it's best to profile first and make a call later just so that at least I have a baseline to work with.
I think the movement packages from server to auto proxy when using mover and npp and optimizing it a bit were between 200 and 400 bits. And that was with transform(s) and multiple movement modes, stamina and what not
You'll also need to diff between data sent to the AutoProxy and data sent to the SimProxy
AutoProxy often needs a lot less data, as it has all the required data locally.
So SimProxys quickly go through the roof while they might not need the data you are replicating
Yeah
The good thing about bandwidth is that you can often take it for granted that the bits can be multiplied by the amount of whatever you are doing
If one AI causes a constant 20 bits, 100 will cause 2000. Obviously depends on distance, relevancy, what the AIs are doing etc, but there is some level of prediction possible.
Still worth double checking of course
Ah, that's a good point, fair enough. The extra cost per actor is effectively linear, there are no surprises introduced by additional scale short of some new interaction that the higher number of actors would introduce, makes sense.
Yeah, of course if all of them cause a replication of some big data you will have a spike
But on a base level if you e.g. On tick replicate a float for everyone and you want 100 AIs on the screen then you can expect that to sum up to 3200 bits
The 1024 bytes melt quickly
That isn't even taking other players into account
Yeah, I think it'd be a transform replicated for each AI to each client however many server ticks there are. I'm assuming that if the server is say running at 60fps then the server would have 16ms to spray the clients with enough packets to report all of the necessary changes, up to some outbound network IO limit on the server.
I'm at least assuming that all of the updates don't have to happen in a single packet per client per frame? No reason for the clients to not be able to accept n packets with the requisite updates up until they actually need to start computing the next frame?
Well the server will try to send per frame
And if the data is important then the client should also not wait too long
Depends a lot on the data
And AIs using CMC will interpolate anyway
30fps on the server might be enough if it's not some competitive counter strike
packets are limited in size
by MTU
it's honestly kind of difficult for me to find an obvious marker of it delaying or deferring a send for later
meanwhile in my hellish RPC frame state:
This particular Actor is an AI bouncy floaty cloud for players to bounce on so the original implementation uses a UFloatingPawnMovement which doesn't look incredibly smooth on the client, but I might be doing something wrong. You can definitely tell it's on the choppy side, but it might be because of how I'm moving the Actor to begin with, I'd have to revisit that.
Does insight even show if a packet is split?
Yeah, I would love to know what that number is. I've read anywhere from 512B to... 64k. It seems like 500ish is the worst case scenario that the packet might inevitably have to deal with if it's some old raggedy bit of the net?
The 1024 you found in UE Source sounds reasonable
this is not an unreal jargon thing but a networking thing... I guess the point is that packets are each all going to be roughly the same size and to send lots of data you need more than one
unreal magically stuffs your data together for you though ๐
not reasonable enough... can I raise it?
Idk. Never tried.
Also not sure what the ini file bandwidth variables do again
It was once said that UEs defaults were too low for modern standards
yeah I'm kind of floored at how little information is out there about actually seeing when it elects to not send things
another silly property is that the limit is per game
your connections could be from wildly different client speeds
and there's no way to say "hey, make this thing go first" afaik at this level
Ah back to your own troubles haha
the RPC order thing for Iris actually works
I haven't measured it much yet but it appears to make a writer in the datachannel right before tick
order as in sending IMMEDIATELY and not waiting for the game tick
this can save a lot of time normally spent waiting on the net broadcast at frame end
honestly I'm considering turning this on for almost everything as there's not much that doesn't want this for my usecase
Doesn't this invert the problem in some cases? As you are sending data of the previous frame and not the result of the new one?
well, in this case the data is already as-is
this is input data from a player that everyone else must know about asap
this being late = rollback hell
Or rather, the data is the same and now you actually delayed it from end of last frame to start of new frame?
the simulation of the game server is not going to change the input data of clients
Something something
Hmhmhm
if this was something that was "most recent result" it would make sense to wait but it's not, it's a specific point in time
if (UReplicationSystem* ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(GetNetOwner())) {
ReplicationSystem->SetRPCSendPolicyFlags(
FindFunctionChecked(GET_FUNCTION_NAME_CHECKED(ThisClass, ClientReceivePlayerInputBufferUnreliable)),
UE::Net::ENetObjectAttachmentSendPolicyFlags::SendImmediate);
}
Right okay, but that means it sends it in the middle of the frame whenever you call the rpc or?
not 100% sure where to place this... Do things share ufunction ptrs?
right before world tick begins
read network data -> send oob stuff (these immediate sends are oob rpcs) -> tick -> regular net broadcast
no, it can be received from clients when clients send data
Ah you also read before world tick then, okay
technically the listen server also produces input inside of the tick but that's a different thing and it's fine for that to be sent later (oh well)
SetRPCSendPolicyFlags makes a map of function ptrs and flags
I don't know if these are per-class or per object
for each RPC ufunction ptr
makes sense to me I guess as it doesn't pass in a ptr
Yus
Compiler wise it will look at the classes function. Only when calling it it will bind this to it I assume
But not like I deeply consumed the c++ compiler shit
The issue I am having with my repnotify is that
While my weapon fires the state changes to attack
And for auto fire
The work is not replicated on the Sim proxies how am I supposed to replicate it on sim proxies
Not sure what you are exactly asking, can you reword that?
Replication to SimProxies is usually a given if you don't have an owner only actor or variable
I am calling on owner If autonomous proxie then on server
Finally on rep
The firing state changes so quickly that it cannot replicate on client
What is the type of that variable?
Enum
It change to attack And none state should I make another enum ??
For auto under that
Depends on what the enum is for. If you just want to indicate that a player shot, then you should probably not use an enum but an int as a burst counter.
Enum can be used if the player can toggle the fire mode of the weapon fwiw.
The enum is for management type like pickup equip attack and none and so on
The idea is having a natural push/pull that the players apply with their hands (so its like pushing a wall/something heavy) the object would move slightly on the ground until it's blocked by something heavier or falls because the floor goes down
So idk if i should set location or use a velocity/force method
Since my game isn't some heavy competitive thing i could do something based on animation sockets
is there any good way to have destructible objects be predicted in their destruction ? without using something more suited for this like gas, i really only have the option of praying that the server doesn't drop the last hit that a client registers. as in, the client locally attacks and hits the object and it's on it's last hp and destroys , but the server maybe drops that or something, not sure how i'd accomodate that , unless i forced it through after if fail
I guess id just locally hide it and let server deal with thr actual deatruction
Is there any function to override in PlayerState or PlayerController where I can be 100% sure that the other part is initialized on the client? Want to dodge a hacky approach with tick function for a one time use
Just make the RPC reliable to the server?
I mean damage payloads probably need to be reliable for your game to work~~~ so Iโd think this is already the case
Iirc playerstate is created by the controller
Hello
<@&213101288538374145>
OnRep_PlayerState() exists on the PlayerController which should be triggered on clients when the reference is set and replicated to them.
@sinful tree thats what I was searching for, thank you :)
OnRep_Owner for the PlayerController on the PlayerState should also work
So many options !
--- Help ---๐ฅ
hey guys i want to increase download and upload speed inside project , actually i have file on MB and i want have high speed to upload and download them , where and how can i Increase them in project ? Thanks ๐ง
Anyone on here can assist in creating a multiplayer faction system? Currently stuck in how to invite other players to join the faction
You probably don't want to utilize unreal's replication and networking system for downloading large amounts of data to clients as it was never intended to handle it.
If you wanted to try and do it, then you'd basically have to break it up into smaller parts and send them through reliable RPCs with an ordering system to ensure it can be rebuilt correctly on the other side.
The alternative is to have clients upload or download from a cloud system of some kind using HTTP/REST.
i want to send file to GPT servers , so i need the high speed of netwoking , im using va rest plugin
You could still build something that allows clients to upload somewhere without having to utilize an RPC to upload to the server to then send to ChatGPT.
Is this backed by any backend? Or does this all just live in some savegame on the Server or player's PC?
In general, you usually make sure that the Player that wants to invite another player has access to their PlayerState in one way or another.
Unreal's networking system was designed to handle networking of game logic, not file transfers, and thus manipulating any of the network settings to try and accommodate sending large files quickly messes up how everything else was intended to work, and the mere act of trying to shove a ton of data over RPCs can break things.
There are limits to how much data can be sent through an RPC, limits on how large arrays can be both in terms of number of indexes and amount of data they can hold (you'd probably be using arrays of bytes to transfer binary files), there's a reliable RPC buffer (which is how many reliable requests can be queued up along with their required data, and you'd have to use reliable if you wanted to ensure the data was fully received), and limits on the number of packets that can be sent in a single frame. So it's not just a matter of flipping a switch to say "GO FAST'.
A bit of a search on google says that you can increase Uneal's networking system to boost the bandwidth a bit higher, but it's still not going to work well, as you're going to potentially be breaking other things in order to achieve this one part of the goal.
A much better system would likely involve an external REST server that your clients authenticate to VIA some kind of token sent by the game server so only valid clients can call your REST server and then use your GPT API keys. The REST server can then receive the file and then upload it to ChatGPT. The results from the upload can then be redirected to the game server by some means (web hook?) to then cause some in-game logic to trigger. If there is ever files you need to send back to clients, then hopefully you can save them somewhere online, again behin a REST API and then notify the appropriate clients to retrieve the files VIA an RPC, and then they can go and download them as needed through VARest. Doing it this way bypasses Unreal's limitations entirely, but means you have a bit more work developing an external system.
Assuming you have some PlayerList Widget, you would want to make sure that each entry is driven by the PlayerState. That way, when you then implement a RightClick -> Invite to Faction function, you can grab the PlayerState and send a ServerRPC (via the Player's own PlayerController, PlayerState, Component, or whatever else you want to use that is owned by said Player) that passes the PlayerState along, so the Server knows exactly what Player is being invited.
From there on, the Server can then send a ClientRPC to the Player that got invited.
E.g. via the PlayerState, or the PlayerController (Owner of the PlayerState), or again some Component.
On the Client side of the Player that gets invited you can then show a UI Element where they can Accept or Decline. Either way, you can send a ServerRPC back with the answer.
You may also want to add some logic on the Server side to check if the Player isn't already in a Faction and send error messages back to the inviting Player if needed.
As well as maybe keep track of Pending Invites somewhere.
Storing this information for reconnecting players is a different story.
Hello there, I'm might be tingling something answered hundreds times before, sorry if that's the case.
Could anyone point me to some nice material about using NetDB plugin with UE5 blueprints? Or basically any other DB plugin. I'm trying to see some standarts and good practices with database flow in a blueprints for a multiplayer game. Where to store such functions, how to call them properly, what to avoid, best practices etc. I know generally I know I want them fully server-side without client having access to it, but I'd like to go deeper.
Any good material on such topic? Thanks in advance.
thank you
the best speeds i've been able to pull from using UE's built in networking was around 50kb/s and that was using a custom NetChannel class
where and how i can access that ? please help me out
it's c++ only, but the jist of it is you create a class that inherits the UChannel class and in your DefaultEngine.ini you add [/Script/Engine.NetDriver] +ChannelDefinitions=(ChannelName=AssetTransfer, ClassName=/Script/JPB.JPBAssetTransferChannel, StaticChannelIndex=-1, bTickOnCreate=true, bServerOpen=true, bClientOpen=true, bInitialServer=true, bInitialClient=true) replacing ChannelName and ClassName with the name and class of your custom class that inherits UChannel.
Actually getting the net channel is a bit strange and I might not be doing it in the best way, but to get a channel for a specific client, you get the UNetConnection object from their PlayerController class with GetNetConnection() and then loop through the "Channel" array, comparing the channel objects ChName to whatever you used in the .ini
and in your custom net channel class you can override ReceivedBunch(FInBunch& Bunch); to handle recieving the data
and send data with SendBunch()
UVoiceChannel is a good simple example of how to use a net channel
Hello. I'm trying to persist data between game servers during hard travel (since my game doesn't use a lobby or matchmaking system, itโs just a persistent world with different maps). My game servers communicate with an external master server to handle travel and determine which server the player should be redirected to when changing maps. My players are mostly identified by the master server through an ID linked to a token.
Is the GameInstance class a good place to store the player ID and their token, so that each time they join a game server during hard travel, they can send this information to the game server via an RPC to retrieve their data using their ID-token?
in hard travels the GI is the only persist thing
You don't want to RPC this but yes
The ULocalPlayer should have a function to override that constructs the option on the connection url
Basically the ?x=y stuff
You can send the id with that, then it's available in AGameMode::Login etc
Which by now is also async so you can ask your backend in that
And deny the player if that fails
Oh truuue I forgot that you could pass parameters in the url string, thank you!
Hi, I'm using multiplayer for the first time and I'm having trouble with server/client communication
I have a widget in my PlayerController, and I want to change its appearance for all clients when one client clicks on it. What would be the correct way to do that?
I've spent hours on it unsuccessfully
How can I retrieve IP address of listen server locally? (Not for LAN connection)
I basically wanna print it on the screen so you can tell it to your friend and they can join
In order to RPC to the server (the only means for a client to communicate anything to the server) you need to send that RPC on a replicated actor owned by that client, so either their player contorller, playerstate, controlled pawn or a replicated component that exists on one of these actors. Usually for UI stuff, the PlayerController probably makes the most sense, so use it or a component. You UI would need to call to the RPC.
Once running on the server, in order to communicate back to all clients, you either need to multicast or utilize replicated variables on a replicated actor that is always relevant (if you always want all clients to receive the updates). Which to use depends on whether it's a one-off event, or if you need some kind of state to be held. GameState is an easy to use always relevant actor, that could potentially suit your purposes, but is good for more "global" type of variables not specific to any single player. If you wanted variables tied to a specific player, you'd use their PlayerState.
Communicating to the UI can be simple using a binding, or complex using a more event driven means. The simple way to utilize this variable would be to create a binding in your UI that gets the GameState, casts to your custom gamestate, and reads the variable as required.
An example:
A button that changes to a random color whenever any client clicks on it, and all clients should see the same color.
The color of the button should be a replicated variable on the GameState since it's something globally shared by all clients, and is something stateful.
So it'd be:
Button Color Binding > Gets GameState > Casts to Custom GameState > Return Color variable.
Click on button in UI > RPC through Player Controller to Server > Server goes to GameState > GameState sets color variable
Color Variable Replicates > UI binding automatically reads the new color and UI updates itself.
I have a actor that stores PCG data and respawns them based on when they were destroyed (trees, rocks etc). This is stored in a replicated array. When a player joins / rejoins though the PCG map is rebuilt on the client even though they no longer exist on the server. I want to remove all these instances but the replicated data does not get passed on to the new client. I also tried to do this with a server call (to get the data to the new client) but getting a no owning connection actor since it's just placed in the level. I tried setting the owner on begin play for this actor (getting the first player controller) but this didn't solve the issue. How can I go about this?
You'd need to use something that retrieves your public IP address which you can't really do without communicating to something outside your network, for example, using a website like https://checkip.amazonaws.com which returns your public IP address.
I'm not sure but I think using the VaREST plugin with that address would do the trick if you're limited to blueprints.
I can do C++
But is it okay to use a random service to check my public IP built into my game?
Maybe not a random one if you're concerned about up time or outages, but that means that's another system you'd need to build and maintain. That one I've given you is from amazonaws which should theoretically always be up.
I use this for dedicated servers. you could try it with a listen server check before it
TSharedRef<FInternetAddr> hostaddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->GetLocalHostAddr(*GLog, false);
As far as I understand this just returns your local address which starts with 192.168. which as far as I understand only can be used for LAN
I use this for my dedicated servers on a public cloud, it returns the public IP
Interesting. Maybe it has something to do with which OnlineSubsystem you are using?
Or maybe servers built different
No, it has to do with how the network is set up. A dedicated server would certainly need to use a public IP address as its main address in order for connections to come in. Computers behind routers, like the ones players would have at home, have internal networks that aren't publicly accessible.
This allows many of us to use 192.168.0.X for our private IP in our internal home network for example, but then when we communicate to the outside world, our computers speak to our router asking to go out to the internet and the receiving end would see our public IP address.
This also means if you're wanting to run servers on an internal private network and connect VIA IP, you need to set up port forwarding so that when someone has the public IP address and they request a connection to a specific port, the router can send the data to the appropriate computer on the internal network that is waiting for those connections.
- So that means I can't setup a peer to peer game easily?
- Do I need to deal with ports in my router or something like that for this to work?
- Btw do I need port information to be able to connect with console command "open IP_ADDRESS" ?
There is no Peer to Peer in Unreal. it's always client/server.
You can have listen servers or dedicated servers.
If you intend to connect VIA IP, yes, ports are a concern, whether listen or dedicated.
Using sessions / online subsystems can bypass the need for using IP addresses and port forwarding.
I believe If you use open IP_ADDRESS it'll default to port 7777.
Isn't listen server same as peer to peer?
No
Client/Server means one computer acts as the host, the central authority. Communication is only between the client and the server, never a client to a client. If the server is disconnected or the host leaves, then the game is effectively shut down as everyone else will disconnect.
Peer to peer means there is no central authority as effectively everyone connected is the authority - each continually update the state of the game as they see it, and they all communicate to all other nodes in the network. As there is no central host, you could have one person start the game and 3 or 4 others join, and then the original person that started the game could leave but the game will still continue as it's running on everyone's computers.
Dedicated Server = Client/Server relationship. It is headless, therefore no graphics are displayed, and no audio is played.
Listen Server = It's still a Client/Server relationship, just that you also happen to have a player playing on the instance of the game that is acting as the server.
I see, I was talking about listen server then
So wise choice would be using sessions then? Or OnlineSubsystemSteam?
Yes. IP Addresses & Ports is now considered the "old way" of doing things.
Sessions have a means of doing what is called NAT Punchthrough, which is basically a means to establish a connection without port forwarding anything.
if you have a replicated actor in the world on a server with a replicated array, a new client joins, the data in that array won't automatically get passed to the new client?
I don't understand how sessions can work tho. as far as I understand you can search for sessions without any IP or something without using steam, epic or any other provider
How?
I mean some centralized place is required for storing and querying that information, right?
It should eventually.
that's why I use something like nakama on a static IP with all server info but that's probably overkill, I would imagine just give them your public IP
Null subsystem I believe is only useful for local testing of games. There's no matchmaking or NAT Punchthrough or anything like that.
Using something like Steam registers the server with Steam -- since your server is connecting to Steam they would have your IP address and know what port to use for the game server and can perform a NAT Punchthough to get clients connected. When you have a client looking for a session, you're searching based on an AppID - Steam will retrieve a list of all servers currently running with that AppID. When you request to join a session, it can then get your client to negotiate a connection to that server.
Would you suggest testing my game in an actual multiplayer scenario using private steam demos or something like that before further developing?
I'm a bit concerned about some issues that can potentially work fine on PIE
I mean testing each feature in actual MP before further progressing
You can test locally without involving steam.
Involving Steam across the internet I believe means you have to buy an AppID ($100?)
I imagine null subsystem would provide same interface as steam subsystem? So I can swap out easily?
If you want to test how your game plays you don't need to worry about sessions or anything like that... You can just connect using IP addresses and the like.
If you want to test the functionality of how Steam Online Subsystems work you can do that locally using 480 AppID for free but this won't work across the internet.
Oh, would it work in LAN with multiple machines? the steam
Or do I need to run two instances in same machine?
Oh wait, I think I remember. I need two steam accounts for this don't I?
And it works just like any steam game
Steam apparently doesn't work well with LAN.
And again, if you wanted to do anything over the internet, you'd need to buy your own App ID.
Testing Steam w/ AppID 480 = everything on the same PC apparently.
What even I'd be testing with this method then? Two game instances in same machine?
Yep
But it somehow can give same result as full MP?
If you've packaged your game, then you're getting as close to what the game would behave like if it was distributed and played over the internet. The only thing it wouldn't simulate well is high ping / packet loss scenarios since it's running locally.
Oh wait... Apprently you can use 480 across the internet too.
Great. Then I'd like to ask for some resources. Up to date ones prefferably
On OnlineSubsystemSteam
Source code 
yes, thats what used for pirated games
any game released on steam that has MP support can use 480 so you can play with ur friends on a pirated games (because you play as "P2P" and not on official servers
I am setting up steam server but it gets the name not from steam but from the computer. what I need to do
- You shouldn't need a replicated array of "players connected", especially so if it's an array of player controllers as PlayerControllers do not replicate to all clients. There is an array in the GameState called "Player Array" which is an automatically managed array of PlayerStates. This is accessible on all computers as well. If you need access to the PlayerControllers on the server, you can get the player controller from the PlayerState, so you can still utilize the Player Array to access them all if need be.
- You shouldn't need an array of player names either. The names can just exist on the PlayerStates and you can read from the PlayerStates when needed.
- If you appropriately implement the Steam Online Subsystem, you should be able to read the Steam ID and get the player's Steam name to then store in the PlayerState's own PlayerName variable.
Client calls are only sent to the locally controlled one?
wondering if a local check is even needed here
You mean client RPCs? It's dictated by who is the owner of the actor. If there is no client owner, then nothing is sent.
So like... Sending a client RPC on a Character from the server would send it only to the client who is possessing that character as they would be the owner of it. If there is no players possessing it, then nothing is sent to anyone.
a unicast rpc I guess in that case?
FWIW if the server->client restriction of being generally limted to playercontroller/pawn objects is frustrating
you can always just add components with rpcs if you want to split them up a bit ๐
replicating subobjects is not very difficult anymore thankfully and is kind of done for you
would 12 bits size matter when it comes to replication?
trying not to use int because I don't always get the same state on both server and client.
FGuid would fit my purpose but just wondering if that's "overkill"
12 bits... how often?
Unreal has a lot of effort put into replicating things like asset paths and others once
- once as a giant full buffer of data
- afterwards to the same connection as just a shared ID both map to
you might be able to leverage this and keep your full GUID (FName replication in 5.5 with iris?)
but if you can get away with a smaller int you should feel free to do so... internally unreal makes network IDs as tiny as possible
Well if I can push the limit, probably something like a bullet hell types of game.
The context here, I want to ID projectiles or damage data.
when you send project data... what does the client know about the projectiles?
does it spawn them in the same packet and know about them? how are they replicated?
Client spawn it's own copy and telling the server to spawn its version. This is where the identifier is passed.
A part of me thinks you could get some more clever packets out of this than just having a small ID... but if a small ID works you are golden imo as this is not a ton of data if it's sparodic
for example if the RPC about the projectile knows the total number of projectiles and the possible range it could map to just a few bits of number information
or even use a bitset
So when the server replicate back to client with its projectile, the projectile spawned locally knows which projectile it should interp to
this might get into the weeds about serialization though... the more low level you get the closer you get to a custom protocol lol
I think that it depends on how you send them and how often
like for example do you send their position over time? or just where they appear and when they explode? (or something happens authority wise)
The projectile just move forwards to a target location. So position isn't send over time.
The only thing that I need to replicate is the actor and the ID
the actual positional data will dwarf the ID completely here too fwiw unless quantized heavily (if it's world relative too)
but you can measure that quite quickly
Yeah, I guess at the end of the day I need to learn how to use the profiling tools.
IMO this should be acceptable to try as a first go and if it's too darn slow you can try to get fancier
also net profiler can't see oodle compression if that helps
so you aren't totally seeing the final result if you use oodle net
I think it would be interesting to have a known bitset between each source of projectiles
or something
like for example you send a bitset for X object that has 11101 which represents it having data targetted at 1, 2, 3 ,and 5
of course how do you map that over easily if they didn't know about the others before etc
massively easier to start with a smol id imo
also consider having these in a fast array serializer or something in a single network manager... it might be much less data than splitting the results on a million other rpc targets etc
this loses a lot of granularity in network priotization though I guess
if your game is like inside 1 room at a time it might work fine though
(or you could have one manager per area, which is what Mass replication did in the old version!)
but yeah try the shrimple way first and then see if it's working out
The frustrating thing is I don't really know how to measure unreal capping bandwidth
generally it manifests visually in losing replication rate on typical actor positions though
I want to learn fast array for my inventory but I heard there is a few gotchas.
if you see your cmcs moving once every 3 seconds it might be something else fighting for space
apparently there is some edge case where fast array is not faster than regular array
there are but it's not that tough to deal with in ureality
under what condition should I chose fast array over normal struct?
the only real gotcha is that they cannot be sorted or relied upon ot have stable indices, and you must ALWAYS correctly mark them dirty etc
Fast array's main benefit in the vanilla non-iris setup is that it's delta serialized for sending changes to each element separately
ok I don't have iris enabled, probably not planning to use it
but with Iris regular TArrays can also delta serialize a bit
is that what atomic replication mean?
with Iris it's still much nicer for one reason: it has onrep style callbacks for every array element change
atomic replication means everything showing up in one single packet/frame etc
I see
for example you could have the actor position and the fact they are jumping arrive at random times even though the authority wrote them and sent the properties inside 1 net broadcast
atomicity is just... stuffing your crap in one ustruct lol
this is massively important for fast paced games imo
that's what I've been doing soo far ๐คฃ . Deffinitly need to leverage more tools before I go knee's deep
the tools are a bit sparodic and it's often easier to just add rather than change
for example you can disable parent replication properties and substitute your own but like
it's a bit of a crapshoot whether it's okay to change
also really what I think would be better would be ways to inform the replication backend "hey, always pack these together!" and not allow it to split packets
I appreciate the patient and formative answers
Iris also has way for you to define how it prioritizes actor/object replication based on distance which you can tweak to fit your project more but I'm a bit clueless on them as I haven't needed to make one
which is basically just Iris's version of repgraph in effect
so for example you could prioritize things shooting more etc
In modbus "atomic" is used to describe a guaranteed order of business
Its only used for FC 23 which is a write and a read in a single message. Guarantees thats the writes are processed before the reads are returned
Kinda ot but.. ๐
Generally in cs it means something akin to exclusive access
In some sense it might actually refer to the same exclusivity , and not the order of business as i initially thought
As the modbus slave will finish that single request before it starts on the next one, it is by nature exclusive, or "only one" at the time
Sorta like what reliable is portraied to be , in rpc's
Halting the channel untill the current rpc is acked, guaranteeing order, but slows down operations^^
Getting curious wether unreal packs rpcs together in single packages now ๐ค
If it doesnt, that should give horrible scaling
it depends
it can do both now
giant RPCs can be split (and reformed later in a similar manner to reliables)
regular rpcs are intended to be in one packet and there can be more than 1 in 1 packet
packets are max ~1024bytes I think
this is easier to see in a network profile... generally there can be a mixture of both replication propreties and rpcs in a packet
in Iris RPCs are called attachements internally
if you ever see that
So there shouldnt really be any benefit of combining multiple rpcs that are more or less chained with a single big one
I havnt had such a scenario at all, just hypothizing
Ty for the knowledge share btw. Ill be sure to check this out when i start profiling our network limitations ^^
fwiw as for how this translates to "save bandwidth" it's not really clear
in general unreal kind of abstracts away a lot of packet-related stuff
so I don't have a great idea of how to like... prioritize an rpc over another
replicate them down the same actor channel under a manager
A manager actor that takes rpcs for any other managed actor?
that would let you choose to rate limit each frame I guess
yes, that'd be the easier guarantee, you know the rest. Make that actor high priority and can even turn off replication on the proxies
Pretty clever
Giving you great control without diving deep into the details of packet transfers
yeah I think network managers are a massively good idea to just... remove all of the spaghetti of regular network stuff
yeah.. really handy, never thought of them before for ordering.. just came to my mind... since in the context of the actor, the order is guaranteed
I was thinking about having one giant manager for each ~100m square area or something for almost all replicated state but that introduces some weirdness
in things going between
I think for stationary-ish things it might help but generally those are fine to go with the normal replication prio sceheme
well you cannot guarantee order in between actors, so its all contextual to what you are building
i remember some friends told me they used them for low NUF interactables, but nothing impedes you to use them for something else
also I'm still pretty new to Iris prio/filtering stuff
so it might do something that makes doing this easier
u know more about Iris than me XD
I know a lot about the reading side but the server side is quite unknown to me
the reading part I have crawled over nearly every damn line in the top level object serializer 
all i know from iris are lil bobs of knowledge i gained while digging through commits XD
I could make some docs things that go into it if you want... I can't gaurantee they would be much use over just reading the source though
It's quite hard to follow compared to typical unreal source as it's very very tryhard (raw c arrays, manual allocations... random bit flags all over)
but you are pretty familiar with those afaik
ive read some of it haha. But I believe the community is probably more interested on usability rather than low level
yes I think the good news is it's 90% identical at the gameplay code level
which is... kind of surprising
you don't really need to "learn iris" as much as just know some weird things to work around in most cases
They still haven't fixed the FieldOfviewNetObjectPrioritizer.. what?
Maybe on latest
yeah... it's pretty active dev right now
It might seriously be worth a patch if it changed
Ah yeah they fixed it on main
5.5. not
rip
VectorRegister DistSqrToConeCenterAxis0 = VectorSubtract(Positions[ObjIt + 0], VectorMultiply(ConeDist0, ViewDir));
VectorRegister DistSqrToConeCenterAxis1 = VectorSubtract(Positions[ObjIt + 1], VectorMultiply(ConeDist1, ViewDir));
VectorRegister DistSqrToConeCenterAxis2 = VectorSubtract(Positions[ObjIt + 2], VectorMultiply(ConeDist2, ViewDir));
VectorRegister DistSqrToConeCenterAxis3 = VectorSubtract(Positions[ObjIt + 3], VectorMultiply(ConeDist3, ViewDir));
of course it's raw vector registers lol
They always do 4 objects at a time
Took me a bit to understand it
The problem is the VectorMultiply
Or rather the lack of a VectorAdd
This calculates the distance between the Cone Center and the Objects
But the Cone Center is just Direction * Distance
Which is wrong
sounds like a nice patch to me?
It is patched
hopefully just that
// Simplified VectorSubtract(Positions[ObjIt + N], VectorMultiplyAdd(ConeDistN, ViewDir, ViewPos)) to VectorMultiplyAdd(ConeDistN, -ViewDir, ObjectDirN)
VectorRegister DistSqrToConeCenterAxis0 = VectorMultiplyAdd(ConeDist0, ReverseViewDir, ObjectDir0);
VectorRegister DistSqrToConeCenterAxis1 = VectorMultiplyAdd(ConeDist1, ReverseViewDir, ObjectDir1);
VectorRegister DistSqrToConeCenterAxis2 = VectorMultiplyAdd(ConeDist2, ReverseViewDir, ObjectDir2);
VectorRegister DistSqrToConeCenterAxis3 = VectorMultiplyAdd(ConeDist3, ReverseViewDir, ObjectDir3);
It was a client project that we implemented Iris on
that seems like a good candidate for a hotfix but Epic probably isn't concerned with crazies like us using Iris yet
Trust me, that is the smallest of the "patches"
ah
Well, Fortnite only recently got their First Person Mode
Sooooo
Idk how that went through into Fortnite otherwise
what's this?
some sort of frustrum based prioritization system?
ah i see, nice :)
But they had a small error where the distance between the object and the cone center was lacking the cone start
unreal sends the point of view constantly so they should be aware of it even during non-playing
And thus was calculating the distance to a slightly offset 0,0,0 location
GetViewPoint etc probably
Which means it didn't matter where you stand
Yeah the whole thing is a level deeper
void UFieldOfViewNetObjectPrioritizer::PrioritizeBatch(FBatchParams& BatchParams)
{
IRIS_PROFILER_SCOPE(UFieldOfViewNetObjectPrioritizer_PrioritizeBatch);
TArray<VectorRegister, TInlineAllocator<16>> ViewPositions;
TArray<VectorRegister, TInlineAllocator<16>> ViewDirs;
for (const UE::Net::FReplicationView::FView& View : BatchParams.View.Views)
{
const FVector& ViewPos = View.Pos;
const FVector& ViewDir = View.Dir;
ViewPositions.Add(VectorLoadFloat3_W0(&ViewPos));
ViewDirs.Add(VectorLoadFloat3_W0(&ViewDir));
}
const VectorRegister* Positions = BatchParams.Positions;
float* Priorities = BatchParams.Priorities;
const int ViewCount = BatchParams.View.Views.Num();
for (uint32 ObjIt = 0, ObjEndIt = BatchParams.ObjectCount; ObjIt < ObjEndIt; ObjIt += 4)
{
VectorRegister Priorities0123 = VectorMax(VectorLoadAligned(Priorities + ObjIt), BatchParams.PriorityCalculationConstants.OutsidePriority);
// As the cone and line of sight capsule are view direction dependent there's not a lot we can do to optimize multi-view calculations.
for (int ViewIt = 0, ViewEndIt = ViewCount; ViewIt < ViewEndIt; ++ViewIt)
{
const VectorRegister ViewPos = ViewPositions[ViewIt];
const VectorRegister ViewDir = ViewDirs[ViewIt];
const VectorRegister ReverseViewDir = VectorNegate(ViewDir);
It def looks more performant than whatever we have without Iris
But it also showed very clearly that it's not production ready for the every day user
Sure if you don't use that FOV Prio, you would be fine in that case
But yeah....
I mean in this case you might be able to copy it out
Iris is designed to make your own classes for those
but it might not work welll yet... you are probably familiar with not-exported classes lol
Well with every day user I mean the ones that turn it on to get performance boosts
Not bugs
oh yeah... definitely not a drop in yet
I think the most bone-simple projects might get away with it
Yeah, I mean, I get it, don't export the whole damn class fwiw
but eventually an onrep will happen in some funny never-before-possible order
But that's also mainly cause they have Core etc. exposign too much
Module / Plugin based engine that has a way too big Core module
Imagine the amount of changes one could add if every single bit of the Engine would have been designed to follow an extandable plugin layout
Dreams be dreams
The last 10 years of me wanting to development multiplayer games as I enjoy playing with friends more than playing alone have kinda made me want to develop singleplayer and couch coop games :D
Man 10 years. wtf
Hey, Cedric is derailing #cpp .. ehh #multiplayer again.
I didn't want to nuke your Iris discussions, please go on @nova wasp @pallid mesa
this is what Godot servers (render servers etc) are supposed to do
I wish...
no lol exi ur fine XD
i was going to suggest to focus third party article efforts on some usability advices like filters... or custom replication bridges and why they can be useful. Now with Iris streaming big quantities of data is simpler, or even creating more complex pattern through non-actor channel replication strategies, which is something now supported and quite nice :)
One massive thing I think nobody knows about is net groups
but thats pretty advanced and very finnicky imo
Why does it have to be, i think all these concepts need to be exposed and provided with some use case examples and hello worlds for other engineers to grasp on
oh 100% I just mean that it's going to have to have a lot of technical "don't ever do this or it will explode" style information
I'm not trying to say it's not worth making... just not going to be 3 paragraphs and 1 code snippet
but probably fairly long
well yeah typical tribal knowledge, such as the good ol - "dont use CACs on x and y"
that's one of my most religious UE opinions lol
I think for anything not-serialized they are... probably going to be fine
I think people sometimes assume we are referring to ANY actor attachement
actor attachement works great... just the CAC is very complicated
explaining why not using them is quite complicated for everyone and i guess you could get into explaining it, but it probably wont interest the masses to get things done rapidly. My main suggestion is to expose on plain and simple and write on subsections for those who wanna dig
yeah, we aren't making youtube tutorials here for sure
those are highly useful, met already many peeps that prefer it over simple articles, also the other way around, the problem with yt is that there's no place to dig. Long videos can be hard to follow unless very specific to a topic
Yeah I wonder if the golden "middle ground" is a brief youtuber overview to catch interest
and then share more in-depth info in the article
along with code etc
Do you guys know any projects that only contain ground work for multiplayer? Like kind of a base for more complex games?
Hello, im pretty new to the cmc for multiplayer but starting to get the hand of it.
But I have a question in many cases I will need to link the GAS and the CMC. To for example link stamina and sprinting.
Another thing, is that I have a parent character class which works with the cmc. However, certain child character classes might change their way of movement when they charge their ultimate and activate. Would this mean that I should make a child cmc for each character that will change their movement? Or how would that work?
And I am asking about linking the GAS and the CMC, because I read a conversation in this channel from some time ago. And it was said that the only way to link them (with prediction working) is using GE. However, it was also said that it is still simpler to just use stamina and and sprinting in on or the other (GAS or CMC) since linking both would imply more work on the interanl code of unreal and how the systems work? (I didnt understand fully) But that was a while ago so I dont know if things have changed
But as you can see in my game, some abilities for certain character will change movement on some characters. So I would think that it would be better to know to how properly use them together with prediction.
Can someone give me some guidance on these topics?
Have you got sprinting work already?
Stamina + sprinting without cmc yes. Sprinting along on the cmc yes
movement should be handled by CMC.
GAS can "activate" an ability to sprint but I would say in a sense it;'s no different than toggling the boolean using your keyboard or controller.
By working I mean, do you follow CMC framework by toggling the bits in FSaved move and test with delay?
Yes
Hi, I'm trying to access all PlayerStates from my GameState
How should I accomplish this? The GetPlayerState(0) node doesn't seem to work
https://github.com/tranek/GASDocumentation
You can see here how sprint is implemented
Ty I will take a look