#udon-networking

1 messages · Page 34 of 1

fiery grove
#

For sync purposes, is it worth using shorts or bytes if possible or can I just use ints for everything regardless of the size?

#

Does an int always take more space than a short, regardless of value?

serene yacht
#

programming-wise, ints are usually 32 bits long, and it does not resize dynamically, it takes up that much space regardless of value stored
shorts or bytes would take up less space than an integer, but in turn have a smaller range of values

lone zealot
#

In .NET "int" is just a shorthand for System.Int32 which is indeed always 32 bits i.e. 4 bytes.

nocturne phoenix
#

I have a udon project built around having 1 unsynced udon script on each client that reads the local player's inputs and applies changes to them, then goes through and checks every player's information and applies effects to match. Basicly All the syncing should be done through the players themselves.
My problem is this script seems to do nothing if its Synchronization Method is set to None. Am I missing something basic here?

frozen igloo
#

Sync mode none is currently broken on live. It's fixed in the beta

nocturne phoenix
#

Oh that sounds hopeful. So is the logic sound? Having a local script that reads inputs can changes player velocity for example, then locally applies effects on each player based on their velocity

frozen igloo
#

yes, as long as you're only planning to do anything to the local player

nocturne phoenix
#

Oh i was hoping vrchat did something to sync the player data. So things like player velocity when changed locally would later get shared and synced up with the other clients

frozen igloo
#

if player A says "I want player B to move" then no, you can't just do playerapiB.setvelocity

#

you'll have to sync a variable or send a network event, which would in turn be received by player B and they would interpret it by setting their velocity

nocturne phoenix
#

Yeah that's what I was trying to figure out thanks

flint cedar
#

So I "think" im taking the right approach here so I want to be sure.

With simple things like switches that trigger behaviour that requires syncing, that's not something you need to constantly switch ownership for right? I assume that would just add networking delay for no benefit even though the if the owner doesn't trigger it there might be a delay for the user who did trigger it to see the action take effect

frozen igloo
#

eh, it's up to you

#

if it's manual, then taking ownership, setting the variable, and requesting serialization shouldn't have much delay

#

On the contrary, if you don't transfer ownership, that means you would have to use network events. Network events have a higher latency than manual sync so it might actually be longer for everyone with that method

flint cedar
#

I was gonna say, having a non-owner make a Network Event request to the owner to have the variable change takes nearly a second for that entire process

#

So I assume ownership transfers are actually quicker?

#

Seems weird and convoluted

frozen igloo
#

if it's manual, yes

#

manual sync is very high priority

flint cedar
#

Yeah, the variable in question is manual

#

Thanks as always, ill try adding an ownership transfer and see how that goes

crisp bone
#

Question on networking logic here, if I have multiple instances of a card game going, I am wondering if somebody were to click "reset" button on two or more games, they'll become the owner of both game's parent object with my game controller logic.

If they hit reset, a local(non-network) event will fire to reset the game because I only found TMPro to do so OnClick().
Could this potentially affect both game instances since they're both owned by the same client? How could I isolate them if I can't provide some sort of GameID or parameter in the event?

Here is what my method looks like, and is called by a local event from TMPro.

supple cradle
#

when using manual sync, OnDeserialization is called for the new joined player and a random player already in room?

azure crane
supple cradle
#

yes, and a random player already in room!

#

i mean, anyone else have this problem? maybe it's a bug.

azure crane
#

how many players are we talking about?

supple cradle
#

player ABC are in room, when player D joined, OnDeserialization is called on D, and one of ABC

azure crane
supple cradle
#

okay, OnDeserialization is fired for both the later joiners and the non-owners already in room.

azure crane
#

it may be caused by another user that updates some udon behaviour and then requests when a player joins

fiery grove
#

Requesting serialization only updates the udon behaviour that requests it tho, right?

azure crane
fiery grove
#

Makes sense

obtuse echo
#

@azure crane @fiery grove correct me if I'm wrong, but that method request the serialization of all other clients. Only the owner can call it and it notifies everyone else to get the right value, right?

azure crane
obtuse echo
#

Thanks, looks like my understanding is correct then. Maybe I misread the question.

flint cedar
#

What is the best way to create a script that only the first user to create/enter an instance executes?

#

Spawn didn't work for me and Start seems to execute before networking states are established which prevents me from checking instance ownership for late joiners in order to stop unwanted script execution

#

...nevermind! Seems like just checking for object ownership instead of instance ownership worked.

wooden sentinel
#

Maybe like combination of OnPlayerJoined + isMaster could be?

fiery grove
#

There's a is network ready event I believe, but I'm not sure what it does

#

Either way just checking for master once should be enough

#

But you need to consider what happens to late joiners as well

lone zealot
#

The network ready event is pretty much a relic of the trigger stuff I think. At least it was explained to me that Udon starts, only after the network has readied

frozen igloo
#

start is effectively onnetworkready. It's an internal function. But "ready" just means connected to the network, so in udon you won't have received all sync until a bit later

honest lance
# fiery grove Yeah but master changes when the old one leaves and it would fire when new peopl...

if you use OnPlayerJoined, and check whether or not the joining player is master, it should fire at most once.
because when the original master leaves, another player who is present becomes master.
thus, a joining player may only be instance master if there were no players in the instance before they joined [in which case the instance is new, as there is nobody to recieve sync from anyways]

fiery grove
#

I see vrcEretNice

honest lance
#

granted, this is what should be the case. if for some reason OnPlayerJoined is fired locally before the local player knows they're not master, this method won't work. so better test

strange token
#

Do we know if they plan to add syncing to any of the new types they're exposing to Udon in the current Open Beta?

fierce thunder
#

Is there any issue with Udon's networking currently? My object assigner that I made won't sync objects to the players it's assigned to currently. Even tried uploading the default test version of the World Jam one and nothing follows the players in world.

azure crane
#

there are no known big syncing issues, except for sync mode None being broken on the live client

can you elaborate your situation with some details?

fierce thunder
#

I'm using the object pooling to assign a simple sphere to players currently. The spheres and such however do not sync to the players position. At first I thought I messed something up but not even the example version in the World Jam works.

azure crane
#

how are you syncing their positions? have you added the object sync component?

fierce thunder
#

Oh does it need an object sync now? Before it didn't. I can try that though.

azure crane
#

object pools only sync whether an object is enabled, nothing else

fierce thunder
#

Huh. Well damn. That resolved my issue. Thank you very much. LOL. I had been spending like, 5 hours trying to figure out what I messed up on. The example version didn't have an object sync either since it wasn't suppose to be a pickup. Thank you for that. Thank you very much.

azure crane
#

glad it worked! iris

drifting flame
#

I'm like day 2 learning udon and vrc networking and such. I could use some code review on a pretty simple vending glow stick vending machine. Here is the udonbehavior I have attached to each of the buttons on the machine:

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
using VRC.SDK3.Components;

public class glowstickbutton : UdonSharpBehaviour
{
    public VRCObjectPool pool;

    public Transform spawnPos;

    public override void Interact()
    {
        Networking.SetOwner(Networking.LocalPlayer, pool.gameObject);

        var stick = pool.TryToSpawn();

        if (stick == null)
        {
            return;
        }

        Networking.SetOwner(Networking.LocalPlayer, stick);
        stick.gameObject.transform.SetPositionAndRotation(spawnPos.position, spawnPos.rotation);
    }
}

This works fine for one player for sure. But I have a suspicion that this is subject to races with SetOwner and whatnot when multiple people are mashing the buttons at the same time. Would it be smarter to send an event to the master and have the master spawn glowsticks on behalf of the button presser?

crisp bone
#

You can or you can deny requests until the local behavior finishes its routines

drifting flame
crisp bone
#

I think the owner of the object pool is the owner of the objects starting off. You could transfer the ownership of objects but the owner of the pool can always take it back with the return method.

#

@drifting flame

#

It is unknown if it'll be subject to onownership request though if you want to deny it. Would be an interesting test

drifting flame
#

@crisp bone do you know if Networking.SetOwner blocks until the ownership requests are resolved? Debating whether I can just

        if (!player.IsOwner(gameObject))
        {
            Networking.SetOwner(player, gameObject);
        }
        if (!player.IsOwner(gameObject))
        {
            return;
        }
abstract cedar
#

how do we get networked toggles to work cross platform?

#

right now, only quest useres can effect toggles for quest users and vice versa for PC

languid snow
obtuse echo
flint cedar
frozen igloo
#

"Blocking" is a very specific term related to multithreading. Udon is not multithreaded so everything will execute instantly.

flint cedar
#

Good point

drifting flame
azure crane
frozen igloo
#

I mean, yeah, you can block the main thread but uhh that's not a good idea

azure crane
#

depends on the application, in udon, you would choose death vrcSkull

#

but for normal cmd programs waiting for user input or network replies, it's very fine

frozen igloo
#

If you are creating an application which is doing nothing else, then sure. But unity has to render frames

#

even then, it's still not a good practice to block main thread on an application that is doing nothing because windows will consider it unresponsive and prompt the user to close or wait

white chasm
#

Technically speaking Udon supports running code on the DSP thread with OnAudioFilterRead. This is executed separately from main thread but it’s a bit tricky to get it working correctly. I don’t recommend using it other than audio processing though, because blocking this thread will block audio you hear

obtuse echo
#

Maybe a bit off topic, but can you find the source code for that in the vrchat application?

civic haven
#

is anyone going to make a vrchat wii sports swordfighting

lone zealot
#

Anything Realtime-PvP is kind of meh, due to the high latency in VRChat.
Its gotten slightly better with regions and having manual sync which has higher priority, but I think its still around 200ms on average which is quite a lot.

sharp solstice
#

If we had access to the latency / connection quality to a player, we could doing... something similar to rollback netcode, maybe? game would have to be designed around it.

abstract cedar
grizzled lake
#

Hello

mental mountain
steel igloo
#

It is pretty cray. This was a test I did to test sending a keypress from my laptop in my VRC instance, to a server on the other side of the USA, then create a video frame with data that changes something visually, then I hear the keypress. It really is as bad as you are noticing, @mental mountain

