#udon-networking

1 messages · Page 2 of 1

rapid pendant
#

The udon behaviors are set to continuous and the empty objects that I'm using to store the position have VRCObjectSync on them

weak mirage
#

so the position/rotation is synced by VRCObjectSync?

rapid pendant
#

Yes, locally the object is rotated and then I rely on VRCObjectSync to carry that to the remote? at least thats how I understand it. I'm still new to this sorta stuff

#

I'm using moving these empties which both have VRCObjectSync on them

weak mirage
#

VRCObjectSync can be a bit choppy sometimes afaik, someone once demonstrated a script they made which was a smoother version of VRCObjectSync in certain scenarios

#udon-showoff message

later on they sent a code snippet #udon-showoff message

however, with a lot of objects it can actually be choppier #udon-showoff message

rapid pendant
#

When moving around it feels for lack of a better word like if the change in rotation is not large enough it doesn't update

weak mirage
#

yeah it might be, idk exactly how VRCObjectSync works

rapid pendant
#

I have some new things I need to try

eternal abyss
#

I want to make an object follow the player when the player clicks on it. Position yourself in the head and follow him. But I don't know how to change the owner of the object based on when I click it

weak mirage
#

and then plug Networking.LocalPlayer in there

eternal abyss
#

thx @weak mirage i change some of the code. now all player can click and take the owner of the object. But the master of the rooms it set as owner when they enter. also i need to check if the object have owner stop the fuction of can be grabeable. can i use the stuff you send here?

rapid pendant
#

well my question was deleted as spam

#

I'm having an odd issue where teleporting the player to zero once they move a certain distance away works as expected in the Client Simulator but in test builds it somehow is teleporting between the two extremes rapidly and I'm stumped on the how or why this is happening. I'm using desynced stations and the player exits the station before teleporting then re-enters after teleporting and the station is also moved to zero. Weirder still after a seemingly random amount of time pinging between the two extremes it will eventually teleport to zero. Not sure how to debug this or what could be causing the different behavior.

rapid pendant
#

I swapped from FixedUpdate to just Update and its now behaving as expected

onyx flame
#

Does anyone know what happens to manually synced variables when the owner crashes? Like if I set an int, serialize it, everyone gets it, and then the owner crashes. Everything should be fine and the new owner should have the update?

fresh stump
#

I need someone to just show me the basics of udon. I have everything installed... right now I'm just looking to make a simple setup where you can pick up anmd object, carry it around then drop it and it won't respawn, or reset. how do I do this in laymen terms?

boreal sail
# fresh stump I need someone to just show me the basics of udon. I have everything installed....

For what you've described it's not necessary to use Udon for this, you can use existing components made by VRChat for this very purpose. Specifically you'll add a VRC_Pickup component to make it pickupable locally, and presumably a VRC_ObjectSync component so the object's position becomes networked and others can see it being moved.

video tutorial on this subject: https://www.youtube.com/watch?v=dfjlVe0XXTU

more details on these components:
https://docs.vrchat.com/docs/udon-networking#example-the-simplest-networked-object
https://docs.vrchat.com/docs/network-components#vrc-object-sync
https://docs.vrchat.com/docs/vrc_pickup

ancient breach
#

I have a question in regarding a Network Event to an owner using SendCustomNetworkEvent
If I send a Network Event to the object's owner, will the rest of the code wait until it gets a response from the owner, or does it continue to execute the rest of the code regardless if the Network Event was received at that time

sharp solstice
onyx flame
#

If I want to set a synced string to the display name of someone that clicks a ui button do I need to make the person clicking the button the owner? Or can I somehow get the name of the person that clicked it sent out another way

#

Somehow I feel like there's overhead to transferring ownership and I should avoid it

weak mirage
onyx flame
#

Thanks. That's what I figured but I wanted to confirm.

#

I'm working on a board game with randomized tiles and it'd be a nightmare if those go out of sync an hour in

weak mirage
# onyx flame If I want to set a synced string to the display name of someone that clicks a ui...

you'll need to make it the owner yeah

