#udon-networking
1 messages · Page 24 of 1
can atkCards be changed? by the attacking player?
no no values at all can be changed by anyone except for the owner. all players in the game except for the owner get read only for all values in the game
all a remote client can do is pass paramaters to the owner and then the owner makes the actual changes
and then those changes are progogated back to everyone else
so serilizations basicly dont occur until after we have done somthing in response to a network event we received.
and for some functions we dont need to send paramas at all just tell the owner to run somthing
Im probubly going to bench this one for awhile and focus on other bugs until I can get some more testers that live far enough from me
it was a one off occurance?
it only happened in a single testing seesion yesterday. but it happened 10 games in a row.
but stopped happening as soon as that player was not in the game. (they where still in the instance just not playing)
it did not matter if that player was the owenr or just a remote player as long as they were in the game. it happened to anyone who was a defender and a non owner
we tried several games where I was the owner and several games while he was the owenr
sounds like ownership transfer issue...
it didint happen with every single move.
theres also another bug that happened slightly differantly but I havent talked about it yet here beacuse I felt talking about two bugs at once would be too confusing but it is similar in nature.
maybe I should include it though there is also another bug where it seems as if the defender does not send the request at all
ownership never transfers after the game starts
you think ownership transfered but as long as he is in game, he is still owner
i mean that sounds like what is happening
if that was the case the bug should still continue to happen while he is in the instance but not playing
the fact when he stops playing the bug goes away means ownership transfer is working beacuse its transfered away from him to another player
also theres a ton of logs confirming who the owners of stuff are that all check out
but we never got to test with 3 players at once including him
i have an idea that with 3 players there will be exactly one player who wont cause the bug but its just a theory needs to be tested
I think it has somthing to do specificly with the transit of packets between our end points
is vrchat even supported on linux? maybe something broke on linux
I dont know thats why I included it as a detail but I know he dosint have issues playing other udon powered games
so theres definitly somthing wrong ive done somewhere
just keep back tracing atkCards
forget about what you believe to be true, and just look at the codes
getting allot of region related issues.
so Ive got a set of bugs that only happen when russain testers try.
and another set that only happens when austrailains test.
its so confusing
some things on c# are culture specific
and all of these bugs litteraly cant reproduce with na players. ive tried 5 hours in a row with none of them occuring XD. but my russain players are getting some constantly
time specific is an intresting idea
maybe
its worth looking into at least
and didint think of it
my code never evaluates time in a network context tho
oh so you do have timers
there is one networked timer but it works correctly 100% of the time for all players
when you pickup cards it starts a 5 seccond timer to allow other players to play any final moves before the next cycle
but that only runs on a totaly differant function and is never the one to break
that timer dosint even run in the cases where we hit bugs
we have some client side timers that look at the last attempted input to prevent spam but thats all totaly local
what time do you use? a local time or Time.realtimeSinceStartup or soemthing else?
for the spam prevention we just store time.time
and for the networked timer we just start it at 5 and count down
owner does it
so if someone attacks before the 5 second is up, they can get the owner to change atkCards?
yes
but thats only if the defender chose to initate the pickup timer
and in all the bug tests where we got the bug to happen the pickup timer was in active
i think this is the point where you set your instance to europe to simulate being a russian connecting to american server, and then spam attack
for testing
to collect more data
oh and the russains have a totaly differant bug where they get straight up script crashes
some of them are playing right now so I might go see if I can farm some more logs
i think rider IDE can warn you about culture specific things
yea in all my dev expeeriance I cant say ive ever seen anythign quite like this
this can get interesting if you are parsing strings into floats
nah only bytes ints and bools
just got the first instance of the bug with a russain player
some new data is its confirmed that the statment at line 30 of the deeper function is the specific statment causing the false return
is playerContainer a playerobject?
this line?
yes i added extra logs currently trying to hit the bug again
if defSelectedSlot is an udonsynced variable, it won't necessarily have the same value for the sending player vs receiving player if the receiver hasn't gotten a deserialize on the object before the event call
if it's not an udonsynced variable then i don't know
shit your right that might just be it
ill look into that
I overlooked this beacuse target is explicitly passed as a network paramater but I forgot that this function does not take that as an argument but does that internaly so if I re write that to be a manditory paramater I can fix this in theory if that is actualy what the issue is
the only way to confirm if its fixed would be to just play for long enough with no occurances of the bug id probubly need at least 10 collective hours to be sure
still wounder why having nearly 1000 ping wouldint cause it to happen though
i don't know the intent of the game/code well enough, but if it's a slot that you select and remains the same for a while, there are a lot of cases where it wouldn't cause any issues. personally i'd expect the event to arrive ahead of deserialize more often than not if it was changed at the same time as an event call
its not realy a race between the two beacuse the event allways gets fired first. and the deserialize only starts in response to the event ariving. but in any case I just made several changes to the code.
and theres a good posibility this bug is gone now
thanks largley to your comment so now its just a matter of playing the game a ton and seeing
if not there are also additional logs that will paint more of a picture if it happens again
i don't mean the owner responding to the event with a serialize, just that the owner relies on defSelectedSlot being deserialized with the same state that the calling player had when they validated
yea I think that might be an issue. I thik def selected slot was the bad data
its the only thing that can be now that I know what I know
but yea ive re written the function so that it directly takes a target as an input
so now instead of using def selected slot it will directly take in whatever the network event passes
and other older sections of the code can still pass in that slot isntead where needed
lol yah, when you first posted your hard and saw that early return, it gave me the big suspicious
yea was definitly a huge over sight on my part
Yah I saw that being an early return and also saw none of your logging was making sure your player value was as expected
too soon to celebrate we could still be totaly wrong about it but its currently most likely to be fixed
and if it is Ive got another big bug to fix heh
in my experience, this fix will reveal another, different issue
the pain with my other bug is I know how to reproduce it but you need to calculate the moves carfuly to hit the condition that would break the game
its not so bad of a bug tho you basicly need all players in the lobby activly trying to make it happen but there is a low chance people do it by accident
I might post that one here later if I havent fixed it by sunday XD
any of you free to playtest preferably people in europe or austrailia?
in hind site that seems to be what happened issue has not happened scince but ive found several new script crashes that ive fixed as I found them
@fallow mountain @misty ermine apparently other worlds have the same object syncing issue too now, this is from a normal Just B Club Lobby
oh, this bug is now the top canny post...
whats a canny post
nickname of a the bug report site https://vrchat.canny.io/bug-reports
canny is name of the feedback platform
ahh gotcha
Yah I'm going to presume it affects every single object using VRCObjectSync in the game
and because it can build up suffering, I can imagine it breaking everything else in the instance if given enougth time
very curious how many bps that object is sending to build up suffering
it my experience, my upload actually dropped to almost nothing as suffering increased
interesting, so it is limited at object level, i assumed it uses continuous sync internally so it should never suffer... maybe they forgot to set the sync mode
but then manual sync would not limit itself at object level, so there is some internal logic for vrc object syncs...
continuous sync can cause and encounter suffering
i thought continuous means it would drop packets and interpolate when needed, to save bandwidth
therefore wouldnt cause suffering on its own
it'll try, but only to a limit
hmm i wonder if what is the limit, maybe it is a certain Hz?
and at least VRCObjectSync, it would cause suffering before dropping below 4hz
this was previous to it getting broken, to clarify
btw i saw a world comparing vrc object sync to two other custom made object sync scripts, both from booth.pm, but it required a second player so i couldnt see the effect
would be interesting to see how it compares with the bug
with the bug affecting vrc object sync
and potentially a fix, by using a non-vrc object sync script, if you need to fix it before the dev fixes it
oh the world is called... <some japanese words> Synchronous system validation
From everything I've gathered, I don't think my project could work with anything but VRCObjectSync due to it not having the extra networking cost that manual sync supposedly has, and due to needing it's ability to sleep itself
im in that world now looking at those demo again, it seems at least one of them has sleeping builtin
I wasn't aware we had access to that feature; I just assumed all custom made object syncs used manual sync
oh yes it says it uses manual sync...
isn't not manually syncing same as sleeping?
i mean not requesting serialization
"sleeping" is the ability for VRCObjectSync to stop synching despite being a continuous sync
https://github.com/MMMaellon/SmartObjectSync the one i was referring to
yah I know of that one
you can make your own logic to stop sending manual if there's no delta or if it's not near players or if a rigidbody is sleeping or whatever really, it's not like a special feature locked behind vrc. they happen to stop sends on vrc's vanilla sync if a rigidbody is sleeping
what if its caused by what they are saying in network details with "Prioritization of visible objects
Udon's networking prioritizes synchronized game objects that are currently visible to the local user.
Udon periodically checks the visibility of all mesh renderer children of synchronized objects. This is used in the quality of service behaviour of Udon's network load balancing."
Yea i was asking about that a month ago I would realy like more details on how that works
Particularly with synced vars that live on an object that has no visible mesh
Contiuous sync can and will cause suffering entirely on its own if you have enough of them :)
VRCObjectSync uses Continuous.
I would like to remind you of your previous statement:
#world-persistence message
I feel we should leave network balancing to vrchat, ... if vrchat updates in the future and have better balancing, the manual balancing might need to be retuned therefore not future proof
In light of recent events it should be obvious how silly this opinion is.
Continuous sync is a black box that can change at any time. This is not good, and it should therefore be avoided whenever possible.
Not only that, but the current behavior of Continuous sync isn't even remotely favorable.
The idea that continuous sync being a black box is somehow good requires pretty wild mental gymnastics.
So other than doing pickup and transform syncing, roll your own updates with manual?
If you're making a chill world with plushies you can pick up you should use VRCObjectSync (which is Continuous sync) on those pickups.
If you're making pretty much anything else (a vehicle for example) then yes, you should absolutely be rolling your own object sync with Manual.
Oh boy, do I have some stuff to rewrite
If you share the specifics of what those are I can provide more curated advice.
Picked up a gokart prefab (kurotori udon kart) and I've been changing it slowly to be less network intensive. A lot of the udon interactables, wheels, ect. were set as continuous, but I've trimmed it back to only the main kart body is continuous for transform purposes
Oh, yeah, this is a perfect example of where you should be using Manual sync.
Continuous has a lot of event buffering built-in which means the data in practice takes 10x longer to arrive than with Manual sync.
This is very bad for vehicles.
just because a bug can happen doesnt mean you should stop using continuous sync and use manual for everything, that would be silly
Both me and Occala have created several of our own object sync implementations using both continuous and manual sync.
We've not only been testing this stuff for a long time, we also help VRChat with private beta testing.
When we tell you you're wrong about something sync-related your alarm bells should be going off.
Instead you somehow manage to disagree, without providing any form of evidence, based purely on your opinion of what Continuous sync should be.
This is what I call silly behavior.
so what is continuous for? in your opinion
Those pickup plushies you see in cozy worlds.
why not use vrc object sync?
VRCObjectSync uses the continuous sync mode, as I understand it.
VRC Object Sync uses Continuous.
It's convenient because you don't have to think about the sync at all -- it just runs forever (even when it is not necessary)
Most of object sync's behavior is implemented directly in Continuous sync.
I've been moving my settings system over to manual sync after noticing that every single setting is getting updated several times per second
each float was eating 80 bytes per second (20 bytes per sync at 4Hz)
yummy
(i am unclear how that turned into 20 bytes)
i guess there's some extra overhead for the UdonSharpBehaviour itself
When you put an Udon script with Continuous sync on a GameObject with a rigidbody on it that script will stop syncing if the rigidbody falls asleep. Even if that's not what you want.
oh that's scary
If replacing objectSync/continuous, is there a prefered update rate? updates per second, a certain amount of frames? I assume doing like sendNetworkEventPerSecond(0.1f) is fine?
If you put an Udon script on Continuous directly on a GameObject with the pickup component it will increase the sync rate a lot when picked up by a player. Afaicr it does this even if you don't have Object Sync on that object.
Depends what you need, for vehicles you can afford 10 hz imo.
(While you're driving the vehicle)
Which I think would be .1f
typically you'd define a sync rate, something like 8hz might be acceptable for a kart starting out (0.125f), 10hz is also a good suggestion
usually you'd run an elapsed timer in update; branching based on owner/not owner (the owner should run the elapsed timer and send if applicable, remote players run interpolation logic)
you'd typically also early return on the owner's branch if not seated, which stops unnecessary sends
public float syncRate = 0.125f;
void Update()
{
if (isOwner)
{
if (!seated) return;
syncTime += Time.deltaTime;
if (syncTime >= syncRate)
DoSerializeStuff();
}
else RemoteInterpolation();
}
void RemoteInterpolation()
{
transform.position = Vector3.Lerp(transform.position, syncedPos, 10 * Time.deltaTime);
}
the interpolation here is extremely basic, you can record the previous instead upon packet receipt for better quality or look into other interpolation
why not use continuous for the vehicle movement? it has built-in interpolation
continuous is buffered extremely far in the past typically, like multiple times more than manual, it's low send rate as well and the interpolation quality is poor compared to many types of interpolation you can run yourself
it sounds like it works, but has behaviors that are annoying (and not accessible to you)
hence it making sense for random props that you don't need a specific behavior for
my opinion is that you should prefer manual unless you have to use continuous
waggling my finger at the framerate-dependent lerp 😉
I'll probably have to do some things with the rigidbody too. I imagine the lerping won't like physics happening
i typically record previous position and constant lerp based on an elapsed since packet receipt in what i'd consider normal lerp
Found a good example of what seems to be continuous sync issues from the VRDC server
https://cdn.discordapp.com/attachments/1354538220662165746/1380331283984547930/vlc-record-2025-06-05-19h07m59s-Replay_2025-06-05_19-03-26.mp4-.mp4?ex=684425ef&is=6842d46f&hm=c54c872292d699de3796b0a67aef9c206477f49d43f39ceb6e2ec64315b2ab05&
https://unity.huh.how/lerp/wrong-lerp explains the issue
I hate Discord video, it's so long to buffer
Works fine for me, might be because I watched it earlier tho
void RemoteInterpolation()
{
timeSincePacket += Time.deltaTime;
normalizedElapsed = timeSincePacket / (syncRate * 1.5f);
transform.position = Vector3.Lerp(previousPos, syncedPos, normalizedElapsed);
}
this resembles what i'd normally do for basic interpolation, but for vehicles or something beyond a pickup it's better to record a buffer of snapshots, there's a good video on the poor version i wrote
https://youtu.be/yGhfUcPjXuE?si=JOIb7YBLzPHsjPlR&t=1069
DeltaTime. This video is all about that mysterious variable that oh so many game developers seem to struggle with. How to use DeltaTime correclty? I got the answers and hope this video will help to deepen your understanding about how to make frame rate independent video games.
0:00 - Intro
0:34 - Creating The Illusion of Motion
1:11 - Simple Li...
Oh yeah, that sounds even better
explicitly using the previous position (or positions)
here's a good example of why you wouldn't want continuous/vrc object sync compared to a manual approach
Hermite spline snapshot interpolation on a circular buffer is nice for when you need to accurately reconstruct the exact path the object took.
If you're attempting to sync someting closer to real-time (fighter jets for example) you'll want to look into ping compensation and extrapolation techniques.
This is what I'm using for my space ships in Far Citizen.
For the player sync in Far Citizen I'm using linear interpolation on a circular buffer.
Someone will correct this idea if it's wrong, but for anyone that finds this whole thing, I suppose the reason continuous and object sync exist is that is a good-enough solution for people that want to make worlds and don't care about being 100% optimized, or learning the details of Udon/Graph
It's not the greatest, but it does what it's supposed to do, and it takes like 2 seconds to ad
object sync is totally fine for casual use, i'd encourage using it
ok that is smooth, is this a certain Hz with interpolation? is this UdonSharp.UdonSyncMode Linear interpolation or Smooth interpolation? or a custom interpolation?
using continuous for variables or something you actually care about being synced relatively well is less ideal
i believe i was running the left ball at 10hz here
i guess i should clarify it's not udon sync's interpolation, it's being run on manual with my own interpolation
correct
it's not going to burn your house down; it's just not good to rely on if you need something more than "the object probably winds up in the right spot pretty quickly"
for some definition of "pretty quickly" 😉
Ok there is some convergent evolution happening... I like what I see with the 10 Hz manual sync, but i worry about my network usage... maybe i should add some throttling logic to drop packets and rely on interpolation, because otherwise my network is going to suffer more and more...
Meanwhile vrchat dev probably should up the frequency on continuous to a similar Hz if network condition allows... I mean there is no real reason to keep it low is there?
I mean I agree what you guys are saying, I am just speculating here
if you blast updates at 10hz on manual yeah you can net suffer/clog, you typically preface sends with the idea that you can gate them. with pickups you'd do that based on the held state and/or sleeping rigidbody, with a vehicle you don't need to send if it's not manned or literally stationary, if you naively continuously send over network in the same way as continuous yeah you'll encounter issues
like take my ball example, it's a default material sphere. i could drop rotation from the sends entirely and it would make no difference. i could run it at 8hz for less bandwidth than continuous is using at 4hz because i know the nature of the object. the gap between 4hz and 8hz is pretty large, it's 125ms. you can shave that time from the interpolation delay/buffering entirely
I feel like "continuous" should be renamed to "automatic", vs "manual"
continuous is a pretty apt name in that it continuously sends updates
but relative to manual, automatic is a decent way to think of it
this is a cool site
it's very handy
one of the regulars on the official Unity discord maintains it
i almost exclusively use it to help people with physics problems
but it has a lot of content
its page about bitmasks is great
i'm seeing 54 bytes per send for a single float on continuous and 50 on manual
the debug menu (shift ~ 6) will actually display something like half if you reference the size value, though the Bps value seems correct
i'm using the new network stat to display it atm
VRC.SDK3.Network.Stats.TotalBytes(gameObject)
and here's the manual version at a similar rate (0.22f)
I was seeing 20B for each of my FloatValue behaviours
I did notice that the Bps value seemed high
My network usage was idling at like 6KB/s
yum
or was it 6Kb/s
probably the latter. i love Bytes and bits being so similar
It's already down to half after getting the float values off of continuous sync
it's KBytes
that gets significant pretty quickly
i think vrc mostly refers to things in bytes rather than bits in networking
KB does vrchat mean 1000 Bytes or 1024 Bytes?😓
Everything we interact with in Udon could be described as a black box, right?
Manual sync is also a black box, the details of how it works can only be guessed upon by external observations of how it works
sure, but it has fewer quirks :p
Also for position sync stuff where cost isn't an issue, I strongly suspect that network events with parameters is the ideal solution. That's what I use for my player position sync. While my network heavy stuff is handled by VRCObjectSync
Yes NEP can go up 100 Hz in theory (tested 60 Hz) so I also suspect the same
The only thing is you need a synced variable to go with it, for late joiners
And how the two streams merge is kinda tricky
manual sync can go ~15 Hz at best
A big thing with events is that it forces high priority updates on the receiving end. This is very useful for player position in my world because I need very up-to-date position of players including those far away and unseen.
Actually if it is always constantly sending, arguably you don't need a persistent variable for late joiners, they will just start receiving the latest data straight away
Just the bandwidth cost is probably big
That's why it is the only kind of that sync for each player
hmmm is your world published? i havn't seen NEP in action in the wild yet
is that short for network events with parameters?
yesh (too lazy to type)
Am I allowed to post a link to my world here? The version uploaded is a bit outdated but it does contain a debug capsule that shows on other players and represents the event sync in action
Note it doesn't use any lerp or anything like that because it's an invisible, background thing
oh i realized i need more than one person
lol, yah
Direct example of this. The blue transparent car is the position and rotation from OnDeserialization
cool visualization!
it has to mean 1024. its not possible to not mean that.
after the update with Parameters in sendcustom. it seems to max out 8-9 kb/s and then it struggles
well, anything is possible with vrchat, you never know (i dont know either)
well if its not 1024 they are doing something reallly bad lol.
considering thats what a kb is
Well, a kilobyte by some definitions is 1000, not 1024, it's ambiguous. A kibibyte refers to 1024
.....but this is just nerd crap and usually when you're talking about memory, a kilobyte is 1024
the k in kb stands for "kinda" 😄
ok yeah it is probably 1024... also because it is a capital K...
the inconsistency in using k instead of K for kilo annoys me.
You don't "need" a synced variable for late joiners. It's perfectly viable to handle late joiner sync yourself with network events.
Claiming that you have to do it with a synced variable is misleading.
at least according to wikipedia (and all the top results), a kibibyte is written as KiB https://simple.wikipedia.org/wiki/Kibibyte
So if it is written as KB it most probably represents a kilobyte which is 1000 bytes
A kibibyte (KiB) is a unit of information or computer storage. A kibibyte is 1024 bytes, 1024 kibibytes are a mebibyte.
1 KiB = 210 bytes = 1,024 bytes
Lots of people aren't as pedantic as using KiB requires though, so you'll find different meanings, unfortunately.
I don't know why you'd presume VRC means kibibyte instead of kilobytes; it'd make more sense to presume the opposite, correct?
in speaking of networking I'd always assume kibibytes unless told otherwise
Networking in Udon can be challenging! Try to keep things simple until you're more experienced.
hmm I wonder when kibibytes came into popular use
oh - they say it clearly, then yeah, go with that. And if they actually mean kibibytes instead.... well....
the wikipedia page for kilobyte clarifies the ambiguity better
In some areas of information technology, particularly in reference to random-access memory capacity, kilobyte instead often refers to 1024 bytes.
if you're talking about memory, a kilobyte is usually 1024 bytes
anything where the exact number of bytes matters I usually just write out the actual number of bytes, avoiding KB/KiB confusion entirely. I usually only state numbers in KB if it's flexible and the precise number doesn't matter, such as bandwidth limits
Yeah it's "good enough" there
why did we programmers do this to ourselves?
so by KB they mean kilobyte, not kibibyte; but by kilobyte they mean kibibyte, not kilobyte
haha yeah
I remember kibibyte not being a thing when I started my career, but I don't recall when it showed up. or maybe just got "accepted" into use
kilo is a 1000 only in marketing heads. or maaaaybe in some irl things like a ton or a kilometer. but def nothing usefull is using 1000, always 1024
google also converts kb as 1000 bytes
Yep, that is generally my assumption
@north thistle it also tells you that moderate amount of poison is good for you. kilo is 1000, but in computing world its 1024, unless youre marketer to sell you 1tb drive (1000000000000 bytes ie 931 actual gb)
in case anyone was actually curious, these values update in tandem
VRC.SDK3.Network.Stats.BytesOutAverage
2044 is approximately 2.00KB/s
is "b" a bit or a byte?
so i'd assume 1024
B means byte, b means bit
So Ive been doing some more testing regarding the monsters and suffering in my game, Despite killing all the monsters and returning them to their object pools, they still take up resources and add to the throughput while theyre inactive... The only way to get them to stop is to entirely destroy the monster object pool which isnt ideal...
are you using continuous sync?
also you should be displaying queued events as well as that can contribute to suffering as well
Oh? what would be the nodes to use to display that?
Network events allow simple one-way network communication between your scripts. When a script executes a network event, it executes the event once for the target players currently in the instance.
The monsters are all using manual sync
I wonder, will a manual sync on a disabled object still be able to trigger a network event if it calls RequestSerialization?
I deleted all the request serialization nodes from the monsters AI
I think disabled objects will stop all their components running, so no it shouldn't generate new traffic nor request serialization
however if there was something serialized prior and is queued, i believe that would still be in the queue
scripts on disabled objects can still run, right? It only disables Update
Even waiting a while after returning the monsters to their object pools it still builds up, the longest a monster should enumerate an AI tick should be about 5 seconds
i don't think disabling the object or component halts networking, it looks like you're still calling events somewhere
I added a queued events log to the debug now
Ive narrowd it down to the spawning and then killing of monsters
Even just having the monsters running around chasing a fake player not in a live game it builds up when theres too many monsters (understandable) but removing them back to object pool they still act like theyre around doing stuff
if you're using something akin to a default pool, ie they start disabled, networking probably doesn't start on the object until they've been activated
Yeah thats correct
but it can continue if they're set inactive beyond that
Yeah is there not a way to shut them up so to say once theyre back in pool?
you'd want to gate the send logic itself
What do you mean by that?
branch the logic so you don't send if it's not active, if that's the intent
Interesting suggestion, so if an udon can still tick over when the object is disabled...
So once the enemy spawns on enable it starts the AI tick
like scripts can still be called and interact with things when the object/component is disabled, mostly they won't call update methods
reaches the end once everything is done then repeats the cycle
i'd be somewhat surprised if delayedseconds was able to call through the object being disabled, but i don't know for sure; this is at the end of the logic where you send network events?
Yeah
i will say that in my experience delayed events remained and didn't call when the object was set to inactive, resuming when it was set active again. if you start another loop in onenable that's concerning in a different way. i haven't tested that recently and i'm on my phone right now
it's hard to say without full context, but it would seem that something is calling events in your code
Il modify the code of one monster and see what happens when I do your suggested gate of checking if the object is active
I think this is the correct node to use in this case
Was expecting a "get active"
Just did a test, apparently an initially disabled game object (from editor) can still send delayed events and NEP and serialize in-game, but SetActive to false (which shouldn't do anything) will stop serializing, but won't stop NEP and events.
strange
I think delayed events are stored within the memory of the recipient object?
I sent delayed events to within the same script, so idk
Come to think of it, why did my disabled gameobject (from editor) even run Start()?
Cos my loops starts from Start()
This whole thing about disabled gameobjects triggering stuff needs to be documented in a wiki somewhere...
I wonder if variables can change internally in a disabled object by itself
Like my AI cycles count from 0 to 40 (When it reaches certain numbers it does special attacks)
yes in my case, the object was disabled, but the udon component was on
you tested it in a real build?
? i did a build and test with 2 windows
yeah, it's just i wouldn't expect it to work the same way in client sim
build and test is fine
is this a bug? Start() running at start even if the game object is deactivated in editor?
is the parent object you're checking the thing you're pooling/gets set inactive directly?
Yeah
Also the queue count on my debugger is always saying 0
Gunna try unplugging my fixed updates and see if thats causing the buildup
Probably not
So I spawn 40 enemies into the scene it barely hangs on which is pretty nice, When I kill them though it builds up
So essentially killing them and returning to pool makes it worse...
I just had an idea... I wonder if this will work (Attaching this script to a parent object that the dastardly script has anyways so itl work well if it... works)
Didnt work...
Ah Im out of ideas, Im gunna consider this a bug with the SDK at this point :L Really dont wanna have to give up this project for some stupid thing like this
you should probably have your enemy code work like a state machine
is this showing NetworkCalling.GetAllQueuedEvents?
as opposed to the one that takes a specific behaviour/event
This
A state machine... Like the animator controllers?
the unity animator controller is a state machine, yes
Not quite sure how to interpet that for a graph code
it's polling the event queue of one of the agents?
that's also not a network event unless that wasn't in response to me, you should try GetAllQueuedEvents for the debug text you're displaying
In general I would strongly advise for any object with a networked behavior on it, to keep it active from scene start to scene end; toggling the active state of a networked object results in a lot of bizarre, semi-invisible behavior.
There's other ways you can "disable" an object if you need it
interesting, only problem is that pools disable objects by default
VRC Object Pool will, but you can make poolers behave however you want
@silver hill its not an issue in case of pools since theyre synced themselves. tho you do want to have a delay between enabling an object and applying some properties to it.
it's that delay that will really mess with you
how long the delay will be can vary based off networking conditions and otherwise working code will suddenly break under load
that's actually the cause of what it sounds like you're describing the necessity of delays for, if they haven't started once properly in udon they won't receive ondeserialization. they will if they have started previously; vrc's pool starts them inactive
@north thistle thats why you make it eventually synced and recheck. i mean, the alternative is 200 always enabled pickups.
even if you manually activate and then deactivate them, they still have weird behavior for an indeterminate amount of time upon being activated again
what's wrong with them being always enabled? If you don't want people to pick it up, disable the ability for them to be picked up. If you don't want them to be seen, disable the renderer. Etc
With that said, if the objects you're enabling/disabling are pretty simple objects with little to no code attached to them it should be fine.
But if you're trying to do something more complex, the added complexity and indeterminate behavior of freshly enabled networked behaviors is just not worth it.
@north thistle its 200 vrcsync objects which is kinda the limit, at least without smart sync prefabs, so why would you intentionaly stress networking when you need only 10 now and 200 is just a limit
My project has almost 400 networked objects that are always enabled. Technically almost 800. And it works fine.
vrcsync ones?
But they're not performing any networking when they're invisible off at 0,0,0
can you describe what happens to freshly enabled behaviours? owner side presumably? i haven't tested disabled objects extensively, but if it exhibits specific behaviour i'd be curious
VRCObjectSync will automatically stop synching when it hasn't moved for a short period of time
Last annoying behavior that finally made me give up on disabling/enabling stuff is that if you enable a VRCObjectSync object, claim ownership of it, and then try to move it somewhere, it will acknowledge your ownership but then ignore it when it receives the last position sync stored on the relay server, moving the object to wherever that position is
This also captures the biggest issue with player scripts using Continuous sync despite it on paper having some uses: we, as far as I know, don't have access to the sleeping functionality of VRCObjectSync and the only other way to pause networking on a continuous is via disabling it.
i observed the sad object sync thing while testing it, seemed like it could be a 1 frame issue. decided to make a manual version of an object sample, using the gameobject active state in this case for the pool above them
400 ? i hope you mean all manual?
So... with all that said what would you guys suggest I do to try and resolve this issue with suffering?
Are they being stored in a pool? if so, how are they always enabled?
find a way to send less data, you can tweak your code to micromanage the throughput, but no micromanagement can fix bad architecture, so potentially going back to drawing board and use a whole different strategy for moving your NPCs and/or gameplay design and make NPCs more deterministic or predictable so they require way less networking
from your debug menu it seems each of your NPCs is sending 260 Bps... do you need it to be this much? or can you just send 1 byte to update its current "target" to chase after and let everything else run locally? Plus another byte for it's current "state"? (Dead or alive or attack modes etc) You can update its position periodically to sync up if you want but this doesn't really need to be very frequent if your AI is run locally, maybe even once every 2 seconds can be enough and wont affect gameplay (you will still have the experience of monsters chasing a certain player if that is the experience you are trying to make)
Because other players will also be delayed or updated at low Hz (because VRChat) so there is no real need to make the monster chasing a remote player to be more "accurate" than the player it is chasing... in fact that might break the illusion because of the perceived desync
Thats not the issue though, the issue is that theyre still taking up real estate when theyre turned off (dead)
If I spawn 5 enemies, kill them then spawn 5 more, the game is acting like Ive spawned 10 enemies and are all active
in your script, maybe you need to logically make sure it is not sending unneeded data when dead
unless it was queued up data from before
I can understand it needing to send off the last delayed network event at the moment after its death but after that it should be silenced, but no it just keeps on sending stuff despite the fact that not only the gameobject is disabled, the udonbehaviour is also disabled!
yeah it is better to stop the traffic in the script logic itself, rather than relying on gameobject or behavior (which doesnt work the way you'd expect even for unity standard...) so you control it inside the script, where you actually have control
But even that doesnt make sense because Ive gated off in the script if the enemy is declared dead it will block off the AI tick cycle
So the Udon script is somehow still able to work despite being blocked turned off and its gameobject disabled...
was it queued up data from before it died?
I dont really know all I can think is that it sent off an ai tick cycle to be sent off in say... 2 seconds but before that could happen the monster died
So yeah fine it could send off the next AI tick cycle but it would fail because the monster is dead it wont go through due to the branch
then it shouldn't send new traffic... maybe you can plug a debug message to see if it is really sending, "NPC A is sending data XYZ"
then you just look at debug menu and look at when it stops
Ive never used debug nodes, what would be the node to print a message?
I assume log will do it
Each entity contains a VRCObjectSync parent object while a manual sync child object
yes you get the idea
my pool doesn't actually manage the active state of my objects; its main purpose is to inform the master which ones are currently in use or not
So the pool doesnt target the objects themselves?
it tells the master, who is in charge of spawning new entities, which ones are active in the game and are thus not avaliable for being used to spawn a new one in
when an entity activates itself, it removes itself from the pool; when it deactivate itself, it add itself back to the pool
thats not gonna work through. VRCObjectSync forces everything to be continous. and we can't mix continous and manual
all 400 vrcobjects? that seems abit high considering each uses 12 bytes each? or even more ?
So I saw you edit your message. Are you still trying to claim that a continuous object will force all child objects to also be continuous?
You can have the main root object be continuous and have their children be manual
Thats what im doing for my monsters
The AI controllers are actually child objects and the parent which houses the navmeshagents are continuous
I want Hostile to answer this question.
yes as far as i understand you cant have a mix of Continous and Manual for instance. and still? i never claimed it before lol. and atleast the last time i forgot to switch it around it warned me that it couldn't so unless this changed
or rather it would just go to the least restrictive so manual.
also 400 objects with vrc object sync? how are you even handling that considering they all use 27 bytes each?. which i just checked.
That's when they are on the same object. Except that isn't relevant to my situation as I sperate them into a child and parent object. And you clearly read and understood that part as your original comment before you edited it claimed that the parent continuous would force its children to also run in continuous. I'm just asking, do you believe that a continuous parent will force it's child to be continuous?
i do yes. again its based on the fact that last i tried to mix and match a child and parent with two different once. it warned me you cannot use a mix.
also how short of a time? i checked before and let it stand roughly 30 seconds? and it did not go to sleep?. plus it would use up 10.8 kb/s immediately which puts it into suffering
I don't know if Udon has ever grouped child objects into a single networked object
i had several issues with it. where if i had a parent object with either manual or cont. and then several under child objects with different once. it would cause all the child objects to get the Deserialized data from the parent. which i alsways found odd. even if it was different objects and scripts.
but that was over a year ago
something kinda fun and possibly a source of confusion (in regards to object sync sleeping); if you place a continuous script (something with an udonsynced var) on an object with object sync it will continue to blast data even while sleeping, though for remote the variable won't update
A year or so ago the opposite was true; a VRCObjectSync was able to silently disable the networking of the object it was attached to; resulted in some very confusing bugs until I realized what was happening
remotely that's probably what would be observed, though the owner seems to continue sends in my test here
oh wait I see what you mean now; not sure if I observed that specific behavior when last I tested it or not
yeah specifically the owner continues sends, but remote doesn't receive variable updates. i was displaying a variable that i was updating owner side in Update and for the remote player they continued to receive deserialize but the variable never changed after it went to sleep on the owner
which seems like an oversight
Did somebody say "NPCS?!" 👀
👀
Hello!! are you working on an NPC controller for characters?
@cerulean zealotYeah, though theyre more enemy characters that chase players around
But its bugging out in multiplayer cause of an issue with pooling
I will probably make a backup of this project and try and refractor how the enemies get events, Im thinking maybe have 1 global controller that sends 1 big network update to allenemies to tell them to readjust their nav agents
I did a test earlier today where I actually just unplugged the ai tick alltogether, it didnt rise up on the suffering, but the moment I kill them all and return to pool, the issue is back
Im convinced that the VRC object pool has a bug or oversight to it so i might have to come up with my own manual pool
Getting kinda sick of arbitrary things getting in the way of my success... :L
Ok. So my system has combat and ownership handling built in it. My object pooling has a controller onto of vrc object pool that handles ownership and buffers incoming requests if too busy.
if you're only using manual and network events there's nothing really arbitrary about it unless you can work out that the pool itself is spamming the network or something. like between manual and network events you have pretty high amounts of control over what it's doing, trying to like band-aid over it isn't going to fix the fundamental logic. i don't know if you're using object sync as well though
Yeah the enemies have object sync
Yeah, my npc system is very strict on its network calls. I don't use networked events, it mostly goes through the serialization loop like a clock.
How many NPC's do you have in a scene though?
I do not know the upper limit
Im trying to get the occlusion handling module working and that will take the theoretical limit even higher.
I mean I can have 100's of enemies on screen in singleplayer, multiplayer though... 25 and then it starts to "suffer"
I send you a friend request and when I get back I can help you out better than what I can now ad I type using my fat-square Neanderthal fingers on this tiny mobile keyboard.
Il actually be away for a week after tonight so will have to wait till then :L
Do you want me to test 100 attacking enemies at once?
Max I got was like 300 in SP 😛 although it did lag my computer
Im ideally targeting 50 or more
I've never stressed the system like that before lol. That'd be funny
or at least 30 with no issues
So their combat behaviour trees only include
1: continuously target and chase player to smack them backwards.
2: if a random time runs out. Choose another option.
Options:
1: shout a meme, calculate a jump, kamakazee dive bomb at player and explode. Then initiate repspwan.
Thats cool
My enemies are varied, have different kinds of behaviours, can buff other enemies and perform special attacks
Yeah mine is capable of npc to npc interaction and group behaviour. Although combat module is currently underdeveloped. Status effects are something is not generalized yet. But the decision maker is there.
my world is going for the hoard approaching, supporting upwards of 100's of networked enemies at once
Yeah, I think that is where my system may fail cause im designing mine to be more high fidelity and complex behaviours. There is no crowd governing controller because they are all built like independent robots.
That's why an occlusion handler is probably very important for my system so it can park NPCs and turn them into standby mode when no players are around.
can anyone else confirm this ? when UdonSynced
1 byte + overhead = 2 bytes
1 short + overhead = 4 bytes
1 int + overhead = 8 bytes.
1 long + overhead = 20 bytes???. when looking at the data usage in the debug menu
you can try byteCount in the OnPostSerialization
https://creators.vrchat.com/worlds/udon/networking/network-details/
maybe it varies
no i was more curious if other people saw the same.
Oh shit I should try that lol.
so I tested my NPC system with over 120 NPCs forming a group and then causing a group action.
Purple = Ownership is me
Green = Ownership is my friend.
If you shoot the Rottie it makes a call out to other NPCs and then initiates an Ownership transfer then issues a Behaviour call. I think there is a bug when it the numbers get too high. Here is my test videos.
We call the rottweiler "wally". You have to shoot that NPC to initiate the GROUP-ATTACK-THIS-PERSON event.
well yea transfering that many at once takes a while and can bug it. you are not really ment to do so. you have to track it another way
i mean.. This is an EXTREAM version of my system.
well you could track who the local person shots. and have them request serialization so everyone else knows you shot that target. and then do your stuff..
just look at my thumnail image lol
ikr i know your shiba squad 😄
im trying to find the upper bounderies of my NPC system. what it can and cant handle
so far it's pretty solid
how many have you been able to handle before it breaks?
see that the thing. it didn't technically "break" the NPC to NPC multi Group handshaked timed out and then choose another action. Which was "just forget it and solo attack."
so it hasn't technically broke.
but the ownership transfer still happened.
and then attacking the initiation NPC again while the player was still owner of the majority of the NPC then the group attack happened.
which is REALLLY exciting
cuase currently that script is told to get ALL NPC under a defined TAG
there is no set cap to the amount of NPCs it needs to form a group
not sure transfering that many objects even not that often is a good thing.
Oh I aggree.. Im testing outlier bounderies to see when it will break
you could with the new SendCustomEvent with parameters trigger it differently all through that is limited to 100 max per second
Not compatible with my NPC system.
how come?
So my NPC system, im aiming for high fidelity NPCs with lots of behaviours and complex decision trees. Thats what im focusing on. Someone suggested "hey can your NPC handle MASSIVE ARMIES?" and im like "idk... lemme test it." So i CTRL+D the shit out of the shibas in my unity project untill I had 150 of them and then just hit UPLOAD to see what would happen. This is the result.
how high fidality ?
so like.. NPC recognize if you wave your arms in front of their faces while they are trying to tell you a quest or somehting. NPCs that like west world. As an animator, I want to see if I can reach a level where players forget they are interacting with an NPC
they will look you in the eye, they will also be synched enough to be like "hold up.. your being rude. im talking to this player right now. wait your turn. Im sorry please continue."
and then later be like "ah!! your the rude person tries to interupt people...what can i do for you?"
small scale player experience ? like not alot of players in the world i assume?
No a generalized NPC system that works with any world
so all world creators have to do is drag and drop my system in to their wrold
Hello!! it's been a while!! I've been learning programing and making more and more animated content in VR!
I launched my latest project and it's been a whild success!! come see it here! https://vrch.at/jupxwrat
the concept works
well goodluck with it 😄 considering how restrictive udon is and with even more restrictions lately it really depends on the world and their data useage.
I proved that on April 1st
No it works
its extreamly lightwieght in networking
how light through?
eveyr NPC is synced with a string character and an Integer
and a byte
once every....... 5-10 seconds
depending on the action
everything else runs locally
mhm. cause eh. with my own creation of what i am doing for a group. things start running slow at 48 players synced. and we are talking Very light weight networking that only on average syncs per 30 seconds. and causes less then 28 bytes total.
even at that level i ran into suffering with the latest sdk which is annoying.
or close to rather.
well im trying to get my occlusion module working which will make it more optimized.
oh and mind you this was all manual. and since you need to be up to date with everyone it kinda cant be occluded even if i wanted to.
but there is some funky things going on with udon.
like with 48 players and doing a a sync roughly every 30 seconds, it used around 6-8 kb/s even through in reality it should be 1.92 kb/s
before the update i was able to handle 60 players which hit the 10-11 kb/s which again makes no sense math wise
but again best of luck @cerulean zealot !
synching the states of npcs can be really cheap; the lion share of your networking cost for npcs is likely going to be their positional data
depends on what you sync. its never really cheap as just doing a sync requires as a 12 byte overhead. which under a already constrained amount is not really ideal. and manual positional data sync is expensive.
But like I said. My system wasn't designed with mass crowds in mind. Every NPC operates on an individual level.
My goal is more of Nintendogs or animal crossing rather than starcraft or Age of Empires.
You don't need to share positional data all the time.
Only their destination and how far the npc owner is away from destination then everyone else locally adjusts behaviour to "catch up"
Oh if you've got a simple movement environment where you can expect no meaningful desyncs, that works
But my npcs use a movement system that involves moving around each other, runtime mavmesh updates, and dynamic reactions to their environment
My movement system is too chaotic for anything short of "normal" positional syncing
Yeah local npc to npc collision handling is on my list to fix
My trex gets stuck if they wander into where the small cats and dogs are
Cause he's a big boi
He's suppose to stay up near the mountains. But every once and a while it decides its gonna wander down near the cat and dog play area
I don't think it is possible to have inter collision and also get away with just destination sync unless you are fine with a potentially significant desync between the actual positions of npcs. It seems like it'd be a pretty chaotic system.
Yes that's the point of my system
It allows for desync in favor of fidelity. But then tries to resync through local adjustments of behaviour
Chaos and emergent behaviour are key design goals
@north thistle there was one update I did . All the huskies started pooping on a specific point in my map. Just a mountain of poop. Then they started dying while wading through the poop
I made a change and it stopped happening. Idk why
Its exciting to see this things occur
Meanwhile my unexplained bug that disappeared as quickly as it appeared involved my friend's pc crashing. Although I have my idea of what could have been responsible...
Outliers are so much fun. Lol
Make sure your npcs aren't being sent to the magical realm of NAN land!
had one bug where my when I spawned in my npcs, instead of appearing on the map I discovered them super far away, spinning irregularly around the map like a constellation
But yeah I agree with ya @north thistle in where the NPCs did have trouble navigating tight spaces. But it was fixed by adjusting their blending trees in their animators.
Man I wish we were given more control over continuous sync, or the ability to mark manual sync data as not needing guarantee of delivery .
Right now if you want a networking-light position sync that has the ability to turn itself off when not needed, you have no other option but VRCObjectSync
How the different sync methods are at position syncing
VRCObjectSync
- the overall most network efficient position sync method
- easy to use
- no control over how the synced data is gathered or applied
- only indirect, limited control over when syncing occurs (it occurs when the object is moving; it stops syncing short after the object stops moving)
Continuous
Same as above, but:
- complete control over how the sync data is gathered and applied
- zero control over when syncing occurs (it happens always as long as the object is active)
Manual
- complete control over how the sync data is gathered and applied
- complete control over when syncing occurs
- a horrific misuse of manual sync's intended use resulting in this being very network inefficient for position sync
? produces suffering at very low bandwidth usage; it seems to be unable to handle many scene-wide serialization requests per second; is this a bug?
"- a horrific misuse of manual sync's intended use resulting in this being very network inefficient for position sync"
can you explain what you mean by this?
for the last part, i believe there is a manual limit per second; i think it's about 50/s, so probably not a bug, but it is unfortunate
Manual sync seems designed for important data that you want to guarantee will eventually be synced with everyone in the instance. To achieve this extra networking occurs, especially on remote clients who seem to have to report back that they have received the data.
Positional data sync, however, is not individually important data, but rather a constant blasting of data where you only really care about the latest most data and don't worry about individual guarantees as the constant blasting will eventually get you the latest data.
Manual sync also seems to increase KBytes In in what I assume is the server sending confirmations it got the manual sync data
its honestly fine for what it is. and what its suppose to do. It's not made for high throughput or doing alot of synchronized data.
Network Events with Parameters
- complete control over how the sync data is gathered and applied
- complete control over when syncing occurs
- forced high priority data for receivers
- 100 events per second limit
? No idea how more or less network efficient it is compared to the other networking behaviors; almost certainly more network efficient than manual but not sure what its upload usage is
it's less effcient and has lower priority over Manual/Cont.
Manual is already pretty efficient lol.
its just the overhead that udon has that is making it less so
Did you read what I wrote or...?
yes....
Then you'd know why I call it inefficient compared to other network behaviors when it comes to synching position data
No, manual is for high important data that you want to guarantee eventual synching
Continuous synchronization is intended for data that changes frequently and where intermediary values don't matter, like the position of an erratically moving transform. VRChat will perform intermediary value approximation to recover lost data, and will attempt to optimize network data for continuous synchronization. they say that right here them self.
also im pretty sure from what i recall is that udon was never ment to support the amount of required data nor constant sync that positional sync requires.
considering continuous is buffered further in the past i don't value it for positional data, if it weren't for the manual limit per second it'd be better for high count positional sync in every case imo
then again all games that sync position does alot of predicting. to save on bandwidth
Also events have the highest priority out of all the network behaviors. Manual and Continuous can get deprioritized on the receiving end pretty heavily, especially if you aren't looking at them.
they diff are not the highest priority.
i think vincil is referring to what the server prioritizes sending other clients
To be clear, by priority I mean how much VRChat will delay a receiver from receiving synced data. The higher the priority the lower the delay.
from what i remember its by default delayed by some internal factor.
I did this testing just a couple weeks ago. Events got their data to remote clients significantly faster than manual.
Especially when manual gets deprioritizes and turns a 40 ping into a 200-300ms delay
events stayed around 80ms
deprioritizes happens to all networked objects well atleast they say so them self.
so that might be a bug
Events are RPC, though
A different kind of networking than what I presume manual/continuous are using
Events are not delayed by SimulationTime are they? Is so then events should have less observable latency if that is what you mean
i dont know the underlaying structure.
Events aren't even object bound
Whereas all other syncs are "received" in SimulationTime to smoothe out jitters
i.e. the Delay in menu 4 or 6
of your player and objects
regardless of it. its not designed for high throughput that positional sync requires.
like udon networking is what 20 hz or was it higher?
at most ~15 Hz achievable for any sync, but potentially 100 Hz for NEPs
100? i never seen it go beyond 20
i assume u mean the things we cannot control like IK etc
VRChat is not designed for high throughput T_T
we can't play CSGO with 120 Hz tick rate
10hz is already pretty fast and is already pushing the limits of manual sync
oh by NEP i meant events
ooh
you can get up to 120 hz tick rate on CS:GO through
i meant in VRChat
yeah VRChat is not the engine for any high throughput games...
mhm.
limited by data for the most part through
otherwise it would have been fine
yeah the hardcap is the ceiling of what is possible
that said since we operate on free servers its kinda obvious as to why
yeah the server doesnt run game codes so there is no "game server" so to speak, you gotta rely on the owner of anything to do anything
also ngl they are using Proton and its not exactly the best one there is. plus they are using a very old version of it from what i understand.
probably limited by unity
not by unity.
a reminder that Halo Reach apparently achieved its networking with only 31.25kb/s upload on shitty console internet using p2p https://youtu.be/h47zZrqjgLc?si=Ai4pmp0hTzOLtumL
In this 2011 GDC session, Bungie's David Aldridge discusses the programming that drove Halo: Reach's online networking.
Register for GDC: http://ubm.io/2gk5KTU
Join the GDC mailing list: http://www.gdconf.com/subscribe
Follow GDC on Twitter: https://twitter.com/Official_GDC
GDC talks cover a range of developmental topics including game des...
Unity is one of the fastest game engines currently .
as much as i dislike the bandwidth limitations this isn't relevant to vrc's rates, their server is handling much more than that at high player counts, you're seeing what a single user is limited to upload wise to the server, not the end result/propagation
P2P was required to save on bandwith.
(i meant, the old proton version is limited by the old unity version vrchat uses (2022))
Photon sorry yea.
photon yes
I'm just saying we can probably achieve more with Udon than people give it credit
i always mix up
not really. not if u want to sync things. we will always be limited by the 8-9 kb/s limit we have and other limits like the fact that udon can be 1000s of time slower
udon is like 90s computing simulator
i mean to be fair to them its their first actual compiler etc i am guessing
also i do actually wonder if Vrchat will ever upgrade the networking stack. to something better then Pun 2 if thats what they use atm
considering no new features, or even security updates happen
I have a world that can handle over 100 position synched navmesh agents
likely over 200+, but I'd need more real-world testing of that
this isn't 90's computing
i mean you can sync them by using alot of data. like 1200-3600 bytes but thats almost 50% of the budget. also thats only if you sync position and not rotation or anything else.
And like occala alluded to, the VRC servers are handling way more than you likely realize
eh. thats already well known. Avatars,sounds,IK etc
I meant in how it manages the networking
eh its alright for what it is.
yea but you are most likely just doing the update once it changes path right? so anything that interacts with it. it would have to do a sync again and update.
The reliability of the behavior around instance master and object ownership allows for networking that is very resilient and versatile
eh. realiablity? i hope you dont rely on the master. as that is often something recommended not to doo
positional data is handled via VRCObjectSync; I need true positional synching as my systems are too chaotic to rely only on synching move destination
right so you are using alot of data just by using VRCObjectSync. but then again if you do that you are going to be heavily limited with how many users, etc
considering how heavy VRCObjectSync are
more users actually makes the network load lighter
I'm using a distributed system
yea? in what way. even if you offload them to other people its still gonna hit the limit fast.
i know that since i have multiple times hit a wall with around 48-60 people using from 7-11 kb/s without doing much.
it seems it is ultimately down to money...
all the new Photon stuff are at $0.5 per CCU up to 50k CCU
whereas PUN is just $0.29, so ~60% the running cost
like my world people only sync once per 30 seconds at tops and its on their request. and its only 28 bytes.
im sure they are using the non cloud version. the legacy one allowed you to not use the cloud they have.
unless they actually do use that garbage cloud
idk... do VRChat run the actual servers?
no? i am sure they are hosted by someone? 😄
maybe they do just use Photon cloud who knows
Or wait no
they use Amazon right?
for storage and such
I'd run into issues fast if I used manual sync for my positional data synching, yah; which is why I don't
i dont use positional sync for anything.
its all based on local and the users position that comes from Vrc them self.
that is updated once per frame. but not networked.
so unless using the API to get a users position then yea. that wouldn't explain it either.
and i am taking about GetTrackingData and GetRotation through the VRCPlayerApi
which is one of the mysterioues i have been trying to find out is how come the data out goes up when a user join even in a non synced world?
which also limits how much data you have left.
what else are you doing with it through? considering over 50% of the budget is most likely used on 100 npc's
@north thistle now i am actually curious if you are using VRC Object Sync. how are you doing 100 of them being alive and not asleep? considering i just tested and with a 100 simple cubes that just rotate. it immediately suffers at 10-12 kb/s out
the thing is you dont need to sync anything if it is a predictable movement, you can just send an event to say "start rotating"
yea. but VRC Object Sync is constant. you cannot control when it does it or not. unless you turn it off or obviously stop rotating or moving. but i just find it hard to believe they can have 100 running without suffering. considering that a 100 simple cubes that just rotates even every 0.5 second causes it to suffer immediately
@fallow mountain
which means every single object that uses VRC Object Sync uses 120 bytes. on average.
VRC Object Sync tends to be like… lower performance than just writing a custom system
And it’s not super hard to make your own item grab & sync behavior imo
i think Vincil meant he doesnt sync position data at all
if he does not sync position at all. then Vrc Object Sync is pointless to use through?
oh nvm, maybe he meant giving the objects out to several owner to spread the throughput
or maybe not everything is moving at the same time
yea thats where i am confused. due to just how heavy it is to Sync position what so ever.
like even a custom one would still need 15-46 bytes per sync.
object sync is made for syncing typical vrchat objects like pickups, which typically only occasionally moves, so if that is the use case then yea maybe you can have large numbers and not lag
since mostly it is only 1 or 2 moving at any given time
i would assume so. but if its npc's they move fairly often through.
My npc system uses strictly uses manual sync, it allows for local adjustments on players end.
Im banking on the fact that "good enough" for a situation cause most players won't notice.
But I will admit fighting split brain syndrome is crazy.
In my experience the opposite is true, although it depends on what you mean by performance. If you mean low latency/lag, than yah a custom sync is going to be better. But if we're talking about networking cost, VRCObjectSync is way more versatile. Events have the 100 limit while manual sync seems like it might have an even lower limit and also confers additional networking costs on everyone in the instance (it really isn't designed for positional sync).
they are less Versatile for sure. considering the data usage is to dam high. 120 bytes per vrc object sync. you wont be able to have more then 66 active at any given time. that are not asleep. and then you hit 8 kb/s and thats all you have. a Manual one would allow you to do FAR more and by doing alot of preditacble movement you can do even more.
yea makes sense. its the only way to handle alot of positional sync. and it can handle it and you can get way more with it then using vrc object sync for instance.
When doing my testing, manual sync couldn't even complete the test because it hit its limit, lol
what tests? and what are you doing? cause i could tell you that you can easily do 100s of manual request every second no issue.
Yeah to ditto @finite sierra im really interested in what your trying to do.
like me or? do u mean vincil?
Vincil
ah yea.
im mostly interested in hearing what because i have yet to hit a limit with manual
position synching nav agents without the use of snyching destinations; so for remote, they are only moved via lerping to the syched positions
👀 bruh.. 11kb per second what are you doing?
Oh wait. I read that wrong
I'm making a horde survival game and I want the horde part to be really good
I thought @finite sierra was hitting limit with manual.
Having 10 scripts synching rotation + position, they can handle 3hz but start breaking down into suffering at 3.33hz
with 48 people each doing 28 bytes of sync once unknown amount. of time but minimum 30 second between. and then the more often but still very uncommon teleport which takes another 12 bytes @cerulean zealot and then another 12 bytes for using SendCustomNetworkingEvent.
so at worst someone can cause 40 bytes of data. to be synced per 30 seconds
Yeah see thats why I started making compromises with my system. Its suppose to be a generic "good enough" high fidelity for general world creators. Think town square or really cool cat in chill world.
but how often do they do it? cause you wont run into a data limit with that. or even manual limit. 10x 32. even at faster rate it wont
for instance with Vrc Object Sync you will run into a data limit with just 66 of them active at any time. and then you wont have enough for anything else. but realisticly you prob cant do more then 5-15 Vrc object syncs. without hitting data limit if there is alot of players.
Most of my "stand in place idle" scripts also do a comparative distance to last destination check. They will proceed to override "stand in place" answer continue navigating untill a new call comes down.
They warp if they are too far behind.
@cerulean zealot also the reason why i am hitting the data cap 11 kb/s. is of a unknown reason. but what i found is that each player that joins increases the total output data. no matter what you do. at 48 players it hovers at 5-6 kb/s without doing anything.
since there is no way that i would otherwise hit that 11 kb/s since 40 bytes every 30 seconds can never amount to 11 kb/s 😄 even if did 100s of them
I have module that handles ownership if the entire stack of the npcs so no player is requesting any serialization if they are not owner
like i have been trying to find out what the true data limit is for a while. by straining it hard. and it always comes to the same conclusion. Each player joining a world eats into the data limit. even if you dont sync anything. and if you have face and fbt its even worse. @cerulean zealot
Wait..
mind you i only hit 11 kb/s if i am on vr and have face and fbt on.
Wut?
Vrchat avatar overhead eats onto udon budget?!
but when i look at data out as desktop versus vr. my data out is higher in vr.
well yea. it diff counts towards it. starts suffering at 11 kb/s ish a little over is fine.
unless its not intended to
considering they mentioned we have like 18 kb/s or something with everything? avatar + udon overhead and such?
yes the 18 KB/s hard cap includes everything
well its hidden but yea.
i can diff say at 11 kb/s out no matter what its suffering.
even if its triggered by face and fbt.
But that's 18kbs out per client right?
serializations are throttled at 50% throughput, around the 8.5 KB area, idk why it goes to 11 KB
yes per client
Oh ok. Sheesh... dwag you had me worried.
yea which i find abit wierd. cause i dont think its per client.
maybe the little extra was player activities
if it really is going up as much as it does with each player joining.
because we can all agree with 40 bytes per 30 second for 48 people. even if it was a global data output limit between all players that would only be 1920 bytes
so unless its because the master of a world / instance sees the total output of a world. that would make more sense.
i did find with serializations you have to allow for a bit extra for each player count in the instance, because receiving serializations will also generate output by the receiver, about 5% or more
i meant you have to budget the extra 5%
if everyone is serializing, your throughput limit will be less, because you will also be sending out the extra 5%
per person
right but even 5% of 40 if thats what u mean is only 2 😄
for example if 80 people is serializing, your budget (x) + 80 * 5% = limit, so you are left with...
x + 4x = limit...
you are left with 20% of the bandwidth budget
with 40 people, x + 40 * 5% = limit, so x + 2x = limit, so you are left with 33% of the budget
i am not even sure if it is just 5%, it might be more (and varies)
but thats the idea, you have to budget for player count
what is the x in this case?
your budget bandwidth for syncing variable
i would go conservative and say 8.5 KB/s should be your max, if there is only two people
or round to 9 KB, for easy calculation
but again it depends on how many people are really syncing at the same time, it is rarely you have the full lobby syncing at the same time for the same amount
this is the reason vincil isn't using manual for their nav agents btw, the number being entered is the target for how many manual scripts are being synced over the course of a second (number of manual serializations per second)
in this case i assume each object is doing one request per second? or are they each doing 70?
i have a large pool of manual senders, i have an interval derived from 1f / targetSendCount
and increment the target index each request
right. but in that case if we do 48 x 5 = 240. that would mean 8500 + 2.4 ? or how did u get to the number of 33% before
so many requests is it doing per second per object?
how many objects in your pool?
that 70 i assume is 70 requests per second? per object? and there are 100s?
can it be because the pool is too small and the Hz is exceeding the per object frequency
i have around 172, but that's not the point, if i enter 70 it's going to request on 70 over the course of a second
right. 70 requests over a second is not ideal what so ever.
it's a limit on manual outside of bandwidth
well you are doing something way outside what is necessory through.
vincil is syncing realtime positions which makes manual not really viable for what they're doing
which isn't possible cause they will hit the data limit with vrc object sync.
i think they did explain that they distributed the load across multiple players
well yea. but even then depending on player count you will eat more then just 50% of the budget on that amount
it seems all your 172 objects are in the same group? i wonder if this is a group Hz limit rather than global Hz limit
anyway with 70 requests per second per object is like sending a request once per 0.011 ms? which is way to many requests no matter what
wait no math wrong.
it might actually be capped at your frame rate, unless he is running solidly over 70 Hz
yea i was about to say so.
you can easily get a smooth position with just 20-30 hz or 20-30 updates per second.
but even then. using navmesh you dont need to update that often. you just need to set a target and update locally
if there is 48 people, that means the hard cap 8500 = x + (48 * 5%) x... where x would be your budget
and by budget u mean i am sorry i dont really get what u mean by that budget 😄
just to add another point because this seems to be a misconception (and something vincil made a good point on), remote clients don't need to acknowledge continuous sends (it doesn't impact their outbound, they aren't reliable)
well yea that is known. continous is from the owner only.
well by budget i mean the "usable" part of the bandwidth (i.e. a portion of 8500) for serializing stuff
right. so 40 bytes is x?
(only applies when everyone is sending at the same time)
what is 40 bytes?
see thats where i am confused by your budget. do you mean how much data you plan to use? or something else?
if our limit is 8500 bytes. that is out budget.
you much data you should use at maximum (and you should never go anywhere near the maximum but that is another topic)
how much*
globally
i mean per each player
by globally i mean in the entire scene
right. but that still doesn't really explain how a world with 48 players doing 40 bytes at worst. per 30 seconds can cause the total output for each person to sit at 7-8 kb/s??
40 KB/s? or 40KB burst every 30 seconds?
no 40 bytes.
40 Bps?
once every 30 seconds?
no at worst can be done once per 30 second
so its 2 byte variables, and 2 uint variables that are synced. totalling with overhead 28 bytes.
then a Rpc call aka SendCustomNetwork that causes 12 bytes. again can only be done once per 30 second max. per person.
40 bytes......every 30 seconds...... 7-8 KB/s????
yup. i have no idea how..
at 48 players in a world.
and there is no continous or any of that
its all manual and controlled
7-8KB/s continuously?
so at 48 players. while the world is in progress as a master if i am there to watch or test. on my end on the Debug Screen 6 it shows 7-8 kb/s out
for the 30 seconds?
even if i am doing nothing
and yea roughly so
each person can interact with another person. that cost that 12 bytes. but thats a interaction.
okay so. Bps is at 11.5 for the first Sync. if i teleport thats another 11.5 Bps. and if i respawn thats another 11.5 bps. but they are all controlled so its impoossible to spam like respawn etc
8 KB/s divided by 48 people is 0.166 KB/s, assuming 5% output for receiving, they might be sending about 3 KB/s each people, which makes sense because they can be all moving about and chatting and playing with avatars etc
hmm
assuming you also send about 5% for receiving player syncs
that would make more sense because before the new limit update we tested with 60 peoeple at it sat just around 10 - 11 kb/s
...which means, that 7-8KB/s you are seeing, will also eat into your serialization budget...
because it throttles once throughput reach 50%.
...which means you cant expect to have good syncs above say a certain amount of people doing typical vrchat stuff
well this is getting worse lol
well while the world is happening people do well stuff. related to the world.
i have yet to actually hit the suffering state. so that is all good. its just concerning to see it hit that 7-8 kb/s out at 48 players
actually im not sure the 7-8KB eats into serialization budget, because i can spam events and make it go to 70% and still have lag free serializations
oh yea mind you i have zero lag and its Happy and it stays around 5-10 hz at all the time at 48 players
maybe it doesnt affect serializations
i have to further test it with the new limits. but yeea. i need to call out for that with the group
and see if it actually starts throttling or suffer or anything once it hits 8.5
if not then maybe the data out i am seeing is not important to the limit.
yeah what is more important is the Bps in your objects i think, you have to manually add them up to see the serialization usage apart from avatar syncs and voice and other stuff
yea i guess i need to log the Bps if we can access it or something over the duration the event.
the world is typically running 1-2 hours soo
but yea at worst. if you really wanted to in my world. you can do about 24 bps i think i saw the highest
also is the bps in this case bytes per second i assume?
you mean the 999 on your screen should be 0 if the syncs are continuous syncs?
i guess i need to setup a https://creators.vrchat.com/worlds/udon/networking/network-stats for the next test i am doing and log each object and ask each player to bring me that log.
A number of networking stats are available to Udon via the VRC.SDK3.Network.Stats static class.
or make it so it syncs to you
wait sync what exactly to me @fallow mountain ? all data is synced to everyone in the world when you do x thing
the right client isn't doing anything in udon networking, you have passive bandwidth out related to vrc that you can observe in the debug menu or through the network stats
you meant continuous will not generate such passive bandwidth?
i meant to sync the stats data they are collecting, so you dont have to ask around for 48 txt files
manual sync data has guaranteed eventual delivery; to guarantee its reception on remote clients, remote clients are forced to send confirmation back to the server that they have received the data, increasing the amount of networking upload they are using
continuous sync doesn't do that
@fallow mountain oh yea i could just at the end make it sync all collected data to me.
im not sure where you got that from. im pretty sure they do not do any confirmation what so ever. and if they did they should do it on Continous too
i can observe outputs by receivers of manual sync, so those might be the "confirmation"
those are the 5%+ i was talking about
maybe. but then again im sure the data we get through that is received data not uploaded again. but thats data including timestamp etc.
however i thought continuous is also reliable as in it will eventually sync up for late joiners
through OnPreSerialization and OnPostSerialization that is
im pretty sure it does. not sure i have seen otherwise.
yeah the data is not uploaded again, it is just networking overhead
both of them are guranteed to arrive.
just that continous stops if you go over the limit manual does not. atleast thats what the udon site says
Wow
actually maybe the server handles resending if the receiver had packets drop
hmm?
one would assume it buffers it. for abit
yah because it never stops sending out sync data, lol
I actually suspect that VRCObjectSync contains a hidden manual sync behavior that it uses to sync its last position whenever it sleeps
yeah i thought the sender would pause or slow down the Hz of sending when being throttled, but it is still reliable if it is sent out
if that is the case... contunuous sync is just events with parameters
with delay
kind of, though it still goes through VRC's network prioritization system while events appear to not
oh yea found it here. https://creators.vrchat.com/worlds/udon/networking/network-details right under the Note for bandwith limits.
Networking in Udon can be challenging! Try to keep things simple until you're more experienced.
that's not saying it's reliable, though it should be noted that it's saying data can be lost via continuous
well the difference is that Manual just caches the event and then try again.
in case you go over
also continuous seems to have no hard limits on how many sync events they can generate in a world, contrary to other sync methods
take a look at my video, the right hand client is rising on outbound because of the acks
i didn't explain this clearly enough, but this other screenshot is of continuous sends on the left. the right hand client is sending no more than what would normally be sent in a world with no udon networking going on
well its limited to 200 bytes so go over that you it will fail likely. and stop working
manual appears to work in two steps:
-
owner sends out the data sync and waits for the vrc server to respond with confirmation (manual sync also increases
kbytes in); if it doesn't receive the confirmation it probably resends the data until it does -
receiver gets the data from the VRC server and then sends confirmation to the server; if the server doesn't get confirmation it likely resends the data to the receiver
which makes sense that it increases kbytes in. but so does continous through.
im not sure where you got that from. im pretty sure they do not do any confirmation what so ever. and if they did they should do it on Continous too
This is what we in the industry like to call "incorrect". Occala straight up posted a video proving you wrong an hour before #udon-networking message
Manual sync requires clients to send messages back and forward in the backend for guaranteed eventual delivery to work. End of story.
which doesn't actually prove it does that. it just proves that manual is doing something extra.
It literally does prove it.
nor have you?
Occala's video.
The ~3 KB/s plateau near the end might be explained by the 200 B limit per serialization per group
Assuming it is sending at about the max 15 Hz
3000 / 15 = 200
you are relying on a video that shows the data going up on both ends. but that doesn't explain anything. nor does it confirm it does.
unless we actually had one of the devs saying so
its speculation on what it does.
When one client sends more manual sync, the other client uses more data to send confirmation messages back.
you are speculating.
the video is showing manual, not continuous
why is it clogged tho at 3 KB/s?
also you can test it with something like clumsy
prob because of the insane 70 manual requests per second lol.
because it's not related to bandwidth
End of story :)
that video you showed it was calling 70 times per object right?
yea thanks some confirmation
yeah but i am trying to understand why there is an undocumented number limit or whether it is actually something else
That is why I wondered if it was a bug or not
it isn't 70 times per object, it's 70 objects over the course of a second
Could be deliberate, but the person writing the docs wasn't aware it existed, lol
well those 70 are also all from the same person.
well there is alot to be desired and missing from the documents. thats why all these questions are asked all the time.
like for instance the explanation as to why data for manual goes up on both ends. and what the limit is for Manual Requests. and what counts towards the limit and so on.
So turns out Events With Parameters has near identical networking behavior compared to manual sync
I mean if you know how networking works and how manual sync is said to behave, it is pretty easy to intuit why manual causes data to go up on both sides, lol
I wonder if PUN docs can explain what vrchat docs are missing
https://doc.photonengine.com/pun/current/gameplay/synchronization-and-state
there are some familiar things in that page
So having tested out each networking behavior, here is the use case I would give for each networking behavior when it comes to "high fidelity" positional tracking
VRCObjectSync: for when you have several objects you need to sync and network optimization becomes a big concern
Events With Parameters: for small amounts of "high value" objects
Manual sync: for when you've run out of event space, or if you want the sync to be impacted by VRC's priority system
Continuous sync: for when you need more control over how the data is gathered and applied compared to VRCObjectSync and don't mind it always consuming bandwidth
Does preserialization get IsClogged? When does that info become avalible?
it's always avaialbe
with that said, if you are about to perform an action that will produce suffering, I don't believe it will appear in preserialization
It might appear in postserialization
well yea. but that information also is only known if you seek it. otherwise its ought to be belived as speculation until otherwise proven. or if you think it might be that. anyway that is cleared out as to why data goes up on both ends.
it looks like, in PUN terms vs VRChat terms,
Object Synchronization = continuous sync
Remote Procedure Call (RPC) = events
Custom Properties = manual sync?
I'd believe it
or, manual sync is just Object Synchronization with "Reliable Delta Compressed"
continuous is "Unreliable OnChange"?
in the case of vrchat its abit odd. Considering that Manual or Continuous has so many meanings lol.
Do they?
kinda.
Also if you're curious as to why data goes up "on both ends" so to speak
https://youtu.be/IP-rGJKSZ3s?si=pTfPBPuFPEvlT4Oe
Time to tell a story about idempotency, computer science, and the Night of the Multiple Orders. • Sponsored by Dashlane —try 30 days for free at: https://www.dashlane.com/tomscott
MORE BASICS: https://www.youtube.com/playlist?list=PL96C35uN7xGLLeET0dOWaKHkAlPsrkcha
Written with Sean Elliott https://twitter.com/SeanMElliott/
Directed by Tom...
like for instance with Manual Sync. you would think its for less data usage. which is true to some extent but since it does consume data for all users in the world. it no longer is true. as if we consume some data on both ends
well it was solved with the fact that PhaseDragon spoke out about it. up until then it was just speculations
It's knowing how networking works...
Phased gave the answer, but this is moreso an explanation of why networking does this
Highly recommend checking it out
that litterly has nothing to do with it in this case.
It has everything to do with the issues you have described
i disagree.
Lmao
you.... explicitly asked for an "explanation as to why data for manual goes up on both ends"..... you refuse to believe any explanation given to you and write it off as "speculation"..... I don't think anyone can make this any clearer. We're not making this stuff up. This isn't something VRChat docs would necessarily explain because this happens with computers pretty much networking anything
thats what i think when i hear Manual or Continuos.
no it was related to why it went up when more people joining. not the latter.
and yes i dont believe it unless otherwise proven by the once who actually makes it. otherwise its speculation. and that why i was hellbent on not beliving that manual would do so as Manual does not mean gurantees unless its mentioned.
I mean... the more people in the lobby, the more acknowledgements you need to send out. two general's problem x80 people in the instance
again not related to Manual / Cont in that case.
that much i understood and starting to confirm with Manual / Cont.
Not the AI table 😭
Phasedragon used the term reliable but that is referring to the fact that it is queued and clogged, rather than discarded, prior to any actual networking happening
But reliable can also mean the two generals sending soldiers back and forth which is what makes "both sides go up"
So continuous is unreliable in both meaning? It will throttle and drop sends, and receivers will not send acks?
has nothing to do with it. its still useful since thats what manual and continious means..
The table contains misinformation.
like what?
Manual sync guarantees delivery. That should be: ✅ Yes
what do you even mean by that
It's guaranteed to be eventually consistent.
That is VRChat's entire networking model.
I need a hat that says "eventually consistent"
Lmao same
huh
hope it helps! <3
I really wish we had more control with continuous, it would be so useful for stuff like positional sync
what kind of control through?
like do you mean being able to control when it should send and not? or something 3rd
The ability to make it sleep is the big one.
Right now you have to use VRCObjectSync for that which in turn gives you very limited control over how the data is collected or applied.
okay so you are a troll got it
Continuous has the ability to send out unreliable data but you can't shut it off; manual gives you that control but then also forces the data to be eventually reliable with all the costs associated with that
Manual sync will always guarantee that the successful serializations you send get received in the order you sent them.
Need syncing? ──► Yes ──► Continuous
│
└─► Yes, but “manual”? ──► Still Continuous
well doesn't Continous Sync stop if you disable the object? or does it actually break it
I'm pretty sure manual sync will throw out in-between states. It only guarantees that eventually the most recent state with be synced
And disabling networked objects results in a lot of weird, undocumented behavior; not worth the hassle imo
yea thats what i was thinking.
leans in 🤔 I’m pretty sure manual-sync 🛠️ will yeet 🚀 those in-between states 🗑️. It only guarantees ⚖️ that, eventually ⏳, the freshest state 🆕 will get synced 🔄.
i was just unsure if it actually led it to eventuelly perhaps break or not work
-# okay i'm done 
This misconception stems from the fact that manual sync doesn't immediately capture the state of your variables as they are the second you call RequestSerialization. However, it does guarantee that the serializations that actually happen do arrive in the same order.
that would violate the idea of eventually reliable and push it into strickly reliable, right?
If you change the value and RequestSerialization
then change the value again before the next network tick and RequestSerialization
then the first value will never be sent.
also if manual sync guanranteed that in-between states were preserved, you'd be able to build up infinite suffering with just manual sync like you can with events, right?
manual sync only sends the value at preserialization, you can request serialization a 100 times prior but only the latest value gets synced
Eventually consistent because you can have the wrong state locally for a period of time.
When you take ownership of an object you locally assume you got it.
Yes, this is correct. You are missing my point.
the idea of eventually reliable is that you can reliably expect that eventually you will get the latest sync state of a networked object
If a player misses updates and then reconnects, does it then have to process a queue of updates it missed? That's the only way I could imagine in-between states being preserved
void Click() {
value = 1;
RequestSerialization();
// the remote player has a value of 1.5 here, obviously.
value = 2;
RequestSerialization();
}
another meaning of keep in-between states = no interpolation
What
the inbetween is kept unchanged, vs lerped
late joiners (or re-joiners) only get the latest sync, no?
they aren't really in-between states. you don't even necessarily receive them in order, but reliability in this context means it will ensure you have the packets needed to play them in order (reliable, ordered); to the client it will look like they're deserialized in order because it will wait for dropped packets before processing
if you're asking about late joins, no, if you're asking about someone that misses packets, yes
Ok this is what I understood. Late joins I knew, just wasn't sure about the missing packets case
ie linux community?
Does the Linux community debate about networking synchronization for hours? Lol
they seem to debate about far more trivial things for days
no but they debate x without getting anything done outside of os itself
Ah so they are CONSULTANTS!
haha
Hey im very curious about Networking.isClogged. like.. what actually causes it to flip from false to true? Will it flip if I try to send too much data? When does that info come down?
Like.. I ask cause what if i have a branch statement that does something else if true? Or is that not a good use for it.
suffering > 100 turns it on
= 100 i guess
As you send more and more KB/s (in serialization) the following happens in order:
- throughput goes up, at the same time your delay and Hz will degrade progressively
- throughput reach 0.5, suffering starts going up from 0
- once suffering reach 100, isClogged
uh... im not a network engineer and just a noodle goblin...
So these are new terms for me. But suffering? What the fuck is suffering? Where are these Hertz?
Are thse numbers i can see?
Ill look these terms up later.
- you can see these numbers in... debug menu 4 and 6
also in the new network stats (there are graph nodes) https://creators.vrchat.com/worlds/udon/networking/network-stats/ - suffering is basically queued up packets waiting to be sent because serializations are throttled at about (just before) 9 KB/s
- Hz is the rate an object (or player i.e. avatar) sends data
- delay is the simulation delay of an object (or player) i.e. a smoothing window to smooth out network jitters and sort out packet orders etc
dont worry, no networking is best networking, just send minimum amount and dont go anywhere near the 9 KB/s u will be good
On the topic of network clogging, I’m currently syncing pos/rot data whenever those values update for my elevator system. Should I add a built in “only update this value every 0.1 seconds” or something similar to reduce chances of network clog or is that over engineering?
- if your elevator travels at a certain speed, you dont need to sync the transform at all, because it can be calculated locally, you just need to sync a timestamp of when it started travelling, perhaps also from which direction...
- if your elevator goes back and forth at a certain interval, you dont need any networking at all, it can just use
GetNetworkDateTime()orGetServerTimeInSeconds()as basis for the starting times