(This tests the difference between ping and IK, and I'm not cheating with ping)

#

BTW - Udon to Photon server is also usually much much faster than IK/audio sync too, though I haven't done detailed profiling wit hit.

mental mountain
#

When I tested of sync problem making some mmd world, ping 50ms, udon sync was 130ms < send custom network event was 550ms == netIK==voice(as i know they work together) < continuous sync 700ms.

languid snow
#

is using LateUpdate instead of FixedUpdate a good idea for sending custom network events more accurrately?

frozen igloo
#

That really won't change anything

languid snow
#

ok

stoic fog
#

Is there a way to network an animator? I made these elevators and I got them working pretty good. The udon graphs that fire off the triggers are networked but everything in the state machine is not networked. I'm still pretty green at this. I thought about just object syncing the individual elements but it feels like that would collide with the animator. If there's a good resource i'd love to read up

obtuse echo
#

This way, all clients will execute "StartElevator" and trigger the animation.

stoic fog
#

ok. I found it strange because for my automatic doors, I'm just using sendcustomevent and its synced for everybody.

#

I think what im going to do is condense all my animations in to a single up or down animation and use any state transistions with udon scripts calling that and see what happens. When I realize how these elevators work, there only needs to be two animations in total to do everything

obtuse echo
stoic fog
#

ok thats what i figured. I'm gonna try this method since it directly calls one animation via the animator and see what happens

#

Is there a way to buffer an event like on SDK2 so that new players will see the current state?

#

I'm guessing I need to set a variable that fires off on entry

strange token
#

I just wanna say I absolutely love udon's networking, it's so easy to set up really good networking!

frozen igloo
#

jeeze, you're making me nervous. I legit can't tell if that's sarcasm or not

#

I guess ever since the udon network update that's significantly less likely to be sarcasm, but still 😁

mental mountain
rugged marsh
#

If it's just a simple looping animation or triggering states what I've been doing is putting an event keyframe at the end of the animation that does a SendCustomEvent (String) to call a method which then (for owner only) updates the animator for everyone via network event.

#

So it's synced to the owner to either rebind and restart the loop or switch everyone to the same state.

lean silo
#

kinda new to networking, trying to figure out the best way I can grab a players name who interacts with a object and put it in a text for all the other players? The closest I have gotten is it the main person can see it but it is blank for others

stoic fog
rugged marsh
#

And then in that method you would check for owner and call the update/sync method as a custom network event to all.

stoic fog
#

I'm using graphs

#

im too unedumacated for c# as of now

rugged marsh
#

I assume it can still be done with graph I'm just not very familiar with that myself. I recall there being a node for custom network events, you might be able to have the animation event keyframe call that directly.

stoic fog
#

its easy to define customs in graph. I just need to test to make sure it works

jade mesa
# lean silo kinda new to networking, trying to figure out the best way I can grab a players ...

I'm not sure how it looks like in graphs, just U#. You'll have two objects: one button and one display.
1. The button has an Interact(...) event listener that calls a function on the display (e.g. ChangeDisplay(...)) and passes the VRCPlayerApi.
2. That function on the display needs to call Networking.SetOwner(...) so that the display is owned by the player who pressed the button. When synchronizing, data flows from the owner to other people.
3. After that you need prepare your synchronized variables: I'd suggest using the int type via VRCPlayerApi.GetPlayerId(...) and not a string since that is lighter on data.
3b. Alternatively you can put the code that prepares the synced variables in the event OnPreSerialization() which gets called on RequestSerialization() before sending data over the network.
4. After setting your synced variable(s), you want to call RequestSerialization() to send this data over the network.
5. This will trigger the OnDeserialization() event on all other players in the world which you can use convert the player id back to a string and display it.

X. Put the behaviour sync mode to manual and use the non-interpolated [UdonSynced]

#

At least that's how I would do it, not sure if it's the way of doing it 🤷‍♀️

thorny kindle
real fractal
#

Why can remote players trigger a network event that has no network event call in the world? There is no sanity check for that?

frozen igloo
lean silo
#

So does OnOwnershipTransferred run for the last owner or current?

thorny kindle
lean silo
#

the only page I could find about it said this

#

so I was kinda confused

lean silo
thorny kindle
#

dont know much, i think that will fire after setowner called and new owner applied

honest lance
lean silo
#

basically doing a onInteract that set's that person as the new owner of text

#

ah ok cool

thorny kindle
#

yup, and if ownershiptransfered fire for everyone (i think), it returns new owner vrcplayerapi where you can grap displayName from

lean silo
#

oh ok wait

#

so if I do set owner should I set the owner to the current object (gameObject) or the text object?

#

I have it set currently to set it as the text object

honest lance
#

it should be on the object you want to transfer ownership of

thorny kindle
#

whatever you want, but that object should have udonbehaviour with ownrtransfrd

honest lance
#

and ownership is only relevant to synced objects (a.k.a objects with udon behaviour or an objectsync component)

lean silo
#

like if I wanted to sync the text, it would be the text object

#

so I should add object sync to the text then

thorny kindle
#

you can have empty with udonbehav, with reference to text component on another object, etc
and assign owner to that empty
or on object with text udonvehav

honest lance
#

objectsync just syncs the position, rotation and scale

lean silo
#

gotcha empty udonbehav

#

so if I do on interact SetOwner of local player to the text object like this

#

and I reference the text object in script which is RacerName

#

and the text have this

#

gotchaaa

honest lance
#

no

lean silo
#

no?

honest lance
#

what you want is to do setOwner on the udonbehaviour itself. and that udonbehaviour then does on ownership transfer: set text to displayname of new owner

lean silo
#

gotcha so this and then when the ownership is transferred I just set the text got it ty!

honest lance
#

yep. because the text panel cares not who owns it. it just displays a preset text to whoever looks at it

lean silo
#

so then out of curiosity

#

when doing player.displayerName; that just deals with the new owner right?

honest lance
#

on ownership transferred does not pass you the new owner. but since it fires after ownership was transferred, you can just getOwner on the gameobject the udon behaviour is on to get the VRCPlayerApi of the new owner

lean silo
#

guessing since it's player api it's just

honest lance
#

should be

thorny kindle
# lean silo kinda new to networking, trying to figure out the best way I can grab a players ...

another way if i wrote everything right ```CSharp
public string PlayerNameProperty
{
get => playerName;
set
{
playerName = value;
ChangeText();
}
}

[UdonSynced] [FieldChangeCallback(nameof(PlayerNameProperty))] public string playerName;

public Text UIText;

public void SetOwner()
{
Networking.SetOwner(Networking.LocalPlayer, gameObject);
playerName = Networking.LocalPlayer.displayName;
RequestSerialization();
}

private void ChangeText() => UIText.text = PlayerNameProperty;

should be `[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]` and on ui button you call SetOwner function ![vrcCatThink](https://cdn.discordapp.com/emojis/784264661410381835.webp?size=128 "vrcCatThink")
lean silo
#

so this should work no?

#

it doesn't run on ownership transferred for myself? not sure about others

#

do I have to do a delay or do the variable change locally?

north mountain
#

well depents on what you want to happen, i assume this is a manual sync udon behaviour

lean silo
#

yeah it is

#

well basically I want to make it so someone clicks on it, it grabs their name and sets the name to a text

north mountain
#

so OnOwnershipTransfered, is a bit of a weird event, i think it only fires for a certain people not everyone

lean silo
#

it works fine if I move the

#

Namestring = Networking.GetOwner(gameObject).displayName;
Nametext.text = Namestring;

#

into OnInteract

#

but wasn't working for me when it was under OnOwnershipTransfered

north mountain
#

Also if you are already the owner of the object because you loaded into the world first, i dont think OnOwnershipTransfered triggers

lean silo
#

ohhh darn

#

how could I make it work for me then if that were to happen?

#

besides getting someone else to click it first then I click it again

#

I mean I could do like check if they are owner already and if they are run what's inside OnOwnershipTransferred right?

north mountain
#

I think if you do GetOwner inside OnOwnershipTransfered you probly get the same player as the in the playerapi paramater as its already transafered

#

but not 100% sure on that i rare work with OnOwnershipTransfered events myzelf

lean silo
#

wouldn't this fix it?

#

the else if I added

north mountain
#

what i would recommend it is adding synched variable of type string, like currentOwner
then in OnInteract(),

if your not the owner, claim it and set currentOwner = Networking.localPlayer.ToString() then request serialisation and then directly call OnDeserialisation()

Then implement OnDeserialisation() like set Nametext.Text = currentOwner

north mountain
#

if in your example NameString is a sycnhed udon variable, then you need to call RequestSerialisation() after you change it, and you change it after you claimed ownership

lean silo
#

ah so I should also call it after

#

here

north mountain
#

i think you should move away from the OnOwnershipTransfered

#

RequestSerialisation only works if you are the owner (or if you ran SetOwner to Networking.LocalPlayer)

lean silo
#

so like in this pic for example

#

I could put it with the if networking.isOwner

#

bc it changes it and it's the owner

north mountain
#

yes i think so

lean silo
#

and then for On Deserialization

north mountain
#

So OnDeserialisaiton() get called when a synched variable was send to other clients
So thats where you use the value of the synched variable and assign it where you want it, so in your case
Nametext.text = Namestring (assuming Namestring is a synched variabe)

lean silo
#

yep it is cool so I got that already

#

also

#

would the OnOwnershipTransferred have a issue if I don't use request serialisation?

#

bc for example

#

actually

#

nvm

jade mesa
#

@lean silo here is how I would do it, syntax might not be 100% since I wrote it in a notepad lol

public class ChangeTextViaSync : ... {

    // The currently displayed playerId
    [UdonSynced]
    public int playerId;

    public string textFormat = "My name is {0}";

    public void ChangeText() {
        var me = Networking.LocalPlayer;
        if (playerId == me.playerId) {
            // No need to sync playerId since it's already set to us.
            return;
        }

        // Change owner to self
        Networking.SetOwner(me, gameObject);
        
        // Set data and sync
        playerId = me.playerId;
        RequestSerialization();

        // Update text for new owner
        UpdateText();
    }

    public override void OnDeserialisation() {
        // Update text for late joiners and when ChangeText() is called.
        UpdateText();
    }

    private void UpdateText() {
        var player = VRCPlayerApi.GetPlayerById(playerId);
        if (!Utilities.IsValid(player)) {
            // Handle unknown player
            return;
        }

        var text = String.Format(textFormat, player.displayName);
        // Do things with text here, like setting an UI.
    }
}

slender kettle
#

notepad, the ide of champions

#

personally i use google docs, but hey, notepad works if you have no connection

strange token
#

I feel like you could write better in discord itself because you can get syntax highlighting

mortal sundial
#

Hey if someone can help point me in the correct direction/methods I need to use for this networking issue. I have candles and a candalabra. All the gameobjects have a VRC Object Sync component. So all players can move them. The canadalabra has a hitbox trigger on each candlestick, and if a user lets go of a candle in the candle stick, the candle teleports to the correct location and becomes a child of the candalabra (inserting the candle into the slot).

In single player it worked great. When the world went live, it had networking issues wherein the new players didn't have the candle childed.

Is there an event/method in Udon that would allow me to pass a transform to all players to specify it as a gameobject's parent? I'm building this with U# if that makes any difference. Thanks a lot for any advice!

wild ore
#

that doesnt sound good because network is dependent on the scene hierachy. By parenting the transformation you are changing the network hierachy, causing desyncs

#

it might be better to just not change the parenting and do the transformation manually

mortal sundial
#

You mean just update the position + rotation every frame without childing the object?

wild ore
#

yeah

#

but im not an expert on networking so I can't say if its possible to do parenting. But in VRChat you get desyncs if you upload a world with different hierarchy from the previous version.

#

a world stays in sync with it's previous version as long as it has the same scene hierarchy, so preserving the hierarchy is super important.

mortal sundial
#

Hmm

#

So that leads me to my other question, in Udon is it possible to pass parameters to networking events?

wild ore
#

you are not using udonsharp arent you?

mortal sundial
#

I am.

#

If I want the candle attached to a particular candlestick, I want to be able to specify that candlestick's transform in an event to inform all players it's attached.

#

Unless there's a better method of doing that.

wild ore
#

from what I feel, i think it is necessary to assign each candle an ID, and during the attaching, pass the ID to everyone

mortal sundial
#

I can do that.

#

Udon events allow passing an ID?

#

This is my first VRC map, so while I have a lot of fullstack developer experience, I don't know what can/can't be done with VRC.

wild ore
#

that doesnt seem possible, but i can expect you can add a "int ParentID" and initialize it to -1 when there's no parent

#

and when its parented, change that ParentID and call RequestSerialization

#

so in the FixedUpdate loop, if the ParentID is not -1, change the transformation.

mortal sundial
#

Mmm yeah that'd work.

wild ore
#

yeah sadly i feel this is the only way to do it since networking is dependent on hierachy

mortal sundial
#

I'll download the udon networking package to see what samples they provide.

wild ore
#
  1. Have a UdonSynced int ParentID, initialized to -1. Use Manual Sync for the fastest update.
  2. When a player move the candle, set the candle's owner to that player.
  3. When that player attaches to a slot, change ParentID to that slot and call RequestSerialization() to sync variables. This causes all other players' candle's ParentID to get synced.
  4. Update the transformation in the update loop based on the ParentID.
#

if this helps, this is pretty much what you need to do to get this to work!

mortal sundial
#

That is exactly what I needed to hear! 😄

rocky spindle
#

Could also do an area trigger over the candelabra holder areas, and when detecting on drop of a candle, toggle off the pickup and toggle on a stationary one already fitted to that slot ?

mortal sundial
wild ore
#

(ops actually i think you'll need continuous sync since there's also position syncing)

mortal sundial
#

I may be able to do a hybrid of your two methods, keeping the candles synchronized using k0sm0s' method but showing/hiding the visuals using Fooma's.

#

That would mean when a player is wooshing the candalabra around, the non-interactable candles would move with it flawlessly while there will still be a real invisible one tracked underneath it the player can interact with.

#

Ok now I'm excited for work to be done with so I can try all this...

rocky spindle
# mortal sundial Ok now I'm excited for work to be done with so I can try all this...

https://buildsoft.booth.pm/items/3159749 check out this grid snap system, it sounds a lot like what you want to do

[説明] CAD、そんな感じ 現在は点グリッド・線グリッドをサポート グリッドを高速で振るとオブジェクトが離れますが、仕様です。 [導入方法] UdonSharp の最新版が import されているプロジェクトに導入してください。 https://github.com/MerlinVR/UdonSharp/releases [利用規約] 改造OK VRChat での利用OK 改造・無改造にかかわらず、無償での再配布OK。 改造・無改造にかかわらず、有償での再配布はNG。 ただし、他の創作物の一部として同封する場合に限り、クレジットを表記した上で有償での再配布を認めます。

mortal sundial
azure crane
#

you could have invisible candles already in place and enable them based on a synced array
one index/element for each candle
getting close to the slot will then snap

dusk marlin
#

Dipping my pinkie into some territory I thought I had mastered before, but am having strange issues so here I am. xD

I'm trying to figure out what the best method is for detecting on a specific udon script that it's owner has left the world. OnOwnershipTransferred was how I thought it worked, but I'm having some strange issues with it.

celest mesa
#

Can I send a serialization request to another Udon script from one that is set to a Sync Method of None and have it go out to all players? (Ie; push button, tell other script it needs to sync for all players) Or does it need at least Manual sync so the serialization request goes out to all players rather than just the local?

lone zealot
celest mesa
#

Cool, I thought it'd work something like that but just wanted to make sure.

marble night
#

[UdonSynced] [SerializeField] int PlayerID; //not syncing?
why does this return different values on my two clients?

#
 public override void Interact()
    {
        PlayerID = Networking.LocalPlayer.playerId;
//        Hair.SetActive(false);
//        LocalHair.SetActive(true);
        SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, "SetTransformVars");

    }

    public void SetTransformVars()
    {
        Debug.LogError(PlayerID);
        Player = VRCPlayerApi.GetPlayerById(PlayerID);
        Go = true;
//    }

    void Update()
//    {
//        if (Go == true)
//        {
//            Hips.position = //Player.GetBonePosition(HumanBodyBones.Hips);

azure crane
#

is this manual sync?

marble night
#

no

#

continuous

azure crane
#

i really would just switch it over to manual sync and do that

marble night
#

if i set it to manual, i have to do RequestSerialization(); before the debug line?

azure crane
#

your code is a bit of a mystery to me
with manual sync, you need to be owner of the behaviour you want to sync, then request, and you can do everything inside OnDeserilization instead of a custom networked event

#

right now, you won't even know if continuous will sync before the event arrives

marble night
#

indeed

#

oh that kinda makes sense

#

il have a do 😛 cheers

azure crane
#

good luck

marble night
#

perfect, got it working first try, not something i say aften lol

#
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class TakeOver : UdonSharpBehaviour
{
    
    [SerializeField] Transform Hips;
    [SerializeField] bool Go;
    [UdonSynced] [SerializeField] int PlayerID;
    [SerializeField] VRCPlayerApi Player;

    public override void Interact() //interact with object
    {
        Networking.SetOwner(Networking.LocalPlayer, this.gameObject);
        PlayerID = Networking.LocalPlayer.playerId; //get player ID who selected button
        RequestSerialization();
        Player = Networking.LocalPlayer; //get player who selected button FOR LOCAL PLAYER
        Go = true; //start update loop FOR LOCAL PLAYER
    }

    public override void OnDeserialization()
    {
        Debug.LogError(PlayerID);
        Player = VRCPlayerApi.GetPlayerById(PlayerID); //get player who selected button FOR ALL PLAYERS (except local?)
        Go = true; //start update loop FOR ALL PLAYERS (except local?)
    }

    void Update()
    {
        if (Go == true)
        {
            Hips.position = Player.GetBonePosition(HumanBodyBones.Hips); //set position of object every update tick
        }
    }

}
``` here the code if your intrested at all lol
mossy ruin
#

just wondering, if you try to claim ownership of an object under heavy network stress, will it evently transfer or is there a chance the attempt will fail?

frozen igloo
#

it will eventually transfer

#

if only one player is trying to take it you can be pretty confident that it'll go through even under the heaviest situation. But if multiple people try to take it, there's no guarantee what order things will happen so they may get mixed up

#

it should still eventually stabilize but hard to say what variables will get through to other players

mossy ruin
#

ok thats good to know, i didnt know if i had to do a retry or not

frozen igloo
#

it's pretty safe to assume that given enough time to deal with latency, everyone will agree on who the owner is

#

but it is not safe to assume that messages arrive in the correct order

#

so it can be good to retry synced variables

warped ore
#

I need help with teleportation. I'm trying to teleport users to a specified location with whitelist. IS anything wrong in this code

#

Hefner is the gameobject, Players is the array with whitelisted players that are allowed to use the teleport function and selectedPlayer is a VRCPlayerApi of the player that should be teleported

azure crane
warped ore
obtuse echo
#

So you would send that message to the client, who then teleports itself locally.

warped ore
warped ore
#

I've got this right now, am I doing something wrong?

#

I can teleport myself but I can not teleport other players

strange oriole
#

so you want to teleport a specific player, but only if they are on a whitelist ?

#

or you only want to teleport a selected player if the person initiating the teleport is on a whitelist ?

warped ore
#

I want to teleport a specific player but only a whitelisted player can use the teleport function

#

second one you wrote

strange oriole
#

how is selected player set ?

warped ore
#

selectedPlayer is an playerAPI that gets set from a playerlist

strange oriole
#

you need to sync which player should be teleported

#

(sync the playerid )

mossy ruin
#

got another question, on the OnPlayerLeft event, the player returned, is it possible checking its display name could result in an error? I have an instance which im trying to narrow down where the code crashed during when a player left it broke on VRCSDKBaseVRCPlayerApi.__get_displayName__SystemString, and im curious if that could be a breaking point

warped ore
#

sync the playerid, hmmm. Alright. I'll google some to see how I do that

strange oriole
#
[UdonSynced]
public int _playerIdToTeleport = -1;

override void OnDeserialization(){
if(Networking:Localplayer.playerId == _playerIdToTeleport)  
     _Teleport();
}
#

oh also, i am not sure, but i think if you put an underscore in front of your method it cant be called over the network

warped ore
#

ooooooooooh

mossy ruin
#

so looking at my debugger, i can say for a fact it broke calling player.displayName from the OnPlayerLeft(VRCPlayerApi player) event, im wondering if this is a bug

warped ore
#

@strange oriole thank you for all the help but it still doesn't work 😦 Feelsbad

warped ore
#

I still can only teleport myself

#
public override void OnDeserialization()
    {

        if (Networking.LocalPlayer.playerId == playerIdToTeleport)
        {
            Teleport();
        }
    }



public void Teleport()
    {
            foreach (string _str in Players)
            {
                if (Networking.LocalPlayer.displayName == _str)
                {
                    playerIdToTeleport = selectedPlayer.playerId;
                    SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, "Teleportation");                        
                }
            }
}

