Difference between pages "SVN Primer" and "ASH For Beginners"

From Kolmafia
(Difference between pages)
Jump to navigation Jump to search
(→‎Specifications: Add info on images/relayimages/)
 
m (Adding BBEdit Language definitions for ASH)
 
Line 1: Line 1:
 
{{TOCright}}
 
{{TOCright}}
 +
==File Editing==
 +
To create and edit ASH scripts, you need a text editing program that doesn't automatically add line-breaks for word wrapping.
  
== Introduction ==
+
===Mac===
 +
While the built in editor TextEdit will work fine (as long as you remember to write only in plaintext), [https://www.barebones.com/products/bbedit/ BBEdit] is a much more powerful tool. It may not be designed for ASH scripting specifically, but it was written for a similar purpose.  It can has a paid mode with more features, but those features are optional.  BBEdit users can install the ASH Language Module  to provide syntax colorization.
  
Subversion (svn) is a centralized version control system. A repository (repo) exists online — this repo contains a scripting project. KoLmafia can download scripts from an online SVN repo and automatically install them for the user. It can even automatically update scripts to the latest version without any effort from the user.
+
===Linux===
 +
If you use Linux, you probably already know about the options available for text editing. Emacs, Vi, etc. are all fine for creating ASH scripts.
  
 +
===Windows===
 +
Windows users beware; using Microsoft Word to create ASH files will lead to no end of headaches! The built-in program notepad will work, as can wordpad when configured with the option "No Wrap" for text. However, having a program that can handle syntax-highlighting can be very beneficial. Many scripters recommend [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++] for ASH (and other programmatic) scripting. In this case, it's also beneficial to have a style configuration that works well with ASH, and one example can be found [http://kolmafia.us/showthread.php?3164-How-do-you-write-an-ASH-file&p=21567&viewfull=1#post21567 here].
  
== Non-Technical FAQ ==
+
==Saving==
'''Q. What is this "SVN" thinggy?'''<br />
+
ASH scripts need to be saved with the file extension ".ash" to be properly recognized by KoLmafia. If you're using a built-in text editor on a Windows machine, it may automatically save your files with the ".txt" extension by default. (So you may end up with a file called "script.ash.txt" instead of the desired "script.ash".) One way around this on Windows that usually works is to put quotes around the file name when you save it, including the extension.
A. It's a better way for users to install scripts.
 
  
'''Q. What do I have to know about SVN to use this feature?'''<br />
+
Most advanced text editors (such as Notepad++) will save files as specified, without the need for the quotes-trick.
A. Absolutely nothing! There's a Script Manger under the Scripts menu. You can select scripts you want to install, right-click and select "install script." Then the magic happens. It's really simple.
 
:[[File:Script_Manager_Abridged.png]]
 
  
'''Q. At the top of the page you said "automatically update scripts." None of my scripts have updated themselves so how does that work?'''<br />
+
Most files should be saved in the "scripts" directory, which is located by default at the same directory level as the KoLmafia .jar or .exe file on Windows. You can also create a sub-directory under "scripts," and it will be listed in KoLmafia's Scripts Menu.
A. There's a preference you have to set to enable it which is off by default. Go to Preferences -> SVN -> Check "Update installed SVN projects on login." That will cause all your SVN installed scripts to be updated once a day.
 
:[[File:Preferences_SVN.png]]
 
  
'''Q. Why is SVN good for KoLmafia scripts?'''<br />
+
Relay browser scripts are the exception to the rule: they must be saved in the "relay" directory. Relay browser overrides need to be saved in the top level of "relay," and must be named the same as the page they will override, except with an ".ash" extension. For example, to override "charpane.php" your script would need to be named "charpane.ash". For user-interface scripts, the script name needs to start with "relay_" and end with ".ash". These scripts must also be saved in the top-level of the "relay" directory.
A. There are a whole bunch of reasons. I'll enumerate:
 
# It makes finding the script you want easy. Just read down the list checking the description for each.
 
# It makes script installation easier. The user doesn't have to ensure that the script is downloaded into the correct directory or fret about putting multiple files into multiple directories.
 
# It makes script updating easier. All scripts can be updated automatically at first run of the day, or the user can type <code> svn update </code> to manually update all scripts.
 
# It is easier for the scripter to publish his scripts and keep them up to date.
 
# When you recommend a script in chat, you can tell them its name in the Script Manager without their having to go download something from the KoLmafia forum.
 
  
'''Q. Why was this added to mafia?'''<br />
+
==Programming==
A. We understand that a lot of people don't use scripts, even scripts that will help them a lot. This is because they find it troublesome to find and install scripts. The intention is to make it easy to install scripts. Even a script like Character Info Toolbox which contains more than 30 files is easy to install now. Just install it from Mafia's Script Manager and every single file will be placed in the correct directory. If you don't like it, you can use the Script Manager to delete it and all those files are removed.
+
You should first read through the various pages listed under "LANGUAGE CONVENTIONS" on the [[Main Page]]. One should also be aware that, with the exception of [[Control Structures]], all ASH commands need to end with a semi-colon. Also, every identifier in ASH&mdash;variables, functions, and other various keywords&mdash;are case-insensitive, so <code>string myVar="abb"</code> and <code>STRing MYvar="abb"</code> produce the same results.
  
'''Q. Wait! Does this mean I don't have to find the correct thread on the KoLmafia forum and login there to install a script?'''<br />
+
===Variables===
A. Yup. It's incomprehensible to most of us, but we've noticed that people hate reading our forum. Now you won't have to do that.
+
Variables are used to hold information that you need to access multiple times. They must be declared before they can be used, by specifying the [[Data Types|Data Type]] that they will hold, followed by the variable name.
 +
{{CodeSample|description=For example:|code=<syntaxhighlight>int count;</syntaxhighlight>}}
 +
would declare a variable named "count" of an integer type. You can also set the initial value of a variable on the same line it is declared.
 +
{{CodeSample|description=On the other hand:|code=<syntaxhighlight>int count = 6;</syntaxhighlight>}}
 +
would declare the variable "count" with an initial value of 6.
  
'''Q. This sounds like black magic!'''<br />
+
Notice that you would not want to have both of the above lines in your script! Variables operate under what's referred to as their scope. In a nutshell, scope defines where a variable is accessible. Scope "cascades" down, similar to stylesheets for those familiar with web programming. A variable declared at the top-level of a script (a "global" variable), outside of any functions, will be accessible anywhere in your script, or in any other scripts that import it. A variable declared inside of a function will be accessible only inside that function (including inside of control structures), but is considered to not exist by other functions. Since ASH uses curly brace scope, variables within a set of curly braces ('''{ }''') will not be available outside that same set of braces.
A. Please state your problem in the form of a question.<br />
 
Q. How does that work?<br />
 
A. Black magic. Not really, but it is very impressive and you don't really need to know the mechanics. Just trust that it works.
 
  
 +
Declaring a variable multiple times will generate an [[ASH Errors#Variable is already defined|error]]. Note that this only applies to variable with overlapping scope; if one function uses a variable named "bob" that is declared inside of the function, another function can declare another variable with the same name, even as a different datatype. However, the error will still occur if you have a globally-defined variable, and then declare a variable with the same name inside of a function (as their scopes overlap).
  
== Revision Merging ==
+
===Functions===
There is another even more impressive ability of the KoLmafia's svn update: Revision Merging! This is only helpful to people who know how to modify someone's script, but you only need to understand a few lines of any script to make this worth reading.  
+
Functions are groupings of operations that can be applied multiple times by referencing the function name. Basically, they avoid having to re-type the same code over and over.
  
The ''real'' awesome here is aimed at people who sometimes like to make small modifications to their scripts. People like you with a little bit of scripting ability. I suspect you've sometimes made a tiny tweak to a script to make it more perfect for your specific needs. Then the original author updates his script and you're stuck trying to decide if it is worth your trouble to copy all your modifications to the new version of his script. If not, you might just refuse to update it. With SVN if you know what you are doing, you can update your cake and eat it too! When svn updates your script it will automatically keep your modifications, producing a blend of your modifications and the author's update. Now I'll tell you how to do this.
+
====Built-in functions====
 +
Many functions are built-in to KoLmafia, and examples can be found all over this wiki. Examples on the wiki are given in the following format:
  
# Acquire the most recent version using <code> svn update </code>
+
<b>datatypeReturned function_name([datatype1 parameter1] ...)</b>
# Open the script's working copy in the project's /svn directory, and make your edits. Always make sure the project in /svn has your changes
 
# Use the command <code> svn sync </code> to push your modifications in the working copy to the local copy in the /scripts or /relay directory
 
# If you ever want to modify your changes or add to them, just repeat steps 2 and 3.
 
  
That's it! Now you can update from svn as usual. You can use <code> svn update bale-ocd </code> to update just that script, or <code> svn update </code> to update all your scripts or just check the box in SVN preferences to make it happen automatically once a day. Whenever the script is updated SVN will magically merge your changes into the working copy in the /svn folder and then push those changes into the local copy. This is magic! This will happen every single time you use svn to update the script without requiring your intervention. The CLI will display a "G" for merGing the script instead of a "U" for Updating it when this happens.
+
The first part is the datatype that the function returns. Though you don't have to make use of this in a script, you would almost always want to (except for some functions that return a boolean). You need to be careful to match datatypes (though sometimes an implicit conversion is done; ie KoLmafia will usually translate a float into an int, and many commands that output text will implicitly convert from most datatypes). For example, if you have a variable of the datatype string, it is often an error to assign to it a function that returns an item.
  
=== Revision Conflicts ===
+
The function name follows and then parentheses, which may have nothing or multiple sets of datatypes & parameters.
If an update to a script changes it so severely that it cannot be merGed with your modifications, it will show "C" for Conflict and produce several files in the working copy to help you solve the problem:
 
* myfile - will have some inline markup at the location of the conflict ( look for <<<<<< and >>>>> markup) showing you both what your text was and what the repo's text was.
 
* myfile.mine - Your version before the update.
 
* myfile.rOld - The pristine repo versions from before the update.
 
* myfile.rNew - The pristine repo versions from after the update.
 
  
With all of these files, you can pretty easily figure out where the problem line(s) are, and how to fix them. Sometimes you'll just want to use rNew and discard your local changes, sometimes you'll want to do something else. Copy/pasting between the different files is straightforward. You will need to delete the extra files when you're done resolving the conflict, and make sure that the remaining file has the same name as the original file.
+
The parameter names are used for reference on the rest of the page (so you can match descriptions of parameters to the parameter in question, which is especially useful if the function takes more than one parameter with the same datatype).
  
 +
Note that, as with assignments of a function's return value, it is important to match the parameter datatypes when using the function. If you have a function with the parameter <b>item it</b>, and you supply the name of the item as text in quotes (which is how a string is written), you will get an error for doing so.
  
== Information for Scripters ==
+
====Custom-coded functions====
The SVN repo contains your project. It not only contains the files for your project, but every previous version of those files that's ever existed. Think of old versions like hitting ctrl-z on a Word document — you can revert changes all the way back to the start, or anywhere in between.
+
It's also possible to write your own functions. To do so, you declare them similarly to a variable as above. However, a function can also have the datatype of "void," which is not allowed for variables. A "void" function is one that does not return any value; it simply does what it's programmed to do and the rest of your program moves on, regardless of the results (unless of course an [[ASH Errors|error]] occurs, including a call to [[abort|abort()]].)
 +
{{CodeSample|description=For example, this simple function will double an integer:|code=<syntaxhighlight>
 +
int double_it(int value) {
 +
  return 2 * value;
 +
}
 +
</syntaxhighlight>}}
 +
{{CodeSample|description=Furthermore, there are two distinct ways to call functions, user-defined or built-in:<br />Conventional,|code=<syntaxhighlight>
 +
function(param1[,param2,param3,...]);
 +
</syntaxhighlight>}}
 +
{{CodeSample|description=and "Java style":|code=<syntaxhighlight>
 +
param1.function([param2,param3,...]);
 +
</syntaxhighlight>}}
 +
The only difference between the two forms is aesthetics, as they are functionally equivalent.
 +
{{CodeSample|description=Also somewhat important to note is that these commands can be chained together, and they will be executed from left-to-right. So, for instance,|code=<syntaxhighlight>
 +
"polka pop".to_item().to_int()
 +
</syntaxhighlight>}}
 +
{{CodeSample|description=will return the item number for $item[Polka Pop], 4342. This is one instance where "Java style" is more aesthetically pleasing compared to the conventional|code=<syntaxhighlight>
 +
to_int(to_item("polka pop"))
 +
</syntaxhighlight>}}
  
It is more than just a place to save files though. There is something called a Working Copy, which is a local version of a remote repository, plus any local changes you may have made. The process of creating this Working Copy is referred to as "checking out" the repo, or "checkout." You have probably also heard the term "commit" which is simply taking some/all local changes in a working copy and syncing them with the repo. Then other users sync their working copies with the repo, and voila!
+
Note that scope (discussed above, under [[ASH_For_Beginners#Variables|Variables]]) also applies to user-defined functions. Also, functions built into KoLmafia have priority over any user-defined functions with the same name and parameters.
  
=== How to Set Up a Repo ===
+
===String Concatenation===
A working copy contains a hidden folder, .svn, that contains all of the metadata needed to know how your local version differs from the repository's version. This is created for you when you checkout the project. You don't really need to know any of these details, really, for the most part using svn does not require knowing how it works under the hood. What you may be interested in is how to create your own repo.  
+
The basics to string concatenation: "Hello" + "world" yields "Helloworld". Likewise, variables can be strung together in this fashion. Unless the variables are both numbers (floats, booleans, or ints), they will be converted to strings, then concatenated. For instance: "3x " + $item[Polka Pop] yields "3x Polka Pop".
  
I'll go over the easiest method under Windows - using TortoiseSVN. Under *nix you should probably just be using the command line "svn" client, though I imagine there are a million different graphical alternatives. There are alternatives in windows as well, I just prefer TortoiseSVN for its file system integration.
+
==Running a Script==
 +
Once your script is saved, you can run it.  Scripts saved in the scripts directory will appear in Mafia under the scripts menu. Simply clicking on one will run it.  You may also run your script from the command line by typing "exec" followed by the script name For instance: exec myscript.
  
First, get a [https://sourceforge.net/ sourceforge] account. Make a new project there. Download [http://tortoisesvn.net/downloads.html TortoiseSVN] and install it. Make a new folder somewhere on your computer. Right-click, and choose SVN Checkout... from the context menu. You will want to give it the address that you see on your new sourceforge project code page - for now just grab the http:// address, it's easier. Ignore the commands in front of the address and after it, those are for command-line svn tools.
+
The script looks for the function 'main()' in order to know where to start.  
  
The rest of the default options are okay. Click OK and you should get a new working copy of your repo! Cool. Open it up and let's add some stuff. Add a new directory called scripts/, and within scripts/ put a new text file. Now navigate back up to the root of your working copy, right click on the folder, and choose SVN commit... Tick all the files/folders (tick the "show unversioned files" box if it's not ticked), give it a quick commit comment up top. You should have to enter your sourceforge user information, save it if you want. If you've done everything correctly, your new project should have been committed.
+
{{CodeSample|description=Generally the function will look like this:|code=<syntaxhighlight>
 +
void main() {
 +
  // the rest of your code
 +
}
 +
</syntaxhighlight>}}
  
Optional: to really play around with this, checkout a second working copy somewhere in another folder on your computer. Try committing changes from one working copy to the repo, then doing right-click SVN Update on the other working copy. Notice how TortoiseSVN helpfully changes the little file/folder icons for you when you make modifications to things. Hopefully you're starting to see how this whole thing works.
+
The main function can contain variables, other code and calls to other functions within the script.
  
=== What it Can Do ===
+
You may also have an input into your main function. By requiring an input, this will cause KoLmafia to show a textbox to the user in order to get input into the script. This textbox can be filled in and submitted, or cancelled.  
Svn is a very mature tool by now, so there's an absolute ton of stuff that I won't cover. You may for example notice that mafia itself has a "Latest SVN Changes" forum, which has .diffs of all the changes to files within mafia. There's also creating patches, merging repos, yada yada... Won't talk about it.
 
  
I'm more interested in talking about how mafia svn integration works. Doing <code> svn checkout <repo> </code> creates a working copy of the repo in your svn/ folder. Then, mafia "pushes" the contents of that working copy to the appropriate subfolders. For example, if a repo has a scripts/dostuff.ash file, that file gets copied to your scripts/ folder.
+
[[Category:Scripting]]
 
 
svn update goes through all your working copies and performs an update. There are other operations that can happen here. With a checkout, you can only be adding ("A") new files to a working copy. With an update you can update ("U"), merge ("G"), delete ("D") or also add ("A") files. Here, we warn the user whenever a file is added, due to security concerns. Note that "U"pdating '''only happens if the "pushed" local file still exists in the user's directory'''. I am bolding this because I'm sure it will confuse some people. This feature is a safeguard against svn re-installing scripts over and over that the user just wants to have deleted.
 
 
 
If you installed TortoiseSVN above and browse to the svn/ folder, you may notice something: the working copies checked out with svn checkout are fully-featured working copies, just like you checked out using TortoiseSVN. This means that you can make changes directly to this folder and commit them to the repo using TortoiseSVN - if you have repo commit permissions, of course.
 
 
 
=== Specifications ===
 
At the base level of the SVN link there are only several legal folders which may contain scripts:
 
 
 
* <code>ccs/</code>
 
* <code>data/</code>
 
* <code>images/</code> (see notes)
 
* <code>planting/</code>
 
* <code>relay/</code>
 
* <code>scripts/</code>
 
 
 
Additionally there is only one legal file:
 
 
 
* <code>dependencies.txt</code>
 
 
 
If there are any other folders or files at the base level of the SVN repository, KoLmafia will refuse to check out the repository. This is a security feature. Within the stated folders you can nest any additional folders and files you desire.
 
 
 
When the SVN repo is committed, the scripts in the folders will be pushed to local copies in corresponding folders in the KoLmafia directory. If there is a file of the same name in any of those folder, or a sub-folder of those folders, then the file will be copied to that location. This allows the user to move the files to new locations or sub-folders and still know that KoLmafia will keep it up to date.
 
 
 
'''Note''': If your relay override script uses images, place them under <code>images/relayimages/</code>. This is because KoLmafia serves images only if they are under <code>images/</code>[https://kolmafia.us/threads/performance-issues.13387/post-98934]. However, the <code>cache clear</code> command will delete all files under <code>images/</code> except for the <code>images/relayimages/</code>[https://kolmafia.us/threads/performance-issues.13387/post-98980].
 
 
 
==== Declaring Dependencies ====
 
The file <code>'''dependencies.txt'''</code> contains a list of other SVN repositories that this script will automatically install. This is done so that the script can install other scripts it depends on. If there is a <code>'''dependencies.txt'''</code> file at the root directory of the repo, it will not be pushed along with the files in the various folders. It only exists to serve this purpose. Each line in the file provides a url to another SVN project. Here is an example of what a <code>'''dependencies.txt'''</code> file may look like:
 
 
 
<pre>
 
https://svn.code.sf.net/p/zlib/code
 
https://svn.code.sf.net/p/smartstasis/code
 
https://svn.code.sf.net/p/therazekolmafia/canadv/code/
 
</pre>
 
 
 
== How to Command SVN ==
 
KoLmafia has both ASH and CLI commands to interact with SVN repos.
 
=== CLI Commands ===
 
SVN Repositories can be checked out, updated or deleted from the CLI with the following commands:
 
* <code>svn checkout <svnurl></code>
 
: This checks out an svn repository and adds the files from the working copy to the appropriate locations. <svnurl> must be a <nowiki>svn://, http://, or https://</nowiki> link to a valid svn repo.
 
* <code>svn list</code>
 
: This lists installed projects.
 
* <code>svn update </code>
 
* <code>svn update <projectname></code>
 
* <code>svn update <SVNURL></code>
 
: This updates your installed projects and pushes any changes to the appropriate locations. If the parameter is blank it will update everything.
 
* <code>svn delete <projectname></code>
 
: This deletes an installed project and the corresponding files that it pushed. <projectname> fuzzy matches the script names from svn list.
 
* <code>svn increment <projectname></code>
 
* <code>svn decrement <projectname></code>
 
: These two commands move an installed svn project up/down one revision, respectively.
 
* <code>svn inc <projectname></code>
 
* <code>svn dec <projectname></code>
 
: The same as the previous two commands. Because typing stuff is hard.
 
* <code>svn sync</code>
 
: This looks through your working copies for modifications, then checks if that file differs from the local copy. If it differs, the working copy file is copied over the local copy one. Note that this is very different from "svn update" and does not contact the repository server at all.
 
 
 
=== ASH Commands ===
 
There are a few additional functions that ASH possesses to check up on an SVN repo.
 
* {{Flink|boolean|svn_exists|string|desc=Returns true if a valid working copy named projectname exists in the /svn folder.}}
 
* {{Flink|boolean|svn_at_head|string|desc=Returns true if projectname exists, is a valid working copy, and is currently at the same revision number as the repository.}}
 
* {{Flink|record|svn_info|string|desc=Returns a record containing additional information about the given projectname: svnurl, last author, last revision, last change date.}}
 
 
 
 
 
[[Category:New User Help]][[Category:Scripting]][[Category:Tech Support]]
 

Revision as of 22:28, 8 April 2021

File Editing

To create and edit ASH scripts, you need a text editing program that doesn't automatically add line-breaks for word wrapping.

Mac

While the built in editor TextEdit will work fine (as long as you remember to write only in plaintext), BBEdit is a much more powerful tool. It may not be designed for ASH scripting specifically, but it was written for a similar purpose. It can has a paid mode with more features, but those features are optional. BBEdit users can install the ASH Language Module to provide syntax colorization.

Linux

If you use Linux, you probably already know about the options available for text editing. Emacs, Vi, etc. are all fine for creating ASH scripts.

Windows

Windows users beware; using Microsoft Word to create ASH files will lead to no end of headaches! The built-in program notepad will work, as can wordpad when configured with the option "No Wrap" for text. However, having a program that can handle syntax-highlighting can be very beneficial. Many scripters recommend Notepad++ for ASH (and other programmatic) scripting. In this case, it's also beneficial to have a style configuration that works well with ASH, and one example can be found here.

Saving

ASH scripts need to be saved with the file extension ".ash" to be properly recognized by KoLmafia. If you're using a built-in text editor on a Windows machine, it may automatically save your files with the ".txt" extension by default. (So you may end up with a file called "script.ash.txt" instead of the desired "script.ash".) One way around this on Windows that usually works is to put quotes around the file name when you save it, including the extension.

Most advanced text editors (such as Notepad++) will save files as specified, without the need for the quotes-trick.

Most files should be saved in the "scripts" directory, which is located by default at the same directory level as the KoLmafia .jar or .exe file on Windows. You can also create a sub-directory under "scripts," and it will be listed in KoLmafia's Scripts Menu.

Relay browser scripts are the exception to the rule: they must be saved in the "relay" directory. Relay browser overrides need to be saved in the top level of "relay," and must be named the same as the page they will override, except with an ".ash" extension. For example, to override "charpane.php" your script would need to be named "charpane.ash". For user-interface scripts, the script name needs to start with "relay_" and end with ".ash". These scripts must also be saved in the top-level of the "relay" directory.

Programming

You should first read through the various pages listed under "LANGUAGE CONVENTIONS" on the Main Page. One should also be aware that, with the exception of Control Structures, all ASH commands need to end with a semi-colon. Also, every identifier in ASH—variables, functions, and other various keywords—are case-insensitive, so string myVar="abb" and STRing MYvar="abb" produce the same results.

Variables

Variables are used to hold information that you need to access multiple times. They must be declared before they can be used, by specifying the Data Type that they will hold, followed by the variable name.

For example:

int count;

would declare a variable named "count" of an integer type. You can also set the initial value of a variable on the same line it is declared.

On the other hand:

int count = 6;

would declare the variable "count" with an initial value of 6.

Notice that you would not want to have both of the above lines in your script! Variables operate under what's referred to as their scope. In a nutshell, scope defines where a variable is accessible. Scope "cascades" down, similar to stylesheets for those familiar with web programming. A variable declared at the top-level of a script (a "global" variable), outside of any functions, will be accessible anywhere in your script, or in any other scripts that import it. A variable declared inside of a function will be accessible only inside that function (including inside of control structures), but is considered to not exist by other functions. Since ASH uses curly brace scope, variables within a set of curly braces ({ }) will not be available outside that same set of braces.

Declaring a variable multiple times will generate an error. Note that this only applies to variable with overlapping scope; if one function uses a variable named "bob" that is declared inside of the function, another function can declare another variable with the same name, even as a different datatype. However, the error will still occur if you have a globally-defined variable, and then declare a variable with the same name inside of a function (as their scopes overlap).

Functions

Functions are groupings of operations that can be applied multiple times by referencing the function name. Basically, they avoid having to re-type the same code over and over.

Built-in functions

Many functions are built-in to KoLmafia, and examples can be found all over this wiki. Examples on the wiki are given in the following format:

datatypeReturned function_name([datatype1 parameter1] ...)

The first part is the datatype that the function returns. Though you don't have to make use of this in a script, you would almost always want to (except for some functions that return a boolean). You need to be careful to match datatypes (though sometimes an implicit conversion is done; ie KoLmafia will usually translate a float into an int, and many commands that output text will implicitly convert from most datatypes). For example, if you have a variable of the datatype string, it is often an error to assign to it a function that returns an item.

The function name follows and then parentheses, which may have nothing or multiple sets of datatypes & parameters.

The parameter names are used for reference on the rest of the page (so you can match descriptions of parameters to the parameter in question, which is especially useful if the function takes more than one parameter with the same datatype).

Note that, as with assignments of a function's return value, it is important to match the parameter datatypes when using the function. If you have a function with the parameter item it, and you supply the name of the item as text in quotes (which is how a string is written), you will get an error for doing so.

Custom-coded functions

It's also possible to write your own functions. To do so, you declare them similarly to a variable as above. However, a function can also have the datatype of "void," which is not allowed for variables. A "void" function is one that does not return any value; it simply does what it's programmed to do and the rest of your program moves on, regardless of the results (unless of course an error occurs, including a call to abort().)

For example, this simple function will double an integer:

int double_it(int value) {
   return 2 * value;
}

Furthermore, there are two distinct ways to call functions, user-defined or built-in:
Conventional,

function(param1[,param2,param3,...]);

and "Java style":

param1.function([param2,param3,...]);

The only difference between the two forms is aesthetics, as they are functionally equivalent.

Also somewhat important to note is that these commands can be chained together, and they will be executed from left-to-right. So, for instance,

"polka pop".to_item().to_int()

will return the item number for $item[Polka Pop], 4342. This is one instance where "Java style" is more aesthetically pleasing compared to the conventional

to_int(to_item("polka pop"))


Note that scope (discussed above, under Variables) also applies to user-defined functions. Also, functions built into KoLmafia have priority over any user-defined functions with the same name and parameters.

String Concatenation

The basics to string concatenation: "Hello" + "world" yields "Helloworld". Likewise, variables can be strung together in this fashion. Unless the variables are both numbers (floats, booleans, or ints), they will be converted to strings, then concatenated. For instance: "3x " + $item[Polka Pop] yields "3x Polka Pop".

Running a Script

Once your script is saved, you can run it. Scripts saved in the scripts directory will appear in Mafia under the scripts menu. Simply clicking on one will run it. You may also run your script from the command line by typing "exec" followed by the script name For instance: exec myscript.

The script looks for the function 'main()' in order to know where to start.

Generally the function will look like this:

void main() {
   // the rest of your code
}


The main function can contain variables, other code and calls to other functions within the script.

You may also have an input into your main function. By requiring an input, this will cause KoLmafia to show a textbox to the user in order to get input into the script. This textbox can be filled in and submitted, or cancelled.