-
Notifications
You must be signed in to change notification settings - Fork 4
Home
Please note that this wiki is for the old 'cycle' framework. This page will be updated once the 'flat' framework is further developed.
- An installation of scalu
- A text or code editor you feel comfortable using
- Enable the developer console in your options menu
It's important that new users already understand the very basics of Source scripting before moving on to more advanced topics. If you are already well versed in how scripting works, feel free to skip this section.
To execute a script, open your console (usually with the ~
key on English keyboards) and type exec [scriptname]
. This will execute any script by that name in your cfg
directory. Source games automatically execute a script called autoexec
upon loading, so any scripts you want to run automatically at startup should be put in there. For example, if I wanted to run scalu at startup, I'd edit autoexec.cfg (or create it if it doesn't exist), put in exec scalu
as a line, then save it.
There is really only one command that really matters for making arithmetic possible: the alias command. The alias command works how you think it would; alias ties a long string of commands to a shorter custom command. Say you want to practice rocket jumping in TF2. Instead of hitting the "~" key and typing
sv_cheats 1; hurtme -9999999
every time you want to practice, you might instead put
alias rj "sv_cheats 1; hurtme -9999999"
in a script. Now, you only need to type
rj
to set cheats to 1 and give yourself health. Note that commands are executed sequentially and are seperated by the ;
operator.
Note that alias itself is just like any other command in Source. Therefore
alias a "alias a hurtme -100"
is a valid command. This command points a to the string "alias a hurtme -100". If you type a
into the console, a will execute the string and rewrite itself to execute hurtme -100
. If you type a
again, it will just execute hurtme -100
again. This is key, as this reveals that aliases can rewrite themselves and other aliases.
It's impossible for this guide to list all of the quirks and conventions of scripting; look here for a more in-depth guide to basic scripting:
https://wiki.teamfortress.com/wiki/Scripting https://www.reddit.com/r/tf2scripthelp/wiki/index
The Source console provides no way to manipulate or store numbers, normally. However, we can manipulate and store aliases. Therefore, in order to store numbers, we create chains of self-rewriting aliases (internally called rotaries) that work to create a register, or a variable. It's actually not that important for you, the enduser, to understand how they work, except to know their size. Registers, by default, are 8 bit signed variables. Therefore, they store all numbers between -128 and 127.
Since registers are laborious to construct, a script called vbuilder.py can write them automatically, with custom names and bit sizes. However, scalu provides a few pre-generated registers by default: r1, r2, and r3.
Constants are structurally similar to registers, but lack the ability to be automatically overwritten. The first 16 integers are stored as constants in the form: c0, c1, c2, c3, ...., c9, ca, cb, cc, cd, ce, cf.
Instructions tell the interface what to do. They come in two types: register instructions, and conditional instructions. Register instructions include add
, dump
, and bxor
. They take between 0 and 2 arguments, and typically manipulate registers with no effect on the "outside" world. Conditional instructions (such as zero
, equal
, and gt
) typically do not manipulate registers, and instead conditionally execute other blocks of script.
All instructions make use of ptr
s (pointers) to know what arguments they're working with. These pointers "point" at the only register interface endusers should worry about, the name of the register. Using add
as an example:
alias add_ptr1 r1
alias add_ptr2 r2
add
The script above will target r1 (register 1) as its first argument, r2 as its second argument, and will then add them together. Note that register instructions will only ever change the value of the first argument. For anyone familiar with x86 assembly, this resembles Intel syntax. Therefore, the r1 has been increased by r2, and r2 remains unchanged.
Conditional instructions work similarly, but have additional arguments. Using equal
as an example
alias equal_ptr1 r1
alias equal_ptr2 c7
alias equal_rettrue yourfunction
alias equal_retfalse yourotherfunction
rettrue and retfalse represent branching depending on whether or not the function is true or false. If register 1 and 2 are equal, rettrue is executed. If not, retfalse is executed. This is where scalu interacts with the outside world, and where you hook in the commands and aliases you want executed.
The sections above are all that is needed to have a solid grasp on using this interface. This section is dedicated to quirks you might encounter as you use the interface
-
Using the same argument twice (r1 and r1, or c4 and c4) will work as expected.
-
If you use vbuilder.py to create new registers, there's a few things to keep in mind. Instructions can handle any word size (you can make all your registers and constants 10 bits or 100 bits, if you so please), however, they expect constant word size; 16 bit is incompatible with 8 bit, etc.