<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.figuramc.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Manuel</id>
	<title>FiguraMC - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.figuramc.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Manuel"/>
	<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php/Special:Contributions/Manuel"/>
	<updated>2026-05-29T16:47:34Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Multiplayer_Avatar_Interaction&amp;diff=842</id>
		<title>Multiplayer Avatar Interaction</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Multiplayer_Avatar_Interaction&amp;diff=842"/>
		<updated>2025-01-30T12:30:08Z</updated>

		<summary type="html">&lt;p&gt;Manuel: How to use avatar vars&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Avatars can share values with one another to allow for interactions between them. An example of this would be the various petting scripts you can find in the community.&lt;br /&gt;
&lt;br /&gt;
The basic princible works like this:&lt;br /&gt;
One avatar can store a value.&lt;br /&gt;
Another avatar can get this stored value and do something based on it.&lt;br /&gt;
&lt;br /&gt;
To store a value that other avatars can read you use avatar:store(key, value)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 avatar:store(&amp;quot;amount&amp;quot;, 1)&lt;br /&gt;
&lt;br /&gt;
Note: It is recommended to never store any UserData objects as this could lead to security issues! Best to only store primitives like numbers, strings, or regular tables!&lt;br /&gt;
&lt;br /&gt;
Someone else can then read this value in their script by checking the avatarVars for each player.&lt;br /&gt;
&lt;br /&gt;
 for uuid, vars in pairs(world.avatarVars()) do&lt;br /&gt;
     print(uuid)&lt;br /&gt;
     printTable(vars)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
So for our example you could read the &amp;quot;amount&amp;quot; which we set to 1 and show the player name as well:&lt;br /&gt;
&lt;br /&gt;
 for uuid, vars in pairs(world.avatarVars()) do&lt;br /&gt;
     if vars[&amp;quot;amount&amp;quot;] then&lt;br /&gt;
         local playerName = uuid&lt;br /&gt;
         for name, plr in pairs(world.getPlayers()) do&lt;br /&gt;
             if plr:getUUID() == uuid then&lt;br /&gt;
                 playerName = name&lt;br /&gt;
             end&lt;br /&gt;
         end&lt;br /&gt;
         print(playerName, &amp;quot;has amount of&amp;quot;, vars[key])&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Types/Tables&amp;diff=128</id>
		<title>Tutorials/Types/Tables</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Types/Tables&amp;diff=128"/>
		<updated>2024-09-26T20:45:22Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A table is a Lua value that can store values in specific keys. The act of getting a value from a table using a key is called “indexing”.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;initialize-table&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialize Table ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A table can be created using curly brackets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local t = {}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;generic-indexing&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Generic Indexing ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;table[key]&amp;lt;/code&amp;gt; is the way to index a table. You can either get what is currently at that key, or assign a value to that key. There is no limitation to what can be used as keys or values in a table. If you index a table with an unknown key, it will return &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;. You can also use variables as a key to index a table using this method.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local v = 6&lt;br /&gt;
