|
Table of Contents
|
Part of VRC_Trigger
Broadcast types are used by the VRC_Trigger component to define who can activate the trigger for which players. Enabling 'Advanced Mode' will allow you to see all Broadcast types.
When you create a trigger, you need to consider three things: who is allowed to initiate it, who can see the result immediately, and how late joiners to the instance will see it.
Ownership
All GameObjects in the world have an owner. Only GameObjects with the VRC_ObjectSync component can change owners. All objects are initially owned by the Master, who is the person in the instance that joined the earliest or in other words has been in the instance the longest. The owner is the one who "wins" in any conflict about network events affecting that objects, mainly the position of the object if Sync Physics is checked in the VRC_ObjectSync component. When using the Owner broadcast type, it is the receiver's owner that determines if you can execute it, and not the owner of the object the trigger is on. If a GameObject does not have VRC_Object sync, then only the master will be able to execute this trigger action.
See VRC_ObjectSync for more details.
Master
Only the master of the instance can activate this trigger, the effects of which are then sent to everyone else. Master is the person who first spawned into the world instance. If that person leaves, Master will be the person who joined the instance the earliest. Master broadcast type is mainly used in cases where you need only one player to broadcast an event to prevent over broadcasting. See the section below for more on over broadcasting. It is also widely used moderatively, to only allow the master to start a minigame or play a video.
Owner
Only the owner of the object can activate this trigger, the effects of which are then sent to everyone else. By default, the instance master will be the owner of every object. Owner status will automatically be given to anyone who picks up an ObjectSynced object. For non-pickups, ownership can be changed using triggers by calling the transfer ownership RPC under scene events. Owner is different from Master as Owner applies to objects. Without this script, all physics for the object are calculated locally on your machine. Even though the position will be calculated locally, Master will still "own" these unsynced objects.
Unlike Master, ownership is very useful for building worlds. Since physics and location data for synced objects are calculated on the Owner's client, you must be the owner of the object if you want to manipulate it. Pickups handle this automatically, but more complicated objects need to have this set manually. An example use for this would be vehicles. If you have ever seen someone sitting on a vehicle not moving, but they can't hear you, this is because they have moved on their game, but the vehicle object itself is not synced with everyone. For the vehicle to work properly, the one riding it must also be the owner.
Buffers
All Buffered
New players who join the instance will buffer every instance of this trigger. It's highly recommended that you don't use this trigger type unless you know what you're doing, as buffering too many triggers at once can cause issues for late-joiners.
- Always
- Master
- Owner
Every time a "Buffered" trigger activates, it is saved so that when someone joins the room later, it can be triggered again for the new person only. While this will keep everything synced between all clients, most times this is used incorrectly. If combined with another broadcast trigger, this will cause all events to happen again for all users. This broadcast type should only be used when something new happens every time you call it. The best example of this would be the Spawn Object action, which will force the trigger to Always. This is required as everyone in the game needs to know of all the spawned objects in the instance. If you do plan on using this method to keep things synced, never link it with another trigger that broadcasts to all players.
Buffer One
Only the most recent trigger will be buffered for new players who join the instance. This buffer type is best for syncing with late-joiners.
- Always Buffer One
- Master Buffer One
- Owner Buffer One
Buffer one means that every time this trigger activates, it saves only the last one for people who join the room later. When using a toggle feature, this can “desync” between old and new players when the trigger has activated an even number of times. This broadcast type is still very useful but should be only used with explicit actions. It should not have different behavior depending on how many times it has been activated. If you have a trigger that toggles a GameObject between active and inactive, it is best to split this into two triggers where one sets it to true and the other sets it to false. Doing so will ensure that all players are synced. Note that entering a station (chair) should always be Buffer One. Again, do not link this broadcast type with another trigger that broadcasts to all players.
Known Issues
When using MasterBufferOne and OwnerBufferOne, there is currently a bug that will cause the trigger to buffer when nonmaster/nonowner users activates the trigger.
https://vrchat.canny.io/bug-reports/p/masterbufferone-buffers-when-non-masters-initiate-the-trigger
Unbuffered
The trigger won't be buffered for new players who join the instance. This buffer type is best for "in the moment" actions, ie sound effects.
- Always Unbuffered
- Master Unbuffered
- Owner Unbuffered
Unbuffered means that when the trigger activates, everyone in the instance will see the results, but no one joining in late will see the results. This is good for things that only need to happen in the moment but don't actually change the world, like playing a particle effect or sound for an event. Other examples include actions on synced objects. Video players are already synced, so you do not need to buffer any next actions. If you teleport a synced object, you do not need to buffer the action as the object's location will already be updated for late joiners. Note that only the owner will actually move the object, but since these are triggered on all clients, the owner will also trigger it.
Local
Anyone can activate this trigger but the effects will only be seen by the individual who triggers it.
- Local
The Local broadcast type will run once on your client only. The person who initiated the trigger will be the only one to see the results and it will not broadcast to all players. While this may not sound that great at first, this is the most useful broadcast type. When combined with the other broadcast triggers, you can have some events happen for only one person, but then other events be broadcasted to all the other players. A simple example of this would be a button that when pressed, turns on a green box for the player that pushed it, but turns on a red box for everyone else. Also, with this broadcast type, there are no network calls. If you really want to optimize your triggers, you will want most of your work to be done through Local triggers. Every trigger that you create that broadcasts to all players should only have a single activate custom trigger action. This custom trigger should then be local and also where all of the work will be done. When you activate a broadcast trigger, every action and every receiver under each action is a new RPC event. You should try to minimize the number of RPC events to get most of the work to be calculated locally.
Instance Desynchronisation
Oversyncing
Oversyncing is a term we have used when multiple sync methods are combined together, with one of them usually involving a broadcasting trigger. There are 3 main types of oversync:
- Overbroadcasting
- Broadcast Chaining
- Overbuffering
Generally with oversync, broadcasting triggers will be executing from more players than needed. Everyone will broadcast to everyone else to do an action. Oversync can lead to a drop in framerate, crashes, and desync'ing the instance.
See Oversync for more details.
Unsuccessfull Broadcasts
If a Trigger is disabled (or the GameObject the Trigger is on is disabled) it will not fire. This means that a broadcast referencing a Trigger which state is variable might be unsuccessful. In this case all events depending on that trigger will (likely) be desynchronised.
For this reason avoid putting triggers on GameObjects that you arent absolutely sure will never be disabled, unless you know what youre doing.
