<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.steeveeo.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Steeveeo</id>
	<title>WaffleSlapper&#039;s Project Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.steeveeo.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Steeveeo"/>
	<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php/Special:Contributions/Steeveeo"/>
	<updated>2026-05-11T15:26:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Troubleshooting&amp;diff=84</id>
		<title>VTI Troubleshooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Troubleshooting&amp;diff=84"/>
		<updated>2024-03-27T22:58:17Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Rewrote Browser Tab issue to match new behavior. Added Access Token Revocation instructions.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
To steal a phrase from a friend of mine, VTI is an imperfect application created by an imperfect being. Not only this, but it also relies on an imperfect communication method (until OSC comes to VRChat Worlds) to work. Because of all this, there are some known issues and caveats that you will probably run into while using [[VRChat Twitch Integration|VTI]]. Below is a list of said common issues and how they may be dealt with.&lt;br /&gt;
&lt;br /&gt;
== VTI Occasionally Opens a Browser Tab That Says &amp;quot;Logged In&amp;quot; ==&lt;br /&gt;
This is because VTI uses Twitch’s Implicit Grant Flow to authenticate with your Twitch account (see [[VTI Function Overview]] for more details). This method generates an &amp;quot;Access Token&amp;quot; that the Companion uses to connect to Twitch securely. This token is only valid for a limited amount of time and must occasionally be reacquired from Twitch (most documentation says once every 60 days, though this may differ).&lt;br /&gt;
&lt;br /&gt;
== I Want To Revoke My Access Tokens! ==&lt;br /&gt;
Whether by way of a security leak or just healthy security paranoia, you might find yourself wanting to remove Twitch access from VTI. This can be done at any time by disconnecting VTI from your Twitch Connections page.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Disconnect &amp;quot;VTI - Stream Integration For VRChat Worlds&amp;quot; On Your [https://www.twitch.tv/settings/connections Twitch Connections Page] ====&lt;br /&gt;
&lt;br /&gt;
== When Trying To Connect, The Panel In VRC Immediately Fails To Connect And Shows A Red Status ==&lt;br /&gt;
VTI will connect to the [[VTI Companion App|Companion]] using Remote String Loading (see [[VTI Function Overview]] for more details). To do this, it needs to be able to connect to &amp;quot;localhost:12011&amp;quot;, and &amp;quot;localhost&amp;quot; is not a whitelisted URL by default.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Enable &amp;quot;Allow Untrusted URLs&amp;quot; in your Comfort &amp;amp; Safety Settings menu. ====&lt;br /&gt;
&lt;br /&gt;
== The VRChat Link Light Just Keeps Blinking Yellow And Never Connects ==&lt;br /&gt;
The [[VTI Companion App]] relies on VRChat’s Debug Log file to hear anything the VRC side is saying. If VRChat is not currently writing out its Debug Output, VTI has nothing to listen to, and the connection will never be able to complete. See [[VTI Function Overview]] for more details.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Enable Logging in VRChat’s Debug options, and remove -nolog from VRChat’s Launch Options if present. ====&lt;br /&gt;
[[File:VTI Logging Option Example.png|300px]]&lt;br /&gt;
&lt;br /&gt;
== New Events Take Several Seconds To Trigger ==&lt;br /&gt;
This is an unfortunate downside of Remote String Loading, as it is globally capped to only work once every 5 seconds, and while on cooldown new requests will be queued and cleared “at random”. If any other Udon script is also trying to use Remote String Loading, VTI will have to wait an additional 5 seconds for the next open “time slot” that it can attempt a read. VTI will only read once every 6 seconds by default, and hard-cap itself to 5.1 seconds at the fastest so as not to completely hog the Remote String Loading queue.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Petition VRChat to add OSC support for Worlds or something. ====&lt;br /&gt;
&lt;br /&gt;
== The Companion App Keeps Throwing Errors About Permissions And Such ==&lt;br /&gt;
Unfortunately, due to how the VTI Companion works, it needs to read from VRChat’s AppData directory. If you are running the [[VTI Companion App|Companion]] with insufficient privileges to read that file, it will fail to connect. Likewise, if you have somehow downloaded the [[VTI Companion App]] without ever running VRChat on the machine, you will see an error that the Log directory cannot be found.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Run the Companion App as Administrator, and run VRChat at least once before launching VTI. ====&lt;br /&gt;
&lt;br /&gt;
== How Do I Run This on Quest/Android? ==&lt;br /&gt;
Due to how the [[VTI Companion App]] functions (see [[VTI Function Overview]] for more details), VTI cannot be supported on standalone Quest or Android devices at this time.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Tether your HMD to a PC. ====&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Troubleshooting&amp;diff=83</id>
		<title>VTI Troubleshooting</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Troubleshooting&amp;diff=83"/>
		<updated>2024-03-27T02:19:19Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Added Allow Untrusted URLs step and some slight reorg.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
To steal a phrase from a friend of mine, VTI is an imperfect application created by an imperfect being. Not only this, but it also relies on an imperfect communication method (until OSC comes to VRChat Worlds) to work. Because of all this, there are some known issues and caveats that you will probably run into while using [[VRChat Twitch Integration|VTI]]. Below is a list of said common issues and how they may be dealt with.&lt;br /&gt;
&lt;br /&gt;
== Every Time I Open VTI, It Opens A Browser Tab ==&lt;br /&gt;
This is because VTI uses Twitch’s Implicit Grant Flow to authenticate with your Twitch account (see [[VTI Function Overview]] for more details). This is the most secure method for both you and myself as the auth tokens only work for that session, are not stored either locally nor on any of my servers, and do not require that I bake VTI’s “Client Secret” into the Companion App’s code or run an external authentication webservice. Put simply: VTI does not collect your login information, and any session information is trashed once VTI is closed.&lt;br /&gt;
&lt;br /&gt;
== When Trying To Connect, The Panel In VRC Immediately Fails To Connect And Shows A Red Status ==&lt;br /&gt;
VTI will connect to the [[VTI Companion App|Companion]] using Remote String Loading (see [[VTI Function Overview]] for more details). To do this, it needs to be able to connect to &amp;quot;localhost:12011&amp;quot;, and &amp;quot;localhost&amp;quot; is not a whitelisted URL by default.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Enable &amp;quot;Allow Untrusted URLs&amp;quot; in your Comfort &amp;amp; Safety Settings menu. ====&lt;br /&gt;
&lt;br /&gt;
== The VRChat Link Light Just Keeps Blinking Yellow And Never Connects ==&lt;br /&gt;
The [[VTI Companion App]] relies on VRChat’s Debug Log file to hear anything the VRC side is saying. If VRChat is not currently writing out its Debug Output, VTI has nothing to listen to, and the connection will never be able to complete. See [[VTI Function Overview]] for more details.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Enable Logging in VRChat’s Debug options, and remove -nolog from VRChat’s Launch Options if present. ====&lt;br /&gt;
[[File:VTI Logging Option Example.png|300px]]&lt;br /&gt;
&lt;br /&gt;
== New Events Take Several Seconds To Trigger ==&lt;br /&gt;
This is an unfortunate downside of Remote String Loading, as it is globally capped to only work once every 5 seconds, and while on cooldown new requests will be queued and cleared “at random”. If any other Udon script is also trying to use Remote String Loading, VTI will have to wait an additional 5 seconds for the next open “time slot” that it can attempt a read. VTI will only read once every 6 seconds by default, and hard-cap itself to 5.1 seconds at the fastest so as not to completely hog the Remote String Loading queue.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Petition VRChat to add OSC support for Worlds or something. ====&lt;br /&gt;
&lt;br /&gt;
== The Companion App Keeps Throwing Errors About Permissions And Such ==&lt;br /&gt;
Unfortunately, due to how the VTI Companion works, it needs to read from VRChat’s AppData directory. If you are running the [[VTI Companion App|Companion]] with insufficient privileges to read that file, it will fail to connect. Likewise, if you have somehow downloaded the [[VTI Companion App]] without ever running VRChat on the machine, you will see an error that the Log directory cannot be found.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Run the Companion App as Administrator, and run VRChat at least once before launching VTI. ====&lt;br /&gt;
&lt;br /&gt;
== How Do I Run This on Quest/Android? ==&lt;br /&gt;
Due to how the [[VTI Companion App]] functions (see [[VTI Function Overview]] for more details), VTI cannot be supported on standalone Quest or Android devices at this time.&lt;br /&gt;
&lt;br /&gt;
==== FIX: Tether your HMD to a PC. ====&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIObjectInstantiate&amp;diff=82</id>
		<title>VTIObjectInstantiate</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIObjectInstantiate&amp;diff=82"/>
		<updated>2024-03-26T04:34:25Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial writeup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIObjectInstantiate is a [[VTI Drivers|VTI Driver]] that will instantiate copies of a Prefab GameObject when fired within a (zero-able) range of either the Streamer or the [[VTI Targets|Target]]. When choosing a Prefab, note that its saved Transform will be used as an offset to its spawned position. For example, if your spawned object should always spawn above the head of a player, make sure the Position in the saved Prefab is set have a Y greater than 0.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039;: These spawned items are &#039;&#039;not&#039;&#039; syncable, do not use this Driver for persistent objects!&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || No (This may change in the future)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients. Spawned objects &#039;&#039;&#039;WILL NOT SYNC&#039;&#039;&#039; to new joiners!&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Prefab || GameObject || The GameObject to copy when spawning objects. This can either be an object in the scene, or a Prefab from your Assets.&lt;br /&gt;
|-&lt;br /&gt;
| Item Container || GameObject || The GameObject to store spawned objects within. This is used to determine how many objects have been spawned when checking against MaxCount, so choose an object without pre-existing children. Defaults to this script&#039;s GameObject.&lt;br /&gt;
|-&lt;br /&gt;
| SpawnAtPlayer || bool || Whether or not to spawn the new object at the Streamer&#039;s feet or around the Target.&lt;br /&gt;
|-&lt;br /&gt;
| RandomSpawnOffsetAxes || Vector3 || How much to randomize the spawn position by in each axis. For instance, setting X to 10.0f will vary the spawn position&#039;s X axis by plus-or-minus 10 meters.&lt;br /&gt;
|-&lt;br /&gt;
| MaxCount || int || How many items can be spawned before this Driver stops spawning new ones. Set to -1 to not limit. &#039;&#039;&#039;Exercise caution when turning off limits when the spawned Prefab does not clean itself up!&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| SpawnDelay || float || How long to wait between setting the randomized spawn position and actually spawning the object. Use to ensure networking has a second to propagate the correct position before spawning.&lt;br /&gt;
|-&lt;br /&gt;
| SpawnCountRecheckDelay || float || How long in seconds to wait before updating the number of spawned items. Lower values will clear the buffer faster, but incur more load on the CPU.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Drivers&amp;diff=81</id>
		<title>VTI Drivers</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Drivers&amp;diff=81"/>
		<updated>2024-03-26T04:20:28Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Added VTIObjectInstantiate line. Also updated to new behavior on VTIObjectToggle.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTIDriver Inspector.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
In the [[VTI World Kit]], a Driver is a script that acts as an &amp;quot;Endpoint&amp;quot; for when an [[VTI Events|Event]] is received and fired. When attached to the same GameObject as a [[VTI Targets|VTITarget]] component, it will receive Event data when said target is Fired by [[VRChat Twitch Integration|VTI]].&lt;br /&gt;
&lt;br /&gt;
Multiple Drivers can exist under the same [[VTI Targets|Target]], allowing multiple actions to be taken upon firing without needing a bespoke custom Driver.&lt;br /&gt;
&lt;br /&gt;
All Drivers are, and must be, derived from the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIDriverBase&amp;lt;/syntaxhighlight&amp;gt; base class. The base class includes all the below properties and methods when inherited.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Properties&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| UserName || string || The Twitch User Name of the user who triggered this [[VTI Events|Event]].&lt;br /&gt;
|-&lt;br /&gt;
| Message || string || The User Message, if applicable, that was sent with this [[VTI Events|Event]].&lt;br /&gt;
|-&lt;br /&gt;
| TriggerCause || string || The reason why this was triggered. Use this when Allow Event Type Rebinding is enabled on the [[VTI Targets|VTITarget]] to dynamically handle user-changed bindings.&lt;br /&gt;
|-&lt;br /&gt;
| TriggerAmount || int || What &amp;quot;value&amp;quot; is associated with this Event, i.e. how many bits cheered, subs gifted, tier subscribed, etc.&lt;br /&gt;
|-&lt;br /&gt;
| IsReady || bool || A helper variable to easily mark a Driver as &amp;quot;busy&amp;quot; and unable to refire. Unless overridden in the derived Driver, &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; will default to just returning this value.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Return !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| VTICheckReady() || bool || This method will be called by VTI just before attempting to fire the parent [[VTI Targets|VTITarget]]. Return &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; if this is ready to be fired.&lt;br /&gt;
|-&lt;br /&gt;
| VTIEventPlay() || void || This method will be called by VTI when its parent [[VTI Targets|VTITarget]] is Fired.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Packaged Drivers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Drivers Included With VTI&lt;br /&gt;
|-&lt;br /&gt;
! Driver !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| [[VTIAnimTrigger]] || Sets an Animator&#039;s Trigger input when Fired.&lt;br /&gt;
|- &lt;br /&gt;
| [[VTIObjectToggle]] || When Fired, this Driver will enable the target GameObject, wait for &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTime&amp;lt;/syntaxhighlight&amp;gt; seconds, and then optionally disable it again.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTIObjectInstantiate]] || Will instantiate a prefab copy when fired within a certain (zero-able) range of either the Streamer or the Target. These copies are not syncable, so do not use them for persistent items.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTIRadialTripObjectToggle]] || A version of [[VTIObjectToggle]] that will &amp;quot;arm&amp;quot; when Fired, and then wait for a Player to get within a set radius before enabling the target GameObject. Will report unready while Armed and not tripped.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTIRunMethod]] || Utilizes &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;SendCustomEvent()&amp;lt;/syntaxhighlight&amp;gt; to trigger a named method on the target UdonBehaviour when Fired. When User Messaging is enabled, this Driver will attempt to set the string variables &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;UserName&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Message&amp;lt;/syntaxhighlight&amp;gt; on the target UdonBehaviour.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Custom Drivers ==&lt;br /&gt;
The [[VTI World Kit]] is designed to be easily extensible by both world designers and programmers alike. To this end, custom Drivers are highly recommended and are built to be fairly simple to create. A custom Driver need only implement one method, &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt;. All other functionality can be added around that, or is already handled by the VTIDriverBase base class.&lt;br /&gt;
&lt;br /&gt;
For an in-depth tutorial on creating a custom Driver, see [[Creating Custom VTI Drivers]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Demo_World&amp;diff=80</id>
		<title>VTI Demo World</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Demo_World&amp;diff=80"/>
		<updated>2024-03-24T00:41:05Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial Writeup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTI-Demo-World main.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The VTI Demo World is an example Unity scene packaged with the [[VTI World Kit]] and is built to demonstrate the capabilities and construction of [[VRChat Twitch Integration]]. As of VTI version 1.0.0, the demo world is laid out on a flat plane with yellow guidelines leading to all the available [[VTI Example Prefabs]] as well as &amp;quot;Explainer Panels&amp;quot; describing the usage and construction of each.&lt;br /&gt;
&lt;br /&gt;
Next to the spawn, there is a main introductory panel describing [[VRChat Twitch Integration|VTI]], how to get the [[VTI Companion App]], and how to connect the Companion to the World. To its left are the [[VTI Control Panel]], [[VTI About Panel]], and the [[VTI Advert Panel]].&lt;br /&gt;
&lt;br /&gt;
This scene serves as both a tutorial for how to use [[VRChat Twitch Integration]] as a User as well as how a VTI-Capable VRChat World is constructed on the Developer side.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI-Demo-World_main.png&amp;diff=79</id>
		<title>File:VTI-Demo-World main.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI-Demo-World_main.png&amp;diff=79"/>
		<updated>2024-03-23T23:47:45Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screenshot depicting the [[VRChat Twitch Integration|VTI]] Demo World for the [[VTI Demo World]] documentation.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIObjectToggle&amp;diff=78</id>
		<title>VTIObjectToggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIObjectToggle&amp;diff=78"/>
		<updated>2024-03-23T21:37:45Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Added StayOn and updated Network Sync.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIObjectToggle is a [[VTI Drivers|VTI Driver]] that will enable a target GameObject when fired, wait for a given amount of time, and then disable the target.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || Yes - Uses two TextMeshPro objects for Username and Message Inputs&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes - Appends Trigger Verb to UserName String&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, object toggle state syncs to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Target || GameObject || The GameObject to toggle on/off when Firing.&lt;br /&gt;
|-&lt;br /&gt;
| UserNameText || TextMeshPro || The TMP object to populate with UserName and Verb text.&lt;br /&gt;
|-&lt;br /&gt;
| MessageText || TextMeshPro || The TMP object to populate with User Message text.&lt;br /&gt;
|-&lt;br /&gt;
| StayOn || bool || Whether or not to leave Target enabled after triggering (true), or to turn it back off after ResetTime (false).&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to keep Target enabled for before disabling.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Function_Overview&amp;diff=77</id>
		<title>VTI Function Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Function_Overview&amp;diff=77"/>
		<updated>2024-02-27T01:23:09Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Fixed category marker.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
This page details how the [[VRChat Twitch Integration]] prefab pack (known as the [[VTI World Kit]]) works in tandem with the [[VTI Companion App]] in order to transmit Twitch events to the VRChat Client.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The first and probably most important thing to note is that VTI is &#039;&#039;not&#039;&#039; a modification of the VRChat client, and therefore does not break the VRChat Terms of Service, nor does it cause issues with Easy Anti-Cheat. Instead, VTI utilizes [https://creators.vrchat.com/worlds/udon/string-loading/ Remote String Loading] and watches VRChat&#039;s Debug Log. Read on for more details.&lt;br /&gt;
&lt;br /&gt;
== How VTI Talks to VRChat ==&lt;br /&gt;
As previously mentioned, VTI uses [https://creators.vrchat.com/worlds/udon/string-loading/ Remote String Loading] in UdonSharp in order to send data to the VRChat Client. The [[VTI Companion App]] will bundle up all the events that have been triggered through Twitch into it&#039;s Event Queue, and then compile said Queue into JSON.&lt;br /&gt;
&lt;br /&gt;
The [[VTI Companion App]] runs a non-internet-facing websocket on port 12011 and listens for VRChat to query for the next update, at which time it will respond with the above JSON, allowing the VRChat side to load the latest Events. This is why the [[VTI Troubleshooting]] article says that turning on &#039;&#039;Allow Untrusted URLs&#039;&#039; is required, as &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;localhost&amp;lt;/syntaxhighlight&amp;gt; is not on the URL Whitelist.&lt;br /&gt;
&lt;br /&gt;
Because of the reliance on Remote String Loading, VTI can only update the Event Queue once every 5 seconds at the fastest due to how VRChat rate-limits its usage. As this rate-limit is global, VTI will intentionally clamp the fastest update speed to 5.1 seconds to allow any other prefab that uses Remote String Loading to function.&lt;br /&gt;
&lt;br /&gt;
== How VRChat Talks To The Companion ==&lt;br /&gt;
At the time of writing, VRChat does not yet support OSC for anything other than Avatars. Because of this, there is only one way to send info outside of the VRChat client, and that is through its Debug Log. If one reads through their VRChat Debug Logs after using VTI, they might come across quite a few lines with the prefix &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;[VAL]&amp;lt;/syntaxhighlight&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot;&amp;gt;2024.02.04 18:00:51 Log        -  [VAL] VTI_EVENT_RECEIVED|7ed84988-73a9-4060-8b39-3752357f3025&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, VTI has sent the Companion a message saying that it&#039;s acknowledged a specific event, and it will take it from here. The several other signal types can be noted by reading the logs further, but will not be discussed in this article as it is supposed to be a general overview rather than a deep dive.&lt;br /&gt;
&lt;br /&gt;
To note about the prefix, &amp;quot;VAL&amp;quot; stands for &amp;quot;VRChat App Link&amp;quot;, and is the moniker for the internal library that handles the intercommunication between VRChat and an application discussed in this article. At this time of writing, this library has not yet been made public, but plans are in place to do so in the future.&lt;br /&gt;
&lt;br /&gt;
== How VTI Connects with Twitch ==&lt;br /&gt;
The [[VTI Companion App]] connects with the Twitch through its [https://dev.twitch.tv/docs/ API]. Specifically, it utilizes the [https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/ Implicit Grant Flow] method of authentication, which has been determined to be the safest method for both the developer and the end user. Unfortunately, this means that VTI will always pop up a browser window when beginning the Twitch connection as the credentials &#039;&#039;&#039;&#039;&#039;are not stored&#039;&#039;&#039;&#039;&#039; in the VTI Companion nor any of [[WaffleSlapper]]&#039;s or [[Poetica Mechanica]]&#039;s servers. This method also does not require the developer to use a Client Secret (required by other authentication methods) which can be used to cause harm if leaked through the [[VTI Companion App]]&#039;s source code or any external service.&lt;br /&gt;
&lt;br /&gt;
The [[VTI Companion App]] utilizes a customized version of the [https://github.com/SaviorXTanren/StreamingClientLibrary StreamingClientLibrary] by SaviorXTanren, which has been modified to enable the above [https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/ Implicit Grant Flow]. You can view the source code for the fork [https://github.com/Steeveeo/StreamingClientLibrary here].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_World_Kit_Setup&amp;diff=76</id>
		<title>VTI World Kit Setup</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_World_Kit_Setup&amp;diff=76"/>
		<updated>2024-02-20T04:10:23Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial tutorial writeup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Tutorials]]&lt;br /&gt;
&lt;br /&gt;
This tutorial will cover the installation and setup of the [[VTI World Kit]] for usage in creating VRChat Worlds that support [[VRChat Twitch Integration]]. It is the first tutorial in the developer series, and will include the process to get a World to connect to the [[VTI Companion App]]. This tutorial will assume basic knowledge on setting up VRChat Worlds and will not cover that topic.&lt;br /&gt;
&lt;br /&gt;
The VTI World Kit can be found here: https://stevegreendesign.com/project/vti/&lt;br /&gt;
&lt;br /&gt;
== Step 1: Installing VTI ==&lt;br /&gt;
[[File:VTI Setup Part1.png|250px]]&lt;br /&gt;
&lt;br /&gt;
Once you have the [[VTI World Kit]] downloaded, install the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;.unitypackage&amp;lt;/syntaxhighlight&amp;gt; file like you would any other package. Navigate to &#039;&#039;&#039;Assets &amp;gt; Import Package &amp;gt; Custom Package...&#039;&#039;&#039; and select the [[VTI World Kit]] package. This will add all the VTI assets under &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Assets/Poetica Mechanica/&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Open the folder &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Poetica Mechanica/VRC Twitch Integration/Prefabs/&amp;lt;/syntaxhighlight&amp;gt;, and drag the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VRChat Twitch Integration.prefab&amp;lt;/syntaxhighlight&amp;gt; prefab into the scene. This is the &amp;quot;Core&amp;quot; of the [[VTI World Kit]] and has all the components necessary to run VTI.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Configure World Settings ==&lt;br /&gt;
[[File:VTI Setup Part2.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
We now need to configure some settings in order to get things working. Select the GameObject &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VRChat Twitch Integration/VRC App Link&amp;lt;/syntaxhighlight&amp;gt;. Change the &#039;&#039;VAL World Name&#039;&#039; and &#039;&#039;VAL World Author&#039;&#039; to what you want your World to display when connecting the [[VTI Companion App]] to it.&lt;br /&gt;
&lt;br /&gt;
Note: &#039;&#039;VAL World Name&#039;&#039; is used when saving and loading World Settings for a VTI-Capable World. If this name matches another VTI-Capable World, the [[VTI Companion App]] will consider it to be the same world and attempt to load settings accordingly. This can be handy if you have multiple versions of your World (like a Beta/Release setup, or A/B Channel builds), but it is also worth ensuring the world name is unique enough to not trip up the user. TL;DR, don&#039;t name your world &amp;quot;World&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Connection Settings ====&lt;br /&gt;
Below the &#039;&#039;World Settings&#039;&#039;, you can see the &#039;&#039;Connection Settings&#039;&#039; section. For the most part &#039;&#039;&#039;it is safe to leave these all default&#039;&#039;&#039;. However, for completeness, here are what each of these settings do:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Enable Autostart || When Enabled, VTI will attempt to connect to the [[VTI Companion App]] immediately rather than waiting for the user to connect.&lt;br /&gt;
|-&lt;br /&gt;
| Companion Sync Delay || How often, in seconds, to attempt to get updates from the [[VTI Companion App]]. This is defaulted to 6 seconds, and clamps itself to 5.1 seconds at a minimum, due to how [https://creators.vrchat.com/worlds/udon/string-loading/ Remote String Loading] is rate-limited.&lt;br /&gt;
|-&lt;br /&gt;
| Reconnect Delay || In the event of a connection failure, how many seconds to wait before attempting to reconnect to the [[VTI Companion App]]&lt;br /&gt;
|-&lt;br /&gt;
| Reconnect Attempt Limit || How many attempts are made to connect before giving up.&lt;br /&gt;
|-&lt;br /&gt;
| Log Ping Delay || If the [[VTI Companion App]] is left in &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;WAIT_LOG&amp;lt;/syntaxhighlight&amp;gt; for this many seconds, this will write a bunch of data to the Debug Log to try to wake it up. Repeats. Best to just leave this at 10 seconds.&lt;br /&gt;
|-&lt;br /&gt;
| Think Rate || How often the [[VTI World Kit]] will &amp;quot;think&amp;quot; and process inputs. Lower numbers &amp;quot;think&amp;quot; more often, which is more responsive but less efficient.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== VTI Core Settings ====&lt;br /&gt;
[[File:VTI Setup Part2-2.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
Neighboring the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VRC App Link&amp;lt;/syntaxhighlight&amp;gt; GameObject is the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTI Core&amp;lt;/syntaxhighlight&amp;gt; object. Select this and note the settings in the Inspector. Like the previous section, &#039;&#039;&#039;these are fine to leave as default&#039;&#039;&#039;. But for your information, here is what each setting does:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Allow Force Queue || Whether or not to allow the [[VTI Companion App]] to force an event to trigger. Useful for debugging, but can break Game worlds.&lt;br /&gt;
|-&lt;br /&gt;
| Think Rate || Much like above, how fast this component will &amp;quot;think&amp;quot;. Lower numbers are more responsive, but incur a heavier performance cost.&lt;br /&gt;
|-&lt;br /&gt;
| Event Fire Think Rate || Similar to the above, but an extra kick to the processing speed when VTI is attempting to fire off an [[VTI Events|Event]]. Useful for reducing delay when multiple VTI users are in the same world together and VTI is waiting on [https://creators.vrchat.com/worlds/udon/networking/#ownership Ownership].&lt;br /&gt;
|-&lt;br /&gt;
| Global Event Cooldown || If you wish to rate-limit the number of [[VTI Events|Events]] cooking off, you can put in an extra delay in seconds here.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 3: Place Control Panel(s) ==&lt;br /&gt;
[[File:VTI Setup Part3.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The final thing we need to do to get this world to connect to the [[VTI Companion App]] is to place down one of the Control Panel prefabs. Navigate to the asset folder &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Poetica Mechanica/VRC Twitch Integration/Prefabs/UI/&amp;lt;/syntaxhighlight&amp;gt; and drag the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;English VTI Panels.prefab&amp;lt;/syntaxhighlight&amp;gt; prefab into the scene.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: More languages are planned to be supported in the future. When they are, choose the VTI Panels prefab matching the language you wish to use.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This prefab contains three panels: the main Control Panel, a Download VTI panel, and a &amp;quot;What Is VTI?&amp;quot; panel. The Control Panel has the actual functionality we need, namely the Connect button. The other two are useful to let your users know about VTI and how to get it and are best placed in the Spawn Area of your World. If you wish to place more Control Panels around your world without the other two auxiliary panels, head into the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;English/&amp;lt;/syntaxhighlight&amp;gt; (or whichever language) asset folder and drag another Control Panel prefab into the scene.&lt;br /&gt;
&lt;br /&gt;
The [[VTI World Kit]] &#039;&#039;&#039;supports any number of Control Panels&#039;&#039;&#039;, and there are &#039;&#039;&#039;no extra links to manually make&#039;&#039;&#039;. Drop as many Control Panels into the World as you wish!&lt;br /&gt;
&lt;br /&gt;
== Closing ==&lt;br /&gt;
And that&#039;s it! You can test if everything is setup correctly by building your World, launching the [[VTI Companion App|Companion]], and clicking the Connect button on any Control Panel. If the [[VTI Companion App|Companion]] connects and all the lights on the Control Panel are green, you&#039;re done!&lt;br /&gt;
&lt;br /&gt;
However, this World doesn&#039;t really &#039;&#039;do anything&#039;&#039; yet. To make it do stuff, continue onto the next tutorial and read [[Creating VTI Targets]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part3.png&amp;diff=75</id>
		<title>File:VTI Setup Part3.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part3.png&amp;diff=75"/>
		<updated>2024-02-20T03:58:02Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap showing the English [[VTI World Kit]] Control Panels for Step 3 of [[VTI World Kit Setup]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part2-2.png&amp;diff=74</id>
		<title>File:VTI Setup Part2-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part2-2.png&amp;diff=74"/>
		<updated>2024-02-20T03:52:03Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Steeveeo uploaded a new version of File:VTI Setup Part2-2.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap depicting the VTI Core settings for Step 2 of the [[VTI World Kit Setup]] tutorial.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part2-2.png&amp;diff=73</id>
		<title>File:VTI Setup Part2-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part2-2.png&amp;diff=73"/>
		<updated>2024-02-20T03:46:00Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap depicting the VTI Core settings for Step 2 of the [[VTI World Kit Setup]] tutorial.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part2.png&amp;diff=72</id>
		<title>File:VTI Setup Part2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part2.png&amp;diff=72"/>
		<updated>2024-02-20T03:23:11Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap depicting the VAL Core settings to change when setting up the [[VTI World Kit]] in a world. From Step 2 of [[VTI World Kit Setup]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part1.png&amp;diff=71</id>
		<title>File:VTI Setup Part1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Setup_Part1.png&amp;diff=71"/>
		<updated>2024-02-20T01:43:40Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap depicting the menu needed to install the [[VTI World Kit]] into a VRChat World. From Step 1 of [[VTI World Kit Setup]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=Creating_VTI_Targets&amp;diff=70</id>
		<title>Creating VTI Targets</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=Creating_VTI_Targets&amp;diff=70"/>
		<updated>2024-02-18T04:12:47Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial tutorial writeup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Tutorials]]&lt;br /&gt;
&lt;br /&gt;
This article is a tutorial on how to use the [[VTI World Kit]] portion of [[VRChat Twitch Integration]] in order to create your own triggerable [[VTI Targets]]. This will be a &#039;&#039;&#039;codeless tutorial&#039;&#039;&#039;, as most basic Targets can be handled by the built-in [[VTI Drivers|Driver Scripts]] included with the World Kit.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you already have the [[VTI World Kit]] setup in your scene. If you have not, please see [[VTI World Kit Setup]].&lt;br /&gt;
&lt;br /&gt;
== Step 1: Design and Driver Selection ==&lt;br /&gt;
[[File:VTI Target Tutorial Step1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
The first step of every new [[VTI Targets|Target]] that you want to make is, of course, figuring out what you want it to do. In the case of this tutorial, we have ourselves an object that we&#039;d like to have appear in the scene: a Spooky Cube that will most certainly jumpscare the Streamer. We want it to show up, wait a short while, and then vanish once again. &lt;br /&gt;
&lt;br /&gt;
With all that in mind, we can now go and select ourselves the most fitting [[VTI Drivers|Driver]] for this application. Knowing that this cube doesn&#039;t have any special animations or interactions that we need to deal with, we can see that all we have to do is toggle the object&#039;s Active state. The [[VTI Drivers|Driver]] that is best for this job would be [[VTIObjectToggle]].&lt;br /&gt;
&lt;br /&gt;
== Step 2: Setting Up The Target ==&lt;br /&gt;
[[File:VTI Target Tutorial Step2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Now that we have our design ideas done, we can start creating the actual [[VTI Targets|Target]]. To do this, we first need to actually &#039;&#039;&#039;&#039;&#039;make the Target&#039;&#039;&#039;&#039;&#039;. Create a new Empty in the scene, and name it something easy to find, perhaps something with the word &amp;quot;Target&amp;quot; in it. Next, attach the &#039;&#039;VTI Target&#039;&#039; component onto this Empty.&lt;br /&gt;
&lt;br /&gt;
To make this nice and modular, so we can move this around or turn it into a prefab and not have to worry about external bindings, go ahead and put the SpookyCube underneath the Target object in the hierarchy.&lt;br /&gt;
&lt;br /&gt;
In the inspector for the &#039;&#039;VTI Target&#039;&#039; script, you can see several fields that are either empty or have placeholder values in them. Here are what each of the items on the Inspector represent and how they are used:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ID&#039;&#039;&#039;: How [[VRChat Twitch Integration|VTI]] will keep track of this Target, and &#039;&#039;&#039;&#039;&#039;must be unique to any other Target in the scene&#039;&#039;&#039;&#039;&#039;. Think of it like the home address of your Target.&lt;br /&gt;
* &#039;&#039;&#039;Display Name&#039;&#039;&#039;: How the users will see this Target. It &#039;&#039;&#039;&#039;&#039;does not need to be unique&#039;&#039;&#039;&#039;&#039; (though it may still be a good idea so as not to be confusing), and is used in the [[VTI Companion App]] and when creating Channel Point Rewards.&lt;br /&gt;
* &#039;&#039;&#039;Description&#039;&#039;&#039;: A short sentence describing your Target&#039;s behavior and usage. It will show up on the [[VTI Companion App]]&#039;s editor, and on any Channel Point Rewards.&lt;br /&gt;
* &#039;&#039;&#039;Cooldown&#039;&#039;&#039;: How often, in seconds, that this Target can be fired. If this Target has been queued up multiple times, this is how long to wait in between each [[VTI Events|Event]]. Use this to make sure whatever your Target is doing is not interrupted or overlapped.&lt;br /&gt;
* &#039;&#039;&#039;Allow Message Input&#039;&#039;&#039;: Some [[VTI Drivers|Drivers]] support User Messaging, allowing Twitch viewers to send a message with their trigger. We will handle that later on in this tutorial.&lt;br /&gt;
* &#039;&#039;&#039;Allow Event Type Rebinding&#039;&#039;&#039;: Whether or not to allow users of the [[VTI Companion App]] to change how this Target is triggered. Most of the time, you can leave this on. However, if you have a very specific effect that &#039;&#039;&#039;&#039;&#039;needs&#039;&#039;&#039;&#039;&#039; to stay on a specific trigger, this is how you prevent changing the binding.&lt;br /&gt;
&lt;br /&gt;
Go ahead and fill out all of that section. Next, note the &#039;&#039;Default Twitch Binding Settings&#039;&#039; below that. This is how you define what specific type of action on Twitch will cause this Target to go off. Every currently-supported event type is available in the &#039;&#039;Default Event Type&#039;&#039; drop down. When selecting an Event Type, the settings form below it will automatically change to match the Event&#039;s values.&lt;br /&gt;
&lt;br /&gt;
For instance, let&#039;s say we want to have this trigger whenever someone donates more than 100 bits. To do that, we&#039;d set the Event Type to &#039;&#039;CHEER&#039;&#039; and the Numeric Compare to &#039;&#039;GREATER_THAN&#039;&#039; (or &#039;&#039;GREATER_OR_EQUAL&#039;&#039; if you want 100 bits to work as well). If we wanted to change that to triggering whenever anyone cheers any amount, change the Numeric Compare to &#039;&#039;ANY&#039;&#039;. To note: When &#039;&#039;Allow Event Type Rebinding&#039;&#039; is enabled, these are your &amp;quot;Recommended&amp;quot; settings for the Target, and the [[VTI Companion App]] will use them until overwritten.&lt;br /&gt;
&lt;br /&gt;
For now, though, we&#039;re going to put this onto &#039;&#039;CHANNEL_POINT_REDEEM&#039;&#039; so we can test this without spending money. Set that and then set the Channel Point Cost to 100.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Adding Functionality ==&lt;br /&gt;
[[File:VTI Target Tutorial Step3.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Finally, it&#039;s time to add in the [[VTI Drivers|Driver]] we picked out in Step 1. Simply add a new component and select the [[VTIObjectToggle]] script. Note that it has a few inputs of its own. The ones we care about for the moment are &#039;&#039;Target&#039;&#039; and &#039;&#039;Reset Time&#039;&#039;. Drag the &amp;quot;SpookyCube&amp;quot; GameObject into the &#039;&#039;Target&#039;&#039; input.&lt;br /&gt;
&lt;br /&gt;
For &#039;&#039;Reset Time&#039;&#039;, we need to determine how long to keep the jumpscare visible for. For this tutorial, 5 seconds is perfectly fine. However, note how in the &#039;&#039;VTI Target&#039;&#039; component, the Cooldown is still set to 1. This can cause our Target to get double-triggered and can make it look weird. To fix this, just match the &#039;&#039;Cooldown&#039;&#039; input to the &#039;&#039;Reset Time&#039;&#039; input, though you may want to add in an extra second or two to &#039;&#039;Cooldown&#039;&#039; to allow for a little bit of a rest between scares. Don&#039;t want to give the Streamer a heart attack or anything.&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all that&#039;s required for a very basic [[VTI Targets|Target]]! At this point, the SpookyCube Target is all ready to go, and you can build your World and give it a test.&lt;br /&gt;
&lt;br /&gt;
== Step 4: User Messaging ==&lt;br /&gt;
[[File:VTI Target Tutorial Step4.png|600px]]&lt;br /&gt;
&lt;br /&gt;
We may have a working Target at this point, but there is one feature we&#039;re not yet utilizing: User Messaging. This was mentioned and glossed over earlier in the tutorial, but now it&#039;s time that we add it on in. Looking at the documentation for [[VTIObjectToggle]], we can see the [[VTI Drivers|Driver]] supports User Messaging by way of two TextMeshPro objects; one for UserName and one for Message.&lt;br /&gt;
&lt;br /&gt;
To add these in, we&#039;re first going to need to do a little adjustment to our hierarchy so we can turn everything on and off, rather than just our jumpscare cube. Create a new Empty with a name of your choice. I went with &amp;quot;Event Object&amp;quot;, as this is the GameObject that we&#039;re going to make [[VTIObjectToggle]] turn on and off rather than SpookyCube itself. Move SpookyCube underneath that in the hierarchy.&lt;br /&gt;
&lt;br /&gt;
Next, we need two TextMeshPro objects to contain our User Messaging. I have cheated here slightly and just copied the TextMeshPro objects out of the [[VTI Target - Event Firework]] example prefab. You can do that too, or go through the effort of setting everything up yourself if you so choose. I choose cheats. Put both of those under the new Empty we just made as well.&lt;br /&gt;
&lt;br /&gt;
Now, go to the [[VTIObjectToggle]] component in Spooky Target and rebind &#039;&#039;Target&#039;&#039; to look at Event Object instead of SpookyCube. While we&#039;re here, also bind the UserText object to the &#039;&#039;User Name Text&#039;&#039; input, and MessageText to &#039;&#039;Message Text&#039;&#039;. Finally, in the &#039;&#039;VTI Target&#039;&#039; component, enabled &#039;&#039;Allow Message Input&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done! When you go into Build and Test mode and link the [[VTI Companion App]] up to the World, the &amp;quot;Cube Jumpscare&amp;quot; redeem will now have a message input added to it automatically. And when activated, the SpookyCube will cause the Streamer to need a change of pants as well as showing who triggered the [[VTI Events|Event]] and a little message to rub salt in the wound.&lt;br /&gt;
&lt;br /&gt;
As an final note, &#039;&#039;Allow Message Input&#039;&#039; is not required to show the UserName of the person who triggered this Target. If &#039;&#039;User Name Text&#039;&#039; is bound and &#039;&#039;Allow Message Input&#039;&#039; is disabled, just the UserName (and [[VTIObjectToggle]]&#039;s &amp;quot;Event Verb&amp;quot;) will be displayed!&lt;br /&gt;
&lt;br /&gt;
== Closing ==&lt;br /&gt;
That&#039;s about all there is to creating your own [[VTI Targets]]. The [[VTI World Kit]] has been created in a way that should allow World Creators to easily create with it with only minimal fuss. As mentioned at the start, the majority of custom [[VTI Targets]] should be able to be created using the [[VTI Drivers|Drivers]] supplied by the [[VTI World Kit]].&lt;br /&gt;
&lt;br /&gt;
However, if you would like to dig a little deeper and learn how to create more complex functionality using code, read the next tutorial: [[Creating Custom VTI Drivers]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Target_Tutorial_Step4.png&amp;diff=69</id>
		<title>File:VTI Target Tutorial Step4.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Target_Tutorial_Step4.png&amp;diff=69"/>
		<updated>2024-02-18T03:47:43Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap of the Unity Editor showing the addition of two TextMeshPro objects, a hierarchy change, and linking said TMP objects to the [[VTIObjectToggle]] [[VTI Drivers|Driver]] in step 4 of [[Creating VTI Targets]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIRadialTripObjectToggle&amp;diff=68</id>
		<title>VTIRadialTripObjectToggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIRadialTripObjectToggle&amp;diff=68"/>
		<updated>2024-02-18T03:43:44Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIRadialTripObjectToggle is a [[VTI Drivers|VTI Driver]] that operates similarly to [[VTIObjectToggle]]. However, Firing this Driver will set it to be &amp;quot;Armed&amp;quot; and wait until a Player enters a given Radius to trigger.&lt;br /&gt;
&lt;br /&gt;
Useful for jumpscares.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || Yes - Uses two TextMeshPro objects for Username and Message Inputs&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes - Appends Trigger Verb to UserName String&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Target || GameObject || The GameObject to toggle on/off when Firing.&lt;br /&gt;
|-&lt;br /&gt;
| UserNameText || TextMeshPro || The TMP object to populate with UserName and Verb text.&lt;br /&gt;
|-&lt;br /&gt;
| MessageText || TextMeshPro || The TMP object to populate with User Message text.&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to keep Target enabled for before disabling.&lt;br /&gt;
|-&lt;br /&gt;
| OnlyPOVTrigger || bool || When enabled, only the Streamer&#039;s client can trip the radius check. Else, any Player can trip.&lt;br /&gt;
|-&lt;br /&gt;
| CheckRadius || float || The distance (in meters) a Player has to be within before this Driver &amp;quot;Detonates&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| CheckRate || float || How long (in seconds) to wait between checking for nearby Players. Lower numbers are more responsive and less likely to &amp;quot;miss&amp;quot; if players are moving at speed; higher numbers are more performant.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIRadialTripObjectToggle&amp;diff=67</id>
		<title>VTIRadialTripObjectToggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIRadialTripObjectToggle&amp;diff=67"/>
		<updated>2024-02-18T03:43:38Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIRadialTripObjectToggle is a [[VTI Drivers|VTI Driver]] that operates similarly to [[VTIObjectToggle]]. However, Firing this Driver will set it to be &amp;quot;Armed&amp;quot; and wait until a Player enters a given Radius to trigger.&lt;br /&gt;
&lt;br /&gt;
Useful for jumpscares.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || Yess - Uses two TextMeshPro objects for Username and Message Inputs&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes - Appends Trigger Verb to UserName String&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Target || GameObject || The GameObject to toggle on/off when Firing.&lt;br /&gt;
|-&lt;br /&gt;
| UserNameText || TextMeshPro || The TMP object to populate with UserName and Verb text.&lt;br /&gt;
|-&lt;br /&gt;
| MessageText || TextMeshPro || The TMP object to populate with User Message text.&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to keep Target enabled for before disabling.&lt;br /&gt;
|-&lt;br /&gt;
| OnlyPOVTrigger || bool || When enabled, only the Streamer&#039;s client can trip the radius check. Else, any Player can trip.&lt;br /&gt;
|-&lt;br /&gt;
| CheckRadius || float || The distance (in meters) a Player has to be within before this Driver &amp;quot;Detonates&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| CheckRate || float || How long (in seconds) to wait between checking for nearby Players. Lower numbers are more responsive and less likely to &amp;quot;miss&amp;quot; if players are moving at speed; higher numbers are more performant.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIObjectToggle&amp;diff=66</id>
		<title>VTIObjectToggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIObjectToggle&amp;diff=66"/>
		<updated>2024-02-18T03:43:26Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Clarified User Messaging support style.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIObjectToggle is a [[VTI Drivers|VTI Driver]] that will enable a target GameObject when fired, wait for a given amount of time, and then disable the target.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || Yes - Uses two TextMeshPro objects for Username and Message Inputs&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes - Appends Trigger Verb to UserName String&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Target || GameObject || The GameObject to toggle on/off when Firing.&lt;br /&gt;
|-&lt;br /&gt;
| UserNameText || TextMeshPro || The TMP object to populate with UserName and Verb text.&lt;br /&gt;
|-&lt;br /&gt;
| MessageText || TextMeshPro || The TMP object to populate with User Message text.&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to keep Target enabled for before disabling.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Target_Tutorial_Step3.png&amp;diff=65</id>
		<title>File:VTI Target Tutorial Step3.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Target_Tutorial_Step3.png&amp;diff=65"/>
		<updated>2024-02-18T02:44:40Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap depicting the addition of the [[VTIObjectToggle]] [[VTI Drivers|Driver]] to the [[VTI Targets|Target]] in the [[Creating VTI Targets]] tutorial.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Target_Tutorial_Step2.png&amp;diff=64</id>
		<title>File:VTI Target Tutorial Step2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Target_Tutorial_Step2.png&amp;diff=64"/>
		<updated>2024-02-18T02:09:30Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap showing the hierarchy changes and the added VTI Target component for step 2 of [[Creating VTI Targets]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTI_Target_Tutorial_Step1.png&amp;diff=63</id>
		<title>File:VTI Target Tutorial Step1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTI_Target_Tutorial_Step1.png&amp;diff=63"/>
		<updated>2024-02-18T02:00:14Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap depicting the initial state of the [[Creating VTI Targets]] tutorial.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VRChat_Twitch_Integration&amp;diff=62</id>
		<title>VRChat Twitch Integration</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VRChat_Twitch_Integration&amp;diff=62"/>
		<updated>2024-02-18T01:41:46Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: /* Documentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
{{DISPLAYTITLE:VRChat Twitch Integration (For Worlds!)}}&lt;br /&gt;
&lt;br /&gt;
[[File:VTI Media Banner.png|thumb|250px]]&lt;br /&gt;
VRChat Twitch Integration (For Worlds!), or VTI for short, is a tool that enables interactions from Twitch viewers to have a tangible effect on VRChat Worlds. This tool has two major components: the VTI World Kit, and the VTI Companion App, which work in conjunction with the VRChat client to trigger in-world events without requiring modifications to the client.&lt;br /&gt;
&lt;br /&gt;
This article serves as the landing page and lookup directory for VTI Documentation. Please use the sections below to find what you need.&lt;br /&gt;
&lt;br /&gt;
[https://stevegreendesign.com/project/vti/ View The VTI Project Page]&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
* [[VTI Troubleshooting|Troubleshooting and Known Issues]]&lt;br /&gt;
* [[VTI Function Overview|How Does VTI Work?]]&lt;br /&gt;
* [[VTI Compatibility|How Does VTI Handle Backwards Compatibility?]]&lt;br /&gt;
* [[Sentry|What Is Sentry?]]&lt;br /&gt;
&lt;br /&gt;
== VTI Companion App ==&lt;br /&gt;
* [[VTI Companion App|About The Companion App]]&lt;br /&gt;
* [[VTI Companion Setup|Getting Started]]&lt;br /&gt;
* [[VTI Companion Walkthrough|How To Use the Companion]]&lt;br /&gt;
* [[VTI Demo World|The VTI Demo World]]&lt;br /&gt;
&lt;br /&gt;
== VTI World Kit ==&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
* [[VTI World Kit|About the VTI World Kit]]&lt;br /&gt;
* [[VTI Targets|Targets]]&lt;br /&gt;
* [[VTI Drivers|Drivers]]&lt;br /&gt;
* [[VTI Example Prefabs|Example Prefabs]]&lt;br /&gt;
&lt;br /&gt;
==== Tutorials ====&lt;br /&gt;
* [[VTI World Kit Setup]]&lt;br /&gt;
* [[Creating VTI Targets]]&lt;br /&gt;
* [[Creating Custom VTI Drivers]]&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VRChat_Twitch_Integration&amp;diff=61</id>
		<title>VRChat Twitch Integration</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VRChat_Twitch_Integration&amp;diff=61"/>
		<updated>2024-02-18T01:41:23Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: VTI World Kit list restructure&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
{{DISPLAYTITLE:VRChat Twitch Integration (For Worlds!)}}&lt;br /&gt;
&lt;br /&gt;
[[File:VTI Media Banner.png|thumb|250px]]&lt;br /&gt;
VRChat Twitch Integration (For Worlds!), or VTI for short, is a tool that enables interactions from Twitch viewers to have a tangible effect on VRChat Worlds. This tool has two major components: the VTI World Kit, and the VTI Companion App, which work in conjunction with the VRChat client to trigger in-world events without requiring modifications to the client.&lt;br /&gt;
&lt;br /&gt;
This article serves as the landing page and lookup directory for VTI Documentation. Please use the sections below to find what you need.&lt;br /&gt;
&lt;br /&gt;
[https://stevegreendesign.com/project/vti/ View The VTI Project Page]&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
* [[VTI Troubleshooting|Troubleshooting and Known Issues]]&lt;br /&gt;
* [[VTI Function Overview|How Does VTI Work?]]&lt;br /&gt;
* [[VTI Compatibility|How Does VTI Handle Backwards Compatibility?]]&lt;br /&gt;
* [[Sentry|What Is Sentry?]]&lt;br /&gt;
&lt;br /&gt;
== VTI Companion App ==&lt;br /&gt;
* [[VTI Companion App|About The Companion App]]&lt;br /&gt;
* [[VTI Companion Setup|Getting Started]]&lt;br /&gt;
* [[VTI Companion Walkthrough|How To Use the Companion]]&lt;br /&gt;
* [[VTI Demo World|The VTI Demo World]]&lt;br /&gt;
&lt;br /&gt;
== VTI World Kit ==&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
* [[VTI World Kit|About the VTI World Kit]]&lt;br /&gt;
* [[VTI Targets|Targets]]&lt;br /&gt;
* [[VTI Drivers|Drivers]]&lt;br /&gt;
* [[VTI Example Prefabs|Examples]]&lt;br /&gt;
&lt;br /&gt;
==== Tutorials ====&lt;br /&gt;
* [[VTI World Kit Setup]]&lt;br /&gt;
* [[Creating VTI Targets]]&lt;br /&gt;
* [[Creating Custom VTI Drivers]]&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Targets&amp;diff=60</id>
		<title>VTI Targets</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Targets&amp;diff=60"/>
		<updated>2024-02-16T10:47:13Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Added section about network ownership.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTITarget Inspector.png|thumb|400px|VTITarget&#039;s Inspector]]&lt;br /&gt;
&lt;br /&gt;
The VTITarget component is one of the core scripts for the [[VTI World Kit]]. It is used to identify a GameObject as something that can be interacted with  by Twitch viewers when running [[VRChat Twitch Integration]].&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Properties&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| ID || The Unique Identifier for this Target. Used internally to dispatch [[VTI Events|Events]]. Must not match any other VTITargets in the scene or a warning will be thrown.&lt;br /&gt;
|-&lt;br /&gt;
| Display Name || The User-Friendly name for this Target. Used in the [[VTI Companion App]]&#039;s Target editor and when generating Channel Point Rewards. Does not need to be unique.&lt;br /&gt;
|-&lt;br /&gt;
| Description || A short sentence describing the usage of this Target. Used in the [[VTI Companion App]]&#039;s Target editor and when generating Channel Point Rewards.&lt;br /&gt;
|-&lt;br /&gt;
| Cooldown || The number of seconds to wait before this Target can be fired again. Set this to at least as long as the events run by any attached [[VTI Drivers]] unless they are capable of being interrupted or overlapped.&lt;br /&gt;
|-&lt;br /&gt;
| Allow Message Input || Enable this when any attached [[VTI Drivers]] expect User Messaging in order to function.&lt;br /&gt;
|-&lt;br /&gt;
| Allow Event Type Rebinding || If any attached [[VTI Drivers]] are specifically tailored to one specific event, disable this. For example: a Driver that expects a chat command with a specific argument will likely not work when set to SUBCRIBE_GIFT.&lt;br /&gt;
|-&lt;br /&gt;
| Default Event Type || What Twitch Event this Target should be fired on. This presents as a dropdown for all [https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types EventSub Subscription Types] currently supported by [[VRChat Twitch Integration|VTI]].&lt;br /&gt;
|-&lt;br /&gt;
| Default Twitch Binding Settings || This section is dynamically displayed based on which Event Type is selected. Use this area to tune exactly what parameters are required to fire this Target. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Return !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| VTICheckCanFire() || bool || Check whether or not this Target is off cooldown and all attached [[VTI Drivers|Drivers]] are reporting Ready.&lt;br /&gt;
|-&lt;br /&gt;
| VTIFire() || void || Trigger this Target. Forwards [[VTI Events|Event]] data to all attached [[VTI Drivers|Drivers]] and calls &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Driver.VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; on each.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Event Firing ==&lt;br /&gt;
When the [[VTI Event Handler]] receives an [[VTI Events|Event]] from the [[VTI Companion App]], it will enqueue it under the ID of the triggered Target. Once that Event is at the top of the Queue, the Event Handler will attempt to dispatch the Event data to the Target and then call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIFire()&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Once Fired, the VTITarget will forward the Event data to each [[VTI Drivers|Driver]] component within the same GameObject as the VTITarget component, and then call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; on each Driver.&lt;br /&gt;
&lt;br /&gt;
==== Readiness Validation ====&lt;br /&gt;
Before firing, the [[VTI Event Handler]] will call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckCanFire()&amp;lt;/syntaxhighlight&amp;gt; against the queued VTITarget. This will first check the current time against the Cooldown property, and then will loop through all attached [[VTI Drivers|Driver]] component and call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; on each. If any Driver returns &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;false&amp;lt;/syntaxhighlight&amp;gt;, or the Cooldown has not yet elapsed, the Event is skipped and the process repeats for the next in line.&lt;br /&gt;
&lt;br /&gt;
==== Network Ownership ====&lt;br /&gt;
As a final step before firing, the [[VTI World Kit]] will attempt to take [https://creators.vrchat.com/worlds/udon/networking/ Ownership] of the GameObject. In order to prevent desynced cooldowns from double-firing or overriding another Streamer&#039;s [[VTI Events|Events]], the VTITarget script will also refuse ownership transfer if it is still in use. Objects that the [[VTI World Kit]] cannot take Ownership of will stay on the queue until Ownership can be obtained. If this results in an [[VTI Events|Event]] that never fires, check to make sure you don&#039;t have other things trying to keep Ownership of that object, e.g. scripts on a Pickup with the VRCObjectSync component attached.&lt;br /&gt;
&lt;br /&gt;
== User Messaging ==&lt;br /&gt;
[[VRChat Twitch Integration|VTI]] supports Twitch viewers sending messages into the VRChat World through [[VTI Events]]. When the Allow Message Input property is enabled, [[VRChat Twitch Integration|VTI]] will automatically handle several aspects on the backend (see below), and VTITarget will ingest these messages to be passed onto any attached [[VTI Drivers|Drivers]].&lt;br /&gt;
&lt;br /&gt;
==== Bits ====&lt;br /&gt;
In CHEER mode, the user&#039;s entire message with the cheered Bits is transmitted in the Message value.&lt;br /&gt;
&lt;br /&gt;
==== Subscriptions ====&lt;br /&gt;
&#039;&#039;&#039;ISSUE&#039;&#039;&#039;: Resubscription User Messaging is not yet supported. This is due to some strangeness in how the Twitch API handles returning Subscriber messages. The &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;channel.subscribe&amp;lt;/syntaxhighlight&amp;gt; event doesn&#039;t contain message data, and the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;channel.subscribe.message&amp;lt;/syntaxhighlight&amp;gt; event fires alongside the former, duplicating triggers. Update 1 is slated to correct this and implement Subscription messages properly.&lt;br /&gt;
&lt;br /&gt;
==== Channel Point Rewards ====&lt;br /&gt;
In CHANNEL_POINT_REDEEM mode, [[VRChat Twitch Integration|VTI]] will automatically set the Channel Point Reward to require the user to input a message with the redemption.&lt;br /&gt;
&lt;br /&gt;
==== Chat Commands ====&lt;br /&gt;
When the Event Type is bound to &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;CHAT_COMMAND&amp;lt;/syntaxhighlight&amp;gt;, the Message value will be set in one of two ways.&lt;br /&gt;
&lt;br /&gt;
===== Exact =====&lt;br /&gt;
In EXACT mode, the first word of the user&#039;s string is treated as the Command (ex: &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;!fire&amp;lt;/syntaxhighlight&amp;gt;). When Messaging is allowed, everything after the first word is transmitted as the Message value.&lt;br /&gt;
&lt;br /&gt;
===== CONTAINS =====&lt;br /&gt;
In CONTAINS mode, or partial string matching, the [[VTI Events|Event]] is fired whenever the trigger string is found in a user&#039;s chat message. In this mode, when Messaging is allowed, the entire chat string is transmitted as the Message value, including the trigger string.&lt;br /&gt;
&lt;br /&gt;
== Target Prefabs ==&lt;br /&gt;
The [[VTI World Kit]] comes with several pre-made Targets to both demonstrate the capabilities of [[VRChat Twitch Integration|VTI]] as well as speed up World integration by handling some common events.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Prefabs&lt;br /&gt;
|-&lt;br /&gt;
! Prefab Name !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Event Firework]] || A firework fountain that lights when the specified Event Type is triggered. Handles User Messaging and Event Type Rebinding dynamically.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Rocket Command]] || Adds a Chat Command to launch the Streamer into the air. User Messaging is used to determine the &amp;quot;power&amp;quot; of the launch.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Anim Trigger]] || Demonstrates how animations can be triggered by VTI.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Tripmine]] || A mine that explodes when the Streamer gets near. Demonstrates how Events can be used to &amp;quot;Arm&amp;quot; an effect and play it later. Handles User Messaging and Event Type Rebinding dynamically.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Hydrate]] || Plays a shower of water particles and shows a message reminding the Streamer to drink some water. Mimics the incredibly common Channel Point Reward in use by many streamers.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Chat Panel]] || A &amp;quot;Q&amp;amp;A&amp;quot; style panel that accepts User Messaging, queuing up any sent messages to be manually displayed by the Streamer. Demonstrates VTI&#039;s usefulness in Panel-style talk shows.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Events&amp;diff=59</id>
		<title>VTI Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Events&amp;diff=59"/>
		<updated>2024-02-16T10:41:16Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial writeup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
An Event in [[VRChat Twitch Integration|VTI]] refers to an instance of a Twitch user triggering a [[VTI Targets|Target]] in a VRChat World with the [[VTI World Kit]] installed. When a Twitch performs an action that matches the Binding Settings for one or more [[VTI Targets|Targets]], the [[VTI Companion App]] will process the action, then create and enqueue an Event with any pertinent data. Then, when the [[VTI World Kit]] queries for a queue update, all queued Events will be serialized into JSON and sent to the VRChat client.&lt;br /&gt;
&lt;br /&gt;
Once processed by the [[VTI World Kit]], this Event will be queued up for firing once it reaches the front of the queue and its [[VTI Targets|Target Object]] becomes available.&lt;br /&gt;
&lt;br /&gt;
== Event Data ==&lt;br /&gt;
All Events are serialized as JSON upon transmission, and contain the following data:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Event Data&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| ID || Guid || [https://learn.microsoft.com/en-us/dotnet/api/system.guid?view=net-8.0 Globally Unique Identifier] for this Event.&lt;br /&gt;
|-&lt;br /&gt;
| TargetID || string || The Unique ID of the [[VTI Targets|Target Object]].&lt;br /&gt;
|-&lt;br /&gt;
| UserName || string || The Twitch User Name of the user who triggered this Event.&lt;br /&gt;
|-&lt;br /&gt;
| Message || string || The User Message, if applicable, that was sent with this Event.&lt;br /&gt;
|-&lt;br /&gt;
| TriggerCause || string || The reason/event type that caused this Event to be created.&lt;br /&gt;
|-&lt;br /&gt;
| TriggerAmount || int || What &amp;quot;value&amp;quot; is associated with this Event, i.e. how many bits cheered, subs gifted, tier subscribed, etc.&lt;br /&gt;
|-&lt;br /&gt;
| Canceled || bool || Marked &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; when the [[VTI Companion App]] user selects the Cancel button on this Event.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Cancellation of Events ==&lt;br /&gt;
Events can be canceled at any time before they are fired. However, they may still fire after the Cancel button is clicked if the [[VTI World Kit]] does not receive the cancellation update in time before firing. This is due to the long delay imposed by Remote String Loading (see: [[VTI Function Overview]]).&lt;br /&gt;
&lt;br /&gt;
In a future update, Events will be auto-canceled if their triggering action (chat message, channel point redeem, etc) is deleted by moderator action.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIRunMethod&amp;diff=58</id>
		<title>VTIRunMethod</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIRunMethod&amp;diff=58"/>
		<updated>2024-02-14T05:02:39Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial driver page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIRunMethod is a [[VTI Drivers|VTI Driver]] that will run a named method on a target UdonBehaviour using &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;SendCustomEvent()&amp;lt;/syntaxhighlight&amp;gt;. This method must be a &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;public void&amp;lt;/syntaxhighlight&amp;gt; method with no arguments.&lt;br /&gt;
&lt;br /&gt;
User Messaging is supported by using &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;SetProgramVariable()&amp;lt;/syntaxhighlight&amp;gt; to attempt to set the string members &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;UserName&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Message&amp;lt;/syntaxhighlight&amp;gt; on the target UdonBehaviour. If these members exist, they will be set and be available when the method is called.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || Yes - Message Data is sent to Target UdonBehaviour as Program Variables&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || No special support added, but should not break when rebinding&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Target || UdonBehaviour || The UdonBehaviour to call Method on.&lt;br /&gt;
|-&lt;br /&gt;
| Method || string || The name of the Method to run on Target.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIObjectToggle&amp;diff=57</id>
		<title>VTIObjectToggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIObjectToggle&amp;diff=57"/>
		<updated>2024-02-14T04:52:51Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIObjectToggle is a [[VTI Drivers|VTI Driver]] that will enable a target GameObject when fired, wait for a given amount of time, and then disable the target.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes - Appends Trigger Verb to UserName String&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Target || GameObject || The GameObject to toggle on/off when Firing.&lt;br /&gt;
|-&lt;br /&gt;
| UserNameText || TextMeshPro || The TMP object to populate with UserName and Verb text.&lt;br /&gt;
|-&lt;br /&gt;
| MessageText || TextMeshPro || The TMP object to populate with User Message text.&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to keep Target enabled for before disabling.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIAnimTrigger&amp;diff=56</id>
		<title>VTIAnimTrigger</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIAnimTrigger&amp;diff=56"/>
		<updated>2024-02-14T04:52:40Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIAnimTrigger is a [[VTI Drivers|VTI Driver]] that will call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Animator.SetTrigger(TriggerName)&amp;lt;/syntaxhighlight&amp;gt; when fired.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || No&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Anim || Animator || The Animator to target when Firing.&lt;br /&gt;
|-&lt;br /&gt;
| TriggerName || string || The name of the Trigger to activate on Anim.&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to wait before this Driver can be fired again.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIRadialTripObjectToggle&amp;diff=55</id>
		<title>VTIRadialTripObjectToggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIRadialTripObjectToggle&amp;diff=55"/>
		<updated>2024-02-14T04:52:28Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial driver page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIRadialTripObjectToggle is a [[VTI Drivers|VTI Driver]] that operates similarly to [[VTIObjectToggle]]. However, Firing this Driver will set it to be &amp;quot;Armed&amp;quot; and wait until a Player enters a given Radius to trigger.&lt;br /&gt;
&lt;br /&gt;
Useful for jumpscares.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes - Appends Trigger Verb to UserName String&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Target || GameObject || The GameObject to toggle on/off when Firing.&lt;br /&gt;
|-&lt;br /&gt;
| UserNameText || TextMeshPro || The TMP object to populate with UserName and Verb text.&lt;br /&gt;
|-&lt;br /&gt;
| MessageText || TextMeshPro || The TMP object to populate with User Message text.&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to keep Target enabled for before disabling.&lt;br /&gt;
|-&lt;br /&gt;
| OnlyPOVTrigger || bool || When enabled, only the Streamer&#039;s client can trip the radius check. Else, any Player can trip.&lt;br /&gt;
|-&lt;br /&gt;
| CheckRadius || float || The distance (in meters) a Player has to be within before this Driver &amp;quot;Detonates&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| CheckRate || float || How long (in seconds) to wait between checking for nearby Players. Lower numbers are more responsive and less likely to &amp;quot;miss&amp;quot; if players are moving at speed; higher numbers are more performant.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIAnimTrigger&amp;diff=54</id>
		<title>VTIAnimTrigger</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIAnimTrigger&amp;diff=54"/>
		<updated>2024-02-14T04:45:27Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIAnimTrigger is a [[VTI Drivers|VTI Driver]] that will call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Animator.SetTrigger(TriggerName)&amp;lt;/syntaxhighlight&amp;gt; when fired.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || No&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Anim || Animator || The Animator to target when Firing&lt;br /&gt;
|-&lt;br /&gt;
| TriggerName || string || The name of the Trigger to activate on Anim&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to wait before this Driver can be fired again&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIObjectToggle&amp;diff=53</id>
		<title>VTIObjectToggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIObjectToggle&amp;diff=53"/>
		<updated>2024-02-14T04:45:16Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial driver page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIObjectToggle is a [[VTI Drivers|VTI Driver]] that will enable a target GameObject when fired, wait for a given amount of time, and then disable the target.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes - Appends Trigger Verb to UserName String&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Triggers on all Clients, does not sync to new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Target || GameObject || The GameObject to toggle on/off when Firing&lt;br /&gt;
|-&lt;br /&gt;
| UserNameText || TextMeshPro || The TMP object to populate with UserName and Verb text&lt;br /&gt;
|-&lt;br /&gt;
| MessageText || TextMeshPro || The TMP object to populate with User Message text&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to keep Target enabled for before disabling&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTIAnimTrigger&amp;diff=52</id>
		<title>VTIAnimTrigger</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTIAnimTrigger&amp;diff=52"/>
		<updated>2024-02-14T04:40:20Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial driver page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Drivers]]&lt;br /&gt;
&lt;br /&gt;
VTIAnimTrigger is a [[VTI Drivers|VTI Driver]] that will call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Animator.SetTrigger(TriggerName)&amp;lt;/syntaxhighlight&amp;gt; when fired.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Driver Capabilities&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports User Messaging&#039;&#039;&#039; || No&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Supports Dynamic Rebinding&#039;&#039;&#039; || Yes&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Network Sync&#039;&#039;&#039; || Does not sync for new joiners&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Inputs&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Anim || Animator || The Animator to target when Firing&lt;br /&gt;
|-&lt;br /&gt;
| TriggerName || string || The name of the Trigger to activate on Anim&lt;br /&gt;
|-&lt;br /&gt;
| ResetTime || float || How long to wait before this Driver can be fired again&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=Creating_Custom_VTI_Drivers&amp;diff=51</id>
		<title>Creating Custom VTI Drivers</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=Creating_Custom_VTI_Drivers&amp;diff=51"/>
		<updated>2024-02-14T01:06:48Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Added &amp;quot;Next Steps&amp;quot; section and some minor cleanup and code highlighting to previous commits.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Tutorials]]&lt;br /&gt;
&lt;br /&gt;
The [[VTI World Kit]] is designed to be easily extensible by both world designers and programmers alike. To this end, custom Drivers are highly recommended and are built to be fairly simple to create. This article serves as a tutorial on how to create a custom Driver. It will assume basic knowledge of UdonSharp, and will not cover Udon Graph at all (as I think quite poorly of the interface and believe it takes several orders of magnitude more effort and time to do something you can do in just a few lines of C#).&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we will be replicating the [[VTIObjectToggle]] Driver as it demonstrates all the core tenets of how [[VTI Drivers]] function.&lt;br /&gt;
&lt;br /&gt;
== Create the Script ==&lt;br /&gt;
Create a new U# script and open it in your IDE of choice. Change the inherited class from UdonSharpBehaviour to VTIDriverBase. This will let it work with the [[VTI World Kit]] and includes a bunch of necessary methods and members to simplify our Driver setup.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need our control variables so the script can function. As we are turning a GameObject on for a period of time, and then off after it, add a public property for a GameObject a float for the time it will take to reset. For sanity&#039;s sake, also add a call in the Start() method to turn the Target off, to make sure it won&#039;t fire when the level loads.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; highlight=&amp;quot;3,4,8&amp;quot;&amp;gt;&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
{&lt;br /&gt;
	public GameObject Target;&lt;br /&gt;
	public float ResetTime = 5.0f;&lt;br /&gt;
&lt;br /&gt;
	void Start()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Add Core Functionality ==&lt;br /&gt;
The simplest possible [[VTI Drivers|Driver]] only needs to implement the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; method. This is what is called when an [[VTI Events|Event]] is received, all checks have passed, and [[VRChat Twitch Integration|VTI]] is attempting to Fire this Driver&#039;s [[VTI Targets|Target]].&lt;br /&gt;
&lt;br /&gt;
Add a public override void method called VTIEventPlay(). Clear out the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;base.VTIEventPlay();&amp;lt;/syntaxhighlight&amp;gt; line if your IDE added it automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to make the Driver actually do the thing we want it to do, which is to turn on a GameObject, wait, and then turn it off. The first thing we&#039;ll need is to call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Target.SetActive(true)&amp;lt;/syntaxhighlight&amp;gt; in our new method. Then, create another method that will do the exact opposite and call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Target.SetActive(false)&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; highlight=&amp;quot;3,6-9&amp;quot;&amp;gt;&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the core of our functionality, we only need to do one more thing: make &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTarget()&amp;lt;/syntaxhighlight&amp;gt; after a delay. We can do this simply by utilizing the built-in &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;SendCustomEventDelayedSeconds()&amp;lt;/syntaxhighlight&amp;gt; method. Add that into &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; and have it wait for &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTime&amp;lt;/syntaxhighlight&amp;gt; seconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an aside, note the usage of &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;nameof&amp;lt;/syntaxhighlight&amp;gt; instead of just putting &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;&amp;quot;ResetTarget&amp;quot;&amp;lt;/syntaxhighlight&amp;gt; in the first argument. This allows for a measure of safety when maintaining projects later on, as if you need to rename &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTarget()&amp;lt;/syntaxhighlight&amp;gt; for whatever reason, you can utilize something like Visual Studio&#039;s Rename function and not have to worry about manually typing the name change into all the Custom Event calls.&lt;br /&gt;
&lt;br /&gt;
At this end of this section, this is how our script looks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
{&lt;br /&gt;
	public GameObject Target;&lt;br /&gt;
	public float ResetTime = 5.0f;&lt;br /&gt;
&lt;br /&gt;
	void Start()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
		SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dealing With Readiness ==&lt;br /&gt;
For the most basic of Drivers, the Cooldown timer is automatically handled by [[VTI Targets|VTITarget]]. However, in this case, we&#039;re turning an object on and telling VRChat to turn it back off after an arbitrary delay. In some circumstances, you may want your Drivers to be able to overlap themselves when triggered multiple times. But in this case, we have a Custom Event running on a timer, which can cause some level of havoc if we don&#039;t tell VTI that we&#039;re not ready to Fire again.&lt;br /&gt;
&lt;br /&gt;
There are two ways to do this: The &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady&amp;lt;/syntaxhighlight&amp;gt; variable, and adding in a custom &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; method. The former method is exceptionally simple, and all we really need for this tutorial, so we&#039;ll cover that first.&lt;br /&gt;
&lt;br /&gt;
==== The IsReady Boolean ====&lt;br /&gt;
The &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady&amp;lt;/syntaxhighlight&amp;gt; boolean serves as a bit of a &amp;quot;Green Light&amp;quot; to signal the [[VTI World Kit]] that this [[VTI Drivers|Driver]] is ready to go or not. Right now, we need to turn that light &amp;quot;red&amp;quot; while we wait for the Custom Event timer to elapse, and then turn it back to &amp;quot;green&amp;quot; when we&#039;re done. To do this, simply set &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady = false;&amp;lt;/syntaxhighlight&amp;gt; in &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt;, and set it back to &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; in &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTarget()&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; highlight=&amp;quot;3,11&amp;quot;&amp;gt;&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = false;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
		SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = true;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that&#039;s it! By default, &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; will simply return the value of &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady&amp;lt;/syntaxhighlight&amp;gt; unless overridden, so for the purposes of this script, we don&#039;t even need to do anything more than this!&lt;br /&gt;
&lt;br /&gt;
==== VTICheckReady() ====&lt;br /&gt;
However, what if we need to be more complex in our checks to see if we can Fire again or not? In this case, a simple boolean may not be enough. For the purposes of this tutorial, this step is optional, and will only serve as an example of how this can be done another way.&lt;br /&gt;
&lt;br /&gt;
There&#039;s not really much we need to check in a Driver as simple as this, so let&#039;s just be super paranoid about the state of the Target GameObject and ensure that it got turned off before allowing [[VRChat Twitch Integration|VTI]] to Fire this again. To do this, first add in an override for &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Next, replace the auto-generated &amp;quot;base&amp;quot; call (if your IDE made one) with a simple expression to return &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; if both &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady&amp;lt;/syntaxhighlight&amp;gt; is &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; and Target is not currently active. This can look like the below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
	public override bool VTICheckReady()&lt;br /&gt;
	{&lt;br /&gt;
		return IsReady &amp;amp;&amp;amp; !Target.activeSelf;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Basic Driver Complete ==&lt;br /&gt;
And that&#039;s basically it! This Driver can now be attached to a [[VTI Targets|VTITarget]] like any of the base Drivers that came with the [[VTI World Kit]]. Our simple Driver code should now look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
{&lt;br /&gt;
	public GameObject Target;&lt;br /&gt;
	public float ResetTime = 5.0f;&lt;br /&gt;
&lt;br /&gt;
	void Start()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = false;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
		SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = true;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Next Steps =&lt;br /&gt;
Now while we have a completed Driver that does what it needs to do, there are still more things that can be done to improve it. Read on to learn how to handle User Messaging and Dynamic Rebinding.&lt;br /&gt;
&lt;br /&gt;
== User Messaging ==&lt;br /&gt;
With the VTIDriverBase base class, User Messaging is already available for any custom [[VTI Drivers|Driver]], it needs only to be tapped into. The base class includes the following four members that are used to handle [[VTI Events|Event]] data:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;public string UserName&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;public string Message&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;public string TriggerCause&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;public int TriggerAmount&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The latter two variables are for dynamically handling different Triggers and will be covered in the next section. This section concerns the first two strings, UserName and Message. These will automatically be populated by the [[VTI World Kit]] when &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; is called, and can be used at that point to populate any effect you wish your Driver to handle.&lt;br /&gt;
&lt;br /&gt;
For the purposes of this tutorial, we are simply going to put the User Messaging contents into a couple TextMeshPro elements and call it a day. Because the Message can be a lot longer than the UserName, we&#039;re going to use two TMP elements here instead of one, so we can make the two elements different sizes.&lt;br /&gt;
&lt;br /&gt;
Add in two public properties for TextMeshPro elements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
	public TextMeshPro UserNameText;&lt;br /&gt;
	public TextMeshPro MessageText;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we will need to expand our &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; a little bit to actually print out the User Messaging. We can do that simply by setting the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;TextMeshPro.text&amp;lt;/syntaxhighlight&amp;gt; property, but on top of that, we generally want Drivers to be flexible, so we&#039;ll wrap them in validity checks as well just in case this is used on a [[VTI Targets|Target]] that doesn&#039;t utilize User Messaging:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; highlight=&amp;quot;5-8,10-13&amp;quot;&amp;gt;&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = false;&lt;br /&gt;
&lt;br /&gt;
		if (Utilities.IsValid(UserNameText))&lt;br /&gt;
		{&lt;br /&gt;
			UserNameText.text = UserName;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (Utilities.IsValid(MessageText))&lt;br /&gt;
		{&lt;br /&gt;
			MessageText.text = Message;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
		SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And once again, that&#039;s as simple as it needs to be!&lt;br /&gt;
&lt;br /&gt;
== Dynamic Rebinding ==&lt;br /&gt;
For the final section of this tutorial, we&#039;ll be handling the most complicated (and optional) part of making a custom Driver: dealing with a [[VTI Targets|Target]] that has been rebound by the user when Allow Event Type Rebinding is enabled. Now, I say complicated, but purely because this part requires just a modicum of thought put into how to handle the different modes.&lt;br /&gt;
&lt;br /&gt;
For our purposes, we&#039;re simply going to change up the UserName line to say what the user did to trigger the [[VTI Events|Event]]. That is, if the Streamer changed the binding from CHANNEL_POINT_REDEEM to CHEER, we want to put &amp;quot;[username] cheered [x] bits&amp;quot; in the UserNameText element. The way you would detect the type of binding used is with the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;TriggerCause&amp;lt;/syntaxhighlight&amp;gt; string from VTIDriverBase.&lt;br /&gt;
&lt;br /&gt;
From there, we can use the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;TriggerAmount&amp;lt;/syntaxhighlight&amp;gt; value to show how &amp;quot;much&amp;quot; the user did whatever they did to trigger the [[VTI Events|Event]], i.e. how many bits, what tier they subscribed at, how many gifted subs, etc.&lt;br /&gt;
&lt;br /&gt;
==== An Important Note About TriggerCause ====&lt;br /&gt;
Now, I must make a note about how &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;TriggerCause&amp;lt;/syntaxhighlight&amp;gt; works: due to an attempt at future proofing, the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;TriggerCause&amp;lt;/syntaxhighlight&amp;gt; includes the origin service name at the front of the string, as I would &#039;&#039;&#039;like to&#039;&#039;&#039; support other Streaming platforms like YouTube or TikTok at some point in the future, and these services all have different methods of interacting with the stream. For instance, if the [[VTI Targets|Target]] is bound to the FOLLOW event type, the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;TriggerCause&amp;lt;/syntaxhighlight&amp;gt; will be set to &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;&amp;quot;TWITCH_FOLLOW&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The way I handled it in [[VTIObjectToggle]] was to simply have a method with a Switch-Case statement that returns a suffix string for each supported event type. This is not the only way to do this, but it worked for my purposes and so we&#039;ll do it here. Add in the following method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
	private string GetEventVerb(int amount = 0)&lt;br /&gt;
	{&lt;br /&gt;
		switch (TriggerCause)&lt;br /&gt;
		{&lt;br /&gt;
			case &amp;quot;TWITCH_FOLLOW&amp;quot;:&lt;br /&gt;
				return &amp;quot; followed&amp;quot;;&lt;br /&gt;
			case &amp;quot;TWITCH_SUBSCRIBE&amp;quot;:&lt;br /&gt;
				return &amp;quot; subscribed (Tier &amp;quot; + amount + &amp;quot;)&amp;quot;;&lt;br /&gt;
			case &amp;quot;TWITCH_SUBSCRIBE_GIFT&amp;quot;:&lt;br /&gt;
				return &amp;quot; gifted &amp;quot; + amount + &amp;quot; subs&amp;quot;;&lt;br /&gt;
			case &amp;quot;TWITCH_CHEER&amp;quot;:&lt;br /&gt;
				return &amp;quot; cheered &amp;quot; + amount + &amp;quot; bits&amp;quot;;&lt;br /&gt;
			default:&lt;br /&gt;
				return &amp;quot;&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method will take in &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;TriggerAmount&amp;lt;/syntaxhighlight&amp;gt; as an argument, look at &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;TriggerCause&amp;lt;/syntaxhighlight&amp;gt;, and branch to what suffix it needs to append to match the bound event type. With the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;default&amp;lt;/syntaxhighlight&amp;gt; case, we&#039;re simply returning an empty string since we don&#039;t care to add anything for something like CHAT_COMMAND or CHANNEL_POINT_REDEEM.&lt;br /&gt;
&lt;br /&gt;
Finally, we just need to adjust our &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; method to apply this new method to the string, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; highlight=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
		if (Utilities.IsValid(UserNameText))&lt;br /&gt;
		{&lt;br /&gt;
			UserNameText.text = UserName + GetEventVerb(TriggerAmount);&lt;br /&gt;
		}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing ==&lt;br /&gt;
And that&#039;s about all there is to making a custom [[VTI Drivers|Driver]]. This may have been a bit of a long-winded article, but I wanted to explain all the steps along the way to making a custom Driver, rather than just throwing the final code at the screen and making you look at it. This tutorial Driver should now be able to be used near-identically to [[VTIObjectToggle]], and the steps we took to get here should be nearly the same for any new applications you wish to add on top of the [[VTI World Kit]].&lt;br /&gt;
&lt;br /&gt;
Here is what our Driver looks like at the end of the tutorial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using TMPro;&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
using VRC.SDKBase;&lt;br /&gt;
&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
{&lt;br /&gt;
	public GameObject Target;&lt;br /&gt;
	public float ResetTime = 5.0f;&lt;br /&gt;
&lt;br /&gt;
	public TextMeshPro UserNameText;&lt;br /&gt;
	public TextMeshPro MessageText;&lt;br /&gt;
&lt;br /&gt;
	void Start()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = false;&lt;br /&gt;
&lt;br /&gt;
		if (Utilities.IsValid(UserNameText))&lt;br /&gt;
		{&lt;br /&gt;
			UserNameText.text = UserName + GetEventVerb(TriggerAmount);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (Utilities.IsValid(MessageText))&lt;br /&gt;
		{&lt;br /&gt;
			MessageText.text = Message;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
		SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = true;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private string GetEventVerb(int amount = 0)&lt;br /&gt;
	{&lt;br /&gt;
		switch (TriggerCause)&lt;br /&gt;
		{&lt;br /&gt;
			case &amp;quot;TWITCH_FOLLOW&amp;quot;:&lt;br /&gt;
				return &amp;quot; followed&amp;quot;;&lt;br /&gt;
			case &amp;quot;TWITCH_SUBSCRIBE&amp;quot;:&lt;br /&gt;
				return &amp;quot; subscribed (Tier &amp;quot; + amount + &amp;quot;)&amp;quot;;&lt;br /&gt;
			case &amp;quot;TWITCH_SUBSCRIBE_GIFT&amp;quot;:&lt;br /&gt;
				return &amp;quot; gifted &amp;quot; + amount + &amp;quot; subs&amp;quot;;&lt;br /&gt;
			case &amp;quot;TWITCH_CHEER&amp;quot;:&lt;br /&gt;
				return &amp;quot; cheered &amp;quot; + amount + &amp;quot; bits&amp;quot;;&lt;br /&gt;
			default:&lt;br /&gt;
				return &amp;quot;&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=Creating_Custom_VTI_Drivers&amp;diff=50</id>
		<title>Creating Custom VTI Drivers</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=Creating_Custom_VTI_Drivers&amp;diff=50"/>
		<updated>2024-02-13T08:39:40Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial tutorial writeup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
[[Category:VTI Tutorials]]&lt;br /&gt;
&lt;br /&gt;
The [[VTI World Kit]] is designed to be easily extensible by both world designers and programmers alike. To this end, custom Drivers are highly recommended and are built to be fairly simple to create. This article serves as a tutorial on how to create a custom Driver. It will assume basic knowledge of UdonSharp.&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we will be replicating the [[VTIObjectToggle]] Driver as it demonstrates all the core tenets of how [[VTI Drivers]] function.&lt;br /&gt;
&lt;br /&gt;
== Create the Script ==&lt;br /&gt;
Create a new U# script and open it in your IDE of choice. Change the inherited class from UdonSharpBehaviour to VTIDriverBase.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need our control variables so the script can function. As we are turning a GameObject on for a period of time, and then off after it, add a public property for a GameObject a float for the time it will take to reset. For sanity&#039;s sake, also add a call in the Start() method to turn the Target off, to make sure it won&#039;t fire when the level loads.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
{&lt;br /&gt;
	public GameObject Target;&lt;br /&gt;
	public float ResetTime = 5.0f;&lt;br /&gt;
&lt;br /&gt;
	void Start()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Add Core Functionality ==&lt;br /&gt;
The simplest possible [[VTI Drivers|Driver]] only needs to implement the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; method. This is what is called when an [[VTI Events|Event]] is received, all checks have passed, and [[VRChat Twitch Integration|VTI]] is attempting to Fire this Driver&#039;s [[VTI Targets|Target]].&lt;br /&gt;
&lt;br /&gt;
Add a public override void method called VTIEventPlay(). Clear out the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;base.VTIEventPlay();&amp;lt;/syntaxhighlight&amp;gt; line if your IDE added it automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to make the Driver actually do the thing we want it to do, which is to turn on a GameObject, wait, and then turn it off. The first thing we&#039;ll need is to call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Target.SetActive(true)&amp;lt;/syntaxhighlight&amp;gt; in our new method. Then, create another method that will do the exact opposite and call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Target.SetActive(false)&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the core of our functionality, we only need to do one more thing: make &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTarget()&amp;lt;/syntaxhighlight&amp;gt; after a delay. We can do this simply by utilizing the built-in &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;SendCustomEventDelayedSeconds()&amp;lt;/syntaxhighlight&amp;gt; method. Add that into &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; and have it wait for &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTime&amp;lt;/syntaxhighlight&amp;gt; seconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an aside, note the usage of &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;nameof&amp;lt;/syntaxhighlight&amp;gt; instead of just putting &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;&amp;quot;ResetTarget&amp;quot;&amp;lt;/syntaxhighlight&amp;gt; in the first argument. This allows for a measure of safety when maintaining projects later on, as if you need to rename &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTarget()&amp;lt;/syntaxhighlight&amp;gt; for whatever reason, you can utilize something like Visual Studio&#039;s Rename function and not have to worry about manually typing the name change into all the Custom Event calls.&lt;br /&gt;
&lt;br /&gt;
At this end of this section, this is how our script looks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
{&lt;br /&gt;
	public GameObject Target;&lt;br /&gt;
	public float ResetTime = 5.0f;&lt;br /&gt;
&lt;br /&gt;
	void Start()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
		SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dealing With Readiness ==&lt;br /&gt;
For the most basic of Drivers, the Cooldown timer is automatically handled by [[VTI Targets|VTITarget]]. However, in this case, we&#039;re turning an object on and telling VRChat to turn it back off after an arbitrary delay. In some circumstances, you may want your Drivers to be able to overlap themselves when triggered multiple times. But in this case, we have a Custom Event running on a timer, which can cause some level of havoc if we don&#039;t tell the parent [[VTI Targets|VTITarget]] that we&#039;re not ready to Fire again.&lt;br /&gt;
&lt;br /&gt;
There are two ways to do this: The &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady&amp;lt;/syntaxhighlight&amp;gt; variable, and adding in a custom &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; method. The former method is exceptionally simple, and all we really need for this tutorial, so we&#039;ll cover that first.&lt;br /&gt;
&lt;br /&gt;
==== The IsReady Boolean ====&lt;br /&gt;
The &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady&amp;lt;/syntaxhighlight&amp;gt; boolean serves as a bit of a &amp;quot;Green Light&amp;quot; to signal the [[VTI World Kit]] that this [[VTI Drivers|Driver]] is ready to go or not. Right now, we need to turn that light &amp;quot;red&amp;quot; while we wait for the Custom Event timer to elapse, and then turn it back to &amp;quot;green&amp;quot; when we&#039;re done. To do this, simply set &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady = false;&amp;lt;/syntaxhighlight&amp;gt; in &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt;, and set it back to &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; in &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTarget()&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = false;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
		SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = true;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that&#039;s it! By default, &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; will simply return the value of &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady&amp;lt;/syntaxhighlight&amp;gt; unless overridden, so for the purposes of this script, we don&#039;t even need to do anything more than this!&lt;br /&gt;
&lt;br /&gt;
==== VTICheckReady() ====&lt;br /&gt;
However, what if we need to be more complex in our checks to see if we can Fire again or not? In this case, a simple boolean may not be enough. For the purposes of this tutorial, this step is optional, and will only serve as an example of how this can be done in another way.&lt;br /&gt;
&lt;br /&gt;
There&#039;s not really much we need to check in a Driver as simple as this, so let&#039;s just be super paranoid about the state of the Target GameObject and ensure that it got turned off before allowing [[VRChat Twitch Integration|VTI]] to Fire this again. To do this, first add in an override for &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Next, replace the auto-generated &amp;quot;base&amp;quot; call (if your IDE made one) with a simple expression to return &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; if both &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;IsReady&amp;lt;/syntaxhighlight&amp;gt; is &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; and Target is not currently active. This can look like the below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
	public override bool VTICheckReady()&lt;br /&gt;
	{&lt;br /&gt;
		return IsReady &amp;amp;&amp;amp; !Target.activeSelf;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing ==&lt;br /&gt;
And that&#039;s basically it! This Driver can now be attached to a [[VTI Targets|VTITarget]] like any of the base Drivers that came with the [[VTI World Kit]]. At a very rough estimate, there are about seven times more words in this tutorial than there are in all of the base Drivers in the Kit combined. Our simple Driver code should now look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using UnityEngine;&lt;br /&gt;
&lt;br /&gt;
public class CustomDriver : VTIDriverBase&lt;br /&gt;
{&lt;br /&gt;
	public GameObject Target;&lt;br /&gt;
	public float ResetTime = 5.0f;&lt;br /&gt;
&lt;br /&gt;
	void Start()&lt;br /&gt;
	{&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public override void VTIEventPlay()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = false;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(true);&lt;br /&gt;
		SendCustomEventDelayedSeconds(nameof(ResetTarget), ResetTime);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void ResetTarget()&lt;br /&gt;
	{&lt;br /&gt;
		IsReady = true;&lt;br /&gt;
&lt;br /&gt;
		Target.SetActive(false);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
This is not all that can be done with a Driver. To continue on, read the next tutorial: [[User Messaging On Custom VTI Drivers]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VRChat_Twitch_Integration&amp;diff=49</id>
		<title>VRChat Twitch Integration</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VRChat_Twitch_Integration&amp;diff=49"/>
		<updated>2024-02-13T07:44:13Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Added Custom Driver tutorial link.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
{{DISPLAYTITLE:VRChat Twitch Integration (For Worlds!)}}&lt;br /&gt;
&lt;br /&gt;
[[File:VTI Media Banner.png|thumb|250px]]&lt;br /&gt;
VRChat Twitch Integration (For Worlds!), or VTI for short, is a tool that enables interactions from Twitch viewers to have a tangible effect on VRChat Worlds. This tool has two major components: the VTI World Kit, and the VTI Companion App, which work in conjunction with the VRChat client to trigger in-world events without requiring modifications to the client.&lt;br /&gt;
&lt;br /&gt;
This article serves as the landing page and lookup directory for VTI Documentation. Please use the sections below to find what you need.&lt;br /&gt;
&lt;br /&gt;
[https://stevegreendesign.com/project/vti/ View The VTI Project Page]&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
* [[VTI Troubleshooting|Troubleshooting and Known Issues]]&lt;br /&gt;
* [[VTI Function Overview|How Does VTI Work?]]&lt;br /&gt;
* [[VTI Compatibility|How Does VTI Handle Backwards Compatibility?]]&lt;br /&gt;
* [[Sentry|What Is Sentry?]]&lt;br /&gt;
&lt;br /&gt;
== VTI Companion App ==&lt;br /&gt;
* [[VTI Companion App|About The Companion App]]&lt;br /&gt;
* [[VTI Companion Setup|Getting Started]]&lt;br /&gt;
* [[VTI Companion Walkthrough|How To Use the Companion]]&lt;br /&gt;
* [[VTI Demo World|The VTI Demo World]]&lt;br /&gt;
&lt;br /&gt;
== VTI World Kit ==&lt;br /&gt;
* [[VTI World Kit|About the VTI World Kit]]&lt;br /&gt;
* [[VTI World Kit Setup|Setting Up VTI]]&lt;br /&gt;
* [[VTI Targets|Targets]]&lt;br /&gt;
* [[VTI Drivers|Drivers]]&lt;br /&gt;
* [[Creating Custom VTI Drivers]]&lt;br /&gt;
* [[VTI Example Prefabs|Examples]]&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Drivers&amp;diff=48</id>
		<title>VTI Drivers</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Drivers&amp;diff=48"/>
		<updated>2024-02-13T07:43:16Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial writeup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTIDriver Inspector.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
In the [[VTI World Kit]], a Driver is a script that acts as an &amp;quot;Endpoint&amp;quot; for when an [[VTI Events|Event]] is received and fired. When attached to the same GameObject as a [[VTI Targets|VTITarget]] component, it will receive Event data when said target is Fired by [[VRChat Twitch Integration|VTI]].&lt;br /&gt;
&lt;br /&gt;
Multiple Drivers can exist under the same [[VTI Targets|Target]], allowing multiple actions to be taken upon firing without needing a bespoke custom Driver.&lt;br /&gt;
&lt;br /&gt;
All Drivers are, and must be, derived from the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIDriverBase&amp;lt;/syntaxhighlight&amp;gt; base class. The base class includes all the below properties and methods when inherited.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Properties&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Type !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| UserName || string || The Twitch User Name of the user who triggered this [[VTI Events|Event]].&lt;br /&gt;
|-&lt;br /&gt;
| Message || string || The User Message, if applicable, that was sent with this [[VTI Events|Event]].&lt;br /&gt;
|-&lt;br /&gt;
| TriggerCause || string || The reason why this was triggered. Use this when Allow Event Type Rebinding is enabled on the [[VTI Targets|VTITarget]] to dynamically handle user-changed bindings.&lt;br /&gt;
|-&lt;br /&gt;
| TriggerAmount || int || What &amp;quot;value&amp;quot; is associated with this Event, i.e. how many bits cheered, subs gifted, tier subscribed, etc.&lt;br /&gt;
|-&lt;br /&gt;
| IsReady || bool || A helper variable to easily mark a Driver as &amp;quot;busy&amp;quot; and unable to refire. Unless overridden in the derived Driver, &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; will default to just returning this value.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Return !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| VTICheckReady() || bool || This method will be called by VTI just before attempting to fire the parent [[VTI Targets|VTITarget]]. Return &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;true&amp;lt;/syntaxhighlight&amp;gt; if this is ready to be fired.&lt;br /&gt;
|-&lt;br /&gt;
| VTIEventPlay() || void || This method will be called by VTI when its parent [[VTI Targets|VTITarget]] is Fired.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Packaged Drivers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Drivers Included With VTI&lt;br /&gt;
|-&lt;br /&gt;
! Driver !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| [[VTIAnimTrigger]] || Sets an Animator&#039;s Trigger input when Fired.&lt;br /&gt;
|- &lt;br /&gt;
| [[VTIObjectToggle]] || When Fired, this Driver will enable the target GameObject, wait for &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;ResetTime&amp;lt;/syntaxhighlight&amp;gt; seconds, and then disable it again.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTIRadialTripObjectToggle]] || A version of [[VTIObjectToggle]] that will &amp;quot;arm&amp;quot; when Fired, and then wait for a Player to get within a set radius before enabling the target GameObject. Will report unready while Armed and not tripped.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTIRunMethod]] || Utilizes &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;SendCustomEvent()&amp;lt;/syntaxhighlight&amp;gt; to trigger a named method on the target UdonBehaviour when Fired. When User Messaging is enabled, this Driver will attempt to set the string variables &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;UserName&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Message&amp;lt;/syntaxhighlight&amp;gt; on the target UdonBehaviour.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Custom Drivers ==&lt;br /&gt;
The [[VTI World Kit]] is designed to be easily extensible by both world designers and programmers alike. To this end, custom Drivers are highly recommended and are built to be fairly simple to create. A custom Driver need only implement one method, &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt;. All other functionality can be added around that, or is already handled by the VTIDriverBase base class.&lt;br /&gt;
&lt;br /&gt;
For an in-depth tutorial on creating a custom Driver, see [[Creating Custom VTI Drivers]].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTIDriver_Inspector.png&amp;diff=47</id>
		<title>File:VTIDriver Inspector.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTIDriver_Inspector.png&amp;diff=47"/>
		<updated>2024-02-13T07:01:58Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap showing an example of a VTI Driver and its parent VTITarget.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Targets&amp;diff=46</id>
		<title>VTI Targets</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Targets&amp;diff=46"/>
		<updated>2024-02-13T06:57:11Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Lots more info for VTITarget.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTITarget Inspector.png|thumb|400px|VTITarget&#039;s Inspector]]&lt;br /&gt;
&lt;br /&gt;
The VTITarget component is one of the core scripts for the [[VTI World Kit]]. It is used to identify a GameObject as something that can be interacted with  by Twitch viewers when running [[VRChat Twitch Integration]].&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Properties&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| ID || The Unique Identifier for this Target. Used internally to dispatch [[VTI Events|Events]]. Must not match any other VTITargets in the scene or a warning will be thrown.&lt;br /&gt;
|-&lt;br /&gt;
| Display Name || The User-Friendly name for this Target. Used in the [[VTI Companion App]]&#039;s Target editor and when generating Channel Point Rewards. Does not need to be unique.&lt;br /&gt;
|-&lt;br /&gt;
| Description || A short sentence describing the usage of this Target. Used in the [[VTI Companion App]]&#039;s Target editor and when generating Channel Point Rewards.&lt;br /&gt;
|-&lt;br /&gt;
| Cooldown || The number of seconds to wait before this Target can be fired again. Set this to at least as long as the events run by any attached [[VTI Drivers]] unless they are capable of being interrupted or overlapped.&lt;br /&gt;
|-&lt;br /&gt;
| Allow Message Input || Enable this when any attached [[VTI Drivers]] expect User Messaging in order to function.&lt;br /&gt;
|-&lt;br /&gt;
| Allow Event Type Rebinding || If any attached [[VTI Drivers]] are specifically tailored to one specific event, disable this. For example: a Driver that expects a chat command with a specific argument will likely not work when set to SUBCRIBE_GIFT.&lt;br /&gt;
|-&lt;br /&gt;
| Default Event Type || What Twitch Event this Target should be fired on. This presents as a dropdown for all [https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types EventSub Subscription Types] currently supported by [[VRChat Twitch Integration|VTI]].&lt;br /&gt;
|-&lt;br /&gt;
| Default Twitch Binding Settings || This section is dynamically displayed based on which Event Type is selected. Use this area to tune exactly what parameters are required to fire this Target. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Return !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| VTICheckCanFire() || bool || Check whether or not this Target is off cooldown and all attached [[VTI Drivers|Drivers]] are reporting Ready.&lt;br /&gt;
|-&lt;br /&gt;
| VTIFire() || void || Trigger this Target. Forwards [[VTI Events|Event]] data to all attached [[VTI Drivers|Drivers]] and calls &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Driver.VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; on each.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Event Firing ==&lt;br /&gt;
When the [[VTI Event Handler]] receives an [[VTI Events|Event]] from the [[VTI Companion App]], it will enqueue it under the ID of the triggered Target. Once that Event is at the top of the Queue, the Event Handler will attempt to dispatch the Event data to the Target and then call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIFire()&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Once Fired, the VTITarget will forward the Event data to each [[VTI Drivers|Driver]] component within the same GameObject as the VTITarget component, and then call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; on each Driver.&lt;br /&gt;
&lt;br /&gt;
==== Readiness Validation ====&lt;br /&gt;
Before firing, the [[VTI Event Handler]] will call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckCanFire()&amp;lt;/syntaxhighlight&amp;gt; against the queued VTITarget. This will first check the current time against the Cooldown property, and then will loop through all attached [[VTI Drivers|Driver]] component and call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; on each. If any Driver returns &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;false&amp;lt;/syntaxhighlight&amp;gt;, or the Cooldown has not yet elapsed, the Event is skipped and the process repeats for the next in line.&lt;br /&gt;
&lt;br /&gt;
== User Messaging ==&lt;br /&gt;
[[VRChat Twitch Integration|VTI]] supports Twitch viewers sending messages into the VRChat World through [[VTI Events]]. When the Allow Message Input property is enabled, [[VRChat Twitch Integration|VTI]] will automatically handle several aspects on the backend (see below), and VTITarget will ingest these messages to be passed onto any attached [[VTI Drivers|Drivers]].&lt;br /&gt;
&lt;br /&gt;
==== Bits ====&lt;br /&gt;
In CHEER mode, the user&#039;s entire message with the cheered Bits is transmitted in the Message value.&lt;br /&gt;
&lt;br /&gt;
==== Subscriptions ====&lt;br /&gt;
&#039;&#039;&#039;ISSUE&#039;&#039;&#039;: Resubscription User Messaging is not yet supported. This is due to some strangeness in how the Twitch API handles returning Subscriber messages. The &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;channel.subscribe&amp;lt;/syntaxhighlight&amp;gt; event doesn&#039;t contain message data, and the &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;channel.subscribe.message&amp;lt;/syntaxhighlight&amp;gt; event fires alongside the former, duplicating triggers. Update 1 is slated to correct this and implement Subscription messages properly.&lt;br /&gt;
&lt;br /&gt;
==== Channel Point Rewards ====&lt;br /&gt;
In CHANNEL_POINT_REDEEM mode, [[VRChat Twitch Integration|VTI]] will automatically set the Channel Point Reward to require the user to input a message with the redemption.&lt;br /&gt;
&lt;br /&gt;
==== Chat Commands ====&lt;br /&gt;
When the Event Type is bound to &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;CHAT_COMMAND&amp;lt;/syntaxhighlight&amp;gt;, the Message value will be set in one of two ways.&lt;br /&gt;
&lt;br /&gt;
===== Exact =====&lt;br /&gt;
In EXACT mode, the first word of the user&#039;s string is treated as the Command (ex: &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;!fire&amp;lt;/syntaxhighlight&amp;gt;). When Messaging is allowed, everything after the first word is transmitted as the Message value.&lt;br /&gt;
&lt;br /&gt;
===== CONTAINS =====&lt;br /&gt;
In CONTAINS mode, or partial string matching, the [[VTI Events|Event]] is fired whenever the trigger string is found in a user&#039;s chat message. In this mode, when Messaging is allowed, the entire chat string is transmitted as the Message value, including the trigger string.&lt;br /&gt;
&lt;br /&gt;
== Target Prefabs ==&lt;br /&gt;
The [[VTI World Kit]] comes with several pre-made Targets to both demonstrate the capabilities of [[VRChat Twitch Integration|VTI]] as well as speed up World integration by handling some common events.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Prefabs&lt;br /&gt;
|-&lt;br /&gt;
! Prefab Name !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Event Firework]] || A firework fountain that lights when the specified Event Type is triggered. Handles User Messaging and Event Type Rebinding dynamically.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Rocket Command]] || Adds a Chat Command to launch the Streamer into the air. User Messaging is used to determine the &amp;quot;power&amp;quot; of the launch.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Anim Trigger]] || Demonstrates how animations can be triggered by VTI.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Tripmine]] || A mine that explodes when the Streamer gets near. Demonstrates how Events can be used to &amp;quot;Arm&amp;quot; an effect and play it later. Handles User Messaging and Event Type Rebinding dynamically.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Hydrate]] || Plays a shower of water particles and shows a message reminding the Streamer to drink some water. Mimics the incredibly common Channel Point Reward in use by many streamers.&lt;br /&gt;
|-&lt;br /&gt;
| [[VTI Target - Chat Panel]] || A &amp;quot;Q&amp;amp;A&amp;quot; style panel that accepts User Messaging, queuing up any sent messages to be manually displayed by the Streamer. Demonstrates VTI&#039;s usefulness in Panel-style talk shows.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Targets&amp;diff=45</id>
		<title>VTI Targets</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Targets&amp;diff=45"/>
		<updated>2024-02-13T06:27:16Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: More fleshing out of VTITarget.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTITarget Inspector.png|thumb|400px|VTITarget&#039;s Inspector]]&lt;br /&gt;
&lt;br /&gt;
The VTITarget component is one of the core scripts for the [[VTI World Kit]]. It is used to identify a GameObject as something that can be interacted with  by Twitch viewers when running [[VRChat Twitch Integration]].&lt;br /&gt;
&lt;br /&gt;
== Event Firing ==&lt;br /&gt;
When the [[VTI Event Handler]] receives an [[VTI Events|Event]] from the [[VTI Companion App]], it will enqueue it under the ID of the triggered Target. Once that Event is at the top of the Queue, the Event Handler will attempt to dispatch the Event data to the Target and then call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIFire()&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Once Fired, the VTITarget will forward the Event data to each [[VTI Drivers|Driver]] component within the same GameObject as the VTITarget component, and then call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; on each Driver.&lt;br /&gt;
&lt;br /&gt;
=== Readiness Validation ===&lt;br /&gt;
Before firing, the [[VTI Event Handler]] will call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckCanFire()&amp;lt;/syntaxhighlight&amp;gt; against the queued VTITarget. This will first check the current time against the Cooldown property, and then will loop through all attached [[VTI Drivers|Driver]] component and call &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;VTICheckReady()&amp;lt;/syntaxhighlight&amp;gt; on each. If any Driver returns &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;false&amp;lt;/syntaxhighlight&amp;gt;, or the Cooldown has not yet elapsed, the Event is skipped and the process repeats for the next in line.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Properties&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| ID || The Unique Identifier for this Target. Used internally to dispatch [[VTI Events|Events]]. Must not match any other VTITargets in the scene or a warning will be thrown.&lt;br /&gt;
|-&lt;br /&gt;
| Display Name || The User-Friendly name for this Target. Used in the [[VTI Companion App]]&#039;s Target editor and when generating Channel Point Rewards. Does not need to be unique.&lt;br /&gt;
|-&lt;br /&gt;
| Description || A short sentence describing the usage of this Target. Used in the [[VTI Companion App]]&#039;s Target editor and when generating Channel Point Rewards.&lt;br /&gt;
|-&lt;br /&gt;
| Cooldown || The number of seconds to wait before this Target can be fired again. Set this to at least as long as the events run by any attached [[VTI Drivers]] unless they are capable of being interrupted or overlapped.&lt;br /&gt;
|-&lt;br /&gt;
| Allow Message Input || Enable this when any attached [[VTI Drivers]] expect User Messaging in order to function.&lt;br /&gt;
|-&lt;br /&gt;
| Allow Event Type Rebinding || If any attached [[VTI Drivers]] are specifically tailored to one specific event, disable this. For example: a Driver that expects a chat command with a specific argument will likely not work when set to SUBCRIBE_GIFT.&lt;br /&gt;
|-&lt;br /&gt;
| Default Event Type || What Twitch Event this Target should be fired on. This presents as a dropdown for all [https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types EventSub Subscription Types] currently supported by [[VRChat Twitch Integration|VTI]].&lt;br /&gt;
|-&lt;br /&gt;
| Default Twitch Binding Settings || This section is dynamically displayed based on which Event Type is selected. Use this area to tune exactly what parameters are required to fire this Target. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Return !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| VTICheckCanFire() || bool || Check whether or not this Target is off cooldown and all attached [[VTI Drivers|Drivers]] are reporting Ready.&lt;br /&gt;
|-&lt;br /&gt;
| VTIFire() || void || Trigger this Target. Forwards [[VTI Events|Event]] data to all attached [[VTI Drivers|Drivers]] and calls &amp;lt;syntaxhighlight lang=&amp;quot;csharp&amp;quot; inline&amp;gt;Driver.VTIEventPlay()&amp;lt;/syntaxhighlight&amp;gt; on each.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Targets&amp;diff=44</id>
		<title>VTI Targets</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Targets&amp;diff=44"/>
		<updated>2024-02-13T05:26:41Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial setup save.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTITarget Inspector.png|thumb|400px|VTITarget&#039;s Inspector]]&lt;br /&gt;
&lt;br /&gt;
The VTITarget component is one of the core scripts for the [[VTI World Kit]]. It is used to identify a GameObject as something that can be interacted with  by Twitch viewers when running [[VRChat Twitch Integration]].&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ VTITarget&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| ID || The Unique Identifier for this Target. Used internally to dispatch [[VTI Events|Events]]. Must not match any other VTITargets in the scene or a warning will be thrown.&lt;br /&gt;
|-&lt;br /&gt;
| Display Name || The User-Friendly name for this Target. Used in the [[VTI Companion App]]&#039;s Target editor and when generating Channel Point Rewards. Does not need to be unique.&lt;br /&gt;
|-&lt;br /&gt;
| Description || A short sentence describing the usage of this Target. Used in the [[VTI Companion App]]&#039;s Target editor and when generating Channel Point Rewards.&lt;br /&gt;
|-&lt;br /&gt;
| Cooldown || The number of seconds to wait before this Target can be fired again. Set this to at least as long as the events run by any attached [[VTI Driver|VTI Drivers]] unless they are capable of being interrupted or overlapped.&lt;br /&gt;
|-&lt;br /&gt;
| Allow Message Input || Enable this when any attached [[VTI Driver|VTI Drivers]] expect User Messaging in order to function.&lt;br /&gt;
|-&lt;br /&gt;
| Allow Event Type Rebinding || If any attached [[VTI Driver|VTI Drivers]] are specifically tailored to one specific event, disable this. For example: a Driver that expects a chat command with a specific argument will likely not work when set to SUBCRIBE_GIFT.&lt;br /&gt;
|-&lt;br /&gt;
| Default Event Type || What Twitch Event this Target should be fired on. This presents as a dropdown for all [https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types EventSub Subscription Types] currently supported by [[VRChat Twitch Integration|VTI]].&lt;br /&gt;
|-&lt;br /&gt;
| Default Twitch Binding Settings || This section is dynamically displayed based on which Event Type is selected. Use this area to tune exactly what parameters are required to fire this Target. &lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=File:VTITarget_Inspector.png&amp;diff=43</id>
		<title>File:VTITarget Inspector.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=File:VTITarget_Inspector.png&amp;diff=43"/>
		<updated>2024-02-13T04:45:36Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A screencap displaying the standard Inspector layout for the VTITarget component.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_World_Kit&amp;diff=42</id>
		<title>VTI World Kit</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_World_Kit&amp;diff=42"/>
		<updated>2024-02-10T02:26:31Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: VTI World Kit stub.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTI Media Banner.png|thumb|200px|link=VRChat Twitch Integration]]&lt;br /&gt;
The VTI World Kit is the VRChat-side component of [[VRChat Twitch Integration]]. It consists of numerous scripts and prefabs in order to enable the [[VTI Companion App]] to communicate with the VRChat World. The VTI spec is also rather flexible, and is set up to allow for easy extensibility for world creators looking to make their own custom events.&lt;br /&gt;
&lt;br /&gt;
Purchase the VTI World Kit: https://stevegreendesign.com/project/vti/&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [[VTI World Kit Setup|Setting Up VTI]]&lt;br /&gt;
* [[VTI Targets|Targets]]&lt;br /&gt;
* [[VTI Drivers|Drivers]]&lt;br /&gt;
* [[VTI Example Prefabs|Examples]]&lt;br /&gt;
* [[VTI Compatibility|How Does VTI Handle Backwards Compatibility?]]&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Companion_App&amp;diff=41</id>
		<title>VTI Companion App</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Companion_App&amp;diff=41"/>
		<updated>2024-02-10T02:11:03Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Resized VTI Logo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
[[File:VTI Media Banner.png|thumb|200px|link=VRChat Twitch Integration]]&lt;br /&gt;
The VTI Companion App is a third-party application for [[VRChat Twitch Integration]]. It acts as a go-between and allows a VRChat World with the [[VTI World Kit]] installed to connect with Twitch and allow a streamer&#039;s chat to trigger special effects. As VRChat itself has no way to connect to web services or APIs like REST on its own, the Companion uses native VRChat functionality to bridge the gap and allow [[VRChat Twitch Integration|VTI]] to function. For more detailed information on how the Companion achieves this, please see [[VTI Function Overview]].&lt;br /&gt;
&lt;br /&gt;
Download the Companion App: https://stevegreendesign.com/project/vti/&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [[VTI Troubleshooting|Troubleshooting and Known Issues]]&lt;br /&gt;
* [[VTI Function Overview|How Does VTI Work?]]&lt;br /&gt;
* [[VTI Companion Setup|Getting Started]]&lt;br /&gt;
* [[VTI Companion Walkthrough|How To Use the Companion]]&lt;br /&gt;
* [[VTI Demo World|The VTI Demo World]]&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Compatibility&amp;diff=40</id>
		<title>VTI Compatibility</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Compatibility&amp;diff=40"/>
		<updated>2024-02-10T01:07:28Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Expanded on &amp;quot;short answer&amp;quot; line.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
If you are reading this article, you may be wondering something along the lines of, &amp;quot;If I implement [[VRChat Twitch Integration|VTI]] in my World, will I have to constantly fix it every time the [[VTI Companion App]] gets updated?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The short answer is &amp;quot;No&amp;quot;. The longer answer is &amp;quot;No, as long as VRChat updates don&#039;t break anything and there are no blocking issues that prevent everything written below.&amp;quot; &lt;br /&gt;
&lt;br /&gt;
== General Approach ==&lt;br /&gt;
When it comes to backwards compatibility, [[VRChat Twitch Integration|VTI]] will follow a simple premise: &#039;&#039;&#039;Old Worlds will be Supported by New Apps, but Old Apps will not Support New Worlds.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Specifically, this means that the goal of the VTI project is to allow any World built on any version of the [[VTI World Kit]] to work in the latest version of the [[VTI Companion App]], but that no effort will be made to have any sort of &amp;quot;underclocking&amp;quot; or &amp;quot;feature lockout&amp;quot; if it detects a user using an older version of the application than that world was built for. This is because the [[VTI World Kit]] is a premium, for-purchase asset, but the [[VTI Companion App]] will always be free.&lt;br /&gt;
&lt;br /&gt;
== Versioning ==&lt;br /&gt;
There are two versions that are checked when the [[VRChat Twitch Integration|VTI]] connection is made in a VTI-capable VRChat world: &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; is the specific interconnect version number between the [[VTI World Kit]] and the [[VTI Companion App]]. This version number will increment if a feature is added that requires more communication between the two sides. It will &#039;&#039;&#039;not&#039;&#039;&#039; increment if a World Kit or Companion update is made that only adds features to that specific side. For example: the [[VTI World Kit]] updates to add more [[VTI Drivers|Driver Types]], which the [[VTI Companion App]] doesn&#039;t need any new info to deal with. In this case, the &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; is &#039;&#039;&#039;not&#039;&#039;&#039; incremented.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt; refers to the backend communication library that VTI uses, called VRChat App Link (VAL). This will only ever increment if the way that the [[VTI World Kit]] and the [[VTI Companion App]] communicate needs to change. For example: VRChat implements OSC for Worlds, and VTI updates to utilize that rather than the current method detailed in [[VTI Function Overview]]. In this hypothetical update, &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt; &#039;&#039;&#039;will&#039;&#039;&#039; increment.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Compatibility&amp;diff=39</id>
		<title>VTI Compatibility</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Compatibility&amp;diff=39"/>
		<updated>2024-02-10T01:06:13Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Fixed typo in Category tag.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
&lt;br /&gt;
If you are reading this article, you may be wondering something along the lines of, &amp;quot;If I implement [[VRChat Twitch Integration|VTI]] in my World, will I have to constantly fix it every time the [[VTI Companion App]] gets updated?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The short answer is &amp;quot;no&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== General Approach ==&lt;br /&gt;
When it comes to backwards compatibility, [[VRChat Twitch Integration|VTI]] will follow a simple premise: &#039;&#039;&#039;Old Worlds will be Supported by New Apps, but Old Apps will not Support New Worlds.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Specifically, this means that the goal of the VTI project is to allow any World built on any version of the [[VTI World Kit]] to work in the latest version of the [[VTI Companion App]], but that no effort will be made to have any sort of &amp;quot;underclocking&amp;quot; or &amp;quot;feature lockout&amp;quot; if it detects a user using an older version of the application than that world was built for. This is because the [[VTI World Kit]] is a premium, for-purchase asset, but the [[VTI Companion App]] will always be free.&lt;br /&gt;
&lt;br /&gt;
== Versioning ==&lt;br /&gt;
There are two versions that are checked when the [[VRChat Twitch Integration|VTI]] connection is made in a VTI-capable VRChat world: &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; is the specific interconnect version number between the [[VTI World Kit]] and the [[VTI Companion App]]. This version number will increment if a feature is added that requires more communication between the two sides. It will &#039;&#039;&#039;not&#039;&#039;&#039; increment if a World Kit or Companion update is made that only adds features to that specific side. For example: the [[VTI World Kit]] updates to add more [[VTI Drivers|Driver Types]], which the [[VTI Companion App]] doesn&#039;t need any new info to deal with. In this case, the &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; is &#039;&#039;&#039;not&#039;&#039;&#039; incremented.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt; refers to the backend communication library that VTI uses, called VRChat App Link (VAL). This will only ever increment if the way that the [[VTI World Kit]] and the [[VTI Companion App]] communicate needs to change. For example: VRChat implements OSC for Worlds, and VTI updates to utilize that rather than the current method detailed in [[VTI Function Overview]]. In this hypothetical update, &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt; &#039;&#039;&#039;will&#039;&#039;&#039; increment.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Compatibility&amp;diff=38</id>
		<title>VTI Compatibility</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Compatibility&amp;diff=38"/>
		<updated>2024-02-10T01:05:52Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Initial writeup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Category:VTI]&lt;br /&gt;
&lt;br /&gt;
If you are reading this article, you may be wondering something along the lines of, &amp;quot;If I implement [[VRChat Twitch Integration|VTI]] in my World, will I have to constantly fix it every time the [[VTI Companion App]] gets updated?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The short answer is &amp;quot;no&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== General Approach ==&lt;br /&gt;
When it comes to backwards compatibility, [[VRChat Twitch Integration|VTI]] will follow a simple premise: &#039;&#039;&#039;Old Worlds will be Supported by New Apps, but Old Apps will not Support New Worlds.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Specifically, this means that the goal of the VTI project is to allow any World built on any version of the [[VTI World Kit]] to work in the latest version of the [[VTI Companion App]], but that no effort will be made to have any sort of &amp;quot;underclocking&amp;quot; or &amp;quot;feature lockout&amp;quot; if it detects a user using an older version of the application than that world was built for. This is because the [[VTI World Kit]] is a premium, for-purchase asset, but the [[VTI Companion App]] will always be free.&lt;br /&gt;
&lt;br /&gt;
== Versioning ==&lt;br /&gt;
There are two versions that are checked when the [[VRChat Twitch Integration|VTI]] connection is made in a VTI-capable VRChat world: &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; is the specific interconnect version number between the [[VTI World Kit]] and the [[VTI Companion App]]. This version number will increment if a feature is added that requires more communication between the two sides. It will &#039;&#039;&#039;not&#039;&#039;&#039; increment if a World Kit or Companion update is made that only adds features to that specific side. For example: the [[VTI World Kit]] updates to add more [[VTI Drivers|Driver Types]], which the [[VTI Companion App]] doesn&#039;t need any new info to deal with. In this case, the &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;VTIVersion&amp;lt;/syntaxhighlight&amp;gt; is &#039;&#039;&#039;not&#039;&#039;&#039; incremented.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt; refers to the backend communication library that VTI uses, called VRChat App Link (VAL). This will only ever increment if the way that the [[VTI World Kit]] and the [[VTI Companion App]] communicate needs to change. For example: VRChat implements OSC for Worlds, and VTI updates to utilize that rather than the current method detailed in [[VTI Function Overview]]. In this hypothetical update, &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;APIVersion&amp;lt;/syntaxhighlight&amp;gt; &#039;&#039;&#039;will&#039;&#039;&#039; increment.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VRChat_Twitch_Integration&amp;diff=37</id>
		<title>VRChat Twitch Integration</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VRChat_Twitch_Integration&amp;diff=37"/>
		<updated>2024-02-10T00:48:09Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Added Backwards Compat. entry.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:VTI]]&lt;br /&gt;
{{DISPLAYTITLE:VRChat Twitch Integration (For Worlds!)}}&lt;br /&gt;
&lt;br /&gt;
[[File:VTI Media Banner.png|thumb|250px]]&lt;br /&gt;
VRChat Twitch Integration (For Worlds!), or VTI for short, is a tool that enables interactions from Twitch viewers to have a tangible effect on VRChat Worlds. This tool has two major components: the VTI World Kit, and the VTI Companion App, which work in conjunction with the VRChat client to trigger in-world events without requiring modifications to the client.&lt;br /&gt;
&lt;br /&gt;
This article serves as the landing page and lookup directory for VTI Documentation. Please use the sections below to find what you need.&lt;br /&gt;
&lt;br /&gt;
[https://stevegreendesign.com/project/vti/ View The VTI Project Page]&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
* [[VTI Troubleshooting|Troubleshooting and Known Issues]]&lt;br /&gt;
* [[VTI Function Overview|How Does VTI Work?]]&lt;br /&gt;
* [[VTI Compatibility|How Does VTI Handle Backwards Compatibility?]]&lt;br /&gt;
* [[Sentry|What Is Sentry?]]&lt;br /&gt;
&lt;br /&gt;
== VTI Companion App ==&lt;br /&gt;
* [[VTI Companion App|About The Companion App]]&lt;br /&gt;
* [[VTI Companion Setup|Getting Started]]&lt;br /&gt;
* [[VTI Companion Walkthrough|How To Use the Companion]]&lt;br /&gt;
* [[VTI Demo World|The VTI Demo World]]&lt;br /&gt;
&lt;br /&gt;
== VTI World Kit ==&lt;br /&gt;
* [[VTI World Kit|About the VTI World Kit]]&lt;br /&gt;
* [[VTI World Kit Setup|Setting Up VTI]]&lt;br /&gt;
* [[VTI Targets|Targets]]&lt;br /&gt;
* [[VTI Drivers|Drivers]]&lt;br /&gt;
* [[VTI Example Prefabs|Examples]]&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=Category:VTI&amp;diff=36</id>
		<title>Category:VTI</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=Category:VTI&amp;diff=36"/>
		<updated>2024-02-10T00:24:05Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Created page with &amp;quot;VTI, or VRChat Twitch Integration (For Worlds!) is a pairing of VRChat Prefabs and a third party application that allows VRChat streamers to let their viewers interact with Worlds and trigger special events.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;VTI, or VRChat Twitch Integration (For Worlds!) is a pairing of VRChat Prefabs and a third party application that allows VRChat streamers to let their viewers interact with Worlds and trigger special events.&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
	<entry>
		<id>https://wiki.steeveeo.com/index.php?title=VTI_Function_Overview&amp;diff=35</id>
		<title>VTI Function Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.steeveeo.com/index.php?title=VTI_Function_Overview&amp;diff=35"/>
		<updated>2024-02-10T00:22:03Z</updated>

		<summary type="html">&lt;p&gt;Steeveeo: Added Category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Category:VTI]&lt;br /&gt;
&lt;br /&gt;
This page details how the [[VRChat Twitch Integration]] prefab pack (known as the [[VTI World Kit]]) works in tandem with the [[VTI Companion App]] in order to transmit Twitch events to the VRChat Client.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The first and probably most important thing to note is that VTI is &#039;&#039;not&#039;&#039; a modification of the VRChat client, and therefore does not break the VRChat Terms of Service, nor does it cause issues with Easy Anti-Cheat. Instead, VTI utilizes [https://creators.vrchat.com/worlds/udon/string-loading/ Remote String Loading] and watches VRChat&#039;s Debug Log. Read on for more details.&lt;br /&gt;
&lt;br /&gt;
== How VTI Talks to VRChat ==&lt;br /&gt;
As previously mentioned, VTI uses [https://creators.vrchat.com/worlds/udon/string-loading/ Remote String Loading] in UdonSharp in order to send data to the VRChat Client. The [[VTI Companion App]] will bundle up all the events that have been triggered through Twitch into it&#039;s Event Queue, and then compile said Queue into JSON.&lt;br /&gt;
&lt;br /&gt;
The [[VTI Companion App]] runs a non-internet-facing websocket on port 12011 and listens for VRChat to query for the next update, at which time it will respond with the above JSON, allowing the VRChat side to load the latest Events. This is why the [[VTI Troubleshooting]] article says that turning on &#039;&#039;Allow Untrusted URLs&#039;&#039; is required, as &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;localhost&amp;lt;/syntaxhighlight&amp;gt; is not on the URL Whitelist.&lt;br /&gt;
&lt;br /&gt;
Because of the reliance on Remote String Loading, VTI can only update the Event Queue once every 5 seconds at the fastest due to how VRChat rate-limits its usage. As this rate-limit is global, VTI will intentionally clamp the fastest update speed to 5.1 seconds to allow any other prefab that uses Remote String Loading to function.&lt;br /&gt;
&lt;br /&gt;
== How VRChat Talks To The Companion ==&lt;br /&gt;
At the time of writing, VRChat does not yet support OSC for anything other than Avatars. Because of this, there is only one way to send info outside of the VRChat client, and that is through its Debug Log. If one reads through their VRChat Debug Logs after using VTI, they might come across quite a few lines with the prefix &amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot; inline&amp;gt;[VAL]&amp;lt;/syntaxhighlight&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;dmesg&amp;quot;&amp;gt;2024.02.04 18:00:51 Log        -  [VAL] VTI_EVENT_RECEIVED|7ed84988-73a9-4060-8b39-3752357f3025&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, VTI has sent the Companion a message saying that it&#039;s acknowledged a specific event, and it will take it from here. The several other signal types can be noted by reading the logs further, but will not be discussed in this article as it is supposed to be a general overview rather than a deep dive.&lt;br /&gt;
&lt;br /&gt;
To note about the prefix, &amp;quot;VAL&amp;quot; stands for &amp;quot;VRChat App Link&amp;quot;, and is the moniker for the internal library that handles the intercommunication between VRChat and an application discussed in this article. At this time of writing, this library has not yet been made public, but plans are in place to do so in the future.&lt;br /&gt;
&lt;br /&gt;
== How VTI Connects with Twitch ==&lt;br /&gt;
The [[VTI Companion App]] connects with the Twitch through its [https://dev.twitch.tv/docs/ API]. Specifically, it utilizes the [https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/ Implicit Grant Flow] method of authentication, which has been determined to be the safest method for both the developer and the end user. Unfortunately, this means that VTI will always pop up a browser window when beginning the Twitch connection as the credentials &#039;&#039;&#039;&#039;&#039;are not stored&#039;&#039;&#039;&#039;&#039; in the VTI Companion nor any of [[WaffleSlapper]]&#039;s or [[Poetica Mechanica]]&#039;s servers. This method also does not require the developer to use a Client Secret (required by other authentication methods) which can be used to cause harm if leaked through the [[VTI Companion App]]&#039;s source code or any external service.&lt;br /&gt;
&lt;br /&gt;
The [[VTI Companion App]] utilizes a customized version of the [https://github.com/SaviorXTanren/StreamingClientLibrary StreamingClientLibrary] by SaviorXTanren, which has been modified to enable the above [https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/ Implicit Grant Flow]. You can view the source code for the fork [https://github.com/Steeveeo/StreamingClientLibrary here].&lt;/div&gt;</summary>
		<author><name>Steeveeo</name></author>
	</entry>
</feed>