The lib_include function contains the 'include' and 'run' functions, which aim to simplify the organization of your mod into separate pieces of code. One way they do this is through the lib_sugar library, which aims to make WEIDU syntax easier by introducing 'syntactic sugar' –i.e., abbreviations for WEIDU code that make code easier to write and more readable. (Even WEIDU's greatest fans (i.e., me) will concede that its syntax leaves a lot to be desired.).
The 'include' function is just a variant of WEIDU's core 'INCLUDE' command. Instead of including a piece of code with
INCLUDE "%MOD_FOLDER%/lib/mycode.tph"
LAF include STR_VAR file=mycode.tph location=lib END
(you can specify the location of the file in the usual SFO way). This automatically applies SFO's syntactic sugar (see below), which is the main reason to use 'include'; if for some reason you don't want it applied, you can set the INT_VAR 'literal' to 1. Note that because 'include' is a function, the scope of the included file is automatically restricted to the function call. (If you actually want to set variables in an included file to use elsewhere, use WEIDU's native functionality - but usually you should not do this.)
Instead of a single file, 'file' can be a space-separated list of files, in which case 'include' includes them all, in order. The same location/locbase/path applies to each.
'run' is a more powerful tool for including files. It specifically applies to so-called 'tpa' files - a tpa file is a file containing WEIDU code (possibly including SFO syntactic sugar) that contains a 'main function': an action function that has the same name as the file itself. So minsc.tpa should contain the action function 'minsc'. That action function should have no arguments (except possibly the STR_VAR 'version'; see below), and should return nothing. Any other functions defined in a tpa should be used only in the main function (though I can't enforce this requirement).
'run' loads the tpa file into memory, applying SFO syntactic sugar if appropriate (as with 'include', set literal=0 to skip this), and then runs the main function. The idea is that a tpa file contains a delineated part of your mod, and execution of a mod component is just the running of one or more tpa files.
An example use of run:
LAF run STR_VAR file=minsc location=npcs END
The location of 'minsc.tpa' is determined in the usual SFO (location/locbase/path) way.
As with 'include', 'file' can be a space-separated list of tpa files (all omitting the '.tpa' suffix).
SFO's intended mod style is that each component is given by a tpa. (That tpa might call other components in turn.) For instance, Talent's of Faerun's 'Add subraces' component's entry in the main TP2 file, in its entirety, is
//////////////////////////////////////////////////////////////////////
/// New races and subraces
//////////////////////////////////////////////////////////////////////
BEGIN @200 DESIGNATED 20000 GROUP @2
REQUIRE_PREDICATE GAME_IS "bgee bg2ee eet iwdee" @50
FORBID_COMPONENT "setup-stratagems.tp2" 5900 @70
LAF run STR_VAR file=subrace location=subrace END
The component specification is the various require and forbid instructions, and then a single 'run' call - everything else is outsourced to the file 'subrace.tpa', which is found in dw_talents/subrace. (Note that since 'run' is a function, this automatically encapsulates the component: nothing in it can affect other components.
When 'run' is used this way, it has some extra features. Any time 'run' is used outside the scope of any other 'run' command (the idea is this happens only when you use 'run' in your tp2 file to call the whole component, though I can't enforce that), the following things happen:
The other way is to define an anonymous function: here you don't need to do anything special to use syntactic sugar, it's included automatically.
If for some reason you want to apply syntactic sugar directly, the patch function 'sugar_apply' will carry out substitutions on the current file.
For this section, code fragments will be assumed to be included via lib_include or an anonymous function.
You can set a string variable in action context like this:
myvar:=="Minsc is a ranger"
(This just abbreviates OUTER_SPRINT myvar "Minsc is a ranger".) In patch context, use ':=' instead of ':=='.
You can write "%string1%"=="%string2%" (and similar) as an abbreviation for "%string1%" STR_EQ "%string2%". Similarly, "%string1%"!=="%string2%" abbreviates "%string1%" STR_CMP "%string2%.
Instead of doing BEGIN … END, you can do [[… ]] in action context and {{ … }} in patch context. (This is a general feature of SFO syntactic sugar: [,] are used in action contexts, {,} in patch contexts.)
You can do an ACTION_IF loop like this:
IF [condition]
[[
action
]]
and a PATCH_IF loop like this:
IF {condition}
{{
action
}}
[[[
code
]]]
abbreviates
OUTER_PATCH "" BEGIN
code
END
Similarly,
{{{
code
}}}
INNER_ACTION BEGIN
code
END
Defining arrays
You can define a new array by
array.new[my_array]
[[
key1=>val1
key2=>val2
…
]]
ACTION_CLEAR_ARRAY my_array
ACTION_DEFINE_ASSOCIATIVE_ARRAY my_array BEGIN
key1=>val1
key2=>val2
…
END
To add to an existing array (i.e. skip the ACTION_CLEAR_ARRAY), use array.add instead. To do it all in patch context, just use {{,}} instead of [[,]].
var=race.int[DWARF]
var=IDS_OF_SYMBOL (race DWARF)
var=race.sym[3]
OUTER_PATCH "" BEGIN
LOOKUP_IDS_SYMBOL_OF_INT var race 3
END
Again, just swap square brackets to curly brackets to work in patch context. (I'm mostly going to stop saying that from here on.)
This code reads in the string at the given strref, applies the code to it as a patch function, and resets the strref to the new string.
strref.patch[9501]
[
REPLACE_TEXTUALLY "Minsc" "Minsc the Awesome"
]
You can patch a string like this:
myvar2=myvar.patch[REPLACE_TEXTUALLY "Minsc" "Minsc the Awesome"]
Alternatively you can write the string into dialog.tlk (after patching) and return the strref:
myvar_strref=myvar.strref[REPLACE_TEXTUALLY "Minsc" "Minsc the Awesome"]
You can also display the result of a patch:
myvar.print[REPLACE_TEXTUALLY "Minsc" "Minsc the Awesome"]
In each case, you can leave the [] empty if you want.
A function with no arguments can be called like this:
run_this[]
which is equivalent to
LAF run_this END
If the function takes a STR_VAR argument 'arguments', you can set the argument like this:
run_this[cat]
which is equivalent to
LAF run_this STR_VAR arguments="cat" END
Other arguments can be included in this form:
run_this[cat| number_of_cats:i=4 size_of_cats="large"]
which abbreviates
LAF run_this INT_VAR number_of_cats=4 STR_VAR arguments="cat" size_of_cats="large" END
You can leave out the 'arguments' bit entirely, but you still need the |, as in
run_this[| number_of_cats:i=4 size_of_cats="large"]
which abbreviates
LAF run_this INT_VAR number_of_cats=4 STR_VAR size_of_cats="large" END
If the function returns 'value', you can do
out=run_this[cat]
which abbreviates
LAF run_this STR_VAR arguments=cat RET out=value END
(SFO has other syntactic sugar related to functions, but it is specific to the various struct functions used in lib_struct, which is discussed elsewhere.)