EPIC Enhanced Programmable IRC-II Client

Programming in EPIC

EPIC's scripting language combines commands, aliases, event handlers, variables, and expressions. Scripts can customize the interface or automate IRC activity. This short guide introduces the rules most likely to matter when writing your first script; see ircII syntax for statement forms and functions for available operations.

Commands and aliases

Commands in script bodies do not need the interactive / prefix. A script alias can override a built-in command; use two literal slashes to call the C built-in instead of recursively calling the alias:

alias mode {
    echo Sending a mode request;
    //mode $*;
};

This alias forwards its arguments through the real mode handler. It does not guarantee the server accepts the request. // is understood directly by EPIC's parser; there is no need to construct it from a command-character variable. Command names are case-insensitive. Ordinary interactive text, unlike script statements, is sent to the current target unless it starts with /.

Blocks and semicolons

A block contains semicolon-separated statements. Put braces around bodies that must be saved and run later, including aliases, hooks, timers, and parse_command bindings:

alias install_example {
    on ^hook "example *" {
        echo Hook text: $*;
        echo Second message;
    };
};

After defining this alias, run /install_example, then /hook example hello. Both messages run when the hook fires. Without the hook body's braces, the semicolon would end the on statement, and the next echo would run immediately while installing it.

Braces group commands; they do not by themselves create a local-variable scope. Calling an alias normally does. Use local or @ :name = value for local storage; an ordinary assignment updates a visible local if present, otherwise a global. See atomic scope and lvalues.

Backslashes, expansion, and protection

A backslash protects the next character during an applicable parsing or expansion pass and is then removed. The surrounding parser matters: a backslash protecting a semicolon in a script block is different from ordinary text typed at the interactive prompt.

Balanced plain parentheses and braces protect their contents from the current general expando-expansion pass. Their contents can be evaluated later by the command receiving them. Square brackets are not a universal equivalent: they delimit expandable text operands in expressions and participate in variable-name construction. Double quotes do not universally suppress expansion or protect semicolons at the block-splitting stage.

A command statement is expanded before its command and arguments are separated. An expression statement such as @ count = count + 1 instead uses expression evaluation. $$ produces a literal dollar sign for one expansion pass; it is not a promise that the resulting text will survive every later evaluation unchanged. See expando substitution and expressions.

Script files and physical lines

Prefer the PF loader for a file written as one normal block:

/load -pf myscript

PF joins physical lines with spaces, removes full-line # comments, and requires your semicolons. It does not treat /* ... */ as C-style comments. Indentation and newlines can make the script readable without changing its intended statement boundaries.

The standard loader has separate legacy line-continuation and semicolon-insertion rules. A trailing backslash continuation is a standard-loader convention, not a universal rule for every script block or PF file. Choose the loader explicitly when the distinction matters.

Code that is evaluated later

Callback bodies need values from the callback's argument context, rather than from the code that installed them. Braces usually express this more clearly than multiple layers of escaped dollar signs and parentheses:

alias show_userhost {
    userhost $0 -cmd {
        echo Lookup result: $*;
    };
};

/show_userhost SomeNick uses the alias's $0 to choose a nickname, but the braced body receives the userhost callback arguments when it runs. The lookup can use a cache and run synchronously, or send a request and run later when replies arrive. Do not assume callback timing or that the caller's ordinary locals remain visible. Use the command's documented callback arguments or explicit extra-data mechanism.

Script-defined functions are aliases called as $name(arguments) or from expression mode. return value supplies the result. Arguments are text expanded before the function is called, usually separated by spaces; an arithmetic expression inside the parentheses is not evaluated automatically.

Practical habits

See Script best practices for PF loading, allocating hook serial numbers, arranging processing around display, and using the supplied theme support.

The C built-ins provide the core language. Bundled scripts such as builtins add compatibility aliases and helpers; availability depends on what your configuration loads. Server-facing commands remain subject to server support, permissions, and connection state.

Source references