public void Teleportation()
    {
        if(Networking.LocalPlayer.playerId == playerIdToTeleport) {
            Networking.LocalPlayer.TeleportTo(Hefner.transform.position, Hefner.transform.rotation);
        }
    }
#

That's what I got. I can still only teleport myself :/

mossy ruin
warped ore
#

I'm pretty sure that's what I'm doing with that code

#

I send an event to the entire lobby and if their playerid matches the one I want to teleport it calls: Networking.LocalPlayer.TeleportTo(Hefner.transform.position, Hefner.transform.rotation);

obtuse echo
warped ore
obtuse echo
mossy ruin
mossy ruin
#

although i dont know if it will work 100% of the time, as it might get a cass of null == null

obtuse echo
#

No idea if there is a better way.

mortal sundial
warped ore
#

im hella drunk

strange oriole
lone zealot
azure crane
#

not really must be the next Update call, as mentioned before, sending a delayed event is fine and will teleport without needing Update, since Update can have an overhead

lone zealot
warped ore
#

Thank you all for the help! I'll take a look at in a few and see if I can figure it out. Such a nice community in here tbh. Thank u thank uuuu 😄

azure crane
lone zealot
mortal sundial
#

Hey I was just wondering if there's any tools to facilitate debugging network issues? Something that allows me to check who currently has ownership or the state of a variable on each client?

