API Reference & Tips

API - Reminders, Helpful tips, and things you should know before starting.
Press F5 to reload and replay scripts while Stream Avatars is connected!
To view the console log, focus Stream Avatars, and press Alt+C, then type: Lua After hitting enter, a console logger will come up showing you the logs. Once it is open, you can close the command input by pressing Alt+C again.
You can close the console log by repeating this process.

Do's and Don'ts

Function Order
If Then Else
Arrays and Loops
String Concatenation
function anotherFunction()
--see how this function is above the return function()?
--the double dash is how we make line comments in lua scripting
this is how we make block comments in lua scripting.
multiple lines. woooo
log('hello world');
return function()
--this should be the last function of your script!
end --Don't put anything below the last end
return function()
local test = 'hi';
local test2 = false;
if test2 == false and test == 'hi' then
log('&& operators is just and');
else if test2 == true or test == 'bye' then
log('|| operators is just or');
if test2 == false then
log('simple if');
if test2 == false then
log('simple if else');
return function()
--in lua, all arrays start at index 1
local test {'one', 'two', 'three' };
log(test[1]); --this will print out one
--notice #test is how we get the length of the array. which is 3.
--a simple for loop
for i = 1, #test do
log(i); --this will print out: 1, 2, 3
--a simple while loop
local test = 0;
while test < 5 do
test = test + 1;
local a = { }
a[1] = 'one';
a[2] = 'two';
a['hello'] = 'hello world';
--ipairs is indexed --note hello world does not get printed
for key, value in ipairs(a) do
log(key .. value);
--pairs key order is unspecified and not garunteed.
for key, value in pairs(a) do
log(key .. value);
--hello world
return function()
--how to concatenate strings in lua.
--(two periods is how you add strings together)
log('this is how ' .. 'you combine strings');
coroutines are unique in SA Lua. They allow for scripts to wait for something to finish before continuing. Do not cross global variables between coroutines! This can be tricky to use but is very powerful for scripting sequences of events.
function exampleCoroutine()
--code in this function does not have access to global scope variables
--Do not reference myGlobalScopeVariable directly!
local myVar = get('myGlobalScopeVariable');
--grab the global var and make it local
log(myVar); --prints hi
myVar = 'bye';
--set the global var to the local variable.
set('myGlobalScopeVariable', myVar);
--this variable belongs to the main coroutine and nowhere else!
myGlobalScopeVariable = 'hi';
return function()
--a really basic coroutine yield
--that waits 1 second before continuing.
local coroutineId = async('exampleCoroutine');
--this prints bye because we waited for it to be set.
--Pauses this coroutine indefinitely, allowing the other coroutines to exist.

Pre-existing Functions and Data

With LUA scripting in stream avatars, there are some addons your your script behind the scenes that you should know about!
JSON Serialization
On Command Call
Trigger Type
return function()
local a = { someData = 'hi', otherData = { 1, 2, 3 }};
--some data table...
local makeItString = json.serialize(a);
--convert a to a JSON string
--prints the data structure.
local b = json.parse(makeItString);
--parse the string back into a table
log(b['someData']); --prints hi
local h = { };
h[1] = 'hey'; --h is array
h[2] = 'dont'; --h is array
h['example'] = 'do'; --h is not array
h['example2'] = 'this'; --h is not array
local j = json.serialize(h); --stop! this breaks.
--instead option 1:
local k = { };
k[1] = 'hey'; --k is array
k[2] = 'DO'; --k is array
k[3] = { }; --k is array
k[3]['example'] = 'do'; --k is array
k[3]['example2'] = 'this'; --k is array
local l = json.serialize(k); --works
--instead option 2:
local m = { };
m['n'] = { };
m['n'][1] = 'hey'; --m is not array
m['n'][2] = 'DO'; --m is not array
m['example'] = 'do'; --m is not array
m['example2'] = 'this'; --m is not array
local o = json.serialize(m); --works
Only exists when the custom command is set to Run As: On Command Call
commandUser is the user that issued the command causing this script to run.
commandMessage is the message that was sent to issue the command.
return function()
--this script is ran by someone running the command...
log(commandMessage); --prints the full message of the command
--if the custom command is set to "exact match = false",
--the commandMessage could be more than just the commandName
--commandMessage could be: !steal clonzeh
--where the command is actually !steal
--but since it doesn't have to match exactly, users can add info after it
example !steal settings
--Scripts are able to control it's own trigger type with a setting.
--(this makes it easier to share commands and keep their settings)
script_trigger_type = 'On Connect';
--with this line uncommented, the script will be forced to run as OnConnect
--with this line uncommented, the script will be forced to run as OnCommand
--script_trigger_type = 'On Command';
return function()
log('script was triggered! the trigger type is: ' .. script_trigger_type);