&lt;br /&gt;
t[2] = &amp;quot;number key, string value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
t[&amp;quot;string key, table value&amp;quot;] = {}&lt;br /&gt;
&lt;br /&gt;
t[false] = true&lt;br /&gt;
&lt;br /&gt;
t[v] = &amp;quot;ree&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
print(t[2]) --&amp;gt; &amp;quot;number key, string value&amp;quot;&lt;br /&gt;
&lt;br /&gt;
print(t[&amp;quot;reeee&amp;quot;]) --&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
print(t[&amp;quot;string key, table value&amp;quot;]) --&amp;gt; table 3be7a8&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;string-indexing-shorthand&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== String Indexing Shorthand ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If that seems like a lot of work to index by a string, yes it is.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;table.key&amp;lt;/code&amp;gt; is the shorthand for indexing a table with a string. This has very specific restrictions for what the string can contain.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Cannot start with a number (&amp;lt;code&amp;gt;t.2fort&amp;lt;/code&amp;gt; will not work. Use &amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt; indexing, or use a different string)&lt;br /&gt;
&lt;br /&gt;
* Cannot contain spaces, periods, or other special characters&lt;br /&gt;
&lt;br /&gt;
* Cannot be Lua Keywords (true, false, local, function)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;t.name = &amp;quot;Katt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
t.age = -1&lt;br /&gt;
&lt;br /&gt;
t.gender = t.name&lt;br /&gt;
&lt;br /&gt;
t.underscores_are_allowed = true&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;object-oriented-method-indexing&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Oriented Method Indexing ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is one more way to index a table. Many of the functions in Figura take in the object that called said function as the first parameter. This is because every object of the same type has the exact same functions. This is done via &amp;lt;code&amp;gt;table:key()&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local posA = player:getPos()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local posB = player.getPos(player)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;initialize-table-with-values&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Initialize Table with Values ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can assign values to keys when the table is initialized. Each key-value pair must be separated by a comma (&amp;lt;code&amp;gt;,&amp;lt;/code&amp;gt;)&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local a = {&lt;br /&gt;
&lt;br /&gt;
    [false] = 1,&lt;br /&gt;
&lt;br /&gt;
    [&amp;quot;string with spaces&amp;quot;] = &amp;quot;string&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    [v] = {&lt;br /&gt;
&lt;br /&gt;
        [&amp;quot;a&amp;quot;] = 1,&lt;br /&gt;
&lt;br /&gt;
        [&amp;quot;b&amp;quot;] = 2,&lt;br /&gt;
&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    -- string shorthand rules still apply. This is equivalent to &amp;lt;code&amp;gt;[&amp;quot;life&amp;quot;] = 42&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    life = 42,&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do not specify an index, the provided values will automatically be assigned a numeric index, starting at &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. This is how arrays are handled in lua, just a table that acts as an array. A table array if you will. Unlike other languages, Lua arrays begin indexing at &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; and functions that take in an array expect the first element at &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local array = {&lt;br /&gt;
&lt;br /&gt;
    42,        -- [1] = 42&lt;br /&gt;
&lt;br /&gt;
    36,        -- [2] = 36&lt;br /&gt;
&lt;br /&gt;
    1024,      -- [3] = 1024&lt;br /&gt;
&lt;br /&gt;
    1,         -- [4] = 1&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;string&amp;quot;,  -- [5] = &amp;quot;string&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    v,         -- [6] = v&lt;br /&gt;
&lt;br /&gt;
    t          -- [7] = t&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- newlines are ignored, as with everything in lua&lt;br /&gt;
&lt;br /&gt;
local array2 = { 42, 36, 1024, 1, &amp;quot;string&amp;quot;, v, t }&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;iterating-over-a-table&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Iterating Over a Table ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Iterating over a table is simple.&amp;lt;br/&amp;gt; You can iterate over every single index using &amp;lt;code&amp;gt;pairs&amp;lt;/code&amp;gt;. This will go through every index, but it will be in an undefined order. &amp;lt;code&amp;gt;pairs&amp;lt;/code&amp;gt; has 2 values it returns when used in a for loop: the current &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt;, and the current &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt; at that &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;for key, value in pairs(t) do&lt;br /&gt;
&lt;br /&gt;
    print(key, value)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the order of the iteration is important, you can use &amp;lt;code&amp;gt;ipairs&amp;lt;/code&amp;gt;, but it only goes over numerical indices. This is what you want to use for table arrays. It starts at index &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, and increments by &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; until the table returns &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;. When used in a for loop, &amp;lt;code&amp;gt;ipairs&amp;lt;/code&amp;gt; returns the current index and the &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt; at that &amp;lt;code&amp;gt;index&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;for index, value in ipairs(array) do&lt;br /&gt;
&lt;br /&gt;
    print(index, value)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;length-of-table-array&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Length of Table Array ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can use the &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt; operator to get the length of a table array. For tables with non-numeric indexes, you have to use &amp;lt;code&amp;gt;pairs&amp;lt;/code&amp;gt; and calculate the length yourself, though the “length” of that kind of table isnt really useful. This follows the same rules as &amp;lt;code&amp;gt;ipairs&amp;lt;/code&amp;gt; in the way that the table’s length is every numeric index until one returns &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;. So &amp;lt;code&amp;gt;#{1,2,3,4}&amp;lt;/code&amp;gt; will return &amp;lt;code&amp;gt;4&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;#{1,2,nil,4}&amp;lt;/code&amp;gt; will return &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt; As an example, &amp;lt;code&amp;gt;ipairs&amp;lt;/code&amp;gt; is pretty much just this.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;for index = 1, #array, 1 do&lt;br /&gt;
&lt;br /&gt;
    print(index, array[index])&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;manipulating-table-arrays&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manipulating Table Arrays ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lua comes built in with ways to manipulate tables. Not all are described here, just the ones that I feel are most important.&amp;lt;br/&amp;gt; All of these functions are available via the &amp;lt;code&amp;gt;tables&amp;lt;/code&amp;gt; global.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;table.insertt-pos-value&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;table.insert(t, pos, value)&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This function can add a value at any index, shifting the other values to account for the added value.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;table.insert(array, 1, “e”)&amp;lt;/code&amp;gt; will insert &amp;lt;code&amp;gt;“e”&amp;lt;/code&amp;gt; at the beggining of the table &amp;lt;code&amp;gt;array&amp;lt;/code&amp;gt;, shifting every other value forward one index.&amp;lt;br/&amp;gt; When adding elements to the end of the array, you use the function as &amp;lt;code&amp;gt;table.insert(t, value)&amp;lt;/code&amp;gt;. So &amp;lt;code&amp;gt;table.insert(array, “l”)&amp;lt;/code&amp;gt; appends &amp;lt;code&amp;gt;“l”&amp;lt;/code&amp;gt; to the end of the table &amp;lt;code&amp;gt;array&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;table.removet-pos&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;table.remove(t, pos)&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This function can remove a value at any index, shifting the other values to account for the removed value. The value that was removed will be returned by this function as well.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;table.remove(array, 1)&amp;lt;/code&amp;gt; will remove the value at index &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; from the table, shifting all the values back an index.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;pos&amp;lt;/code&amp;gt; is optional, with the default value being &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;table.remove(array)&amp;lt;/code&amp;gt; will remove the last value in the table.&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Types/Strings&amp;diff=127</id>
		<title>Tutorials/Types/Strings</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Types/Strings&amp;diff=127"/>
		<updated>2024-09-26T20:45:21Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A string is a Lua value that represents a sequence of characters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Strings are not interpreted as code and are treated as literally being characters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Strings are used with quotation marks (“)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&amp;quot;hello&amp;quot; -- this is a string, as identified by the quotes bracketing it&lt;br /&gt;
&lt;br /&gt;
hello -- not a string&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Types/Numbers&amp;diff=126</id>
		<title>Tutorials/Types/Numbers</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Types/Numbers&amp;diff=126"/>
		<updated>2024-09-26T20:45:21Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A number is a Lua value that represents a real number.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Although Lua doesn’t have an integer type, some methods may ask for integers, this means they want a whole number.&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Types/Functions&amp;diff=125</id>
		<title>Tutorials/Types/Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Types/Functions&amp;diff=125"/>
		<updated>2024-09-26T20:45:20Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A function contains code that can be executed by calling the function. This is useful if you want to use the same code multiple times and can make your code more structured.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To define a function you use the function keyword, then the name of the function and ().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Any code after it will be considered inside this function, until you tell lua that the function is done here by using the end keyword. For better readability we indent the code inside the function using spaces or tabs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The print statement will not execute until the function is called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function hello()&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Hello function!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever you call a function by putting () after the function name, all the code inside the function will run line by line first, before continuing with the rest of your code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;print(&amp;quot;Outside.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
hello()&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Below hello.&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will output the following:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&amp;quot;Outside.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Hello function!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Below hello.&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also give the function some values to work with by putting variable names inside the (). These variables are called parameters. The function can also return a new value itself that is accessible from where the function is called. If no return is specified, the function returns nil (see “Types” section below). Here is an example of a function that calculates the sum of two numbers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function sum(a, b) -- parameters seperated by commas&lt;br /&gt;
&lt;br /&gt;
    local s = a + b -- calculate the sum&lt;br /&gt;
&lt;br /&gt;
    return s -- return the sum to be used by the caller&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local var1 = 2&lt;br /&gt;
&lt;br /&gt;
local var2 = 8&lt;br /&gt;
&lt;br /&gt;
local var3 = sum(var1, var2) -- call the function and pass two variables. note that these do not have to be called a and b&lt;br /&gt;
&lt;br /&gt;
print(var3) --&amp;gt; 10, as you might have noticed, `print` is also a function that takes a parameter&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some functions are called by Figura, you’re probably familiar with events.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.render(delta, context)&lt;br /&gt;
&lt;br /&gt;
    log(context)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case the function is run once a frame (per context) and the parameters are supplied by Figura.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sometimes functions are used as parameters for methods, like setOnLeftClick for actions, and setOnPress for keybinds. Since those methods call the given function (and thus don’t need a name to call them) they can be given anonymous functions. Anonymous functions are simply functions without names.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;myKey:setOnPress(function()&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;hi&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end)&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Types/Booleans&amp;diff=124</id>
		<title>Tutorials/Types/Booleans</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Types/Booleans&amp;diff=124"/>
		<updated>2024-09-26T20:45:19Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A boolean is a Lua value that is either &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, Lua treats all values as if they’re ‘truthy’ or ‘falsey’.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If a value is truthy and it’s in an if statement or a function that wants a boolean value, it’s treated like it’s true.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;if 0 then&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;truthy&amp;quot;) -- numbers are truthy so this will always be logged&lt;br /&gt;
&lt;br /&gt;
else&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;falsey&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a value is falsey and it’s in an if statement or a function that wants a boolean value, it’s treated like it’s false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;if nil then&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;truthy&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
else&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;falsey&amp;quot;) -- nil is falsey so this will always be logged&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The only values that are falsey are false and nil, every other value (numbers, tables, modelparts, etc) is truthy. (nil as a value means there’s no information. It’s literally nothing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;not&amp;lt;/code&amp;gt; operator flips the truthiness of the value into true or false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Examples (all of these are true statements):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;not true == false&lt;br /&gt;
&lt;br /&gt;
not false == true&lt;br /&gt;
&lt;br /&gt;
not nil == true -- a non-boolean value is turned into a boolean&lt;br /&gt;
&lt;br /&gt;
not models == false -- models is a modelpart and truthy, so flipping it turns it into false&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When used in methods &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; usually activates something, and &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; deactivates it. However in some places returning true may turn something off, always read the description of a method, field, or event to discover what boolean does what.&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Sounds&amp;diff=123</id>
		<title>Tutorials/Sounds</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Sounds&amp;diff=123"/>
		<updated>2024-09-26T20:45:15Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Playing sounds tutorial&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using Figura you can play custom sounds and sounds from Minecraft itself.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article assumes you know to avoid calling the player in init.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;playing-a-sound&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Playing A Sound ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most common way to play a sound is through the &amp;lt;code&amp;gt;playSound&amp;lt;/code&amp;gt; function in the sound API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;sounds:playSound(soundID, position, volume, pitch, loop)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see this function takes five arguments, the sound ID, the position it will be played, the volume (this dictates how close players need to be to hear the sound, default is 1), its pitch (default is 1), and whether or not it will start playing immediately after it ends (default is false).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For Minecraft sounds the sound ID is the internal name of the sound, you can find these on the [https://minecraft.wiki/w/Sounds.json/Java_Edition_values Minecraft Wiki] under the Sound Event column. It will play one of the sounds associated with that ID at random.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example, note that the id is a string because it’s in quotes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;sounds:playSound(&amp;quot;entity.bat.ambient&amp;quot;, player:getPos())&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For this example I’m supplying the player position as the location or else it will play at (0,0,0) in the world itself. Because I left out the volume, pitch, and loop, the default values of 1, 1, and false were filled in by Figura. Meaning, it will play with default pitch, default volume, and it won’t loop.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example with the other arguments filled:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;sounds:playSound(&amp;quot;entity.bat.ambient&amp;quot;, player:getPos(), 1, 1, false)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;custom-sounds&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Custom Sounds ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Playing a custom sound is exactly the same as playing a Minecraft sound, except the sound ID is now the name of the sound file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ex: If your file is &amp;lt;code&amp;gt;horn.ogg&amp;lt;/code&amp;gt; then your playSound line would look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;sounds:playSound(&amp;quot;horn&amp;quot;, player:getPos())&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Minecraft will only play specific sound files, namely sounds that are .ogg files. Here’s an [https://audio.online-convert.com/convert-to-ogg online OGG converter]. You will want to change the audio channels setting to &amp;lt;code&amp;gt;mono&amp;lt;/code&amp;gt; and the audio codec to &amp;lt;code&amp;gt;Vorbis&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If your custom sound is stored in a subfolder in the avatar, the subfolder name gets added onto the sound name like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;sounds:playSound(&amp;quot;subfolder.horn&amp;quot;, player:getPos())&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;mono-vs-stereo-sounds&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mono vs Stereo Sounds ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The audio channel type determines if the right and left ear will have two separate channels (meaning that the left and right ears can be different) or if they’ll have the same channel for both ears.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mono sounds are half the size of stereo when it comes to file size. Mono also acts like your average vanilla sound meaning only people near you will be able to hear the sound.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Stereo sounds are much bigger (and sounds are already quite big when it comes to file size) and will play for &#039;&#039;everyone in the server&#039;&#039; similarly to activating an end portal. There’s no way to get around that other than to swap the audio channels to mono.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;alternative-ways-to-play-sounds&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternative Ways To Play Sounds ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to make a long or looping sound follow your movement you’re going to need to use a different method for playing sounds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You have to store a reference to the sound in a variable so you can use it later&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local wDeath = sounds[&amp;quot;entity.wither.death&amp;quot;]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you have the wither death sound available for your use wherever within that local scope.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;wDeath:play():loop(true)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will play the sound and make it loop, but without a position it will be at (0,0,0) in the world.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.tick()&lt;br /&gt;
&lt;br /&gt;
    wDeath:pos(player:getPos())&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local wDeath = sounds[&amp;quot;entity.wither.death&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
wDeath:play():loop(true)&lt;br /&gt;
&lt;br /&gt;
function events.tick()&lt;br /&gt;
&lt;br /&gt;
    wDeath:pos(player:getPos())&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can alter the volume, pitch, and loop with this method as well.&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Pings_(Tutorial)&amp;diff=122</id>
		<title>Pings (Tutorial)</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Pings_(Tutorial)&amp;diff=122"/>
		<updated>2024-09-26T20:45:13Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Information on pings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With normal mods, there is comunication between the Minecraft Server and it’s clients which allows everything to stay in sync. &amp;lt;br/&amp;gt; Figura is completely client-side. It will never comunicate with the Minecraft Server you are connected to. Figura does not have a server-side component, meaning nothing will happen if you put the mod on a server.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What does this mean for you, the user? It means that certain functionality that only your client has access to will not be synced with other players.&amp;lt;br/&amp;gt; Some examples:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Keybinds&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
** If the Minecraft Server tracked every single keystroke, it would be a major security issue. The exact keystrokes are never sent, only the result of those keystrokes.&lt;br /&gt;
&lt;br /&gt;
* Action Wheel&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
** The Action Wheel is a feature added by Figura. Remember how I said that Figura never comunicates with the Minecraft Server? It should be obvious why the Action Wheel isnt synced.&lt;br /&gt;
&lt;br /&gt;
* HostAPI&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
** The HostAPI exclusivly contains variables that only you, the owner of the avatar and the owner of the machine running Minecraft, has access to. All functions contained within are vanilla variables that are not synced with the Minecraft Server. They are wrapped in a nice, explicit package stating that they are never synced. This is unlike the PlayerAPI, which you can assume is always synced (to some extent (I’m looking at you &amp;lt;code&amp;gt;isGrounded&amp;lt;/code&amp;gt;))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So how can we sync information with other players if we cannot do it through the Minecraft Server? The answer is Pings.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;general-pings&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General Pings ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pings utilize Figura’s Backend to sync information with other clients.&amp;lt;br/&amp;gt; Pings are functions that when called, triggers all other clients to call the same function for their instance of your avatar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ping-rate-limiting&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ping Rate Limiting ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The backend restricts you on how much data you can send over a period of time.&amp;lt;br/&amp;gt; The developer given limits are:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* 1024 bytes per second&lt;br /&gt;
&lt;br /&gt;
* 32 pings per second&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If either of these are reached, the backend will ignore any comunication from you for some amount of time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;pingable-values&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pingable Values ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pings can send most primitive types and some userdata types.&amp;lt;br/&amp;gt; All pingable types use a single byte to represent the type of data that is being sent. This byte is not included in the listed byte totals.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt; - 0 Bytes&lt;br /&gt;
&lt;br /&gt;
** if a type that is not supported is used as a parameter, it will be replaced with &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;boolean&amp;lt;/code&amp;gt; - 0 Bytes&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;integer&amp;lt;/code&amp;gt; - 1-4 Bytes&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;code&amp;gt;integers&amp;lt;/code&amp;gt; only take up as many bytes as it needs.&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;code&amp;gt;integers&amp;lt;/code&amp;gt; are signed. For example, to only use a single byte the value must be between -128 and 127.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt; - 8 Bytes&lt;br /&gt;
&lt;br /&gt;
** If the number has a decimal at all, or is outside the range of a 4 byte &amp;lt;code&amp;gt;integer&amp;lt;/code&amp;gt;, it will be sent as a &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;string&amp;lt;/code&amp;gt; - 2+n Bytes&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;code&amp;gt;strings&amp;lt;/code&amp;gt; will always use 2 bytes to store the length.&lt;br /&gt;
&lt;br /&gt;
** Ascii characters will be a single byte each.&lt;br /&gt;
&lt;br /&gt;
** UTF-8 characters will be multiple bytes per character.&lt;br /&gt;
&lt;br /&gt;
** The absolute maximum size of string you can send is &amp;lt;code&amp;gt;65535&amp;lt;/code&amp;gt; characters. If a larger string is sent, it will be truncated.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;table&amp;lt;/code&amp;gt; - Too Many Bytes&lt;br /&gt;
&lt;br /&gt;
** Every key and value is send as data, resulting in high byte costs.&lt;br /&gt;
&lt;br /&gt;
** It is recommended to never send a table over pings.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;VectorN&amp;lt;/code&amp;gt; - 1+8*N Bytes&lt;br /&gt;
&lt;br /&gt;
** Vectors have a single byte that stores the size of the Vector.&lt;br /&gt;
&lt;br /&gt;
** Vectors are always assumed to store &amp;lt;code&amp;gt;doubles&amp;lt;/code&amp;gt;. If you have a Vector of integers, I recommend sending them as 3 seperate arguments instead.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;MatrixN&amp;lt;/code&amp;gt; - 2+8*W*H Bytes&lt;br /&gt;
&lt;br /&gt;
** Matrices store both the width and height of the matrix, then every value as a &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ping&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ping ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Below is an example ping.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function pings.pingName(a)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Ping&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Data Recieved:&amp;quot;, a)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Pong&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It accepts a single variable, which it will print to the chat as an example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To call it, just call it like any other lua function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;pings.pingName(&amp;quot;This is a string wooooooooooooooooo&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you as the host call the ping, the function will execute for all other clients, regardless of their current state.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Do note that if a non-host client reaches a line where a ping gets called, it is completely ignored. No data is sent to the backend, and the contents of the ping will not be executed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ping functions can be passed into functions that expect a function as a parameter, such as Action &amp;lt;code&amp;gt;onToggle&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;actionVariable:onToggle(pings.pingName)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember that we are passing the function itself as a variable. The below would be passing the &#039;&#039;return result&#039;&#039; of the ping function, which is nigh guarenteed to be &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt; as Pings &#039;&#039;should never&#039;&#039; return a value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;--do not do&lt;br /&gt;
&lt;br /&gt;
actionVariable:onToggle(pings.pingName())&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;advanced-pings&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Pings ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Situational techniques that may be handy, depending on the use case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ping-on-init&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ping on Init ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Calling a ping function when the script is first loaded is a horrible idea. The ping will only ever execute for other clients when you, the host, load the avatar. Not only that, it may never be executed on other clients, as they might not have your avatar loaded by the time you broadcast the ping.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
How do we get around this? Well, when you assign a function to an index in the &amp;lt;code&amp;gt;pings&amp;lt;/code&amp;gt; table, the Lua Function gets replaced with a Java Function. This happens because of metatables, specifically the &amp;lt;code&amp;gt;__newindex&amp;lt;/code&amp;gt; metamethod. Functions cannot be modified, so if we store the function before assing it to the &amp;lt;code&amp;gt;pings&amp;lt;/code&amp;gt; table, we can use it like a regular function, and use the same code as a ping function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local function doThing(state)&lt;br /&gt;
&lt;br /&gt;
    models.modelA:setVisible(state)&lt;br /&gt;
&lt;br /&gt;
    models.modelB:setVisible(not state)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
pings.doThing = doThing&lt;br /&gt;
&lt;br /&gt;
-- doThing and pings.doThing are 2 completely seperate values at this point, as the pings table has replaced the index at pings.doThing with a Java Function that wraps the doThing Lua Function.&lt;br /&gt;
&lt;br /&gt;
-- &amp;lt;code&amp;gt;doThing==pings.doThing&amp;lt;/code&amp;gt; will return &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
print(doThing, pings.doThing, doThing == pings.doThing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local keybindState = false&lt;br /&gt;
&lt;br /&gt;
-- I call the local doThing instead of pings.doThing, as pings.doThing is a function that invokes network code.&lt;br /&gt;
&lt;br /&gt;
-- This ensures that the default state is set correctly. If this was a ping function, both models will be visible for other clients until you press the keybind.&lt;br /&gt;
&lt;br /&gt;
doThing(keybindState)&lt;br /&gt;
&lt;br /&gt;
local keyA = keybinds:newKeybind(&amp;quot;KeybindName&amp;quot;, &amp;quot;key.keyboard.k&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
function keyA.press()&lt;br /&gt;
&lt;br /&gt;
    keybindState = not keybindState&lt;br /&gt;
&lt;br /&gt;
    -- We still need to call the ping function in the keybind.&lt;br /&gt;
&lt;br /&gt;
    pings.doThing(keybindState)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The alternative is to reiterate the &amp;lt;code&amp;gt;models.modelA:setVisible(state) models.modelB:setVisible(not state)&amp;lt;/code&amp;gt; part of the ping.&amp;lt;br/&amp;gt; For larger pings it will be combersome to rewrite code that is already defined, which is why this technique is useful.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;byte-array&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Byte Array ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are some situations where you will want to send a large amount of raw bytes, and you need to do it efficiently. The most efficient way is to send a string.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Asside from the 2 constant bytes for the length, a string will always be 1 byte per ascii character (UTF-8 characters are multiple ascii characters, interpreted as a single character). This makes it very consistent in terms of bytes, making it easy to predict and avoid being rate limited.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Below is a basic conversion of a byte array to a string, ready to be pinged and converted back into a byte array on the client’s end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function pings.recieveData(str)&lt;br /&gt;
&lt;br /&gt;
    local byteArray = table.pack(string.byte(str))&lt;br /&gt;
&lt;br /&gt;
    printTable(byteArray)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local packet=[]&lt;br /&gt;
&lt;br /&gt;
for i=1,20 do&lt;br /&gt;
&lt;br /&gt;
    table.insert(packet, math.random(0,255))&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local keyA = keybinds:newKeybind(&amp;quot;KeybindName&amp;quot;, &amp;quot;key.keyboard.k&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
function keyA.press()&lt;br /&gt;
&lt;br /&gt;
    local packedString = string.char(table.unpack(packet))&lt;br /&gt;
&lt;br /&gt;
    pings.recieveData(packedString)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Particles&amp;diff=121</id>
		<title>Tutorials/Particles</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Particles&amp;diff=121"/>
		<updated>2024-09-26T20:45:11Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Spawning particles tutorial&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using the particle API you can spawn particles from Minecraft. These work similarly to the &amp;lt;code&amp;gt;/particle&amp;lt;/code&amp;gt; command in-game. For particles with special properties like dust, they are placed in the name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Most of the article assumes you know to avoid calling the player in init.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;spawning-particles&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Spawning Particles ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;particles:newParticle(particleID, position, velocity)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you’re looking at the [https://minecraft.wiki/w/Particles Minecraft wiki] then the particle id is the name under the ‘Java Edition ID Name’ column. Or, it’s the same id used by the /particle command. If you’re using Minecraft particles you can exclude the Minecraft “mod name”.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;particles:newParticle(&amp;quot;minecraft:explosion&amp;quot;, player:getPos())&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I’ve added the player position, but excluded the velocity.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dust example, it’s color is included in its name:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;particles:newParticle(&amp;quot;dust 0 1 1 1&amp;quot;, player:getPos())&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will spawn an aqua dust particle as the color values need a number between 0 and 1, the fourth number is the alpha. I excluded the ‘minecraft:’ mod name to demonstrate that it’s unnecessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;spawning-at-a-part-location&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Spawning At A Part Location ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To spawn a particle at a modelPart’s position you’ll need to get the position matrix of that part, and insert it into the position like normal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;particles:newParticle(&amp;quot;explosion&amp;quot;, modelPart:partToWorldMatrix():apply())&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;modelPart&amp;lt;/code&amp;gt; is a reference to a real modelPart in your avatar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;an-alternative-method&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== An Alternative Method ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can store a reference to a specific particle, and then use it later to change its properties wile it still exists in the world.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local boom = particles[&amp;quot;explosion&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function events.entity_init()&lt;br /&gt;
&lt;br /&gt;
    boom:spawn():setPos(player:getPos())&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It’s in an entity_init event to protect from an entity init error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;community-resources&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Community Resources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;confetti-by-manuel&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Confetti by Manuel ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Spawns custom particles that you make in Blockbench. [https://github.com/Manuel-3/figura-scripts/tree/main/src/confetti Find it here on GitHub]&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/ModelPart_Indexing&amp;diff=120</id>
		<title>Tutorials/ModelPart Indexing</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/ModelPart_Indexing&amp;diff=120"/>
		<updated>2024-09-26T20:45:11Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;import Emoji from ‘@site/src/components/Emoji’; import FileTreeRoot from ‘@site/src/components/FileTree/Root’; import FileTreeNode from ‘@site/src/components/FileTree/Node’;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page describes the process to access any ModelPart from the global ModelPart &amp;lt;code&amp;gt;models&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;getting-a-modelpart&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Getting a ModelPart =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A property of all ModelParts is that you can get a child ModelPart of a parent ModelPart by [[tutorials/types/Tables#generic-indexing|indexing]] the parent with the child’s name.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;models&amp;lt;/code&amp;gt; itself is a ModelPart. All bbmodel files in the avatar act as child ModelParts to &amp;lt;code&amp;gt;models&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt; Everything in the root of a Blockbench project is a child of the bbmodel ModelPart.&amp;lt;br/&amp;gt; After that, parenting follows the parent structure as defined in the Blockbench OUTLINER.&amp;lt;br/&amp;gt; For example the cube &amp;lt;Emoji icon=&amp;quot;blockbench/cube&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;RightArm&amp;lt;/code&amp;gt;,&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;model.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Head&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Head&amp;quot; icon=&amp;quot;blockbench/cube&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Head Layer&amp;quot; icon=&amp;quot;blockbench/cube&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;RightArm&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;RightArm&amp;quot; icon=&amp;quot;blockbench/cube&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;RightArm Layer&amp;quot; icon=&amp;quot;blockbench/cube&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Would be accessed via &amp;lt;code&amp;gt;models.model.RightArm.RightArm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;figura-model-format&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Figura Model Format ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using the Figura Model Format Blockbench plugin you can right click a group/cube/mesh and copy the path to your clipboard.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To use the plugin open Blockbench and go to &amp;lt;code&amp;gt;File&amp;lt;/code&amp;gt; in the upper left, and go down to the &amp;lt;code&amp;gt;Plugins…&amp;lt;/code&amp;gt; option, you can find &amp;lt;code&amp;gt;Figura Model Format&amp;lt;/code&amp;gt; there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once the plugin is installed, open the Blockbench project and go back to &amp;lt;code&amp;gt;File&amp;lt;/code&amp;gt; and then &amp;lt;code&amp;gt;Convert Project&amp;lt;/code&amp;gt;. Choose the &amp;lt;code&amp;gt;Figura Model&amp;lt;/code&amp;gt; format and press confirm.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After that’s complete you can right click on a group/cube/mesh and copy the path to your clibboard. Note that this path will not include any subfolders the Blockbench model is in.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;storing-a-modelpart&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Storing a ModelPart =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As there is nothing special about indexing straight from &amp;lt;code&amp;gt;models&amp;lt;/code&amp;gt; all the time (its just another ModelPart), if a specific ModelPart is used multiple times in a script we can store it in a variable for ease of access.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;--sets a World parented part to match the player&#039;s position and body rotation&lt;br /&gt;
&lt;br /&gt;
local worldPart = models.model.World&lt;br /&gt;
&lt;br /&gt;
function events.RENDER(delta, context)&lt;br /&gt;
&lt;br /&gt;
    worldPart:setPos(player:getPos(delta) * 16)&lt;br /&gt;
&lt;br /&gt;
    worldPart:setRot(0, -player:getBodyYaw(delta) + 180, 0)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;bbmodels-in-subfolders&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BBmodels in subfolders =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
bbmodel files in subfolders are a special case. For them, the folder itself acts as another ModelPart.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;subfolderA&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Pet.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;bow.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;subfolderB&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;model.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;bow.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The bbmodel &amp;lt;Emoji icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;Pet.bbmodel&amp;lt;/code&amp;gt; would be accessed by &amp;lt;code&amp;gt;models.subfolderA.Pet&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Keybinds&amp;diff=119</id>
		<title>Tutorials/Keybinds</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Keybinds&amp;diff=119"/>
		<updated>2024-09-26T20:45:09Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Keybind tutorial&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Through Figura’s keybind API you can have the script listen for key presses to make things happen. Common uses are to trigger animations or toggle modelParts on and off.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Keybinds are unsynced information, meaning that without a ping other players cannot know that you pressed a key at all. This guide will be using pings with all the example keybinds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: Keybinds can be used while the player is unloaded (aka you are out of render distance), if the player API is called during this time your script will error.&#039;&#039;&#039; You can protect yourself from these errors by adding this check: &amp;lt;code&amp;gt;if not player:isLoaded() then return end&amp;lt;/code&amp;gt; as the first line of code run &#039;&#039;&#039;&#039;&#039;inside the ping.&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;example-keybind&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Keybind ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First things first, you need to initialize the keybind&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local exampleKey = keybinds:newKeybind(&amp;quot;Keybind Name&amp;quot;, &amp;quot;key.keyboard.h&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, the keybind will show up in the avatar’s keybind list- accessible via the Figura menu- with the name Keybind Name and assigned to the letter H. But pressing H won’t do anything yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More keybinds ids can be found in the [[../enums/Keybinds-List.md|KeybindsList]] page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are multiple ways to detect keybinds, but the most common is through &amp;lt;code&amp;gt;press&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; as they are easiest to ping. If you’re not familiar with pings see [[./Pings|Pings]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Underneath creating the key we will be tying the press of the key to a ping function. It’s done underneath as the code is read top-down and the key must exist first.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local exampleKey = keybinds:newKeybind(&amp;quot;Keybind Name&amp;quot;, &amp;quot;key.keyboard.h&amp;quot;, false)&lt;br /&gt;
&lt;br /&gt;
exampleKey.press = pings.examplePing&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This itself won’t do anything until we create the function pings.examplePing, this must be done above where press is assigned to the ping function, because the ping function will need to exist before it can be assigned. If it’s done beneath nothing will happen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The false at the end decides whether or not the keybind will function while a gui like the inventory is opening. It can be skipped and the value will be considered false. If it’s set to true then this keybind will run even while any gui is open or closed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function pings.examplePing()&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Pressed!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local exampleKey = keybinds:newKeybind(&amp;quot;Keybind Name&amp;quot;, &amp;quot;key.keyboard.h&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
exampleKey.press = pings.examplePing&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And there we have it! Now this keybind will send Pressed! in chat every time H is pressed. At this point you could put whatever lines of code you wish into the ping function and it will be synced.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively, &amp;lt;code&amp;gt;release&amp;lt;/code&amp;gt; will run the keybind when the key is released rather than when it is first pressed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;toggling-with-a-keybind&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Toggling With A Keybind ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is going to look extremely similar to the last example, but we are going to add in a boolean that we’re toggling&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local keybindState = true&lt;br /&gt;
&lt;br /&gt;
-- Here the keybindState is true, meaning the first press will swap it to false&lt;br /&gt;
&lt;br /&gt;
-- If you wish the first press to swap to false, change the true to false above&lt;br /&gt;
&lt;br /&gt;
function pings.examplePing(state)&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;state is &amp;quot; .. tostring(state))&lt;br /&gt;
&lt;br /&gt;
    models:setVisible(state)&lt;br /&gt;
&lt;br /&gt;
    -- This will toggle the visibility of all or models, add in a model path to turn on/off specific modelParts&lt;br /&gt;
&lt;br /&gt;
    -- animations.bbmodelName.animationName:setPlaying(not state)&lt;br /&gt;
&lt;br /&gt;
    -- And this is an example of toggling an animation on/off, I&#039;m using not state here because the first press will set this toggle to false and thusly stop the animation, swapping the boolean value like this will make the first press play it&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local exampleKey = keybinds:newKeybind(&amp;quot;Keybind Name&amp;quot;, &amp;quot;key.keyboard.h&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
exampleKey.press = function()&lt;br /&gt;
&lt;br /&gt;
    keybindState = not keybindState&lt;br /&gt;
&lt;br /&gt;
    -- This not is flipping the boolean value between true and false&lt;br /&gt;
&lt;br /&gt;
    pings.examplePing(keybindState)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- This time .press is being tied to a function that is then calling the ping, instead of being &#039;attached&#039; to it directly.&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;detecting-when-a-key-is-held-down&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Detecting When A Key Is Held Down ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have the know-how it is possible to use the &amp;lt;code&amp;gt;isPressed()&amp;lt;/code&amp;gt; function to detect when a key is being held down, but it’s not recommended, as using press and release in conjunction is far more effective.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local keybindState = false&lt;br /&gt;
&lt;br /&gt;
-- keybindState is the variable you will be using to keep track of the pressed-ness of the keybind&lt;br /&gt;
&lt;br /&gt;
function pings.examplePing(state)&lt;br /&gt;
&lt;br /&gt;
    keybindState = state&lt;br /&gt;
&lt;br /&gt;
    -- keybindState is made equivalent to the state sent by press or release for use in other parts of the script&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local exampleKey = keybinds:newKeybind(&amp;quot;Keybind Name&amp;quot;, &amp;quot;key.keyboard.h&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
exampleKey.press = function()&lt;br /&gt;
&lt;br /&gt;
    pings.examplePing(true)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Here, examplePing is sending the boolean value true to the ping function&lt;br /&gt;
&lt;br /&gt;
exampleKey.release = function()&lt;br /&gt;
&lt;br /&gt;
    pings.examplePing(false)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- When it&#039;s released, the boolean value false will be sent, indicating that the key is no longer being pressed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- This is unnecessary, but can be used to track the state of keybindState so you can see it working, at this point you can use keybindState wherever and however you wish- as long as it&#039;s in the same script file&lt;br /&gt;
&lt;br /&gt;
function events.tick()&lt;br /&gt;
&lt;br /&gt;
    log(keybindState)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;canceling-a-key-press&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Canceling A Key Press ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A key press can be “cancelled” (Minecraft won’t register it as being pressed) using &amp;lt;code&amp;gt;return&amp;lt;/code&amp;gt;. Specifically, if you &amp;lt;code&amp;gt;return true&amp;lt;/code&amp;gt; in the function for the key press it will cancel the press. Returning a non-truthy value will not cancel the key press, so you can use a toggling variable to control the return. Note that returning in the ping will not cancel the key press, only doing it inside the keybind’s press function will cancel it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Below is an example for cancelling the detection of the &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; key while also sending a ping.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function pings.examplePing()&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Pressed!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local exampleKey = keybinds:newKeybind(&amp;quot;Keybind Name&amp;quot;, &amp;quot;key.keyboard.w&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
exampleKey.press = function() &lt;br /&gt;
&lt;br /&gt;
    pings.examplePing() return true &lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to cancel without sending a ping, that is completely possible. But the return always has to be at the end of the function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;using-a-vanilla-keybind&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using A Vanilla Keybind ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to detect a vanilla action like attacking or walking forwards but want it to be compatible in the case that someone bound forward to an arrow key you can directly get the vanilla keybind and use it. There’s multiple ways to accomplish this but we’ll use the same method as previous examples.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local exampleKey = keybinds:newKeybind(&amp;quot;Keybind Name&amp;quot;, keybinds:getVanillaKey(&amp;quot;key.forward&amp;quot;))&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will now detect the forward key regardless of what it’s bound to. &amp;lt;code&amp;gt;getVanillaKey()&amp;lt;/code&amp;gt; is going to need a key id from a specific list of ids that all correspond to a vanilla keybind. They can be found in the [[../enums/KeyIDs.md|keyIDs]] enum.&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Emissive_Textures&amp;diff=118</id>
		<title>Tutorials/Emissive Textures</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Emissive_Textures&amp;diff=118"/>
		<updated>2024-09-26T20:45:09Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;import Emoji from ‘@site/src/components/Emoji’;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page describes everything to know about Emissive Textures.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;defining-a-texture-as-emissive&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Defining a Texture as Emissive ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Every ModelPart in BlockBench has a reference to a single texture. When Figura loads the avatar, Figura looks for a texture with the same name as the texture used by the ModelPart but with &amp;lt;code&amp;gt;_e&amp;lt;/code&amp;gt; added to the end of it. For example, the emissive texture used by ModelParts that use &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;texture.png&amp;lt;/code&amp;gt; will use &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;texture_e.png&amp;lt;/code&amp;gt; as their emissive texture.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;_e&amp;lt;/code&amp;gt; is one of the [[../start_here/BlockBench#texture-suffix|texture suffixes]] that Figura looks for when loading an avatar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/emissive-example/names.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;emissive-texture-behavior&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Emissive Texture Behavior ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/emissive-example/emissive.png&amp;quot;).default} align=&amp;quot;right&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The pixels on a Texture using the &amp;lt;code&amp;gt;“EMISSIVE”&amp;lt;/code&amp;gt; [[../enums/RenderTypes|RenderType]] are not interpreted the same was as a regular texture.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First of all, the alpha values of pixels are ignored. This means that the emissive texture itself cannot be halfway visible. Its either the pixel is completely opaque, or completely gone. No in between.&amp;lt;br/&amp;gt; On the texture below, both pixels will render the exact same. Even though they appear to be 2 distinct colors, the right color has an alpha value of &amp;lt;code&amp;gt;139&amp;lt;/code&amp;gt; and is blending with the gray GitHub background. They have the exact same RGB values and will be rendered exactly the same under the &amp;lt;code&amp;gt;“EMISSIVE”&amp;lt;/code&amp;gt; RenderType.&amp;lt;br/&amp;gt; &amp;lt;img src={require(&amp;quot;@site/static/img/emissive-example/alpha.png&amp;quot;).default} width=&amp;quot;40&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Second, the “brightness” of a pixel is what determines the intensity of the emissive glow. If you know HSV, its the Value that controls this property. Emissive Intensity controls how bright the pixel will render, but also how much of the pixel behind it will show through.&amp;lt;br/&amp;gt; On the texture below, both pixels will render with the same color. The pixel on the left will render with max brightness, not allowing the pixels on the base texture to blend through. The pixel on the right won’t glow as much, but allows the pixels on the base texture to blend through.&amp;lt;br/&amp;gt; &amp;lt;img src={require(&amp;quot;@site/static/img/emissive-example/brightness.png&amp;quot;).default} width=&amp;quot;40&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;iris-emissives&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Iris Emissives ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you use Iris, regardless of the fact of if you are currently using custom shaders, the &amp;lt;code&amp;gt;“EMISSIVE”&amp;lt;/code&amp;gt; RenderType is modified to use the alpha value when rendering the emissive texture. How exactly is not known. Experimentation is required.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;emissive-render-types&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Emissive Render Types ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three emissive render types: EMISSIVE, EMISSIVE_SOLID, and EYES. All of these &#039;&#039;&#039;require&#039;&#039;&#039; the original _e texture and will make the same pixels glow that are in the _e texture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;emissive&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== EMISSIVE ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is the default render type of the _e texture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;emissive_solid&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== EMISSIVE_SOLID ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Like EMISSIVE, but it doesn’t allow transparency, transparent pixels will render as black.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;eyes&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== EYES ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The render type as Enderman and Spider eyes. This will not make the glowing pixels visible while you are under the invisibility effect.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;setting-render-type-example&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setting Render Type Example ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be clear: To use these you still need to have the _e texture, this can simply change the rendering of it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can set the render type to “Eyes” like this&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;models:setSecondaryRenderType(&amp;quot;Eyes&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The glow on the paperdoll and the skull may look slightly different.&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Custom-Items&amp;diff=117</id>
		<title>Tutorials/Custom-Items</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Custom-Items&amp;diff=117"/>
		<updated>2024-09-26T20:45:07Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;import Emoji from ‘@site/src/components/Emoji’; import FileTreeRoot from ‘@site/src/components/FileTree/Root’; import FileTreeNode from ‘@site/src/components/FileTree/Node’;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;custom-items&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Custom Items =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Custom items tutorial&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using Figura you can make custom items that are visible in first and third person.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You’ll need to use the Item [[../enums/ModelPartParentTypes|keyword]] and the item_render event combined.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;item-keyword&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Item Keyword ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you give a Blockbench group the Item keyword (by starting the group name with &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt;) it will be primed and ready to be used as an item. Without the event the Item group will vanish- and so will every item you hold. It has to be Item with a capital I.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/items/good-keyword.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;item-render-event&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Item Render Event ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The item_render event runs once a frame for every item you’re rendering and they do their own things in their own version of the event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In order to make the Item show up you must return it in the item_render event. This example assumes the bbmodel is named &amp;lt;code&amp;gt;model&amp;lt;/code&amp;gt; and that the keyworded group is named Item. If you wish to test this change &amp;lt;code&amp;gt;model&amp;lt;/code&amp;gt; to your bbmodel name and the Item group to your version.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.item_render()&lt;br /&gt;
&lt;br /&gt;
    return models.model.Item&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will replace every single item you’re holding with your custom item&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;replacing-specific-items&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Replacing Specific Items ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here’s an exmaple for replacing a single item by id:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.item_render(item)&lt;br /&gt;
&lt;br /&gt;
    if item.id == &amp;quot;minecraft:crossbow&amp;quot; then&lt;br /&gt;
&lt;br /&gt;
        return models.model.ItemBow&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here’s an exmaple for replacing a single item by name:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.item_render(item)&lt;br /&gt;
&lt;br /&gt;
    if item:getName() == &amp;quot;Lightning&amp;quot; then&lt;br /&gt;
&lt;br /&gt;
        return models.model.ItemBow&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can use the event’s arguments to get different information from the item you’re holding, and they are: the itemstack, rendering mode, position, rotation, scale, and if its in the left hand. [[../enums/ItemDisplayModes|Possible item rendering modes.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.item_render(item, mode, pos, rot, scale, left)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is storing all the values you can get, but in most cases you only need item and sometimes mode. Let’s replace bows, shields, and all swords. These are all for a blockbench model that looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;model.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;ItemSword&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;ItemBow&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;ItemShield&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.item_render(item)&lt;br /&gt;
&lt;br /&gt;
    if item.id == &amp;quot;minecraft:bow&amp;quot; then&lt;br /&gt;
&lt;br /&gt;
        return models.model.ItemBow&lt;br /&gt;
&lt;br /&gt;
    elseif item.id == &amp;quot;minecraft:shield&amp;quot; then&lt;br /&gt;
&lt;br /&gt;
        return models.model.ItemShield&lt;br /&gt;
&lt;br /&gt;
    elseif item.id:find(&amp;quot;sword&amp;quot;) then&lt;br /&gt;
&lt;br /&gt;
        return models.model.ItemSword&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The find function is searching the id for the word ‘sword’ so you don’t need to type in every single sword id. This also makes it compatible with modded swords.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;things-to-note&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Things To Note ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Do &#039;&#039;not&#039;&#039; put the Item group inside any other group. The Blockbench outliner should look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;model.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Item&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;model.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Item&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Item2&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
because you can have more than one of these keywords. Do &#039;&#039;&#039;not&#039;&#039;&#039; nest Item keywords inside another. And, do &#039;&#039;&#039;not&#039;&#039;&#039; have more than one custom item per instance of the Item keyword.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/items/bad-location.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You &#039;&#039;&#039;could&#039;&#039;&#039; put your Item group in another group but be careful, doing so makes it easier to cause unwanted behavior. For example, if you put it into RightArm or LeftArm it will be force unrendered, defeating the point of it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;2&amp;quot; style=&amp;quot;list-style-type: decimal;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;0,0,0 in Blockbench is where the player will be holding the item in the world&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Commands&amp;diff=116</id>
		<title>Tutorials/Commands</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Commands&amp;diff=116"/>
		<updated>2024-09-26T20:45:07Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Figura comes with a small set of commands that can help you use Figura. As Figura is a client-side mod these only affect the client.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;normal-commands&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Normal Commands ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Debug ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;/figura debug&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug generates a file in your Figura directory that contains information about your Figura mod settings and the avatar you currently have equipped. This includes the file sizes of all of the elements in the avatar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;docs&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;/figura docs&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Docs contains all of the documentation you can find in the Globals and Enums section of this wiki, simply use autofill to discover all of the options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;emojis&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Emojis ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;/figura emojis&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Emojis contains a list of all the emojis added by Figura. &amp;lt;code&amp;gt;/figura emojis all&amp;lt;/code&amp;gt; can show you all of them at once.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;export&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Export ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;/figura export avatar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Export, as the name suggests, exports certain files to your Figura directory. The most useful is &amp;lt;code&amp;gt;/figura export avatar&amp;lt;/code&amp;gt; which puts your currently worn avatar’s moon file into your directory. If you’ve lost your avatar and it’s still on Figura’s backend, you can retrieve its .moon file with this command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;links&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/figura links&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Links contains all the links for various Figura pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;load&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Load ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[WIP]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;reload&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reload ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/figura reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Reload reloads your currently equipped avatar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;run&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;/figura run log(&amp;amp;quot;Hello World&amp;amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run runs whatever lua code you type after it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;debug-mode-commands&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debug Mode Commands ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More commands can be unlocked by turning Debug Mode on in Figura’s settings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;backend2&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Backend2 ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[WIP]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;set_avatar&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set_Avatar ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;/figura set_avatar targetuuid sourceuuid&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set_avatar can be used to set the avatar of an entity using its uuid. targetuuid is the entity whose avatar is being set, and sourceuuid is the entity from where the avatar is coming from. For example, if you were to set a cow to have the avatar you’re wearing, the cow’s uuid would be the targetuuid and your uuid would be the sourceuuid.&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Avatar-Metadata&amp;diff=115</id>
		<title>Tutorials/Avatar-Metadata</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Avatar-Metadata&amp;diff=115"/>
		<updated>2024-09-26T20:45:04Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;import Emoji from ‘@site/src/components/Emoji’; import FileTreeRoot from ‘@site/src/components/FileTree/Root’; import FileTreeNode from ‘@site/src/components/FileTree/Node’;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;avatar-metadata&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Avatar Metadata =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
avatar.json information&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Emoji icon=&amp;quot;file/json&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;avatar.json&amp;lt;/code&amp;gt; is the file that contains Avatar Metadata. It tells Figura specific information about the avatar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;json-basics&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Json Basics ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The format that metadata is stored in is JSON. More specifically, a JSON object. It behaves very similar to a Lua table, it just uses different syntax. However, JSON has a very strict syntax and any errors will cause the avatar to fail to load.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JSON objects operate on key value pairs. Keys are separated from their values using colons (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;), and entries are separated with commas (&amp;lt;code&amp;gt;,&amp;lt;/code&amp;gt;). Unlike Lua tables, keys must be strings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;key&amp;quot;: &amp;quot;value&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;stringKey,numberValue&amp;quot;: 4,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;objectValue&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;key, but of sub object&amp;quot;: &amp;quot;value, but of sub object&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;arrayWooo&amp;quot;: [1, 2, &amp;quot;stringlol&amp;quot;, {}, &amp;quot;42&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;metadata-fields&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Metadata Fields ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Figura looks for specific keys in this JSON object and does things based on the value. Remember that all of these keys are optional. You only need to define the ones you care about.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;name-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“name”&amp;lt;/code&amp;gt; : String ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The value of this key determines the name of the avatar. This name is showed on the avatar information sidebar on the right of the Wardrobe, but also determines the name used to find the avatar on the left of the Wardrobe.&amp;lt;br/&amp;gt; If this key is not present, the name of the folder containing the &amp;lt;Emoji icon=&amp;quot;file/json&amp;quot;/&amp;gt;&amp;lt;code&amp;gt;avatar.json&amp;lt;/code&amp;gt; file is used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;description-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“description”&amp;lt;/code&amp;gt; : String ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The value of this key will appear below the avatar’s name in the wardrobe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Example avatar.json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;authors-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“authors”&amp;lt;/code&amp;gt; : String[] ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The value of this key is an array of strings. An array can contain many different values within itself, and Figura expects these values to be strings. The values are used in the Authors field in the avatar information sidebar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Example avatar.json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;authors&amp;quot;: [&amp;quot;@KitCat962&amp;quot;, &amp;quot;KitCat#0962&amp;quot;, &amp;quot;Katakana962&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;author-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“author”&amp;lt;/code&amp;gt; : String ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A place for a single author, should you dislike &amp;lt;code&amp;gt;“authors”&amp;lt;/code&amp;gt;. Does the exact same thing as &amp;lt;code&amp;gt;“authors”&amp;lt;/code&amp;gt; with only 1 element.&amp;lt;br/&amp;gt; If the &amp;lt;code&amp;gt;“authors”&amp;lt;/code&amp;gt; key is present, this key is ignored.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;version-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“version”&amp;lt;/code&amp;gt; : String ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A place to define a [https://semver.org/ Semantic Versioning] version. You can define the lowest possible Figura version that this avatar will run on. If another client uses a Figura version that is less than the version defined here, a &amp;lt;Emoji icon=&amp;quot;badge/warning&amp;quot;/&amp;gt; warning badge will appear on your nameplate for them. If they hover over it, it will state that their Figura version is lower than what this avatar was designed to run on. If this key does not exist, Figura will use the version that was used to load the avatar.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Example avatar.json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;authors&amp;quot;: [&amp;quot;KitCat962&amp;quot;, &amp;quot;Katakana962&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;color-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“color”&amp;lt;/code&amp;gt; : String ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This key defines the color of the &amp;lt;Emoji icon=&amp;quot;badge/mark&amp;quot;/&amp;gt; Figura mark on your nameplate. It must be a string in the format of a 3 character hex code or a 6 character hex code. For example, both &amp;lt;code&amp;gt;“3ab”&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;“FF00FF”&amp;lt;/code&amp;gt; are valid inputs. If this key does not exist, the color &amp;lt;code&amp;gt;“5AAAFF”&amp;lt;/code&amp;gt; will be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Example avatar.json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;authors&amp;quot;: [&amp;quot;@KitCat962&amp;quot;, &amp;quot;KitCat#0962&amp;quot;, &amp;quot;Katakana962&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;color&amp;quot;: &amp;quot;fc5bd9&amp;quot;&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;autoscripts-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“autoScripts”&amp;lt;/code&amp;gt; : String[] ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By default, every single &amp;lt;Emoji icon=&amp;quot;file/lua&amp;quot;/&amp;gt; script file in the avatar will execute in an undefined order. The &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; function can be used to control when a script is first executed, but some may prefer to define the script order in the metadata. This key is an array of strings that define which scripts run and in which order. Scripts not defined here will not run by default on avatar init, but can still be ran via &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. A script is specified via it’s file name without the &amp;lt;code&amp;gt;.lua&amp;lt;/code&amp;gt; extension. If a script is in a subfolder, that folder must also be defined, with the folder separator being a period (&amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;).&amp;lt;br/&amp;gt; Consider the following avatar:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;KattExampleAvatar&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;accessories&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;halo.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;ribbon.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;libs&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;armorAidLib.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;RainbowNameplate.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;JsonifyTextLib.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;avatar.json&amp;quot; icon=&amp;quot;file/json&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;player.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;diamond_layer_1&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;diamond_layer_2&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;script.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;skin.png&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;pet.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To make only &amp;lt;code&amp;gt;RainbowNameplate.lua&amp;lt;/code&amp;gt; run on avatar init, the &amp;lt;code&amp;gt;autoScripts&amp;lt;/code&amp;gt; would look like&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&amp;quot;autoScripts&amp;quot;:[&amp;quot;libs.RainbowNameplate&amp;quot;]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For our example metadata file, we will state that only &amp;lt;Emoji icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;script.lua&amp;lt;/code&amp;gt; will run by default, and the script itself will call &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; on the library scripts which will “import” them into itself. You may be thinking “whats the point of &amp;lt;code&amp;gt;”autoScripts”&amp;lt;/code&amp;gt; if &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; is objectively better at controlling script load order?“, To which my response would be”I don’t know”. But if you give an empty array, then no script will run which can be useful for debugging.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Example avatar.json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;authors&amp;quot;: [&amp;quot;@KitCat962&amp;quot;, &amp;quot;KitCat#0962&amp;quot;, &amp;quot;Katakana962&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;color&amp;quot;: &amp;quot;fc5bd9&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;autoScripts&amp;quot;: [&amp;quot;script&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;autoanims-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“autoAnims”&amp;lt;/code&amp;gt; : String[] ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This key defines which animations should start playing when the avatar first loads. The string to reference an animation follows the pattern &amp;lt;code&amp;gt;“modelPath.animName”&amp;lt;/code&amp;gt;. Consider the following avatar:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;KattExampleAvatar&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;accessories&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;halo.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;ribbon.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;libs&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;armorAidLib.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;RainbowNameplate.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;JsonifyTextLib.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;avatar.json&amp;quot; icon=&amp;quot;file/json&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;player.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;diamond_layer_1&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;diamond_layer_2&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;script.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;skin.png&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;pet.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If we want the animation &amp;lt;code&amp;gt;“idle”&amp;lt;/code&amp;gt; in the bbmodel &amp;lt;Emoji icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;player.bbmodel&amp;lt;/code&amp;gt;, we would include the string &amp;lt;code&amp;gt;“player.idle”&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;“autoAnims”&amp;lt;/code&amp;gt; array.&amp;lt;br/&amp;gt; Folder seperation is done with a period (&amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;) instead of slash (&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;).&amp;lt;br/&amp;gt; If we want the animation &amp;lt;code&amp;gt;“spin”&amp;lt;/code&amp;gt; in the model &amp;lt;Emoji icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;halo.bbmodel&amp;lt;/code&amp;gt;, we would include the string &amp;lt;code&amp;gt;“accessories.halo.spin”&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;“autoAnims”&amp;lt;/code&amp;gt; array.&amp;lt;br/&amp;gt; This is not table indexing like how you would index the &amp;lt;code&amp;gt;animations&amp;lt;/code&amp;gt; table to get an Animation. It is just string concatenation.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;autoAnims&amp;lt;/code&amp;gt; has a very niche use case as 99% of the time you have animations that you only want playing sometimes or want to play on a trigger. The only real use case is for a constantly playing looping animation that you don’t want to waste ~8 instructions on play at the beginning of a script, or perhaps you have an avatar that does not have any script files and you want to keep it that way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Example avatar.json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;authors&amp;quot;: [&amp;quot;@KitCat962&amp;quot;, &amp;quot;KitCat#0962&amp;quot;, &amp;quot;Katakana962&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;color&amp;quot;: &amp;quot;fc5bd9&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;autoScripts&amp;quot;: [&amp;quot;script&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;autoAnims&amp;quot;: [&amp;quot;player.idle&amp;quot;, &amp;quot;accessories.halo.spin&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;ignoredtextures-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“ignoredTextures”&amp;lt;/code&amp;gt; : String[] ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This key defines which textures should be ignored when loading the avatar. This is useful for when you have a cube that gets its texture set via code, but since all cubes must have a blockbench texture for Figura to even load the cube, you will either have to waste space with a dummy texture or use another texture in the model, which probably won’t look good on the cube. This key allows you to have that dummy texture in blockbench without having to waste precious bytes on having that texture loaded with the avatar.&amp;lt;br/&amp;gt; Referencing a texture is exactly the same format as getting a Texture object with the &amp;lt;code&amp;gt;textures&amp;lt;/code&amp;gt; global.&amp;lt;br/&amp;gt; Consider this avatar:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;KattExampleAvatar&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;accessories&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;halo.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;ribbon.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;libs&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;armorAidLib.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;RainbowNameplate.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;JsonifyTextLib.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;avatar.json&amp;quot; icon=&amp;quot;file/json&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;player.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;diamond_layer_1&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;diamond_layer_2&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;script.lua&amp;quot; icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;skin.png&amp;quot; icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;pet.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hypothetically, the armor of this avatar is being handled by &amp;lt;Emoji icon=&amp;quot;file/lua&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;armorAidLib.lua&amp;lt;/code&amp;gt;. It changes the texture of cubes to the vanilla armor textures. There is no need to have the &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;diamond_layer_1&amp;lt;/code&amp;gt; and &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;diamond_layer_2&amp;lt;/code&amp;gt; textures in the bbmodel, but setting the cubes to use &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;skin.png&amp;lt;/code&amp;gt; will make editing the model a pain. So we remove both unused textures.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Example avatar.json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;authors&amp;quot;: [&amp;quot;@KitCat962&amp;quot;, &amp;quot;KitCat#0962&amp;quot;, &amp;quot;Katakana962&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;color&amp;quot;: &amp;quot;fc5bd9&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;autoScripts&amp;quot;: [&amp;quot;script&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;autoAnims&amp;quot;: [&amp;quot;player.idle&amp;quot;, &amp;quot;accessories.halo.spin&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;ignoredTextures&amp;quot;: [&amp;quot;player.diamond_layer_1&amp;quot;, &amp;quot;player.diamond_layer_2&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;customizations-modelpart-customization-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;“customizations”&amp;lt;/code&amp;gt; : {“ModelPart” : {“Customization” : “String”}} ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Does that Type identifier make any sense? Not really, but thats what the &amp;lt;code&amp;gt;“customizations”&amp;lt;/code&amp;gt; property is.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;“customizations”&amp;lt;/code&amp;gt; allows for modifications to ModelParts that cant be done in BlockBench. You can still do this stuff via script, but the intent is for an avatar that does not have a script to still have access to some functionality.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;“customizations”&amp;lt;/code&amp;gt; itself is a JSON object. The keys of that object are references to ModelParts, with the values being another JSON object. &#039;&#039;That&#039;&#039; object contains key value pairs that operate on the referenced ModelPart.&amp;lt;br/&amp;gt; Consider the following avatar:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;FileTreeRoot&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;KattExampleAvatar&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;accessories&amp;quot; icon=&amp;quot;file/folder&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;ribbon.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;cube&amp;quot; icon=&amp;quot;blockbench/cube&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;avatar.json&amp;quot; icon=&amp;quot;file/json&amp;quot;/&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;player.bbmodel&amp;quot; icon=&amp;quot;file/bbmodel&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Head&amp;quot; icon=&amp;quot;blockbench/group&amp;quot;&amp;gt; &amp;lt;FileTreeNode label=&amp;quot;Head&amp;quot; icon=&amp;quot;blockbench/cube&amp;quot;/&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeNode&amp;gt; &amp;lt;/FileTreeRoot&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To target the &amp;lt;Emoji icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;Head&amp;lt;/code&amp;gt;, the correct key to use would be &amp;lt;code&amp;gt;“player.Head”&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt; To target the &amp;lt;Emoji icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;ribbon&amp;lt;/code&amp;gt;, the correct key to use would be &amp;lt;code&amp;gt;“accessories.ribbon”&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;player.Head&amp;quot;: {},&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.ribbon&amp;quot;: {}&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now for the keys that work inside these sub-objects.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;primaryrendertype-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;“primaryRenderType”&amp;lt;/code&amp;gt; : String ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sets the RenderType to use for the Primary/Default texture. The default primaryRenderType is &amp;lt;code&amp;gt;“TRANSLUCENT”&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;player.Head&amp;quot;: {},&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.ribbon&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;primaryRenderType&amp;quot;: &amp;quot;END_PORTAL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;secondaryrendertype-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;“secondaryRenderType”&amp;lt;/code&amp;gt; : String ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sets the RenderType to use for the Secondary/Emissive/&amp;lt;code&amp;gt;_e&amp;lt;/code&amp;gt; texture. The default secondaryRenderType is &amp;lt;code&amp;gt;“EMISSIVE”&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;player.Head&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;secondaryRenderType&amp;quot;: &amp;quot;GLINT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.ribbon&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;primaryRenderType&amp;quot;: &amp;quot;END_PORTAL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;parenttype-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;“parentType”&amp;lt;/code&amp;gt; : String ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Keywords in BlockBench set the ParentType of the ModelPart. This key overrides that, or sets one if there is no Keyword. The default ParentType is &amp;lt;code&amp;gt;“None”&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;player.Head&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;secondaryRenderType&amp;quot;: &amp;quot;GLINT&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;parentType&amp;quot;: &amp;quot;Body&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.ribbon&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;primaryRenderType&amp;quot;: &amp;quot;END_PORTAL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;moveto-string&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;“moveTo”&amp;lt;/code&amp;gt; : String ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Forces the ModelPart reference given to be a child of this ModelPart. This is useful if you like to organize your avatar into separate bbmodels. You can use this to stitch them together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;player.Head&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;secondaryRenderType&amp;quot;: &amp;quot;GLINT&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;parentType&amp;quot;: &amp;quot;Body&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.ribbon&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;primaryRenderType&amp;quot;: &amp;quot;END_PORTAL&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;moveTo&amp;quot;: &amp;quot;player.Head&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;visible-boolean&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;“visible”&amp;lt;/code&amp;gt; : Boolean ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Overrides the visibility defined in BlockBench. Useful to be able to hide ModelParts in BlockBench to edit the model more easily, without it affecting the final result of the Avatar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;player.Head&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;secondaryRenderType&amp;quot;: &amp;quot;GLINT&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;parentType&amp;quot;: &amp;quot;Body&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.ribbon&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;primaryRenderType&amp;quot;: &amp;quot;END_PORTAL&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;moveTo&amp;quot;: &amp;quot;player.Head&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;visible&amp;quot;: true&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;remove-boolean&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;“remove”&amp;lt;/code&amp;gt; : Boolean ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This customization will prevent the targeted ModelPart from loading at all.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.exampleMesh&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;smooth&amp;quot;: true&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;smooth-boolean&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;“smooth”&amp;lt;/code&amp;gt; : Boolean ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This customization must be applied directly to a mesh object.&amp;lt;br/&amp;gt; This will calculate the vertex normals so that the mesh appears smooth, reducing the visibility of individual triangles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.exampleMesh&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;smooth&amp;quot;: true&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;final-example-avatar.json&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Final Example &amp;lt;code&amp;gt;avatar.json&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Katt&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Example avatar.json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;authors&amp;quot;: [&amp;quot;@KitCat962&amp;quot;, &amp;quot;KitCat#0962&amp;quot;, &amp;quot;Katakana962&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;color&amp;quot;: &amp;quot;fc5bd9&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;autoScripts&amp;quot;: [&amp;quot;script&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;autoAnims&amp;quot;: [&amp;quot;player.idle&amp;quot;, &amp;quot;accessories.halo.spin&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;ignoredTextures&amp;quot;: [&amp;quot;player.diamond_layer_1&amp;quot;, &amp;quot;player.diamond_layer_2&amp;quot;],&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;customizations&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;player.Head&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;secondaryRenderType&amp;quot;: &amp;quot;GLINT&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;parentType&amp;quot;: &amp;quot;Body&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;accessories.ribbon&amp;quot;: {&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;primaryRenderType&amp;quot;: &amp;quot;END_PORTAL&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;moveTo&amp;quot;: &amp;quot;player.Head&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;visible&amp;quot;: true&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/Animations&amp;diff=114</id>
		<title>Tutorials/Animations</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/Animations&amp;diff=114"/>
		<updated>2024-09-26T20:45:03Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tutorial for playing and troubleshooting Blockbench animations&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Figura can play animations from Blockbench using the Animation API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;playing-an-animation&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Playing an Animation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In order to play an animation you need to index the animation through the Blockbench model it is in and the &amp;lt;code&amp;gt;animations&amp;lt;/code&amp;gt; global.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let’s say we have a Blockbench model named &amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleBbmodel.png&amp;quot;).default} width=&amp;quot;200&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
and an animation named &amp;lt;code&amp;gt;idle&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleIdle.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If we want to play this animation we can use this code:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;animations.example.idle:play()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;animations&amp;lt;/code&amp;gt; stores all the animation data for every Blockbench model.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The next part of the index is always the Blockbench model name that contains the animation you want to play, in our case this is &amp;lt;code&amp;gt;example.bbmodel&amp;lt;/code&amp;gt; (if your Blockbench model is in a subfolder, that will need to be included as well like &amp;lt;code&amp;gt;animations[“subfolder.example”].idle&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the last is always the animation name, in this case &amp;lt;code&amp;gt;idle&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;blockbench-is-tricking-you&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Blockbench is Tricking You ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you’re looking at your animation in Blockbench and there’s two names, the smaller name in gray is the actual animation name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleLie.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;You can’t use the method above to play the animation if it looks like this image&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You have two options: Rename the animation, or deal with the long animation name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;option-one&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Option One: ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rename the animation &amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleIdle.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;option-two&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Option Two: ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Deal with the animation name by changing the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;animations.example[&amp;quot;animation.model.idle&amp;quot;]:play()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;alternatives-to-play&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternatives to play() ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is another function that can play animations, &amp;lt;code&amp;gt;setPlaying(bool)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can put a boolean value inside the parenthesis for the function and it will play the animation if the boolean is true, or stop it if the boolean is false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is often used for toggles in the action wheel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;setplaying-example&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== setPlaying Example ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By nature, setPlaying needs to be in a function that will run multiple times, we’re going to use a tick event but you could use a ping or anything else&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.tick()&lt;br /&gt;
&lt;br /&gt;
    local crouching = player:getPose() == &amp;quot;CROUCHING&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    -- This detects if you are crouching and stores it into crouch.&lt;br /&gt;
&lt;br /&gt;
    -- So: crouch == true when crouching, and crouch == false when you&#039;re not crouching&lt;br /&gt;
&lt;br /&gt;
    animations.example.idle:setPlaying(crouching)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And now our animation &amp;lt;code&amp;gt;idle&amp;lt;/code&amp;gt; will play whenever we’re crouching!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This methodology can be expanded infinitely but it gets more complex the more animations you add.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;simple-idle-walk-sprint-crouch-setup&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Simple Idle-Walk-Sprint-Crouch Setup ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As an example we’ll do code for a set of four animations: idle, walk, sprint, and crouch. Here’s our animations in our Blockbench model. &amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleAnims.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.tick()&lt;br /&gt;
&lt;br /&gt;
    local crouching = player:getPose() == &amp;quot;CROUCHING&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    -- This is the same line of code from the previous example&lt;br /&gt;
&lt;br /&gt;
    local walking = player:getVelocity().xz:length() &amp;gt; .01&lt;br /&gt;
&lt;br /&gt;
    -- walking == true when moving, and walking == false when still (or going directly up/down as we excluded the y axis)&lt;br /&gt;
&lt;br /&gt;
    local sprinting = player:isSprinting()&lt;br /&gt;
&lt;br /&gt;
    -- If you want to find more player functions, check out the Player Global page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    -- Now we&#039;re going to use a lot of logic to figure out when animations should/shouldn&#039;t play&lt;br /&gt;
&lt;br /&gt;
    animations.example.idle:setPlaying(not walking and not crouching)&lt;br /&gt;
&lt;br /&gt;
    -- You&#039;re idle when not walking and not crouching&lt;br /&gt;
&lt;br /&gt;
    animations.example.walk:setPlaying(walking and not crouching and not sprinting)&lt;br /&gt;
&lt;br /&gt;
    -- You&#039;re walking when... walking and not crouching, but you want to make sure you&#039;re not sprinting either&lt;br /&gt;
&lt;br /&gt;
    animations.example.sprint:setPlaying(sprinting and not crouching)&lt;br /&gt;
&lt;br /&gt;
    -- You probably can catch my drift by now&lt;br /&gt;
&lt;br /&gt;
    animations.example.crouch:setPlaying(crouching)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;common-errors&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Errors ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;fixing-the-index-error&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fixing the index error ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You might run into some script errors while doing this, here’s some solutions to &amp;lt;code&amp;gt;attempt to index ? (a nil value)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The error will tell you about a key, the key is AFTER the part that’s experiencing an incorrect.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleErrorAnim.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Like in this example, it says that &amp;lt;code&amp;gt;setPlaying&amp;lt;/code&amp;gt; is the key, so we know that the problem is BEFORE it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You’ll notice that the animation name is misspelled, once you fix that the error will go away or change.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleErrorBbmodel.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here it is again, but this time the key is &amp;lt;code&amp;gt;idle&amp;lt;/code&amp;gt;, meaning the problem is with the Blockbench model name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You’ll notice that it’s misspelled in this version, fixing it will make the error go away or change.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;errors-inside-a-keyframe&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Errors inside a keyframe ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Errors inside keyframes are vary vastly, but you can indentify them by the name of the animation in the error. Here’s three examples: &amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleErrorKeyframe.png&amp;quot;).default} width=&amp;quot;800&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
How you fix this will greatly depend on what the error is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;overriding-vanilla-animations&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Overriding Vanilla Animations ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override vanilla animations using the override setting in Blockbench, this is set per-animation and it overrides per-part and per-channel (rotation, position, scale). It only overrides while the animation is playing. &amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleCheck.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/animation/exampleOverride.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;special-keyframe-types&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Special Keyframe Types ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Blockbench animations have a special category of keyframes called Effects keyframes. There are three of them and Figura ignores Particle and Sound&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;instruction-keyframes&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Instruction Keyframes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The third special keyframe type is Instruction, Instruction keyframes run lua code when the animation reaches that keyframe. This can be used to play sounds, spawn particles, literally anything. Remember that Lua code is what goes in this spot, not Molang.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each instruction is its own ‘scope’ meaning that variables local to any of the scripts can’t be accessed by the keyframes without specifically interfacing between them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;community-resources&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Community Resources ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;jimmys-animation-handler&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Jimmy’s Animation Handler ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have a lot of animations that need detections, Jimmy’s Animation Handler can play your animations for you. [https://github.com/JimmyHelp/JimmyAnims Find it here on GitHub]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;gsanimblend&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GSAnimBlend ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to smooth the transition between animations so it doesn’t jump between them you can use GSAnimBlend. [https://github.com/GrandpaScout/GSAnimBlend Find it here on GitHub]&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=User:PenguinEncounter/OldTutorials/ActionWheel&amp;diff=113</id>
		<title>User:PenguinEncounter/OldTutorials/ActionWheel</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=User:PenguinEncounter/OldTutorials/ActionWheel&amp;diff=113"/>
		<updated>2024-09-26T20:45:00Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tutorial for most things action wheel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you’re just here to copy-paste something without the tutorial go [[./ActionWheel/#here-is-the-full-copy-paste-for-an-example-action-wheel|here]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Action Wheel is a gui element provided by Figura that allows for adding highly customizable Actions that can provide additional functionality to your avatar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Action Wheel operates on Pages. Only a single Page can be active at a time.&amp;lt;br/&amp;gt; Pages contain Actions. A Page can have an unlimited amount of Actions, but the Action Wheel can only render 8 at a time. While a Page with more than 8 Actions is active, you can use the scroll wheel to move between the groups of 8 Actions within the Page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The docs page for the [[../globals/action-wheel|Action Wheel]] has more examples for specific action wheel functions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;example-action-wheel&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Action Wheel ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The first step is to create the Page that will hold the Actions. This is done via the &amp;lt;code&amp;gt;newPage&amp;lt;/code&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local mainPage = action_wheel:newPage()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates a new page, but thats it. If you save and try to open the Action Wheel (Default Keybind B), you will see a message stating that there is no active page. We can use the &amp;lt;code&amp;gt;setPage&amp;lt;/code&amp;gt; function while providing a reference to a Page object to set the active page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;action_wheel:setPage(mainPage)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tada. New blank page and Figura isnt screaming at us. Now for some actions.&amp;lt;br/&amp;gt; You can call the &amp;lt;code&amp;gt;newAction&amp;lt;/code&amp;gt; function on a Page object. This will create a new Action &#039;&#039;and&#039;&#039; add it to the Page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You technically do not need to store the Action in a variable. If you do, please give it a unique variable name. Using the same variable name for all actions can cause issues when doing more advanced stuff.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local action = mainPage:newAction()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New Action, but it really doesn’t look like much. Lets add a title, a display item, and perhaps change the color that appears when the Action is hovered over.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One thing to remember is that all Action functions return itself. This allows for functions to be chained together, always modifying the same action&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local action = mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;My Action&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;minecraft:stick&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :hoverColor(1, 0, 1)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty, but functionally useless. Lets add a function to the &amp;lt;code&amp;gt;leftClick&amp;lt;/code&amp;gt; field. When the Action is left clicked, the function stored in the Action’s &amp;lt;code&amp;gt;leftClick&amp;lt;/code&amp;gt; field gets invoked.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local action = mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;My Action&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;minecraft:stick&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :hoverColor(1, 0, 1)&lt;br /&gt;
&lt;br /&gt;
    -- the onLeftClick function just sets the Action&#039;s leftClick field&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
        print(&amp;quot;Hello World!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    end)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we have an Action that does stuff. You may not notice anything, but there is a glaring issue with the current code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The issue is that the leftClick code will only execute on your computer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As described in [[./Pings|Pings]], Figura is completely clientside. The Action Wheel is a feature added by Figura, meaning it will never be synced between clients via the Minecraft Server. So instead, we must use Pings that utilize Figura’s Backend to sync data between clients.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First step is to take the code that would be executed on leftClick, and turn it into a ping function. Then, instead of assigning an anonymous function to &amp;lt;code&amp;gt;leftClick&amp;lt;/code&amp;gt;, we assign the ping function itself to &amp;lt;code&amp;gt;leftClick&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;IMPORTANT: ALL PING FUNCTIONS MUST HAVE UNIQUE NAMES&#039;&#039;&#039;&#039;&#039;&amp;lt;br/&amp;gt; Also, please name your ping function so that it describes what it does. I &#039;&#039;hate&#039;&#039; seeing &amp;lt;code&amp;gt;pings.actionClicked&amp;lt;/code&amp;gt; in the hellp channel in discord. Do something like &amp;lt;code&amp;gt;pings.playEmote1&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;pings.setArmorVisibility&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;-- Create ping function that does the same thing the Action would have done.&lt;br /&gt;
&lt;br /&gt;
-- It must be defined above the Action.&lt;br /&gt;
&lt;br /&gt;
function pings.actionClicked()&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Hello World!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local action = mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;My Action&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;minecraft:stick&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :hoverColor(1, 0, 1)&lt;br /&gt;
&lt;br /&gt;
    -- Pass in the ping function itself into onLeftClick&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(pings.actionClicked)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And there you have it. An Action that correctly executes it’s contents across all clients.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
While this will correctly sync the timing of the execution of the ping function with all clients, it needs a slight modification if you want to send arguments with the ping.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function pings.actionClicked(a)&lt;br /&gt;
&lt;br /&gt;
  print(&amp;quot;Hello World!&amp;quot;, a)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local action = mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;My Action&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;minecraft:stick&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :hoverColor(1, 0, 1)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
        pings.actionClicked(math.random())&lt;br /&gt;
&lt;br /&gt;
    end)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What we are doing is wrapping the call to the ping function inside another function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The code below is a common mistake beginners can fall into.&amp;lt;br/&amp;gt; While the code might seem correct to those less code literate, it translates to “call the ping function, then assign the return result to the &amp;lt;code&amp;gt;leftClick&amp;lt;/code&amp;gt; field”.&amp;lt;br/&amp;gt; A ping will never have a return value, meaning &amp;lt;code&amp;gt;leftClick&amp;lt;/code&amp;gt; is being assigned the value &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;, meaning nothing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(pings.actionClicked2(math.random()))&lt;br /&gt;
&lt;br /&gt;
    -- Do not do use this code. It will not work.&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;here-is-the-full-copy-paste-for-an-example-action-wheel&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Here is the full copy paste for an example Action Wheel ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local mainPage = action_wheel:newPage()&lt;br /&gt;
&lt;br /&gt;
action_wheel:setPage(mainPage)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function pings.actionClicked()&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Hello World!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    -- animation example (commented out to avoid erroring):&lt;br /&gt;
&lt;br /&gt;
    -- animations.bbmodelname.animationname:play()&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local action = mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;My Action&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;minecraft:stick&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :hoverColor(1, 0, 1)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(pings.actionClicked)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;toggle-example&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Toggle Example ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an exmaple of the onToggle function, which swaps between two states. It does not work on its own as it doesn’t have a page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function pings.toggling(state)&lt;br /&gt;
&lt;br /&gt;
    models:setVisible(state)&lt;br /&gt;
&lt;br /&gt;
    -- animation toggle example (commented out to avoid erroring):&lt;br /&gt;
&lt;br /&gt;
    -- animations.bbmodelname.animationname:setPlaying(state)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local toggleaction = mainPage:newAction() -- If you&#039;re getting an error here it&#039;s probably because you didn&#039;t make the page&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;disabled&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :toggleTitle(&amp;quot;enabled&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;red_wool&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :toggleItem(&amp;quot;green_wool&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :setOnToggle(pings.toggling)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;multiple-actions-example&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple Actions Example ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When working with multiple actions, it’s important to give the actions and pings unique names&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local mainPage = action_wheel:newPage()&lt;br /&gt;
&lt;br /&gt;
action_wheel:setPage(mainPage)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function pings.actionClicked() -- this ping is named actionClicked&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Hello World!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local action = mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    -- this action is saved to action&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;My Action&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;minecraft:stick&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :hoverColor(1, 0, 1)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(pings.actionClicked)&lt;br /&gt;
&lt;br /&gt;
    -- this calls the ping named actionClicked&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function pings.toggling(state)&lt;br /&gt;
&lt;br /&gt;
    -- this ping is named toggling. it&#039;s important that all pings have unique names&lt;br /&gt;
&lt;br /&gt;
    models:setVisible(state)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local toggleaction = mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    -- this action is saved to toggleaction. it&#039;s important that actions are saved to unique variables&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;disabled&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :toggleTitle(&amp;quot;enabled&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;red_wool&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :toggleItem(&amp;quot;green_wool&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :setOnToggle(pings.toggling) &lt;br /&gt;
&lt;br /&gt;
    -- this calls the ping named toggling&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;multiple-pages-example&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple Pages Example ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local mainPage = action_wheel:newPage()&lt;br /&gt;
&lt;br /&gt;
local secondPage = action_wheel:newPage() -- make sure you save the pages to unique variables&lt;br /&gt;
&lt;br /&gt;
action_wheel:setPage(mainPage) -- this is setting the page you&#039;ll see when you first open the wheel to mainPage&lt;br /&gt;
&lt;br /&gt;
local toSecond = mainPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;Change To Second Page&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;item_frame&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
    -- this is a new action on mainPage. its purpose will be to swap to secondPage&lt;br /&gt;
&lt;br /&gt;
    -- this doesn&#039;t need to be pinged&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Swapped to the second page&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    action_wheel:setPage(secondPage)&lt;br /&gt;
&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local toMain = secondPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;Change To Main Page&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;glow_item_frame&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
    -- this is a new action on secondPage. its purpose will be to swap to mainPage&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Swapped to the main page&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    action_wheel:setPage(mainPage)&lt;br /&gt;
&lt;br /&gt;
    end)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local newAction = secondPage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;Hello&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;zombie_head&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
    -- this is a second action on the second page just to show it can be done&lt;br /&gt;
&lt;br /&gt;
    log(&amp;quot;Hello World&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    end)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;further-reading&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go [[../globals/Action-Wheel/Action.md|here]] for more information on Actions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go [[../globals/Action-Wheel/Page.md|here]] for more information on Pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;advanced-action-wheel&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Action Wheel ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go [[../tutorials/ActionWheel-Advanced|here]] for an advanced action wheel tutorial.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;for-when-you-want-to-skip-the-tutorials-altogether&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== For when you want to skip the tutorials altogether ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you scrolled to the bottom of the page just to copy-paste something without the tutorial go [[./ActionWheel/#here-is-the-full-copy-paste-for-an-example-action-wheel|here]]&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/ActionWheel-Advanced&amp;diff=112</id>
		<title>Tutorials/ActionWheel-Advanced</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/ActionWheel-Advanced&amp;diff=112"/>
		<updated>2024-09-26T20:44:59Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Advanced action wheel tutorial&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you haven’t read and understood the beginner action wheel tutorial, start [[../tutorials/ActionWheel.md|there]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;multi-page-setup&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Multi Page Setup ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Creating a network of Pages can be overwhelming. Lets try to rectify that.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This method for creating a Page Network divides the Pages into seperate, isolated files. These files return an Action that can be added to a different page. This Action will set the cuurrent page to the page in the file, but it first stores a reference to the Page it came from. That way when you want to go back to the previous page, its as simple as setting the current page to the stored Page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This allows Pages to be modular and easily reorganized if needed. More importantly, it can help make multiple pages less overwhelming.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;--ActionWheel.lua&lt;br /&gt;
&lt;br /&gt;
-- This file controls the root Page. All Pages are &#039;children&#039; of this Page.&lt;br /&gt;
&lt;br /&gt;
local mainpage = action_wheel:newPage()&lt;br /&gt;
&lt;br /&gt;
-- setAction is used to add an Action that already exists to this Page&lt;br /&gt;
&lt;br /&gt;
-- You need to specify the slot the Action wil go into, but -1 can be used to put it in the next available slot.&lt;br /&gt;
&lt;br /&gt;
mainpage:setAction(-1, require(&amp;quot;Page1&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
mainpage:setAction(-1, require(&amp;quot;Page2&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
action_wheel:setPage(mainpage)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;--Page1.lua&lt;br /&gt;
&lt;br /&gt;
-- Create the Page&lt;br /&gt;
&lt;br /&gt;
local page = action_wheel:newPage()&lt;br /&gt;
&lt;br /&gt;
-- Define the Actions within the Page (These are dummy example Actions)&lt;br /&gt;
&lt;br /&gt;
page:newAction():title():color():onLeftClick()&lt;br /&gt;
&lt;br /&gt;
page:newAction():title():color():onLeftClick()&lt;br /&gt;
&lt;br /&gt;
page:newAction():title():color():onLeftClick()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- This variable stores the Page to go back to when done with this Page&lt;br /&gt;
&lt;br /&gt;
local prevPage&lt;br /&gt;
&lt;br /&gt;
-- This Action just sets the stored page as active&lt;br /&gt;
&lt;br /&gt;
page:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;GoBack&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;minecraft:barrier&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
        action_wheel:setPage(prevPage)&lt;br /&gt;
&lt;br /&gt;
    end)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Page:newAction automatically adds the Action to the Page.&lt;br /&gt;
&lt;br /&gt;
-- This is unwanted, so action_wheel:newAction() is used so just make an Action.&lt;br /&gt;
&lt;br /&gt;
-- This is the Action that will be returned by require and will be used to navigate to this file&#039;s Page&lt;br /&gt;
&lt;br /&gt;
return action_wheel:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;Page1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
        -- store the current active page so that we can set it back as active later&lt;br /&gt;
&lt;br /&gt;
        prevPage = action_wheel:getCurrentPage()&lt;br /&gt;
&lt;br /&gt;
        -- set this file&#039;s page as active&lt;br /&gt;
&lt;br /&gt;
        action_wheel:setPage(page)&lt;br /&gt;
&lt;br /&gt;
    end)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;--Page2.lua&lt;br /&gt;
&lt;br /&gt;
-- Page2 is just to show that the entire process can be repeated verbatum, so long as the variables are local.&lt;br /&gt;
&lt;br /&gt;
local page = action_wheel:newPage()&lt;br /&gt;
&lt;br /&gt;
page:newAction():title():color():onLeftClick()&lt;br /&gt;
&lt;br /&gt;
page:newAction():title():color():onLeftClick()&lt;br /&gt;
&lt;br /&gt;
page:newAction():title():color():onLeftClick()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local prevPage&lt;br /&gt;
&lt;br /&gt;
page:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;GoBack&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :item(&amp;quot;minecraft:barrier&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
        action_wheel:setPage(prevPage)&lt;br /&gt;
&lt;br /&gt;
    end)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return action_wheel:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;Page2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :onLeftClick(function()&lt;br /&gt;
&lt;br /&gt;
        prevPage = action_wheel:getCurrentPage()&lt;br /&gt;
&lt;br /&gt;
        action_wheel:setPage(page)&lt;br /&gt;
&lt;br /&gt;
    end)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;setting-default-state-of-toggle-action&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setting Default State of Toggle Action ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This primarily utilizes calling a ping function without the network code, which is explained [[./Pings#ping-on-init|here]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This example will correctly set the default visibility of a theoretical jetpack model&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- prettier-ignore --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;-- This variable&#039;s initial value will control the default state of the togglable thing.&lt;br /&gt;
&lt;br /&gt;
local jetpackEnabled = true&lt;br /&gt;
&lt;br /&gt;
local jetpackModel = models.model.Body.Jetpack -- reference a ModelPart for convinience&lt;br /&gt;
&lt;br /&gt;
local function setJetpack(bool)&lt;br /&gt;
&lt;br /&gt;
    jetpackEnabled = bool -- this will be a ping function, so we still need to set the client&#039;s variable for when it is used in the toggle.&lt;br /&gt;
&lt;br /&gt;
    jetpackModel:setVisible(bool)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
pings.setJetpack = setJetpack -- we now have a normal function and a ping function that calls the normal function after network stuff&lt;br /&gt;
&lt;br /&gt;
-- This event controls the particle effect of the jetpack&lt;br /&gt;
&lt;br /&gt;
function events.tick()&lt;br /&gt;
&lt;br /&gt;
    -- once every 4 ticks while the jetpack is visible&lt;br /&gt;
&lt;br /&gt;
    if jetpackEnabled and world.getTime() % 4 == 0 then&lt;br /&gt;
&lt;br /&gt;
        -- spawn particles relative to the model itself in the world&lt;br /&gt;
&lt;br /&gt;
        local partMatrix = jetpackModel:partToWorldMatrix()&lt;br /&gt;
&lt;br /&gt;
        particles:newParticle(&amp;quot;minecraft:flame&amp;quot;, partMatrix:apply(3, -6, 0))&lt;br /&gt;
&lt;br /&gt;
        particles:newParticle(&amp;quot;minecraft:flame&amp;quot;, partMatrix:apply(-3, -6, 0))&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Page boilerplate&lt;br /&gt;
&lt;br /&gt;
local mainpage = action_wheel:newAction()&lt;br /&gt;
&lt;br /&gt;
action_wheel:setPage(mainpage)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- calling a ping in the script initialization is a bad idea, hence why the reference to the normal function is needed&lt;br /&gt;
&lt;br /&gt;
setJetpack(jetpackEnabled)&lt;br /&gt;
&lt;br /&gt;
mainpage:newAction()&lt;br /&gt;
&lt;br /&gt;
    :title(&amp;quot;Enable Jetpack&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :toggleTitle(&amp;quot;Disable Jetpack&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    :onToggle(pings.setJetpack) -- use the ping for the action toggle, as that is still needs to be pinged&lt;br /&gt;
&lt;br /&gt;
    :toggled(jetpackEnabled) -- the toggled function sets the internal state of the Toggle Action. It *does not* call toggle or untoggle.&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Tutorials/.How-To-Read-Documentation&amp;diff=111</id>
		<title>Tutorials/.How-To-Read-Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Tutorials/.How-To-Read-Documentation&amp;diff=111"/>
		<updated>2024-09-26T20:44:59Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span id=&amp;quot;how-to-read-documentation&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= How To Read Documentation =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;danger&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This article needs to be entirely rewritten for the current docs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This article is a WIP.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As of writing this article, the GitHub wiki is not complete, but there are other sources of documentation for Figura out there. The most updated one is called Figs and it’s made and managed by GitHub user applejuiceyy. [https://applejuiceyy.github.io/figs/ Here’s a link].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
User GrandpaScout has their [https://github.com/GrandpaScout/FiguraRewriteVSDocs VSDocs] which are used in conjunction with the text/code editor Visual Studio Code. These docs will help autofill function names and blockbench model paths for you.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In-game, Figura has a custom command to find documentation. &amp;lt;code&amp;gt;/figura docs&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;the-basics&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Basics ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;globals&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Globals ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Globals are where functions that allow you to access various information are stored. For instance, functions relating to player data are stored in the global &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt;, and functions relating to the avatar’s models are stored in the global &amp;lt;code&amp;gt;models&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;enums&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enums ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enums are not functions, but rather lists of key words a function may return or take as an argument. For example, the &amp;lt;code&amp;gt;ParentTypes&amp;lt;/code&amp;gt; enums contains all the parent types you could set a modelPart to (which are equivalent to the Blockbench keywords). On the other hand, the &amp;lt;code&amp;gt;EntityPoses&amp;lt;/code&amp;gt; enums contains all the entity poses (including non-player poses) that an entity can achieve, as returned by &amp;lt;code&amp;gt;getPose()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;reading-figs&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Reading Figs ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page will be providing a tutorial on how to find and use all of Figura’s functions using Figs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We will be viewing Figs in the ‘experienced person’ mode. By default Figs is in new person mode, to change this you can select the Preferences button in the upper right of the webpage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Upon opening Figs you will be primarily presented the option to select your version, this is the version of Figura you are using. If you select the wrong one you may be missing functions or you may be seeing functions you can’t actually use. If you skip selecting a version Figs will be showing you the functions in the latest version of Figura.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Regardless of if you select a version or not you will see a list of words on the left of the screen. The ones are the top are globals, and then you can scroll down that sidebar to see miscellaneous types and miscellaneous enums.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Figs has a search function which will find any word in the name or description of a function, so if you don’t know what global a function is in, you can use the search function to keyword search for it. (For example, if you want to change the camera, search for camera and scroll)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let’s say we want to make a custom elytra that turns off/on depending on if we’re wearing an elytra. We’re a player, so all of our information is going to be in the player API. On the left sidebar scroll down until you find &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt; underneath the globals section. Aside from scrolling through the entire player API list you could search for the word ‘item’ (as we are looking for item information) until you find &amp;lt;code&amp;gt;getItem()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;how-to-read-whats-being-given&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How To Read What’s Being Given ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There’s going to be some information there, and all of it is necessary. You can click on &amp;lt;code&amp;gt;PlayerAPI.getItem&amp;lt;/code&amp;gt; to open the full page for the function (though this doesn’t provide more information)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;PlayerAPI.getItem&amp;lt;/code&amp;gt; tells us that the function &amp;lt;code&amp;gt;getItem&amp;lt;/code&amp;gt; is in the PlayerAPI. Functions in the player API are accessed via the &amp;lt;code&amp;gt;player&amp;lt;/code&amp;gt; global so the function can be accessed by writing &amp;lt;code&amp;gt;player:getItem()&amp;lt;/code&amp;gt;. But it doesn’t tell us how to get all the information we want out of it yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Look down until you see &amp;lt;code&amp;gt;overload 1:&amp;lt;/code&amp;gt; this next bit of information is the second piece of the puzzle&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;PlayerAPI:getItem(index: Integer): ItemStack&amp;lt;/code&amp;gt; is giving us &#039;&#039;&#039;four&#039;&#039;&#039; very important pieces of information, the first two we’ve already gone over.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The third piece of information is what’s inside the brackets &amp;lt;code&amp;gt;()&amp;lt;/code&amp;gt;. In this case it’s &amp;lt;code&amp;gt;index: Integer&amp;lt;/code&amp;gt;. In this context, “index” refers to the item slot being checked. An integer is a whole number, so this tells us that the slot to check is determined by putting a whole number in the brackets.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Looking back up at the description of the item, Figs tells us &amp;lt;code&amp;gt;slots are indexed with 1 as the main hand, 2 as the off hand, and 3,4,5,6 as the 4 armor slots from the boots to the helmet&amp;lt;/code&amp;gt;. In short, the integer we enter as an argument will dictate what slot it will search. Figs says 6 is the helmet and it goes down to the boots, and we want the chestplate slot so 5 is the integer we must give it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point we have this: &amp;lt;code&amp;gt;player:getItem(5)&amp;lt;/code&amp;gt; and we’re going to test that it’s working with a bit of code&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.tick()&lt;br /&gt;
&lt;br /&gt;
    log(player:getItem(5))&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And… huzzah! Our game chat is being spammed by the log, and that log is telling us what’s in our chestplate slot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The game is telling us, at the end of the message, that this is an ItemStack. If you look back at figs’ overload: &amp;lt;code&amp;gt;PlayerAPI:getItem(index: Integer): ItemStack&amp;lt;/code&amp;gt; you’ll notice that ‘ItemStack’ is after the parenthesis. That’s because the information after the colon &amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt; is what the function is going to return. Essentially, what it’s going to give back to us after it’s done.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So now we can get information from the chesplate slot, but we’re not doing anything with that information yet, we must dive into information given to us via the ItemStack.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In Figs, click on &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt; and it will bring you to another page that has even more functions on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We want to know if this ItemStack is from an elytra. The best way to do this is via the item’s id. If you’ve ever used the /give command, you give yourself an item via the item ID, and it looks like &amp;lt;code&amp;gt;minecraft:stick&amp;lt;/code&amp;gt; or something similar. An item’s id can also be viewed by turning advanced tooltips on using F3+H.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you’ve searched the ItemStack page for id you will easily find the &amp;lt;code&amp;gt;getID()&amp;lt;/code&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Its overload looks like this: &amp;lt;code&amp;gt;ItemStack:getID(): String&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Like before, getID() is in ItemStack, meaning it wants an ItemStack, but we don’t have an ItemStack API like the player API, we can’t do ItemStack:getID() because ItemStack is meaningless (it’s not in the list of globals). However, &amp;lt;code&amp;gt;player:getItem(5)&amp;lt;/code&amp;gt; returns an ItemStack which the &amp;lt;code&amp;gt;getID()&amp;lt;/code&amp;gt; function can be used on directly. As such, we can use &amp;lt;code&amp;gt;player:getItem(5):getID()&amp;lt;/code&amp;gt; which in our testing log looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.tick()&lt;br /&gt;
&lt;br /&gt;
    log(player:getItem(5):getID())&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You might be wondering about putting something in getID’s parentehsis, so let’s turn our attention back to the overload figs gives us. In &amp;lt;code&amp;gt;ItemStack:getID(): String&amp;lt;/code&amp;gt; the parenthesis are empty here. That means no arguments are necessary and nothing should be put in the brackets. Anything given will be ignored.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Notably, it’s returning a String which is quite literally a string of characters. Putting something in quotes makes it a string. So &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; is a boolean, but &amp;lt;code&amp;gt;“true”&amp;lt;/code&amp;gt; is a string. In our case this string of characters is the id of the item in our chestplate slot. At this point we can compare the string of our item with the string of the elytra id.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function events.tick()&lt;br /&gt;
&lt;br /&gt;
    log(player:getItem(5):getID() == &amp;quot;minecraft:elytra&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This statement is known as an evaluation. The doubled equals sign &amp;lt;code&amp;gt;==&amp;lt;/code&amp;gt; tells the game to compare the two values on either side of it. In the case of functions, it will compare the value the function returns. If an elytra is worn then &amp;lt;code&amp;gt;player:getItem(5):getID()&amp;lt;/code&amp;gt; will return &amp;lt;code&amp;gt;“minecraft:elytra&amp;lt;/code&amp;gt;, which is equal to what we’re checking for and as such the game will show &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. The evaluation can be combined with other code to do more with it, such as store its value in a variable or put it in an if statement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, after all this, our elytra detection is &amp;lt;code&amp;gt;player:getItem(5):getID() == “minecraft:elytra”&amp;lt;/code&amp;gt;. It’s using the player API to run &amp;lt;code&amp;gt;getItem()&amp;lt;/code&amp;gt; on the player, and then use &amp;lt;code&amp;gt;getID()&amp;lt;/code&amp;gt; on the player’s item, and then compare it’s ID to that of the elytra to find out if we’re wearing an elytra or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For clarification: The log is another function that we put the final result into. It serves to make the information we put in it as an argument to the chat. If you copied the log that will break things&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;using-the-in-game-docs&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using The In-Game Docs ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
WIP&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
	<entry>
		<id>https://wiki.figuramc.org/index.php?title=Blockbench&amp;diff=109</id>
		<title>Blockbench</title>
		<link rel="alternate" type="text/html" href="https://wiki.figuramc.org/index.php?title=Blockbench&amp;diff=109"/>
		<updated>2024-09-26T20:34:06Z</updated>

		<summary type="html">&lt;p&gt;Manuel: Automated upload of converted .txt file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;import Emoji from ‘@site/src/components/Emoji’;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The basics on how to use Blockbench&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Proper tutorials for blockbench can be found online. This page just explains Figura specific stuff. This page assumes you are using the Desktop version of BlockBench, not the online app.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;project-properties&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Project Properties ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is the popup that appears when you create a Project. You can also get to this page via File-&amp;amp;gt;Project.&amp;lt;br/&amp;gt; &amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/project.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&amp;lt;br/&amp;gt; Figura only accepts &amp;lt;Emoji icon=&amp;quot;file/bbmodel&amp;quot;/&amp;gt; bbmodels in the Generic Model format. If your format is not Generic Model, Figura will refuse to load the avatar. To convert a project, File-&amp;amp;gt;Convert Project. Deselect &amp;lt;code&amp;gt;Create Copy&amp;lt;/code&amp;gt;, ensure format is Generic Model, and press Confirm. If the popup does not go away after pressing Confirm, close it manually.&amp;lt;br/&amp;gt; &amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/convert_project.png&amp;quot;).default} width=&amp;quot;400&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;File Name&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Model Identifier&amp;lt;/code&amp;gt; fields are unused by Figura.&amp;lt;br/&amp;gt; &amp;lt;code&amp;gt;UV Mode&amp;lt;/code&amp;gt; determines how BlockBench handles how UVs are positioned. Figura will handle both &amp;lt;code&amp;gt;Box UV&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Per-face UV&amp;lt;/code&amp;gt;. Its up to you which you want. UVs determine where a 2D texture is applied to a 3D model. Each face has it’s own UV coordinates which determines where on the 2D texture it will get it’s pixels from.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/uvmode_box.png&amp;quot;).default} width=&amp;quot;200&amp;quot; style={{&amp;quot;float&amp;quot;:&amp;quot;right&amp;quot;}}&amp;gt;&amp;lt;/img&amp;gt; &amp;lt;code&amp;gt;Box UV&amp;lt;/code&amp;gt; forces each face of a cube to match how vanilla does UVs. If you have ever edited your own vanilla skin before, you will recognize the pattern. While this does simplify the texturing process, it limits what you can do. Also, all textures in the model must have the same size, as what is a pixel is determined by the project’s global &amp;lt;code&amp;gt;Texture Size&amp;lt;/code&amp;gt; instead of the size of the texture itself. Also, meshes cannot be used while using &amp;lt;code&amp;gt;Box UV&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;{{&amp;amp;quot;clear&amp;amp;quot;:&amp;amp;quot;both&amp;amp;quot;}}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/uvmode_perface.png&amp;quot;).default} width=&amp;quot;200&amp;quot; style={{&amp;quot;float&amp;quot;:&amp;quot;right&amp;quot;}}&amp;gt;&amp;lt;/img&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Per-face UV&amp;lt;/code&amp;gt; allows full control over each face of the cube/mesh. Each face can be positioned, scaled, and rotated individually from each other. You can even set a different texture for each face, or remove a face to reduce clutter. While the pixel grid is effected by the project’s global &amp;lt;code&amp;gt;Texture Size&amp;lt;/code&amp;gt;, changing the &amp;lt;code&amp;gt;Texture Size&amp;lt;/code&amp;gt; has zero effect on the UVs themselves, unlike &amp;lt;code&amp;gt;Box UV&amp;lt;/code&amp;gt; which will have destructive effects when changing the project&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;{{&amp;amp;quot;clear&amp;amp;quot;:&amp;amp;quot;both&amp;amp;quot;}}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Texture Size&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Texture Size&amp;lt;/code&amp;gt; field aids with UV calculation. In rendering, UVs are a float from 0-1 representing the percentage of the texture that this point is at. A UV of (0.5,0.5) represents the center of the texture, regardless of the texture’s own size. A way of calculating this percentage is to take the pixel coordinate you want and divide it by the texture’s size. (32,16)/(64,64)=(0.5,0.25). The &amp;lt;code&amp;gt;Texture Size&amp;lt;/code&amp;gt; field determines this texture size globally. BlockBench never uses the texture’s actual size, which causes issues when you have a model with textures of different sizes. Thankfully, changing it only has an effect om ModelParts that use &amp;lt;code&amp;gt;Box UV&amp;lt;/code&amp;gt;, so when you need to edit ModelParts using a different sized texture, you can change this with no worries so long as you are using &amp;lt;code&amp;gt;Per-face UV&amp;lt;/code&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;modelparts&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ModelParts ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;parenttypes&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ParentTypes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the name of a &amp;lt;Emoji icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; group begins with a specific string, Figura will apply special effects to that group. Some examples include &amp;lt;code&amp;gt;“Head”&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;“RightArm”&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;“World”&amp;lt;/code&amp;gt;. These are called [[../enums/ModelPartParentTypes|ParentTypes]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;blank-texture&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Blank&amp;lt;/code&amp;gt; Texture ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ModelParts that use the BlockBench inbuilt &amp;lt;code&amp;gt;Blank&amp;lt;/code&amp;gt; texture will not be loaded by Figura at all. If you want a Model to not have a texture and assign the texture via script, use the [[../tutorials/Avatar-Metadata|&amp;lt;code&amp;gt;ignoredTextures&amp;lt;/code&amp;gt; metadata customization]]. The &amp;lt;code&amp;gt;Transparent&amp;lt;/code&amp;gt; texture that can only be applied to individual faces in Per-face UV behave the same way. Figura will not load those faces.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;meshes&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Meshes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;Emoji icon=&amp;quot;blockbench/mesh&amp;quot;/&amp;gt; Meshes are allowed. Nothing special with Figura. This is just here for those that need to be explicitly told Meshes work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;textures&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Textures ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;localexternal-textures&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Local/External Textures ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In BlockBench, textures have 2 distinct states: Local and External.&amp;lt;br/&amp;gt; To determine the state your texture is in, Right Click a texture-&amp;amp;gt;Properties. An External texture will have a file path, while a Local one will not.&amp;lt;br/&amp;gt;There is one key factor for a texture to be External, and that is for the file itself to be inside the avatar’s folder. If the filepath does not lead to a file inside the avatar’s folder, Figura will load it as a Local file.&amp;lt;br/&amp;gt; &amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/texture_local.png&amp;quot;).default} width=&amp;quot;300&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/texture_external.png&amp;quot;).default} width=&amp;quot;300&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Whether a texture is Local or External will determine how Figura will load it which is important when getting a Texture in script.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Render Mode&amp;lt;/code&amp;gt; field determines how the texture will be rendered. In BlockBench, this changes nothing visually.&amp;lt;br/&amp;gt; &#039;&#039;&#039;Figura ignores &amp;lt;code&amp;gt;Render Mode&amp;lt;/code&amp;gt;.&#039;&#039;&#039; The Primary Texture will always be &amp;lt;code&amp;gt;“TRANSLUCENT”&amp;lt;/code&amp;gt; by default, and the Secondary Texture will always be &amp;lt;code&amp;gt;“EMISSIVE”&amp;lt;/code&amp;gt; by default.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Render Sides&amp;lt;/code&amp;gt; field determines if the cube should be rendered when looking at the back of a face.&amp;lt;br/&amp;gt; &#039;&#039;&#039;Figura ignores &amp;lt;code&amp;gt;Render Sides&amp;lt;/code&amp;gt;.&#039;&#039;&#039; To apply the same effect, use the &amp;lt;code&amp;gt;“TRANSLUCENT_CULL”&amp;lt;/code&amp;gt; [[../enums/RenderTypes|RenderType]] in a script.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;texture-suffix&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Texture Suffix ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In BlockBench, each cube (face) can only point to a single texture, which means that Figura needs to get creative when it wants to link multiple textures together for stuff like emissive textures.&amp;lt;br/&amp;gt; When Figura loads a texture, it looks for another texture with the same name but with a specific suffix. Then for all ModelParts in BlockBench that use the texture, Figura will link the suffixed texture to that ModelPart as well.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
List of suffixes used by Figura:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;_e&amp;lt;/code&amp;gt;: This texture will be used as the Secondary Texture, also known as the [[../tutorials/Emissive%20Textures|Emissive Texture]], of the ModelPart. The Secondary RenderType of a ModelPart is by default &amp;lt;code&amp;gt;“EMISSIVE”&amp;lt;/code&amp;gt;, but can be changed in script.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;_n&amp;lt;/code&amp;gt;: This texture will be used as the [https://en.wikipedia.org/wiki/Normal_mapping Normal Texture]. &amp;lt;b&amp;gt;Do not confuse this with the Primary Texture&amp;lt;/b&amp;gt;. “Normal” means something very specific in modeling. This suffix is used with Iris Shaders, and does nothing with vanilla rendering. &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;This suffix currently does not function&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;_s&amp;lt;/code&amp;gt;: This texture will be used as the [https://en.wikipedia.org/wiki/Specularity Specular Texture]. This suffix is used with Iris Shaders, and does nothing with vanilla rendering. &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;This suffix currently does not function&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An example is the &amp;lt;Emoji icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;Head&amp;lt;/code&amp;gt;, &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;skin&amp;lt;/code&amp;gt;, and &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;skin_e&amp;lt;/code&amp;gt;. When the &amp;lt;Emoji icon=&amp;quot;blockbench/group&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;Head&amp;lt;/code&amp;gt; uses the texture &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;skin&amp;lt;/code&amp;gt;, when the Avatar is loaded, &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;skin_e&amp;lt;/code&amp;gt; is used as the Secondary Texture, ie the Emissive Texture.&amp;lt;br/&amp;gt; &amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/settexture.png&amp;quot;).default} width=&amp;quot;300&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For a texture to have the same name, they must both be either [[#localexternal-textures|Local or External]], and should they be external, they must be in the same folder. Otherwise, they will not have the same name internally.&amp;lt;br/&amp;gt; For textures with file extensions, the suffix goes before the extension. &amp;lt;Emoji icon=&amp;quot;file/texture&amp;quot;/&amp;gt; &amp;lt;code&amp;gt;skin_e.png&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;animations&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;animation-properties&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Animation Properties ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This popup appears when you create an animation. To get back to this popup, Right Click an Animation-&amp;amp;gt;Properties.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/animation_properties.png&amp;quot;).default} width=&amp;quot;500&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Name&amp;lt;/code&amp;gt; is the animation’s name. It is very important that you change this to something shorter. The entire textbox is the animation’s name, so unless you want to refer to this animation in lua with &amp;lt;code&amp;gt;animations.player[“animation.model.new”]&amp;lt;/code&amp;gt;, change the name. An animation named just &amp;lt;code&amp;gt;“new”&amp;lt;/code&amp;gt; is indexed via &amp;lt;code&amp;gt;animations.player.new&amp;lt;/code&amp;gt;. Much nicer, right? &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Loop Mode&amp;lt;/code&amp;gt; controls what happens when the animation stops. There are 3 valid loop modes: Play Once, Hold On Last Frame, and Loop.&amp;lt;br/&amp;gt; Play Once stops the animation once the animation ends.&amp;lt;br/&amp;gt; Hold On Last Frame keeps the animation values from the end of the animation. The animation is still technically playing.&amp;lt;br/&amp;gt; Loop sets the animation’s time to 0, or to the animation’s end if the animation is playing backwards. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Override&amp;lt;/code&amp;gt; determines if Mimic-type &amp;lt;a href=&amp;quot;../enums/ModelPartParentTypes&amp;quot;&amp;gt;ParentTypes&amp;lt;/a&amp;gt; will apply their transformations while this animation is playing. It only effects ModelParts that have a keyframe in this animation. Default &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Snapping&amp;lt;/code&amp;gt; determines the snapping distance for keyframes. Holding ctrl while moving a keyframe ignores this. &amp;lt;b&amp;gt;Figura does not care about this value&amp;lt;/b&amp;gt;. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Anim Time Update&amp;lt;/code&amp;gt;. I have no clue what this does in blockbench, but figura uses this value for determining the start offset. In other words, when you call &amp;lt;code&amp;gt;play&amp;lt;/code&amp;gt; this is the time that figura will start the animation at. This allows you to put keyframes behind the start of the animation which can help with Cubic Interpolation keyframes. Default is &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Blend Weight&amp;lt;/code&amp;gt; is a multiplier for every single keyframe in the animation. Not very useful as a property, but it can be changed in script to raise or reduce the intensity of animations. Default is &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Start Delay&amp;lt;/code&amp;gt; is the time it takes after calling &amp;lt;code&amp;gt;play&amp;lt;/code&amp;gt; for the animation to actually start. Default is &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Loop Delay&amp;lt;/code&amp;gt; is a property that only shows up with the Loop &amp;lt;code&amp;gt;Loop Mode&amp;lt;/code&amp;gt;. It adds a delay between the animation ending, then starting again. Default is &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;keyframe-expressions&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keyframe Expressions ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
While blockbench supports Molang, &#039;&#039;&#039;Figura does not&#039;&#039;&#039;.&amp;lt;br/&amp;gt; To remedy this, Figura allows writing lua code into keyframe fields.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Figura provides data for the keyframe expression, which is accessible via the &amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt; variable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It has 2 pieces of data, the keyframe time, and the Animation object of the animation itself.&amp;lt;br/&amp;gt; Keyframe time is measured in percentage, not seconds. So assuming a Step interpolation keyframe, &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; is at the time at the keyframe itself, and &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; is at the next keyframe. Keyframe time is only useful when the keyframe uses Step interpolation.&amp;lt;br/&amp;gt;When using other interpolation types, the expression will execute before it has reached the keyframe itself to interpolate. While this happens, it will give the Keyframe time of the previous keyframe and go back to zero once it reaches itself.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
They can be extracted via the following line:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local time, anim = ...&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Keyframe Expressions accept 2 different formats:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* A single lua expression that evaluates to a number&lt;br /&gt;
&lt;br /&gt;
* A lua script that &amp;lt;code&amp;gt;returns&amp;lt;/code&amp;gt; a number&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;math.sin(world.getTime())&amp;lt;/code&amp;gt; is a single lua expression, so it is a valid Keyframe Expression.&amp;lt;br/&amp;gt; However, &amp;lt;code&amp;gt;local _, anim=... math.sin(anim:getTime())&amp;lt;/code&amp;gt; is not a single lua expression and will need to have an explicit return value:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;local _, anim = ...&lt;br /&gt;
&lt;br /&gt;
return math.sin(anim:getTime())&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively, you can rewrite it as a single lua expression: &amp;lt;code&amp;gt;math.sin({...}[2]:getTime())&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt; This deconstructs the &amp;lt;code&amp;gt;...&amp;lt;/code&amp;gt; varargs into a table and grabs the second value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;instruction-keyframes&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Instruction Keyframes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instruction Keyframes run lua code when the Animation reaches that keyframe. This can be used to play sounds, spawn particles, literally anything. Remember that Lua code is what goes in this spot, not Molang.&amp;lt;br/&amp;gt; You can access Instruction Keyframes via the Magic Wand icon. An Effects timeline should appear along with the other ModelPart timelines.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;animation-features-that-figura-does-not-care-about&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Animation Features That Figura Does Not Care About ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Below are features provided by BlockBench Animations that figura does not use when loading the bbmodel.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Variable Placeholders&#039;&#039;&#039;&amp;lt;br/&amp;gt; &amp;lt;img src={require(&amp;quot;@site/static/img/blockbench/animation_variableplaceholders.png&amp;quot;).default} width=&amp;quot;200&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&amp;lt;br/&amp;gt; This is completely ignored by Figura.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Inverse Kinematics&#039;&#039;&#039;&amp;lt;br/&amp;gt; Don’t bother. Not a thing in Figura.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Global Rotation&#039;&#039;&#039;&amp;lt;br/&amp;gt; There is a toggle for Global Rotation next to the Rotation timeline for ModelParts. Figura does not obey this, so keep it disabled.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sound Keyframes&#039;&#039;&#039;&amp;lt;br/&amp;gt; Figura does not read these. Use [[#instruction-keyframes|Instruction Keyframes]].&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Particle Keyframes&#039;&#039;&#039;&amp;lt;br/&amp;gt; Figura does not read these. Use [[#instruction-keyframes|Instruction Keyframes]].&amp;lt;br/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Manuel</name></author>
	</entry>
</feed>