warped ore
azure crane
#

you can also use nameof() on udon methods to generate strings of them, prevents typos

warped ore
#

I'm pretty sure I must have it without _ or else I can not use it in

azure crane
#

you can, but you cannot do a networked custom event

warped ore
#

oh, alright

#

wait, so that event isn't networked? so I can't use that event to teleport somebody with (the delayed event)

azure crane
#

no, there is a different function with a networked word in the name
who is calling this? the remote player?

#

is this in Deserialization?

#

should add logs
check if the function is called
who is the user and what ids they have and need to have

warped ore
#

Okay so, a whitelisted user, can select players from a playerlist. When a player is selected it saves their playerid in a synced variable. Then it calls Teleport when the whitelisted user presses a teleport button

#

and teleport sends the event with Teleportation

#

I had the same code yesterday but used the networked event instead and I could only teleport myself. I could not teleport other users

azure crane
#

let the selection set the id,
the button requests serialisation,
users check in OnDeserialization if the id matches, then issue the delayed teleport

#

ensure the user clicking the button owns the gameobject with the udon behaviour or sets the ownership otherwise

warped ore
#

so basically all I have to do is add: RequestSerialization(); in my teleport function?

#

and move the send customevent to the desrializaiton

strange oriole
#

Teleports a player by name. I tested it and you don't seem to need to offset teleportation by a frame.

warped ore
#

it works but, yeah 😂

strange oriole
#

it teleports them to _taretTransform

#

also I forgot to set owner

warped ore
#

nah

#

I teleport to a gameobject I have

#

I can teleport to the game object with my keypad

#

but when i teleport someone they fly into a wall

#

It's funny as hell but not really what I'm looking for hahaha

strange oriole
#

ah, that might be that issue Helper was talking about then

warped ore
#

Maybe this is why you need to delay it

strange oriole
#

try this then

warped ore
#

good thing I saved my teleportation method

#

yep, that works much better

#

Finally!

warped ore
strange oriole
#

👍

warped ore
#

I just had a weird bug that my friend that I teleported got teleported twice. It might've been cause someone else joined right after they were teleported. I'll have to do some testing on it

strange oriole
#

yes, this happens cause OnDeserialization get's called when a player joines

#

gimme a sec ill fix it

#

@warped ore here you go, a beautiful bit flag to fix it

warped ore
strange oriole
#

yes

warped ore
#

oooh, now I see

strange oriole
#

(it might actually be okay inside, but i havent tested that)

warped ore
#

I was just gonna put it inside and everytime it when inside the IF statment it just reset the playerid to -1 and use the check Utilities.IsValid(VRCPlayerApi.GetPlayerById(playerIdToTeleport))

strange oriole
#

yeah, i guess resetting it to -1 would work too. Would be a little more network usage, but negligible

warped ore
#

If using bitflags is better I'll just use the code u sent. I've never read about bitflags tho. Might read a bit about them now

floral oasis
#
mortal sundial
#

For now I'm managing using Debug.Log but if I can get a breakpoint working that'd be rad.

floral oasis
#

There is this but I haven’t really played with it yet …

mortal sundial
#

Ah girl you're amazing. Thank you so much! 😄

#

Another day at work just fantasizing about getting home and working on VRC stuff again~~~

magic hornet
#

Hewo, there is a way to get the player API (local) when you click on a button sending the "interact" event in udon ?

I Was trying to use "Get LocalPlayer" for edit the Voice Gain/Distance, but looks like the udon component crash when the event interact trigger the udon script

frozen igloo
magic hornet
#

Hmm... Okay i see, i'll put some times on it so ^^"

modern ocean
#

I have some boulders that i want to be destructible if the player that enters their trigger at a certain speed
I want it to either be clientside so each player needs to break their own, or synced where the boulder breaks if anyone touches it, but right now it just desyncs and the boulder breaks for the first to hit it but noone else

modern ocean
modern ocean
#

text sets for one player, is ignored by the other
does setowner disable the script for local players entering a trigger?

wild ore
modern ocean
#

it kindof works now
it just runs a network synced bool and im not bothering with clientside anymore

wild ore
modern ocean
mossy ruin
#

so wanted to verify something. Does the owner of the object need to call RequestSerialization() on a manual object the same frame as the object changed? I saw there was a recommendation that you change the value in PreSerialization but ive been able to change a value and then request serialization with no issue, tho as of late im seeing a weird error when I RequestSerilization some frames later when the network isnt clogged:
ERROR: [Behaviour] Caught ArgumentNullException: Value cannot be null

azure crane
#

does not matter when you call it, all RequestSerialization does is requesting the network system to send the data to the remote players, you can request the serialisation and then still change values, they also may be sent, as the network sending does not happen instantly nor will it prevent changes

#

your error often refers to a method/function being used incorrectly, is that the full error?

lone zealot
# azure crane does not matter when you call it, all `RequestSerialization` does is requesting ...

It does not request anything. It sets a flag. The network handler has an internal timing for when it serialize the data. If the flag is not set it will simply skip serialization. So when you call RequestSerialization all it does, is set a flag to tell the network handle to serialize the data the next time it does. So yeah you can in fact change the value in-between calling it and the serialization actually happening.

azure crane
lone zealot
#

Well the problem is that "request" especially, in the world of apis is usually an active act where data is being sent somewhere. While this is a request, it's a rather passive one. So the potential for confusion is quite high there.

azure crane
#

i agree with you

mossy ruin
mossy ruin
#

since the only way to use the method is call RequestSerlization()

#

also should add, by changing my code to request serlization within the same frame of the code change, all my code started working as intended

#

as a reminder, this wasnt an issue of changing the data after calling RequestSerialization, this was an issue of changing the data long before calling it

#

like potentially 0.6 seconds before

frozen igloo
#

requestserialization should send all data no matter what

#

when you changed the data a long time ago, are you sure you were even the owner?

mossy ruin
#

yes, i have a system where i have my own player list that keeps track of what i call player callers. Each player caller is assigned a player where they are set to own said caller. I also have a queue of commands in a string (local only) to each player, that on a timer ever 0.2 seconds checks if the network is not clogged, and if its not, it interprets the next line in the queue. These are all intended to be actions that effect the network, one of them being RequestSerilization. When i was doing changes to certain synced values, i was changing them, then adding to the queue a command which when it ran through the system called RequestSerialization. In essence, depending on how bogged the network was, could take anywhere from milliseconds (when the timer gets called) to seconds (if the networked is bogged down and the timer tried several times). When i changed it to instead of going through this queue to call RequestSerialization to just calling it the same frame, everything started to work and properlly sync the data. I will note this method i used use to work in the past,

#

unfortunatly, ive been changing the code over the week a lot to try and optimize features on it since i need it done by tomarrow, so its not in the same state as it was before. When i get the changes working ill try to set it up to the way it was before and see if it was a fluke where i missed somthing, or indeed a problem assosiated with the timing when to seralize

mossy ruin
# frozen igloo requestserialization should send all data no matter what

oh also, wanted to ask, So if i set a value, requestSerailization, then call a networked event, is there a possibility that the event will fire off before the values are synced? so far all the code ive written, even when the system is super bogged down, the items in a manual synced object always seem to sync the values before the event triggers, which seems pretty fantastic

frozen igloo
mossy ruin
#

hmm..gonna have to note that and try to think of a better way to do networked method calls with parameters in the future

frozen igloo
#

yeah, just do stuff in OnDeserialization

mossy ruin
# frozen igloo yeah, just do stuff in OnDeserialization

I had a huge issue with that, OnDeseralization seemed to fire off when people joined, causing values I thought should be one thing end up flipping to another. So if i set a value intended as a method, the logic would fire off a second time. Maybe i can find a better way to do it but i tried my best not to use the method

#

oh, one last thing. My code for my player list worked great up till resently. I posted bout it but seemed the information tied to the returned player in OnPlayerLeft can be flawed. Had a debug log error out an udon script because calling that player was miss referenced. Know anything bout that bug?

frozen igloo
#

yeah, you can't ever rely on OnDeserialization happening just once. It is not a message system, it does not guarantee that

#

if you want to guarantee unique messages, you can simply add another variable like a timestamp and then if the timestamp hasn't changed since the last OnDeserialization, you know it's not unique

mossy ruin
#

true could do that

#

but gotta figure a way around the OnPlayerLeft bug before i work twords that optimization

frozen igloo
#

don't know about that, but at the same time OnPlayerLeft implicitly tells you that player left so can't you just manually invalidate them, remove them from your array, whatever?

mossy ruin
#

if the returned value is null, how do i know who left?

#

ooo you mean go through my list and verify who isnt valid anymore

