These are some standards and conventions that I use in my scripts:

General Conventions Edit

It is highly recommended that you show the output window while the script is running.

A script will set the recent best score at the beginning of the script. If the script is stopped at any time, you may restore the recent best to recover the best score since the script was started. A recipe will never (and should never) work with the absolute best score.

Any improvement in the recent best score will be noted in the output window surrounded by ++++ symbols. This means the script found points.

Any time that a recipe starts, it will report the improvement since the script started surrounded by >>>> score <<<<. It will also report the improvement since the script started. When the script ends, it will report the same.

Script Main Code Edit

The main code of the script must begin with fsl.ScriptInitialize() and end with fsl.ScriptFinalize(). Between these are calls to the recipes. This will appear at the end of the script. For example:


Recipes Edit

Recipes are parts of a script. These are algorithms that manipulate the protein or user interface somehow.

Recipes must be structured like this:

local function _RecipeName(arg1, arg2)
    local functionName, scoreStart = fsl.ScriptBegin('Recipe Name')
    --code for the recipe goes here
    return fsl.ScriptEnd(functionName, scoreStart, false)

The argument to the ScriptBegin function is the name of the recipe. The third argument to the fsl.ScriptEnd() function determines whether the recipe restores to the recent best when it exits. An optional fourth argument is a function to run after restoring to the recent best.

There should be an entry in the recipe table. For example:

recipe =
    RepeatBlueFuse = _RepeatBlueFuse,

    Cataclysm = _Cataclysm,

    RecipeName = _RecipeName,

The recipe is called in the main code by using this code:

recipe.RecipeName(val1, val2)

Code in recipes are not allowed to call functions that begin with an underscore. Code in the fsl library is allowed to call functions that begins with an underscore. The same is true for variables that begin with an underscore. If the code inside a recipe needs to have a function to call, then it should be structured like this:

local function _CommonFunction()
    -- body of common function

local exampleprocs =
    CommonFunction = _CommonFunction,

Then called like this


Reporting and Locking in Score Improvements Edit

Any time the recipe may have improved the score, it should call fsl.ReportAndLockScoreIncrease(). Most calls to the fsl library do this already, but you should check and make sure.

Banding Edit

A normal recipe is not allowed to delete existing bands. If the user has placed 150 bands to the guide, he is going to be extremely annoyed that his bands have been deleted.

Instead, the recipe can disable the existing bands at the beginning of the script with fsl.BandDisable(). Afterward, loops that enumerate all bands must skip the bands that existed when the script started. This can be done like this:

for i=fsl.BandsAtStart() + 1, foldit.GetBandCount() do
    --example code content of loop
    foldit.BandSetLength(i, 20.0)
    foldit.BandSetStrength(i, 10.0)

If a recipe makes radical changes to the structure, such as tlaloc Make Denovo or tlaloc Find Best Start, which requires the use of all bands, then the recipe must start with this code:

assert(foldit.GetBandCount() == 0, 'Must delete existing bands\nbefore running this code.')

This prevents the code from killing existing bands. The user must manually kill the bands before running the code. Any call to fsl.SetPristine() that deletes bands must have this assertion at the beginning of the recipe.

Working with Save Slots Edit

All code that works with a save slot, must request one with fsl.RequestSaveSlot(), then release it when it is done with it with fsl.ReleaseSaveSlot(). This makes the code generic, so that functions won't stomp on each other's save slots. For example:

    local saveSlot = fsl.RequestSaveSlot()
    -- more code here

These must always be paired.

Printing Edit

Printing to the output window must be done with fsl.Print(). Printing can be disabled across a block of code using

local printStatus = fsl.PrintStatus(false)
-- code that won't print

These must always be paired. This will never disable the reporting of an score improvement to the recent best score (i.e. a ++++ score ++++).

Cancel by user Edit

To exit gracefully and reset Clash Importance=1 when a user cancels a script create a Cleanup function in Lua V2. V2 supports the xpcall function (see the Lua documentation). Clicking the Cancel button actually generates an error that can be trapped. Here is an example of using a cleanup function in V2 to reset the clash importance back to 1.00 if you hit cancel. Try hitting the Cancel button while it is performing the WiggleAll and watch it reset back to 1.00.

function test()
	print("In test")

function cleanup()
	print("Cleaning up")

xpcall(test, cleanup)
Community content is available under CC-BY-SA unless otherwise noted.