<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.hard-light.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=72.194.192.77</id>
	<title>FreeSpace Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.hard-light.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=72.194.192.77"/>
	<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php/Special:Contributions/72.194.192.77"/>
	<updated>2026-11-15T12:01:07Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Scripting_API&amp;diff=4644</id>
		<title>Scripting API</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Scripting_API&amp;diff=4644"/>
		<updated>2006-02-13T07:36:41Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The FS2_Open scripting API is intended to be as cross-platform and as language non-specific as possible. However, it is generally assumed that the most popular language will be Lua.&lt;br /&gt;
&lt;br /&gt;
==Part One: Basic API and Scripting Hooks ==&lt;br /&gt;
===Things To Know===&lt;br /&gt;
;Script_system:This object abstracts a scripting session. It is generally used to allow for easy construction/destruction of whatever is necessary to initialize scripting system objects, and make sure that the right language session data is passed. Its constructor takes one argument, the name of the scripting session (for easy debugging)&lt;br /&gt;
;Script_system.CreateLuaSession(libraries):Initializes a Lua session. Until this is called, you will not be able to use Lua at all and fs2_open should ignore code chunks that use it.&lt;br /&gt;
;Script_system.ParseChunk(debugname):Parses a &#039;code chunk&#039;. These are snippets of code encapsulated by symbols such as square brackets or parentheses. It stores a handle to the parsed script in memory (Probably bytecode).&lt;br /&gt;
:script_system.RunBytecode(handle):Actually executes a code chunk that has been parsed with ParseChunk&lt;br /&gt;
====Example====&lt;br /&gt;
This snippet of code (using FS2_Open functions) will parse a file that has scripting after each &amp;quot;$Global:&amp;quot; variable identifier. After all the scripting has been parsed, it will evaluate every hook, once.&lt;br /&gt;
 //Create script system object&lt;br /&gt;
 script_system Script_system;&lt;br /&gt;
 &lt;br /&gt;
 //Create array that holds a series of scripting hooks&lt;br /&gt;
 std::vector&amp;lt;script_hook&amp;gt; Script_globalhooks;&lt;br /&gt;
 &lt;br /&gt;
 //Initialize Lua&lt;br /&gt;
 Script_system.CreateLuaState(Lua_libraries);&lt;br /&gt;
 &lt;br /&gt;
 //Parse file&lt;br /&gt;
 read_file_text(&amp;quot;scripting.tbl&amp;quot;);&lt;br /&gt;
 reset_parse();&lt;br /&gt;
 while(optional_string(&amp;quot;$Global:&amp;quot;))&lt;br /&gt;
 {&lt;br /&gt;
 	Script_globalhooks.push_back(st-&amp;gt;ParseChunk());&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 //Execute hooks&lt;br /&gt;
 for(uint i = 0; i &amp;lt; Script_globalhooks.size(); i++)&lt;br /&gt;
 {&lt;br /&gt;
 	Script_system.RunBytecode(Script_globalhooks[i]);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
==Part Two: The Higher-Level Lua Library==&lt;br /&gt;
The Lua library is probably what you&#039;ll want to be the most familiar with, as it&#039;s where you&#039;ll edit to add functions, classes, libraries, and variables.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Limitations===&lt;br /&gt;
* Lbraries can only contain functions, and not variables or arrays.&lt;br /&gt;
* All &amp;quot;arrays&amp;quot; must be an object with an indexer (see LUA_INDEXER define).&amp;lt;br&amp;gt;I was not able to get this working originally, but I&#039;ve got another idea on how to try this so if you really feel an array class would be best in a given situation, tell me.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===General conventions===&lt;br /&gt;
For the internal Lua API:&lt;br /&gt;
* All internal lua functions are prefixed with lua_&lt;br /&gt;
* All Lua library and object variables are prefixed with l_, so &amp;quot;l_Graphics&amp;quot;.&lt;br /&gt;
* When failure occurs due to a bad type being passed, or a subsystem not being ready, LUA_RETURN_NIL is usually used.&lt;br /&gt;
* When failure lies with the content of data, rather than the circumstances or type, LUA_RETURN_FALSE is generally used where appropriate.&lt;br /&gt;
&lt;br /&gt;
For Scripting:&lt;br /&gt;
* All variable names have the form of &amp;quot;EverySomethingIsCapitalized&amp;quot;&lt;br /&gt;
* All function names have the form of &amp;quot;doSomethingFast()&amp;quot;&lt;br /&gt;
* All object names have the form of &amp;quot;somethingneat&amp;quot;&lt;br /&gt;
* All library names are one capitalized word. For more than one word, the same syntax as variables(?)&lt;br /&gt;
* All library shortnames are two noncapitalized letters relating to the name. &amp;quot;Sound&amp;quot; -&amp;gt; &amp;quot;sd&amp;quot;&lt;br /&gt;
* So far, I&#039;ve used three-letter noncapitalized variables for globals. But I may decide to switch to the normal variable convention soon, as it&#039;s MUCH clearer about what the variable is.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Things To Know===&lt;br /&gt;
;lua_lib:Defines a Lua library.&lt;br /&gt;
;lua_obj:Defines a Lua object type (userdata).&lt;br /&gt;
;LUA_FUNC:Defines a Lua member function. Used with both lua_lib and lua_obj.&lt;br /&gt;
;LUA_VAR:Defines a Lua member variable. Only used with lua_obj.&lt;br /&gt;
;LUA_INDEXER:Defines Lua activity when brackets are used. Only used with lua_obj.&lt;br /&gt;
&lt;br /&gt;
Once you invoke any of the above, it&#039;s not necessary to do anything else for it to be present in Lua.&lt;br /&gt;
&lt;br /&gt;
===lua_lib===&lt;br /&gt;
 lua_lib l_Base(&amp;quot;Base&amp;quot;, &amp;quot;ba&amp;quot;, &amp;quot;Base Freespace 2 functions&amp;quot;);&lt;br /&gt;
Defines a Lua library, which can contain member functions (But not any kind of variables).&lt;br /&gt;
&lt;br /&gt;
Probably the simplest and most obvious to work with. The first field is the library name; the second is the shorthand version. The last is merely the description, which is only used for -ouput_scripting&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===lua_obj===&lt;br /&gt;
 lua_obj&amp;lt;object_h&amp;gt; l_Ship(&amp;quot;ship&amp;quot;, &amp;quot;Ship object&amp;quot;, &amp;amp;l_Object);&lt;br /&gt;
Defines a lua object, via a C++ template. The &amp;lt;&amp;gt; defines what type of C data the object will hold. In general, it&#039;s better to pass a handle to Freespace data (such as the ship_info struct) than to try and copy the entire thing. For &#039;static&#039; data - such as image handles or species indices - a simple &amp;lt;int&amp;gt; with the index of the item will suffice. For perishable data, you may want to store a unique identifier - say, an object&#039;s signature. In the above example, I use a helper struct that holds both a pointer to the object, and the object&#039;s signature. That way, all I need to do is check that the object at the pointer has the same signature to make sure that the handle is still valid.&lt;br /&gt;
&lt;br /&gt;
The next two parameters are fairly obvious - the name of the object (becomes the metatable name), and the description in output_scripting.&lt;br /&gt;
&lt;br /&gt;
The last parameter warrants some explanation - it is the parent of the object. Multiple levels of derived objects aren&#039;t supported, and a derived object must have the same type as its parent object, since all of the parent object&#039;s functions will generally only support the parent object&#039;s data type, and it&#039;s just needlessly complicating.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===LUA_FUNC===&lt;br /&gt;
 LUA_FUNC(newVector, l_Math, &amp;quot;[x, y, z]&amp;quot;, &amp;quot;Vector object&amp;quot;, &amp;quot;Creates a vector object&amp;quot;)&lt;br /&gt;
One of the two most used of the Big 5. The same tactics used for a LUA_FUNC are virtually the same for LUA_VAR and LUA_INDEXER.&lt;br /&gt;
&lt;br /&gt;
There are two components to LUA_FUNC. The first is the arguments (above); the second is the actual body.&lt;br /&gt;
&lt;br /&gt;
The arguments are, the function name (As it will appear in Lua). This is also used internally for the C compiler, so it is not actually a string. The second argument is the library or object that the function is a part of. So, the above example is the &amp;quot;newVector&amp;quot; function of the &amp;quot;Math&amp;quot; library, and would be accessed by calling &amp;quot;Math.newVector()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The third, fourth, and fifth arguments are all purely descriptive, but you should always fill them in if applicable to ensure good documentation. The first is the arguments that the function will take; they may be in any form you please, but I have generally used the &amp;quot;required, required, [optional, optional]&amp;quot; form. As you can see, in the example all arguments are optional.&lt;br /&gt;
The second argument is the return value. If the function returns different types, you should note it here.&lt;br /&gt;
The last argument is the basic description. Because it can be pretty long, I&#039;ve sometimes split it up across multiple lines.&lt;br /&gt;
&lt;br /&gt;
Now, for the body of the define:&lt;br /&gt;
 {&lt;br /&gt;
 	vec3d v3 = vmd_zero_vector;&lt;br /&gt;
 	lua_get_args(L, &amp;quot;|fff&amp;quot;, &amp;amp;v3.xyz.x, &amp;amp;v3.xyz.y, &amp;amp;v3.xyz.z);&lt;br /&gt;
 	return lua_set_args(L, &amp;quot;o&amp;quot;, l_Vector.Set(v3));&lt;br /&gt;
 }&lt;br /&gt;
&#039;&#039;&#039;Defining function variables&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In the first line, we create the C vector object that we&#039;re going to return, and initialize it to 0 (since all arguments are optional).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parsing arguments passed to your function in Lua&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In the second line, lua_get_args is used to parse the arguments from Lua. This function is big and messy and takes care of all the warnings and errors that may be caused by invalid types and such. The first argument, L, is just the lua state data that must be passed along; ignore it but don&#039;t forget it. The second argument is a list of characters that specify the variable types. These characters represent the following C types:&lt;br /&gt;
*b - Boolean&lt;br /&gt;
*d - Double&lt;br /&gt;
*f - Float&lt;br /&gt;
*i - Int&lt;br /&gt;
*s - String&lt;br /&gt;
*x - Fix&lt;br /&gt;
*o - lua_obj (See later)&lt;br /&gt;
Finally,&lt;br /&gt;
*| - Denotes all variables after this as being optional.&lt;br /&gt;
&lt;br /&gt;
All arguments after the formatting string should be pointers to the variables you want lua_get_args to set. Be careful; compilers will not catch if you use the a boolean where you have specified a double, for example. Optional variables will only be changed if a value is specified.&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If a wrong type is passed to an optional variable of your function, that variable will be skipped, although variables after it may be changed.&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You do pass pointers to (char *), so you end up passing a char **. Lua will take care of all memory concerns; don&#039;t try to deallocate the pointer yourself.&lt;br /&gt;
&lt;br /&gt;
When using the &#039;o&#039; parameter, you can get objects in one of two ways:&lt;br /&gt;
 vec3d v3;&lt;br /&gt;
 vec3d *v3p;&lt;br /&gt;
 lua_get_args(L, &amp;quot;oo&amp;quot;, l_Vector.GetPtr(&amp;amp;v3p), l_Vector.Get(&amp;amp;v3));&lt;br /&gt;
&amp;quot;v3p&amp;quot; would be a pointer to the first object&#039;s data, while &amp;quot;v3&amp;quot; would merely hold a copy of the data in the second object. Because it&#039;s not necessary to allocate or copy as much memory, getting pointers may be faster; but at the same time, you should be careful not to change the data in the pointer unless you really want to, as it will change the actual object&#039;s data. &#039;&#039;&#039;&#039;&#039;When you define a member function, the object will be passed as the first argument&#039;&#039;&#039;&#039;&#039;. As a result, this lua_get_args call would be suitable for, say, a function that copies the data passed in the argument to the calling object - &amp;quot;vectora:copyData(vectorb)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
lua_get_args will return the number of arguments parsed, or 0 if the required variables requirement was not met. So when working with required variables (or an object), you should generally use the form:&lt;br /&gt;
 if(!lua_get_args(...))&lt;br /&gt;
 	return LUA_RETURN_NIL;&lt;br /&gt;
The exception being when you want to actually know the number of arguments, in which case you should handle 0 appropriately. (More on LUA_RETURN_NIL later)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Return values&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return values are set via the lua_set_args function, which works pretty much exactly the same as lua_get_args, except in reverse. The differences:&lt;br /&gt;
*Actual variables, rather than pointers, are passed.&lt;br /&gt;
*Objects use their .Set() function (and there is no SetPtr() function).&lt;br /&gt;
*No | character&lt;br /&gt;
&lt;br /&gt;
Always use &amp;quot;return lua_set_args&amp;quot;, or one of the following:&lt;br /&gt;
*LUA_RETURN_NIL - Function returns nothing.&lt;br /&gt;
*LUA_RETURN_FALSE - Function returns false.&lt;br /&gt;
*LUA_RETURN_TRUE - Function returns true.&lt;br /&gt;
&lt;br /&gt;
Yes, you can have multiple return values. The syntax in Lua is:&lt;br /&gt;
 a, b = Library.theFunction() --In Lua&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Operators&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Definitely an advanced topic, which I will write when someone has need for it. These are slightly crazy as you can reverse objects and I don&#039;t fully understand what happens when you try to use an operator on two different objects that have different actions defined for that one operator.&lt;br /&gt;
&lt;br /&gt;
Look at the vector class for what I&#039;ve done with operators; if you got the LUA_FUNC section, you should be able to understand it. Note that the lua_isnumber() functions take the almighty L, and the argument index to check (Starting from 1).&lt;br /&gt;
&lt;br /&gt;
Look up the lua_Operators[] array for the full list of operators, as well as a bit of descriptive text.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===LUA_VAR===&lt;br /&gt;
 LUA_VAR(Name, l_Species, &amp;quot;String&amp;quot;, &amp;quot;Species name&amp;quot;)&lt;br /&gt;
Arguments are variable name, object that this variable will be a member of, the type that this variable is, and a brief description of what the variable is.&lt;br /&gt;
&lt;br /&gt;
Variables defined by fs2_open are functions. This is generally the easiest and fastest way to go about doing things, since Lua is only a part of the much-larger fs2_open base, which cannot be going through the API to get at variables - not without causing massive code rewrites and slowdowns.&lt;br /&gt;
&lt;br /&gt;
So, if you want an object to have actual data, you&#039;ll have to rely on the internal C dataset to do this. See the vector class for a good example.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Actually doing stuff with LUA_VAR&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The two big differences with LUA_VAR are the LUA_SETTING_VAR macro, and how lua_get_args is used. Much like with functions, the first argument of lua_get_args will be the object that the variable is a member of. The second argument is optional, and is the value that the variable may be set to.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the body for the above example, minus some safeguarding to make it easier to read:&lt;br /&gt;
 	char *s = NULL;&lt;br /&gt;
 	int idx;&lt;br /&gt;
 	if(!lua_get_args(L, &amp;quot;o|s&amp;quot;, l_Species.Get(&amp;amp;idx), &amp;amp;s))&lt;br /&gt;
 		return LUA_RETURN_NIL;&lt;br /&gt;
 &lt;br /&gt;
 	if(LUA_SETTING_VAR &amp;amp;&amp;amp; s != NULL) {&lt;br /&gt;
 		strncpy(Species_info[idx].species_name, s, sizeof(Species_info[idx].species_name)-1);&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	return lua_set_args(L, &amp;quot;s&amp;quot;, Species_info[idx].species_name);&lt;br /&gt;
&lt;br /&gt;
You should consider LUA_SETTING_VAR to be the safest way of determining whether or not a variable is actually being set, because it uses Lua&#039;s own internal guidelines to determine this. &lt;br /&gt;
&lt;br /&gt;
It is good practice to return the value of the variable after changing it, so the scripter can check the value afterwards.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===LUA_INDEXER===&lt;br /&gt;
 LUA_INDEXER(l_ShipTextures, &amp;quot;Texture name or index&amp;quot;, &amp;quot;Texture&amp;quot;, &amp;quot;Ship textures&amp;quot;)&lt;br /&gt;
First argument is the object, second is what can be placed in the brackets ([]), third is the type returned, and fourth is a description of what the array is.&lt;br /&gt;
&lt;br /&gt;
The first argument passed to the indexer will be the parent object; the second, the index (This can be whatever you like - a number, a string, even an image handle, just as long as lua_get_args can handle it). The third, the value that the scripter wants the current index to be set to.&lt;br /&gt;
&lt;br /&gt;
In all other respects, it is exactly like LUA_VAR; use LUA_SETTING_VAR to determine whether you are in setting mode or not.&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Development_Reference&amp;diff=2015</id>
		<title>Development Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Development_Reference&amp;diff=2015"/>
		<updated>2006-02-04T02:26:50Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: Made page a list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Scripting API]]&lt;br /&gt;
* [[FS2_Open Lua Scripting]]&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=4751</id>
		<title>FS2 Open Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=4751"/>
		<updated>2006-02-03T21:48:44Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: Added information on +Override&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is intended as a crash-course in Lua scripting as it relates to Freespace 2. It&#039;s only meant to get you started with Lua scripting - more advanced concepts such as metatables will not be covered.&lt;br /&gt;
&lt;br /&gt;
You don&#039;t need to read the Appendices, but I recommend at least reading the &amp;quot;Optimizing&amp;quot; section if you&#039;re doing much scripting.&lt;br /&gt;
&lt;br /&gt;
== What You Need ==&lt;br /&gt;
You will need a basic understanding of how to open and edit computer files, a copy of Freespace 2, and an open mind. Any kind of prior scripting experience will be immensely helpful, but you shouldn&#039;t need any to understand this document.&lt;br /&gt;
&lt;br /&gt;
Here we go!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Although all the examples should not cause syntax errors anywhere, they may not work in certain places. For example, you have to load a mission before you can get handles to ships in the mission.&lt;br /&gt;
&lt;br /&gt;
== Scripting hooks ==&lt;br /&gt;
A scripting hook is a segment of Lua code, that is run at a specific place in FS2_Open. Some scripting hooks, such as $GameInit, are executed only once. Others, such as state hooks, are executed every frame. Others may be executed only when a specific action occurs (such as a keypress or a ship warping out).&lt;br /&gt;
&lt;br /&gt;
There are three different types of hooks. All hooks are parsed and loaded into memory when they are read, so there is no speed difference. Also, the optional field &amp;quot;+Override: YES&amp;quot; can be used to make a scripting hook completely override fs2_open&#039;s usual behavior. (For example, for the HUD, this would completely disable the default fs2_open HUD and use the scripting version instead)&lt;br /&gt;
&lt;br /&gt;
For the sake of organization, information on different scripting hooks can be found in the wiki page for the table that they are actually in.&lt;br /&gt;
&lt;br /&gt;
=== Return hook ===&lt;br /&gt;
 $Hook: 2 + Mission.getNumShips()&lt;br /&gt;
This works like a normal table variable, except that you can use scripting functions as well.&lt;br /&gt;
&lt;br /&gt;
=== Normal hook ===&lt;br /&gt;
 $Hook: [&lt;br /&gt;
 	gr.setColor(255, 255, 255)&lt;br /&gt;
 	gr.drawString(&amp;quot;Hello, world!&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 	return 2 + Mission.getNumShips()&lt;br /&gt;
 ]&lt;br /&gt;
A normal hook is denoted by [ and ]. Whatever is within the brackets is passed to the Lua interpreter. This means that you cannot use table-style ;; comments within brackets; you must use Lua&#039;s comments.&lt;br /&gt;
&lt;br /&gt;
However, you can still use it with a .tbl field that takes a value, using the &amp;quot;return&amp;quot; command. In this case, even though the other lines are still run, the $Hook: variable would be set to the same value as in the &#039;Return hook&#039; example.&lt;br /&gt;
&lt;br /&gt;
=== File hook ===&lt;br /&gt;
&amp;lt;pre&amp;gt;$Hook: [[script.lua]]&amp;lt;/pre&amp;gt;&lt;br /&gt;
A file hook loads the scripting from the file in the data/scripts directory. In all other respects, it is the same as a normal hook.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
A &amp;quot;comment&amp;quot; (in any programming or scripting language) is a block of a script that is ignored. In Lua there is only one kind of comment, which starts with double-dashes. Any time you put two dashes in a Lua script outside of a string, the rest of the line will be ignored. (This is the same as putting a double-semicolon in a Freespace table)&lt;br /&gt;
&lt;br /&gt;
For example, this:&lt;br /&gt;
 --Load a mission for use in the mainhall&lt;br /&gt;
 Mission.loadMission(&amp;quot;sm2-10.fs2&amp;quot;) --Use &#039;King&#039;s Gambit&#039; for now.&lt;br /&gt;
&lt;br /&gt;
Will do exactly the same thing as this:&lt;br /&gt;
 Mission.loadMission(&amp;quot;sm2-10.fs2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
A variable is the simplest kind of thing that there is in Lua. All it really does is hold data; no more, no less. They really aren&#039;t that scary. Here are some different types of variables&lt;br /&gt;
&lt;br /&gt;
 --Number variable&lt;br /&gt;
 life = 42&lt;br /&gt;
 &lt;br /&gt;
 --String variable&lt;br /&gt;
 name = &amp;quot;Bob&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 --Boolean variables&lt;br /&gt;
 smoking = true&lt;br /&gt;
 healthy = false&lt;br /&gt;
 &lt;br /&gt;
 --Userdata (Handle or object) variable&lt;br /&gt;
 player = mn.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 --Nil variable&lt;br /&gt;
 --Erases a previously set variable&lt;br /&gt;
 life = nil&lt;br /&gt;
 &lt;br /&gt;
 --Member variable of userdata. Can be any of the above types.&lt;br /&gt;
 player.Name = &amp;quot;Ship&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Although technically objects and handles are all userdata, it&#039;s easier to just think of every object and handle as being different types of variables.&lt;br /&gt;
&lt;br /&gt;
=== Arrays ===&lt;br /&gt;
&lt;br /&gt;
An array is a special type of variable, that holds multiple variables. The &#039;&#039;&#039;&#039;&#039;index&#039;&#039;&#039;&#039;&#039; of all Lua arrays starts at 1.&lt;br /&gt;
&lt;br /&gt;
 --Set the fifth element of array to 1&lt;br /&gt;
 a[5] = 12&lt;br /&gt;
 --Set n to the fifth element (tehe)&lt;br /&gt;
 n = a[5]&lt;br /&gt;
 --n will be 12&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
In order to gain access to the FS2_Open engine through scripting, you must use the FS2_Open libraries. Each library represents a different section of the engine. In addition, libraries may be referenced one of two ways: the full name, or a shorthand version of the name made up of two letters. Here, the same setColor &#039;&#039;&#039;&#039;&#039;function&#039;&#039;&#039;&#039;&#039; is used twice.&lt;br /&gt;
&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 gr.setColor(255, 255, 255)&lt;br /&gt;
&lt;br /&gt;
For the sake of easy reading, I&#039;ve used the longhand version of names in the wiki. However, I recommend you learn the shorthand versions as they&#039;re generally faster to work with when scripting.&lt;br /&gt;
&lt;br /&gt;
To get a full list of library functions, use the &amp;quot;-output_scripting&amp;quot; command line parameter. This should create a file called scripting.html, with a list of the different libraries, functions, and types supported by that build. (Use a web browser to open it)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
A function is an instruction to Lua to do something. It may change variables, or it may call (activate) other functions. Functions are the meat of scripting; they get everything done. Essentially, they are much like an individual SEXP.&lt;br /&gt;
&lt;br /&gt;
As a result, this section is pretty tough, but covers almost all of the specific knowledge you&#039;ll need to work within Lua.&lt;br /&gt;
&lt;br /&gt;
=== Function vocabulary ===&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Return value&#039;&#039;&#039;&#039;&#039; - Data that a function returns. Any data that a function returns may be stored in a variable.&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Arguments&#039;&#039;&#039;&#039;&#039; - Data that is given to a function. May be data itself, a variable containing the data, or even the return value of another function.&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Call&#039;&#039;&#039;&#039;&#039; - To run a function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Typical function use ===&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt; This will write &amp;quot;Alpha 1&amp;quot; in the upper-left corner of the screen.&lt;br /&gt;
 player = Mission.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 Graphics.drawString(player.Name, 5, 5)&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 1:&amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;In the first line, the &amp;quot;getShipByName&amp;quot; function of the mission library is run. Because &amp;quot;Alpha 1&amp;quot; is specified as the argument, the return value of the getShipByName function will be the ship handle of the ship named &amp;quot;Alpha 1&amp;quot; in the mission (or nil if Alpha 1 is dead or there was no Alpha 1 to begin with). Because the player variable is set to the function, it will take on the return value of the function. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;After the first line, the player variable is a ship handle to the ship named &amp;quot;Alpha 1&amp;quot; in the current mission.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 2&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;In the second line, the &amp;quot;setColor&amp;quot; function is used to set the current drawing color to pure white. Unlike getShipByName, it takes at least three arguments, all numbers - the red, green, and blue scale of the current color, from 0 to 255. It&#039;s always a good idea to use the setColor function before doing any drawing in scripting, as the engine can and will change the current color between scripting hooks.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;Current drawing color is set to pure white&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 3&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;In the third line, the drawString function takes three arguments - a string, followed by two numbers. The string specifies the text to write, the numbers specify the x and y position of the upper-left corner of the written text. As you can see, we&#039;ve directly used a &#039;&#039;&#039;&#039;&#039;member variable&#039;&#039;&#039;&#039;&#039; of the player variable to fill the first argument. Because we got the ship handle by its name, the Name variable will be the same as the name that we got it by (&amp;quot;Alpha 1&amp;quot;).&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;After the third line, &amp;quot;Alpha 1&amp;quot; will appear in the upper-left corner of the string in white text.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Numbers and certain types of userdata will automatically convert to strings. In all other cases, functions will give an error if you try to use the wrong type of argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Debugging note:&amp;lt;/b&amp;gt; If Alpha 1 were dead in the above example, you would get an error about &#039;trying to index a nil value&#039; because it would not be able to run the getName() function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Userdata functions ===&lt;br /&gt;
Handles and objects may also have functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt; This will write the number of subsystem&#039;s on Alpha 1&#039;s ship in the upper-left corner.&lt;br /&gt;
 player = Mission.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 Graphics.drawString(player:getNumSubsystems(), 5, 5)&lt;br /&gt;
&lt;br /&gt;
As before, we get the handle to the Alpha 1 ship with getShipByName.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Optional arguments ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you don&#039;t have to use an argument. For example, the setColor function has an optional fourth argument - how opaque the color should be. If the argument isn&#039;t used, the color is totally opaque. These two lines do the same thing:&lt;br /&gt;
&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 Graphics.setColor(255, 255, 255, 255)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Quick, a full example! ==&lt;br /&gt;
By this point, you may be bored of all this exposition. So here&#039;s your typical &amp;quot;Hello, World!&amp;quot; example.&lt;br /&gt;
&lt;br /&gt;
For this amazing trick, we&#039;ll make our very own splash screen. Turn off all Freespace 2 mods, and create a file called &amp;quot;scripting.tbl&amp;quot; in your data/tables directory. Open that up in a text editor, and write:&lt;br /&gt;
 #Global Hooks&lt;br /&gt;
 $Splash:	[&lt;br /&gt;
 	--Set the color to white&lt;br /&gt;
 	Graphics.setColor(255, 255, 255)&lt;br /&gt;
 	--Write &amp;quot;Hello, world!&amp;quot;&lt;br /&gt;
 	Graphics.drawString(&amp;quot;Hello, world!&amp;quot;, 5, 10)&lt;br /&gt;
 ]&lt;br /&gt;
 +Override: YES&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
Now, when you start up FS2_Open, you should see &amp;quot;Hello, world!&amp;quot; in the upper-left, as it loads.&lt;br /&gt;
&lt;br /&gt;
== Control structures ==&lt;br /&gt;
A control structure is a series of statements that let you change how a script runs, based on some condition - say, a ship is dead, or the life of a certain ship has fallen below a certain amount.&lt;br /&gt;
&lt;br /&gt;
=== If statements ===&lt;br /&gt;
If statements are a way to check if something is some way or not. All if statements have the form:&lt;br /&gt;
 if (something) then&lt;br /&gt;
 	(execute)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
(something) can be true, or false. If it&#039;s true, then (execute) will be run. If it&#039;s false, then the script will skip down to &amp;quot;end&amp;quot; and go on from there.&lt;br /&gt;
&lt;br /&gt;
To check that a handle is valid:&lt;br /&gt;
 ship = Mission.getShipByName(&amp;quot;Alpha 2&amp;quot;)&lt;br /&gt;
 if ship then&lt;br /&gt;
 	--This will always happen while Alpha 2 is alive&lt;br /&gt;
 	Graphics.drawString(&amp;quot;MACKIE LIVES!&amp;quot;, 5, 10)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To check a variable value&lt;br /&gt;
 x = 42&lt;br /&gt;
 y = 23&lt;br /&gt;
 if x &amp;lt; y or x is y then&lt;br /&gt;
 	--We never get here, because x is bigger than y&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== For statements ===&lt;br /&gt;
A for statement is generally used to iterate through a list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
This bit of scripting will run through all of Alpha 2&#039;s subsystems if she isn&#039;t dead, and display a list of them in the upper-left.&lt;br /&gt;
&lt;br /&gt;
 ship = Mission.getShipByName(&amp;quot;Alpha 2&amp;quot;)&lt;br /&gt;
 if ship then&lt;br /&gt;
 	num_subsys = ship:getNumSubsystems()&lt;br /&gt;
 	x = 5&lt;br /&gt;
 	y = 5&lt;br /&gt;
 	for i=1,num_subsys do&lt;br /&gt;
 		--Use the i variable to go through the ship&#039;s subsystems,&lt;br /&gt;
 		--and to change the y position of the text.&lt;br /&gt;
 		gr.drawString(ship[i]:getName(), x, y + i*10)&lt;br /&gt;
 	end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== More information ===&lt;br /&gt;
For other keywords you can use with control structures, see the [http://www.lua.org/manual/5.0/manual.html#2.5.2 Lua Documentation]&lt;br /&gt;
&lt;br /&gt;
For more detailed information on if statements and other types of control structures, see the [http://lua-users.org/wiki/ControlStructureTutorial Lua-users wiki]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s more depth to scripting than what&#039;s covered above. To make the rest of the article shorter, I&#039;ve put the topics still within the scope of this article, but not necessary to know in most cases, down here.&lt;br /&gt;
&lt;br /&gt;
However, I HIGHLY recommend you read the optimizing scripting section.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Optimizing scripting ===&lt;br /&gt;
&lt;br /&gt;
Because fs2_open is written in C, which is much faster than Lua, it is much better to store variables in C and provide Lua functions to work with them. In addition, to keep Lua scripting from messing with C scripting and to make it as friendly as possible, there are a number of safeguards to catch problems, in most of the Lua functions.&lt;br /&gt;
&lt;br /&gt;
As a result, whenever you&#039;re working with a value provided by a library or object function, you should set it to a Lua variable if you&#039;re going to use it more than 1-2 times due to the large overhead resulting from the interface.&lt;br /&gt;
&lt;br /&gt;
Thus, even though it may [i]look[/i] like &amp;quot;Name&amp;quot; is a member variable of the ship handle, it is actually a function that performs 3-4 validity checks before returning the value, which must also be converted from C to Lua. Setting a variable to the return value of the function means that you can use that variable wherever you want to use the ship name using the native Lua environment.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Debugging scripting ===&lt;br /&gt;
&lt;br /&gt;
Unfortunately, the Lua interpreter provides only limited debugging information about hooks. (Supposedly, it will provide more information about scripting within user functions, but I haven&#039;t tested that claim yet)&lt;br /&gt;
&lt;br /&gt;
Generally, error messages complaining about referencing or indexing a &#039;nil value&#039; occur because a function could not return a handle, so it returned nil. Some functions also return false to indicate that the handle is correct, but due to some kind of wrong information being passed, it couldn&#039;t complete.&lt;br /&gt;
&lt;br /&gt;
Generally, you should check all handles before using them:&lt;br /&gt;
 player = getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 if player then&lt;br /&gt;
 &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
With all uses of the player handle falling in the &amp;quot;if&amp;quot; statement.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Function types ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s all the different kinds of functions you can have:&lt;br /&gt;
 --A function provided by itself&lt;br /&gt;
 x = cos(y)&lt;br /&gt;
 --A function provided by a library&lt;br /&gt;
 x = Math.cos(y)&lt;br /&gt;
 --A function provided by a userdata variable.&lt;br /&gt;
 x = y:cos()&lt;br /&gt;
In every case, x would be set to the cosine of y, which is 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; You must use a &amp;quot;:&amp;quot; with userdata functions, as in the example. This tells Lua that it needs to give the function the value of the variable that it&#039;s being called from.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Making your own functions ===&lt;br /&gt;
So, let&#039;s make the doSomething() function do, well, something.&lt;br /&gt;
 doSomething = function()&lt;br /&gt;
 	color = &amp;quot;red&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
As you can see, creating a function is much like creating a variable; you just use function() instead of the value, then write what you want the function to do. To end the function, you just write &amp;quot;end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s use our new doSomething() function.&lt;br /&gt;
 color = &amp;quot;black&amp;quot;&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --After using doSomething(), color is now red&lt;br /&gt;
&lt;br /&gt;
Functions can also &#039;&#039;&#039;&#039;&#039;return&#039;&#039;&#039;&#039;&#039; values.&lt;br /&gt;
 --Make a new function&lt;br /&gt;
 doSomethingElse = function()&lt;br /&gt;
 	return 10&lt;br /&gt;
 end&lt;br /&gt;
 x = 0&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --x is now 27&lt;br /&gt;
 x = doSomethingElse()&lt;br /&gt;
 --x is now 10&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Variable Scope ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;scope&#039;&#039;&#039;&#039;&#039; of a variable is the area where it exists. Writing &amp;lt;tt&amp;gt;local&amp;lt;/tt&amp;gt; in front of the variable name will tell Lua that the variable should only exist within that function or hook.&lt;br /&gt;
&lt;br /&gt;
Note that this means that if you use the same variable name in two different hooks without using local, the same variable will be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may find it useful to have some way of distinguishing global variables from local ones, to remind yourself that the value does carry over. For example, starting global variable names with &amp;quot;g_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt; The following will draw the text &amp;quot;Media VP&amp;quot; in the upper-left corner of the main hall, even though the variable is set in a different hook than it is used in.&lt;br /&gt;
&lt;br /&gt;
 #Global Hooks&lt;br /&gt;
 $GameInit: [g_mod = &amp;quot;Media VP&amp;quot;]&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
 #State Hooks&lt;br /&gt;
 $State: GS_STATE_MAIN_MENU&lt;br /&gt;
 $Hook: [Graphics.drawString(g_mod, 0, 0)]&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Variable Types ===&lt;br /&gt;
Variables can hold different types of data. These basic types are:&lt;br /&gt;
&lt;br /&gt;
==== Boolean ====&lt;br /&gt;
A boolean is a simple variable - it can be true, or false.&lt;br /&gt;
 --It&#039;s Monday, and Dilbert is at the office&lt;br /&gt;
 working = true&lt;br /&gt;
 --Oops, he just opened Solitaire&lt;br /&gt;
 working = false&lt;br /&gt;
&lt;br /&gt;
==== Numbers ====&lt;br /&gt;
A number is any variable that holds (As you might&#039;ve guessed) a number. A number will automatically convert into a string, if needed.&lt;br /&gt;
 --A variable can be a whole number, like this&lt;br /&gt;
 x = 5&lt;br /&gt;
 --Or it can be a decimal value&lt;br /&gt;
 x = 3.141592654&lt;br /&gt;
 --Or you can divide two numbers for a fraction&lt;br /&gt;
 x = 3/4&lt;br /&gt;
&lt;br /&gt;
==== Strings ====&lt;br /&gt;
A string is a variable that holds a series of characters, and a character is any number, letter, or symbol on your keyboard (and then some). Basically, strings are the way that words and sentences are passed around in Lua.&lt;br /&gt;
 --A cow says moo!&lt;br /&gt;
 cow = &amp;quot;moo&amp;quot;&lt;br /&gt;
 --A friend&#039;s name&lt;br /&gt;
 friend = &amp;quot;Bob&amp;quot;&lt;br /&gt;
Note that actual string content is contained within double quotation marks, to mark it as a string.&lt;br /&gt;
&lt;br /&gt;
==== nil ====&lt;br /&gt;
nil isn&#039;t really a variable type, but it is important. nil means that a variable doesn&#039;t hold anything. If you want to get rid of a variable, you just set it to be nil.&lt;br /&gt;
&lt;br /&gt;
 --Today I got a new dog&lt;br /&gt;
 dog = &amp;quot;Spot&amp;quot;&lt;br /&gt;
 --But then he ran away&lt;br /&gt;
 dog = nil&lt;br /&gt;
&lt;br /&gt;
Any time an error says that a variable is nil, it usually means that it doesn&#039;t exist (Double-check your spelling).&lt;br /&gt;
&lt;br /&gt;
==== Userdata/objects ====&lt;br /&gt;
Objects (or &amp;quot;userdata&amp;quot;, as they are known in Lua) is a variable that can contain other variables, or functions. Variables or functions within an object are known as &amp;quot;member variables&amp;quot; or &amp;quot;member functions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 --Assuming we have a my_car object, this will copy it to your_car&lt;br /&gt;
 your_car = my_car&lt;br /&gt;
 --Congratulations! But maybe you want to customize it?&lt;br /&gt;
 --Note how I refer to the member variable, color&lt;br /&gt;
 your_car.color = &amp;quot;Red&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Handles ====&lt;br /&gt;
A handle isn&#039;t technically a Lua type, but handles are used a lot in FS2_Open Lua scripting. Essentially, a handle is a variable that refers to a specific object; but doesn&#039;t actually contain that object&#039;s data. An example is the &amp;quot;shipclass&amp;quot; type; it doesn&#039;t actually contain the data in ships.tbl, it just serves to reference the ship class so that you can get and set data.&lt;br /&gt;
 --Get the &amp;quot;GTF Ulysses&amp;quot; ship type&lt;br /&gt;
 --For this, I use the function &#039;getShipclassByName&#039;&lt;br /&gt;
 ulysses = tb.getShipclassByName(&amp;quot;GTF Ulysses&amp;quot;)&lt;br /&gt;
 --Now get rid of the handle&lt;br /&gt;
 ulysses = nil&lt;br /&gt;
 --Even though we&#039;ve gotten rid of the handle, the Ulysses will still exist.&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=1925</id>
		<title>FS2 Open Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=1925"/>
		<updated>2006-02-03T21:43:57Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: Minor corrections to formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is intended as a crash-course in Lua scripting as it relates to Freespace 2. It&#039;s only meant to get you started with Lua scripting - more advanced concepts such as metatables will not be covered.&lt;br /&gt;
&lt;br /&gt;
You don&#039;t need to read the Appendices, but I recommend at least reading the &amp;quot;Optimizing&amp;quot; section if you&#039;re doing much scripting.&lt;br /&gt;
&lt;br /&gt;
== What You Need ==&lt;br /&gt;
You will need a basic understanding of how to open and edit computer files, a copy of Freespace 2, and an open mind. Any kind of prior scripting experience will be immensely helpful, but you shouldn&#039;t need any to understand this document.&lt;br /&gt;
&lt;br /&gt;
Here we go!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Although all the examples should not cause syntax errors anywhere, they may not work in certain places. For example, you have to load a mission before you can get handles to ships in the mission.&lt;br /&gt;
&lt;br /&gt;
== Scripting hooks ==&lt;br /&gt;
A scripting hook is a segment of Lua code, that is run at a specific place in FS2_Open. Some scripting hooks, such as $GameInit, are executed only once. Others, such as state hooks, are executed every frame. Others may be executed only when a specific action occurs (such as a keypress or a ship warping out).&lt;br /&gt;
&lt;br /&gt;
There are three different types of hooks. All hooks are parsed and loaded into memory when they are read, so there is no speed difference.&lt;br /&gt;
&lt;br /&gt;
For the sake of organization, information on different scripting hooks can be found in the wiki page for the table that they are actually in.&lt;br /&gt;
&lt;br /&gt;
=== Return hook ===&lt;br /&gt;
 $Hook: 2 + Mission.getNumShips()&lt;br /&gt;
This works like a normal table variable, except that you can use scripting functions as well.&lt;br /&gt;
&lt;br /&gt;
=== Normal hook ===&lt;br /&gt;
 $Hook: [&lt;br /&gt;
 	gr.setColor(255, 255, 255)&lt;br /&gt;
 	gr.drawString(&amp;quot;Hello, world!&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 	return 2 + Mission.getNumShips()&lt;br /&gt;
 ]&lt;br /&gt;
A normal hook is denoted by [ and ]. Whatever is within the brackets is passed to the Lua interpreter. This means that you cannot use table-style ;; comments within brackets; you must use Lua&#039;s comments.&lt;br /&gt;
&lt;br /&gt;
However, you can still use it with a .tbl field that takes a value, using the &amp;quot;return&amp;quot; command. In this case, even though the other lines are still run, the $Hook: variable would be set to the same value as in the &#039;Return hook&#039; example.&lt;br /&gt;
&lt;br /&gt;
=== File hook ===&lt;br /&gt;
&amp;lt;pre&amp;gt;$Hook: [[script.lua]]&amp;lt;/pre&amp;gt;&lt;br /&gt;
A file hook loads the scripting from the file in the data/scripts directory. In all other respects, it is the same as a normal hook.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
A &amp;quot;comment&amp;quot; (in any programming or scripting language) is a block of a script that is ignored. In Lua there is only one kind of comment, which starts with double-dashes. Any time you put two dashes in a Lua script outside of a string, the rest of the line will be ignored. (This is the same as putting a double-semicolon in a Freespace table)&lt;br /&gt;
&lt;br /&gt;
For example, this:&lt;br /&gt;
 --Load a mission for use in the mainhall&lt;br /&gt;
 Mission.loadMission(&amp;quot;sm2-10.fs2&amp;quot;) --Use &#039;King&#039;s Gambit&#039; for now.&lt;br /&gt;
&lt;br /&gt;
Will do exactly the same thing as this:&lt;br /&gt;
 Mission.loadMission(&amp;quot;sm2-10.fs2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
A variable is the simplest kind of thing that there is in Lua. All it really does is hold data; no more, no less. They really aren&#039;t that scary. Here are some different types of variables&lt;br /&gt;
&lt;br /&gt;
 --Number variable&lt;br /&gt;
 life = 42&lt;br /&gt;
 &lt;br /&gt;
 --String variable&lt;br /&gt;
 name = &amp;quot;Bob&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 --Boolean variables&lt;br /&gt;
 smoking = true&lt;br /&gt;
 healthy = false&lt;br /&gt;
 &lt;br /&gt;
 --Userdata (Handle or object) variable&lt;br /&gt;
 player = mn.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 --Nil variable&lt;br /&gt;
 --Erases a previously set variable&lt;br /&gt;
 life = nil&lt;br /&gt;
 &lt;br /&gt;
 --Member variable of userdata. Can be any of the above types.&lt;br /&gt;
 player.Name = &amp;quot;Ship&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Although technically objects and handles are all userdata, it&#039;s easier to just think of every object and handle as being different types of variables.&lt;br /&gt;
&lt;br /&gt;
=== Arrays ===&lt;br /&gt;
&lt;br /&gt;
An array is a special type of variable, that holds multiple variables. The &#039;&#039;&#039;&#039;&#039;index&#039;&#039;&#039;&#039;&#039; of all Lua arrays starts at 1.&lt;br /&gt;
&lt;br /&gt;
 --Set the fifth element of array to 1&lt;br /&gt;
 a[5] = 12&lt;br /&gt;
 --Set n to the fifth element (tehe)&lt;br /&gt;
 n = a[5]&lt;br /&gt;
 --n will be 12&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
In order to gain access to the FS2_Open engine through scripting, you must use the FS2_Open libraries. Each library represents a different section of the engine. In addition, libraries may be referenced one of two ways: the full name, or a shorthand version of the name made up of two letters. Here, the same setColor &#039;&#039;&#039;&#039;&#039;function&#039;&#039;&#039;&#039;&#039; is used twice.&lt;br /&gt;
&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 gr.setColor(255, 255, 255)&lt;br /&gt;
&lt;br /&gt;
For the sake of easy reading, I&#039;ve used the longhand version of names in the wiki. However, I recommend you learn the shorthand versions as they&#039;re generally faster to work with when scripting.&lt;br /&gt;
&lt;br /&gt;
To get a full list of library functions, use the &amp;quot;-output_scripting&amp;quot; command line parameter. This should create a file called scripting.html, with a list of the different libraries, functions, and types supported by that build. (Use a web browser to open it)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
A function is an instruction to Lua to do something. It may change variables, or it may call (activate) other functions. Functions are the meat of scripting; they get everything done. Essentially, they are much like an individual SEXP.&lt;br /&gt;
&lt;br /&gt;
As a result, this section is pretty tough, but covers almost all of the specific knowledge you&#039;ll need to work within Lua.&lt;br /&gt;
&lt;br /&gt;
=== Function vocabulary ===&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Return value&#039;&#039;&#039;&#039;&#039; - Data that a function returns. Any data that a function returns may be stored in a variable.&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Arguments&#039;&#039;&#039;&#039;&#039; - Data that is given to a function. May be data itself, a variable containing the data, or even the return value of another function.&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Call&#039;&#039;&#039;&#039;&#039; - To run a function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Typical function use ===&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt; This will write &amp;quot;Alpha 1&amp;quot; in the upper-left corner of the screen.&lt;br /&gt;
 player = Mission.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 Graphics.drawString(player.Name, 5, 5)&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 1:&amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;In the first line, the &amp;quot;getShipByName&amp;quot; function of the mission library is run. Because &amp;quot;Alpha 1&amp;quot; is specified as the argument, the return value of the getShipByName function will be the ship handle of the ship named &amp;quot;Alpha 1&amp;quot; in the mission (or nil if Alpha 1 is dead or there was no Alpha 1 to begin with). Because the player variable is set to the function, it will take on the return value of the function. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;After the first line, the player variable is a ship handle to the ship named &amp;quot;Alpha 1&amp;quot; in the current mission.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 2&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;In the second line, the &amp;quot;setColor&amp;quot; function is used to set the current drawing color to pure white. Unlike getShipByName, it takes at least three arguments, all numbers - the red, green, and blue scale of the current color, from 0 to 255. It&#039;s always a good idea to use the setColor function before doing any drawing in scripting, as the engine can and will change the current color between scripting hooks.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;Current drawing color is set to pure white&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 3&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;In the third line, the drawString function takes three arguments - a string, followed by two numbers. The string specifies the text to write, the numbers specify the x and y position of the upper-left corner of the written text. As you can see, we&#039;ve directly used a &#039;&#039;&#039;&#039;&#039;member variable&#039;&#039;&#039;&#039;&#039; of the player variable to fill the first argument. Because we got the ship handle by its name, the Name variable will be the same as the name that we got it by (&amp;quot;Alpha 1&amp;quot;).&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;After the third line, &amp;quot;Alpha 1&amp;quot; will appear in the upper-left corner of the string in white text.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Numbers and certain types of userdata will automatically convert to strings. In all other cases, functions will give an error if you try to use the wrong type of argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Debugging note:&amp;lt;/b&amp;gt; If Alpha 1 were dead in the above example, you would get an error about &#039;trying to index a nil value&#039; because it would not be able to run the getName() function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Userdata functions ===&lt;br /&gt;
Handles and objects may also have functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt; This will write the number of subsystem&#039;s on Alpha 1&#039;s ship in the upper-left corner.&lt;br /&gt;
 player = Mission.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 Graphics.drawString(player:getNumSubsystems(), 5, 5)&lt;br /&gt;
&lt;br /&gt;
As before, we get the handle to the Alpha 1 ship with getShipByName.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Optional arguments ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you don&#039;t have to use an argument. For example, the setColor function has an optional fourth argument - how opaque the color should be. If the argument isn&#039;t used, the color is totally opaque. These two lines do the same thing:&lt;br /&gt;
&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 Graphics.setColor(255, 255, 255, 255)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Quick, a full example! ==&lt;br /&gt;
By this point, you may be bored of all this exposition. So here&#039;s your typical &amp;quot;Hello, World!&amp;quot; example.&lt;br /&gt;
&lt;br /&gt;
For this amazing trick, we&#039;ll make our very own splash screen. Turn off all Freespace 2 mods, and create a file called &amp;quot;scripting.tbl&amp;quot; in your data/tables directory. Open that up in a text editor, and write:&lt;br /&gt;
 #Global Hooks&lt;br /&gt;
 $Splash:	[&lt;br /&gt;
 	--Set the color to white&lt;br /&gt;
 	Graphics.setColor(255, 255, 255)&lt;br /&gt;
 	--Write &amp;quot;Hello, world!&amp;quot;&lt;br /&gt;
 	Graphics.drawString(&amp;quot;Hello, world!&amp;quot;, 5, 10)&lt;br /&gt;
 ]&lt;br /&gt;
 +Override: YES&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
Now, when you start up FS2_Open, you should see &amp;quot;Hello, world!&amp;quot; in the upper-left, as it loads.&lt;br /&gt;
&lt;br /&gt;
== Control structures ==&lt;br /&gt;
A control structure is a series of statements that let you change how a script runs, based on some condition - say, a ship is dead, or the life of a certain ship has fallen below a certain amount.&lt;br /&gt;
&lt;br /&gt;
=== If statements ===&lt;br /&gt;
If statements are a way to check if something is some way or not. All if statements have the form:&lt;br /&gt;
 if (something) then&lt;br /&gt;
 	(execute)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
(something) can be true, or false. If it&#039;s true, then (execute) will be run. If it&#039;s false, then the script will skip down to &amp;quot;end&amp;quot; and go on from there.&lt;br /&gt;
&lt;br /&gt;
To check that a handle is valid:&lt;br /&gt;
 ship = Mission.getShipByName(&amp;quot;Alpha 2&amp;quot;)&lt;br /&gt;
 if ship then&lt;br /&gt;
 	--This will always happen while Alpha 2 is alive&lt;br /&gt;
 	Graphics.drawString(&amp;quot;MACKIE LIVES!&amp;quot;, 5, 10)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To check a variable value&lt;br /&gt;
 x = 42&lt;br /&gt;
 y = 23&lt;br /&gt;
 if x &amp;lt; y or x is y then&lt;br /&gt;
 	--We never get here, because x is bigger than y&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== For statements ===&lt;br /&gt;
A for statement is generally used to iterate through a list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
This bit of scripting will run through all of Alpha 2&#039;s subsystems if she isn&#039;t dead, and display a list of them in the upper-left.&lt;br /&gt;
&lt;br /&gt;
 ship = Mission.getShipByName(&amp;quot;Alpha 2&amp;quot;)&lt;br /&gt;
 if ship then&lt;br /&gt;
 	num_subsys = ship:getNumSubsystems()&lt;br /&gt;
 	x = 5&lt;br /&gt;
 	y = 5&lt;br /&gt;
 	for i=1,num_subsys do&lt;br /&gt;
 		--Use the i variable to go through the ship&#039;s subsystems,&lt;br /&gt;
 		--and to change the y position of the text.&lt;br /&gt;
 		gr.drawString(ship[i]:getName(), x, y + i*10)&lt;br /&gt;
 	end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== More information ===&lt;br /&gt;
For other keywords you can use with control structures, see the [http://www.lua.org/manual/5.0/manual.html#2.5.2 Lua Documentation]&lt;br /&gt;
&lt;br /&gt;
For more detailed information on if statements and other types of control structures, see the [http://lua-users.org/wiki/ControlStructureTutorial Lua-users wiki]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s more depth to scripting than what&#039;s covered above. To make the rest of the article shorter, I&#039;ve put the topics still within the scope of this article, but not necessary to know in most cases, down here.&lt;br /&gt;
&lt;br /&gt;
However, I HIGHLY recommend you read the optimizing scripting section.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Optimizing scripting ===&lt;br /&gt;
&lt;br /&gt;
Because fs2_open is written in C, which is much faster than Lua, it is much better to store variables in C and provide Lua functions to work with them. In addition, to keep Lua scripting from messing with C scripting and to make it as friendly as possible, there are a number of safeguards to catch problems, in most of the Lua functions.&lt;br /&gt;
&lt;br /&gt;
As a result, whenever you&#039;re working with a value provided by a library or object function, you should set it to a Lua variable if you&#039;re going to use it more than 1-2 times due to the large overhead resulting from the interface.&lt;br /&gt;
&lt;br /&gt;
Thus, even though it may [i]look[/i] like &amp;quot;Name&amp;quot; is a member variable of the ship handle, it is actually a function that performs 3-4 validity checks before returning the value, which must also be converted from C to Lua. Setting a variable to the return value of the function means that you can use that variable wherever you want to use the ship name using the native Lua environment.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Debugging scripting ===&lt;br /&gt;
&lt;br /&gt;
Unfortunately, the Lua interpreter provides only limited debugging information about hooks. (Supposedly, it will provide more information about scripting within user functions, but I haven&#039;t tested that claim yet)&lt;br /&gt;
&lt;br /&gt;
Generally, error messages complaining about referencing or indexing a &#039;nil value&#039; occur because a function could not return a handle, so it returned nil. Some functions also return false to indicate that the handle is correct, but due to some kind of wrong information being passed, it couldn&#039;t complete.&lt;br /&gt;
&lt;br /&gt;
Generally, you should check all handles before using them:&lt;br /&gt;
 player = getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 if player then&lt;br /&gt;
 &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
With all uses of the player handle falling in the &amp;quot;if&amp;quot; statement.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Function types ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s all the different kinds of functions you can have:&lt;br /&gt;
 --A function provided by itself&lt;br /&gt;
 x = cos(y)&lt;br /&gt;
 --A function provided by a library&lt;br /&gt;
 x = Math.cos(y)&lt;br /&gt;
 --A function provided by a userdata variable.&lt;br /&gt;
 x = y:cos()&lt;br /&gt;
In every case, x would be set to the cosine of y, which is 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; You must use a &amp;quot;:&amp;quot; with userdata functions, as in the example. This tells Lua that it needs to give the function the value of the variable that it&#039;s being called from.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Making your own functions ===&lt;br /&gt;
So, let&#039;s make the doSomething() function do, well, something.&lt;br /&gt;
 doSomething = function()&lt;br /&gt;
 	color = &amp;quot;red&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
As you can see, creating a function is much like creating a variable; you just use function() instead of the value, then write what you want the function to do. To end the function, you just write &amp;quot;end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s use our new doSomething() function.&lt;br /&gt;
 color = &amp;quot;black&amp;quot;&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --After using doSomething(), color is now red&lt;br /&gt;
&lt;br /&gt;
Functions can also &#039;&#039;&#039;&#039;&#039;return&#039;&#039;&#039;&#039;&#039; values.&lt;br /&gt;
 --Make a new function&lt;br /&gt;
 doSomethingElse = function()&lt;br /&gt;
 	return 10&lt;br /&gt;
 end&lt;br /&gt;
 x = 0&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --x is now 27&lt;br /&gt;
 x = doSomethingElse()&lt;br /&gt;
 --x is now 10&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Variable Scope ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;scope&#039;&#039;&#039;&#039;&#039; of a variable is the area where it exists. Writing &amp;lt;tt&amp;gt;local&amp;lt;/tt&amp;gt; in front of the variable name will tell Lua that the variable should only exist within that function or hook.&lt;br /&gt;
&lt;br /&gt;
Note that this means that if you use the same variable name in two different hooks without using local, the same variable will be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may find it useful to have some way of distinguishing global variables from local ones, to remind yourself that the value does carry over. For example, starting global variable names with &amp;quot;g_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt; The following will draw the text &amp;quot;Media VP&amp;quot; in the upper-left corner of the main hall, even though the variable is set in a different hook than it is used in.&lt;br /&gt;
&lt;br /&gt;
 #Global Hooks&lt;br /&gt;
 $GameInit: [g_mod = &amp;quot;Media VP&amp;quot;]&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
 #State Hooks&lt;br /&gt;
 $State: GS_STATE_MAIN_MENU&lt;br /&gt;
 $Hook: [Graphics.drawString(g_mod, 0, 0)]&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Variable Types ===&lt;br /&gt;
Variables can hold different types of data. These basic types are:&lt;br /&gt;
&lt;br /&gt;
==== Boolean ====&lt;br /&gt;
A boolean is a simple variable - it can be true, or false.&lt;br /&gt;
 --It&#039;s Monday, and Dilbert is at the office&lt;br /&gt;
 working = true&lt;br /&gt;
 --Oops, he just opened Solitaire&lt;br /&gt;
 working = false&lt;br /&gt;
&lt;br /&gt;
==== Numbers ====&lt;br /&gt;
A number is any variable that holds (As you might&#039;ve guessed) a number. A number will automatically convert into a string, if needed.&lt;br /&gt;
 --A variable can be a whole number, like this&lt;br /&gt;
 x = 5&lt;br /&gt;
 --Or it can be a decimal value&lt;br /&gt;
 x = 3.141592654&lt;br /&gt;
 --Or you can divide two numbers for a fraction&lt;br /&gt;
 x = 3/4&lt;br /&gt;
&lt;br /&gt;
==== Strings ====&lt;br /&gt;
A string is a variable that holds a series of characters, and a character is any number, letter, or symbol on your keyboard (and then some). Basically, strings are the way that words and sentences are passed around in Lua.&lt;br /&gt;
 --A cow says moo!&lt;br /&gt;
 cow = &amp;quot;moo&amp;quot;&lt;br /&gt;
 --A friend&#039;s name&lt;br /&gt;
 friend = &amp;quot;Bob&amp;quot;&lt;br /&gt;
Note that actual string content is contained within double quotation marks, to mark it as a string.&lt;br /&gt;
&lt;br /&gt;
==== nil ====&lt;br /&gt;
nil isn&#039;t really a variable type, but it is important. nil means that a variable doesn&#039;t hold anything. If you want to get rid of a variable, you just set it to be nil.&lt;br /&gt;
&lt;br /&gt;
 --Today I got a new dog&lt;br /&gt;
 dog = &amp;quot;Spot&amp;quot;&lt;br /&gt;
 --But then he ran away&lt;br /&gt;
 dog = nil&lt;br /&gt;
&lt;br /&gt;
Any time an error says that a variable is nil, it usually means that it doesn&#039;t exist (Double-check your spelling).&lt;br /&gt;
&lt;br /&gt;
==== Userdata/objects ====&lt;br /&gt;
Objects (or &amp;quot;userdata&amp;quot;, as they are known in Lua) is a variable that can contain other variables, or functions. Variables or functions within an object are known as &amp;quot;member variables&amp;quot; or &amp;quot;member functions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 --Assuming we have a my_car object, this will copy it to your_car&lt;br /&gt;
 your_car = my_car&lt;br /&gt;
 --Congratulations! But maybe you want to customize it?&lt;br /&gt;
 --Note how I refer to the member variable, color&lt;br /&gt;
 your_car.color = &amp;quot;Red&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Handles ====&lt;br /&gt;
A handle isn&#039;t technically a Lua type, but handles are used a lot in FS2_Open Lua scripting. Essentially, a handle is a variable that refers to a specific object; but doesn&#039;t actually contain that object&#039;s data. An example is the &amp;quot;shipclass&amp;quot; type; it doesn&#039;t actually contain the data in ships.tbl, it just serves to reference the ship class so that you can get and set data.&lt;br /&gt;
 --Get the &amp;quot;GTF Ulysses&amp;quot; ship type&lt;br /&gt;
 --For this, I use the function &#039;getShipclassByName&#039;&lt;br /&gt;
 ulysses = tb.getShipclassByName(&amp;quot;GTF Ulysses&amp;quot;)&lt;br /&gt;
 --Now get rid of the handle&lt;br /&gt;
 ulysses = nil&lt;br /&gt;
 --Even though we&#039;ve gotten rid of the handle, the Ulysses will still exist.&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=1924</id>
		<title>FS2 Open Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=1924"/>
		<updated>2006-02-03T21:41:00Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is intended as a crash-course in Lua scripting as it relates to Freespace 2. It&#039;s only meant to get you started with Lua scripting - more advanced concepts such as metatables will not be covered.&lt;br /&gt;
&lt;br /&gt;
You don&#039;t need to read the Appendices, but I recommend at least reading the &amp;quot;Optimizing&amp;quot; section if you&#039;re doing much scripting.&lt;br /&gt;
&lt;br /&gt;
== What You Need ==&lt;br /&gt;
You will need a basic understanding of how to open and edit computer files, a copy of Freespace 2, and an open mind. Any kind of prior scripting experience will be immensely helpful, but you shouldn&#039;t need any to understand this document.&lt;br /&gt;
&lt;br /&gt;
Here we go!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Although all the examples should not cause syntax errors anywhere, they may not work in certain places. For example, you have to load a mission before you can get handles to ships in the mission.&lt;br /&gt;
&lt;br /&gt;
== Scripting hooks ==&lt;br /&gt;
A scripting hook is a segment of Lua code, that is run at a specific place in FS2_Open. Some scripting hooks, such as $GameInit, are executed only once. Others, such as state hooks, are executed every frame. Others may be executed only when a specific action occurs (such as a keypress or a ship warping out).&lt;br /&gt;
&lt;br /&gt;
There are three different types of hooks. All hooks are parsed and loaded into memory when they are read, so there is no speed difference.&lt;br /&gt;
&lt;br /&gt;
For the sake of organization, information on different scripting hooks can be found in the wiki page for the table that they are actually in.&lt;br /&gt;
&lt;br /&gt;
=== Return hook ===&lt;br /&gt;
 $Hook: 2 + Mission.getNumShips()&lt;br /&gt;
This works like a normal table variable, except that you can use scripting functions as well.&lt;br /&gt;
&lt;br /&gt;
=== Normal hook ===&lt;br /&gt;
 $Hook: [&lt;br /&gt;
 	gr.setColor(255, 255, 255)&lt;br /&gt;
 	gr.drawString(&amp;quot;Hello, world!&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 	return 2 + Mission.getNumShips()&lt;br /&gt;
 ]&lt;br /&gt;
A normal hook is denoted by [ and ]. Whatever is within the brackets is passed to the Lua interpreter. This means that you cannot use table-style ;; comments within brackets; you must use Lua&#039;s comments.&lt;br /&gt;
&lt;br /&gt;
However, you can still use it with a .tbl field that takes a value, using the &amp;quot;return&amp;quot; command. In this case, even though the other lines are still run, the $Hook: variable would be set to the same value as in the &#039;Return hook&#039; example.&lt;br /&gt;
&lt;br /&gt;
=== File hook ===&lt;br /&gt;
&amp;lt;pre&amp;gt;$Hook: [[script.lua]]&amp;lt;/pre&amp;gt;&lt;br /&gt;
A file hook loads the scripting from the file in the data/scripts directory. In all other respects, it is the same as a normal hook.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
A &amp;quot;comment&amp;quot; (in any programming or scripting language) is a block of a script that is ignored. In Lua there is only one kind of comment, which starts with double-dashes. Any time you put two dashes in a Lua script outside of a string, the rest of the line will be ignored. (This is the same as putting a double-semicolon in a Freespace table)&lt;br /&gt;
&lt;br /&gt;
For example, this:&lt;br /&gt;
 --Load a mission for use in the mainhall&lt;br /&gt;
 Mission.loadMission(&amp;quot;sm2-10.fs2&amp;quot;) --Use &#039;King&#039;s Gambit&#039; for now.&lt;br /&gt;
&lt;br /&gt;
Will do exactly the same thing as this:&lt;br /&gt;
 Mission.loadMission(&amp;quot;sm2-10.fs2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
A variable is the simplest kind of thing that there is in Lua. All it really does is hold data; no more, no less. They really aren&#039;t that scary. Here are some different types of variables&lt;br /&gt;
&lt;br /&gt;
 --Number variable&lt;br /&gt;
 life = 42&lt;br /&gt;
 &lt;br /&gt;
 --String variable&lt;br /&gt;
 name = &amp;quot;Bob&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 --Boolean variables&lt;br /&gt;
 smoking = true&lt;br /&gt;
 healthy = false&lt;br /&gt;
 &lt;br /&gt;
 --Userdata (Handle or object) variable&lt;br /&gt;
 player = mn.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 --Nil variable&lt;br /&gt;
 --Erases a previously set variable&lt;br /&gt;
 life = nil&lt;br /&gt;
&lt;br /&gt;
 --Member variable of userdata. Can be any of the above types.&lt;br /&gt;
 player.Name = &amp;quot;Ship&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Although technically objects and handles are all userdata, it&#039;s easier to just think of every object and handle as being different types of variables.&lt;br /&gt;
&lt;br /&gt;
=== Arrays ===&lt;br /&gt;
&lt;br /&gt;
An array is a special type of variable, that holds multiple variables. The &#039;&#039;&#039;&#039;&#039;index&#039;&#039;&#039;&#039;&#039; of all Lua arrays starts at 1.&lt;br /&gt;
&lt;br /&gt;
 --Set the fifth element of array to 1&lt;br /&gt;
 a[5] = 12&lt;br /&gt;
 --Set n to the fifth element (tehe)&lt;br /&gt;
 n = a[5]&lt;br /&gt;
 --n will be 12&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
In order to gain access to the FS2_Open engine through scripting, you must use the FS2_Open libraries. Each library represents a different section of the engine. In addition, libraries may be referenced one of two ways: the full name, or a shorthand version of the name made up of two letters. Here, the same setColor &#039;&#039;&#039;&#039;&#039;function&#039;&#039;&#039;&#039;&#039; is used twice.&lt;br /&gt;
&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 gr.setColor(255, 255, 255)&lt;br /&gt;
&lt;br /&gt;
For the sake of easy reading, I&#039;ve used the longhand version of names in the wiki. However, I recommend you learn the shorthand versions as they&#039;re generally faster to work with when scripting.&lt;br /&gt;
&lt;br /&gt;
To get a full list of library functions, use the &amp;quot;-output_scripting&amp;quot; command line parameter. This should create a file called scripting.html, with a list of the different libraries, functions, and types supported by that build. (Use a web browser to open it)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
A function is an instruction to Lua to do something. It may change variables, or it may call (activate) other functions. Functions are the meat of scripting; they get everything done. Essentially, they are much like an individual SEXP.&lt;br /&gt;
&lt;br /&gt;
As a result, this section is pretty tough, but covers almost all of the specific knowledge you&#039;ll need to work within Lua.&lt;br /&gt;
&lt;br /&gt;
=== Function vocabulary ===&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Return value&#039;&#039;&#039;&#039;&#039; - Data that a function returns. Any data that a function returns may be stored in a variable.&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Arguments&#039;&#039;&#039;&#039;&#039; - Data that is given to a function. May be data itself, a variable containing the data, or even the return value of another function.&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Call&#039;&#039;&#039;&#039;&#039; - To run a function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Typical function use ===&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
This will write &amp;quot;Alpha 1&amp;quot; in the upper-left corner of the screen.&lt;br /&gt;
 player = Mission.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 Graphics.drawString(player.Name, 5, 5)&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 1:&amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;In the first line, the &amp;quot;getShipByName&amp;quot; function of the mission library is run. Because &amp;quot;Alpha 1&amp;quot; is specified as the argument, the return value of the getShipByName function will be the ship handle of the ship named &amp;quot;Alpha 1&amp;quot; in the mission (or nil if Alpha 1 is dead or there was no Alpha 1 to begin with). Because the player variable is set to the function, it will take on the return value of the function. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;After the first line, the player variable is a ship handle to the ship named &amp;quot;Alpha 1&amp;quot; in the current mission.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 2&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;In the second line, the &amp;quot;setColor&amp;quot; function is used to set the current drawing color to pure white. Unlike getShipByName, it takes at least three arguments, all numbers - the red, green, and blue scale of the current color, from 0 to 255. It&#039;s always a good idea to use the setColor function before doing any drawing in scripting, as the engine can and will change the current color between scripting hooks.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;Current drawing color is set to pure white&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;b&amp;gt;Line 3&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;In the third line, the drawString function takes three arguments - a string, followed by two numbers. The string specifies the text to write, the numbers specify the x and y position of the upper-left corner of the written text. As you can see, we&#039;ve directly used a &#039;&#039;&#039;&#039;&#039;member variable&#039;&#039;&#039;&#039;&#039; of the player variable to fill the first argument. Because we got the ship handle by its name, the Name variable will be the same as the name that we got it by (&amp;quot;Alpha 1&amp;quot;).&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Result&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;After the third line, &amp;quot;Alpha 1&amp;quot; will appear in the upper-left corner of the string in white text.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; Numbers and certain types of userdata will automatically convert to strings. In all other cases, functions will give an error if you try to use the wrong type of argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Debugging note:&amp;lt;/b&amp;gt; If Alpha 1 were dead in the above example, you would get an error about &#039;trying to index a nil value&#039; because it would not be able to run the getName() function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Userdata functions ===&lt;br /&gt;
Handles and objects may also have functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
 player = Mission.getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 Graphics.drawString(player:getNumSubsystems(), 5, 5)&lt;br /&gt;
&lt;br /&gt;
As before, we get the handle to the Alpha 1 ship with getShipByName.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Optional arguments ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you don&#039;t have to use an argument. For example, the setColor function has an optional fourth argument - how opaque the color should be. If the argument isn&#039;t used, the color is totally opaque. These two lines do the same thing:&lt;br /&gt;
&lt;br /&gt;
 Graphics.setColor(255, 255, 255)&lt;br /&gt;
 Graphics.setColor(255, 255, 255, 255)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Quick, a full example! ==&lt;br /&gt;
By this point, you may be bored of all this exposition. So here&#039;s your typical &amp;quot;Hello, World!&amp;quot; example.&lt;br /&gt;
&lt;br /&gt;
For this amazing trick, we&#039;ll make our very own splash screen. Turn off all Freespace 2 mods, and create a file called &amp;quot;scripting.tbl&amp;quot; in your data/tables directory. Open that up in a text editor, and write:&lt;br /&gt;
 #Global Hooks&lt;br /&gt;
 $Splash:	[&lt;br /&gt;
 	--Set the color to white&lt;br /&gt;
 	Graphics.setColor(255, 255, 255)&lt;br /&gt;
 	--Write &amp;quot;Hello, world!&amp;quot;&lt;br /&gt;
 	Graphics.drawString(&amp;quot;Hello, world!&amp;quot;, 5, 10)&lt;br /&gt;
 ]&lt;br /&gt;
 +Override: YES&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
Now, when you start up FS2_Open, you should see &amp;quot;Hello, world!&amp;quot; in the upper-left, as it loads.&lt;br /&gt;
&lt;br /&gt;
== Control structures ==&lt;br /&gt;
A control structure is a series of statements that let you change how a script runs, based on some condition - say, a ship is dead, or the life of a certain ship has fallen below a certain amount.&lt;br /&gt;
&lt;br /&gt;
=== If statements ===&lt;br /&gt;
If statements are a way to check if something is some way or not. All if statements have the form:&lt;br /&gt;
 if (something) then&lt;br /&gt;
 	(execute)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
(something) can be true, or false. If it&#039;s true, then (execute) will be run. If it&#039;s false, then the script will skip down to &amp;quot;end&amp;quot; and go on from there.&lt;br /&gt;
&lt;br /&gt;
To check that a handle is valid:&lt;br /&gt;
 ship = Mission.getShipByName(&amp;quot;Alpha 2&amp;quot;)&lt;br /&gt;
 if ship then&lt;br /&gt;
 	--This will always happen while Alpha 2 is alive&lt;br /&gt;
 	Graphics.drawString(&amp;quot;MACKIE LIVES!&amp;quot;, 5, 10)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To check a variable value&lt;br /&gt;
 x = 42&lt;br /&gt;
 y = 23&lt;br /&gt;
 if x &amp;lt; y or x is y then&lt;br /&gt;
 	--We never get here, because x is bigger than y&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== For statements ===&lt;br /&gt;
A for statement is generally used to iterate through a list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example:&amp;lt;/b&amp;gt;&lt;br /&gt;
This bit of scripting will run through all of Alpha 2&#039;s subsystems if she isn&#039;t dead, and display a list of them in the upper-left.&lt;br /&gt;
&lt;br /&gt;
 ship = Mission.getShipByName(&amp;quot;Alpha 2&amp;quot;)&lt;br /&gt;
 if ship then&lt;br /&gt;
 	num_subsys = ship:getNumSubsystems()&lt;br /&gt;
 	x = 5&lt;br /&gt;
 	y = 5&lt;br /&gt;
 	for i=1,num_subsys do&lt;br /&gt;
 		--Use the i variable to go through the ship&#039;s subsystems,&lt;br /&gt;
 		--and to change the y position of the text.&lt;br /&gt;
 		gr.drawString(ship[i]:getName(), x, y + i*10)&lt;br /&gt;
 	end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
=== More information ===&lt;br /&gt;
For other keywords you can use with control structures, see the [http://www.lua.org/manual/5.0/manual.html#2.5.2 Lua Documentation]&lt;br /&gt;
&lt;br /&gt;
For more detailed information on if statements and other types of control structures, see the [http://lua-users.org/wiki/ControlStructureTutorial Lua-users wiki]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
There&#039;s more depth to scripting than what&#039;s covered above. To make the rest of the article shorter, I&#039;ve put the topics still within the scope of this article, but not necessary to know in most cases, down here.&lt;br /&gt;
&lt;br /&gt;
However, I HIGHLY recommend you read the optimizing scripting section.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Optimizing scripting ===&lt;br /&gt;
&lt;br /&gt;
Because fs2_open is written in C, which is much faster than Lua, it is much better to store variables in C and provide Lua functions to work with them. In addition, to keep Lua scripting from messing with C scripting and to make it as friendly as possible, there are a number of safeguards to catch problems, in most of the Lua functions.&lt;br /&gt;
&lt;br /&gt;
As a result, whenever you&#039;re working with a value provided by a library or object function, you should set it to a Lua variable if you&#039;re going to use it more than 1-2 times due to the large overhead resulting from the interface.&lt;br /&gt;
&lt;br /&gt;
Thus, even though it may [i]look[/i] like &amp;quot;Name&amp;quot; is a member variable of the ship handle, it is actually a function that performs 3-4 validity checks before returning the value, which must also be converted from C to Lua. Setting a variable to the return value of the function means that you can use that variable wherever you want to use the ship name using the native Lua environment.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Debugging scripting ===&lt;br /&gt;
&lt;br /&gt;
Unfortunately, the Lua interpreter provides only limited debugging information about hooks. (Supposedly, it will provide more information about scripting within user functions, but I haven&#039;t tested that claim yet)&lt;br /&gt;
&lt;br /&gt;
Generally, error messages complaining about referencing or indexing a &#039;nil value&#039; occur because a function could not return a handle, so it returned nil. Some functions also return false to indicate that the handle is correct, but due to some kind of wrong information being passed, it couldn&#039;t complete.&lt;br /&gt;
&lt;br /&gt;
Generally, you should check all handles before using them:&lt;br /&gt;
 player = getShipByName(&amp;quot;Alpha 1&amp;quot;)&lt;br /&gt;
 if player then&lt;br /&gt;
 &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
With all uses of the player handle falling in the &amp;quot;if&amp;quot; statement.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Function types ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s all the different kinds of functions you can have:&lt;br /&gt;
 --A function provided by itself&lt;br /&gt;
 x = cos(y)&lt;br /&gt;
 --A function provided by a library&lt;br /&gt;
 x = Math.cos(y)&lt;br /&gt;
 --A function provided by a userdata variable.&lt;br /&gt;
 x = y:cos()&lt;br /&gt;
In every case, x would be set to the cosine of y, which is 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt;&lt;br /&gt;
You must use a &amp;quot;:&amp;quot; with userdata functions, as in the example. This tells Lua that it needs to give the function the value of the variable that it&#039;s being called from.&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Making your own functions ===&lt;br /&gt;
So, let&#039;s make the doSomething() function do, well, something.&lt;br /&gt;
 doSomething = function()&lt;br /&gt;
 	color = &amp;quot;red&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
As you can see, creating a function is much like creating a variable; you just use function() instead of the value, then write what you want the function to do. To end the function, you just write &amp;quot;end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s use our new doSomething() function.&lt;br /&gt;
 color = &amp;quot;black&amp;quot;&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --After using doSomething(), color is now red&lt;br /&gt;
&lt;br /&gt;
Functions can also &#039;&#039;&#039;&#039;&#039;return&#039;&#039;&#039;&#039;&#039; values.&lt;br /&gt;
 --Make a new function&lt;br /&gt;
 doSomethingElse = function()&lt;br /&gt;
 	return 10&lt;br /&gt;
 end&lt;br /&gt;
 x = 0&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --x is now 27&lt;br /&gt;
 x = doSomethingElse()&lt;br /&gt;
 --x is now 10&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Variable Scope ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;scope&#039;&#039;&#039;&#039;&#039; of a variable is the area where it exists. Writing &amp;lt;tt&amp;gt;local&amp;lt;/tt&amp;gt; in front of the variable name will tell Lua that the variable should only exist within that function or hook.&lt;br /&gt;
&lt;br /&gt;
Note that this means that if you use the same variable name in two different hooks without using local, the same variable will be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt;&lt;br /&gt;
You may find it useful to have some way of distinguishing global variables from local ones, to remind yourself that the value does carry over. For example, starting global variable names with &amp;quot;g_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example&amp;lt;/b&amp;gt;&lt;br /&gt;
The following will draw the text &amp;quot;Media VP&amp;quot; in the upper-left corner of the main hall, even though the variable is set in a different hook than it is used in.&lt;br /&gt;
&lt;br /&gt;
 #Global Hooks&lt;br /&gt;
 $GameInit: [g_mod = &amp;quot;Media VP&amp;quot;]&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
 #State Hooks&lt;br /&gt;
 $State: GS_STATE_MAIN_MENU&lt;br /&gt;
 $Hook: [Graphics.drawString(g_mod, 0, 0)]&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
=== Appendix: Variable Types ===&lt;br /&gt;
Variables can hold different types of data. These basic types are:&lt;br /&gt;
&lt;br /&gt;
==== Boolean ====&lt;br /&gt;
A boolean is a simple variable - it can be true, or false.&lt;br /&gt;
 --It&#039;s Monday, and Dilbert is at the office&lt;br /&gt;
 working = true&lt;br /&gt;
 --Oops, he just opened Solitaire&lt;br /&gt;
 working = false&lt;br /&gt;
&lt;br /&gt;
==== Numbers ====&lt;br /&gt;
A number is any variable that holds (As you might&#039;ve guessed) a number. A number will automatically convert into a string, if needed.&lt;br /&gt;
 --A variable can be a whole number, like this&lt;br /&gt;
 x = 5&lt;br /&gt;
 --Or it can be a decimal value&lt;br /&gt;
 x = 3.141592654&lt;br /&gt;
 --Or you can divide two numbers for a fraction&lt;br /&gt;
 x = 3/4&lt;br /&gt;
&lt;br /&gt;
==== Strings ====&lt;br /&gt;
A string is a variable that holds a series of characters, and a character is any number, letter, or symbol on your keyboard (and then some). Basically, strings are the way that words and sentences are passed around in Lua.&lt;br /&gt;
 --A cow says moo!&lt;br /&gt;
 cow = &amp;quot;moo&amp;quot;&lt;br /&gt;
 --A friend&#039;s name&lt;br /&gt;
 friend = &amp;quot;Bob&amp;quot;&lt;br /&gt;
Note that actual string content is contained within double quotation marks, to mark it as a string.&lt;br /&gt;
&lt;br /&gt;
==== nil ====&lt;br /&gt;
nil isn&#039;t really a variable type, but it is important. nil means that a variable doesn&#039;t hold anything. If you want to get rid of a variable, you just set it to be nil.&lt;br /&gt;
&lt;br /&gt;
 --Today I got a new dog&lt;br /&gt;
 dog = &amp;quot;Spot&amp;quot;&lt;br /&gt;
 --But then he ran away&lt;br /&gt;
 dog = nil&lt;br /&gt;
&lt;br /&gt;
Any time an error says that a variable is nil, it usually means that it doesn&#039;t exist (Double-check your spelling).&lt;br /&gt;
&lt;br /&gt;
==== Userdata/objects ====&lt;br /&gt;
Objects (or &amp;quot;userdata&amp;quot;, as they are known in Lua) is a variable that can contain other variables, or functions. Variables or functions within an object are known as &amp;quot;member variables&amp;quot; or &amp;quot;member functions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 --Assuming we have a my_car object, this will copy it to your_car&lt;br /&gt;
 your_car = my_car&lt;br /&gt;
 --Congratulations! But maybe you want to customize it?&lt;br /&gt;
 --Note how I refer to the member variable, color&lt;br /&gt;
 your_car.color = &amp;quot;Red&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Handles ====&lt;br /&gt;
A handle isn&#039;t technically a Lua type, but handles are used a lot in FS2_Open Lua scripting. Essentially, a handle is a variable that refers to a specific object; but doesn&#039;t actually contain that object&#039;s data. An example is the &amp;quot;shipclass&amp;quot; type; it doesn&#039;t actually contain the data in ships.tbl, it just serves to reference the ship class so that you can get and set data.&lt;br /&gt;
 --Get the &amp;quot;GTF Ulysses&amp;quot; ship type&lt;br /&gt;
 --For this, I use the function &#039;getShipclassByName&#039;&lt;br /&gt;
 ulysses = tb.getShipclassByName(&amp;quot;GTF Ulysses&amp;quot;)&lt;br /&gt;
 --Now get rid of the handle&lt;br /&gt;
 ulysses = nil&lt;br /&gt;
 --Even though we&#039;ve gotten rid of the handle, the Ulysses will still exist.&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Guide_to_FS_Open_on_Linux&amp;diff=1921</id>
		<title>Guide to FS Open on Linux</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Guide_to_FS_Open_on_Linux&amp;diff=1921"/>
		<updated>2006-01-30T06:21:46Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This HOWTO was written by bottomfan to help Freespace fans get the latest bleeding-edge version of fs2_open from CVS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;WARNING! Compling from CVS will let you play with the most recent features and BUGS! Yes, BUGS, compile errors, strange game behavior and/or angry monkeys attacking you. Murphy&#039;s Law is very much in effect!&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Installing CVS ==&lt;br /&gt;
CVS stands for Concurrent Versions System and is a version control system used to record the changes in documents, such as a source files. Developers use CVS so they can easily share their code changes among other developers.&lt;br /&gt;
You will need this tool to download( &amp;quot;checkout&amp;quot; in CVS termology ) fs2_open from the CVS server.&lt;br /&gt;
&lt;br /&gt;
Use your package tool supplied by your distribution to download and install CVS.&lt;br /&gt;
&lt;br /&gt;
Debian users want to:&lt;br /&gt;
 apt-get install cvs&lt;br /&gt;
Gentoo users want to:&lt;br /&gt;
 emerge cvs&lt;br /&gt;
&lt;br /&gt;
== Installing Dev Libs ==&lt;br /&gt;
You will also need OpenAL, libvorbis, OpenGL(most likely provided with your videocard driver),&lt;br /&gt;
and LUA development packages( You dont need LUA if you dont need LUA scripting enabled, it wont go b0rk the compile if it cant find it). &lt;br /&gt;
And ofcourse the GCC compiler and requierd make tools.&lt;br /&gt;
&lt;br /&gt;
Debian want to:&lt;br /&gt;
 apt-get install libopenal-dev libvorbis-dev build-essential&lt;br /&gt;
Gentoo want to:&lt;br /&gt;
 emerge openal libvorbis&lt;br /&gt;
Before you begin, make sure you are situated in a a directory where you have write permissons.&lt;br /&gt;
Your /home/user/ directory is pretty much a sure bet. I recommend that you create a permanent home/user/dev directory from which you run the CVS command, this way CVS will only update the files changed the next time you download the source.&lt;br /&gt;
&lt;br /&gt;
== Using the source ==&lt;br /&gt;
&lt;br /&gt;
=== Downloading ===&lt;br /&gt;
&lt;br /&gt;
Now get the source. Run from a terminal:&lt;br /&gt;
 cvs -d:pserver:anonymous:anonymous@warpcore.org:/home/fs2source/cvsroot loginand then&lt;br /&gt;
 cvs -z3 -d:pserver:anonymous@warpcore.org:/home/fs2source/cvsroot co fs2_open&lt;br /&gt;
The first cvs command tells the CVS tool to first use a password file for authentication( pserver ), that you&lt;br /&gt;
are user &amp;quot;anonymous&amp;quot; with the password &amp;quot;anonymous&amp;quot; who wants to access warpcore.org&#039;s CVS repository &amp;quot;/home/fs2source/cvsroot&amp;quot; and login.&lt;br /&gt;
The second command tells the CVS server on which we are now connected to that we want to checkout( co ) the fs2_open module.&lt;br /&gt;
&lt;br /&gt;
Because 99,999% of all computer errors can be traced back to human-to-keyboard mishaps&lt;br /&gt;
(linguistically proven by yours truly),&lt;br /&gt;
I&#039;ve written a quick bash script that will get the source for you. &lt;br /&gt;
&lt;br /&gt;
Save this and name it something appropriate like &amp;quot;get-fs2_open&amp;quot;, and make it executable( &amp;lt;tt&amp;gt;chmod +x get-fs2_open&amp;lt;/tt&amp;gt; ).&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # CVS Checkout Script for fs2_open&lt;br /&gt;
 CVS_ATTEMPT=0&lt;br /&gt;
 until [  $CVS_ATTEMPT = 1 ]; do&lt;br /&gt;
 	cvs -d:pserver:anonymous:anonymous@warpcore.org:/home/fs2source/cvsroot  login &amp;amp;&amp;amp; \&lt;br /&gt;
 	cvs -z3 -d:pserver:anonymous:anonymous@warpcore.org:/home/fs2source/cvsroot co fs2_open &amp;amp;&amp;amp; \&lt;br /&gt;
 let CVS_ATTEMPT=1&lt;br /&gt;
 done&lt;br /&gt;
NOTE: This script will run until it successfully downloaded fs2_open, abort it with CTRL+C. &lt;br /&gt;
( Originally designed to hammer SourceForge&#039;s CVS server )&lt;br /&gt;
Run the script from a terminal( &amp;lt;tt&amp;gt;./get-fs2_open&amp;lt;/tt&amp;gt;) and wait for it to download the source files.&lt;br /&gt;
&lt;br /&gt;
=== Building ===&lt;br /&gt;
&lt;br /&gt;
In the directory you ran the CVS command from, a new directory will appear, namely fs2_open.&lt;br /&gt;
From that fs2_open directory run in a terminal:&lt;br /&gt;
 ./autogen.sh&lt;br /&gt;
autogen.sh is a script that will generate the required makefiles. You will see alot of &amp;quot;checking for this&amp;quot; and &amp;quot;checking for that&amp;quot;, this is actually the &amp;quot;configure&amp;quot; script ( which can be run with &amp;lt;tt&amp;gt;./configure&amp;lt;/tt&amp;gt; if you need to change the options) examening and configuring fs2_open for your system.&lt;br /&gt;
&lt;br /&gt;
Now run:&lt;br /&gt;
 make &lt;br /&gt;
Sit back and enjoy gcc work its magic.&lt;br /&gt;
&lt;br /&gt;
=== Using the Binaries ===&lt;br /&gt;
&lt;br /&gt;
When the compile is done and if all went well, a binary executable will reside in the code directory &lt;br /&gt;
fs2_open_r or fs2_open_d if you configured for a debug build.&lt;br /&gt;
Move the binary to where you got your mediaVP&#039;s and your all set to go.&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Source_Code_Project_index&amp;diff=4425</id>
		<title>Source Code Project index</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Source_Code_Project_index&amp;diff=4425"/>
		<updated>2006-01-30T06:11:10Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Getting Started with the Source Code Project===&lt;br /&gt;
&lt;br /&gt;
[[FSSCP Introduction]]&lt;br /&gt;
&amp;lt;br&amp;gt;[[Installing fs2_open]]&lt;br /&gt;
&amp;lt;br&amp;gt;[[FS2 data installation]]&lt;br /&gt;
&amp;lt;br&amp;gt;[[Installing mods for fs2_open]]&lt;br /&gt;
&amp;lt;br&amp;gt;[[Troubleshooting]]&lt;br /&gt;
&amp;lt;br&amp;gt;[[Bug Reporting]]&lt;br /&gt;
&lt;br /&gt;
===Getting Started with Development===&lt;br /&gt;
&amp;lt;br&amp;gt;[[Coding In C]]&lt;br /&gt;
&amp;lt;br&amp;gt;[[Linux CVS Howto]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Source Code Project]]&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=1923</id>
		<title>FS2 Open Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=1923"/>
		<updated>2006-01-16T23:33:34Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: /* Finally, a full example! */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is intended as a crash-course in Lua scripting as it relates to Freespace 2. It&#039;s only meant to get you started with Lua scripting - more advanced concepts such as metatables will not be covered.&lt;br /&gt;
&lt;br /&gt;
== What You Need ==&lt;br /&gt;
You will need a basic understanding of how to open and edit computer files, a copy of Freespace 2, and an open mind. Any kind of prior scripting experience will be immensely helpful, but you shouldn&#039;t need any to understand this document.&lt;br /&gt;
&lt;br /&gt;
Here we go!&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
A &amp;quot;comment&amp;quot; (in any programming or scripting language) is a block of a script that is ignored. In Lua there is only one kind of comment, which starts with double-dashes. Any time you put two dashes in a Lua script outside of a string, the rest of the line will be ignored. (This is the same as putting a double-semicolon in a Freespace table)&lt;br /&gt;
&lt;br /&gt;
For example, this:&lt;br /&gt;
 --This is a comment&lt;br /&gt;
 mn.loadMission(&amp;quot;sm2-10.fs2&amp;quot;) --Load a mission&lt;br /&gt;
 --Greetings!&lt;br /&gt;
&lt;br /&gt;
Will do exactly the same thing as this:&lt;br /&gt;
 mn.loadMission(&amp;quot;sm2-10.fs2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
A variable is the simplest kind of thing that there is in Lua. All it really does is hold data; no more, no less. They really aren&#039;t that scary. Here is a variable, as it may be seen in the wild:&lt;br /&gt;
&lt;br /&gt;
 x = 42&lt;br /&gt;
 --x is 42&lt;br /&gt;
 y = x&lt;br /&gt;
 --y, copycat that it is, is now also equal to 42&lt;br /&gt;
&lt;br /&gt;
=== Types ===&lt;br /&gt;
However, variables can hold different types of data. These basic types are:&lt;br /&gt;
&lt;br /&gt;
==== Boolean ====&lt;br /&gt;
A boolean is a simple variable - it can be true, or false.&lt;br /&gt;
 --It&#039;s Monday, and Dilbert is at the office&lt;br /&gt;
 working = true&lt;br /&gt;
 --Oops, he just opened Solitaire&lt;br /&gt;
 working = false&lt;br /&gt;
&lt;br /&gt;
==== Numbers ====&lt;br /&gt;
A number is any variable that holds (As you might&#039;ve guessed) a number. A number will automatically convert into a string, if needed.&lt;br /&gt;
 --A variable can be a whole number, like this&lt;br /&gt;
 x = 5&lt;br /&gt;
 --Or it can be a decimal value&lt;br /&gt;
 x = 3.141592654&lt;br /&gt;
 --Or you can divide two numbers for a fraction&lt;br /&gt;
 x = 3/4&lt;br /&gt;
&lt;br /&gt;
==== Strings ====&lt;br /&gt;
A string is a variable that holds a series of characters, and a character is any number, letter, or symbol on your keyboard (and then some). Basically, strings are the way that words and sentences are passed around in Lua.&lt;br /&gt;
 --A cow says moo!&lt;br /&gt;
 cow = &amp;quot;moo&amp;quot;&lt;br /&gt;
 --A friend&#039;s name&lt;br /&gt;
 friend = &amp;quot;Bob&amp;quot;&lt;br /&gt;
Note that actual string content is contained within double quotation marks, to mark it as a string.&lt;br /&gt;
&lt;br /&gt;
==== nil ====&lt;br /&gt;
nil isn&#039;t really a variable type, but it is important. nil means that a variable doesn&#039;t hold anything. If you want to get rid of a variable, you just set it to be nil.&lt;br /&gt;
&lt;br /&gt;
 --Today I got a new dog&lt;br /&gt;
 dog = &amp;quot;Spot&amp;quot;&lt;br /&gt;
 --But then he ran away&lt;br /&gt;
 dog = nil&lt;br /&gt;
&lt;br /&gt;
Any time an error says that a variable is nil, it usually means that it doesn&#039;t exist (Double-check your spelling).&lt;br /&gt;
&lt;br /&gt;
==== Userdata/objects ====&lt;br /&gt;
Objects (or &amp;quot;userdata&amp;quot;, as they are known in Lua) is a variable that can contain other variables, or functions. Variables or functions within an object are known as &amp;quot;member variables&amp;quot; or &amp;quot;member functions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 --Assuming we have a my_car object, this will copy it to your_car&lt;br /&gt;
 your_car = my_car&lt;br /&gt;
 --Congratulations! But maybe you want to customize it?&lt;br /&gt;
 --Note how I refer to the member variable, color&lt;br /&gt;
 your_car.color = &amp;quot;Red&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Handles ====&lt;br /&gt;
A handle isn&#039;t technically a Lua type, but handles are used a lot in FS2_Open Lua scripting. Essentially, a handle is a variable that refers to a specific object; but doesn&#039;t actually contain that object&#039;s data. An example is the &amp;quot;shipclass&amp;quot; type; it doesn&#039;t actually contain the data in ships.tbl, it just serves to reference the ship class so that you can get and set data.&lt;br /&gt;
 --Get the &amp;quot;GTF Ulysses&amp;quot; ship type&lt;br /&gt;
 --For this, I use the function &#039;getShipclassByName&#039;&lt;br /&gt;
 ulysses = tb.getShipclassByName(&amp;quot;GTF Ulysses&amp;quot;)&lt;br /&gt;
 --Now get rid of the handle&lt;br /&gt;
 ulysses = nil&lt;br /&gt;
 --Even though we&#039;ve gotten rid of the handle, the Ulysses will still exist.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;scope&#039;&#039;&#039;&#039;&#039; of a variable is the area where it exists. By default, all variables exist everywhere; however, if you define your own function, writing &#039;local&#039; in front of the variable name will tell Lua that the variable should only exist within that function.&lt;br /&gt;
&lt;br /&gt;
Note that this means that if you make a variable called &#039;x&#039; in one hook, and a variable called &#039;x&#039; in another hook, they will actually be the same value.&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
A function is an instruction to Lua to do something. It may change variables, or it may call (activate) other functions.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
 doSomething()&lt;br /&gt;
This single line of code would, presumeably tell Lua to do &#039;something&#039;. What that something is, depends on what the function is supposed to do. Note the two parentheses after the function name; these tell Lua to run the function. (There are reasons to use function names without the parentheses, but that is one of those &#039;advanced topics&#039;)&lt;br /&gt;
&lt;br /&gt;
Here&#039;s all the different kinds of functions you can have:&lt;br /&gt;
 --A function provided by itself&lt;br /&gt;
 x = cos(y)&lt;br /&gt;
 --A function provided by a library&lt;br /&gt;
 x = ma.cos(y)&lt;br /&gt;
 --A function provided by an object&lt;br /&gt;
 x = y:cos()&lt;br /&gt;
In every case, x would be set to the cosine of y, which is 1.&lt;br /&gt;
&lt;br /&gt;
Functions may also have multiple arguments:&lt;br /&gt;
 gr.drawString(&amp;quot;Hello!&amp;quot;, 5, 10)&lt;br /&gt;
This tells Freespace 2 to draw the string &amp;quot;Hello!&amp;quot; on-screen, starting at the point 5 pixels down from the top of the screen, and 10 pixels from the left of the screen.&lt;br /&gt;
&lt;br /&gt;
=== Finally, a full example! ===&lt;br /&gt;
By this point, you may be bored of all this exposition. So let&#039;s actually use variables and functions to do something in Freespace!&lt;br /&gt;
&lt;br /&gt;
For this amazing trick, we&#039;ll make our very own splash screen. Turn off all Freespace 2 mods, and create a file called &amp;quot;scripting.tbl&amp;quot; in your data/tables directory. Open that up in a text editor, and write:&lt;br /&gt;
 #Global Hooks&lt;br /&gt;
 $Splash:	[&lt;br /&gt;
 	--Set the color to white&lt;br /&gt;
 	gr.setColor(255, 255, 255)&lt;br /&gt;
 	--Write &amp;quot;Hello, world!&amp;quot;&lt;br /&gt;
 	gr.drawString(&amp;quot;Hello, world!&amp;quot;, 5, 10)&lt;br /&gt;
 ]&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
Now, when you start up FS2_Open, you should see &amp;quot;Hello, world!&amp;quot; in the upper-left, as it loads.&lt;br /&gt;
&lt;br /&gt;
=== Making your own functions (Optional) ===&lt;br /&gt;
So, let&#039;s make the doSomething() function do, well, something.&lt;br /&gt;
 doSomething = function()&lt;br /&gt;
 	color = &amp;quot;red&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
As you can see, creating a function is much like creating a variable; you just use function() instead of the value, then write what you want the function to do. To end the function, you just write &amp;quot;end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s use our new doSomething() function.&lt;br /&gt;
 color = &amp;quot;black&amp;quot;&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --After using doSomething(), color is now red&lt;br /&gt;
&lt;br /&gt;
Functions can also &#039;&#039;&#039;&#039;&#039;return&#039;&#039;&#039;&#039;&#039; values.&lt;br /&gt;
 --Make a new function&lt;br /&gt;
 doSomethingElse = function()&lt;br /&gt;
 	return 10&lt;br /&gt;
 end&lt;br /&gt;
 x = 0&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --x is now 27&lt;br /&gt;
 x = doSomethingElse()&lt;br /&gt;
 --x is now 10&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
A library provides various functions, which may in turn provide various objects or handles with their own functions. All Freespace 2 libraries are named using two letters. &amp;quot;Graphics&amp;quot; is &amp;quot;gr&amp;quot;, &amp;quot;Mouse&amp;quot; is &amp;quot;ms&amp;quot;, and so on.&lt;br /&gt;
&lt;br /&gt;
You can see how functions in a graphics are referenced in the &amp;quot;Hello, world!&amp;quot; example above.&lt;br /&gt;
&lt;br /&gt;
To get a full list of library functions, use the &amp;quot;-output_scripting&amp;quot; command line parameter. This should create a file called scripting.html, with a list of the different libraries and functions supported by that build.&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=1835</id>
		<title>FS2 Open Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=FS2_Open_Lua_Scripting&amp;diff=1835"/>
		<updated>2006-01-16T23:32:57Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is intended as a crash-course in Lua scripting as it relates to Freespace 2. It&#039;s only meant to get you started with Lua scripting - more advanced concepts such as metatables will not be covered.&lt;br /&gt;
&lt;br /&gt;
== What You Need ==&lt;br /&gt;
You will need a basic understanding of how to open and edit computer files, a copy of Freespace 2, and an open mind. Any kind of prior scripting experience will be immensely helpful, but you shouldn&#039;t need any to understand this document.&lt;br /&gt;
&lt;br /&gt;
Here we go!&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
A &amp;quot;comment&amp;quot; (in any programming or scripting language) is a block of a script that is ignored. In Lua there is only one kind of comment, which starts with double-dashes. Any time you put two dashes in a Lua script outside of a string, the rest of the line will be ignored. (This is the same as putting a double-semicolon in a Freespace table)&lt;br /&gt;
&lt;br /&gt;
For example, this:&lt;br /&gt;
 --This is a comment&lt;br /&gt;
 mn.loadMission(&amp;quot;sm2-10.fs2&amp;quot;) --Load a mission&lt;br /&gt;
 --Greetings!&lt;br /&gt;
&lt;br /&gt;
Will do exactly the same thing as this:&lt;br /&gt;
 mn.loadMission(&amp;quot;sm2-10.fs2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
A variable is the simplest kind of thing that there is in Lua. All it really does is hold data; no more, no less. They really aren&#039;t that scary. Here is a variable, as it may be seen in the wild:&lt;br /&gt;
&lt;br /&gt;
 x = 42&lt;br /&gt;
 --x is 42&lt;br /&gt;
 y = x&lt;br /&gt;
 --y, copycat that it is, is now also equal to 42&lt;br /&gt;
&lt;br /&gt;
=== Types ===&lt;br /&gt;
However, variables can hold different types of data. These basic types are:&lt;br /&gt;
&lt;br /&gt;
==== Boolean ====&lt;br /&gt;
A boolean is a simple variable - it can be true, or false.&lt;br /&gt;
 --It&#039;s Monday, and Dilbert is at the office&lt;br /&gt;
 working = true&lt;br /&gt;
 --Oops, he just opened Solitaire&lt;br /&gt;
 working = false&lt;br /&gt;
&lt;br /&gt;
==== Numbers ====&lt;br /&gt;
A number is any variable that holds (As you might&#039;ve guessed) a number. A number will automatically convert into a string, if needed.&lt;br /&gt;
 --A variable can be a whole number, like this&lt;br /&gt;
 x = 5&lt;br /&gt;
 --Or it can be a decimal value&lt;br /&gt;
 x = 3.141592654&lt;br /&gt;
 --Or you can divide two numbers for a fraction&lt;br /&gt;
 x = 3/4&lt;br /&gt;
&lt;br /&gt;
==== Strings ====&lt;br /&gt;
A string is a variable that holds a series of characters, and a character is any number, letter, or symbol on your keyboard (and then some). Basically, strings are the way that words and sentences are passed around in Lua.&lt;br /&gt;
 --A cow says moo!&lt;br /&gt;
 cow = &amp;quot;moo&amp;quot;&lt;br /&gt;
 --A friend&#039;s name&lt;br /&gt;
 friend = &amp;quot;Bob&amp;quot;&lt;br /&gt;
Note that actual string content is contained within double quotation marks, to mark it as a string.&lt;br /&gt;
&lt;br /&gt;
==== nil ====&lt;br /&gt;
nil isn&#039;t really a variable type, but it is important. nil means that a variable doesn&#039;t hold anything. If you want to get rid of a variable, you just set it to be nil.&lt;br /&gt;
&lt;br /&gt;
 --Today I got a new dog&lt;br /&gt;
 dog = &amp;quot;Spot&amp;quot;&lt;br /&gt;
 --But then he ran away&lt;br /&gt;
 dog = nil&lt;br /&gt;
&lt;br /&gt;
Any time an error says that a variable is nil, it usually means that it doesn&#039;t exist (Double-check your spelling).&lt;br /&gt;
&lt;br /&gt;
==== Userdata/objects ====&lt;br /&gt;
Objects (or &amp;quot;userdata&amp;quot;, as they are known in Lua) is a variable that can contain other variables, or functions. Variables or functions within an object are known as &amp;quot;member variables&amp;quot; or &amp;quot;member functions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 --Assuming we have a my_car object, this will copy it to your_car&lt;br /&gt;
 your_car = my_car&lt;br /&gt;
 --Congratulations! But maybe you want to customize it?&lt;br /&gt;
 --Note how I refer to the member variable, color&lt;br /&gt;
 your_car.color = &amp;quot;Red&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Handles ====&lt;br /&gt;
A handle isn&#039;t technically a Lua type, but handles are used a lot in FS2_Open Lua scripting. Essentially, a handle is a variable that refers to a specific object; but doesn&#039;t actually contain that object&#039;s data. An example is the &amp;quot;shipclass&amp;quot; type; it doesn&#039;t actually contain the data in ships.tbl, it just serves to reference the ship class so that you can get and set data.&lt;br /&gt;
 --Get the &amp;quot;GTF Ulysses&amp;quot; ship type&lt;br /&gt;
 --For this, I use the function &#039;getShipclassByName&#039;&lt;br /&gt;
 ulysses = tb.getShipclassByName(&amp;quot;GTF Ulysses&amp;quot;)&lt;br /&gt;
 --Now get rid of the handle&lt;br /&gt;
 ulysses = nil&lt;br /&gt;
 --Even though we&#039;ve gotten rid of the handle, the Ulysses will still exist.&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;scope&#039;&#039;&#039;&#039;&#039; of a variable is the area where it exists. By default, all variables exist everywhere; however, if you define your own function, writing &#039;local&#039; in front of the variable name will tell Lua that the variable should only exist within that function.&lt;br /&gt;
&lt;br /&gt;
Note that this means that if you make a variable called &#039;x&#039; in one hook, and a variable called &#039;x&#039; in another hook, they will actually be the same value.&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
A function is an instruction to Lua to do something. It may change variables, or it may call (activate) other functions.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
 doSomething()&lt;br /&gt;
This single line of code would, presumeably tell Lua to do &#039;something&#039;. What that something is, depends on what the function is supposed to do. Note the two parentheses after the function name; these tell Lua to run the function. (There are reasons to use function names without the parentheses, but that is one of those &#039;advanced topics&#039;)&lt;br /&gt;
&lt;br /&gt;
Here&#039;s all the different kinds of functions you can have:&lt;br /&gt;
 --A function provided by itself&lt;br /&gt;
 x = cos(y)&lt;br /&gt;
 --A function provided by a library&lt;br /&gt;
 x = ma.cos(y)&lt;br /&gt;
 --A function provided by an object&lt;br /&gt;
 x = y:cos()&lt;br /&gt;
In every case, x would be set to the cosine of y, which is 1.&lt;br /&gt;
&lt;br /&gt;
Functions may also have multiple arguments:&lt;br /&gt;
 gr.drawString(&amp;quot;Hello!&amp;quot;, 5, 10)&lt;br /&gt;
This tells Freespace 2 to draw the string &amp;quot;Hello!&amp;quot; on-screen, starting at the point 5 pixels down from the top of the screen, and 10 pixels from the left of the screen.&lt;br /&gt;
&lt;br /&gt;
=== Finally, a full example! ===&lt;br /&gt;
By this point, you may be bored of all this exposition. So let&#039;s actually use variables and functions to do something in Freespace!&lt;br /&gt;
&lt;br /&gt;
For this amazing trick, we&#039;ll make our very own splash screen. Turn off all Freespace 2 mods, and create a file called &amp;quot;scripting.tbl&amp;quot; in your data/tables directory. Open that up in a text editor, and write:&lt;br /&gt;
 #Global Hooks&lt;br /&gt;
 $Splash:	[&lt;br /&gt;
	--Set the color to white&lt;br /&gt;
 	gr.setColor(255, 255, 255)&lt;br /&gt;
	--Write &amp;quot;Hello, world!&amp;quot;&lt;br /&gt;
 	gr.drawString(&amp;quot;Hello, world!&amp;quot;, 5, 10)&lt;br /&gt;
 ]&lt;br /&gt;
 #End&lt;br /&gt;
&lt;br /&gt;
Now, when you start up FS2_Open, you should see &amp;quot;Hello, world!&amp;quot; in the upper-left, as it loads.&lt;br /&gt;
&lt;br /&gt;
=== Making your own functions (Optional) ===&lt;br /&gt;
So, let&#039;s make the doSomething() function do, well, something.&lt;br /&gt;
 doSomething = function()&lt;br /&gt;
 	color = &amp;quot;red&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
As you can see, creating a function is much like creating a variable; you just use function() instead of the value, then write what you want the function to do. To end the function, you just write &amp;quot;end&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s use our new doSomething() function.&lt;br /&gt;
 color = &amp;quot;black&amp;quot;&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --After using doSomething(), color is now red&lt;br /&gt;
&lt;br /&gt;
Functions can also &#039;&#039;&#039;&#039;&#039;return&#039;&#039;&#039;&#039;&#039; values.&lt;br /&gt;
 --Make a new function&lt;br /&gt;
 doSomethingElse = function()&lt;br /&gt;
 	return 10&lt;br /&gt;
 end&lt;br /&gt;
 x = 0&lt;br /&gt;
 doSomething()&lt;br /&gt;
 --x is now 27&lt;br /&gt;
 x = doSomethingElse()&lt;br /&gt;
 --x is now 10&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
A library provides various functions, which may in turn provide various objects or handles with their own functions. All Freespace 2 libraries are named using two letters. &amp;quot;Graphics&amp;quot; is &amp;quot;gr&amp;quot;, &amp;quot;Mouse&amp;quot; is &amp;quot;ms&amp;quot;, and so on.&lt;br /&gt;
&lt;br /&gt;
You can see how functions in a graphics are referenced in the &amp;quot;Hello, world!&amp;quot; example above.&lt;br /&gt;
&lt;br /&gt;
To get a full list of library functions, use the &amp;quot;-output_scripting&amp;quot; command line parameter. This should create a file called scripting.html, with a list of the different libraries and functions supported by that build.&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Talk:Feature_Requests&amp;diff=1604</id>
		<title>Talk:Feature Requests</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Talk:Feature_Requests&amp;diff=1604"/>
		<updated>2005-12-27T01:09:19Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Excuse me, but should this be not in the SCP forum or the SCP website? Things like these do not beling to wikis. - [[User:TopAce|TopAce]] 19:15, 10 Dec 2005 (GMT)&lt;br /&gt;
&lt;br /&gt;
The problem is that adding it to the SCP site would require a special PHP script, and a thread on the forums quickly becomes cluttered by irrelevant posts and discussions on the features. It also serves as a reference for feature requests...not the ideal solution, but the simplest one. [[User:72.194.192.77|72.194.192.77]] 01:09, 27 Dec 2005 (GMT)&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Scripting_API&amp;diff=2017</id>
		<title>Scripting API</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Scripting_API&amp;diff=2017"/>
		<updated>2005-12-14T20:21:40Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The FS2_Open scripting API is intended to be as cross-platform and as language non-specific as possible. However, it is generally assumed that the most popular language will be Lua.&lt;br /&gt;
&lt;br /&gt;
== Code Description ==&lt;br /&gt;
&lt;br /&gt;
===Part One: Basic API and Scripting Hooks ===&lt;br /&gt;
====Things To Know====&lt;br /&gt;
;script_system:This object abstracts a scripting session. It is generally used to allow for easy construction/destruction of whatever is necessary to initialize scripting system objects, and make sure that the right language session data is passed. Its constructor takes one argument, the name of the scripting session (for easy debugging)&lt;br /&gt;
;script_system-&amp;gt;CreateLuaSession(libraries):Initializes a Lua session. Until this is called, you will not be able to use Lua at all and fs2_open should ignore code chunks that use it.&lt;br /&gt;
;script_system-&amp;gt;ParseChunk(debugname):Parses a &#039;code chunk&#039;. These are snippets of code encapsulated by symbols such as square brackets or parentheses. It stores a handle to the parsed script in memory (Probably bytecode).&lt;br /&gt;
:script_system-&amp;gt;RunBytecode(handle):Actually executes a code chunk that has been parsed with ParseChunk&lt;br /&gt;
====Example====&lt;br /&gt;
This snippet of code (using FS2_Open functions) will parse a file that has scripting after each &amp;quot;$Global:&amp;quot; variable identifier. After all the scripting has been parsed, it will evaluate every hook, once.&lt;br /&gt;
 script_system Script_system;&lt;br /&gt;
 std::vector&amp;lt;script_hook&amp;gt; Script_globalhooks;&lt;br /&gt;
 &lt;br /&gt;
 //Initialize Lua&lt;br /&gt;
 Script_system.CreateLuaState(Lua_libraries);&lt;br /&gt;
 &lt;br /&gt;
 //Parse file&lt;br /&gt;
 read_file_text(&amp;quot;scripting.tbl&amp;quot;);&lt;br /&gt;
 reset_parse();&lt;br /&gt;
 while(optional_string(&amp;quot;$Global:&amp;quot;))&lt;br /&gt;
 {&lt;br /&gt;
 	Script_globalhooks.push_back(st-&amp;gt;ParseChunk());&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 //Execute hooks&lt;br /&gt;
 for(uint i = 0; i &amp;lt; Script_globalhooks.size(); i++)&lt;br /&gt;
 {&lt;br /&gt;
 	Script_system.RunBytecode(Script_globalhooks[i]);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
===Part Two: The Higher-Level Lua Library===&lt;br /&gt;
====Things To Know====&lt;br /&gt;
;script_lua_func_list:A function list array, used to store the name, function pointer, and descriptive text for library functions.&lt;br /&gt;
;script_lua_obj_func_list:Same as a function list, except for object member functions and operators&lt;br /&gt;
;script_lua_obj_list:An object list array, used to store the name, function object list, and descriptive text for objects.&lt;br /&gt;
;script_lua_lib_list:A library function/object list, used to store the library name, function list, object list, and descriptive text. It can then be used to create a Lua session by passing it to CreateLuaSession()&lt;br /&gt;
;SCRIPT_END_LIST:Ends the above lists&lt;br /&gt;
;lua_cvar&amp;lt;&amp;gt;:A template used as an easy way of ensuring that a given object in Lua has the correct name and type everywhere.&lt;br /&gt;
;LUA_OPER_*:A series of defines that can be used in place of an object member function name in the list, to cause the callback function to be used when that operator is present. Not very reliable right now.&lt;br /&gt;
;script_lua_callback:Return value for a Lua callback function (ie a C function that is called from Lua)&lt;br /&gt;
;script_parse_args:Call from within a Lua function callback to convert the passed arguments to C variables. Uses a format string to check for correct arguments and variable type, followed by pointers to the destination variables. The following list shows formatting characters, followed by the Lua value and the C variable type that must be passed for the value to be stored.&lt;br /&gt;
:&#039;b&#039; - boolean (bool*)&lt;br /&gt;
:&#039;d&#039; - number (double*)&lt;br /&gt;
:&#039;f&#039; - number (float*)&lt;br /&gt;
:&#039;i&#039; - number (int*)&lt;br /&gt;
:&#039;o&#039; - object (uses the lua_cvar variable&#039;s Parse() function with *object)&lt;br /&gt;
:&#039;p&#039; - object pointer (uses the lua_cvar variables ParsePtr() function with **object, where object is the actual one allocated by Lua)&lt;br /&gt;
:&#039;s&#039; - string (char**)&lt;br /&gt;
:&#039;|&#039; - specifies that all arguments after this are optional.&lt;br /&gt;
;script_return_args:Call from with a Lua function callback to convert the passed arguments to C variables. Uses the same format as script_parse_args, except that objects use Return() instead of Parse(), and &#039;p&#039; is not supported.&lt;br /&gt;
;LUA_RETURN_NOTHING:A define used for when a function doesn&#039;t use script_return_args&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
A (very small) math library, that provides the function &#039;math.lvec(x,y,z)&#039;. After this example you could then pass Lua_libraries to CreateLuaSession() to access the function.&lt;br /&gt;
 //Define the local-vector object&lt;br /&gt;
 static lua_cvar&amp;lt;vec3d&amp;gt;		l_lvec(&amp;quot;lvec&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 //Define the callback function&lt;br /&gt;
 script_lua_callback lua_fs2_lvec(lua_State *L)&lt;br /&gt;
 {&lt;br /&gt;
 	vec3d v3 = vmd_zero_vector;&lt;br /&gt;
 	script_parse_args(L, &amp;quot;|fff&amp;quot;, &amp;amp;v3.xyz.x, &amp;amp;v3.xyz.y, &amp;amp;v3.xyz.z);&lt;br /&gt;
 &lt;br /&gt;
 	//Note that script_return_args with the &amp;quot;o&amp;quot; parameter creates a new object in Luaspace&lt;br /&gt;
 	//which is managed by Lua&lt;br /&gt;
 	return script_return_args(L, &amp;quot;o&amp;quot;, l_lvec.Return(&amp;amp;v3));&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 //For this example, lvec has no member functions&lt;br /&gt;
 static const script_lua_obj_func_list lua_math_lvec_funcs[] = {&lt;br /&gt;
 	{SCRIPT_END_LIST},&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 //Add the callback to the library&#039;s function list&lt;br /&gt;
 static const script_lua_func_list lua_math_lib[] = {&lt;br /&gt;
 	{&amp;quot;lvec&amp;quot;, lua_fs2_lvec, &amp;quot;Creates a new local vector&amp;quot;,&amp;quot;number,number,number&amp;quot;,&amp;quot;lvec&amp;quot;},&lt;br /&gt;
 	{SCRIPT_END_LIST},&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 //Add the object to the library&#039;s object list&lt;br /&gt;
 static const script_lua_obj_list lua_math_lib_obj[] = {&lt;br /&gt;
 	{l_lvec.GetName(), lua_math_lvec_funcs, &amp;quot;Local vector&amp;quot;},&lt;br /&gt;
 	{SCRIPT_END_LIST},&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 //Add the library function and object lists to Lua_libraries&lt;br /&gt;
 const script_lua_lib_list Lua_libraries[] = {&lt;br /&gt;
 	{&amp;quot;math&amp;quot;, lua_math_lib, lua_math_lib_obj, &amp;quot;Math library&amp;quot;},&lt;br /&gt;
 	{SCRIPT_END_LIST},&lt;br /&gt;
 };&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Scripting_API&amp;diff=1302</id>
		<title>Scripting API</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Scripting_API&amp;diff=1302"/>
		<updated>2005-12-14T19:38:53Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: Initial page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The FS2_Open scripting API is intended to be as cross-platform and as language non-specific as possible. However, it is generally assumed that the most popular language will be Lua.&lt;br /&gt;
&lt;br /&gt;
== Code Description ==&lt;br /&gt;
&lt;br /&gt;
===Part One: Basic API and Scripting Hooks ===&lt;br /&gt;
====Things To Know====&lt;br /&gt;
;script_system:This object abstracts a scripting session. It is generally used to allow for easy construction/destruction of whatever is necessary to initialize scripting system objects, and make sure that the right language session data is passed. Its constructor takes one argument, the name of the scripting session (for easy debugging)&lt;br /&gt;
;script_system-&amp;gt;CreateLuaSession(libraries):Initializes a Lua session. Until this is called, you will not be able to use Lua at all and fs2_open should ignore code chunks that use it.&lt;br /&gt;
;script_system-&amp;gt;ParseChunk(debugname):Parses a &#039;code chunk&#039;. These are snippets of code encapsulated by symbols such as square brackets or parentheses. It stores a handle to the parsed script in memory (Probably bytecode).&lt;br /&gt;
;script_system-&amp;gt;RunBytecode(handle):Actually executes a code chunk that has been parsed with ParseChunk&lt;br /&gt;
====Example====&lt;br /&gt;
This snippet of code (using FS2_Open functions) will parse a file that has scripting after each &amp;quot;$Global:&amp;quot; variable identifier. After all the scripting has been parsed, it will evaluate every hook, once.&lt;br /&gt;
 script_system Script_system;&lt;br /&gt;
 std::vector&amp;lt;script_hook&amp;gt; Script_globalhooks;&lt;br /&gt;
 &lt;br /&gt;
 //Initialize Lua&lt;br /&gt;
 Script_system.CreateLuaState(Lua_libraries);&lt;br /&gt;
 &lt;br /&gt;
 //Parse file&lt;br /&gt;
 read_file_text(&amp;quot;scripting.tbl&amp;quot;);&lt;br /&gt;
 reset_parse();&lt;br /&gt;
 while(optional_string(&amp;quot;$Global:&amp;quot;))&lt;br /&gt;
 {&lt;br /&gt;
 	Script_globalhooks.push_back(st-&amp;gt;ParseChunk());&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 //Execute hooks&lt;br /&gt;
 for(uint i = 0; i &amp;lt; Script_globalhooks.size(); i++)&lt;br /&gt;
 {&lt;br /&gt;
 	Script_system.RunBytecode(Script_globalhooks[i]);&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Development_Reference&amp;diff=1788</id>
		<title>Development Reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Development_Reference&amp;diff=1788"/>
		<updated>2005-12-14T19:17:09Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Scripting API]]&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Main_Page&amp;diff=1463</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Main_Page&amp;diff=1463"/>
		<updated>2005-12-14T19:16:50Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p style=&amp;quot;margin: 0.5em 0 0; text-align: center; &lt;br /&gt;
font-size: 125%; line-height: 1.3&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Welcome to the Freespace Wiki, the ultimate source for Freespace info on the web.&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=0 align=right cellpadding=4 cellspacing=0 width=30% style=&amp;quot;margin: 0 0 1em 1em; background: #404040; border: 1px &lt;br /&gt;
&lt;br /&gt;
#CC0500 solid; border-collapse: collapse; font-size: 95%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Retail Freespace&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Portal:Freespace 1|Freespace 1]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Portal:Freespace 2|Freespace 2]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Freespace Source Code Project&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Getting Started(Main)|Getting Started]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Multiplayer(Main)|Multiplayer]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Command-Line_Reference|Command-Line Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Development_Reference|Development Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Feature Requests|Feature Requests]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Modding Freespace&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Portal:Modding|General Modding]]&lt;br /&gt;
|-&lt;br /&gt;
| [[User-made_Campaigns|User-made Campaigns]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Freespace Universe&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Portal:FS Universe|The Universe]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Other&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Freespace Lingo]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Freespace_Wiki:Community_Portal|Freespace Community]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Getting Freespace]]&lt;br /&gt;
|-&lt;br /&gt;
| [[BitTorrent(Main)|BitTorrent]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #462424; 70%;&amp;quot;|Alternately, explore the &#039;&#039;&#039;FreeSpace&#039;&#039;&#039; universe through &#039;&#039;[[Special:Categories|categories]].&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Freespace Wiki is designed to be a comprehensive source of data for the Freespace series of games, including information about the games themselves, the Freespace universe, and community activities, such as modding and the Source Code Project. It also contains help with some of the more common problems, such as setting up multiplayer and obtaining the freespace games, which can be quite difficult in stores.&lt;br /&gt;
&lt;br /&gt;
Anyone can edit the Freespace Wiki, and we encourage you to do so, but please read our [[canon|Canon Policy]] for information on what sort of data should be submitted, and how to submit it, before you begin.&lt;br /&gt;
&lt;br /&gt;
{| border=0 align=left cellpadding=4 cellspacing=0 width=65% style=&amp;quot;margin: 0 0 1em 1em; background: #404040; border: 1px &lt;br /&gt;
&lt;br /&gt;
#CC0500 solid; border-collapse: collapse; font-size: 95%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Featured Article of the Moment&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|{{Featured Article}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Modular_Tables&amp;diff=1402</id>
		<title>Modular Tables</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Modular_Tables&amp;diff=1402"/>
		<updated>2005-12-10T08:29:11Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Modular tables are SCP addition to the standard FreeSpace table system. XMTs (or eXtentable Modular Tables) offer capability to add new entries or alter already existing tables without any need of editing the &#039;parent&#039; table file.&lt;br /&gt;
&lt;br /&gt;
==Extentable Tables==&lt;br /&gt;
*[[armor.tbl]] can be extended with &#039;&#039;&#039;xxx-amr.tbm file&#039;&#039;&#039; (non-XMT)&lt;br /&gt;
*[[hud_gauges.tbl]] can be extended with &#039;&#039;&#039;xxx-hdg.tbm file&#039;&#039;&#039; (non-XMT)&lt;br /&gt;
*[[music.tbl]] can be extended with &#039;&#039;&#039;xxx-mus.tbm file&#039;&#039;&#039; (non-XMT)&lt;br /&gt;
*[[Ships.tbl]] can be extented with &#039;&#039;&#039;xxx-shp.tbm file&#039;&#039;&#039; (XMT)&lt;br /&gt;
*[[Weapons.tbl]] can be extended with &#039;&#039;&#039;xxx-wep.tbm file&#039;&#039;&#039; (XMT)&lt;br /&gt;
*[[Weapon_expl.tbl]] can be extended with &#039;&#039;&#039;xxx-wxp.tbm file&#039;&#039;&#039; (non-XMT)&lt;br /&gt;
&lt;br /&gt;
==Important Notes==&lt;br /&gt;
*Modular table files should use the &#039;parent table&#039; files sections.&lt;br /&gt;
*Completely new entries and also complete rewrites of entries in parent table file are always possible.&lt;br /&gt;
*For &#039;&#039;&#039;xxx-shp.tbl&#039;&#039;&#039; and &#039;&#039;&#039;xxx-wep.tbl&#039;&#039;&#039;&lt;br /&gt;
**Table entries in modular tables do not have to be complete. Partial entries can be used to alter the data found in parent table files when only some changes to the original are desired to be made.&lt;br /&gt;
**Adding &#039;&#039;&#039;+nocreate&#039;&#039;&#039; right after the entry&#039;s name prevents possible creation of partially undefined entry. For example if the parent table file lacked the entry that was included to the as a partial entry to the modular table file then the creation of partially undefined entry is possible which could cause problems with the game.&lt;br /&gt;
***Example:&lt;br /&gt;
&lt;br /&gt;
   $Name:              @Subach HL-7&lt;br /&gt;
      +nocreate&lt;br /&gt;
&lt;br /&gt;
==Sample - Alpha-wep.tbm==&lt;br /&gt;
*Changes the speed of the &#039;&#039;Subach HL-7&#039;&#039; and also adds a faint grey trail to it.&lt;br /&gt;
&lt;br /&gt;
   #Primary Weapons&lt;br /&gt;
   $Name:              @Subach HL-7&lt;br /&gt;
      +nocreate&lt;br /&gt;
   $Velocity:         650.0	&lt;br /&gt;
   $Trail:&lt;br /&gt;
      +Start Width:      0.4&lt;br /&gt;
      +End Width:        0.0&lt;br /&gt;
      +Start Alpha:      0.35&lt;br /&gt;
      +End Alpha:        0.0&lt;br /&gt;
      +Max Life:         0.2&lt;br /&gt;
      +Bitmap:           Contrail&lt;br /&gt;
   #End&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tables]]&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Feature_Requests&amp;diff=1254</id>
		<title>Feature Requests</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Feature_Requests&amp;diff=1254"/>
		<updated>2005-12-09T08:54:44Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is primarily to serve as a database for feature requests for the Source Code Project.&lt;br /&gt;
&lt;br /&gt;
== Side Multipart Turrets ==&lt;br /&gt;
Support for fully rotating turrets on the sides of ships.&lt;br /&gt;
* &#039;&#039;&#039;Supported By:&#039;&#039;&#039; Battlestar Galactica, The Babylon Project&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Customizable ship types ==&lt;br /&gt;
Add a new table (or an addendum to ships.tbl) that would allow modders to turn on and off individual aspects of ship types, as well as define new ones. Type should be settable in the $Flags: variable, just as it is now, and the :V: defaults should be integrated so that they may be overriden by mods.&lt;br /&gt;
* &#039;&#039;&#039;Supported By:&#039;&#039;&#039; ???&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Feature_Requests&amp;diff=1253</id>
		<title>Feature Requests</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Feature_Requests&amp;diff=1253"/>
		<updated>2005-12-09T08:54:24Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is primarily to serve as a database for feature requests for the Source Code Project.&lt;br /&gt;
&lt;br /&gt;
== Side Multipart Turrets ==&lt;br /&gt;
Support for fully rotating turrets on the sides of ships.&lt;br /&gt;
* &#039;&#039;&#039;Supported By:&#039;&#039;&#039; Battlestar Galactica, The Babylon Project&lt;br /&gt;
&lt;br /&gt;
== Customizable ship types ==&lt;br /&gt;
Add a new table (or an addendum to ships.tbl) that would allow modders to turn on and off individual aspects of ship types, as well as define new ones. Type should be settable in the $Flags: variable, just as it is now, and the :V: defaults should be integrated so that they may be overriden by mods.&lt;br /&gt;
* &#039;&#039;&#039;Supported By:&#039;&#039;&#039; ???&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=Main_Page&amp;diff=1301</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=Main_Page&amp;diff=1301"/>
		<updated>2005-12-09T08:46:44Z</updated>

		<summary type="html">&lt;p&gt;72.194.192.77: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p style=&amp;quot;margin: 0.5em 0 0; text-align: center; &lt;br /&gt;
font-size: 125%; line-height: 1.3&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Welcome to the Freespace Wiki, the ultimate source for Freespace info on the web.&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=0 align=right cellpadding=4 cellspacing=0 width=30% style=&amp;quot;margin: 0 0 1em 1em; background: #404040; border: 1px &lt;br /&gt;
&lt;br /&gt;
#CC0500 solid; border-collapse: collapse; font-size: 95%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Retail Freespace&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Portal:Freespace 1|Freespace 1]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Portal:Freespace 2|Freespace 2]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Freespace Source Code Project&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Getting Started(Main)|Getting Started]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Multiplayer(Main)|Multiplayer]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Command-Line_Reference|Command-Line Reference]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Feature Requests|Feature Requests]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Modding Freespace&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Portal:Modding|General Modding]]&lt;br /&gt;
|-&lt;br /&gt;
| [[User-made_Campaigns|User-made Campaigns]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Freespace Universe&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Portal:FS Universe|The Universe]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Other&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| [[Freespace Lingo]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Freespace_Wiki:Community_Portal|Freespace Community]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Getting Freespace]]&lt;br /&gt;
|-&lt;br /&gt;
| [[BitTorrent(Main)|BitTorrent]]&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #462424; 70%;&amp;quot;|Alternately, explore the &#039;&#039;&#039;FreeSpace&#039;&#039;&#039; universe through &#039;&#039;[[Special:Categories|categories]].&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Freespace Wiki is designed to be a comprehensive source of data for the Freespace series of games, including information about the games themselves, the Freespace universe, and community activities, such as modding and the Source Code Project. It also contains help with some of the more common problems, such as setting up multiplayer and obtaining the freespace games, which can be quite difficult in stores.&lt;br /&gt;
&lt;br /&gt;
Anyone can edit the Freespace Wiki, and we encourage you to do so, but please read our [[canon|Canon Policy]] for information on what sort of data should be submitted, and how to submit it, before you begin.&lt;br /&gt;
&lt;br /&gt;
{| border=0 align=left cellpadding=4 cellspacing=0 width=65% style=&amp;quot;margin: 0 0 1em 1em; background: #404040; border: 1px &lt;br /&gt;
&lt;br /&gt;
#CC0500 solid; border-collapse: collapse; font-size: 95%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;color: white; height: 30px; background: #613030; 70%;&amp;quot;|&#039;&#039;Featured Article of the Moment&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|{{Featured Article}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>72.194.192.77</name></author>
	</entry>
</feed>