#

ya, that could work

frozen igloo
#

no, you can do comparisons in onplayerleft

#

go through your array and check if it matches the player that left

mossy ruin
#

i was doing that, and i dont get a match

frozen igloo
#

hm, I've been doing that since before getplayers was a thing and it worked

mossy ruin
#

this is with each of my object containing a VRCPlayerAPI of said player, and doing a player == player comparison

#

thats what boggled me

#

it was working before, so i was wondering if somthing changed that broke the reference

#

do you do a .Equals or a ==?

#

ill also need to triple check i dont have anything unsetting my player

azure crane
#

there is an obscure bug that if you never reference a player (eg upon join), they may have a bad player id when the player leaves

mossy ruin
#

seems that bug does extend to their display name, i tagged that onto the canny that i saw related to that bug

#

btw, i just found that indeed my code was unsetting my reference to the player before onPlayerLeft event fired off. I now have it set it up it wont do that

sacred geode
#

What's UDON?

haughty shuttle
sacred geode
#

Ohhhh

#

I see.

#

Thanks.

#

So, basically Java for VRCHAT?

haughty shuttle
#

More like C# in a Bolt format. Even more like C# if using UdonSharp. But unity supports various languages so it doesnt matter as long as you convert it to Udon.

warped ore
#

Ayyy, I'm back with another question. So I got this spinner from a drinking game but sometimes it decides to either stop spinning at all or land at the same location every spin. Is there something wrong inside of this code? I'm not really sure what it could be.

haughty shuttle
#

SyncSpeen is sent by/to owner but no where do you actually set an owner. I guess technically the instance master is the owner but if you are looking for dependable then the person interacting should be the owner.

strange oriole
#

Interact should probably call Speen, and not SyncSpeen

#

also if manual synced you need to call request serialization

#

no owner setting needed since the synced var is set by the owner via network event

rugged marsh
#

Been trying to find some clarification in the docs with no luck, but I assume using _Underscore() method names to block malicious network event calls is only necessary for public methods? Or do they somehow have access to private ones too?

I've seen people using them for variable names too which is also throwing me off, just trying to figure out what all I need to actually worry about renaming.

frozen igloo
#

and putting an underscore in front of a private variable is just common code styling, it doesn't do anything functionally

rugged marsh
rugged marsh
# strange oriole

Thanks yea I saw that but it didn't specify private/public and I hadn't thought of the graph/# distinction. Makes sense now.

frozen igloo
#

to clarify: making it a private function is still valid. And an underscore is not necessary in that case

strange oriole
#

ah, okay, i missed that distinction (in the question)

frozen igloo
#

it's even safer than underscore because modded clients can't even call it on their own machine, let alone others

zealous patio
#

always use underscore if you attend the event to be local only at all times

lone zealot
golden wyvern
#

simple button that spawns from pool. For some reason only instance owner can spawn. Is vrchat checking owner by default?

frozen igloo
golden wyvern
#

Thank you ❤️

dusk steeple
#

How can I make an object sync their position over the network. I have the VRC Object Sync script on it. But when I spawn it. it just kinda freezes position on the NON master clients: (Master Client on right) I want it to fall. It has Rigidbody and I spawn the cube using VRCInstantiate

golden wyvern
dusk steeple
#

:I let's not talk about my stoopidity 🙃

dusk steeple
#

Wait so do I still need to call it from a SendCustomNetworkEvent for it to spawn on EVERY client though 👀

vast agate
#

I can get it to spawn on join and go to their hip bone, but no luck making it follow them.

dusk steeple
#

Yes I want something like that. So I want an object to "spawn" (Grabbed from the pool) than it goes from point a to b after x amount of time

vast agate
#

hmmm

#

Delayed events maybe

#

or use the timer thing they have in the SDK example

celest mesa
#

What's your object actually going to do while tethered to the player? Is it something only they need or needs to talk to other instances of itself on other players?

stray galleon
#

i need the udonsharp form merlin fr the 2019. i think its 2021.3 or something

haughty shuttle
#

that is the current version

#

you do not need or want an older version unless using an outdated sdk in which case your on your own

stray galleon
#

im having an error where it says its missing ascript of vrc. its cs0234 and cs0236 and i put the newest vrcsdk3 in FIRST

#

also thats for the 2018. im using 2019 and there is a 404 error when i click on the upgrading

haughty shuttle
#

no its current. Dont pay attention to the 2018 bs. readme needs update

stray galleon
#

Ok but im still getting the cs error even for my world now with that version

haughty shuttle
#

Show your errors

vernal arch
dusk steeple
#

I will be honest XR I can't remember anymore 👀

#

I kinda stopped making VRChat worlds imma just focus on actual game development and bot development. My brain is too smoll for VRChat worlds

cyan trench
#

Can someone join me right now so I can test object sync if its working for late joiners?

sharp solstice
#

One way to test it yourself is to enable 'Go' on load & start multiple test clients via Unity

cyan trench
#

All my clients loaded at the same time

#

So does not really help

#

unless there is a way to intentionally block one from joining until im ready, regardless it does not work

#

if anyone knows how vrc udon networking works can i get help making the state of an object to sync with late joiners

vestal radish
#

Disable "skip go button" in settings, thus you can enter the instance late

rugged marsh
cyan trench
#

u replied to me but talk to someone else?

rugged marsh
#

The response was for both of you, so yea.

cyan trench
#

Matswaps in worlds a thing or no

haughty shuttle
#

yup define new_Material GetComponent<MeshRenderer>().material = new_Material;

cyan trench
#

nice, thank you

#

why did i put that in networking lol

celest mesa
#

Just want to double-check; Is this an ideal/optimized use case for a Manual Udon script? Bool value stays largely unchanged, only toggles when object enters detection cube.

azure crane
celest mesa
#

Cheers, I haven't messed with Manual sync much.

sharp tinsel
#

Quick question: Will the OnDeserialization() still being called if it's set to Continues syncing?

frozen igloo
#

yes

sharp tinsel
fresh stump
#

What's the max data send rate for manual sync?

frozen igloo
outer harbor
#

are fast paste pvp maps do able on udon or am i going to run into network problems and limits with udon?

azure crane
#

you are likely going to run into ping/latency issues instead
vrchat has no networking engineered towards fast pace pvp

#

nor any special internal routing like some games offer

celest mesa
#

Got a general networking question; I'm looking at the debug screens in-game and I'm noticing that network hitches is constantly increasing for players who aren't the world owner. Is that normal, or do I need to go bug hunting to find what's causing that?

outer harbor
#

@sharp tinsel could i dm you to ask you some stuff i saw your ghost world

fresh stump
#

How to enforce ownership

#

Should I check If (I'm not owner): Set me as owner
In Update ()
Or in LateUpdate()

Does it matter?

azure crane
sharp tinsel
outer harbor
sharp tinsel
#

oh, hahah

golden wyvern
#

is get players with tag still broken?

azure crane
real fractal
#

Seems pretty much anything could go either way

haughty shuttle
#

If you are safe you can use either one. Animations are updated per frame every frame so when they are not in use you deactivate them. You won't find many tutorials that explain that though. I'm old school, I script almost everything, and just like Animations, if you are lazy with your scripts you can tax your performance as well. So basically it's just "you do you".

#

if you need a specific situation it would be networking. If something needs tracked for sync you are better off scripting it for now. object sync will in time cover Animations I am sure but for now, those should be scripted.

fresh stump
#

How can I stop this cyan trigger from teleporting other players along with me? Doesn't seem to be completely local in game (edit: just switched the first tab to VRC_Direct instead of Local player after reading the manual, hopefully that works)

wooden sentinel
fresh stump
wooden sentinel
#

If you need further help, Cyan got official support discord at "JHA3ZQ5mXM" as well.

cursive ember
#

is there an overlay i can enable somewhere to see the synced variables of an object?

wooden sentinel
ivory gorge
#

Apologies if I'm miss-reading your question (or if you've already solved it by now), but isn't this because your not breaking it down when you search? When finding a node, you first find the component type and then you say what with said component. In terms of VideoPlayer.get IsPlaying node, you would first search up 'videoplayer', selected it, and then search up 'get isplaying'. You can't search up 'videoplayer.getisplaying' as a whole in the search, you have to search in two parts

#

Sorry for the ping then. Just that your image didn't show so I though I better check

frozen igloo
#

try using tab to do a full search instead. It will be slower, but it will give you absolutely everything without having to go inside a directory

dusk shuttle
#

Hi. I'm currently trying to create a vehicle switcher for Sacchan's Flight and Vehicles prefab. Locally, things work perfectly fine, but I'm having issues getting the owner of the buttons to change. So far, I've gotten it (mostly) working, however there are some issues.

#

This graph is applied to all "Toggle" buttons

#

This graph is in the "Script", which is the sort of main control for the selector. This is the only networking related part. The reason I have it doing the same thing on the request and transfer is because non-owners were having to press the button twice. (I haven't tested if this even works yet, so just pretend the request part doesn't exist for now).

#

"selectedHeli" is a synced variable, while "tempSelectedHeli" isn't synced

#

There are many issues with the selector, for example, it will select a seemingly random helicopter on the first ownership change

obtuse echo
dusk shuttle
#

I tried that before, and it refused to set the owner

#

This way actually works at the very least

#

It's just extremely buggy

#

It seems to select a random helicopter on first ownership transfer

obtuse echo
#

Is selectedHeli manual synced?

dusk shuttle
#

Yep

obtuse echo
#

Then you have to do RequestSerialization to propagate it to everyone else.

dusk shuttle
#

Ah okay, that will probably solve all of my problems then

obtuse echo
#

Yeah, try doing Interact -> SetOwner -> set selectedHeli -> RequestSerialization, then should already do what you want. Then you call OnDeserialization and execute the actual heli change.

dusk shuttle
#

The actual heli change is all local and happens on update, it's just listening for the synced variable which is used to define an entry in an array

obtuse echo
dusk shuttle
#

Right but what about late joiners

obtuse echo
#

So you can save yourself some frames.

#

That works too.

#

They receive OnDeserialization when they join.

dusk shuttle
#

Oh that's neat

#

I'll replace update with that then, it should automatically work

obtuse echo
dusk shuttle
frozen igloo
#

do you have a VRCUIShape on the canvas?

#

then you don't need to worry about that, because that script will assign the event camera

