LoliScript Reference

LoliScript is the line-based domain-specific language used by OBM2 Pro to define automation scripts. It is both written by hand and generated by the visual Stacker editor.

Overview

LoliScript is a simple imperative language where each line is one instruction. Beyond block invocations, control flow and variable assignment, it can also embed inline scripts (JavaScript or IronPython) for custom logic — see Inline Scripting. It is case-insensitive for keywords.

ℹ

The Stacker (visual editor) and the LoliScript editor stay fully in sync. Editing one updates the other in real time.

Script Structure

A LoliScript file consists of a sequence of lines. Blank lines are ignored. Each non-blank line is either a:

  • Block invocation — runs a stacker block (REQUEST, PARSE, KEYCHECK, etc.)
  • Control statement — IF, ELSE, END, JUMP, LABEL
  • Built-in command — SET, LOG
  • Comment — line starting with #
# A minimal LoliScript config
REQUEST GET "https://example.com"
PARSE <SOURCE> LR "token:" "\"" -> "token"
KEYCHECK
  KEYCHAIN Success OR
    KEY "<token>" Exists
  KEYCHAIN Failure OR
    KEY "<RESPONSECODE>" EqualTo "401"

Comments

Lines beginning with # are ignored by the interpreter.

# This is a comment
REQUEST GET "https://example.com"  # Inline comments are NOT supported
⚠

Inline comments (after an instruction on the same line) are not supported. Place comments on their own line.

Variables in LoliScript

Variable values are substituted by wrapping the name in angle brackets: <varName>. This substitution happens automatically in string fields before each instruction executes.

SET "greeting" "Hello, <username>! Your score is <score>."
LOG "<greeting>"

See the Variables & BotData page for the full reference including automatic variables and list syntax.

Control Flow

IF / ELSE / END

Conditional branching. The condition is evaluated against a variable using the same operators as Keycheck.

IF "<RESPONSECODE>" EqualTo "200"
  PARSE <SOURCE> JSON "user.token" -> "token"
ELSE
  SET "token" ""
  LOG "Unexpected response code: <RESPONSECODE>"
END

Available Operators in IF

Same as Keycheck: Contains, DoesNotContain, EqualTo, NotEqualTo, Exists, DoesNotExist, GreaterThan, LessThan, MatchesRegex.

JUMP & LABEL

Unconditional jump to a named label. Useful for retry loops or skipping sections.

LABEL retry
REQUEST GET "https://example.com/check"
IF "<RESPONSECODE>" EqualTo "429"
  UTILITY Wait 2000
  JUMP retry
END
PARSE <SOURCE> JSON "status" -> "status"
⚠

Infinite loops via JUMP are possible. Always include an exit condition (IF / Keycheck) before jumping back.

SET & LOG

SET

Assign a value to a variable. The value string supports variable substitution.

SET "apiUrl" "https://api.example.com/v1/user/<userId>"
SET "authHeader" "Bearer <token>"

LOG

Write a message to the run log. Visible in the Debugger's Log tab and in the Runner log panel.

LOG "User: <email> — Status: <RESPONSECODE>"
LOG "Capture: <planType>"

Inline Scripting (JavaScript / IronPython)

When the standard blocks aren't enough, LoliScript can embed an inline script between BEGIN SCRIPT and END SCRIPT. The current LoliScript variables are injected into the script's scope; the variables listed after OUTPUTS are read back and stored as BotData variables, usable by the blocks that follow.

BEGIN SCRIPT IronPython
# <USERNAME> and <PASSWORD> are injected as variables
result = USERNAME.upper() + "::" + PASSWORD
END SCRIPT -> VARS OUTPUTS "result"

The language token right after BEGIN SCRIPT selects the engine: IronPython (embedded Python, no system install required) or JavaScript. Use OUTPUTS "a,b,c" to export several variables at once.

ℹ

IronPython scripting was reintroduced on .NET 8 — embedded, with no external interpreter required. It is distinct from the PYRUN utility, which shells out to a separately installed Python.

Block Keywords Reference

Every stacker block has a corresponding LoliScript keyword. Parameters enclosed in quotes are strings (support variable substitution); parameters in parentheses are named boolean/int flags.

KeywordBlockMinimal Example
REQUESTHTTP RequestREQUEST GET "https://url"
TLSREQUESTTLS RequestTLSREQUEST GET "https://url" TLSPROFILE:"Chrome"
KEYCHECKKeycheck(multi-line, see Stacker docs)
PARSEParsePARSE <SOURCE> LR "L" "R" -> "out"
FUNCTIONFunctionFUNCTION Hash MD5 "<pass>" -> "hash"
UTILITYUtilityUTILITY Wait 1000
CAPTCHACaptchaCAPTCHA RecaptchaV2 "url" "sitekey" -> "token"
NAVIGATENavigate (Selenium)NAVIGATE "https://url" TIMEOUT:10000
BROWSERACTIONBrowserActionBROWSERACTION SendKeys "<TAB>||Hello||<ENTER>"
ELEMENTACTIONElementActionELEMENTACTION id "username" ClearAndType "<email>"
EXECUTEJSExecuteJSEXECUTEJS "return document.title;" -> "title"
TCPTCPTCP Connect "host" "port" (UseSSL=False)
IMAPIMAPIMAP Connect "imap.host" "993" (UseSSL=True) 30000
POP3POP3POP3 Connect "pop.host" "995" (UseSSL=True) 30000
SMTPSMTPSMTP Connect "smtp.host" "587" (UseSSL=True) 30000
FTPFTPFTP Connect "ftp.host" "21" "user" "pass" (UseSSL=False) 15000

Debugger

The Debugger lets you step through a script line by line with test data, without running the full Runner.

TabDescription
DataLive view of all BotData variables after each step
LogExecution log with timestamps and block names
HTML ViewRendered HTML of the last HTTP or browser response
NotepadScratch pad — test regex patterns, LR anchors, or JSONPath expressions against pasted text

Test Input

Enter test credentials in the Debugger's input field in the same format as your wordlist (e.g. user@example.com:password123). You can also specify a test proxy.