www.:3schools.com

blessscript docs

what is blessscript

blessscript is a language that was made on stream to be used as a redeem. you can run any program using the !bs command.

it is a weird mix of mostly javascript but some elements from python and lisp is also included. the name and inspiration comes from Bless, a shelved project from @LCOLONQ zone that was a riff on FORTH language.

data types

Number: is stored as js number, either a number or (+/-)Infinity.

String: is stored as js string, in quotation marks ("", NOT '')

Bool: is stored as js bool, either true or false

Null: indicates various undefined values. null.

List: much like js list, variable length, variable data type. constructed by wrapping a comma separated list of elements in [].

Dict: a string key: any value pair that is like js objects, but more strict in construction. (much like json, construct like {"a": 2, "b": "c", "c": [1,2,3]}).

Function: unlike js, there is no function keyword and instead all functions are lambda generated by the => keyword.

Basic Operation

this is the kind of stuff that exists in other languages

Arithmetic: math can be done using +, -, * and /. % for modulo, ** for exponentiation.

Division without remainder can be done using //.

Bitwise operation: &, |, ^, << and >> is available.

Concatenation: strings can be added together with +, and repeated using *.

List append/extend: elements can be appended to list with List + Any, and lists can be joined together with List | List.

List inclusion: Any in List can be used to check if an element is inside of a list.

List intersection: List & List or List ^ List can be used to return an intersection or an "xor" of a list. List - Any also exists to return a list without that element.

List access: List[Number] and Dict[String] can be used to retrieve a single element, String[Number] can be used to return a string with 1 letter, List[Number(start):Number(end):Number(step)] exists to slice a list python style.

List ?????: List << Number and List >> Number can be used to shift the list Number times, and List % Number can be used to return the Nth element in the list.

String split/join: String / String can be used to split a string into list, and List * String(delimiter) can be used to join list into string.

Type Checking: typeof Any can be used to return a string with the type name, and Any is String(type name) can be used to check if something is of that type.

Type Coersion: bool Any, number Any, string Any, list Any, dict Any can be used to coerce one type to another. when dict becomes a list, it behaves like Object.entries(), when list or dict becomes a string or vice versa, it acts like WASD. falsey values include null, false, 0, "", [], {}. functions cannot be coerced into anything other than string.

Boolean Operation: && and || exists for AND and OR. ! exists for not (that also coerces into bool).

Comparison: <, >, <=, >=, ==, != exists to compare. null is treated as [] or 0, numbers are compared, lists are compared from first element to last, strings are compared with a special function that sorts "more smartly" than the usual lexical sort. (such that "16" > "8")

Comment: /* ... */ can be used to comment.

Variables and Functions

variables can be declared without any special keyword (python style), where the first appearance of that variable will determine a scope.

variables from higher scope can be accessed, but variables in lower scope will be destroyed when that scope is exited (by return and whatnot).

all arithmetic operations can be appended with = to do assignment at the same time (x += 1; x &&= 4; x **= 2;).

functions can be assigned to variables like x = a => 1 + a; or x = a => b => a + b; and called later such as x(1).

Flow Control

Nullish Operation: Any ?? Any can be used js style. can also be used as x ??= Any.

Ternary Operation: Condition ? IfTrue : IfFalse.

if statement: if (condition) statement; or if (condition) { statements ... } optionally followed by else statement;, else { statements... } or else (another if statement...).

while loop: while (conditon) statement; or while (condition) { statements... }.

for loop: for (initial;conditon;increment) statement; or for (initial;conditon;increment) { statements... }. these are like the same syntax as many other languages

continue, break and return / return Any; is supported.

"Gizmos"

this is kind of the reason why bless script exists

call String or call List: calls a command or chat in your behalf. commands usually do not reply but you can make it reply by putting "!!" in front of your queries. (so that call "!!guy" would announce it worked on chat)

call is equivalent to typing the exact same thing in chat, and must start with "!" to execute commands.

query String(url) Dict(query): queries this website and returns its output. if string contains a slash, it queries prod.kr/${url}?${query}, if it does not, it queries prod.kr/api/${url}?${query} so that query "chat" {"count": 1} would return the most recent chat message.

Fuel system to avoid spamming the chat or overloading the stream, each bs call has an initial "fuel value" of 5000. this value can be increased by 1 per 1 millisecond of sleep Number(seconds) called. each call or query costs 1000 fuel, and each nested blessscript evaluation (through function calls, for and while loops, brackets, etc) costs 1 fuel per evaluation.

ffi

there are a few functions and constants that are defined in the topmost variable scope to begin with to aid in making programs.

map(List, Function(current, index, array) => Any): calls js Array.map

filter(List, Function(current, index, array) => Bool): calls js Array.filter

reduce(List, Function(previous, current, index, array) => Any, previous=null): calls js Array.reduce

abs(Number) and sign(Number): returns the absolute value and sign of the number.

sin(Number), cos(Number), tan(Number), atan2(Number(y), Number(x)): trigonometry functions. calls js Math

log(Number, Number(base)=E): gets the log of a number.

PI, E: math constants.

floor(Number), ceil(Number), trunc(Number), round(Number), prec(Number, Number(digits)=6): rounds a number.

sqrt(Number): square root, equivalent to Number ** 0.5

toUpperCase(String), toLowerCase(String), trim(String): string operations, calls js String.trim() and whatnot.

time(): calls the current seconds since 2025/01/01 (cannot do unix time bc js float and were not bigint)

random(): calls random.

using blessscript for guys

you can go to !brain and submit a hook that is written in blessscript. these hooks will run whenever a specific command, ipc, or chat message have been sent.

a specific type of hook under "guy" is ran and its result parsed for the ai of the guys, allowing for people to program their own guy ai. you can also steal brain for other people by clicking one of the 3 randomly selected users' brains of the same hook below.

more on the argument and return type of each hooks in the following sections.

!guy ai hooks

idle hook is fired every time a guys action finishes. where a new action shall be given as a return value of this hook.

other hooks, such as attacked, peaced and listen acts as an interrupt to the idle hook, firing irrespective of the completion of the current task.

a set of top level arguments are passed that are relevant to your guy.

in attacked hook, damage for recent damage taken will be given also.

for idle hook, a return value must be given, otherwise your guy will idle 1000. return value is either a list or a space delimited string.

for an example, see the Default guy idle hook.

non-guy hooks

hooks can be applied to any execution within the stream gizmo, and return values are not required for this one, you may use call function to influence on hook.

chat starts with and chat includes are called when a normal chat message (NOT commands) starts with or includes a specified word or a phrase.

command called hooks are called when a specified command is called. the event name must be based on its js file name instead of the phrase you use to execute the command. (for example, !guy would be spawnShimeji.)

both chat and command hooks share the same list of following arguments.

ipc calls are the most direct form of execution, and the event name is similar to reload names (such as "twitch raid"). this is dependent on the file structure within src/@main/command, and is executed whenever those are. check the github for detail on directory layout.

only args argument is passed for ipc call hook, which is a list of arguments that is being called.

Mastodon Mastodon 2