#

so when you point at the UI, does the laser show up?

#

what layer is this on?

#

put it on default

#

UI is for internal stuff, not world things

frozen igloo
#

Are you getting any errors in your log?

#

add some debug logs to see how far the code is getting and what it's doing

#

add a new node, search for debug

#

yes

#

and then add a string const node to plug into the debug log

#

place these wherever things happen so that you can later look at your log and make sure things happen when you expect them to

frozen igloo
#

that's not necessary, don't worry about it

heavy spindle
#

If a Client wants update a networked value of a program, do I have to transfer ownership first

strange gyro
#

The client who is updating the synced variable must be the owner of the object, so yes

left lagoon
#

IS there anyone around that can help me test performance

heavy spindle
#

is there a way for custom events to call methods with arbitrary parameters?

frozen igloo
#

no

#

there are many alternatives, though. If you give more details about what you're trying to do I could recommend an alternative

heavy spindle
#

I want Clients to be authoritive in adding themselves to a VRCPlayerApi[] which represents the players in the game I am developing

frozen igloo
#

ah, like a "I want to join red team" kinda thing?

heavy spindle
#

Yeah

#

but I can't deduce how to get a player's ID unless the event includes that

frozen igloo
#

Easiest way would be to simply take ownership of an object, change the array, and then sync it as an int array. Realistically, manual sync is fast enough that it might work even if two people click it at the same time, as long as you're not using OnOwnershipRequest

heavy spindle
#

I was hoping to avoid taking ownership of the manager since hypothetically, 22 people could be wanting to join at the exact same time

frozen igloo
#

if that's not acceptable because you expect a large number of players to sign up very quickly, the more robust but complicated option would be to give a unique object to every player

#

and usually in a game, it's very useful to have a unique object per player for many other reasons anyway

heavy spindle
#

I'll probably go with that. Is there a way to properly make a relation between an arbitrary value and a player where programs can access it?

#

Oh. Wow

frozen igloo
#

yeah, just grab their playerid

#

playerids are gauranteed to be unique

heavy spindle
#

even in test mode?

frozen igloo
#

yes

#

they start at 1 and increase by 1 every time a player joins

heavy spindle
#

I see. That's handy

#

Thank you for the advice. My work around would have been the physics host being authoritive in determining who's on what team, but I don't want to network what I don't have to

#

working with Arrays is also jank since I'm coming from JS which is very high level

left lagoon
#

I need help setting up some simple actions that look for any player in an instance pressing a keyboard key and triggering an action. I've tried it with Cyantrigger but it seems that using simple if statements for checking 20 different keypresses across everyone in the world fudges frames. I dont know a better way of doing this or how to check this locally and send the event to everyone else...

frozen igloo
#

could you clarify what you mean by "fudging frames"?

frail fog
#

I forgot how to do simple networking stuff

#

is there anyone i could DM my code example for some advice?

dusk shuttle
#

Is there a way to make it so OnOwnershipTransferred doesn't call when the master leaves and a new master is chosen?

#

My method for sort of "bypassing" this right now is this, but I can see this being an issue that will require the master to press the button twice to actually change the variable

#

Right now, when the master leaves, all the helicopters in my world get set to whichever one the new master last chose, which kicks people out of their helicopters

obtuse echo
obtuse echo
dusk shuttle
#

So basically store all the variables and when the master leaves, send it to the new master?

dusk shuttle
#

They have to first take ownership of the script so they are able to change the variable

obtuse echo
dusk shuttle
#

Hmm you might have a point actually lol

#

Idk how it works tbh

#

There's no good documentation anywhere about how it all works

#

I was told by someone that it takes time to take ownership of something so I should use OnOwnershipTransferred

#

Changing a synced variable requires ownership of the behaviour object, does it not?

obtuse echo
#

It does require ownership, however, if you call RequestSerialization after SetOwner, it should arrive properly.

#

This has worked for me so far.

dusk shuttle
#

Even if it's in two different behaviours?

#

Basically, the OnOwnershipTransferred part happens in the button graph, and the requestserialization happens in the main graph

obtuse echo
# dusk shuttle

Ahh, I think I understand now. Sorry, graph is a bit hard to read for me sometimes. It's also a bit different than what I would do.

dusk shuttle
#

Yeah I should really just learn U# shouldn't I 🤣

#

If there's a way I could get around using OnOwnershipTransferred, that'd be awesome

#

Maybe I could do SetOwner in the main script? Instead of checking for owner in the button script, just send the custom event no matter what, and on the owner check in the main script, SetOwner and then RequestSerialization

obtuse echo
#

Yeah, I'd definitely use OnDeserialization for this. It will be a lot cleaner. Basically as I wrote before, literally Interact -> SetOwner of Sync object to local -> change selectedHeli on Sync object -> RequestSerialization on Sync object

dusk shuttle
#

I tried that before but it didn't work due to the multiple graph thing

obtuse echo
#

What did not work?

#

You need to use OnDeserialization event on the Sync object to catch the change after too.

dusk shuttle
#

OnDeserialization

#

It wasn't calling it

#

I even hooked it up to a debug log

obtuse echo
#

The thing is, since you are doing it cross graph, you might need to call syncObj.RequestSerialization in the button.

dusk shuttle
#

Got no response from it at all

#

What's syncObj

obtuse echo
#

Sorry, you called it syncBehavior

#

I could actually code it up for you real quick.

dusk shuttle
#

What if I did
Interact>SetProgramVariable>SendCustomNetworkEvent
in the button, and in the main script I did
CustomEvent>Branch(isOwner)>If True do>set syncedVariable to localVariable>RequestSerialization>else(If False)>SetOwner>set syncedVariable to localVariable>RequestSerialization

#

Because I'm not setting owner of the button, I'm setting owner of the main script anyways

obtuse echo
dusk shuttle
#

I'm just trying to change a synced variable in the main script using the buttons, that's all

#

The "SetProgramVariable" changes a local variable that it uses as a reference for which button was pressed basically

obtuse echo
#

I'm changing the selectedHeli in the main script, which is a synced variable, right?

dusk shuttle
#

It first changes a local variable in the main script

#

The customnetworkevent changes the synced variable into the local variable

obtuse echo
#

And instead of changing a local variable in the main script to then sync it, you can instead change the synced variable directly is what I'm saying.

dusk shuttle
#

Not from the button though, because then they'd have to take ownership of each button individually

obtuse echo
#

Hold on, I'll make a better example how I'd do it maybe it will be more clear then. (I could be misunderstanding too).

dusk shuttle
#

That's what I tried before and it didn't work

obtuse echo
obtuse echo
#

You can also use this node instead of OnDeserialization:

dusk shuttle
#

The OnDeserialization is optional, right?

obtuse echo
dusk shuttle
#

Alright

#

Everything before that is basically what I was saying

#

Except without the ownership checking branch

#

Which I didn't realize is actually not necessary

obtuse echo
# dusk shuttle Which I didn't realize is actually not necessary

Yeah, and this way it's easier to see what's going on since it's more simple.
One thing to know though, OnDeserialization is called when someone receives a change of the variable from the network, so the one who set it locally won't get it called. That's why I suggested the Change node, that one will be called every time the synced variable changes, be it from the Network or locally.

dusk shuttle
#

Ah that makes a lot of sense

#

That might be why it wasn't working for me lol. I always check with CyanEmu if it even works locally before I build and test it to see if it syncs properly

#

I'm completely new to networking stuff in general so I don't understand a lot of what's going on

#

But it's starting to make sense now

obtuse echo
obtuse echo
#

Also, don't worry, Networking can make very little sense for normal humans if you try hard enough, so better keep it simple for yourself.

dusk shuttle
#

I understand a lot of the concepts of it, but actually working with it is confusing

#

I don't understand what a lot of these words and phrases actually mean in networking, can it's hard to find any information about it

#

So this isn't working lol

#

Ownership isn't being transferred at all for some reason

#

Ah

#

It might be because local testing is weird

#

This is what it says when I try clicking on it with the other client

obtuse echo
# dusk shuttle Ah

This is intended, SetOwner gets ignored if you are already the master.

#

Everything else will continue working.

dusk shuttle
#

No

#

I'm saying

#

For the client that wasn't the owner

#

It wasn't setting the owner

#

It would say that in the console

#

I'm testing it with a second account

obtuse echo
dusk shuttle
#

One local client is master (first joined), the other isn't master and doesn't own anything unless otherwise specified

obtuse echo
#

What exactly is not working by the way?

dusk shuttle
#

Then why does the console say I already own it if it didn't own anything

dusk shuttle
#

Anytime I clicked on the button with the LOCAL user, not the master, it would give me that warning in the console

#

It claimed I already had ownership

#

My guess is it was bugging out since local testing just does that sometimes

obtuse echo
dusk shuttle
#

If I put the target on all, it'll desync

#

Because it doesn't update the local variable for everyone else

#

So it sets it to whatever THEIR local variable is

obtuse echo
#

Oh wait, I just realized it's a networked event, you don't need that.

dusk shuttle
#

Ah okay I was about to say

#

I had it on all before and I had this nightmare occuring

#

Hm

#

I have to SetOwner in the button script I just realized

#

That's why I'm having issues

#

Or

#

I need to switch the networkevent for a normal customevent

#

Because a normal customevent affects the local player

obtuse echo
#

Only the local player needs to take control over the sync and then tell everyone else what they do with it.

dusk shuttle
#

Thanks for the help again btw

#

It's working now hmm might just go ahead and drop this and see how it goes lol

thorn surge
#

I'm trying to figure out why some networking events are working for some players and not others, purely as a fact find - have there been any known cases of client modifications interfering with in-map udon events?

frozen igloo
#

could be several things. I don't think it would be a modified client unless they're specifically blocking it, which I doubt would happen on accident

thorn surge
#

Sure, that was the expected answer, thanks Phase.

frozen igloo
#

first things first - make sure everyone is on the same version of the world. If it's been updated recently, get everyone to rejoin. If there is both a quest and PC version, make sure that both versions have the same hierarchy

#

other thing might be that the scripts have crashed for some people

thorn surge
#

Ah actually thanks for mentioning that. I have been trying to test networking events through using the in-built Test feature in the API package. Are there any limitations on this? For example, if I am trying to do something by a vrcplayerapi, does it register two test clients as separate players?

frozen igloo
#