transferring ownership isn't to bad, you mostly should just make sure that 2 people don't request owner at the same time. When that happens, only 1 of the clicks will actually get through, depending on what arrives first (that's called a "race condition").

If you have a button that gets clicked on by a lot of people at once, like a join button, you can either consider a different design, like an area where people need to stand to join the game, or use player object pooling, which has a synced object for every player in the instance (which can be a bit tricky to code with if you don't have a lot of programming experience). If you're gonna use player object pooling, I highly recommend this prefab: https://github.com/CyanLaser/CyanPlayerObjectPool which handles allocating and removing owners when people join/leave for you

GitHub

A VRChat system that will assign a unique object to every player in the world. - GitHub - CyanLaser/CyanPlayerObjectPool: A VRChat system that will assign a unique object to every player in the world.

onyx flame
#

I've got a decent amount of experience in everything except udon. Race condition shouldn't matter here as it only puts their name on a turn order board. If the string is set to anything other than empty it doesn't allow a new entry. Whichever gets in first is fine.

#

Thanks for the info though.

frigid sky
#

hmm, how reliable is testing network things with multiple local clients? I'm checking some synced variables and it appears to be working fine - but is it client-based or is it just working because both have the same IP? 🤔

#

I'm assuming it's ok, since one would be the owner and one isn't

frozen igloo
frigid sky
#

great! good to know, thank you

weak mirage
#

usually the only thing you can't test well locally is if you have a lot of people doing things at once, for example lots of people pressing buttons at the same time in a synced menu for example

mint sparrow
#

Is the local testing intentionally extra desynced? Or is this a side effect of me handling the networking poorly (I've only ever really done local/rollback stuff before)

frozen igloo
#

no, it's the same conditions as a normal instance

mint sparrow
#

If it's all done locally shouldn't most things be updating instantly though? there's nearly a second delay between what I do in one instance and what I see in the other

#

I might be too uneducated on this ^^' just trying to understand

#

Mostly only worked with rollback before

frozen igloo
#

it still uses a normal server, so it has the same round trip as anything else

#

a full second delay is a lot, but could be explained by either being far from the server you're connected to, lots of other network traffic causing you to be clogged, or simply using continuous sync when you probably want manual sync

#

"local" refers to where the world files come from, it does not refer to where the networking takes place

mint sparrow
#

I thought it did everything locally ^^' it not being uploaded to the servers and all that

frozen igloo
#

it doesn't need to be uploaded to the servers, since the servers don't need to know anything about the world. They just relay synced data between clients, that's all

violet ledge
#

I'm trying to play a sound that can be heard by other players via a game object, which is spawned from the VRCObjectPool, but I'm not hearing the audio from the other player's window and they're getting constant Non-owner attempted to return sndGameObject to sndObjPool errors in their logs. Wat do?

frozen igloo
real geode
#

Is there a way I can have late joiners be able to hear music that has already been played, so that when they join, they are in the middle of the song? (basically trying to figure out late joiner event syncing)

vocal glacier
faint rock
obtuse echo
#

If it's looping, you can rotate the delta using modulo and AudioClip.length.

real geode
#

Idk, ill keep looking into it. Thanks for the advice guys

sharp palm
#

Is there any reason where manually synced variables that are being updated by an object owner running RequestSerialization wouldn't get updated for clients? I've been working on a lot of stuff for the past few weeks and its been working fine; until a few days ago when my synced variables decided to no longer sync for other clients when RequestSerialization is ran.

I cant find any sort of cause in my logs, and bizzarely, network events still function fine on the scripts which rules out crashing; it only seems to be syncing variables that isnt working. Deserialization is being ran by clients, so they are getting something I guess(?); but its not updating their variables. I'm mostly just wondering if anyone else has had something like this happen and if theres anything that would stop variables from being updated (apart from setting them locally, which isn't happening either)

vast agate
#

I'm having issues with sync atm. Basically my program sets a float timer every frame on the host of the lobby. The variable is UdonSynced. I then have it send a custom network event every frame aswell to update a float on an animator for all players based on the variable. However, it appears that the float is not being synced as the progress bar is empty for everyone but the host. Anyone know what could be happening

weak mirage
vast agate
#

Or at least I don't think it is, but there isn't a console in build&test to check

#

and play mode only has one player, who is the owner

hazy cargo
weak mirage
real geode
obtuse echo
dry oasis
#

Super basic question; How DO you populate a player array with the players in the instance?

#

Like, GetPlayers wants an input and outputs and array... but I want to get the players in the instance, not from another array, and it can't be blank.

#

Or.. .do I GIVE GetPlayers an empty player array, and it populates it?

#

Logic tells me that GetPlayers from the empty array would retrieve nothing from it... not from whoever is in the instance.

#

I can use GetPlayerCount... That tells me how many people are in the instance... but not who they are.

dry oasis
#

OK, so it looks like you have to first get the player count of the instance... use that to construct an empty array of that size... and then fill it with players afterwards.
THEN you can copy that populated array to one you've made to keep that information.

#

Boy that is convoluted~

#

I'm surprised there's no node that like... SetPlayers, and drops all that directly into an array for you.

#

GetPlayerCount will just get the number of players... why isn't there something that just gets the players too? 🤷

#

It seems backwards to me.
Get the players, and THEN count them.
Not... get the player count, and then build a list of players from that. 🤔

frozen igloo
dry oasis
frozen igloo
#

no, you don't have to add and remove manually. Any time a player joins, you just need to call getplayers on an existing array, that's it

dry oasis
frozen igloo
#

no, but you can just start with an array that can fit all the players that your world supports

#

which is (softcap * 2) + 2

dry oasis
frozen igloo
#

the simplest way is to just iterate over the entire array. But if this is a performance-critical context such as happening every frame, then what you can do is only iterate the loop counter when you find a valid player. Then use playercount as the max instead of the array length. I don't think you can do this with a for loop in graph, though, you'd have to do it with a while loop

dry oasis
#

Phew... OK. 🤔
Far easier to recreate the array from GetPlayerCount though at OnPlayerJoined and OnPlayerLeft and use GetLength. 😂

#

I'm pretty new to all of this, so I'm trying to apply logic and keeping things simple without knowing the consequences. :B

frozen igloo
#

ultimately, if it's just one script doing that then sure, no big deal. But if you've got hundreds it could add up

dry oasis
#

Noted. Currently making a UI player list, just to figure out exactly how this whole player array things works, and stumbled on how to actually get an array of players.

#

Thanks for the explanation though~ ¦3

frozen igloo
#

nothing wrong with that

gray kiln
#

Hey, Does anyone know if it would be faster to sync an array of 16 bytes, or an array of 2 ulongs?

#

same bits total, just wondering

frozen igloo
abstract sky
frozen igloo
#

though if you're serializing from something else into a byte array in udon, that's going to be a lot slower than the system doing that for you

abstract sky
#

oh you’re right, i didn’t read close enough to see they’re both arrays

#

regardless the performance difference should be extremely negligible with 1 vs 2 obiects

restive cliff
#

How do I forcefully wake up an non-moving object with continuous sync so that the variables update for other clients?
Providing that the script with continuous sync also has a rigidbody and object sync component on the same game object.

real geode
obtuse echo
# real geode Sorry for replying so late, but here's an example of a script I attempted. The p...

One thing I notice is that you have the same event name twice. Is that even allowed in udon graph?
Also, you are getting the audio source time and then setting it to the same value again, basically not changing anything.
You need to define a synced variable for the time and use that to set the audio source time when it's being updated. I think you can hold Alt (or something) to get access to the on change event when drag and dropping the variable.

#

Also, the master needs to set that synced time so it gets send to people who join.

fresh stump
#

Can I get some assistance I’m trying to make a working weapon for pvp combat and I’m struggling can someone please help me out I’ll pay if wanted

fresh stump
#

Try Toly's combat system or P - Shooters.

mild robin
#

I set up the networking for the decoration that will turn on/off globally. It works and everyone can see it when someone presses the button, but whenever someone joins the world, it would be turned off by itself. Any reason why this happens?

mild robin
# sweet wolf

I'm a fucking idiot. Thank you very much. You are the best.

opal dome
#

Does anyone know how I can use an audio player and have it pull MP3s from Github? I've tried several audio players with zero results. I don't see why if a player can pull from YouTube that it should be able to pull from another source. I'm very new to this Udon thing, and I'm not a coder. Reading the instructions and script options makes me cross-eyed. emoji

weak mirage
sweet wolf
#

The usual mp3 format also plays great in the players.

weak mirage
#

oh really? I kinda assumed it doesn't because it's not a video

sweet wolf
#
hazy cargo
#

Does RequestSerialization() sync transform of the object by default?

weak mirage
#

no, it just syncs synced udon variables

#

if you want to sync the transform you can use the VRCObjectSync component

frozen igloo
#

be aware that if you're talking about requestserialization you're probably talking about a manual synced udonbehaviour, and manual sync cannot be on the same object as a vrcobjectsync

lone zealot
fresh stump
#

Would it be more optimized to stuff all my game pieces in one ObjectPool and spawn the correct amount based off the index?

Or would it be fine for each piece to have its own objectpool?

little bison
# fresh stump Would it be more optimized to stuff all my game pieces in one ObjectPool and spa...

If you are dealing with objects of different data types (resources vs tools) split them, if objects have the same data pieces (chess pieces) keep them in the same pool. If your pools get large, consider using a stored indexer (location of last valid) to use during iteration. Ideally you won't instantiate objects during run-time and will already have them generated before uploading your world (have all your chess pieces initialized and in-scene, editor-enabled scripts are your friend here). In my experience this helps cutting down on initial lag and possible object desync, you also get to fiddle with the object net assignments (TopBar ->VRChat -> Utilities -> Network ID Utility).

fresh stump
# little bison If you are dealing with objects of different data types (resources vs tools) spl...

Yeah each piece has different attributes and they are summoned dynamically with non predetermined amounts.
At the moment in testing I only have four pieces.

I know there cannot be more than 77 of one piece at once though.

Also how do object pools work exactly like if I place 1 game object in it can it infinitely generate that game object or can it only summon one of each in the array at a time?

#

Each type of piece will work the same. The only difference in similar types of pieces is their health.

fresh stump
#

I would also like to mention the pieces are not all spawned in at once. A piece spawning in is "rare" it's slow to happen maybe like once per 30 seconds

little bison
#

I'm not sure how the default/included pooling solution works, I just wrote my own to give me more control over processing (like optimizing access attempts and pool object regeneration in editor). If each piece is derived from the same interface, then you could use a single pool system. The downside would be that access becomes more expensive as the number of pooled objects grows. Processing is extremely slow in udon, so if you are using large object sets it still might be best to decompose pools based on true classes rather than their interface.

fresh stump
#

Yeah I only used that joined interface for calling a few main methods code wise so I don't have to store active pieces separately.

Maybe it would just be optimized to have 77 instances pre-made?

That would get horrible over time though when say I have 10 different pieces not just 4

little bison
fresh stump
#

I don't want to share too much info on it but basically it's like tower defense.

little bison
# fresh stump I don't want to share too much info on it but basically it's like tower defense.

I understand. The number of assets existing in your scene at a time usually isn't a big worry as long as they are prefab'd. It's going to be the amount of processing/networking those objects do in your scene that you'll want to look out for.

I think the best solution for units would be pools per AI type/complexity, but you could also do mesh type/complexity as an alternative for built-in load balancing. Have your data/control object (health, move-speed, movescript) as the pooled/parent object to the lower display object (animated unit moving down the lane). You'll also likely want to lock the control object to only process on the local player and break the synced data for enemies apart into smaller packet objects with certain manual deserialization calls (set state, take damage) that call back up to your data object.

fresh stump
#

Yeah that's what I was thinking about networking.
I would just have an event to start enemies and game pieces.

And in theory since everything movement wise is predetermined all clients should be synced but just in case o was planning on doing manual sync for death of an enemy

#

I just was unsure about the spawning of game pieces.

Like can I just have 1 hidden on scene and use the pool to spawn more. Or will I need 77 of each piece on scene since I know that's the max that can be placed.

Rather than free placement I'm going based off of calculated voxel (cubes) in an area

#

So each piece holds its voxel place x1 y~ z4

little bison
#

I'm not 100% on what the spawning method for the default pools are, but you'll want your object to exist in your scene before the starts. From there you can easily de/activate them as needed (instead of instantiating them as needed). Udon is extremely slow, so a space for speed trade is usually always a win.

#

So if you already know the max # of allowed enemies and towers, you should generate your pools to those limits

fresh stump
#

Hmm alright, thx! Gonna go play around with that.

elfin pelican
#

I have an array of Text and want to display one entry of that array. The Player should be able to interact to display the next entry. The currently displayed Text should be synced to all players. I did get some synced behaviour working but synced players ended up having different Texts and it was continous.
My latest try does not work at all and I don't know why
UdonBehaviour Synchro is set to Manual
iterator Variable is marked as synced

sweet wolf
#

Synchronization of all variables works only through SetOwner.

elfin pelican
#

i added a RequestSerialization at the end of both Branch Pathes. Both can interact to display the next Text, but it only syncs with one user, (the owner i guess?)

#

I don't know how to use SetOwner here

#

oh... it automatically assigns the player and the object. That's nice. Works so far.
So I have to change the owner everytime someone else wants to make a change?

sweet wolf
#
elfin pelican
#

Set SliderValue looks like a custom function. Is it possible to create own functions with udon?

wanton gyro
#

No, not yet. Potentially will be able to when they make Udon2

rigid temple
#

Aren't they just called custom events?

hazy cargo
#

If I use manual sync do I have to handle the ownership change of the gameobject?

#

Using OnOwnershipTransferred event

frozen igloo
# hazy cargo Using OnOwnershipTransferred event

Onownershiptransferred is not something you "handle" it's just an event that notifies you when something happened, so you can use it however you want. If you want a nameplate somewhere to update to the name of the current owner, then yes that is something you would have to handle and you would do so by using onownershiptransferred

shy trout
#

Hello, I'm trying to figure out why a drinking game I made is not syncing between the PC and Quest version of my world.
I am using U# to code the functionality and how I have it setup is there is a RoundTable gameobject in the world (first picture) that has an arrow the players have to click on in order to swap out the RoundTable with the actual DrinkingTable gameobject which is active by default but is stored in a parent gameobject that is inactive by default called "SpinWheelGame".
Once SpinWheelGame becomes active so should the DrinkingTable gameobject which has the game functionality on it. The DrinkingTable has an arrow on it that once clicked, spins the wheel through a script attached to it. It rotates the anchor point (second picture) rotating the arrow as well. The arrow has the script set to Continuous Synchronization and also has a VRC Object Sync script attached to it. The Continuous synchronization only handles a UdonSynced bool named isSpinning so that once someone spins the arrow, no one else will be able to spin the arrow until it stops

hazy cargo
#

Hello, need a clarification of this sentence from the documentation. Can someone help me? I am understanding that whoever owns the script is the local player from that script.

"The local player is the Player that this Udon script is currently running on-- alternately, the local player is you. It's very important to know yourself!"

obtuse echo
obtuse echo
faint field
#

aight i got my nice panel to work, now i need to network it properly! can i test OnDeserialization on the local test with 2 clients? or do i need to upload and test with someone else?

#

nevermind the question above it works with local

#

how would i transfer ownership of a slider tho? because i want everyone that sees a slider or button to be able to use it

faint field
#

yeah networking is my nemesis. i can't transfer ownership for my sliders because it wants a Gameobject.

rigid temple
#

your slider component would be on a gameobject

faint field
#

ye i know but i'm kinda confused which gameobject i should use. my ui structure is full of emptys to keep organization hehe

#

should i use the rLabel or the sliders or the ringcontrol or the panel or canvas etc

#

my brain is not working properly rn xd

#

this is my code for the owner check as an example

obtuse echo
faint field
#

wait i can legit just put gameObject down?

#

i swear to god i feel so stupid right now

obtuse echo
faint field
#

Sync method is set to manual

#

HA it works!

#

besides slider 1 but i'm pretty sure i just fed up on the ui itself there

shy trout
obtuse echo
tropic sigil
#

hiii one of the lines on my script is saying it doesnt recognize the identifier 'NetworkInstantiate' does anyone know what to use in udon to replace that? the line is
grid[i][j] = NetworkInstantiate(objects[randomIndex], transform.position, transform.rotation);

frozen igloo
#

do you need these objects to be synced with other players?

tropic sigil
#

yes

frozen igloo
#

Instantiated objects cannot sync, so you need to make an object pool. You can either create your own or use VRCObjectPool

nocturne phoenix
#

For a new client joining, does OnPlayerJoined get called once for each person already in the room?

little bison
#

Yes, and the user joining also does a self call

nocturne phoenix
#

Okay I'm starting to piece together what I'm doing wrong. Got a couple more questions though. Are playerId's the same in every instance? and Can a player's ID be larger than a room's max player capacity?

nocturne phoenix
#

Augh. I have this world were each player gets a script from a array. Player one joins They get the first script. Player 2 gets the second script, Etc. But for some reason It breaks for Player 1 (the host) as soon as anyone else joins, it doesn't seem to break for anyone else though

obtuse echo
cinder spade
#

How can I create a new object synced with everyone? Right now I'm only using Instantiate(object) so it's only local
Edit: I just notice someone with the very same question above, but I'm still confused on how it works

lone zealot
#

The "Player ID" is really more of a session id...but naming things is hard :P

shut gull
#

Bruh ski

#

@tranquil hull can I have role

rigid temple
#

who tf begs for roles xd?

sharp palm
#

does anyone know what "suffering" refers to? (because it probably shouldn't be this high!)

frozen igloo
# sharp palm does anyone know what "suffering" refers to? (because it probably shouldn't be t...

Suffering refers to how saturated your outbound connection is. If you try to send too much data too quickly, you will get "suffering" which will slow down how fast you're able to send data. Suffering will slowly go down over time as traffic is successfully sent out. 13k suffering is very very high indeed, and may result in some network events being dropped completely. Udon sync variables should still be able to get through eventually, though it may take them a while.

#

You can't get the suffering number directly in your code in order to prevent people from relying on specific arbitrary thresholds, but you can get networking.isclogged which is a bool that returns true if suffering is anything above 0

sharp palm
#

I see, there's been a lot of reports in my worlds of lagging and i've concluded its related to 'suffering' constantly going up overtime. I don't exactly know why, and it wasn't an issue when I uploaded them; only seemed to start happening this week. Thanks for the answer though, I guess i'll wait and see if there's either more reports of random sufferings or try and deduce whatever got changed within the past week to cause it.

frozen igloo
#

is it possible that you're sending tons of data, either on purpose or on accident? Maybe requestserialization or sendcustomnetwork every frame?

sharp palm
#

I don't think so, but i'd have to check to make sure whenever I have some spare time. Thanks!

#

I just found it odd that they suddenly started having this after being fine for the past few months; but yeah, i'll take a look and try and get some more info later.

rich delta
#

I cannot get these freaking spawned objects to network! Any ideas what I'm doing wrong?? I can post the spawner udon screenshots here

rich delta
#

Fixed

sharp palm
# sharp palm I see, there's been a lot of reports in my worlds of lagging and i've concluded ...

I've done some more experimenting, and have concluded that having literally anything marked as using the "Continuous" synchronization method seems to be the source of the issue. I don't think a gameObject storing a couple synced integers should be outputting 340 bps if it's sleeping and not even doing anything with said integers. (unless that is correct, and that's just how badly continuous runs. also this example was through experimenting, i am aware its not actually practical.)

I'm not really sure what to do about it except just well, not using continuous, and just rewriting my code to work with Manual syncing instead, but I think it's something that should be looked into I guess because it wasn't an issue for the past year. I also had issues with Continuous in my other world project where it would cause all my scripts to be unable to get the server time; so I am kind of in the belief that something is wrong with Continuous syncing at the moment.

I guess it's also worth noting I use U#, so maybe it's an error on U#'s part? I dunno. If I find time i'll try to isolate the issue and put it up on canny or something.

frozen igloo
#

continuous sync objects will automatically adjust depending on network conditions, so if you have a ton of them they'll keep you right under the limit. But if you have one large manual sync in addition to that, it will blast right past the limit. If it continues to do that over and over without allowing any chance for the network to recover, it will just get worse and worse over time

#

also, continuous sync objects do not sleep. They will continue to send even if there is no activity. So If you have a lot of little things and each one only sends occasionally, you should set them to manual so that they can sit in the background and do nothing

sharp palm
#

I'm working off Kuro's Apartment at the moment; since it also got effected by it (it does significantly less than the bus). I have found swapping to manual sync on all of the pickup able items has stopped the world (Kuro's Apartment) from gaining suffering; so I think I'm just going to do that to the bus at some point and see what happens.

sharp palm
rapid oak
#

Hi. I have a question about syncing arrays. If I try to sync 1 Int array with a size of 500 different values, will the network have a difficult time sending the data? It is in Manual sync and it should sync about one time at least every 3 minutes or more. I am new to array syncing and would like to know the limitation/what not to do when syncing arrays before I try it with a high array size. In the docs it says that Manual sync is limited to 49 kB per serialization, is an Int array with a size of 500 values close to that number? Or it depends on the value and size of the array?

frozen igloo
#

1 int is 32 bits or 4 bytes, so 500 ints is 2KB

#

though I should mention, if you don't need to represent very large values, you won't need to sync an int. You could use a smaller data type that is cheaper to sync.

a classic "int" is 32 bits and can go up to 2,147,483,647
a "short" is a 16-bit integer and can go up to 32,767
a "byte" is an 8-bit integer and can go up to 255

rapid oak
#

I see thank you for the info. I will not be needing an int larger than 32´000 so If i try using a short int array with 500 (in reality I would use about 350) 2 bytes * 350 , will that be a more reasonable amount of data sent to avoid getting the network clogged? I believe that is about 700 bytes.

frozen igloo
#

eh, it might still clog a little but it would clear up very quick

#

it really depends on how much other things you have in the world trying to sync

#

but once every 3 minutes is plenty of time regardless

#

it's really not the end of the world to get clogged a little if you leave room for it to clear

rapid oak
#

I am planning on having just that one int variable be synced over the network. When the network gets clogged, does it affects players in some way (for example, their IK starts to slow down, along with voice breaking) Or does it only affects networked events with Udon scripts? Can I use this node to see when the data has finished completed on the local player or is that node used differently?

frozen igloo
#

serializationresult comes from OnPostSerialization event, which happens after sending synced data. It allows you to know whether or not it was sent successfully and how many bytes were sent. It does not give you any information about when other players receive it

#

and yes, if you are heavily clogged it can affect all your outbound traffic a little, making your movement slow down. But voice is pretty resilient and unlikely to notice a difference

#

udon can know if you're clogged by checking Networking.IsClogged and ingame you can see the exact amount by looking in debug menu 4's Suffering readout. 0 is ideal, hundreds are pretty light, thousands are heavy https://docs.vrchat.com/docs/world-debug-views

rapid oak
#

I see, very useful info! I will keep all in mind when working on it, thanks. One more question: Does "OnPostSerialization" event fires for the owner of the script, or for everyone receiving the serialized data? (I understand that OnSerialization only runs on remote players, not the owner so I wonder if it is the same with OnPostSerialization)

frozen igloo
#

only for the sender

#

sender gets OnPreserialization and OnPostserialization

receivers get OnDeserialization

rapid oak
#

I see. Thanks for the information!

shy trout
#

I'm having trouble getting sync between pc and quest. I have a UdonSynced bool that keeps track of the state of whether or not a gameObject should be shown.
for some reason it works between PC users in the world, and it works for Quest users in the world but it's not cross-platform syncing between the two.
if anyone can help me figure this out I'd really appreciate it
I'm available to share my screen as well

sweet wolf
frozen igloo
#

hang on, before you try that, do you have the pc and quest versions in two different projects? That's what that tool is for

shy trout
frozen igloo
#

ok, then yes that's exactly what you need. You can use it to export network IDs from one project and then import network IDs into the other project

fresh stump
#

When you set the VRC video player on repeat, does it take a toll on bandwidth usage on it just stores the entire video in cache and replays it?

I am trying to figure out if it makes any difference on the server side were the video is being taken from in terms of bandwidth.

lone zealot
fresh stump
#

Is it possible to network gameobject child detachment

frozen igloo
fresh stump
frozen igloo
#

be aware that that won't sync with late joiners

fresh stump
#

hmmm, it means it will stay in the same position as the world loaded?

frozen igloo
#

it means it will not unparent

#

or will not perform whatever action you have in UpdatePosition

fresh stump
#

I see, so synced variables is better option?

frozen igloo
#

yes, synced variables are much more reliable and built for syncing with late joiners automatically

fresh stump
#

I see, thank you 😄

limber light
#

Do players have a persistent Id that I can get? For example if a player leaves and then enters an instance, I would like to be able to have their hp and upgrades stored. For this I would need to be able to uniquely identify the player...

obtuse echo
normal sundial
#

You can just store their username?

#

Usernames are unique arent they?

#

So long as they dont change it

limber light
#

@obtuse echo @normal sundial how can I get that? I was reading a section about player in the manual https://docs.vrchat.com/docs/getting-players Okay, i see it says "Look for a particular name" in the details about getting all players now that I read it again but it is not listed as any method there in the list which confused me. Is there a decent up to date detailed documentation about the different APIs somwehere?

normal sundial
#

What method are you looking for

obtuse echo
obtuse echo
# limber light <@106513983044898816> <@183033825108951041> how can I get that? I was reading a...

This has some API stuff too, in case you missed it: https://docs.vrchat.com/docs/players

limber light
#

So what would the equallient to that graph be in UdonSharp?

limber light
#

allPlayers looks like an uninitialized array?

#

ah

#

It both takes allPlayers as a parameter and returns it?

obtuse echo
limber light
#

How did you find out that there was an GetPlayerCount?

obtuse echo
limber light
#

Ah thank you, i had the top level of Player API selected and did not realize searching that page did not search the sub levels.

obtuse echo
#

Just remembered it exists, maybe it might be helpful to you.

limber light
#

Why the heck is the bot telling me no spamming when I try to ask questions?

#

Are the some forbidden letters or something that makes a message count as spam?

#

Okay if i post code it tells me to not spam...

obtuse echo
#

What works is uploading a file. So you could create a quick text document for it.

limber light
#

Right, well it wasn't important I managed to get it to work with some minor adjustments. Is there a way to persist data once all players leave an instance? Like for example a persistent leaderboard?

#

And is there something equallilent to UnityEvent where I can add an arbitrary amount of objects and methods in the inspector to call?

obtuse echo
limber light
boreal sail
#

Persisting within an instance is one thing. Persisting across instances is a whole other can of worms.

limber light
#

Well I want data persistence within an insyance for this case.

obtuse echo
limber light
#

Ah i see. Butter If the player gets disconnected for 15 minutes and then rejoins vrchat, i think they will be kicked out of the worlds they were in and would lose their association? I guess if it's a5 minuter game it's irrelevant but if it's something longer it could be nice to be able to handle scenarios where a player leaves the instance against their will. Perhaps that's not generally expected even if it would feel good too know a good solution to it.

obtuse echo
limber light
#

Yeah i was hoping someone would say "we have this UdonSyncedPlayerMagic that does everything you want" but i guess it's not that fun. Is there some built in functionally for object pooling that works over network? If i for example want to fire bullets but may not want the overhead of instantiation of and destruction of bullet prefabs...

obtuse echo
#

If you want to have a pool assign objects to each player that joins, then you could look into Cyan's Object Pool on github.

limber light
#

Bullets should only be visual?

obtuse echo
#

You only want to send the actual hits.

limber light
#

Let's say i would have A fireball that moves slowly enough to be avoided then? If you're thinking of bullets as something that generally hit what's in it's path at fire time.

obtuse echo
#

VRCObjectSync might honestly work for your use case, even if it's a bit overkill.

ivory sandal
#

why does this not work... only the instance owner can interact

frozen igloo
# ivory sandal

you need to take ownership of an object pool before trying to spawn

ivory sandal
#

is that just set to local player?

frozen igloo
#

yes

#

also it's totally unnecessary to have the interact call a sendcustomevent when it's just.. right there. You could just put everything in the interact directly

#

the main reason to do it separately would be if you want sendcustomnetworkevent, but that's not what you want in this case unless you wanted the master to handle spawning or you wanted everyone to spawn one thing each

ivory sandal
#

i want everyone to see the same object.

heavy spindle
# limber light Do you know how things like storing player health and such is generally handled?...

There's a VRCPlayerApi.CombatSystem which can do health and such and even ragdolls your character when you reach 0 health although I'm not sure if the health value is synced, but I'm certain that setting the health to 0 tells the owner to die.

What you have to do in order to get it to work is
OnPlayerJoin => player.CombatSetup(); => set the CombatSetup death graphic to null (otherwise it's always on) => you're good to go. You can call GetHealth and SetHealth freely. There's also some other options like if players should respawn at all after dying, how long it takes to respawn and where they respawn at which can be updated at any time

#

but this approach is uncommom because for Udon, it's undocumented on how to get it to work and that it's also not supposed to work. I use it personally because I want to avoid object ownership and such and all of my players die in one shot anyways

limber light
# heavy spindle but this approach is uncommom because for Udon, it's undocumented on how to get ...

Interesting, I saw some notes in the documentation about these stuff not working, but it actually does? That's confusing... https://docs.vrchat.com/docs/players

VRChat

You can interact with Players in your world through the VRCPlayerApi. Each Player has a VRCPlayerApi Object, and your world fires the OnPlayerJoined / OnPlayerLeft events on any UdonBehaviours that listen for them when a player joins or leaves. This page includes info on using some general nodes. Si...

heavy spindle
#

it does! A bit of self ads, but if other players are playing, you can see how it works in Murder Classic

rigid temple
heavy spindle
#

technically, but it still works for Udon

rigid temple
#

oh cool

limber light
#

Anyone know of any tutorials for making a multiplayer game with combat that is synced? I get the feel like there is a lot of stuff that isn't really documented here and it would be nice to see how someone else had done stuff. Even a git repo for a basic game like this would be very nice to have something to study.

heavy spindle
#

depends on what kind of combat

limber light
# heavy spindle depends on what kind of combat

Players shooting fireballs at enemies and enemies slashing players. So i made this game a long time ago in unity and wanted to see if i could rebuild something like that in vr and with multiplayer https://play.unity.com/mg/other/dungeon-0-1

Unity Play

---Make sure you click the speaker icon and turn on sound when playing --
Release 13 Updated 2020-07-12. Please see https://connect.unity.com/p/dungeon-crawler-change-log-and-wish-list for complete release notes.

  • Made some enemies walk around randomly in the dungeon instead of just standing still to make things feel more alive and less predi...
upbeat python
#

Hey quick question.
I got an object (A) with object sync.
Now I have other objects (B) with object sync that I, on runtime, assign as children to the first object.
The objects are moving out of sync now.
I am under the assumption that they all try to sync their position separately, mismatching their positions in the process.
Is there a way to stop the child objects (B) from syncing their own positions individually and just let the parent object (A) sync the position of the whole construct?

boreal sail
upbeat python
#

well, it's more of an easter basket kinda problem.
There's is an indefinite amount of (A)s that each can hold an indefinite amount of (B)s.
You can't tell ahead of time which instances of (B) (A) is going to get assigned.
Like a game of easter egg hunt.
(A) is the basket, (B) are the eggs.
Everyone participating can grab any egg they come across, and put it in their basket.
That's why I can't simply assign them as children of (A) from the beginning.

At this point I'm thinking of just faking the (B)s in (A) by just telling (A) what (B) it got and deactivating (B).
Then just tell (A) to instantiate a simplified copy of (B) over a networked Call.

It's just effort I was hoping to avoid...

Now would be the question, if it's possible to, on pickup of the decoy, to activate the original (B) and make the player Hold the original instead.

upbeat python
#

Current Code:

obtuse echo
upbeat python
#

I just wasn't sure if I might be doing Owner changes wrong...

obtuse echo
# upbeat python This is where I set the `RecentPlayer` Variable

What are you expecting that code to do that it doesn't?
Aside from that, some things are not necessary like base.OnPickup or SetOwner on pickup. Last one, I think it does it for you. I also wouldn't set all children to the owner and be specific instead. These things are not a problem, but can be cut out imo.

upbeat python
#

well, I might have a solution.
While testing with two clients the pickups move wonkily for the none owner player.
It doesn't break anything, but it looks janky.
Just figured that my alternative route might not be as complicated as I thought.
It works fine for the owner, so I just have to deactivate the children for everyone except the owner and put in placeholders that only have a meshfilter and renderer that are identical to the originals

tired quail
upbeat python
tired quail
#

and once you take the object out again you could just re-enable it

#

you'd have to make sure to sync that on / off sync state between clients though

upbeat python
#

yep, maybe I should just check if turning it off works in the game

north moon
#

I'm searching for a tutorial (or help of any kind) to make a script that attaches an object to all players on join, before and after any one person joins, visible by all and attached to all. Synced attached object for all players. Always on, no trigger or on/off. I've tried a couple scripts I've found, yet they only work for the local player or the first joiner depending on the script. I have a couple ideas on how to make it, though I'm too lost already and inexperienced with Udon. Anyone able to point me in the right direction? tyyy

heavy spindle
# north moon I'm searching for a tutorial (or help of any kind) to make a script that attache...

you want an object pool when it comes to object ownership. I personally have CyanPlayerObjectPool come to mind I would use. Beyond initial setup, if you want the object to follow a player, you'd have the position not be Object synced if it's fixed and can't be removed. In such a scenario, you'd get tracking data of the Owner of the Object (which CyanPlayerObjectPool does automatically) and then do position and rotation of the object stuff in code.

north moon
fresh stump
#

is it possible to RequestSerialization only for late joiners ?

fresh stump
#

When Im local testing, is my ID is the same with all clients? or its different?

obtuse echo
fresh stump
#

Yes Im talking about playerId, thank you 😄

obtuse echo
fresh stump
#

Yes it make sense, Im working on system that will hold player ID when they left the list will be updated

fresh stump
#

When Im doing Instantiate for game object I need to also sync it, correct?

obtuse echo
fresh stump
#

So there is no option to get data from the new gameObjects?

obtuse echo
celest mesa
#

OnOwnershipTransferred doesn't seem to fire when the owner leaves the instance, is there a good means to catch this some other way?

fresh stump
quaint rain
quaint rain
#

OnOwnershipTransferred seems to work as expected for me when the player who is the Owner of any given object is not the instance master

#

So the behavior seems to be that when the current master leaves and ownership transfers to the new master it will not trigger an OnOwnershipTransferred event

obtuse echo
#

I noticed that too very recently. It's really confusing because you'd expect ANY ownership transfer to trigger that method. Initially, I was using it to clean up an object, which obviously didn't go well resulting in some rare errors.
I had to switch to OnPlayerLeft, that worked for me.

Related question: If I call GetOwner in OnPlayerLeft, will I get the previous or the new owner?

celest mesa
#

Yeah, that's what I noticed. It feels like a bug IMO, as it should still be an ownership transfer.

#

I THINK it fires after the player's removed and ownership shuffles around, so new owner.

obtuse echo
#

Hmm, but then you can't check if the owner of that object just left which sucks. Would be nice if OnOwnershipTransferred would cover that use case. I think that's why I had to check against a saved playerId in my project.

quaint rain
sharp kraken
#

Using a delayed custom event is the way to avoid requesting serialization too often, right?

frozen igloo
#

if you want to build a reliable clock that happens less often than update, yes

wheat meadow
#

Hi guys, how do I make an avatar always pick up a weapon from the hilt?

solemn fjord
sharp solstice
faint rock
#

What's the easiest way to synchronise the enabled state of gameobjects for late joiners?

faint rock
#

This isn't the spawning/deletion of objects so I'm not sure that would be suitable?

humble girder
faint rock
#

Oh, hmm ok so I was thinking of something else.

#

So it sounds like it's designed for spawning. Will it work just to keep objects enabled/disabled state synced if I'm not using any spawning functionality? (e.g. if I'm just toggling the objects on/off via another script).

humble girder
faint rock
#

That wouldn't quite fit into what I'm trying to do without making it a lot more messy. But yeah, does the object pool keep the object's enabled/disabled state synced regardess of how they are toggled?

humble girder
obtuse echo
# faint rock That wouldn't quite fit into what I'm trying to do without making it a lot more ...

Keep in mind that an object pool is made to have a bunch of objects of the same type that you can have a lot of. Is that what you want?
If you want to have a on/off toggle for a lot of specific objects, like a poster, or chunks of your map, then you can look into synced toggles instead. There are a few videos like this out there: https://www.youtube.com/watch?v=K3kAGQvrH9A

Synced toggles are back! Now we've got them set up using a Synced Bool, which is a way more efficient way then the Send Custom Network Event we had previously, as well as making full use of Ownership transfer and Manual sync!
All assets are available on my Patreon if you'd like to have access to anything I made during or before the video.

Full ...

▶ Play video
#

Oh, and I just remembered. There are examples in the SDK if you search for "toggle", which can be used.

faint rock
obtuse echo
faint rock
obtuse echo
#

So one main script with the sync from the video but with integer instead of bool. And then one other script that can be attached to each button. No need to make 5 scripts each.

faint rock
#

Yeah that all makes sense. That was what I originally thought I'd have to do but hoped there'd be some cleaner, somewhat unified way to do it without multiple scripts. Ah well, thanks for confirming.

obtuse echo
rose rain
#

Question, if i want any pick up to be seen for other player i probably need networking sync or something, does this video helps? https://www.youtube.com/watch?v=MOw8a5RmMjU

Networking can be trick to understand, I hope this video can help people understand some of the basics.

public GameObject superHotMirror;
[UdonSynced] private bool mirrorIsOn;

public override void Interact()
{
    SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, "MirrorStuff");
}

public void...
▶ Play video
frozen igloo
#

that's talking more about how to make your own scripts with networking. If you just need a synced pickup, all you need is to add vrcobjectsync

boreal sail
# rose rain Question, if i want any pick up to be seen for other player i probably need netw...

If you want a pickup to be synced between multiple players, VRChat has a handy component for that: VRCObjectSync https://docs.vrchat.com/docs/udon-networking#example-the-simplest-networked-object

VRChat

The three main concepts used for networking in Udon are Variables, Events and Ownership. Variables are containers for values - like a number, a set of colors or a 3D position.Events are things that happen at a moment in time.Ownership is the system that decides which user can update a variable, whic...

rose rain
#

now my main question is, i want person B to see person A holding an object.. how do i do that?

frozen igloo
#

add vrcobjectsync

rose rain
frozen igloo
#

yes

rose rain
#

and for object thats is spawned?

frozen igloo
#

depends how it's spawned. You cannot sync objects that are instantiated, but you can sync objects that are simply enabled from a pool

rose rain
#

hmm

#

is there any way i can check my object can be seen without the need of a second player to test?

frozen igloo
#

you can launch multiple test clients yourself

rose rain
#

yeah just realise thanks.

faint rock
#

Does anyone know why continuous physics collision would result in what looks like only one networked positioned update per second?

rigid temple
obtuse sun
#

can anyone help with somthing im trying to code ??

#

im trying to make it when you press a button it changes the skybox and the lighting of the world how can i do that

amber ice
#

Is there a way to sync animations with the networking?
as i'm working on a show that involves animations.
and i need them to be synced with everyone (even late-joiners)

amber ice
cerulean zealot
#

@amber ice the script from github should be fine. If it causes you any performance trouble I can give you my "elastic sync" that I'm building out now. I'd have to write in some clamp method so it doesn't spam and use up to many resources from the computer.

cerulean zealot
#

Just link it here. Why be all secrete with dms? @amber ice

faint rock
amber ice
faint rock
#

Yeah, I use that one. It works well for the most part, until people come along with PCs that have out of sync clocks 😉

sour trout
#

The spamming bot hates me so resend as an image. I'm still very new to Networking & I'm trying to build a card game but wondering how I should network it. I was thinking of using just SendCustomNetworkEvent and treating the Owner as a server and all other players as clients that track an event log. Opinions / "gotchas" you can see with something like this?

#

^ note I don't want to resend all events to late joiners but instead just events to sync the current game state 🤔

obtuse echo
sour trout
obtuse echo
sour trout
sour trout
# sour trout So in total it's going to be about 1100 shared variables, would this be too much...

Tested with the VRC Quick Launcher with two users and a button that randomly refreshes 144 cards, unless someone tells me there is going to be an issue this seems viable? Each card has a Sync() method that performs the RequestSerialization() call once ready and is set to Manual Sync Mode. The game itself is never going to perform 144 requests at once so should be fine?

fresh stump
#

Maybe it's better to have a single script that calls a unique requestserialization of an synced int array for all your cards.

obtuse echo
# sour trout So in total it's going to be about 1100 shared variables, would this be too much...

I don't think that would be a problem. As you said, if each card syncs individually, it's really not that much data at each point at time. And since it's a card game, I'd assume the syncing is pretty infrequent.
Of course, there are more efficient way to do things. For example, I don't think you need to sync stuff like attack and defense, or even the state of the cards. You can just sync the act of placing the card on the field using the id, and the on placing the card, calculate the states locally.

sour trout
#

Does the VRC Quick Launcher use the normal VRC Networking servers? Or do I need to stress test in game?

frozen igloo
inland aspen
#

Can anyone recommend a Video tutorial or similar explaining how I can spawn a pickup prefab and have the spawning and positions synced for everyone?

#

Basically I just need a button that spawns a prefab, which is just a pickup with objectsync on it.

timber salmon
inland aspen
#

So there's no way to actually create a new object and have it properly networked synced with vrcobjectsync? They all have to exist already?

tulip valley
#

Are there any known issues of OnDeserialization() not running for late joiners? My world relies on manual synced objects and now breaks for late joiners. OnDeserialization() not running seems to be the cause of it. It runs properly while in the world, just not after joining. It used to work a few months ago and the docs say it should run. Am I misunderstanding something?

stone badger
#

What I don't know is when the OnDeserialization() callback occurs. I assume Awake and Start must be called first. If Start sets the value an UdonSynced property I am assuming it is overwritten by the deserialization as it syncs with the world owner. I wish more of this "peeking under the hood" stuff was documented with examples.

tulip valley
# stone badger Are you saying that it isn't running only because you don't see the effect? I su...

Yes, I checked with Debug.Log. Start() gets called but no sign of OnDeserialization(). I made a new project with a simple script to test, toggling an object, same result with late joiners, they don't toggle the object and don't run the OnDeserialization() method. It used to work correctly a year ago, only recently I noticed it doesn't anymore. Either I am doing something wrong or the behavior changed without the docs getting updated.

tulip valley
#

To add to this: before Start() wasn't called when spawned from a VRC Object pool. This seems to work fine now. And variables seem to be already synced before Start().
Because Start() didn't work back then I put my initialization logic into a one time method firing once at OnDeserialization(), I can fix it by moving it to Start(), although still, the documentation says it should fire once for late joiners, but doesn't.

tulip valley
#

And another add: objects not from a VRC Object pool call Start() without synced data, so can't even workaround it by updating/initializing in Start() because data is not correct yet. No OnDeserialization() called.

stone badger
#

Ok I checked and I too do not see the OnDeserialization call. It seems reasonable to believe that this is because my client would not have called it. I was the world owner in this case so only other player's would have it called. You may need to have to set something in the world that indicates it was called and/or get a friend to send them their copy of the log.

tulip valley
#

Yes, my log is from a second instance of the client. The object owner doesn't call it (and I don't need it, as the owner sets the variables), just late joiners are the problem.

stone badger
#

There are some videos that demonstrate that it works. I'd be surprised if you more or less clone that as an example that it wouldn't work for you as well.

#

Meanwhile... is there a way to detect that a playing sound file has ended?

stone badger
tulip valley
#

Yes, I checked the owner. The owner changes the variable value. OnDeserialization() gets called correctly for non owners. Just late joiners never call it, even though documentation says it should. https://docs.vrchat.com/docs/udon-networking#bonus-concept-late-joiners

VRChat

📘OverviewMultiplayer experiences are the heart of VRChat, so creating a world that reacts to players and synchronizes the data between them is key.This page introduces the concepts that power our networking system. Once you've understood the basics, you can dig into specifics:Network ComponentsNetw...

tulip valley
#

Hah, wanted to create a test case for the canny, but this one worked now. I will have to look into this why that one syncs now

quaint rain
tulip valley
#

No, this is without the object pool, I have two test cases, one with object pool, one without. Before both wouldn't do it. This one (simplified a bit more for the canny) is working correct now. Still trying to figure out why/what changed.

quaint rain
#

I don't think its reported or documented anywhere specifically but as far as I know OnDeserialization will fail for late joiners if the object is disabled by default

#

The variables still sync properly though so you should be able to use Start() to read back the variables

tulip valley
#

The test object was enabled by default, so that can't be it. But good to know.

quaint rain
#

Which test object?

tulip valley
#

The object that has the udonbehavior on it

quaint rain
#

Was that object part of an object pool though?

tulip valley
#

Not this time, just an object in the scene, no spawning. Though my previous one also was just like this and didn't work. Still debugging it.

quaint rain
#

Are you using Udon Graph or Udon Sharp?

tulip valley
#

UdonSharp

tulip valley
#

Odd, similar scripts, one calls OnDeserialization() on join, the other one doesn't.

#

both work fine for players in the world and toggle their object (in different ways), but I don't understand why one calls OnDeserialization() and the other one doesn't

quaint rain
tulip valley
#

it doesn't need to, it just sends a network request to toggle it, so each client toggles it on their own. the deserialization is only for late joiners (which has worked in the past)

#

it's also just a small example script, my actual problem was objects that were placed by players in the world (spawned from a object pool) would not sync their location for late joiners. also because no OnDeserialization()

#

but easier to test with simpler scripts

#

So for the second script, a late joiner should call OnDeserialization() when joining (as it does for the first script) and sync up the current state of it

quaint rain
tulip valley
#

Not based on the documentation, which says it is called once you join the world

#

(and has done so, the world that broke is over a year old and has worked flawlessly until recently)

#

When someone joins your world, the OnDeserialization event will fire for every Networked Object in the world with the latest data, and they'll run whatever logic you have in place to update things based on that data.
So based on this, I would assume it should call OnDeserialization() when entering the world

#

(which it used to)

#

I thought maybe it detects if the RequestSerialization() method is used in behavior and then does it, otherwise it doesn't count as a networked object

#

but seemed to make no difference adding a bogus RequestSerialization() call in there

#

My spawned objects from the pool do call RequestSerialization() though and don't sync on late joiners, so that can't be it

quaint rain
#

Without calling RequestSerialization() there will be no variable data that can be sent over the network

#

If you set a synced int to 10 and RequestSerialization then update the int to 20 and don't RequestSerialization again the serialized value that gets networked is still going to be 10

tulip valley
#

yes, but late joiners should get the value

quaint rain
#

Yes and they would receive the value 10

tulip valley
#

in the past, they would have received 20

#

I have used this script before and it synced properly without calling RequestSerialization

#

I'll quickly do a sanity test, if that's the case for the button now

quaint rain
#

It would work if you didn't have it set to manual sync mode

#

In that case RequestSerialization isn't used

tulip valley
#

I'm not sure how the internals work, I assume RequestSerialization is only needed if I want to spread a new value. if a new client joins it gets the current value. the 10 should be no longer anywhere stored, unless vrchat has a serialization cache on the master/owner

#

hah, ok so. seems to be the case now. A year ago I didn't need to call RequestSerialization, it would just get the latest data on join. Now I HAVE to do it

#

a little bit closer to the solution now

obtuse echo
#

Well, in that case it was also disabling objects, so I'm guessing that plays a role in that too.

tulip valley
#

There are definitely some undocumented quirks in there

#

Especially with an object pool it seems, calling RequestSerialization placing an object (from a pool), it still does not call OnDeserialization for late joiners.
BUT it has synced values on Start(), so there's at least that.

#

Maybe a special case for object pool spawned objects

quaint rain
#

RequestSerialization() seems to fail if you try to call it OnEnable() / Start() when enabling a GameObject and OnDeserialization() will also fail to run when a GameObject first gets enabled

tulip valley
#

though the missing OnDeserialization might actually be a bug. I remember I wanted to sync up using Start() but Start() was never called

#

and OnDeserialization worked fine

tulip valley
#

Ah, yeah I did not consider the "disabled" part. My world only uses object pools, so I thought it might be related to that. Haven't tested a disabled case without pool

tired quail
#

does Networking.SetOwner change the owner instantly, so if you set the owner of something to the local player and then later on in the same method have a check to see the local player is the owner, should it pass?

#

Because it doesnt seem to be. Or maybe I have something else weird going on.

sour trout
#

Hey, quick question if I call RequestSerialization() on two different networked gameObjects, are the requests handled in order for other players? e.g:

Local

  1. ObjectA.RequestSerialization() @ 0.01ms
  2. ObjectB.RequestSerialization() @ 0.02ms

Remote

  1. ObjectA.OnDeserialization()
  2. ObjectB.OnDeserialization()

Or could Remote receive them in any order?

sour trout
sour trout
#

Does vrchat send the entire networked object variables or just the ones with a changed value? e.g:

some networked object:
  - byteA = 1
  - byteB = 1
  - byteC = 2 // just changed, RequestSerialization()

Is that one byte of data sent over the network or three?

lone zealot
quaint rain
#

You should see it in build and test when using two clients, won't work in editor though

tawdry wolf
#

what could be preventing this from working?

public override void OnPickup(){ Networking.SetOwner(Networking.LocalPlayer, gameObject); playerApi = Networking.LocalPlayer; debounce = true; }

public override bool OnOwnershipRequest(VRCPlayerApi requester, VRCPlayerApi newOwner){ return true; }

Thx

frozen igloo
#

also, implementing OnOwnershipRequest and then always returning true is not recommended because OnOwnershipRequest changes ownership transfers to require confirmation from the previous owner, which increases latency. If you just don't include it, all transfers will go through without any need for confirmation

tawdry wolf
#

The revolver itself has manual variable sync which prevents me from using object sync, so I made my own object sync script that looks like this:

#

and this is set to continuous

#

basically the owner should update everyone else

frozen igloo
#

think but if it has manual then it would also conflict with this being continuous

tawdry wolf
#

yeah that's why I have a seprate sync script on a empty

frozen igloo
#

so then why can't you use objectsync?

tawdry wolf
#

because it's manual

frozen igloo
#

so the object with the pickup has the manual sync and the separate sync script is continuous?

tawdry wolf
#

YES :D

frozen igloo
#

you have it backwards, typically you have the pickup use objectsync and then the separate sync script is manual

tawdry wolf
#

would the order really matter? Considering most actions are done ON the revolver root I wanted to sync all those variables manually, and just the transformation is continuous. Just wondering

frozen igloo
#

well the order matters because then you can have objectsync instead of trying to make your own sync script, which is a pretty big task that I would only recommend if you actually needit. This scenario does not need it

tawdry wolf
#

ahh alright thanks . . . time for a mild rewrite 🥲 thx for the help

tired quail
#

is there anything that would cause the rotation of a synced object to not be exactly the same between clients?

I have a stationary object on a table with an object sync on it. On interact the person takes ownership of it, and sets its rotation to a specific direction, and then after a delay everyone else reads the rotation of that object to preform some math (to calculate wat its pointing at)

Now sometimes the owner sees a few degrees different result to everyone else and i have no idea why.

#

does it have something to do with the movement interpolation or something?

#

If i can't find why I'll just stop using the object sync script and just manually sync the rotation angle.

hot whale
#

I wouldn't be surprised if they quantize rotations

quaint rain
tired quail
#

As impiaaa said, might just be easier to manually sync the rotation to be more exact

quaint rain
#

Yeah object sync is not designed to be precise

cerulean zealot
#

question about Deserialization. Does OnDeserialization happen for every script everywhere, all at once? or do I have the ability to control what type of information comes down and where?

For example: I have an Array that contains a lot of information. I want to send it to another client but only that specific client. Can I isolate the sending of information to only client A to client B? Or do I have to send everything to everyone and only client B accepts the information and every other client ignores it.
[2:21 PM]
and does happen accross different scripts at different times?

humble girder
cerulean zealot
#

cool thx

tawdry wolf
#

WARNING with the method above cheaters will still be able to intercept everything :/

cerulean zealot
#

Question about networking data: (context Udon Graph editor)

So the data that is sent out across the network, do I have to set that data (synced variables) on the OnPreSerialization loop? Can I just have synced variables and call request serialization for that script?

#

this is what I mean: do i need to do wonky shit like this?

cerulean zealot
# weak mirage what are you trying to do?

ok, so from a highlevel perspective:

I'm trying to have my NPC's be able to handle Dynamic Ownership transfers to other users so I can run their code locally on clients machines on a case by case basis. This will allow me higher fidelity interactions between User and NPC while having it synced for remote players (give 1-2 seconds delay for remote players). This is very important if I want the NPC to look the selected player in the eyes, hand them a drink, birds land on their finger, and so forth.

The issue im running into: I'm trying to set up a Ownership module that all other scripts will reference when it comes to any branch statements where I need to separate code that runs only for the owner of the object and non-owners of the object. This Ownership module will also contain synced information about the previous owner of the object incase I have the ownership of my NPCs have to jump back to the previous owner. This is important for late joiners.

I've ran into an issue with the variable heap limit (512 is limit) if I constantly do a gameobject.getowner -> vrcplayerAPI.

My idea is to extract the Owner Players ID and store it as an int. This would allow me to sync the data.

I'm doing it this way because my previous method of ownership syncing is still causing issues and i'm trying to centralize where in my code it handels it all.

Having get.gameobject -> get.vrcplayerapi -> store vrcplayerAPI as a variable on start does not allow late joiners to sync previous owners.

This script will be one of many scripts in a state machine style behavior tree.

#

I'm very new when it comes to programming. (only started back in December) and I only know how to work with the udon Graph because in my artist brain that makes the most sense.

weak mirage
cerulean zealot
#

and making sure that information is consistent across all machines at all times on manual sync is where i'm getting all wonky and flustered lol.

weak mirage
lone zealot
# cerulean zealot Question about networking data: (context Udon Graph editor) So the data that is...

OnPreSerialization is an event that is invoked immediately, before the "networked data" of the UdonBehaviour is serialized, such that it can be sent to other players over the network.
You can set the data in there, you can set the data before it. It doesnt matter when you set the data. The data that is set after "OnPreSerialization" exits is the data that will be serialized.

For manual sync:
RequestSerialization => OnPreSerialization => OnPostSerialization => OnDeserialization
(not immediate i.e. some (real)time might pass between these)

However be aware that OnPre/PostSerialization are only called for the current network owner of the GameObject the UdonBehaviour is on, and OnDeserialization is not called for the current owner.
And RequestSerialization may only be called by the current owner.

wary elbow
#

I'm trying to wrap my head around network basics to sync a gun and bottles I made a few years ago. The bottles can be broken via collision, or the gun can call the break function after a raycast. If I understand the answer to another recent question, one script (e.g., VRCPickup) suffices to assign ownership for other scripts on an object. If this is correct, does ownership from one script apply to other objects in the hierarchy (at least children)? Also, ownership of a held bottle is clear, but shooting a bottle won't trigger an OnPickup function. Is it necessary to use the gun script to set the bottle owner after a raycast hit?

quaint rain
# wary elbow I'm trying to wrap my head around network basics to sync a gun and bottles I mad...

Ownership only applies to the current Game Object and won't affect children objects. For ownership you could set the owner after a raycast hit but it isn't necessarily needed as you can use SendCustomNetworkEvent to send events from any client to the owner of the object, but in that case you would probably need local and remote handling for bottles being hit and breaking otherwise the local player would notice a delay as they would have to wait for the owner to relay back that it had been hit.

wary elbow
quaint rain
wary elbow
#

I assigned ownership of the bottle from the gun script. Doing that alone didn't help with the delays, so I decided to try your local/remote event suggestion. Now, the gun script directly calls the break function for the owner and sends a network event for a second function. The second function just calls the break function for anyone who isn't the bottle's owner. Despite the extra steps, everything now appears to be smooth and fast for both the owner and the networked instance.

weary girder
#

So I'm wanting to create a throttle lever like control in my world for a control panel.
In terms of operation, I'm thinking I'll have an invisible grabbable block at the handle of the lever that will act like a short piece of string to drag the lever its self that will be pinned in place and can only rotate a small amount on one axis.
I'm then thinking VRCObjectSync on the lever would let me sync the basic rotation of the lever automatically, and I can then perform some additional smoothing if needs be on the value of the control possibly.

timber parcel
#

Let's see if I'm understanding the logic right.

I've got a turned based game situation. With Vehicles and command Markers.

The markers don't ever need to be interacted by more than one player so I don't need to network them at all.

When placed the Marker sends a event to the Vehicle which gives it target position data etc. The Vehicle replicates this data to all clients and then each client simulates it moving to the target position.

Should I set the vehicle to manual sync as I only have to send target location data once a turn?

timber parcel
#

This event is successfully being called by one client, but the bool movementActive is not updating to the other clients. Did I miss something.

Only one client is calling it at a time so they shouldn't be ownership fighting.

tender echo
#

Hey I've created a simple logic for a private room lock that will unlock the door when a player inside the trigger respawns or exits the room. However, when I test with 2 clients and I exit the game on one client, the room remains locked.

Can someone help me create an udon graph or script to check if there are no valid players in a trigger area so that I can then trigger the doors to unlock if someone crashes or logs off or leaves the world in that room? Thanks!!

rigid temple
#

Is this a ban speedrun or smthn?

tough burrow
#

I'd like to remind you that using a custom SDK is against VRC ToS and is a one way to get banned :)

shut gull
#

i did not know that

tough burrow
tall crescent
#

question is there a way to initialize a object to all world members?

#

currently I am using Object.Initialize but this is only local any scripts that one there aren't sync at all?
even if I initialize it for all players at the exact time, the scripts aren't getting synced

#

(using udonsharp)

humble girder
tall crescent
#

I am working with a game that idk how many players will be playing

#

so it need to be scaleable (preferably) unlimited

#

^ also makes world download size smaller if I dont initialize all object in unity before uploading

humble girder
tall crescent
#

mhmm gotcha~

#

guess I will do a feature request on the forum

humble girder
tall crescent
#

we will see

restive cliff
#

Hi there. I forgot if running request serialization on a parent will affect child objects that have their own manual sync scripts

frozen igloo
restive cliff
#

Thank you

#

@brisk panther there we have it

brisk panther
#

🙏

timber parcel
#

... when you have been troubleshooting for hours and it turn out you had the wrong variable with Sync ticked

tall crescent
#

Back on my subject of 2d ago~

So there is no way to initialize a object network wise? Only local (causing even with the same name / same place in hierarchy not to be sync with any type of udon syncing)

Since gonna throw out a case scenario:
Like I am building a card game~ a card deck exists of 52 cards~
meaning that I have to make my card deck 2-4x the size to get all the cards the game requires (even still limited to the amount of card decks I put in)

having to copy over groups of card decks instead of able to spawn in a entire deck as prefab and directly being synced to all players (pickup able or interactable -> triggers of udon scripts)

What is the best way of doing this since making X *f 52 cards per decks 'pre-spawned' in kinda unnecessary?

#

be able to spawn in network wise a object or object group (all cards as example) when I really required it

frozen igloo
tall crescent
#

since udon script aren't synced if you instantiate a object with a script on it

frozen igloo
#

an object pool does not instantiate, it simply enables objects that have always been there

tall crescent
#

^ yeah I am trying to not use that
since I might require 52 cards at max
or maybe 500 cards

frozen igloo
#

I understand what you want

#

you need to use an object pool

#

synced instantiation is not available

tall crescent
#

okay! Guess I got to use the 'dirty way' of using it then for now
since instantiate 500 cards from the start~ can become performance heavy + download size increase

But thank you for letting me know

frozen igloo
#

download size shouldn't be affected because additional gameobjects are basically nothing. Assets themselves such as textures should always be there

#

frame rate performance should be unaffected. Startup performance may be worse if you have an udonbehaviour with lots of code on every card.

tall crescent
#

fair yeah download shouldnt be effected as much~ I just like scalability when I make stuff so don't have to worry about any 'edge case scenario's of running out of cards' in my case

timber parcel
# tall crescent okay! Guess I got to use the 'dirty way' of using it then for now since instanti...

I agree that you should just use object pool.

But if you insist...
Make each deck a deck controller. This controller has a list of objects and a list of translations and a list of rotations. The deck controllers are manual synced.

When activated each deck spawns it's list of cards. Each card is unsynced and has it's own little script that says "when dropped, tell the controller my transform"

Then the controller syncs the data, and all of its networked versions "on deserialize, update all the card locations"

I don't think this is actually a good idea though.

timber parcel
tall crescent
sour trout
#

Sorry n00b question, for: "200 bytes per serialization". Does this mean 200 bytes udon synced per script or all scripts?

For context my world idea requires continuous syncing of: ( 1 Vector3 + 1 Quaternion + 2 floats ) * 5 * number of players

humble girder
sour trout
humble girder
sour trout
humble girder
sour trout
sour trout
random parrot
weak mirage
#

because world creator and instance creator can always join regardless

dark bane
#

Anyone know what this means??

#

This message appears every time I want to test build my world

dark bane
frozen igloo
#

the console tab, bottom left

dark bane
#

Ok thank you!! I'm not home rn I'll check it out later when I'm on my pc

tall crescent
#

What would be the best way to change a transform parent and have it synced to all user & late joiners?

Currently thinking of making a script for each obj and store its current parent~
But I got todo this from 50 to 300 objects~

#

that might not work~ since the parent that I am setting it to only exist locally since there no way to init a gameobject to all users and have it synced~

#

or I need to init all the gameobject in unity before uploading~
trying to make it scaleable so idk how much the max can be

#

the path stays the same~ as in /player/p_1/cards/stack_1

#

but locally init

frozen igloo
#

if you need to put synced things on an object, then it can't be instantiated. But if you don't explicitly need the syncing on those objects, then you could put the syncing somewhere else and have the instantiation managed by a synced object

#

syncing a setparent operation is a bit complex because you can't sync transforms. If you could, it would be as easy as syncing the current parent and then when you receive ondeserialization you just set the object to that parent.

But since you can't sync transforms, you'll instead have to build an array of possible transforms that it could be a child of, and then sync an int that specifies where it is in the array.

The size of that array will depend on how many possibilities you need, like if this can just be arbitrarily parented anywhere in the scene, then you need every object in the scene in that array. But if it's only a few different possibilities, you only need that array to be a few long. If it's just switching between two different parents, you don't even need an array at all, it could just be a bool and 2 parents that it switches back and forth on.

tall crescent
#

I was thinking of writing my own syncing script for gameobject but this ofc can cause being limited by amount of bytes we can send per update (total)

timber parcel
#

I still say you should have a bunch of bank cards that update their texture/text only when pulled from the deck. That way you only need a object per card that would be in hand/play at once, rather than everycard.

tall crescent
#

and all 140 can be in the game at the same time

tall crescent
#

question is there a way to test thing regarding network easy~
since trying it using unity test build, I will have 2x the same account name?
Or is there a way what makes it 'different' for the session~?

currently storing the displayname of the player in a string list (since a vrcplayerapi list isn't possible)

lone zealot
tall crescent
lone zealot
#

And no. If you need to be absolutely certain that some networking thing is working then upload the world and test it with two (or more) accounts.
Thats the safest way. It sucks, but it is what it is.

tall crescent
#

but yeah need to make sure for they can rejoin if they would crash

#

only local testing with displayname is just not possible (without 2 accounts)

#

but someone told me I could use the quick launcher in the vcc to use profiles

lone zealot
#

There were requests about exposing a player GUID in Udon, however the concern was that people would maliciously target specific players with certain functionality.

tall crescent
frozen igloo
# tall crescent question is there a way to test thing regarding network easy~ since trying it us...

Two things:

You can definitely have a VRCPlayerApi array. The only restriction is that this can't be synced - in that case, you should use an int[] of playerid's as @lone zealot suggested. These two options should cover most use cases.

But, if there is a situation where you absolutely do need to launch multiple different accounts into the same local test, you can use the VRC Quick Launcher. It's available in the creator companion tools section. You can set up multiple "profiles" which simply correspond to remembered login details. So profile 0 is your default, already logged in as you. You can set another to profile 1, and then you can log in as a different account. And those two login profiles will be remembered independently. You can then use VRC Quick launcher's local option to launch into a local test build.

tall crescent
#

yeah I got told about the quick launcher

#

after posting my message

#

and yes I meant having it synced playerapi list, if I say correctly this still wouldn't work since the playerapi in the list becomes null if I am not mistaking if the player leaves.

frozen igloo
#

that's correct, but you should be using extensive validity checks when dealing with players in general because they could become invalid at any time

tall crescent
#

So only storing the player guid in a list would be optional

frozen igloo
#

no, the GUID is not necessary. PlayerID is sufficient

#

if the player leaves, their playerapi becomes invalid, and you simply check for that and stop doing things with them, done

tall crescent
#

playerid is network relate so if they leave it won't work , so if they crash they can't join back in since new playerid right?

frozen igloo
#

if your goal is to recover from leaving and coming back, then yes you'll need to use player displayname, that's an important detail

tall crescent
#

that's why I am using displayname since there is less chance anyone would change there name then crashing

frozen igloo
#

ok, then keep doing that

tall crescent
#

quick launcher is helpfully

lone zealot
# frozen igloo no, the GUID is not necessary. PlayerID is sufficient

Well if a player crashes or rejoins and you want to restore their data, then playerID doesnt work.
The only currently "stable" (i.e. same after rejoin) metric is their displayname. Which isnt great.
A GUID would solve that, but as I said it has the issue of targeting.
A potential solution would be a session/temporary GUID which changes weekly, daily or every session.
You could still run into issues then, but those would be rare I suppose.

frozen igloo
#

it depends entirely on the use case. And if the use case was clearly stated from the beginning I would not have said that

tall crescent
#

could use a third party webserver and use custom api code to collect the guid

#

but yeah latency and isn't worth it

frozen igloo
#

maybe don't do that

tall crescent
#

I won't don't worry

lone zealot
#

As far as I know there also isnt a way to do that.

tall crescent
#

There work around but against tos heavy against tos

#

so no not a option

lone zealot
#

There is no point in the ToS that would disallow you from doing that in general. (that I know of)
You just cant use it maliciously or to collect user data, or in any other way harm, damage or violate any user or VRChat.

But as I said, you wouldnt even be able to get a players displayname out of VRChat. There is measures in place to avoid that.

tall crescent
#

Me will just write a feature request for the SDK to able to also use profiles within unity (easier to reload and test)

obtuse echo
#

So I usually just call OnDeserialization to apply the new synced state locally. But with the new parameter it doesn't really work anymore, so I have to do this:

#

My problem is that the timing doesn't seem to be the same local vs remote.

#

Is there a better way I can do this?

frozen igloo
#

what do you mean by the timing isn't the same?

#

if you're referring to the sendtime and receivetime being different between two different clients, it's because they're both relative to each player's individual Time.RealTimeSinceStartup

#

so if you're going to sync anything, you need to sync relative numbers, not absolute

#
VRChat

This doc covers Networking Components, Properties and Events you can use in your Udon Programs.Networking PropertiesSpecial properties you can get from Networking:IsClogged - returns true if there is too much data trying to get out. You can use this to hold off some operations or adjust your logic.I...

obtuse echo
frozen igloo
#

what does syncstate do?

obtuse echo
#

Only thing I can think of is syncing the time myself.

frozen igloo
#

I'm having a hard time following this logic, especially without seeing the entire thing and no coloring. But I can tell you that sendTime is not based on Time.TimeSinceLevelLoad, it is based on Time.RealTimeSinceStartup of the current local client

obtuse echo
#

Ok, I'll try that.

#

Here is the code for context. You're supposed to hold down a button and depending on the duration after letting go, a different particle plays. When I'm close to that timing - which is 0.5s - both clients see a different particle.

#

Ahh, this is wit the realTimeSinceStartup change, going to try that right now.

frozen igloo
#

oh, if that's your goal then using ondeserialization timing probably isn't the best use case. I would not rely on letting other players decide the timing. Just do the timing locally and send which one it's supposed to be

obtuse echo
#

You are probably right. I was mostly just trying out the new parameter, which I thought would be me relying on the timing of the original user.

#

Yeah, realtimeSinceStartup doesn't seem to produce the same timing either.

#

I'll just scrap that idea and make it more simple.

shy sierra
#

Is there any known issues going on with VRC Object Sync and Udon, currently? Or with Udon ownership in general?

I and a friend with two different worlds of ours (one each) are having issues where objects:

  • Sync incorrectly (Respawn() respawns the object, then returns it to where it was right before respawn).

  • Fail to sync (Respawn() fires locally, not globally)

  • Fail to change ownership (Variables do not change globally; possibly related to previous entry.)

  • Fight for ownership (Respawn() causes the object to interpolate between its previous position and the spawn point, as if both ends are vying for ownership.)

There's no consistency in the behavior, either, as sometimes it will work just fine. It's wholly inconsistent and happening across worlds.

#


And is there any way to protect from these issues?

wooden sentinel
shy sierra
#

Update: It's also causing psuedo-kinematic physics

When a player picks up an object, there is a chance that it stays where the player last let go of it, despite not being kinematic and having rigidbody physics.

#

At random.

shy sierra
#

Package resolver just started showing a new SDK.

wooden sentinel
shy sierra
#

Like straight up anything they touch is suddenly kinematic.

#

With no reason, lmao

wooden sentinel
#

yeah, it is intended I think. they are.....lost what to do by lost of owner...

#

I saw it in murder previously.

shy sierra
#

Yeah definitely ownership issues then. Maybe the SDK update will fix it (hopefully) but if so they need to start blocking non compatible SDKs.

wooden sentinel
tall crescent
#

soooo~
what can possibly cause that my udon behavior get reset when someone joins~

all the functions in my OnDeserialization are all local
they only get the value of the object and translate it towards UI and or the state of the game

#

figured out the issue~

#

the issue that caused it: changing the value of a ui element (toggle isOn/ slider value) with code in the start or OnDeserialization
cause it to trigger it as a event -> that connected to changing the value making the person loading the owner before he has all the data causing a complete reset of the behavior~

#

soo using the 'SetIsOnWithoutNotify(X)' instead of 'IsOn = X' fixed the issue

silver jackal
#

I am trying to send a networked event to teleport players, but found that custom network events do not activate the custom event? This is a stripped down version of the nodes and this does not even have the log that the custom event even fired so its not calling?

frozen igloo
silver jackal
#

🤦‍♂️

#

I forgot to set the sync mode

frozen igloo
#

It sounds like you're describing the behavior where ObjectSync goes to sleep. When it does this, it takes any udonbehaviours with it. If you want to sync variables while the objectsync is asleep, the best way to do that is to put it on a separate object, yes

shy sierra
frozen igloo
#

whether or not it's moving

random parrot
#

why does smoothing not work on quaternions?

lone zealot
#

I read that wrong. Are you using Quaternion.Slerp?

random parrot
#

sorry, i meant an UdonSynced quaternion

lone zealot
#

Ohh...not sure if smoothing quaternions was ever supported out of the box. I would just do that myself. But I also generally like to know whats happening instead of having to rely on blackbox implementations.

random parrot
#

ah, i see

tall crescent
#

Question do VRC Object Pool also go in sleep or can cause strange behavior with udonscript on the same object like not syncing correctly?

frozen igloo
tall crescent
#

nope

#

found out the issue was caused by switching between owners to quick before the serialization was finished

shy sierra
#

Or would it be more appropriate to sync the position directly in Udon in that case?

frozen igloo
tawdry wolf
#

sometimes the drop isn't working and the gun stays in the players hand is this a bug?

humble girder
noble halo
#

hey there, can i force animation on player with udon? with C#

humble girder
noble halo
noble halo
#

im using a station and turned "seated" off so my head wont be tracked while animating a dance, but now im unable to leave the station's location

quaint rain
#

Just need to call Immobilize(false) on the player when they exit

noble halo
#

hmmmm, head still tracking now that i tested the world, any way to stop the head tracking during animation?

quaint rain
noble halo
#

interesting, you sure it cannot be done otherwise?

quaint rain
#

Yeah, anything involving stations you kind of have to expect to learn work-arounds and accept dealing with some level of jank

noble halo
#

oh well, i hope they will fix that in the future

quaint rain
#

As a basic example of station animator controller it would be setup something like this

noble halo
noble halo
#

@quaint rain is it normal that i cannot use "build&test" after i added the avatar sdk?

#

no error, it just doesn't start

quaint rain
noble halo
noble halo
#

oh well, for some reason it doesnt compile when avatar sdk is added, no idea why

tawdry wolf
tall crescent
#

what is the max characters limit of a string that is udonsynced?
like can we for example sync a string with 2000 letters/characters ?

humble girder
tall crescent
#

ooeehhh

#

interesting okay ❤️

tall crescent
#

since manual serialization ~ idk when other script sync triggers so what will get priority in that case

humble girder
tall crescent
#

yeah I knew about the bandwidth limit (idk how much that is but yeah)

#

also what happens if we would go over the max serialization on the obj? will it be send in parts or not send at all

lone zealot
tall crescent
#

since vrc doesn't allowed List<> and only type[] <- that has to be set else it won't sync.

lone zealot
#

Generally serialized objects have bigger memory footprints than their non-serialized form, so you want to avoid strings if you can.

#

For example the string "100000" takes up 12B while the int 100000 takes up 4B

frozen igloo
tall crescent
frozen igloo
tall crescent
#

ohh thank u~ are those syncable?

humble girder
brisk willow
#

Hi still new to udonscripting. And i dont know if someone can help me or not. But what i want to do is that when players enter this room. That is outside of the main world. A colliders check for all the players inside that room and then returns a synced list. I just dont know how what VRC feature to call to get the name that is not local player. Unless using Networking.Localplayer is the only way to get a list

sinful vessel
#

I'm having an insane issue.... I have a game world that's been working for a while through PC and Quest players and I was going to full launch today, but all of a sudden PC and Quest players are unable to see room syncing up. I have 12 rooms to be claimable. Only the very first room is able to be seen by both PC and Quest. If a PC player is host and grants Room 2, only PC players can see it. If a Quest Host Grants rooms, only Quest players can see rooms 2-12 and not PC

#

Literally everything else works and are synchronized except those rooms

frozen igloo
sinful vessel
#

Sure not. It's the same one

#

And I've refreshed the NetworkIDs several times and still not working

#

It was all working until last night

#

when it suddenly stopped

#

Me and my coder's been tearing out our hair tying to figure it out

#

(mostly me)

frozen igloo
#

and after clearing network IDs you reuploaded both quest and PC?

sinful vessel
#

You want me to clear all id's instead refresh? (honest question)

frozen igloo
#

wait are you talking about this button?

sinful vessel
#

Sorry regenerate

frozen igloo
#

that doesn't do anything to network IDs, it just refreshes to find the VRCWorld

sinful vessel
#

Brain's been mush for the past 20 hours

frozen igloo
#

regenerate does pretty much the same as clear, because if you clear and then upload it generates during upload

sinful vessel
#

hm

frozen igloo
#

I'm just asking if you uploaded both PC and quest after doing that

sinful vessel
#

Yeah.

frozen igloo
#

okay so it's probably not a network ID difference then

#

could these issues be explained by udonbehaviour crashes? Is it that nothing happens, or that the wrong thing happens?

sinful vessel
#

After running some more tests a moment ago, the data is being held, as when I hit randomize rooms, a room a Quest player couldn't see a PC player owning gets updated if it hits room 1

#

There's no errors in my Console, both on build and while observing unity with Vrc

#

(we have debug scripts pop, but that's nothing intersting)

#

So say You are on quest and claim room 1, and I claim room 2, I hit randomize. Room 1 is now me but room 2 wouldn't show up for you (but would for me)

#

I hit it again and you get room 1 back and can see it

frozen igloo
#

is it a race condition?

sinful vessel
#

I.. doubt it?

#

I'll ask him

#

Yeah he said "nope"

#

I've been over here scratching my head trying to figure out what happened, since it all was working last week

brisk willow
#

im having a weird issue. Maybe its obvious and i am not seeing it but i have two scripts talking to each other. When i get the cachedname from the room script,it returns nothing. Even if room already knows the data.

sinful vessel
#

What the actual hell. Thank you.... I've been so stressed out about this

frozen igloo
#

huh that's odd

#

but cool

brisk willow
#

Okay i got it working at a certain point. I have this and the networkevent is being called. I tried it on a test build and it is working. But i recently tried it on 2 differentes computers and accounts. But the second account is not seeing the name being instantiated

brisk willow
#

I think i already know where i got it wrong. I only can do manual sync for arrays. So how can i exactly pass on the array data to others?

obtuse echo
# brisk willow Okay i got it working at a certain point. I have this and the networkevent is be...

A few things, some minor and not important but just suggestions:

  1. You can use an autoformatter in VSCode. I think it's Shift+Alt+F (haven't used it in a while). I see some odd spaces left in the code.

  2. I haven't tried syncing arrays continuously yet, which I feel like you shouldn't. But the the issue is probably because of this: https://docs.vrchat.com/docs/udon-networking#requestserialization
    When syncing behaviours with synced array variables on them - make sure to always initialize those arrays to some value, e.g. an empty array. If any of the synced arrays are left uninitialized - the behaviour will not sync!

  3. The ChangePlayerListNetworked is not really required if all the people see and trigger the collider. If someone walks in the collider, the OnPlayerTriggerEnter will be executed and therefore ChangePlayerList is executed for everyone without networking. In fact, that networked event will be executed multiple times for every player in the lobby, which is a bit redundant.
    Now that I look at it, you also try to sync playersInRoom. Again, OnPlayerTriggerEnter will be executed for everyone without networking. So you can just remove the UdonSynced.

brisk willow
#

And the strange thing is if i use the [udonsynced] in playersinroom and cachedNamed. It does work regarless of whoever presses the button first. But it does it twice.

obtuse echo
brisk willow
hardy plank
#

(in ClientSim)
I have an UdonBehaviour with Sync set to Manual and I'm calling RequestSerialization but am never receiving an OnPreSerialization or OnPostSerialization on local and the remotes are never receiving an OnDeserialization

#

Using UdonSharp btw

#

and yes, I do check if the local player is the Owner as well

quaint rain
hardy plank
#

thanks for the info

sinful vessel
#

rather annoying but at least I can still get it uploaded with syncing

visual badger
#

hey guys I'm having an issue trying to make sure a Player as joined but is also ready - Should be OnPlayerJoinComplete() but it is not exposed.

frozen igloo
visual badger
#

Oh could well be thanks I'm gonna look into it

#

@frozen igloo but ONDeserialisation will run before OnPlayerJoinComplete so do you have a specific workaround in mind like checking smthing specific there?

frozen igloo
#

OnPlayerJoinComplete isn't a thing and it's a bit unclear exactly what you're asking for

#

OnDeserialization happens when you receive data. Is that not complete enough of a join for you?

#

If you need to wait for all your objects to receive OnDeserialization not just one, then you should keep track of which ones have received and which ones haven't, and wait until all of them have

#

as for your suggestion of VRChat implementing something like this - VRChat cannot do that for you because it does not know the difference between an object that has sent something you haven't received yet, and an object that never sent anything at all

visual badger
#

there is a random delay between payer joined and the scene is completely initialized (OnPlayerJoined complete then spawns in the log). I'm trying to sync audio track timing for late joiners (using network manual syncing).

frozen igloo
#

If you have a recent SDK, OnDeserialization will give you a DeserializationResult with SendTime and ReceiveTime. You can subtract SendTime from ReceiveTime to give you the total delay in seconds between when it was sent and when it was received. You can use that to figure out a more accurate time to play the audio at

visual badger
#

audio is desync from 5 / 10 seconds because of that delay network values are ready before the scene

#

yes thanks. But in my case as the scene is not completely initalized I don't think it can help.

frozen igloo
#

that doesn't sound right, udon and networking starts pretty late, long after unity stuff like audio

visual badger
#

ho idk that's not what I see (local testing with quickLauncher) but that may be a lead

#

The scene litteraly fade out from black but it has already completed initialisation and network process. I'm using UdonSharp btw could that make a difference?

frozen igloo
#

yeah, and unity starts even earlier than that

#

this shouldn't be a concern

visual badger
#

ok, thanks for your help 🙂 I'm gonna continue working on it

normal sundial
#

What kind of scale should i be looking to limit myself to as far as syncing variables? For example if i wanted to sync, 10, 100, 1000, etc. Ulongs, where would i start to experience limitations of the platform?

frozen igloo
# normal sundial What kind of scale should i be looking to limit myself to as far as syncing vari...

You're limited to sending about 10KB per second right now, and vrc players take up about 3-5 of that. 1 ulong is 64 bits or 8 bytes, so 10, 100, you can spam as much as you want. 1000 would be 8KB, so you'll be limited in sending that about once every two seconds at most, but ideally it would be good to leave breathing room for everything else and only send that once every 5 or 10 seconds or more

normal sundial
#

Thanks! Thats great to know! My plans shouldnt really involve much other than the ulongs im using so it sounds like im good to go!

normal sundial
#

On a similar note, do you or someone else know how much of that limit some of the common pen set assets use of that?

frozen igloo
#

not much

normal sundial
#

Cool, thanks!

dark bane
#

anyone know how to fix this?

cold laurel
#

How is this a networking problem.

dark bane
#

where do i put this problem?

#

why are there so many folders for these its confusing

cold laurel
misty sail
#

hello! so I'm trying to build a procedurally-generated backrooms world and i'm having issues with the part where everyone should see the same thing.

i have an empty gameobject that serves as the main manager, and in its Start function i call the subfunction to set up the initial state of the rooms. i want to send non-owners the random seed used by the owner so that when they spawn the rooms they spawn the same rooms, so I make that function only run if the player is the owner of that gameobject, but then no matter what i do that object does not seem to call the OnDeserialization event.

@cerulean zealot pinging you 'cause you asked me to

cold laurel
misty sail
#

ik the owner is doing fine

cold laurel
#

Are you calling RequestSerialization?

misty sail
#

Start checks that the player is owner, if so it sets assigns the rng seed to a UdonSynced variable and then calls the SetUp function; then the OnDeserialization function for the non-owners uses that rng seed to do the thing

misty sail
# cold laurel Are you calling `RequestSerialization`?

i thought OnDeserialization ran on player spawn but i did try both with and without calling it, though i'm not sure when i'd call it so what i did was add a condition to the Start function so that if the player is not the owner it sends a network message to the owner to run a function that then fires RequestSerialization. also tried to run that function in the non-owner's version of the script themself and that also didn't work

cold laurel
cold laurel
misty sail
#

so how does it work?

cold laurel
#

The owner needs to RequestSerialization

#

Then eventually when VRC is ready to sync OnPreserialization is called for the owner.

#

This is where the owner can make sure the synced variables contain the most up to date information.

#

For every other player in the instance, OnDeserialization is called after the synced variables have been synced.

misty sail
cold laurel
#

You do not need to do that

#

OnDeserialization runs on join

misty sail
#

so how do i make sure the owner runs RequestSerialization for every new player that spawns as soon as they spawn?

cold laurel
#

it just does

misty sail
cold laurel
#

It does.

misty sail
#

i added a simple Debug.Log to OnDeserialization and it does not get fired

cold laurel
#

Set your script to manual sync mode

#

:p

misty sail
#

i did

cold laurel
#

Really?

misty sail
cold laurel
#

Can I have a look at the code here.

misty sail
#

this bit here i added just for debugging purposes and the "fired ondeserialization" message doesn't show

cold laurel
misty sail
#

build and test

#

2 clients

misty sail
# misty sail

this code does not have the networking part, i got frustrated after trying a million things and deleted it all to try to start over from scratch after asking stuff here

cold laurel
#

Fair enough, syncing a single number shouldn't be that complicated

misty sail
#

this shows up fine

#

but the second client is not sending the "fired deserialization" message at all

#

nor the "owner start" ofc

cold laurel
#

What variable is the seed here?

misty sail
#

i don't have it, that was part of what i deleted, lemme rewrite what i had at first real quick

cold laurel
#

That's a little bit of indentation there

misty sail
#

i had three variables with

[UdonSynced] int rngSeed;
[UdonSynced] bool syncRng = false;
bool syncedRng = false;

then down at the start i had

public override void OnDeserialization()
{
    if(syncRng && !syncedRng) {
        syncedRng = true;
        SetUp();
    }
}

void Start()
{
    if(Networking.IsOwner(transform.gameObject)) {
        rngSeed = UnityEngine.Random.Range(Int32.MinValue, Int32.MaxValue);
        syncRng = true;
        SetUp();
    }
}

public void SetUp()
{
    Unity.Random.InitState(rngSeed);
    ...
}
#

er

#

there

#

ik there must be a way to get the seed that isn't making a new one

#

but UnityEngine.Random.seed is deprecated

cold laurel
misty sail
#

make sure OnDeserialization() only gets run exactly once in case that was getting funky

#

but i did try without

cold laurel
#

That..

misty sail
#

having only the rngSeed variable and have no if condition inside OnDeserialization

cold laurel
#

Shouldn't be synced.

misty sail
#

why not?

cold laurel
#

it needs to be local?

misty sail
#

syncedRng is local, syncRng is not

cold laurel
#

Each client needs to keep track of if it's been synced

cold laurel
#

Remove it

misty sail
#

sure, tried that

#

did not work anyway

cold laurel
#

You aren't calling RequestSerialization here?

misty sail
#

you said it runs on player join

cold laurel
#

...

#

no

misty sail
#

er

#

OnDeserialization()*

cold laurel
#

yes

misty sail
#

but i also tried calling requestserialization

#

like such:

#
public override void OnDeserialization()
{
    SetUp();
}

void Start()
{
    if(Networking.IsOwner(transform.gameObject)) {
        rngSeed = UnityEngine.Random.Range(Int32.MinValue, Int32.MaxValue);
        syncRng = true;
        SetUp();
    } else {
        SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.Owner, "serializeMe");
    }
}

public void serializeMe()
{
    RequestSerialization();
}

public void SetUp()
{
    Unity.Random.InitState(rngSeed);
    ...
}
cold laurel
#

...

#

that is not how that works

misty sail
#

i am aware, that is why i am asking here :P

#

but you said OnDeserialization runs on player join; empirically it does not, otherwise Debug.Log would have fired

cold laurel
#
public override void OnDeserialization()
{
    if(syncedRng) return; 

    syncedRng = true;
    SetUp();
}

void Start()
{
    if(Networking.IsOwner(transform.gameObject)) {
        rngSeed = UnityEngine.Random.Range(Int32.MinValue, Int32.MaxValue);
        RequestSerialization();
        SetUp();
    }
}

public void SetUp()
{
    Unity.Random.InitState(rngSeed);
    ...
}
misty sail
#

what's shocking about this

cold laurel
#

How confidently wrong you are while I am trying my very best to help you.

misty sail
#

sorry, i don't mean to sound confident

#

that was not the intended tone

#

i meant to sound confused

#

i am not confident in any of this

cold laurel
#

sorry, I am very bad at reading cues like that 😅

misty sail
#

this was in the original code i sent up above:

public override void OnDeserialization()
{
    Debug.Log("<color=lime>fired ondeserialization</color>");
}

void Start()
{
    if(Networking.IsOwner(transform.gameObject)) {
        Debug.Log("<color=lime>owner start</color>");
    }
   ...
} 

if OnDeserialization runs on player join, shouldn't the Debug.Log up above run? if not, why not? and in that case, how do I get it to?

cold laurel
misty sail
#

give me five minutes i'm getting a coffee but then i am

misty sail
#

@/KitKat thank you it worked! i am ready to rumble 😁

cold laurel
cerulean zealot
#

@misty sail hello Red i'm avalible now

misty sail
#

ok so i have an extremely simple script for a flashlight that i got from a tutorial. it works fine locally, and the other client sees me carrying it just fine, but the light's state doesn't seem to change for the other client. any idea what's up?

cold laurel
frozen igloo
misty sail
#

. . .

#

yes i do

#

lmao

cold laurel
#

I am blind kek

misty sail
#

thank you for pointing that out

cold laurel
#

I usually prefer forcing the sync mode in my scripts but again (this is graph xd)

misty sail
#

if i use GameObject.Instantiate to spawn some prefabs that have objectsync in them, do i still need every player to spawn them or do i just have the owner do it?

frozen igloo
misty sail
#

oh alright

#

fair enuf

frozen igloo
#

because synced instantiation requires communicating network IDs with other clients which is fragile and not something we want to directly expose to udon. Instantiation and destruction in general is also good to discourage because it generates a lot of garbage which needs to be collected later, causing hitches

cinder spade
#

That makes sense. Also another thing, why is objects named with seemingly random "i" and "l"? Is it to give them unique id's too look for or something else?

frozen igloo
#

I'm not sure what you're referring to

cinder spade
#

When using the debug menu in game, if you pickup/drop an object, it's logging that, and the object it's referring to (I think is an object) has a random name made up of "i" and "l" 's

humble girder
frozen igloo
humble girder
#

Have never noticed that before

cinder spade
humble girder
#

I don't even read the log about pickup object since it seems too redundant.

cinder spade
#

Fair

arctic marlin
#

So I have a RequestSerialization that isn't firing and I'm unsure why. I've done a similar pattern up to now, but all of a sudden it's not working.

#

First a player hits a button that is hooked up to this function.

#

It declares that person as the current owner and hops to the next function with an integer.

#

It goes through this and at lines 120 and 121 it does the serializtion process which looks like this:

#

Is it alright to be using this sort of switch system in Deserialization?

#

This system worked for the previous three cases, but this fourth one... when I put a debug log in the case or the UpdateCurrentPlayers, the RequestSerialization is not even firing....

#

This is for a memory matching game in English and Japanese.

#

I'm trying to make it so the board locks for the other 3 people when it's one persons turn to flip cards.

#

I had some trouble with referencing a separate script for strings when I first started off, so this time I tried to keep the entire code on script... is that generally better with Udon?

#

(Sync mode is set to Manual)

#

I do have a fair bit of [UdonSynced] variables... not sure if this is a lot or just a few...

#

I kind of have some questions about Udon Syncing,so while I'm here typing away. I thought I should ask:

  1. What is a rough estimate for to much Udon Synced variables?
  2. If Setowner is called once, that user can make changes to variables outside the function it's called in right? ex. a function called by a function.
  3. Should I manually be doing something with Preserialization, or is that better left untouched?
#

This is the next step:

#
  1. I noticed that when I run two clients in the builder, the displayName of all the avatars I have in separate windows are all the same, but the recieve separate player Ids.
    Do these separate avatars count as separate VRCPlayerAPI units in the Build and Test mode? I was hoping to avoid having to create two separate accounts and debug things online that way.
#

Sorry for all the questions, I just kind of hit a wall with this. It's so much nicer when the computer does weird things such as nothing at all.
Any other good networking documentation like this: https://docs.vrchat.com/docs/udon-networking ?

VRChat

📘OverviewMultiplayer experiences are the heart of VRChat, so creating a world that reacts to players and synchronizes the data between them is key.This page introduces the concepts that power our networking system. Once you've understood the basics, you can dig into specifics:Network ComponentsNetw...

quaint rain
#

Yes they count as separate VRCPlayerAPIs despite having the same displayName.

quaint rain
#

Also when you say RequestSerialization() isn't firing can you verify by putting a Debug Log before the switch statement?

arctic marlin
#

Oh, that's a clever spot to put it.

#

gimme a sec

#

this text should change to:

#

hmmm.

cold laurel
# arctic marlin I kind of have some questions about Udon Syncing,so while I'm here typing away. ...
  1. https://docs.vrchat.com/docs/network-details
  2. Yes, as long as the changes happen before the object is serialized.
  3. You can for example use pre serialization to move data that changed into a single synced byte[] to save bandwidth by only syncing the data that changed.
VRChat

TipsTry not to sync everything; consider what you can determine from the minimal amount of information shared. For example: if an object will move on a fixed or predictable path, then its position may not need to be synchronized and instead its initial location and velocity may be sufficient.If ther...

#

Manual sync is limited to roughly 49 Kilobytes per serialization.

#

You should be fine :p

arctic marlin
#

The only thing I can think of right now is that the owner isn't setting for some reason...

arctic marlin
#

hmmm, owner is set properly...

humble girder
humble girder
arctic marlin
#

sorry, so small.

humble girder
arctic marlin
#

Actually, I'm not sure. I've heard the override term before, but I didn't really get it.

#

Do I want to override that implimentation?

#

It seems like I should put in override or new.

humble girder
#

The implementation is called metamorphism in object-oriented programming, where you try to change function implementation of base class it's derived from.

arctic marlin
#

I feel like I don't want to change it, so I put in override.

humble girder
#

You usually don't want to use "feeling" in programming: computer doesn't feel.

arctic marlin
#

hmm, isolated the bit of code in a separate script, and gave it a go, but it doesn't change though.

#

I'll have to take another look at OOP sometime soon.

humble girder
arctic marlin
#

These three guys:

#

hang on the isolated script wasn't manual...

#

That manual button... haha.

#

I'm gonna check the big script now with override. Thanks for the help!

#

hmm, override doesn't do it in the mainscript, but I can build off the smaller script for now.

#

Thanks to everyone for the info/help! I learned a lot! 🙏

#

Smaller script works!

cold laurel
humble girder
#

Polymorphism

#

Haven't used this term for years

arctic marlin
#

I got what you were getting at though, somehow... Hope my code metamorphs into a butterfree some day.