yes, local testing with multiple clients is quite reliable and I would highly recommend doing that before dragging in a bunch of people

#

the only situation that won't work is if you are checking their name, the name will be the same

thorn surge
#

Excellent, it is good to rule that out.

#

I shall puzzle on, thanks for your insight man.

junior badger
#

I correct in my understanding that OnPlayerCollision and such events fire on all clients including master?

frozen igloo
#

onplayertrigger events, yes

#

collision events are a bit different and probably not what you want

junior badger
#

Probably I testing triggers currently, and somewhere between event and variable sync something not working (silently)

junior badger
#

does Synchronization have something to do with trigger/collision detection?

frozen igloo
#

not directly

#

everyone will observe it happen because the players themselves are synced

#

but that doesn't mean the event itself is "synced" it's just that everyone observes it as a result of something that is synced

junior badger
#

i still cant trigger OnPlayerTrigger on master from client.

frozen igloo
#

what layer is the object on

junior badger
#

default

#

it works for instance owner

frozen igloo
#

does this object move?

junior badger
#

nope

frozen igloo
#

does it extend all the way to the floor or is it floating?

junior badger
#

floating

frozen igloo
#

ah, that would do it

#

there's a weird thing where remote player colliders are smaller than local colliders

#

if you were to jump they'd probably see it

junior badger
#

...

#

it worked

junior badger
#

how do i destroy object for all players?

#

Unity.Destroy destroys only local copy...

#

i thinking about sending Destroy network event and killing object in each instance. Any other way?

frozen igloo
#

Networking destroy won't work. You would need to send some kind of network event or synced variables that can tell other players what you want to do and then they all do unity destroy together

#

But of course instantiated objects can't sync so some other object would need to coordinate this and have some way of determining which object you want to deatroy

junior badger
#

will that work?

frozen igloo
#

Depends, what is destroyonhit?

junior badger
#

gameobject

#

not very intuitive i know

#

WIP XD

frozen igloo
#

No I mean where does it come from

#

Was it instantiated? Can you guarantee that it will always be valid before this point?

junior badger
#

from inspector on prefab

frozen igloo
#

What I'm getting at is that you probably want to add another isvalid when they receive the event because it may be valid on the person sending but not the receiver

#

Or perhaps two people have it valid and send the event at the same time and now it tries to destroy twice

junior badger
#

done, thanks for suggestion. hope it works

#

what about "instantiated objects can't sync"? that sounds very important

frozen igloo
#

Yeah, you cannot put synced variables or objectsync on them

#

But depending on what you're doing, you can make the actual syncing happen through an object that is not instantiated

junior badger
#

sooooo

#

this wont sync?

#

Max/CurrentHealth i mean

junior badger
#

tested it... now i get why instantiated object don't sync... they created locally only aren't they?

#

so if i want to create them everywhere i need to do in on each client separately, but then they will be different object and wont sync

#

what a pain...

#

is there a way to instantiate object so it would sync?)

frozen igloo
#

No

junior badger
#

i starting to think of just creating those objects on scene for each possible player manually....

#

and there no way to transfer actual data over network other then sync, right?

frozen igloo
#

That's the definition of sync

#

Ownership, Synced variables, and network events

junior badger
#

but they didnt say anything about instantiating working only locally! so i thought maybe they didn't tell us something actually usefull X)

frozen igloo
#

Look for cyan object pool, it assigns a unique object to each player from a pool rather than indtantiating

junior badger
golden wyvern
#

When someone spawns all available objects from pool, and someone else tries to spawn from empty, their vrchat crashes. am i doing something wrong? pretty sure its not supposed to crash people.

frozen igloo
golden wyvern
#

I do, but that code from empty test scene with simple cubes that dont have anything. still crashes

frozen igloo
#

I don't see how the code you posted could crash

golden wyvern
#

makes 2 of us

frozen igloo
#

but if you're doing anything with the object you get, make sure that you check isvalid before trying to do anything else

#

because if the pool is full, trytospawn will return null. Trying to do anything with a null object will crash

golden wyvern
#

it crashes on TryToSpawn, so there is nothing to validate

frozen igloo
#

what's the error you're getting?

golden wyvern
#

i dont have errors, just freeze and crash

frozen igloo
#

wait you're saying vrchat itself crasges?

#

wtf

golden wyvern
#

yeah, it freezes, and only way to close is to force close the window

frozen igloo
#

that sounds like it's stuck in an infinite loop

golden wyvern
#

also i wasnt able to replicate in cyanemu

frozen igloo
#

could you share a pic of the objectpool with the array expanded?

golden wyvern
#

that the test one

frozen igloo
#

hm I'm not sure how it would cause the problem you're describing, but you shouldn't have that udonbehaviour on continuous

golden wyvern
#

its not the issue

golden wyvern
#

yeah just replicated issue in completly new clean project, i guess its a bug

frozen igloo
#

upload a world and post a canny with the world

golden wyvern
#

you need 2 clients to test it though. it happens only to second person that didnt spawn original pool objects

#

ill go celebrate now, happy new year @frozen igloo and thanks for trying to help

frozen igloo
#

if you need a quick alternative though, one solution would be to send a network event to the owner and then have the owner spawn from the pool

golden wyvern
#

thanks for advice, i think there wont be an alternative anytime soon so ill use it instead

#

❤️

#

yeah dont want owner to be bombarded with network events though, its for discord events, and host will be owner of everything....

frozen igloo
#

sending a network event to the owner would be better than transferring ownership

golden wyvern
#

really? transferring ownership is that heavy on network?

#

i mean i want like 20 pools to be manged

frozen igloo
#

I mean it's all pretty cheap tbh

#

splitting hairs

#

if it was a single pool, keeping it on one owner would be better. but if you have a bunch of pools, you can distribute them to all the players so technically that might be cheaper. But the majority of the cost is going to come from the objects that are spawned from the pool, not from the pool itself. So it really doesn't matter

sharp tinsel
#

So.. my game almost always take very long to initialize sync, but it will work smoothly after the first time load, what could be the potential reason that can delay the manual sync for 1 min?

frozen igloo
sharp tinsel
frozen igloo
sharp tinsel
frozen igloo
#

two thinga: if a player joins, manual sync is resent on all objects

sharp tinsel
frozen igloo
#

and if you have a lot to send, you will be "clogged" and which will delay manual sync and slow continuous

sharp tinsel
#

🤔 if I set these object inactive when player just joined, will that help?

frozen igloo
#

not really

#

you shouldn't try to stop it, it's doing exactly what you want

#

you should instead try to reduce how much data you're sending

sharp tinsel
#

well not exactly... caz they are just empty player slot when player joined, it will only be filled later when the game start, by when I need to sync them for assigning roles and stuff.

frozen igloo
#

if you add OnPostSerialization to your manual sync objects, you can then access serializationresult.bytecount and see how expensive it is. If it's around a few thousand that's like a bit but not a ton. over 10 thousand is where it gets heavy. And the limit is 50k

#

if you're under 1000 bytes and still running into problems then it's not your fault

frozen igloo
#

is that all the objects you have?

#

are there any others?

sharp tinsel
#

vrcCatThink The only other sync object is the lobby manager, which does have a bit more data but the door will only open when it finished sync, but I can double check its sync byte count

#

well there's 20 players in total so it's going to be around a few thousand when the game start I guess.

#

It's just weird that even when there's 20 players, it really doesn't take long to sync,

#

it's just when a lot new player joins, it greatly delay the sync, like for minutes. And I removed all "OnPlayerJoined" functions still not getting any better. that's where confuses me

#

well.....

#

I think it's probably multipliying the sync request... 20 players joining at the same time ended with 20 x requests for 20 player objects and that's about 25,600 byte data to sync.

#

maybe?

sharp tinsel
#

vrcCatThink Did set all sync objects into inactive by default when the player loads in, that helps a bit, previously I was setting them into inactive after the initialization functions. Could be much easier if it supports static member.

frozen igloo
#

yeah if they've never been active once they won't sync with late joiners

sharp tinsel
#

But it still takes relatively long to do the initial sync, I just couldn't find what is causing it. Only 10 vrc object sync objects left in the scene.

frozen igloo
#

but as soon as they've been active then it doesn't matter if they're active or not, they'll always sync

sharp tinsel
frozen igloo
#

hm, I'm not sure about objectsync

#

I know manual does

sharp tinsel
#

I see, I guess it's okay in that case then, caz when player joined the game and going through that initial sync, if it's in-game, it has tons of time to sync, if it's not in-game, well, most of the guns and items will be inactive at that point.

#

oh there's only 21 manual sync objects in total in my scene. I figured it didn't help to set characters as inactive by default and enable when needed.

#

I meant I disabled many object sync objects.

#

gun pickups

#

I further compressed the byteCount for sync data of my character objects and lobby manager, now the character is at 60, and lobby manager is like 90 or something, not significant improve, but it should still help.

jade obsidian
#

Job/gig Offer: PAID, SFW

  • Looking for World Developers
  • Assets/3D designers
  • Udon programmers

Currently I'm exploring posibilities of what can be done, and looking for people to work with.

PM example of your work (and hourly rate), thank you!

ivory gorge
fresh stump
#

Can somebody help me find a militaristic tactical anime female avatar?

#

id perfer a black outfit

humble roost
frozen igloo
#

I don't think so. I'm not familiar with it but from a quick search it looks like something you have to bind/send/receive on specific ports, which is quite a bit lower-level than udon networking

Udon networking has two primary components: network events, where you just make a function happen on other clients. And synced variables, where an udonbehaviour has a list of pre-defined variables. The owner will send their values and everyone else will receive those values. Then your code can interpret what to do with them

lone zealot
#

You'd think that

#

simpler is the better word

#

not necessarily easier

atomic palm
#

Not sure if my question belongs here or in the udon-questions-channel:

I am working on a soccer game where players drive around on robots and by click, shoot the ball, if they are close to it.
It seems the synced ball only has proper collisions for the localPlayer, while other players only see an oscillating movement where the ball never hits the walls.
Is there a way to force a higher priority on corretc movement/collisions of a single object, to get it as accurate and fast as possible in the network?
The standard VRCObjectSync seems not to do the trick in my example.

azure crane
#

vrcobjectsync is really bad on fast movements, even slow movements, sadly, this was not always the case, but it happened at some point of udon, i am not sure when
it usually looks okay for the owner of the object and the eventual final position should be the same nonetheless

you can do a manual sync approach and see if that works better, but you will have to implement logic such as lerping too

fresh stump
junior badger
#

is there a way to get avatar size?

fresh stump
lone zealot
junior badger
#

Well, I mostly need current upper boundary of the head, I thought about using head bone, but head size can vary greatly between avatars, so the position of the bone in the head

fresh stump
lone zealot
fresh stump
#

I suppose its enough to do it at start & when the menu is closed

mossy ruin
#

i have a networking question wondering if anyone can answer. Does anyone know if you set a bytearray sync during on deserialization and call request serialization during a condition that prevents it from spamming, is it possible for that data to not get sent out on a manual sync behavior?

lone zealot
fresh stump
#

okay then attach a sphere with a collider to the head and ontriggerexit recalculate it

frozen igloo
fresh stump
#

or something idk figure it out your the developer

#

im just random person on internet

mossy ruin
frozen igloo
#

well if you're receiving ondeserialization then you're 100% not the owner

mossy ruin
#

so they should but ya if its not getting set then that would be bad

#

yes, tho thats not the issue here, lemme explain what im doing

#

each class is set to a player id and claimed. I have a byte array that has a timestamp, method, and parameter data that is set. Im using this to set a paramater for a player by calling their own parameter set method (which they own). Ondeseralization gets called for that object which everyone sees, and since one of the assosiated parameters is the target player, that player then sets the assosiated data for their own script, then request seralizing for others to pick up on the next on deseralize

#

but on their own object

frozen igloo
#

yeah, straight forward "hey you, gimme your data"

mossy ruin
#

ya

frozen igloo
#

just make sure to do setowner

mossy ruin
#

i want to avoid spamming it if i dont need to, ondeserlize does have an ownership check

#

so ill run a quick test to see if they arnt claiming the object yet

frozen igloo
#

ondeserialize, only setowner if your playerID matches the playerID

#

shouldn't spam anything, should just be one round trip

mossy ruin
#

yes, thats apart of my ownership check

mossy ruin
frozen igloo
#

did onpostserialization happen for the person who did requestserialization?

#

that also gives you a serializationresult so you can see if it succeeded and how many bytes it took up

mossy ruin
#

ah, it did and had a false on the result

frozen igloo
#

is this a lot of data?

mossy ruin
#

no, its a byte array with one byte

frozen igloo
#

what other synced variables are on it?

mossy ruin
#

the methodbuffer...wait

#

so it is giving this error:
caught argument excpetion: argument cant be null

frozen igloo
#

some synced empty arrays might break things

mossy ruin
#

thats...annoying

#

so, the method buffer is only ment to signal a method call, do i need to fill it with at least one byte of data?

frozen igloo
#

I think you can give it an array with length 0

mossy ruin
#

ah, i think that i can do, ill try that and see what happens

mossy ruin
fresh stump
#

If a player joins mid-game, while this get run on any variables that get synced from the server? 🙂

frozen igloo
#

yes

fresh stump
#

Awesome, thanks 🙂

fresh stump
#

If the first player / main owner leaves, and a new owner is assigned, what happens to the variables of the objects he receives ownership of?

#

Does he get the new state that the original owner had, or do the variables stay the same as when they had no ownership?

frozen igloo
#

variables will not change without you telling them to

#

the owner will send the state of the variables, and when it transfers to someone else they will have the same state

#

however if the owner sets a variable and then leaves before they've sent them, nobody will see it

fresh stump
#

ah okay. I'm used to not replicating every variable because in theory the clients don't need to know everything about the internals of a round, but in this case its very important that everyone could in theory take over the scripts right?:

#

And does that mean the game could in theory soft-lock if the owner is running a timer on an important object, but the owner leaves?

frozen igloo
#

yeah definitely

#

you can build in safeguards where if the owner leaves, it resets the round back to some default state. But it would probably be better (albeit more difficult) to make sure anyone can take over at any time

fresh stump
#

yep, that makes sense

#

hmm for my game I suppose the owner leaving causing a reset isn't a huge deal

#

but I'll try just properly propagating state first

atomic palm
#

Hi guys, when using Manual instead of Continuous on an UdonBehaviour, how do I trigger the manual sync?

strange gyro
#

UdonBehaviour.RequestSerialization

atomic palm
#

Thank you!

mossy ruin
#

what's a good rule of thumb for how many bytes you should limit to a single continous object? like would a byte array of 67 bytes be too much?

frozen igloo
#

I believe it's somewhere around 200 bytes in total. But that does not directly correspond to the length of a byte array. To see how much data you're using precisely, you can use OnPostSerialization's serializationresult

mossy ruin
#

ok, but it sounds like at least ill likly be in a good target zone with 67 length byte array

frozen igloo
#

yeah probably

mossy ruin
#

is this per object or for all objects in scene?

frozen igloo
#

per object

mossy ruin
#

sweetness

mossy ruin
#

had another idea of approach...but i dont know if it would be better. Roughly how many frames do you think pass between packet sends on continuous objects? trying to think if i track input on a per frame bases how much data would i collect before it seralizes it

#

i assume it would depend on how much traffic is going on, wasnt sure if there was a good average on how offten it seralizes

frozen igloo
#

it's about 5 per second, but can go down to 1-2 per second if the network is clogged

gritty lark
#

Hey, are there any world-creators interested in making something related for fitness?

#

I'm with a company called YUR and we're thinking about making some fitness-related content in VRchat

#

Send me a DM if you're interested, any skill level is fine

azure crane
#

i don't think this server is the right place for this type of advertisement

ivory gorge
gritty lark
#

Hmm, where would a good spot be?

#

Oh, thanks :)

idle drift
#

I mean it’s technically networking lmao

sleek cosmos
#

VRCObjectSync on the main body and wheels, VRC Station controls the wheel colliders for movement and it updates the wheel's pos/rot to the matching collider (making it "roll" and "turn"), anybody know why the wheels are moving at a different rate than the body?

sinful lotus
#

does anyone know how to make a button that enables/disables an object and that object is synced for anyone? also that only the owner of the instance or world can toggle and nobody else? thanks

sinful lotus
#

i have this but idk how to make it work only for the owner of the instance or world

ivory gorge
sharp tinsel
mossy ruin
#

If you keep under the 200 bytes limit on a continous object, whats the liklyhood that there will be data loss if a lot of players are on? Right now i have an object that syncs a lil less then 90bytes, but if a packet is loss that can start causing trouble for what its doing

frozen igloo
#

if you care about every single packet then you shouldn't use continuous

mossy ruin
#

hmm...then how bad would it be if i did the 100 bytes manual, but keep flagging request seralization?

frozen igloo
#

if you do it at the same rate it will have roughly the same cost

#

you can spam it faster than 5 per second but it will dramatically increase cost

mossy ruin
#

aaah gotcha

#

so if i make a timer set to go off 5 times per second to call request seralization, then it should be alright

frozen igloo
#

probably

#

you can keep an eye on it by checking Networking.IsClogged. If you spam requestserialization too much, it will get clogged and then your manual sync will be forcefully delayed. So the trick is if you're doing manual sync in a continuous-like way, you want to adjust the frequency of the requestserialization so that it does not get clogged

mossy ruin
#

hmm, well the issue is the longer i wait, the more data that will stack up

#

the faster i use it, the less data i need to send

frozen igloo
#

but all that being said, just switching to manual and still doing the same thing that continuous does will probably not solve your problem. Manual does not guarantee that all players receive all packets because if the synced variables get overridden before a player has received them, they will be lost

mossy ruin
#

wait they can be overridden before they get it?

frozen igloo
#

yeah, if their connection is particularly unsteady

#

it will be cheaper and more reliable to send occasional bursts of data than a frequent stream of data

mossy ruin
#

i see, so i shouldnt go too fast, but in this case i shouldnt go too slow.

#

i am working in a optimization to help remove data related to the player not changing input, hopefully that will help too

frozen igloo
#

that is indeed the main dilemma of realtime networking

#

if you want to guarantee that everyone receives a very important message and there might be other important messages coming later, the best way to do that is a network event

#

network events, unlike synced variables, do guarantee that they are received exactly once

mossy ruin
#

ya, tho thats not gonna work here

frozen igloo
#

if this is input then that's a finite range of values, no?

mossy ruin
#

im basicly trying to make the preview of a game in sync by controlling random and time interval, and syncing the player input

#

the range of values is an x/y of the joystick, and a button press

#

that x/y isnt static tho, i could make it static which then that would work better but change the percesion

#

overall, this is mainly for the preview, so if it desyncs i suppose thats ok, itll reset next game

#

wait, not sure if static is the right word, its a float not a 0-1

frozen igloo
#

if you want to sync the input that's fine, but you should definitely also sync the results of that input too so that it doesn't drift out of sync

mossy ruin
#

that would end up being too much data tho

frozen igloo
#

are you sure? Manual sync can do a lot

mossy ruin
#

i have a player, 30 eneimes, 10 power ups, with different states

#

i think overall it was close to 100bytes as well

#

so i would be pushing that 200 byte limit

frozen igloo
#

manual sync can do 1 kilobyte instantly, 10kb if you wait a few seconds, and the absolute limit is about 60kb per serialization

#

a few hundred bytes is nothing

mossy ruin
#

hmm

#

wait, its 100 bytes per frame of result

#

so the input is 3 bytes a frame

#

i suppose its more of i could capture where they are that frame

#

right as you said, result of them XD

frozen igloo
#

I would probably capture a whole second of data and send that as one big blob, to be replayed when it is received

mossy ruin
#

mmm, maybe, ima try just doing the input, keeping that in sync, and see if itll be enough in a stress test. If not ill see about what i can do to show the result too

#

in the end, i just want it so others can watch you play

frozen igloo
#

yes, in situations where you are simply sharing what happened and you don't need other players to interact with it live, recording and playing back large chunks of data is ideal. That is effectively what video buffering is

mossy ruin
#

imagine figuring out how to caputre the per frame texture of the shader result, and syncing that XD

frozen igloo
#

syncing input is typically used in situations where neither player has authority over the simulation. it's a valid technique but I don't think it's the best here

mossy ruin
#

possibly, if this doesnt work i can limit the input to be very constrained and switch to events

#

i think 8 events would be the least needed for a joystick and single button