<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://springrts-wiki.p2004a.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gajop</id>
	<title>Spring - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://springrts-wiki.p2004a.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gajop"/>
	<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/wiki/Special:Contributions/Gajop"/>
	<updated>2026-11-08T21:58:02Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:Tutorial_Finalizing&amp;diff=13644</id>
		<title>Mapdev:Tutorial Finalizing</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:Tutorial_Finalizing&amp;diff=13644"/>
		<updated>2021-01-10T16:33:07Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Compiling the smf and smt files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Finalizing =&lt;br /&gt;
This page describes how to compile some of the texture files into the smf smt files, test your map, archive the map using 7zip and upload to springfiles.com&lt;br /&gt;
&lt;br /&gt;
= Review = &lt;br /&gt;
Following stage one of the beginners tutorial you will have some intermediary files ready to convert into the SMF and SMT map format:&lt;br /&gt;
* heightmap.png&lt;br /&gt;
* metalmap.png&lt;br /&gt;
* diffuse.png&lt;br /&gt;
* mini.bmp&lt;br /&gt;
* grassmap.png&lt;br /&gt;
&lt;br /&gt;
There is also the [[Mapdev:terraintype|terrain type]] map but thats not covered in these tutorials&lt;br /&gt;
&lt;br /&gt;
= Compiling the smf and smt files =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! springMapConvNG (Windows/Linux)&lt;br /&gt;
| &amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open up the terminal and navigate to your working directory&lt;br /&gt;
&amp;lt;li&amp;gt;Generate the mymapname.smf and mymapname.smt files by runing mapconv with these options:&lt;br /&gt;
&amp;lt;pre&amp;gt;springMapConvNG -t diffuse.png -h heightmap.png -m metalmap.png&lt;br /&gt;
-v grassmap.png -minimap mini.bmp -ct 1 -o mymapname&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Copy the smf and smt files to the ./mymapname.sdd/maps/ directory (Do not rename!)&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! smf_tools (Windows/Linux)&lt;br /&gt;
| &amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open up the terminal and navigate to your working directory&lt;br /&gt;
&amp;lt;li&amp;gt;Generate the mymapname.smt and mymapname.smt.csv (tilemap) with this command:&lt;br /&gt;
&amp;lt;pre&amp;gt;smt_convert -vf --smt -o mymapname.smt --tilesize 32x32 diffuse.png&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Generate the mymapname.smf file with this command:&lt;br /&gt;
&amp;lt;pre&amp;gt;smf_cc -vf --height height.png --metal metal.png --map mymapname.smt.csv --grassmap grassmap.png --minimap minimap.png mymapname.smt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Copy the smf and smt files to the ./mymapname.sdd/maps/ directory (Do not rename!)&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! MapConv (Windows)&lt;br /&gt;
| &amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;In mapconv directory: right click, new file, mymapname.bat&lt;br /&gt;
&amp;lt;li&amp;gt;Edit in text editor, put in these options:&lt;br /&gt;
&amp;lt;pre&amp;gt;MapConv -i -c 0 -x 256 -n 10 -o mymapname.smf -t diffuse.png -a &lt;br /&gt;
heightmap.png -m metalmap.png -v grassmap.png&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Depending on the desired quality add:&lt;br /&gt;
&amp;lt;pre&amp;gt;Fastest compile, lowest quality:&lt;br /&gt;
&lt;br /&gt;
 -z &amp;quot;nvdxt.exe -dxt1a -nmips 4 -quick -file&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Medium speed, good quality: (CUDA version, requires nvidia 8 or higher series gfx card)&lt;br /&gt;
&lt;br /&gt;
 -q&lt;br /&gt;
&lt;br /&gt;
Slow, great quality: (Nothing)&lt;br /&gt;
&lt;br /&gt;
Slower, best possible quality:&lt;br /&gt;
&lt;br /&gt;
-z &amp;quot;nvdxt.exe -dxt1a -nmips 4 -Sinc -quality_highest -file&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Make sure mini.bmp is in the same directory as the mymapname.bat&lt;br /&gt;
&amp;lt;li&amp;gt;Generate the mymapname.smf and mymapname.smt files by executing mymapname.bat file&lt;br /&gt;
&amp;lt;li&amp;gt;Copy the smf and smt files to the ./mymapname.sdd/maps/ directory (Do not rename!)&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Mac &lt;br /&gt;
|{{FIXME}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Testing the map =&lt;br /&gt;
Copying the sdd directory to your spring maps folder will allow spring to recognise it as a map, this way you can tweak parameters and test things before archiving it for distribution.&lt;br /&gt;
&lt;br /&gt;
= Archiving =&lt;br /&gt;
Archiving the map creates a single file with smaller overall size for easy distribution.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create a new 7zip archive containing the contents of the sdd folder.(see below for platform specific instructions)&lt;br /&gt;
&amp;lt;li&amp;gt;Copy the archive to maps folder to test&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{Caution|Make sure that you have not created the archive with the &amp;quot;solid archive&amp;quot; option, or spring will not recognise it.}}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! Linux&lt;br /&gt;
|&lt;br /&gt;
# Open a terminal and navigate to your sdd directory&lt;br /&gt;
# Run the following command:&lt;br /&gt;
: &amp;lt;code&amp;gt;7z a -ms=off mymapname.sd7 *&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!Windows &lt;br /&gt;
|[[File:Examplearchivewith7zip.jpg|512px]]&lt;br /&gt;
|-&lt;br /&gt;
!Mac &lt;br /&gt;
|{{FIXME}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Uploading to springfiles.com =&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Head on over to [http://www.springfiles.com springfiles.com] and create an account&lt;br /&gt;
&amp;lt;li&amp;gt;Select upload from the main horizontal menu&lt;br /&gt;
&amp;lt;li&amp;gt;Fill out as much as you can&lt;br /&gt;
&amp;lt;li&amp;gt;Post to [http://springrts.com/phpbb/viewforum.php?f=13 map creation] subforum with something like &amp;quot;[new map]&amp;quot; in the subject line so as to increase visibiity.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
= Congratulations =&lt;br /&gt;
Your map is set free into the wilds of the internet. We sincerely hope its well loved.&lt;br /&gt;
&lt;br /&gt;
Please browse the [[Mapdev:Main|Map Development]] wiki pages for more ways to make awesome maps. Please help us make this wiki as comprehensive as possible, if you see something missing don&#039;t hesitate to jump in and add it.&lt;br /&gt;
&lt;br /&gt;
Additionally, now you have gotten into maps, perhaps other areas of spring development may interest you. Check out the [[Game_and_Unit_development|Game development]] pages.&lt;br /&gt;
&lt;br /&gt;
For help and discussions please visit the [http://springrts.com/phpbb/viewforum.php?f=13 forums]&lt;br /&gt;
&lt;br /&gt;
Good Luck.&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Spring_on_ARM&amp;diff=17556</id>
		<title>Spring on ARM</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Spring_on_ARM&amp;diff=17556"/>
		<updated>2020-09-20T12:06:39Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Note: currently it doesn&#039;t compile at many places. some of them can maybe fixed by changing compiler flags. Also the emulation is horrible slow, so better get a real arm computer.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Setting up a virtualized environment for arm on ubuntu==&lt;br /&gt;
&lt;br /&gt;
see https://wiki.ubuntu.com/ARM/RootfsFromScratch&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   sudo apt-get install qemu-system rootstock&lt;br /&gt;
   sudo rootstock \&lt;br /&gt;
         --fqdn ubuntu \&lt;br /&gt;
         --login ubuntu \&lt;br /&gt;
         --password ubuntu \&lt;br /&gt;
         --imagesize 3G \&lt;br /&gt;
         --seed openssh-server,linux-image-omap \&lt;br /&gt;
         --notarball&lt;br /&gt;
&lt;br /&gt;
  mv qemu-armel-*.img qemu-armel.img&lt;br /&gt;
  mkdir tmp&lt;br /&gt;
  sudo mount -o loop qemu-armel.img tmp&lt;br /&gt;
  echo &amp;quot;auto eth0&lt;br /&gt;
iface eth0 inet dhcp&amp;quot; &amp;gt;&amp;gt; tmp/etc/network/interfaces&lt;br /&gt;
  sudo umount tmp&lt;br /&gt;
  rmdir tmp&lt;br /&gt;
  wget http://ports.ubuntu.com/ubuntu-ports/dists/lucid/main/installer-armel/current/images/versatile/netboot/vmlinuz&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
start with:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
qemu-system-arm -M versatilepb -cpu cortex-a8 -kernel ./vmlinuz \&lt;br /&gt;
        -hda qemu-armel.img -m 256 -append &amp;quot;root=/dev/sda&amp;quot; \&lt;br /&gt;
        -net nic -net user,hostfwd=tcp::2222-:22&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
login with ubuntu:ubuntu&lt;br /&gt;
&lt;br /&gt;
or with &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh ubuntu@localhost -p 22222&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==install required build tools==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install build-essentials cmake&lt;br /&gt;
sudo apt-get install libglew1.6-dev libsdl1.2-dev libdevil-dev libopenal-dev \&lt;br /&gt;
libogg-dev libvorbis-dev libfreetype6-dev p7zip-full libxcursor-dev \&lt;br /&gt;
libboost-thread1.46-dev libboost-regex1.46-dev libboost-system1.46-dev \&lt;br /&gt;
libboost-program-options1.46-dev libboost-signals1.46-dev&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
since here it should be possible to follow the [[Building_Spring_on_Linux#Ubuntu|linux build instructions]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Engine Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:metal&amp;diff=13933</id>
		<title>Mapdev:metal</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:metal&amp;diff=13933"/>
		<updated>2020-09-16T14:08:41Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Metal =&lt;br /&gt;
Metal maps are used for the built in resourcing scheme (Metal/Energy), they define metal areas on a battlefield based upon the values in the red channel of the metal map.&lt;br /&gt;
&lt;br /&gt;
{{Caution|There are several games for Spring which use their own resourcing system. If you are creating a map for one of those games a metal map may not be necessary, however it is always nice if you can make your maps as compatible with other games as possible, but this is a choice left entirely up to you.}}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-metal.png|256px]] || [[File:Mapdev-metal-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Metal Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
* [[Mapdev:mapinfo.lua|mapinfo.lua]]&lt;br /&gt;
&amp;lt;pre&amp;gt;mapinfo ={&lt;br /&gt;
   ...&lt;br /&gt;
   maxMetal        = 0.02,&lt;br /&gt;
   extractorRadius = 500.0,&lt;br /&gt;
   autoShowMetal   = true,&lt;br /&gt;
   ...&lt;br /&gt;
   smf = {&lt;br /&gt;
        ....&lt;br /&gt;
        metalmapTex = &amp;quot;&amp;quot;,&lt;br /&gt;
        ....&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Image File ==&lt;br /&gt;
* The red value of pixel corresponds to the metal value.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| The metal map is an intermediary file compiled into the SMF file using [[MapConv]] or [[MapConvNG]], it can also be specified in the mapinfo.lua.&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| Any that the Mapconv programs support&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| Greyscale&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| &amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
!Spring Map Size&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
!pixels = Spring Map Size * 32&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 64&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| 128&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| 256&lt;br /&gt;
|-&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| 1024&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: left;font-style:italic&amp;quot; colspan=2 | &amp;amp;#42; must be multiples of 2&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Additional Information =&lt;br /&gt;
== Patch Technique ==&lt;br /&gt;
If you do want perfect metal patches, use a 6x6 pixel pencil in your image editor with a red value of 255. This combined with setting the &amp;quot;MaxMetal&amp;quot; tag in the definitions to 1, will result in a perfect 2.0 metal generation per patch (using Balanaced Annihilation values). The game use isn&#039;t the point however. The fact is that if you can predict how much each spot will output (typically), using the &amp;quot;MaxMetal&amp;quot; parameter, you can easily scale the values up and down. As an example of another extreme, Evolution RTS dictates that all metal patches will output 0.5 metal regardless of the map settings. So whether you need to put a lot of thought into your metal map values depends entirely upon the game for which you are creating the map.&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:water&amp;diff=14056</id>
		<title>Mapdev:water</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:water&amp;diff=14056"/>
		<updated>2020-05-13T16:35:34Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Water =&lt;br /&gt;
The &#039;water&#039; engine feature can be used for more than just water, it can be Lava, Slime, and completely invisible for maps in space.&lt;br /&gt;
&lt;br /&gt;
Water is always at zero elevation, the terrain is positioned above and below the water using the &amp;lt;code&amp;gt;minHeight&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;maxHeight&amp;lt;/code&amp;gt; values(see [[Mapdev:height]]).&lt;br /&gt;
&lt;br /&gt;
Shading of the water is split into two parts; the surface of the water and the surface of the ground under the water&lt;br /&gt;
&lt;br /&gt;
Water has five different rendering modes which can be set ingame by the command:&lt;br /&gt;
&amp;lt;pre&amp;gt;/water&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;ol start=0&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; basic&lt;br /&gt;
&amp;lt;li&amp;gt; reflective&lt;br /&gt;
&amp;lt;li&amp;gt; dynamic&lt;br /&gt;
&amp;lt;li&amp;gt; reflective&amp;amp;refractive&lt;br /&gt;
&amp;lt;li&amp;gt; bumpmapped&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The relevant soure code [https://github.com/spring/spring/tree/bfc21aada48a6a606b039819ba55017fe3d4f29d/rts/Rendering/Env files]&lt;br /&gt;
&lt;br /&gt;
= Specifications =&lt;br /&gt;
Now because of the various graphical modes, and some options being shared, I&#039;ve split this into sections.&lt;br /&gt;
&lt;br /&gt;
==Data Types==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
== Options that are always relevant ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   tidalStrength = 0,&lt;br /&gt;
   voidWater = false,&lt;br /&gt;
   ...&lt;br /&gt;
   water = {&lt;br /&gt;
      damage =  0.0,&lt;br /&gt;
&lt;br /&gt;
      absorb    = {0.0, 0.0, 0.0},&lt;br /&gt;
      baseColor = {0.0, 0.0, 0.0},&lt;br /&gt;
      minColor  = {0.0, 0.0, 0.0},&lt;br /&gt;
&lt;br /&gt;
      forceRendering = false,&lt;br /&gt;
&lt;br /&gt;
      planeColor = {0.0, 0.4, 0.0},&lt;br /&gt;
    },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=tidalStrength|type=float}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=voidWater|default=false|type=bool|description=If true, the water will not be drawn. Also the terrain under the water will not be drawn.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=damage|type=float}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=absorb|type=float3|description=Used to calculate the colour of the terrain under the water, see below.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=baseCcolor|type=float3|description=Used to calculate the colour of the terrain under the water, see below.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=minColor|type=float3|description=Used to calculate the colour of the terrain under the water, see below.}}&lt;br /&gt;
&lt;br /&gt;
The absorb, baseColor and minColor variables are used to alter the colour of the terrain under the water as defined in a glsl shader, see [https://github.com/spring/spring/blob/a71c17d710cc387c484e876971881837ecb0ff10/cont/base/springcontent/shaders/GLSL/SMFFragProg.glsl line 163].&lt;br /&gt;
&lt;br /&gt;
{{tag|name=forceRendering|default=false|type=bool|description=If false, and the minimum height of the terrain is above 1.0, then the water will not be drawn.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=planeColor|default={0.0, 0.4, 0.0}|type=float3|description=sets the colour of the horizon water plane, to prevent it from being drawn at all you must comment out this line.}}&lt;br /&gt;
&lt;br /&gt;
== Basic ==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Water basic example.jpg|400px]]&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   water = {&lt;br /&gt;
      repeatX = 0.0,&lt;br /&gt;
      repeatY = 0.0,&lt;br /&gt;
&lt;br /&gt;
      --texture = &amp;quot;&amp;quot;,&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=repeatX|type=float|default=0|description=control the texture repetition}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=repeatY|type=float|default=0|description=control the texture repetition}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=texture|type=string|default=0|description=the texture image to use, searches the ./maps/ directory of the map archive.}}&lt;br /&gt;
&lt;br /&gt;
== Reflective ==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|+ Example&lt;br /&gt;
| {{FIXME}}need to place an image here&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   water = {&lt;br /&gt;
      surfaceColor  = {0.75, 0.8, 0.85},&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{FIXME}}?&lt;br /&gt;
&lt;br /&gt;
{{tag|name=surfaceColor|type=float3f|default={0.0, 0.0, 0.0}|description=Effects the reflected colour.}}&lt;br /&gt;
&lt;br /&gt;
== Dynamic ==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|+ Example&lt;br /&gt;
| [[file:water_dynamic_example.jpg|400px]]&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   water = {&lt;br /&gt;
      surfaceColor  = {0.75, 0.8, 0.85},&lt;br /&gt;
      --foamTexture =   &amp;quot;&amp;quot;,&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=surfaceColor|type=float3f|default={0.0, 0.0, 0.0}|description=Effects the reflected colour.}}&lt;br /&gt;
&lt;br /&gt;
{{FIXME}}?&lt;br /&gt;
&lt;br /&gt;
== Reflective and Refractive ==&lt;br /&gt;
From what i can tell, this mode is basically the same as the reflective mode, except that it distorts(refracts the light) of objects under the surface.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|+ Example&lt;br /&gt;
| [[file:water_refractive_example.jpg|400px]]&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   water = {&lt;br /&gt;
      surfaceColor  = {0.75, 0.8, 0.85},&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=surfaceColor|type=float3f|default={0.0, 0.0, 0.0}|description=Effects the reflected colour.}}&lt;br /&gt;
&lt;br /&gt;
== Bump Mapped ==&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|+ Example&lt;br /&gt;
| {{FIXME}}need to place an image here&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   water = {&lt;br /&gt;
      ambientFactor  = 1.0,&lt;br /&gt;
      diffuseFactor  = 1.0,&lt;br /&gt;
      specularFactor = 1.0,&lt;br /&gt;
      specularPower  = 20.0,&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      surfaceColor  = {0.75, 0.8, 0.85},&lt;br /&gt;
      surfaceAlpha  = 0.55,&lt;br /&gt;
      diffuseColor  = {1.0, 1.0, 1.0},&lt;br /&gt;
      specularColor = {0.5, 0.5, 0.5},&lt;br /&gt;
&lt;br /&gt;
      fresnelMin   = 0.2,&lt;br /&gt;
      fresnelMax   = 0.8,&lt;br /&gt;
      fresnelPower = 4.0,&lt;br /&gt;
&lt;br /&gt;
      reflectionDistortion = 1.0,&lt;br /&gt;
&lt;br /&gt;
      blurBase      = 2.0,&lt;br /&gt;
      blurExponent = 1.5,&lt;br /&gt;
&lt;br /&gt;
      perlinStartFreq  =  8.0,&lt;br /&gt;
      perlinLacunarity = 3.0,&lt;br /&gt;
      perlinAmplitude  =  0.9,&lt;br /&gt;
      windSpeed = 1.0, --// does nothing yet&lt;br /&gt;
&lt;br /&gt;
      shoreWaves = true,&lt;br /&gt;
&lt;br /&gt;
      --foamTexture =   &amp;quot;&amp;quot;,&lt;br /&gt;
      --normalTexture = &amp;quot;&amp;quot;,&lt;br /&gt;
      --caustics = {&lt;br /&gt;
      --   &amp;quot;&amp;quot;,&lt;br /&gt;
      --   &amp;quot;&amp;quot;,&lt;br /&gt;
      --},&lt;br /&gt;
      numTiles = 1,&lt;br /&gt;
      hasWaterPlane = true,&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{FIXME}}?&lt;br /&gt;
&lt;br /&gt;
= Forum Discussions =&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?f=13&amp;amp;t=28264 chockolate rain] map discussion apparrently has soemthing in it i wanted to keep for later.. cant remember though...&lt;br /&gt;
* [[Water_Height:_Mapconv_vs._Heightmap|water height]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:grass&amp;diff=13811</id>
		<title>Mapdev:grass</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:grass&amp;diff=13811"/>
		<updated>2020-05-06T04:03:04Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Grass =&lt;br /&gt;
Grass is entirely optional, but can be customized via map parameters and adds a nice touch to your map.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| [[File:Mapdev-grass.png]] || [[File:Mapdev-grass-example.png|451px]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Grass Disribution&lt;br /&gt;
! In Game Result&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   smf = {&lt;br /&gt;
        ....&lt;br /&gt;
        grassmapTex = &amp;quot;&amp;quot;,&lt;br /&gt;
        ....&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      grassBladeTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      grassShadingTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
   grass = {&lt;br /&gt;
      bladeWaveScale = 1.0,&lt;br /&gt;
      bladeWidth = 0.32,&lt;br /&gt;
      bladeHeight = 4.0,&lt;br /&gt;
      bladeAngle = 1.57,&lt;br /&gt;
      bladeColor = {0.59, 0.81, 0.57},&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Blade Wave Scale ===&lt;br /&gt;
Defaults to 1. It specifies how much the blades will wave in the wind. Higher makes them wave more.&lt;br /&gt;
&lt;br /&gt;
=== Blade Height ===&lt;br /&gt;
Default is 4. Defines the length of the blade of grass in elmos.&lt;br /&gt;
&lt;br /&gt;
=== Blade Angle ===&lt;br /&gt;
Default is pi/4. It defines how much each blade of grass curves.&lt;br /&gt;
&lt;br /&gt;
=== Blade Color ===&lt;br /&gt;
does nothing when blade texture is set.&lt;br /&gt;
&lt;br /&gt;
== Distribution Image ==&lt;br /&gt;
Formerly [[Mapdev:features|Feature]] Map. Grass distribution is defined by blue pixels, the more blue the pixel is (the closer to blue 255 it is), the thicker grass will be at that location. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| The distribution map is an intermediary file compiled into the SMF/SMT files using [[MapConv]] or [[MapConvNG]], it can also be specified in the mapinfo.lua&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| Any that Mapconv programs support&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| Greyscale&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| &amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
!Spring Map Size&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
!pixels = Spring Map Size * 16&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 32&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| 64&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| 96&lt;br /&gt;
|-&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| 512&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: left;font-style:italic&amp;quot; colspan=2 | &amp;amp;#42; must be multiples of 2&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Shading Image ==&lt;br /&gt;
* If a shading image is not present, the minimap will be used in its place.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGB&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be stretched over the terrain.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| [[File:Grassmap_Map_example.jpegâ€Ž]] || [[File:Grassmap_Map_ingame.jpg|512px|â€Ž]]&lt;br /&gt;
|-&lt;br /&gt;
! Example !! Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Blade Texture ==&lt;br /&gt;
Specify a texture for the individual grass blades. The grass blades go from top to bottom, vertically. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGB (alpha does nothing here)&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
| https://springrts.com/mediawiki/images/3/36/Grass_blade_tex_testing.png || https://springrts.com/mediawiki/images/9/9f/Grass_blade_tex_ingame.PNG&lt;br /&gt;
|-&lt;br /&gt;
! Example  !! Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Forum Discussions =&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?f=13&amp;amp;t=27585 Try to keep perspective]&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:set.lua&amp;diff=13970</id>
		<title>Mapdev:set.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:set.lua&amp;diff=13970"/>
		<updated>2020-05-06T03:33:48Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* setcfg */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= set.lua Reference =&lt;br /&gt;
This file lists all the units, buildings and features that belong to the gaia team, their locations and orientation.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which reads this file from the map is viewable here:&lt;br /&gt;
* ???&lt;br /&gt;
== Example ==&lt;br /&gt;
Can be found in the [https://github.com/jk3064/Map-Blueprint/archive/master.zip map blueprint]&lt;br /&gt;
&lt;br /&gt;
= File Location =&lt;br /&gt;
relative to the root directory of the map&lt;br /&gt;
: ./mapconfig/featureplacer/set.lua&lt;br /&gt;
&lt;br /&gt;
= Formatting =&lt;br /&gt;
check [http://www.lua.org/docs.html Lua Documentation] for syntax etc.&lt;br /&gt;
&lt;br /&gt;
In this wiki page, variables are organised as such:&lt;br /&gt;
{{tag|name=VariableName|type=type|range=[valid range]|special=Required|default=value&lt;br /&gt;
|description=Description}}&lt;br /&gt;
&lt;br /&gt;
== Data Types ==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
= Sections =&lt;br /&gt;
== setcfg ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
----------------------------------------------------------&lt;br /&gt;
-- AutoCreated by FeaturePlacer (by smoth)&lt;br /&gt;
&lt;br /&gt;
local setcfg = {&lt;br /&gt;
   unitlist = {&lt;br /&gt;
   ...&lt;br /&gt;
   { name = &#039;name&#039;, x = 0 , z = 0 , rot = &amp;quot;0&amp;quot;},&lt;br /&gt;
   ...&lt;br /&gt;
   },&lt;br /&gt;
   buildinglist = {&lt;br /&gt;
   ...&lt;br /&gt;
   { name = &#039;name&#039;, x = 0 , z = 0 , rot = &amp;quot;0&amp;quot;},&lt;br /&gt;
   ...&lt;br /&gt;
   },&lt;br /&gt;
   objectlist = {&lt;br /&gt;
   ...&lt;br /&gt;
   { name = &#039;name&#039;, x = 0 , z = 0 , rot = &amp;quot;0&amp;quot;},&lt;br /&gt;
   ...&lt;br /&gt;
   },&lt;br /&gt;
}&lt;br /&gt;
return setcfg&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=name|type=string&lt;br /&gt;
|description=name of the unit, feature, or building owned by the gaia team}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=x|type=integer&lt;br /&gt;
|description=x position on the map}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=z|type=integer&lt;br /&gt;
|description=z position on the map}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=rot|type=string&lt;br /&gt;
|description=a number which specifies the rotation of the object}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:mapinfo.lua&amp;diff=13914</id>
		<title>Mapdev:mapinfo.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:mapinfo.lua&amp;diff=13914"/>
		<updated>2020-05-06T03:33:04Z</updated>

		<summary type="html">&lt;p&gt;Gajop: remove &amp;lt;code&amp;gt; tags&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= mapinfo.lua Reference =&lt;br /&gt;
This file is the primary configuration file for maps, list many things including resources, attributes, ad properties.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which reads this file from the map is viewable here:&lt;br /&gt;
* {{sourcelink|file=rts/Map/MapInfo.cpp}}&lt;br /&gt;
* {{sourcelink|file=rts/Map/MapParser.cpp}}&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Can be found in the [https://github.com/jk3064/Map-Blueprint/archive/master.zip map blueprint]&lt;br /&gt;
&lt;br /&gt;
= File Location =&lt;br /&gt;
relative to the root directory of the map&lt;br /&gt;
: ./mapinfo.lua&lt;br /&gt;
&lt;br /&gt;
= Formatting =&lt;br /&gt;
check [http://www.lua.org/docs.html Lua Documentation] for syntax etc.&lt;br /&gt;
&lt;br /&gt;
In this wiki page, variables are organised as such:&lt;br /&gt;
{{tag|name=VariableName|type=type|range=[valid range]|special=Required|default=value&lt;br /&gt;
|description=Description}}&lt;br /&gt;
&lt;br /&gt;
== Data Types ==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
= Sections =&lt;br /&gt;
== mapinfo ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   name        = &amp;quot;MyMap&amp;quot;,&lt;br /&gt;
   shortname   = &amp;quot;&amp;quot;,&lt;br /&gt;
   description = &amp;quot;&amp;quot;,&lt;br /&gt;
   author      = &amp;quot;&amp;quot;,&lt;br /&gt;
   version     = &amp;quot;1.0&amp;quot;,&lt;br /&gt;
   --mutator   = &amp;quot;deployment&amp;quot;;&lt;br /&gt;
   mapfile     = &amp;quot;maps/mymap.smf&amp;quot;, -- // location of smf/sm3 file&lt;br /&gt;
   modtype     = 3, --// 1=primary, 0=hidden, 3=map&lt;br /&gt;
   depend      = {&amp;quot;Map Helper v1&amp;quot;},&lt;br /&gt;
   replace     = {},&lt;br /&gt;
&lt;br /&gt;
   --startpic   = &amp;quot;&amp;quot;, --// deprecated&lt;br /&gt;
   --StartMusic = &amp;quot;&amp;quot;, --// deprecated&lt;br /&gt;
&lt;br /&gt;
   maphardness     = 100,&lt;br /&gt;
   notDeformable   = false,&lt;br /&gt;
   gravity         = 130,&lt;br /&gt;
   tidalStrength   = 0,&lt;br /&gt;
   maxMetal        = 0.02,&lt;br /&gt;
   extractorRadius = 500.0,&lt;br /&gt;
   voidWater       = false,&lt;br /&gt;
   voidGround      = false,&lt;br /&gt;
   autoShowMetal   = true,&lt;br /&gt;
&lt;br /&gt;
   smf = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   sound = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   splats = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   atmosphere = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   grass = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   lighting = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   water = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   teams = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   terrainTypes = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
&lt;br /&gt;
   custom = {&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=name|type=string|special=Required|default=none&lt;br /&gt;
|description=Name of the map}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=shortname|type=string|special=Required&lt;br /&gt;
|description=maps will not show in the map list without a valid shortname(not sure on its requirements)}} &lt;br /&gt;
&lt;br /&gt;
{{tag|name=description|type=string|default=&amp;lt;span style=&amp;quot;color:#cccccc;text-shadow: #111 2px 2px 2px;&amp;quot;&amp;gt;name&amp;lt;/span&amp;gt;&lt;br /&gt;
|description=The description of the map that shows in the multiplayer battleroom}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=author|type=string|default=&amp;quot;&amp;quot;&lt;br /&gt;
|description=Author of the map}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=version|type=string&lt;br /&gt;
|description=version, appended to name}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=mutator|type=string}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=mapfile|type=string&lt;br /&gt;
|description=location of smf/sm3 file}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=modtype|type=int|range=[013]|special=Required&lt;br /&gt;
|description=1=primary, 0=hidden, 3=map}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=depend|special=Required}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=replace}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=maphardness|type=float|default=100.0&lt;br /&gt;
|description=Defines how much a map will deform from impacts. Higher values mean less deformation, negative values will result in negative deformation (really funny looking)}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=notDeformable|type=bool|default=false&lt;br /&gt;
|description=Setting it to 1 means that no explosions can deform the map.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=gravity|type=float|range=[0.001-max]|default=130.0&lt;br /&gt;
|description=As you would expect, affects ballistics and how far units fly after an explosion. The force of gravity in units/sec^2}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=tidalStrength|type=float|range=[0.0-max]|default=0.0&lt;br /&gt;
|description=The amount of energy which will be given by tidal generators.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=maxMetal|type=float|range=[0.0-max]|default=0.02&lt;br /&gt;
|description=How much metal a map square with the maximum metal value gives.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=extractorRadius|type=float|range=[0.0-max]|default=500&lt;br /&gt;
|description=The radius of effect that a single extractor will extract from. If two radii intersect, both extractors will suffer from reduced output.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=voidWater|type=bool|default=false&lt;br /&gt;
|description=Voidwater means there will be no water plane, and all parts of the map under water will be completely transparent, to show the skybox through the map. For example, check [http://springrts.com/phpbb/viewtopic.php?f=13&amp;amp;t=20684&amp;amp;hilit=apophis Apophis_v2]}}. Additionally for this to work, the &amp;lt;code&amp;gt;mapinfo.water.planeColor&amp;lt;/code&amp;gt; variable must not be specified in the mapinfo.lua file, delete or comment it out if it exists.&lt;br /&gt;
&lt;br /&gt;
{{tag|name=voidGround|type=bool|default=false&lt;br /&gt;
|special=&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;New in 92.0&amp;lt;/span&amp;gt;&lt;br /&gt;
|description=Allows portions of the ground to be invisible if the map was compiled with a diffuse image that has an alpha channel. The terrain still exists, its just transparent.}}. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{tag|name=voidAlphaMin|type=float|default=0.9&lt;br /&gt;
|description=Controls what alpha level the transparency trigger.}}. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{tag|name=autoShowMetal|type=bool|default=true&lt;br /&gt;
|description=Defines whether the metal map (F4 mode) is shown automatically when a mex is queued for placement.}}&lt;br /&gt;
&lt;br /&gt;
== smf ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   smf = {&lt;br /&gt;
      minHeight = 1000,&lt;br /&gt;
      maxHeight = -300,&lt;br /&gt;
      minimapTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      smtFileName0 = &amp;quot;&amp;quot;,&lt;br /&gt;
      smtFileName1 = &amp;quot;&amp;quot;,&lt;br /&gt;
      smtFileName.. = &amp;quot;&amp;quot;,&lt;br /&gt;
      smtFileNameN = &amp;quot;&amp;quot;,&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{tag|name=minHeight|type=float|default=0.0&lt;br /&gt;
|description=Overrides the minimum map height specified while compiling. Compile time height used if undefined}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=maxHeight|type=float|default=0.0&lt;br /&gt;
|description=Overrides the maximum map height specified while compiling. Compile time height used if undefined}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=minimapTex|type=string&lt;br /&gt;
|special=&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;New in 99.0&amp;lt;/span&amp;gt;&lt;br /&gt;
| description=Overrides the minimap with an image of your choice, smf used if undefined or invalid}} &lt;br /&gt;
&lt;br /&gt;
{{tag|name=metalmapTex|type=string&lt;br /&gt;
|special=&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;New in 99.0&amp;lt;/span&amp;gt;&lt;br /&gt;
| description=Overrides the metalmap with an image of your choice, smf used if undefined or invalid}} &lt;br /&gt;
&lt;br /&gt;
{{tag|name=typemapTex|type=string&lt;br /&gt;
|special=&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;New in 99.0&amp;lt;/span&amp;gt;&lt;br /&gt;
| description=Overrides the typemap with an image of your choice, smf used if undefined or invalid}} &lt;br /&gt;
&lt;br /&gt;
{{tag|name=grassmapTex|type=string&lt;br /&gt;
|special=&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;New in 99.0&amp;lt;/span&amp;gt;&lt;br /&gt;
| description=Overrides the grassmap with an image of your choice, smf used if undefined or invalid}} &lt;br /&gt;
&lt;br /&gt;
{{tag|name=smtFileName[N]|type=string}}&lt;br /&gt;
&lt;br /&gt;
== sound ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   sound = {&lt;br /&gt;
      preset = &amp;quot;default&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
      passfilter = {&lt;br /&gt;
         ...&lt;br /&gt;
      },&lt;br /&gt;
&lt;br /&gt;
      reverb = {&lt;br /&gt;
         ...&lt;br /&gt;
      },&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=preset|type=string|default=&amp;quot;default&amp;quot;&lt;br /&gt;
|description=Sets the _reverb_ preset (= echo parameters), passfilter (the direct sound) is unchanged. To get a list of all possible presets check: [https://github.com/spring/spring/blob/master/rts/System/Sound/OpenAL/EFXPresets.cpp EFXPresets.cpp]}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|You can change the preset at runtime via:&lt;br /&gt;
* /tset UseEFX [1&amp;amp;#124;0]&lt;br /&gt;
* /tset snd_eaxpreset preset_name   (may change to a real cmd in the future)&lt;br /&gt;
* /tset snd_filter %gainlf %gainhf  (may    &amp;quot;   &amp;quot;  &amp;quot;  &amp;quot;    &amp;quot;  &amp;quot;   &amp;quot;    &amp;quot;   )}}&lt;br /&gt;
&lt;br /&gt;
=== passfilter ===&lt;br /&gt;
Note, you likely want to set these tags due to the fact that they are _not_ set by `preset`!  So if you want to create a muffled sound you need to use them.&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   sound = {&lt;br /&gt;
      ...&lt;br /&gt;
      passfilter = {&lt;br /&gt;
         gainlf = 1.0,&lt;br /&gt;
         gainhf = 1.0,&lt;br /&gt;
      },&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=gainlf|type=float}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=gainhf|type=float}}&lt;br /&gt;
&lt;br /&gt;
=== reverb ===&lt;br /&gt;
Normally you just want use the `preset` tag but you can use handtweak a preset if wanted with the following tags. To know their function &amp;amp; ranges check the official OpenAL1.1 SDK document.&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   sound = {&lt;br /&gt;
      ...&lt;br /&gt;
      reverb = {         &lt;br /&gt;
         --density&lt;br /&gt;
         --diffusion&lt;br /&gt;
         --gain&lt;br /&gt;
         --gainhf&lt;br /&gt;
         --gainlf&lt;br /&gt;
         --decaytime&lt;br /&gt;
         --decayhflimit&lt;br /&gt;
         --decayhfratio&lt;br /&gt;
         --decaylfratio&lt;br /&gt;
         --reflectionsgain&lt;br /&gt;
         --reflectionsdelay&lt;br /&gt;
         --reflectionspan&lt;br /&gt;
         --latereverbgain&lt;br /&gt;
         --latereverbdelay&lt;br /&gt;
         --latereverbpan&lt;br /&gt;
         --echotime&lt;br /&gt;
         --echodepth&lt;br /&gt;
         --modtime&lt;br /&gt;
         --moddepth&lt;br /&gt;
         --airabsorptiongainhf&lt;br /&gt;
         --hfreference&lt;br /&gt;
         --lfreference&lt;br /&gt;
         --roomrollofffactor&lt;br /&gt;
      },&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== resources ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      grassBladeTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      grassShadingTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      detailTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      specularTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      splatDetailTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      splatDistrTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      skyReflectModTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      detailNormalTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      lightEmissionTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      parallaxHeightTex = &amp;quot;&amp;quot;,&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=grassBladeTex|type=string&lt;br /&gt;
|description=Specifies the texture to be used on the grass blades themselves. Green-yellow gradients make for some interesting effects. Defaults to the internally generated blade texture. More Information: [[Mapdev:grass]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=grassShadingTex|type=string&lt;br /&gt;
|description=Specifies the color variation of the grass across the map. This defaults to the minimap, so the grass color can match the map color. More Information: [[Mapdev:grass]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=detailTex|type=string&lt;br /&gt;
|description=Specifies the detail texture for the map. More Information: [[Mapdev:detail]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=specularTex|type=string&lt;br /&gt;
|description=More Information: [[Mapdev:specular]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=splatDetailTex|type=string&lt;br /&gt;
|description=More Information: [[Mapdev:splatdetail]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=splatDistrTex|type=string&lt;br /&gt;
|description=More Information: [[Mapdev:splatdetail]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=skyReflectModTex|type=string&lt;br /&gt;
|description=More Information: [[Mapdev:skyreflectmod]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=detailNormalTex|type=string&lt;br /&gt;
|description=More Information: [[Mapdev:normal]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=lightEmissionTex|type=string&lt;br /&gt;
|description=More Information: [[Mapdev:lightemission]]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=parallaxHeightTex|type=string&lt;br /&gt;
|description=More Information: [[Mapdev:parallax]]}}&lt;br /&gt;
&lt;br /&gt;
== splats ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   splats = {&lt;br /&gt;
      texScales = {0.02, 0.02, 0.02, 0.02},&lt;br /&gt;
      texMults  = {1.0, 1.0, 1.0, 1.0},&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{tag|name=texScales|type=float[4]&lt;br /&gt;
|default={0.2, 0.2, 0.2, 0.2}|description=Scale value for the splat texture in the RGBA channels respectively.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=texMults|type=float[4]&lt;br /&gt;
|default={1.0, 1.0, 1.0, 1.0}|description=Value for the splat texture in the RGBA channels respectively.}}&lt;br /&gt;
&lt;br /&gt;
== atmosphere ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   atmosphere = {&lt;br /&gt;
      minWind      = 5.0,&lt;br /&gt;
      maxWind      = 25.0,&lt;br /&gt;
&lt;br /&gt;
      fogStart     = 0.1,&lt;br /&gt;
      fogEnd       = 1.0,&lt;br /&gt;
      fogColor     = {0.7, 0.7, 0.8},&lt;br /&gt;
&lt;br /&gt;
      sunColor     = {1.0, 1.0, 1.0},&lt;br /&gt;
      skyColor     = {0.1, 0.15, 0.7},&lt;br /&gt;
      skyDir       = {0.0, 0.0, -1.0},&lt;br /&gt;
      skyBox       = &amp;quot;&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
      cloudDensity = 0.5,&lt;br /&gt;
      cloudColor   = {1.0, 1.0, 1.0},&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tag|name=minWind|type=float|range=[0.0-max]|default=5.0|&lt;br /&gt;
description=The minimum amount of energy the wind on the map will give. is clamped to maxwind}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=maxWind|type=float|range=[0.0-max]|default=25.0&lt;br /&gt;
|description=The maximum amount of energy the wind on the map will give}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=fogStart|type=float|default=0.1&lt;br /&gt;
|description=The distance from the camera at which the fog will start. &amp;lt;code&amp;gt;viewRange * fogStart&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=fogEnd|type=float|default=1.0&lt;br /&gt;
|description=The distance from the camera that fog is opaque. &amp;lt;code&amp;gt;viewRange * fogEnd&amp;lt;/code&amp;gt; }}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=fogColor|type=rgb|default={0.7, 0.7, 0.8}&lt;br /&gt;
|description=The color of the fog and the infinite plane below the world. The values are in the order Red, Green, Blue. However, giving values higher than 1.0 will give brighter fog and less than 0.0 will give darker}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=sunColor|type=rgb|default={1.0, 1.0, 1.0}&lt;br /&gt;
|description=The color of the sun in the sky. The values are in the order Red, Green, Blue. This will also effect the size of the star. As the values increase (including over 1.0), the disc will get bigger; the inverse is also true}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=skyColor|type=rgb|default={0.1, 0.15, 0.7}&lt;br /&gt;
|description=The color of the sky itself. The values are in the order Red, Green, Blue}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=skyDir|type=float[3]|default={0.0, 0.0, -1.0}&lt;br /&gt;
|description=Is normalised vector}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=skyBox|type=string&lt;br /&gt;
|description=Specify a .dds skybox (also called skycube) for examples and resources see this [http://springrts.com/phpbb/viewtopic.php?f=56&amp;amp;t=11009 thread]}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=cloudDensity|type=float|range=[0.0-max]|default=0.5&lt;br /&gt;
|description=The amount of clouds in the sky}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=cloudColor|type=rgb&lt;br /&gt;
|default={1.0, 1.0, 1.0}|description=The color of the clouds}}&lt;br /&gt;
&lt;br /&gt;
== grass ==&lt;br /&gt;
The shader for grass color at https://github.com/spring/spring/blob/266b51ad4c0301103e269a13f8e72f9c26511b4e/cont/base/springcontent/shaders/GLSL/GrassFragProg.glsl#L48 samples grassBladeTex, and multiplies it with grassShadingTex (which defaults to minimap)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   grass = {&lt;br /&gt;
      bladeWaveScale = 1.0,&lt;br /&gt;
      bladeWidth  = 0.32,&lt;br /&gt;
      bladeHeight = 4.0,&lt;br /&gt;
      bladeAngle  = 1.57,&lt;br /&gt;
      bladeColor  = {0.59, 0.81, 0.57},&lt;br /&gt;
      maxStrawsPerTurf = 150,&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{tag|name=bladeWaveScale|type=float|default=1.0&lt;br /&gt;
|description=Specifies how much the wind should effect grass blade movement, as well as the amplitude of the grass motion. Setting it to 0 will stop grass animation}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=bladeWidth|type=float|default=0.32&lt;br /&gt;
|description=Specifies the width of each blade of grass}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=bladeHeight|type=float|default=4.0&lt;br /&gt;
|description=Specifies the length of each blade of grass}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=bladeAngle|type=float|default=1.57&lt;br /&gt;
|description=Specifies the curvature of each blade of grass. Unit is radians. 0 means completely straight blades of grass}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=maxStrawsPerTurf|type=int|default=150&lt;br /&gt;
|description=The maximum number of grass blades per &#039;turf&#039;, A turf is approximately 32x32 elmos. }}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=bladeColor|type=rgb|default={0.59, 0.81, 0.57}&lt;br /&gt;
|description=does nothing when `grassBladeTex` is set}}&lt;br /&gt;
&lt;br /&gt;
== Lighting ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   lighting = {&lt;br /&gt;
      --// dynsun&lt;br /&gt;
      sunStartAngle = 0.0,&lt;br /&gt;
      sunOrbitTime  = 1440.0,&lt;br /&gt;
      sunDir        = {0.0, 1.0, 2.0, 1e9},&lt;br /&gt;
&lt;br /&gt;
      --// unit &amp;amp; ground lighting&lt;br /&gt;
      groundAmbientColor  = {0.5, 0.5, 0.5},&lt;br /&gt;
      groundDiffuseColor  = {0.5, 0.5, 0.5},&lt;br /&gt;
      groundSpecularColor = {0.1, 0.1, 0.1},&lt;br /&gt;
      groundShadowDensity = 0.8,&lt;br /&gt;
      unitAmbientColor    = {0.4, 0.4, 0.4},&lt;br /&gt;
      unitDiffuseColor    = {0.7, 0.7, 0.7},&lt;br /&gt;
      unitSpecularColor   = {0.7, 0.7, 0.7},&lt;br /&gt;
      unitShadowDensity   = 0.8,&lt;br /&gt;
      &lt;br /&gt;
      specularExponent    = 100.0,&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{tag|name=sunStartAngle|type=float|default=0.0}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=sunOrbitTime|type=float|default=1440.0}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=sunDir|type=float[3]|default={0.0, 1.0, 2.0}&lt;br /&gt;
|description=The direction of the sun, which is normalized by Spring. The Y-axis is up}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=groundAmbientColor|type=rgb|default={0.5, 0.5, 0.5}&lt;br /&gt;
|description=The ambient (non-sun-lit) color of ground, grass, trees and other features. The values are in the order Red, Green, Blue}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=groundDiffuseColor|type=rgb|default={0.5, 05, 0.5}&lt;br /&gt;
|description=The color of ground where it is fully sun lit (added to GroundAmbientColor). The values are in the order Red, Green, Blue}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=groundSpecularColor|type=rgb|default={0.1, 0.1, 0.1}&lt;br /&gt;
|description=and its effect when a specular map is present?}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=groundShadowDensity|type=float|default=0.8&lt;br /&gt;
|description=How far from the non shadowed to the ambient color stuff in shadow will go.}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=unitAmbientColor|type=float|default={0.4, 0.4, 0.4}&lt;br /&gt;
|description=The ambient (non-sun-lit) color of units and corpses}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=unitDiffuseColor|type=rgb|default={0.7, 0.7, 0.7}&lt;br /&gt;
|description=The color of units where they is fully sun lit (added to UnitAmbientColor). The color of units where they is fully sun lit (added to UnitAmbientColor)}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=unitSpecularColor|type=rgb|default=unitDiffuseColor}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=unitShadowDensity|type=float|default=0.8&lt;br /&gt;
|description=How far from the non shadowed to the ambient color stuff in shadow will go}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=specularExponent|type=float|default=100}}&lt;br /&gt;
&lt;br /&gt;
== water ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   water = {&lt;br /&gt;
      damage =  0.0,&lt;br /&gt;
&lt;br /&gt;
      repeatX = 0.0,&lt;br /&gt;
      repeatY = 0.0,&lt;br /&gt;
&lt;br /&gt;
      absorb    = {0.0, 0.0, 0.0},&lt;br /&gt;
      baseColor = {0.0, 0.0, 0.0},&lt;br /&gt;
      minColor  = {0.0, 0.0, 0.0},&lt;br /&gt;
&lt;br /&gt;
      ambientFactor  = 1.0,&lt;br /&gt;
      diffuseFactor  = 1.0,&lt;br /&gt;
      specularFactor = 1.0,&lt;br /&gt;
      specularPower  = 20.0,&lt;br /&gt;
&lt;br /&gt;
      planeColor = {0.0, 0.4, 0.0},&lt;br /&gt;
&lt;br /&gt;
      surfaceColor  = {0.75, 0.8, 0.85},&lt;br /&gt;
      surfaceAlpha  = 0.55,&lt;br /&gt;
      diffuseColor  = {1.0, 1.0, 1.0},&lt;br /&gt;
      specularColor = {0.5, 0.5, 0.5},&lt;br /&gt;
&lt;br /&gt;
      fresnelMin   = 0.2,&lt;br /&gt;
      fresnelMax   = 0.8,&lt;br /&gt;
      fresnelPower = 4.0,&lt;br /&gt;
&lt;br /&gt;
      reflectionDistortion = 1.0,&lt;br /&gt;
&lt;br /&gt;
      blurBase      = 2.0,&lt;br /&gt;
      blurExponent = 1.5,&lt;br /&gt;
&lt;br /&gt;
      perlinStartFreq  =  8.0,&lt;br /&gt;
      perlinLacunarity = 3.0,&lt;br /&gt;
      perlinAmplitude  =  0.9,&lt;br /&gt;
      windSpeed = 1.0, --// does nothing yet&lt;br /&gt;
&lt;br /&gt;
      shoreWaves = true,&lt;br /&gt;
      forceRendering = false,&lt;br /&gt;
&lt;br /&gt;
      --// undefined == load them from resources.lua!&lt;br /&gt;
      --texture =       &amp;quot;&amp;quot;,&lt;br /&gt;
      --foamTexture =   &amp;quot;&amp;quot;,&lt;br /&gt;
      --normalTexture = &amp;quot;&amp;quot;,&lt;br /&gt;
      --caustics = {&lt;br /&gt;
      --   &amp;quot;&amp;quot;,&lt;br /&gt;
      --   &amp;quot;&amp;quot;,&lt;br /&gt;
      --},&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{tag|name=damage|type=float|default=0.0&lt;br /&gt;
|description=Number of hit points per game frame (30 frames per second) a unit will be damaged if it is in the water. As of 95.0 by default damage is also applied to hovercraft units. i wonder if this can be made to give life...?}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=repeatX|type=float|default=0.0&lt;br /&gt;
|description=effects the filing frequency of the watertexture}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=repeatY|type=float|default=0.0&lt;br /&gt;
|description=effects the filing frequency of the watertexture}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=absorb|type=rgb|default={0.0, 0.0, 0.0}&lt;br /&gt;
|description=How fast different colors (RGB in order) are absorbed by the water. Can be used to make the water look murky at deeper sections and so on. How this works: the waterabsorb value for the color channel gets multiplied by the depth of the water at a point, and this product gets subtracted from WaterBaseColor, until WaterMinColor is reached. Example: WaterAbsorb is 0.01, for the red channel, and we want to know how much red will be left in the water at a Spring elevation of -100, since 0.01*100= 1 , at this depth, there will be no more red component in the water, unless WaterMinColor is higher than 0 on the red channel}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=baseColor|type=rgb|default={0.0, 0.0, 0.0}&lt;br /&gt;
|description=The color of the water just beneath the surface plane. This is the starting color from which deeper waters will absorb more color. The values are in the order Red, Green, Blue}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=minColor|type=rgb|default={0.0, 0.0, 0.0}&lt;br /&gt;
|description=The smallest values the water will go down to due to WaterAbsorb}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=ambientFactor|type=float|default=1.0}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=diffuseFactor|type=float|default=1.0}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=specularFactor|type=float|default=1.0}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=specularPower|type=float|default=20.0}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=planeColor|type=rgb|default={0.0, 0.4, 0.0}&lt;br /&gt;
|description=This sets the color of the groundplane under the water outside the map boundaries}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=surfaceColor|type=rgb|default={0.75, 0.8, 0.85}&lt;br /&gt;
|description=The color of the water surface. Mostly affects the colors of the reflections off the top of the water. Has no effect on bump mapped water!}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=surfaceAlpha|type=float|default=0.55&lt;br /&gt;
|description= Transparency of the water surface. 0 meaning almost fully transparent water plane(low amount of reflections visible), and 1 being nearly opaque (massive amount of reflections)}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=diffuseColor|type=rgb|default=value&lt;br /&gt;
|description=This specifies the diffuse color of the water body. WARNING: use of this tag disables the effect of WaterAbsorb , in fact, this tag does nothing but disable WaterAbsorb. Avoid}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=specularColor|type=rgb|default=lighting.groundDiffuseColor}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=fresnelMin|type=float|default=0.2}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=fresnelMax|type=float|default=0.8}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=fresnelPower|type=float|default=4.0}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=reflectionDistortion|type=float|default=1.0&lt;br /&gt;
|description=How much the surface should distort reflections that are cause by waves not being level: ergo it adds more choppyness to your reflections sensible from 0 to 20}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=blurBase|type=float|default=2.0&lt;br /&gt;
|description=Something to do with blur, but it just seems to cause banding with values under 2 and corruption with values above 10}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=blurExponent|type=float|default=1.5&lt;br /&gt;
|description=How much reflections on water surface should be blurred together with the water surface, lower values meaning clearer reflections, (0.2-5) Warning: above 5 seems to cause water corruption}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=perlinStartFreq|type=float|default=8.0&lt;br /&gt;
|description=Wave sizes, smaller = big waves, sensible: [1,20] (influence the wave sizes)}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=perlinLacunarity|type=float|default=3.0&lt;br /&gt;
|description=Defines the size of the perlin waves, small values being big waves ([0.2,5] is sensible)}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=perlinAmplitude|type=float|default=0.9&lt;br /&gt;
|description=Base stillness of water surface, 0 is dead still, 1 is &#039;windy&#039; .This doesnt affect the bump texture depth, besides the fact that this disables the bump texture when set to 0}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=windSpeed|type=float|default=1.0&lt;br /&gt;
|description=does nothing yet}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=shoreWaves|type=bool|default=true}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=forceRendering|type=bool|default=true}}&lt;br /&gt;
&lt;br /&gt;
will have to ask about those undefined tags&lt;br /&gt;
&lt;br /&gt;
== teams ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   teams = {&lt;br /&gt;
      [0] = {startPos = {x = 2033, z = 852}},&lt;br /&gt;
      [1] = {startPos = {x = 10134, z = 852}},&lt;br /&gt;
      [2] = {startPos = {x = 0, z = 0}},&lt;br /&gt;
      [3] = {startPos = {x = 0, z = 0}},&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Holds an array of start positions&lt;br /&gt;
&lt;br /&gt;
== terrainTypes ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   terrainTypes = {&lt;br /&gt;
      [0] = {&lt;br /&gt;
         name = &amp;quot;Default&amp;quot;,&lt;br /&gt;
         hardness = 1.0,&lt;br /&gt;
         receiveTracks = true,&lt;br /&gt;
         moveSpeeds = {&lt;br /&gt;
            tank  = 1.0,&lt;br /&gt;
            kbot  = 1.0,&lt;br /&gt;
            hover = 1.0,&lt;br /&gt;
            ship  = 1.0,&lt;br /&gt;
         },&lt;br /&gt;
      },&lt;br /&gt;
      [1]  = { &lt;br /&gt;
         ...&lt;br /&gt;
      },&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Holds an array of start types where each element contains:&lt;br /&gt;
&lt;br /&gt;
{{tag|name=name|type=string&lt;br /&gt;
|description=A label for the terrain type}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=hardness|type=float|range=[0.001-max]|default=1.0&lt;br /&gt;
|description=Used as a multiplier against the mapinfo.mapHardness value. Can be used to make a particular terrain type softer or harder. A value of &#039;1&#039; will make it as hard as MapHardness, and 0.5 will make it half as hard}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=receiveTracks|type=bool|default=true&lt;br /&gt;
|description= Effects whether track decals will be placed on the ground from moving vehicles}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=moveSpeeds.tank|type=float|range=[0.0-max]|default=1.0&lt;br /&gt;
|description= Speed multiplier for tanks when travelling on the parent terrain type. A value of &#039;1.0&#039; is normal speed, 0.5 will make them travel at half speed on the parent terrain type}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=moveSpeeds.kbot|type=float|range=[0.0-max]|default=1.0&lt;br /&gt;
|description= Speed multiplier for kbots when travelling on the parent terrain type. A value of &#039;1.0&#039; is normal speed, 0.5 will make them travel at half speed on the parent terrain type}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=moveSpeeds.hover|type=float|range=[0.0-max]|default=1.0&lt;br /&gt;
|description= Speed multiplier for hovercraft when travelling on the parent terrain type. A value of &#039;1.0&#039; is normal speed, 0.5 will make them travel at half speed on the parent terrain type}}&lt;br /&gt;
&lt;br /&gt;
{{tag|name=moveSpeeds.ship|type=float|range=[0.0-max]|default=1&lt;br /&gt;
|description= Speed multiplier for ships when travelling on the parent terrain type. A value of &#039;1.0&#039; is normal speed, 0.5 will make them travel at half speed on the parent terrain type}}&lt;br /&gt;
&lt;br /&gt;
== custom ==&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   custom = {&lt;br /&gt;
      fog = {&lt;br /&gt;
         color    = {0.26, 0.30, 0.41},&lt;br /&gt;
         height   = &amp;quot;80%&amp;quot;, --// allows either absolue sizes or in percent of map&#039;s MaxHeight&lt;br /&gt;
         fogatten = 0.003,&lt;br /&gt;
      },&lt;br /&gt;
      precipitation = {&lt;br /&gt;
         density   = 30000,&lt;br /&gt;
         size      = 1.5,&lt;br /&gt;
         speed     = 50,&lt;br /&gt;
         windscale = 1.2,&lt;br /&gt;
         texture   = &#039;LuaGaia/effects/snowflake.png&#039;,&lt;br /&gt;
      },&lt;br /&gt;
&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Fonts&amp;diff=11297</id>
		<title>Lua Fonts</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Fonts&amp;diff=11297"/>
		<updated>2020-04-12T01:00:18Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Inlined ColorCodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
=Load/Delete=&lt;br /&gt;
&#039;&#039;&#039;gl.LoadFont&#039;&#039;&#039;&lt;br /&gt;
  ( string fontfilename, number size = 14,&lt;br /&gt;
    number outlineWidth = 2, number outlineWeight = 15 ) -&amp;gt; userdata font&lt;br /&gt;
&#039;&#039;&#039;gl.DeleteFont&#039;&#039;&#039;&lt;br /&gt;
  ( userdata font ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
=Userdata Functions=&lt;br /&gt;
&#039;&#039;&#039;font:Print&#039;&#039;&#039;&lt;br /&gt;
  (string &amp;quot;text&amp;quot;, number x, number y [, number size [, string &amp;lt;span class=note&amp;gt;&amp;quot;options&amp;quot;&amp;lt;/span&amp;gt;] ] ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;span class=note&amp;gt;&lt;br /&gt;
  options are:&lt;br /&gt;
    horizontal alignment:&lt;br /&gt;
       &#039;c&#039; = center&lt;br /&gt;
       &#039;r&#039; = right&lt;br /&gt;
    vertical alignment:&lt;br /&gt;
       &#039;a&#039; = ascender (is a font specific value)&lt;br /&gt;
       &#039;t&#039; = top (depends on text)&lt;br /&gt;
       &#039;v&#039; = vertical center&lt;br /&gt;
       &#039;x&#039; = baseline&lt;br /&gt;
       &#039;b&#039; = bottom&lt;br /&gt;
       &#039;d&#039; = descender&lt;br /&gt;
    decorations:&lt;br /&gt;
       &#039;o&#039; = black outline&lt;br /&gt;
       &#039;O&#039; = white outline&lt;br /&gt;
       &#039;s&#039; = shadow&lt;br /&gt;
    other:&lt;br /&gt;
       &#039;n&#039; = don&#039;t round vertex coords to nearest integer (font may get blurry)&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
http://home.arcor.de/jkei/fontlines.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;font:SetTextColor&#039;&#039;&#039;&lt;br /&gt;
  ( number r, number g, number b [, number a ] ) -&amp;gt; nil&lt;br /&gt;
  ( {r,g,b,a} ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;font:SetOutlineColor&#039;&#039;&#039;&lt;br /&gt;
  ( number r, number g, number b [, number a ] ) -&amp;gt; nil&lt;br /&gt;
  ( {r,g,b,a} ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;font:SetAutoOutlineColor&#039;&#039;&#039;&lt;br /&gt;
  ( boolean enable ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;font:GetTextWidth&#039;&#039;&#039;&lt;br /&gt;
  (string &amp;quot;text&amp;quot;) -&amp;gt; number width  &amp;lt;span class=note&amp;gt;(in pixels, with a font size of 1.0)&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;font:GetTextHeight&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;text&amp;quot; ) -&amp;gt; nil | number height, number descender, number numlines&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;(height &amp;amp; descender in pixels, with a font size of 1.0)&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;further descriptions here: [[GetTextHeight]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;font:WrapText&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;text&amp;quot;, number max_width [, number max_height [, number size ] ])&lt;br /&gt;
    -&amp;gt; nil | string wrappedText, number lines&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;font:BindTexture&#039;&#039;&#039;&lt;br /&gt;
  (  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;&amp;lt;b&amp;gt;If you have multiple font:Print calls, then you can bunch them between a font:Begin() and font:End() to speedup the rendering.&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;font:Begin&#039;&#039;&#039;&lt;br /&gt;
  (  ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;font:End&#039;&#039;&#039;&lt;br /&gt;
  (  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
=Userdata Properties (ReadOnly)=&lt;br /&gt;
string &#039;&#039;&#039;font.path&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
string &#039;&#039;&#039;font.family&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
string &#039;&#039;&#039;font.style&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
number &#039;&#039;&#039;font.size&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
number &#039;&#039;&#039;font.height&#039;&#039;&#039; a.k.a. &#039;&#039;&#039;font.lineheight&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
number &#039;&#039;&#039;font.descender&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
number &#039;&#039;&#039;font.outlinewidth&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
number &#039;&#039;&#039;font.outlineweight&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
number &#039;&#039;&#039;font.texturewidth&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
number &#039;&#039;&#039;font.textureheight&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=Inlined ColorCodes=&lt;br /&gt;
&amp;lt;span class=info&amp;gt; Whole Spring FontRendering supports `inlined colorcodes`, there are 2 special chars to indicate those &#039;&amp;lt;code&amp;gt;\255\$r\$g\$b&amp;lt;/code&amp;gt;&#039; &amp;amp; &#039;&amp;lt;code&amp;gt;\b&amp;lt;/code&amp;gt;&#039;:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local black = &amp;quot;\255\001\001\001&amp;quot;&lt;br /&gt;
local blue = &amp;quot;\255\001\001\255&amp;quot;&lt;br /&gt;
local reset = &amp;quot;\b &amp;quot; -- !space after &amp;quot;\b &amp;quot; is necessary if you put it at the end of the string you want to print, otherwise the parsing will break&lt;br /&gt;
font:Print(blue .. &amp;quot;bluetext&amp;quot; .. black .. &amp;quot;blacktext&amp;quot; .. reset .. blue .. &amp;quot;bluetext again&amp;quot; .. reset, 0, 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From 98.0 onwards inlined colorcodes reuse the currently set alpha value.&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Admin:Rapid&amp;diff=1786</id>
		<title>Admin:Rapid</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Admin:Rapid&amp;diff=1786"/>
		<updated>2019-07-27T08:00:47Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* How to add a rapid repository */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==How to add a rapid repository==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /home/packages/git&lt;br /&gt;
git clone git://github.com/ZeroK-RTS/Zero-K.git zk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(git:// should be prefered as it uses less resources when its updated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vi forceupdate.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
adjust the line &amp;quot;for REPO in /home/packages/git/zk ;&amp;quot; to the path which was added, run it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./forceupdate.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
this should create the folder /home/packages/www/zk.&lt;br /&gt;
&lt;br /&gt;
then repos.gz must be updated:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /home/packages/www/repos.springrts.com&lt;br /&gt;
./update-repos.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Administration]]&lt;br /&gt;
[[Category:Download Systems]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Admin:Rapid&amp;diff=1785</id>
		<title>Admin:Rapid</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Admin:Rapid&amp;diff=1785"/>
		<updated>2019-07-27T07:46:47Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==How to add a rapid repository==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /home/packages/git&lt;br /&gt;
git clone git://github.com/ZeroK-RTS/Zero-K.git zk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(git:// should be prefered as it uses less resources when its updated)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vi forceupdate.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
adjust the line &amp;quot;for REPO in /home/packages/git/zk ;&amp;quot; to the path which was added, run it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./forceupdate.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
this should create the folder /home/packages/www/zk.&lt;br /&gt;
&lt;br /&gt;
then repos.gz must be updated:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/packages/www/repos.springrts.com&lt;br /&gt;
./update-repos.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Administration]]&lt;br /&gt;
[[Category:Download Systems]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_VFS&amp;diff=12474</id>
		<title>Lua VFS</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_VFS&amp;diff=12474"/>
		<updated>2019-04-21T04:00:11Z</updated>

		<summary type="html">&lt;p&gt;Gajop: Add two additional functions that exist in develop/maintenance branches.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
= Modes =&lt;br /&gt;
&#039;&#039;&#039;VFS.RAW&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.MOD&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.MAP&#039;&#039;&#039;  {{new|104.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.BASE&#039;&#039;&#039;  {{new|104.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.MENU&#039;&#039;&#039;  {{new|104.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.ZIP&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.RAW_FIRST&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.ZIP_FIRST&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.RAW_ONLY&#039;&#039;&#039; &amp;lt;font color=#55ee99&amp;gt;(same as VFS.RAW)&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.ZIP_ONLY&#039;&#039;&#039; &amp;lt;font color=#55ee99&amp;gt;(same as VFS.ZIP)&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Files =&lt;br /&gt;
&#039;&#039;&#039;VFS.Include&#039;&#039;&#039; &amp;lt;span class=note&amp;gt;(if enviroment=nil then use current one)&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, table enviroment = nil [, number mode ] ] ) -&amp;gt;&lt;br /&gt;
&amp;lt;span class=note&amp;gt;The environment arg sets the global environment (see generic lua refs). In almost all cases, this should be left nil to preserve Springs default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;VFS modes are single char strings and can be concatenated; doing specifies an order of preference for the mode (=location) from which to include files.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.LoadFile&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ] ) -&amp;gt; nil | string data&lt;br /&gt;
&#039;&#039;&#039;VFS.FileExists&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ] ) -&amp;gt; boolean&lt;br /&gt;
&amp;lt;span class=note&amp;gt;example usage: if VFS.FileExists(&amp;quot;maps/Castles.sdz&amp;quot;) then ... end &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.DirList&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;directory&amp;quot; [, string &amp;quot;pattern&amp;quot; = &amp;quot;*&amp;quot;  [, number mode ] ] )&lt;br /&gt;
    -&amp;gt; { [1] = string filename, ... }&lt;br /&gt;
&#039;&#039;&#039;VFS.SubDirs&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;directory&amp;quot;, [, string &amp;quot;pattern&amp;quot; = &amp;quot;*&amp;quot;  [, number mode ] ] )&lt;br /&gt;
    -&amp;gt; { [1] = string subdir1, ... }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetAvailableAIs&#039;&#039;&#039;&lt;br /&gt;
  ( [ string gameName] [, string mapName ] )&lt;br /&gt;
    -&amp;gt; { ai1, ai2, ... }&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Gets a list of all Spring AIs. The optional gameName and mapName parameters can be used to include game/map specific LuaAIs in the list.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UseArchive&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ], lua_function [, arg1 [,arg2 ]] )&lt;br /&gt;
    -&amp;gt; result1,result2,... of the given lua_function&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Loads an archive &#039;&#039;&#039;temporarely&#039;&#039;&#039; in the VFS and then runs the given lua_function,&amp;lt;br&amp;gt;which can make usage of the files in the archive.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.MapArchive&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename/modname of archive&amp;quot;, [string checksum of archive] )&lt;br /&gt;
    -&amp;gt; bool&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Permanently loads an archive into the VFS (to load zipped music collections etc.). &amp;lt;br&amp;gt; Does nothing if the archive is already loaded in the VFS (won&#039;t reload even if there are &amp;lt;br&amp;gt; changes made to the archive). If checksum is given it checks if the to be loaded file is correct,&amp;lt;br&amp;gt;if not then it won&#039;t load it and return false.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnmapArchive&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only! available in 98.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename/modname of archive&amp;quot;)&lt;br /&gt;
    -&amp;gt; bool&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Removes an already loaded archive (see VFS.MapArchive)&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.CompressFolder&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;folderPath&amp;quot; [, string &amp;quot;archiveType&amp;quot; ] [, string &amp;quot;compressedFilePath&amp;quot; ] &amp;lt;br&amp;gt; [, bool includeFolder ] [, number mode ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Compresses the specified folder. &amp;lt;br&amp;gt;archiveType defines the compression type which can currently be only &amp;quot;zip&amp;quot; &amp;lt;br&amp;gt;includeFolder specifies whether the archive should have the specified folder as root (defaults to false) &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetFileAbsolutePath&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only! available in 105.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ] ) -&amp;gt; absPath | nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveContainingFile&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only! available in 105.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ] ) -&amp;gt; archiveNameWithVersion | nil&lt;br /&gt;
&lt;br /&gt;
= Generic hash =&lt;br /&gt;
&#039;&#039;&#039;VFS.CalculateHash&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( string input, number hashType)&lt;br /&gt;
    -&amp;gt; string md5hash&lt;br /&gt;
&lt;br /&gt;
Calculates hash (in base64 form) of a given string (with md5 support initially). Note supplying 0 (MD5) as hashType is mandatory&lt;br /&gt;
&lt;br /&gt;
= Archives =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetMaps&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( ) -&amp;gt; {&lt;br /&gt;
   [1] = string mapName, ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetGames&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( ) -&amp;gt; {&lt;br /&gt;
   [1] = string gameName, ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetAllArchives&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( ) -&amp;gt; {&lt;br /&gt;
   [1] = string archiveName, ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetLoadedArchives&#039;&#039;&#039; {{new|105.0}}&lt;br /&gt;
  ( ) -&amp;gt; {&lt;br /&gt;
   [1] = string archiveName, ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchivePath&#039;&#039;&#039; {{new|105.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; string archivePathOnDisk&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetNameFromRapidTag&#039;&#039;&#039; {{new|105.0}}&lt;br /&gt;
  ( string rapidTag ) -&amp;gt; string archiveName&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.HasArchive&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveInfo&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) - &amp;gt;&lt;br /&gt;
     {        &lt;br /&gt;
          name = string,&lt;br /&gt;
          shortname = string,&lt;br /&gt;
          version = string,&lt;br /&gt;
          mutator = string,&lt;br /&gt;
          game = string,&lt;br /&gt;
          shortgame = string,&lt;br /&gt;
          description = string,&lt;br /&gt;
          mapfile = string,&lt;br /&gt;
          modtype = number,     &lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;modtype values:1=primary, 0=hidden, 3=map&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveChecksum&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; string singleArchiveChecksum, string completeArchiveChecksum&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveDependencies&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; { &lt;br /&gt;
    [1] = string archiveName, ... &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveReplaces&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; { &lt;br /&gt;
    [1] = string archiveName, ... &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.DownloadArchive&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( name, category ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Category must be one of: map, game, engine.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.AbortDownload&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( id ) -&amp;gt; boolean foundAndRemoved&lt;br /&gt;
&lt;br /&gt;
Additional functions are available as part of the [[Lua_UnsyncedCtrl#.28Virtual-.29FileSystem|unsynced ctrl]].&lt;br /&gt;
&lt;br /&gt;
= Packing =&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot; style=&amp;quot;font-size:110%&amp;quot;&amp;gt;The Pack- and Unpack-functions are used to convert numbers-&amp;gt;strings and strings-&amp;gt;numbers.&lt;br /&gt;
So you can read a binary file and then convert the received strings back to numbers and the other way around. Also you can use it in combination with the SendLuaXYZMsg-functions.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackU8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackU16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackU32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackS8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackS16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackS32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackF32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;arguments are:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackX( number arg1, number arg2, number arg3, ... )&#039;&#039;&#039; -&amp;gt; string&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackX( {[1]=number,[2]=number,..} )&#039;&#039;&#039; -&amp;gt; string&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackU8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackU16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackU32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackS8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackS16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackS32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackF32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;arguments are:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackX( string &amp;quot;binary&amp;quot; [, number position = 1] [, number count] )&#039;&#039;&#039;&lt;br /&gt;
  -&amp;gt; number | table { [1]=number,[2]=number,.. }&lt;br /&gt;
&lt;br /&gt;
= Zlib =&lt;br /&gt;
&#039;&#039;&#039;VFS.ZlibCompress&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;uncompressedStr&amp;quot; )&lt;br /&gt;
    -&amp;gt; nil | string &amp;quot;compressedStr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.ZlibDecompress&#039;&#039;&#039; &amp;lt;span class=note&amp;gt;available in synced, too!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;compressedStr&amp;quot; [, number uncompressed size = 65500] )&lt;br /&gt;
    -&amp;gt; nil | string &amp;quot;uncompressedStr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_VFS&amp;diff=12473</id>
		<title>Lua VFS</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_VFS&amp;diff=12473"/>
		<updated>2019-04-05T23:26:09Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
= Modes =&lt;br /&gt;
&#039;&#039;&#039;VFS.RAW&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.MOD&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.MAP&#039;&#039;&#039;  {{new|104.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.BASE&#039;&#039;&#039;  {{new|104.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.MENU&#039;&#039;&#039;  {{new|104.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.ZIP&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.RAW_FIRST&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.ZIP_FIRST&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.RAW_ONLY&#039;&#039;&#039; &amp;lt;font color=#55ee99&amp;gt;(same as VFS.RAW)&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.ZIP_ONLY&#039;&#039;&#039; &amp;lt;font color=#55ee99&amp;gt;(same as VFS.ZIP)&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Files =&lt;br /&gt;
&#039;&#039;&#039;VFS.Include&#039;&#039;&#039; &amp;lt;span class=note&amp;gt;(if enviroment=nil then use current one)&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, table enviroment = nil [, number mode ] ] ) -&amp;gt;&lt;br /&gt;
&amp;lt;span class=note&amp;gt;The environment arg sets the global environment (see generic lua refs). In almost all cases, this should be left nil to preserve Springs default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;VFS modes are single char strings and can be concatenated; doing specifies an order of preference for the mode (=location) from which to include files.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.LoadFile&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ] ) -&amp;gt; nil | string data&lt;br /&gt;
&#039;&#039;&#039;VFS.FileExists&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ] ) -&amp;gt; boolean&lt;br /&gt;
&amp;lt;span class=note&amp;gt;example usage: if VFS.FileExists(&amp;quot;maps/Castles.sdz&amp;quot;) then ... end &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.DirList&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;directory&amp;quot; [, string &amp;quot;pattern&amp;quot; = &amp;quot;*&amp;quot;  [, number mode ] ] )&lt;br /&gt;
    -&amp;gt; { [1] = string filename, ... }&lt;br /&gt;
&#039;&#039;&#039;VFS.SubDirs&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;directory&amp;quot;, [, string &amp;quot;pattern&amp;quot; = &amp;quot;*&amp;quot;  [, number mode ] ] )&lt;br /&gt;
    -&amp;gt; { [1] = string subdir1, ... }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetAvailableAIs&#039;&#039;&#039;&lt;br /&gt;
  ( [ string gameName] [, string mapName ] )&lt;br /&gt;
    -&amp;gt; { ai1, ai2, ... }&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Gets a list of all Spring AIs. The optional gameName and mapName parameters can be used to include game/map specific LuaAIs in the list.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UseArchive&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ], lua_function [, arg1 [,arg2 ]] )&lt;br /&gt;
    -&amp;gt; result1,result2,... of the given lua_function&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Loads an archive &#039;&#039;&#039;temporarely&#039;&#039;&#039; in the VFS and then runs the given lua_function,&amp;lt;br&amp;gt;which can make usage of the files in the archive.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.MapArchive&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename/modname of archive&amp;quot;, [string checksum of archive] )&lt;br /&gt;
    -&amp;gt; bool&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Permanently loads an archive into the VFS (to load zipped music collections etc.). &amp;lt;br&amp;gt; Does nothing if the archive is already loaded in the VFS (won&#039;t reload even if there are &amp;lt;br&amp;gt; changes made to the archive). If checksum is given it checks if the to be loaded file is correct,&amp;lt;br&amp;gt;if not then it won&#039;t load it and return false.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnmapArchive&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only! available in 98.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename/modname of archive&amp;quot;)&lt;br /&gt;
    -&amp;gt; bool&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Removes an already loaded archive (see VFS.MapArchive)&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.CompressFolder&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;folderPath&amp;quot; [, string &amp;quot;archiveType&amp;quot; ] [, string &amp;quot;compressedFilePath&amp;quot; ] &amp;lt;br&amp;gt; [, bool includeFolder ] [, number mode ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Compresses the specified folder. &amp;lt;br&amp;gt;archiveType defines the compression type which can currently be only &amp;quot;zip&amp;quot; &amp;lt;br&amp;gt;includeFolder specifies whether the archive should have the specified folder as root (defaults to false) &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetFileAbsolutePath&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only! available in 105.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ] ) -&amp;gt; absPath | nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveContainingFile&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only! available in 105.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;filename&amp;quot; [, number mode ] ) -&amp;gt; archiveNameWithVersion | nil&lt;br /&gt;
&lt;br /&gt;
= Generic hash =&lt;br /&gt;
&#039;&#039;&#039;VFS.CalculateHash&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( string input, number hashType)&lt;br /&gt;
    -&amp;gt; string md5hash&lt;br /&gt;
&lt;br /&gt;
Calculates hash (in base64 form) of a given string (with md5 support initially). Note supplying 0 (MD5) as hashType is mandatory&lt;br /&gt;
&lt;br /&gt;
= Archives =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetMaps&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( ) -&amp;gt; {&lt;br /&gt;
   [1] = string mapName, ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetGames&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( ) -&amp;gt; {&lt;br /&gt;
   [1] = string gameName, ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetAllArchives&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( ) -&amp;gt; {&lt;br /&gt;
   [1] = string archiveName, ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.HasArchive&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveInfo&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) - &amp;gt;&lt;br /&gt;
     {        &lt;br /&gt;
          name = string,&lt;br /&gt;
          shortname = string,&lt;br /&gt;
          version = string,&lt;br /&gt;
          mutator = string,&lt;br /&gt;
          game = string,&lt;br /&gt;
          shortgame = string,&lt;br /&gt;
          description = string,&lt;br /&gt;
          mapfile = string,&lt;br /&gt;
          modtype = number,     &lt;br /&gt;
      }&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;modtype values:1=primary, 0=hidden, 3=map&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveChecksum&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; string singleArchiveChecksum, string completeArchiveChecksum&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveDependencies&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; { &lt;br /&gt;
    [1] = string archiveName, ... &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.GetArchiveReplaces&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string archiveName ) -&amp;gt; { &lt;br /&gt;
    [1] = string archiveName, ... &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.DownloadArchive&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( name, category ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Category must be one of: map, game, engine.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.AbortDownload&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( id ) -&amp;gt; boolean foundAndRemoved&lt;br /&gt;
&lt;br /&gt;
Additional functions are available as part of the [[Lua_UnsyncedCtrl#.28Virtual-.29FileSystem|unsynced ctrl]].&lt;br /&gt;
&lt;br /&gt;
= Packing =&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot; style=&amp;quot;font-size:110%&amp;quot;&amp;gt;The Pack- and Unpack-functions are used to convert numbers-&amp;gt;strings and strings-&amp;gt;numbers.&lt;br /&gt;
So you can read a binary file and then convert the received strings back to numbers and the other way around. Also you can use it in combination with the SendLuaXYZMsg-functions.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackU8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackU16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackU32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackS8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackS16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackS32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackF32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;arguments are:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackX( number arg1, number arg2, number arg3, ... )&#039;&#039;&#039; -&amp;gt; string&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.PackX( {[1]=number,[2]=number,..} )&#039;&#039;&#039; -&amp;gt; string&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackU8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackU16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackU32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackS8&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackS16&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackS32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackF32&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=note&amp;gt;arguments are:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.UnpackX( string &amp;quot;binary&amp;quot; [, number position = 1] [, number count] )&#039;&#039;&#039;&lt;br /&gt;
  -&amp;gt; number | table { [1]=number,[2]=number,.. }&lt;br /&gt;
&lt;br /&gt;
= Zlib =&lt;br /&gt;
&#039;&#039;&#039;VFS.ZlibCompress&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;unsynced only!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;uncompressedStr&amp;quot; )&lt;br /&gt;
    -&amp;gt; nil | string &amp;quot;compressedStr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VFS.ZlibDecompress&#039;&#039;&#039; &amp;lt;span class=note&amp;gt;available in synced, too!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;compressedStr&amp;quot; [, number uncompressed size = 65500] )&lt;br /&gt;
    -&amp;gt; nil | string &amp;quot;uncompressedStr&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Script.txt&amp;diff=16317</id>
		<title>Script.txt</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Script.txt&amp;diff=16317"/>
		<updated>2019-01-15T15:49:15Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Script.txt =&lt;br /&gt;
Start script file for Spring Engine. &lt;br /&gt;
&lt;br /&gt;
Lobbies create it for spring, usually found in &amp;lt;code&amp;gt;~/.spring/script.txt&amp;lt;/code&amp;gt; on Linux/MacOSX.&lt;br /&gt;
&lt;br /&gt;
On Windows it can be found mostly in &amp;lt;code&amp;gt;My Documents\My Games\Spring\script.txt&amp;lt;/code&amp;gt; or next to spring.exe.&lt;br /&gt;
&lt;br /&gt;
== Structure ==&lt;br /&gt;
See {{sourcelink|file=doc/StartScriptFormat.txt}} for a more detailed example.&lt;br /&gt;
&lt;br /&gt;
Spring 97.0 added &amp;lt;code&amp;gt;GAME/MUTATOR{0..9}&amp;lt;/code&amp;gt; so you can load arbitrary mutator archives before the game. Additionally since 97.0 &amp;lt;code&amp;gt;GAME/GameID&amp;lt;/code&amp;gt; is the only seed of the synced random generator, so you can define the &amp;lt;code&amp;gt;GameID&amp;lt;/code&amp;gt; in a luaAI battle startscript and you will always get a syncing match.&lt;br /&gt;
&lt;br /&gt;
Since 99.0 &amp;lt;code&amp;gt;GAME/Gametype&amp;lt;/code&amp;gt; can be a [[rapid]] tag, and demo recording can be disabled by setting &amp;lt;code&amp;gt;GAME/RecordDemo&amp;lt;/code&amp;gt; to 0&lt;br /&gt;
&lt;br /&gt;
Since 102.0 &amp;lt;code&amp;gt;GAME/SaveFile&amp;lt;/code&amp;gt; can be specified in start script in order to start from a (lua) save (.slsf).&lt;br /&gt;
&lt;br /&gt;
Overview of the structure:&lt;br /&gt;
&amp;lt;pre&amp;gt;[GAME]&lt;br /&gt;
{&lt;br /&gt;
  // game attributes&lt;br /&gt;
  [MUTATOR0]&lt;br /&gt;
  {&lt;br /&gt;
    // mutator attributes&lt;br /&gt;
  }&lt;br /&gt;
  [AI0]&lt;br /&gt;
  {&lt;br /&gt;
    // AI attributes&lt;br /&gt;
  }&lt;br /&gt;
  [PLAYER0]&lt;br /&gt;
  {&lt;br /&gt;
    // player attributes&lt;br /&gt;
  }&lt;br /&gt;
  [TEAM0]&lt;br /&gt;
  {&lt;br /&gt;
    // team attributes&lt;br /&gt;
  }&lt;br /&gt;
  [ALLYTEAM0]&lt;br /&gt;
  {&lt;br /&gt;
    // ally team attributes&lt;br /&gt;
  }&lt;br /&gt;
  [RESTRICT]&lt;br /&gt;
  {&lt;br /&gt;
    // restrictions&lt;br /&gt;
  }&lt;br /&gt;
  [MODOPTIONS]&lt;br /&gt;
  {&lt;br /&gt;
    // values for the options defined in Modoptions.lua&lt;br /&gt;
  }&lt;br /&gt;
  [MAPOPTIONS]&lt;br /&gt;
  {&lt;br /&gt;
    // values for the options defined in Mapoptions.lua&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
== minimal functional startscript ==&lt;br /&gt;
Based on {{forumlink|topic=32893&amp;amp;p=566971#p566953|title=these two posts:}} &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[GAME]&lt;br /&gt;
{&lt;br /&gt;
	MapName=DeltaSiegeDry;&lt;br /&gt;
	GameType=Balanced Annihilation V8.10;&lt;br /&gt;
	IsHost=1;&lt;br /&gt;
	[PLAYER0]&lt;br /&gt;
	{&lt;br /&gt;
		Team=0;&lt;br /&gt;
	}&lt;br /&gt;
	[TEAM0]&lt;br /&gt;
	{&lt;br /&gt;
		TeamLeader=0;&lt;br /&gt;
		AllyTeam=0;&lt;br /&gt;
	}&lt;br /&gt;
	[ALLYTEAM0]&lt;br /&gt;
	{&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== More examples ==&lt;br /&gt;
startscripts used for pre-defined offline matches vs AI in different team configurations -  &lt;br /&gt;
https://code.google.com/p/springtanks/source/browse/#svn%2Ftrunk%2FMissions&lt;br /&gt;
&lt;br /&gt;
= Generating startscripts =&lt;br /&gt;
It is possible to use for example Springlobby to setup a game via the Singleplayer tab.&lt;br /&gt;
&lt;br /&gt;
The temporary file that gets generated can be copied for further use.&lt;br /&gt;
&lt;br /&gt;
== Converting Lua tables to script.txt format ==&lt;br /&gt;
&lt;br /&gt;
{{forumlink|topic=32643|title=lua table -&amp;gt; script.txt generator}} - thread with two examples&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:Tutorial_Simple&amp;diff=13755</id>
		<title>Mapdev:Tutorial Simple</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:Tutorial_Simple&amp;diff=13755"/>
		<updated>2019-01-02T03:49:24Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Edit mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Beginners Tutorial Stage 1 =&lt;br /&gt;
This beginners tutorial is aimed at getting you from nothing, to something simple which you can build upon.&lt;br /&gt;
&lt;br /&gt;
* We&#039;ll start with the height map, defining the structure of the terrain&lt;br /&gt;
* Then the metalmap, a resource scheme built into the spring engine&lt;br /&gt;
* The diffuse texture, defining the colour of the terrain&lt;br /&gt;
* The minimap, for when selecting the map in the game lobby&lt;br /&gt;
* The grass map, for that extra flourish of detail&lt;br /&gt;
* Finally set up the start positions&lt;br /&gt;
&lt;br /&gt;
= What you will need =&lt;br /&gt;
* An image editor, such as [http://www.gimp.org/ GIMP] or [http://www.adobe.com/products/photoshop.html Adobe Photoshop], [http://en.wikipedia.org/wiki/List_of_raster_graphics_editors#List etc]&lt;br /&gt;
* [http://www.7-zip.org/ 7zip]&lt;br /&gt;
* Windows - [[MapConv]], Linux - [[MapConvNG]]&lt;br /&gt;
* a copy of the map blueprint [https://github.com/jk3064/Map-Blueprint/archive/master.zip archive]&lt;br /&gt;
&lt;br /&gt;
There are a multitude of other tools you can use to make maps, however for the purposes of this beginners tutorial, these are the only ones you will need. Check the [[Mapdev:Main#Tools|tools]] section for more information.&lt;br /&gt;
&lt;br /&gt;
= Download =&lt;br /&gt;
* [http://springfiles.com/spring/other/mapdev-stage1-working-files Download] the working  files&lt;br /&gt;
* [http://springfiles.com/spring/spring-maps/mapdev-stage1 Download] the completed map archive&lt;br /&gt;
&lt;br /&gt;
= Preparation =&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Extract the mapcontainer.sdd folder from the blueprint archive into your working directory.&amp;lt;/li&amp;gt;&lt;br /&gt;
Your directory structure should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;working directory&lt;br /&gt;
  |-mapcontainer.sdd/&lt;br /&gt;
    |-LuaGaia/&lt;br /&gt;
    |-mapconfig/&lt;br /&gt;
    |-maphelper/&lt;br /&gt;
    |-maps/&lt;br /&gt;
    |-mapinfo.lua&lt;br /&gt;
    |-mapoptions.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;    &lt;br /&gt;
&amp;lt;li&amp;gt;Rename the mapcontainer.sdd folder to the name of your map, eg. mymap.sdd&lt;br /&gt;
&amp;lt;li&amp;gt;Edit the following variables in the mapinfo.lua file, ignore the rest for now.&lt;br /&gt;
* name&lt;br /&gt;
* shortname&lt;br /&gt;
* description&lt;br /&gt;
* author&lt;br /&gt;
* version (just put like v1 or something in here)&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Height map =&lt;br /&gt;
For this tutorial we will be creating a 4x4 size map, which is relatively small. Typically maps will be 8x8 (for a 1v1) or larger, but entirely depends on the game you are targeting.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:height|height]] page to get our image dimensions. In our case a 4x4 map yields a image resolution of 257x257 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 257x257 greyscale image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Draw the terrain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it heightmap.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{Tip|Black represents the lowest elevation on the map, white represents the highest, in between lies all the shades of grey. Hard edges in the image will be cliffs, and smooth gradients will be ramps.}}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-height.png|256px]] || [[File:Mapdev-height-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Height Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
== Edit mapinfo.lua ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Change the &amp;lt;code&amp;gt;minHeight&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;maxHeight&amp;lt;/code&amp;gt; variables to &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;256&amp;lt;/code&amp;gt; respectively&amp;lt;br&amp;gt;&lt;br /&gt;
These values control the overall height of the terrain, and will be unique to your map. After loading up the map in game you may want to revisit and tweak these values to get the best result.&amp;lt;br&amp;gt;&lt;br /&gt;
The resulting portion of code should appear like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   smf = {&lt;br /&gt;
      minHeight = 10,&lt;br /&gt;
      maxHeight = 256,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Metal Map =&lt;br /&gt;
{{Caution|There are several games for Spring which use their own resourcing system. If you are creating a map for one of those games, a metal map may not be necessary, however it is always nice if you can make your maps as compatible with other games as possible, but this is a choice left entirely up to you.}}&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:metal|metal]] page to get our image dimensions. In our case a 4x4 map yields an image resolution of 128x128 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 128x128 RGB image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Paint the whole image black&lt;br /&gt;
&amp;lt;li&amp;gt;Paint full red spots 6 or so pixels in diameter on the places where you want metal to appear in game.&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it metalmap.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-metal.png|256px]] || [[File:Mapdev-metal-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Metal Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
== Edit mapinfo.lua ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Change the &amp;lt;code&amp;gt;maxMetal &amp;lt;/code&amp;gt; and the &amp;lt;code&amp;gt;extractorRadius&amp;lt;/code&amp;gt; variables to &amp;lt;code&amp;gt;6.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;32.0&amp;lt;/code&amp;gt; respectively&amp;lt;br&amp;gt;&lt;br /&gt;
These variables control the maximum amount of metal that a metal extractor can extract at full capacity, and  the radius that a metal extractor will be able to draw from.&amp;lt;br&amp;gt;&lt;br /&gt;
The resulting portion of code will appear thus:&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   maxMetal = 6.0,&lt;br /&gt;
   extractorRadius = 32.0,&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Diffuse Texture =&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:diffuse|diffuse]] page to get our image dimensions. In our case a 4x4 map yields an image resolution of 2048x2048 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 2048x2048 RGB image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Paint your ground colour in such a way that it compliments the height of the terrain, and metal spots.&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it diffuse.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{Tip|It may be useful to use the heightmap.png and metalmap.png images as a starting points, scaling them up to size, and then painting over the top.}}&lt;br /&gt;
{{Caution|The larger the map the greater the file size this texture will be, a 4x4 map at 2048x2048 the diffuse texture image is already at 5.4mb, imagine a 32x32 size map, it would be in the hundreds of megabytes. Working with large textures is difficult, and requires good hardware. }}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-diffuse.jpg]] || [[File:Mapdev-diffuse-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Diffuse Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Mini Map =&lt;br /&gt;
The [[Mapdev:minimap|mini-map]] is a thumbnail image of the the whole map displayed in lobbies when selecting maps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Load up your diffuse.png image&lt;br /&gt;
&amp;lt;li&amp;gt;Scale the image to exactly 1024x1024 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it mini.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Grass Map =&lt;br /&gt;
Grass adds additional depth to your map, giving it a little bit extra.&lt;br /&gt;
# Check the [[Mapdev:grass|grass]] page to get our image dimensions. In our case a 4x4 map yields a image resolution of 64x64 pixels&lt;br /&gt;
# Create a 64x64 RGB image using your image editor&lt;br /&gt;
# Paint the image fully black to begin with&lt;br /&gt;
# Paint varying strengths of blue for where you want the grass to show up.&lt;br /&gt;
# Save the image to your working directory, call it grassmap.png&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-grass.png]] || [[File:Mapdev-grass-example.png|455px]]&lt;br /&gt;
|-&lt;br /&gt;
! Grass map !! In Game Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Define Start Positions =&lt;br /&gt;
considering the small size of the map we will only define two teams&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Locate the teams subtable and delete the lines for teams 2 and 3&lt;br /&gt;
&amp;lt;li&amp;gt;Edit the &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; coordinate for each team to define their start location&amp;lt;br&amp;gt;&lt;br /&gt;
The coordinates for spring relate 1:1 with the pixels in the diffuse map. Starting at the top left of the image at (0,0). &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; increases horizontally to the right, &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; increases vertically downwards.&amp;lt;br&amp;gt;&lt;br /&gt;
The code should look similar to this:&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
  ...&lt;br /&gt;
  teams = {&lt;br /&gt;
    [0] = {startPos = {x = 256, z = 1024}},&lt;br /&gt;
    [1] = {startPos = {x = 1792, z = 1024}},&lt;br /&gt;
  },&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| [[File:Mapdev-coords.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Coordinates&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review =&lt;br /&gt;
From the tutorial we have learned how to make the:&lt;br /&gt;
* Height map&lt;br /&gt;
* Diffuse texture&lt;br /&gt;
* Metal map&lt;br /&gt;
* Mini map&lt;br /&gt;
* Grass map&lt;br /&gt;
* Start locations&lt;br /&gt;
&lt;br /&gt;
Your directory structure should look similar to this:&lt;br /&gt;
&amp;lt;pre&amp;gt;working directory&lt;br /&gt;
  |-mymapname.sdd/&lt;br /&gt;
  | |-LuaGaia/&lt;br /&gt;
  | |-mapconfig/&lt;br /&gt;
  | |-maphelper/&lt;br /&gt;
  | |-maps/&lt;br /&gt;
  | |-mapinfo.lua&lt;br /&gt;
  | |-mapoptions.lua&lt;br /&gt;
  |-grassmap.png&lt;br /&gt;
  |-heightmap.png&lt;br /&gt;
  |-metalmap.png&lt;br /&gt;
  |-diffuse.png&lt;br /&gt;
  |-minimap.png&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we need to get the map loaded into the game&lt;br /&gt;
&lt;br /&gt;
= Finalizing =&lt;br /&gt;
Continue to [[Mapdev:Tutorial_Finalizing|this page]] to compile, test and archive your map for distribution.&lt;br /&gt;
&lt;br /&gt;
= I want more =&lt;br /&gt;
Continue to [[Mapdev:Tutorial_Intermediate|stage two]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:Tutorial_Simple&amp;diff=13754</id>
		<title>Mapdev:Tutorial Simple</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:Tutorial_Simple&amp;diff=13754"/>
		<updated>2019-01-02T03:49:17Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Edit mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Beginners Tutorial Stage 1 =&lt;br /&gt;
This beginners tutorial is aimed at getting you from nothing, to something simple which you can build upon.&lt;br /&gt;
&lt;br /&gt;
* We&#039;ll start with the height map, defining the structure of the terrain&lt;br /&gt;
* Then the metalmap, a resource scheme built into the spring engine&lt;br /&gt;
* The diffuse texture, defining the colour of the terrain&lt;br /&gt;
* The minimap, for when selecting the map in the game lobby&lt;br /&gt;
* The grass map, for that extra flourish of detail&lt;br /&gt;
* Finally set up the start positions&lt;br /&gt;
&lt;br /&gt;
= What you will need =&lt;br /&gt;
* An image editor, such as [http://www.gimp.org/ GIMP] or [http://www.adobe.com/products/photoshop.html Adobe Photoshop], [http://en.wikipedia.org/wiki/List_of_raster_graphics_editors#List etc]&lt;br /&gt;
* [http://www.7-zip.org/ 7zip]&lt;br /&gt;
* Windows - [[MapConv]], Linux - [[MapConvNG]]&lt;br /&gt;
* a copy of the map blueprint [https://github.com/jk3064/Map-Blueprint/archive/master.zip archive]&lt;br /&gt;
&lt;br /&gt;
There are a multitude of other tools you can use to make maps, however for the purposes of this beginners tutorial, these are the only ones you will need. Check the [[Mapdev:Main#Tools|tools]] section for more information.&lt;br /&gt;
&lt;br /&gt;
= Download =&lt;br /&gt;
* [http://springfiles.com/spring/other/mapdev-stage1-working-files Download] the working  files&lt;br /&gt;
* [http://springfiles.com/spring/spring-maps/mapdev-stage1 Download] the completed map archive&lt;br /&gt;
&lt;br /&gt;
= Preparation =&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Extract the mapcontainer.sdd folder from the blueprint archive into your working directory.&amp;lt;/li&amp;gt;&lt;br /&gt;
Your directory structure should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;working directory&lt;br /&gt;
  |-mapcontainer.sdd/&lt;br /&gt;
    |-LuaGaia/&lt;br /&gt;
    |-mapconfig/&lt;br /&gt;
    |-maphelper/&lt;br /&gt;
    |-maps/&lt;br /&gt;
    |-mapinfo.lua&lt;br /&gt;
    |-mapoptions.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;    &lt;br /&gt;
&amp;lt;li&amp;gt;Rename the mapcontainer.sdd folder to the name of your map, eg. mymap.sdd&lt;br /&gt;
&amp;lt;li&amp;gt;Edit the following variables in the mapinfo.lua file, ignore the rest for now.&lt;br /&gt;
* name&lt;br /&gt;
* shortname&lt;br /&gt;
* description&lt;br /&gt;
* author&lt;br /&gt;
* version (just put like v1 or something in here)&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Height map =&lt;br /&gt;
For this tutorial we will be creating a 4x4 size map, which is relatively small. Typically maps will be 8x8 (for a 1v1) or larger, but entirely depends on the game you are targeting.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:height|height]] page to get our image dimensions. In our case a 4x4 map yields a image resolution of 257x257 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 257x257 greyscale image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Draw the terrain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it heightmap.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{Tip|Black represents the lowest elevation on the map, white represents the highest, in between lies all the shades of grey. Hard edges in the image will be cliffs, and smooth gradients will be ramps.}}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-height.png|256px]] || [[File:Mapdev-height-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Height Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
== Edit mapinfo.lua ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Change the &amp;lt;code&amp;gt;minHeight&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;maxHeight&amp;lt;/code&amp;gt; variables to &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;256&amp;lt;/code&amp;gt; respectively&amp;lt;br&amp;gt;&lt;br /&gt;
These values control the overall height of the terrain, and will be unique to your map. After loading up the map in game you may want to revisit and tweak these values to get the best result.&amp;lt;br&amp;gt;&lt;br /&gt;
The resulting portion of code should appear like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   smf = {&lt;br /&gt;
      minHeight = 10,&lt;br /&gt;
      maxHeight = 256,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Metal Map =&lt;br /&gt;
{{Caution|There are several games for Spring which use their own resourcing system. If you are creating a map for one of those games, a metal map may not be necessary, however it is always nice if you can make your maps as compatible with other games as possible, but this is a choice left entirely up to you.}}&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:metal|metal]] page to get our image dimensions. In our case a 4x4 map yields an image resolution of 128x128 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 128x128 RGB image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Paint the whole image black&lt;br /&gt;
&amp;lt;li&amp;gt;Paint full red spots 6 or so pixels in diameter on the places where you want metal to appear in game.&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it metalmap.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-metal.png|256px]] || [[File:Mapdev-metal-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Metal Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
== Edit mapinfo.lua ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Change the &amp;lt;code&amp;gt;maxMetal &amp;lt;/code&amp;gt; and the &amp;lt;code&amp;gt;extractorRadius&amp;lt;/code&amp;gt; variables to &amp;lt;code&amp;gt;6.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;32.0&amp;lt;/code&amp;gt; respectively&amp;lt;br&amp;gt;&lt;br /&gt;
These variables control the maximum amount of metal that a metal extractor can extract at full capacity, and  the radius that a metal extractor will be able to draw from.&amp;lt;br&amp;gt;&lt;br /&gt;
The resulting portion of code will appear thus:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   maxMetal = 6.0,&lt;br /&gt;
   extractorRadius = 32.0,&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Diffuse Texture =&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:diffuse|diffuse]] page to get our image dimensions. In our case a 4x4 map yields an image resolution of 2048x2048 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 2048x2048 RGB image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Paint your ground colour in such a way that it compliments the height of the terrain, and metal spots.&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it diffuse.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{Tip|It may be useful to use the heightmap.png and metalmap.png images as a starting points, scaling them up to size, and then painting over the top.}}&lt;br /&gt;
{{Caution|The larger the map the greater the file size this texture will be, a 4x4 map at 2048x2048 the diffuse texture image is already at 5.4mb, imagine a 32x32 size map, it would be in the hundreds of megabytes. Working with large textures is difficult, and requires good hardware. }}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-diffuse.jpg]] || [[File:Mapdev-diffuse-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Diffuse Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Mini Map =&lt;br /&gt;
The [[Mapdev:minimap|mini-map]] is a thumbnail image of the the whole map displayed in lobbies when selecting maps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Load up your diffuse.png image&lt;br /&gt;
&amp;lt;li&amp;gt;Scale the image to exactly 1024x1024 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it mini.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Grass Map =&lt;br /&gt;
Grass adds additional depth to your map, giving it a little bit extra.&lt;br /&gt;
# Check the [[Mapdev:grass|grass]] page to get our image dimensions. In our case a 4x4 map yields a image resolution of 64x64 pixels&lt;br /&gt;
# Create a 64x64 RGB image using your image editor&lt;br /&gt;
# Paint the image fully black to begin with&lt;br /&gt;
# Paint varying strengths of blue for where you want the grass to show up.&lt;br /&gt;
# Save the image to your working directory, call it grassmap.png&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-grass.png]] || [[File:Mapdev-grass-example.png|455px]]&lt;br /&gt;
|-&lt;br /&gt;
! Grass map !! In Game Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Define Start Positions =&lt;br /&gt;
considering the small size of the map we will only define two teams&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Locate the teams subtable and delete the lines for teams 2 and 3&lt;br /&gt;
&amp;lt;li&amp;gt;Edit the &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; coordinate for each team to define their start location&amp;lt;br&amp;gt;&lt;br /&gt;
The coordinates for spring relate 1:1 with the pixels in the diffuse map. Starting at the top left of the image at (0,0). &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; increases horizontally to the right, &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; increases vertically downwards.&amp;lt;br&amp;gt;&lt;br /&gt;
The code should look similar to this:&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
  ...&lt;br /&gt;
  teams = {&lt;br /&gt;
    [0] = {startPos = {x = 256, z = 1024}},&lt;br /&gt;
    [1] = {startPos = {x = 1792, z = 1024}},&lt;br /&gt;
  },&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| [[File:Mapdev-coords.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Coordinates&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review =&lt;br /&gt;
From the tutorial we have learned how to make the:&lt;br /&gt;
* Height map&lt;br /&gt;
* Diffuse texture&lt;br /&gt;
* Metal map&lt;br /&gt;
* Mini map&lt;br /&gt;
* Grass map&lt;br /&gt;
* Start locations&lt;br /&gt;
&lt;br /&gt;
Your directory structure should look similar to this:&lt;br /&gt;
&amp;lt;pre&amp;gt;working directory&lt;br /&gt;
  |-mymapname.sdd/&lt;br /&gt;
  | |-LuaGaia/&lt;br /&gt;
  | |-mapconfig/&lt;br /&gt;
  | |-maphelper/&lt;br /&gt;
  | |-maps/&lt;br /&gt;
  | |-mapinfo.lua&lt;br /&gt;
  | |-mapoptions.lua&lt;br /&gt;
  |-grassmap.png&lt;br /&gt;
  |-heightmap.png&lt;br /&gt;
  |-metalmap.png&lt;br /&gt;
  |-diffuse.png&lt;br /&gt;
  |-minimap.png&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we need to get the map loaded into the game&lt;br /&gt;
&lt;br /&gt;
= Finalizing =&lt;br /&gt;
Continue to [[Mapdev:Tutorial_Finalizing|this page]] to compile, test and archive your map for distribution.&lt;br /&gt;
&lt;br /&gt;
= I want more =&lt;br /&gt;
Continue to [[Mapdev:Tutorial_Intermediate|stage two]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:Tutorial_Simple&amp;diff=13753</id>
		<title>Mapdev:Tutorial Simple</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:Tutorial_Simple&amp;diff=13753"/>
		<updated>2019-01-02T03:48:43Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Define Start Positions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Beginners Tutorial Stage 1 =&lt;br /&gt;
This beginners tutorial is aimed at getting you from nothing, to something simple which you can build upon.&lt;br /&gt;
&lt;br /&gt;
* We&#039;ll start with the height map, defining the structure of the terrain&lt;br /&gt;
* Then the metalmap, a resource scheme built into the spring engine&lt;br /&gt;
* The diffuse texture, defining the colour of the terrain&lt;br /&gt;
* The minimap, for when selecting the map in the game lobby&lt;br /&gt;
* The grass map, for that extra flourish of detail&lt;br /&gt;
* Finally set up the start positions&lt;br /&gt;
&lt;br /&gt;
= What you will need =&lt;br /&gt;
* An image editor, such as [http://www.gimp.org/ GIMP] or [http://www.adobe.com/products/photoshop.html Adobe Photoshop], [http://en.wikipedia.org/wiki/List_of_raster_graphics_editors#List etc]&lt;br /&gt;
* [http://www.7-zip.org/ 7zip]&lt;br /&gt;
* Windows - [[MapConv]], Linux - [[MapConvNG]]&lt;br /&gt;
* a copy of the map blueprint [https://github.com/jk3064/Map-Blueprint/archive/master.zip archive]&lt;br /&gt;
&lt;br /&gt;
There are a multitude of other tools you can use to make maps, however for the purposes of this beginners tutorial, these are the only ones you will need. Check the [[Mapdev:Main#Tools|tools]] section for more information.&lt;br /&gt;
&lt;br /&gt;
= Download =&lt;br /&gt;
* [http://springfiles.com/spring/other/mapdev-stage1-working-files Download] the working  files&lt;br /&gt;
* [http://springfiles.com/spring/spring-maps/mapdev-stage1 Download] the completed map archive&lt;br /&gt;
&lt;br /&gt;
= Preparation =&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Extract the mapcontainer.sdd folder from the blueprint archive into your working directory.&amp;lt;/li&amp;gt;&lt;br /&gt;
Your directory structure should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;working directory&lt;br /&gt;
  |-mapcontainer.sdd/&lt;br /&gt;
    |-LuaGaia/&lt;br /&gt;
    |-mapconfig/&lt;br /&gt;
    |-maphelper/&lt;br /&gt;
    |-maps/&lt;br /&gt;
    |-mapinfo.lua&lt;br /&gt;
    |-mapoptions.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;    &lt;br /&gt;
&amp;lt;li&amp;gt;Rename the mapcontainer.sdd folder to the name of your map, eg. mymap.sdd&lt;br /&gt;
&amp;lt;li&amp;gt;Edit the following variables in the mapinfo.lua file, ignore the rest for now.&lt;br /&gt;
* name&lt;br /&gt;
* shortname&lt;br /&gt;
* description&lt;br /&gt;
* author&lt;br /&gt;
* version (just put like v1 or something in here)&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Height map =&lt;br /&gt;
For this tutorial we will be creating a 4x4 size map, which is relatively small. Typically maps will be 8x8 (for a 1v1) or larger, but entirely depends on the game you are targeting.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:height|height]] page to get our image dimensions. In our case a 4x4 map yields a image resolution of 257x257 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 257x257 greyscale image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Draw the terrain&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it heightmap.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{Tip|Black represents the lowest elevation on the map, white represents the highest, in between lies all the shades of grey. Hard edges in the image will be cliffs, and smooth gradients will be ramps.}}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-height.png|256px]] || [[File:Mapdev-height-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Height Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
== Edit mapinfo.lua ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Change the &amp;lt;code&amp;gt;minHeight&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;maxHeight&amp;lt;/code&amp;gt; variables to &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;256&amp;lt;/code&amp;gt; respectively&amp;lt;br&amp;gt;&lt;br /&gt;
These values control the overall height of the terrain, and will be unique to your map. After loading up the map in game you may want to revisit and tweak these values to get the best result.&amp;lt;br&amp;gt;&lt;br /&gt;
The resulting portion of code should appear like this:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   smf = {&lt;br /&gt;
      minHeight = 10,&lt;br /&gt;
      maxHeight = 256,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Metal Map =&lt;br /&gt;
{{Caution|There are several games for Spring which use their own resourcing system. If you are creating a map for one of those games, a metal map may not be necessary, however it is always nice if you can make your maps as compatible with other games as possible, but this is a choice left entirely up to you.}}&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:metal|metal]] page to get our image dimensions. In our case a 4x4 map yields an image resolution of 128x128 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 128x128 RGB image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Paint the whole image black&lt;br /&gt;
&amp;lt;li&amp;gt;Paint full red spots 6 or so pixels in diameter on the places where you want metal to appear in game.&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it metalmap.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-metal.png|256px]] || [[File:Mapdev-metal-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Metal Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
== Edit mapinfo.lua ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Change the &amp;lt;code&amp;gt;maxMetal &amp;lt;/code&amp;gt; and the &amp;lt;code&amp;gt;extractorRadius&amp;lt;/code&amp;gt; variables to &amp;lt;code&amp;gt;6.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;32.0&amp;lt;/code&amp;gt; respectively&amp;lt;br&amp;gt;&lt;br /&gt;
These variables control the maximum amount of metal that a metal extractor can extract at full capacity, and  the radius that a metal extractor will be able to draw from.&amp;lt;br&amp;gt;&lt;br /&gt;
The resulting portion of code will appear thus:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   maxMetal = 6.0,&lt;br /&gt;
   extractorRadius = 32.0,&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Diffuse Texture =&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the [[Mapdev:diffuse|diffuse]] page to get our image dimensions. In our case a 4x4 map yields an image resolution of 2048x2048 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Create a 2048x2048 RGB image using your image editor&lt;br /&gt;
&amp;lt;li&amp;gt;Paint your ground colour in such a way that it compliments the height of the terrain, and metal spots.&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it diffuse.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{Tip|It may be useful to use the heightmap.png and metalmap.png images as a starting points, scaling them up to size, and then painting over the top.}}&lt;br /&gt;
{{Caution|The larger the map the greater the file size this texture will be, a 4x4 map at 2048x2048 the diffuse texture image is already at 5.4mb, imagine a 32x32 size map, it would be in the hundreds of megabytes. Working with large textures is difficult, and requires good hardware. }}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-diffuse.jpg]] || [[File:Mapdev-diffuse-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Diffuse Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Mini Map =&lt;br /&gt;
The [[Mapdev:minimap|mini-map]] is a thumbnail image of the the whole map displayed in lobbies when selecting maps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Load up your diffuse.png image&lt;br /&gt;
&amp;lt;li&amp;gt;Scale the image to exactly 1024x1024 pixels&lt;br /&gt;
&amp;lt;li&amp;gt;Save the image to your working directory, call it mini.png&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Create Grass Map =&lt;br /&gt;
Grass adds additional depth to your map, giving it a little bit extra.&lt;br /&gt;
# Check the [[Mapdev:grass|grass]] page to get our image dimensions. In our case a 4x4 map yields a image resolution of 64x64 pixels&lt;br /&gt;
# Create a 64x64 RGB image using your image editor&lt;br /&gt;
# Paint the image fully black to begin with&lt;br /&gt;
# Paint varying strengths of blue for where you want the grass to show up.&lt;br /&gt;
# Save the image to your working directory, call it grassmap.png&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-grass.png]] || [[File:Mapdev-grass-example.png|455px]]&lt;br /&gt;
|-&lt;br /&gt;
! Grass map !! In Game Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Define Start Positions =&lt;br /&gt;
considering the small size of the map we will only define two teams&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open the mapinfo.lua file in a text editor&lt;br /&gt;
&amp;lt;li&amp;gt;Locate the teams subtable and delete the lines for teams 2 and 3&lt;br /&gt;
&amp;lt;li&amp;gt;Edit the &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; coordinate for each team to define their start location&amp;lt;br&amp;gt;&lt;br /&gt;
The coordinates for spring relate 1:1 with the pixels in the diffuse map. Starting at the top left of the image at (0,0). &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; increases horizontally to the right, &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; increases vertically downwards.&amp;lt;br&amp;gt;&lt;br /&gt;
The code should look similar to this:&lt;br /&gt;
&amp;lt;pre&amp;gt;local mapinfo = {&lt;br /&gt;
  ...&lt;br /&gt;
  teams = {&lt;br /&gt;
    [0] = {startPos = {x = 256, z = 1024}},&lt;br /&gt;
    [1] = {startPos = {x = 1792, z = 1024}},&lt;br /&gt;
  },&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| [[File:Mapdev-coords.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Coordinates&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review =&lt;br /&gt;
From the tutorial we have learned how to make the:&lt;br /&gt;
* Height map&lt;br /&gt;
* Diffuse texture&lt;br /&gt;
* Metal map&lt;br /&gt;
* Mini map&lt;br /&gt;
* Grass map&lt;br /&gt;
* Start locations&lt;br /&gt;
&lt;br /&gt;
Your directory structure should look similar to this:&lt;br /&gt;
&amp;lt;pre&amp;gt;working directory&lt;br /&gt;
  |-mymapname.sdd/&lt;br /&gt;
  | |-LuaGaia/&lt;br /&gt;
  | |-mapconfig/&lt;br /&gt;
  | |-maphelper/&lt;br /&gt;
  | |-maps/&lt;br /&gt;
  | |-mapinfo.lua&lt;br /&gt;
  | |-mapoptions.lua&lt;br /&gt;
  |-grassmap.png&lt;br /&gt;
  |-heightmap.png&lt;br /&gt;
  |-metalmap.png&lt;br /&gt;
  |-diffuse.png&lt;br /&gt;
  |-minimap.png&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we need to get the map loaded into the game&lt;br /&gt;
&lt;br /&gt;
= Finalizing =&lt;br /&gt;
Continue to [[Mapdev:Tutorial_Finalizing|this page]] to compile, test and archive your map for distribution.&lt;br /&gt;
&lt;br /&gt;
= I want more =&lt;br /&gt;
Continue to [[Mapdev:Tutorial_Intermediate|stage two]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:lightemission&amp;diff=13846</id>
		<title>Mapdev:lightemission</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:lightemission&amp;diff=13846"/>
		<updated>2018-12-18T15:39:50Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Light Emission Texture =&lt;br /&gt;
Adds colour to a fragment (pixel). The colour added is the RGB colour of the emission texture, while the alpha of the emission texture determines the amount of the original colour that remains. &lt;br /&gt;
&lt;br /&gt;
Can be used for accentuation. For example, metal spots in shadowed regions&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| &lt;br /&gt;
[[File:Map without light emission.jpg|frameless|Map without light emission]]&lt;br /&gt;
 || &lt;br /&gt;
[[File:Map with light emission.jpg|frameless|Map with light emission]]&lt;br /&gt;
|-&lt;br /&gt;
! Without Light Emission Texture!! With Light Emission Texture&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
The relevant sections of the [[Mapdev:mapinfo.lua|mapinfo.lua]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      lightEmissionTex = &amp;quot;light_emission.png&amp;quot;,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Image File==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGBA&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be stretched over the terrain. Should be the same size as the [[Mapdev:specular]] image&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Modifies the fragment color as follows&lt;br /&gt;
 &lt;br /&gt;
fragmentColor.rgb = fragmentColor.rgb * (1 - lightEmissionTex.a) + lightEmissionTex.rgb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:skyreflectmod&amp;diff=13984</id>
		<title>Mapdev:skyreflectmod</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:skyreflectmod&amp;diff=13984"/>
		<updated>2018-12-18T15:39:39Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Sky Reflection Modifier Texture =&lt;br /&gt;
Sets the weight for mixing the diffuse texture colour with the reflected colour of the sky. This occurs before any other shading calculations use the diffuse colour. &lt;br /&gt;
&lt;br /&gt;
This can be used to suggest a surface composed of reflective materials, such as ice or crystals.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File: skyreflectmod_without_example.png|300px]]|| [[File: skyreflectmod_with_example.png|300px]]&lt;br /&gt;
|-&lt;br /&gt;
! Without Sky Reflection Modifier Map !! With Sky Reflection Modifier Map&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
The relevant sections of the [[Mapdev:mapinfo.lua|mapinfo.lua]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      skyReflectModTex = &amp;quot;skyreflectmod.png&amp;quot;,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Image File==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGB&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be stretched over the terrain. Should be the same size as the [[Mapdev:specular]] image&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Modifies the diffuse colours as follows:&lt;br /&gt;
diffuseColor.r = diffuseColor.r * (1 - skyReflectModTex.r) +&lt;br /&gt;
                   reflectionColor.r * skyReflectModTex.r&lt;br /&gt;
diffuseColor.g = diffuseColor.g * (1 - skyReflectModTex.g) +&lt;br /&gt;
                   reflectionColor.g * skyReflectModTex.g&lt;br /&gt;
diffuseColor.b = diffuseColor.b * (1 - skyReflectModTex.b) +&lt;br /&gt;
                   reflectionColor.b * skyReflectModTex.b&lt;br /&gt;
&lt;br /&gt;
Equivalent to the GLSL code: (diffuseColor is a vector)&lt;br /&gt;
diffuseColor = mix(diffuseColor, reflectionColor, skyReflectModTex)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:normal&amp;diff=13951</id>
		<title>Mapdev:normal</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:normal&amp;diff=13951"/>
		<updated>2018-12-18T15:39:09Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Normal Texture =&lt;br /&gt;
Gives the terrain a normal map. This can be used to suggest small surface details while keeping terrain flat. The RGB channels determine the XYZ of the new surface normal (in tangent space), while the alpha channel determines how much of the original surface normal is kept.&lt;br /&gt;
&lt;br /&gt;
[https://code.google.com/p/gimp-normalmap/ This GIMP plugin] provides various ways to convert heightmaps into normal maps.&lt;br /&gt;
&lt;br /&gt;
{{Caution|Requires clients to have GLSL-spec hardware}}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| {{FIXME}} needs image file || {{FIXME}} needs image file&lt;br /&gt;
|-&lt;br /&gt;
! Without Normal Map !! With Normal Map&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Important Info =&lt;br /&gt;
&lt;br /&gt;
* The normal map effect will *not* be shown unless you have a specular map defined. It can be as simple as a full-black with full-black alpha image, TGA 32-bit format is recommended.&amp;lt;br /&amp;gt;&lt;br /&gt;
* If you want to merge two normal maps, for instance, one for the terrain and one for the resources (metal, geo vents), it&#039;s not as simple as it might sound if you want to do it properly. You can read about it in detail [http://wiki.polycount.com/wiki/Normal_map here]. The &amp;quot;Whiteout&amp;quot; technique is recommended, there is a Photoshop action available for it [https://polycount.com/discussion/163801/udn-and-whiteout-normal-map-blending-photoshop-actions here]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
The relevant sections of the [[Mapdev:mapinfo.lua|mapinfo.lua]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      detailNormalTex = &amp;quot;normal.png&amp;quot;,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Image File==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGBA&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be stretched over the terrain.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Modifies the shading normal as follows&lt;br /&gt;
&lt;br /&gt;
shadingNormal.xyz = NORMALIZE(terrainNormal.xyz * (1 - detailNormalTex.a) &lt;br /&gt;
                               + detailNormalTex.rgb)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:specular&amp;diff=13995</id>
		<title>Mapdev:specular</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:specular&amp;diff=13995"/>
		<updated>2018-12-18T15:38:59Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Specular =&lt;br /&gt;
Gives you per-pixel control over the color and intensity of specular highlights anywhere on the map. You could eg. make all highlights red, or have them depend on the type of material that a pixel represents, or something more exotic.&lt;br /&gt;
The alpha channel defines how &amp;quot;polished&amp;quot; the surface looks (glossiness), and the RGB color is the amount of light that gets reflected for each color channel.&lt;br /&gt;
{{Caution|requires clients to have GLSL-spec hardware}}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| [[File:Mapdev-specular.jpg|256px]] || [[File:Mapdev-spec_with.jpg|451px]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Specular Texture&lt;br /&gt;
! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
The relevant sections of the [[Mapdev:mapinfo.lua|mapinfo.lua]]&lt;br /&gt;
* If specularTex points to a file that does not exist, you will get full unmoderated specularity based on whatever your map&#039;s lighting settings are&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      specularTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
   lighting = {&lt;br /&gt;
      ...&lt;br /&gt;
      groundSpecularColor = {0.1, 0.1, 0.1},&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Image File ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGBA&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be stretched over the terrain.&lt;br /&gt;
|}&lt;br /&gt;
* The RGB channels will control the red, green, and blue contribution per highlight&lt;br /&gt;
* The Alpha channel (multiplied by 16) becomes the specular exponent. Or on other words controls the sharpness of the specular highlights, the higher the value the sharper the highlights.&lt;br /&gt;
* You have to set the RGB values to zero if you want no specular contribution&lt;br /&gt;
* If you omit the alpha channel, or have a fully opaque image, the specular exponent is at its max and the results are a very sharp specular highlights.&lt;br /&gt;
{{Caution|If you set the alpha value of the specular texture to zero, or you will get the below result. Use almost zero instead.}}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| [[File:Mapdev-spec_alpha_issue.jpg]]&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Forum Discussion =&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?f=13&amp;amp;t=21951 Make Your Maps Shiny(er) With SSMF]&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:splatdetailnormals&amp;diff=14034</id>
		<title>Mapdev:splatdetailnormals</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:splatdetailnormals&amp;diff=14034"/>
		<updated>2018-12-18T15:38:46Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Detail Normal Texture Splatting (DNTS) =&lt;br /&gt;
&lt;br /&gt;
This extends the existing functionality of SSMF splatted detail textures [[Mapdev:splatdetail]], with the option of specifying 4 different (normal map + greyscale diffuse map) detail textures.&lt;br /&gt;
&lt;br /&gt;
Splatted detail textures only allowed grayscale textures to be overlayed on the map, while DNTS also allows normal maps as well.&lt;br /&gt;
&lt;br /&gt;
Instead of creating a combined detail texture of 4 different single-channel diffuse detail textures stored in a single RGBA image, it uses four separate normal textures. &lt;br /&gt;
&lt;br /&gt;
The textures must contain the normal maps in the RGB channel (standard normal maps), with a diffuse luminance in the alpha channel.&lt;br /&gt;
&lt;br /&gt;
The system uses the same splatDistributionTexture as regular SSMF.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;You cannot specify these options in .smd files, only .lua!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Example result:&lt;br /&gt;
&lt;br /&gt;
[[File:dnts_example.jpg|960px]]&lt;br /&gt;
== Distribution Image ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA, DDS&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGBA&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be stretched over the terrain.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The RGBA Channels are individual greyscale distribution maps which define which detail textures to splat onto the ground. The intensity of the splatted textures is multipled by the pixel values for the corresponding channels.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-ddist.gif]] || [[File:Mapdev-ddist.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Detail Distribution maps !! Combined Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Detail Normal Textures ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA, DDS &lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGB for normal maps only, RGBA for normal map + diffuse map in alpha channel. The Y (green) channel of normal maps should be inverted.&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be tiled over the terrain.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Detail Normal Texture Example&lt;br /&gt;
| [[File:Mapdev-dnts-normal.jpg|400px]] || [[File:Mapdev-dnts-diffuse-alpha.jpg|400px]]&lt;br /&gt;
|-&lt;br /&gt;
! Normal texture in RGB channel !! greyscale diffuse in ALPHA channel&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
&lt;br /&gt;
Specify splatDetailNormalTex1 .. splatDetailNormalTex4 in the MAP resources section. splatDetailTex will be unused if and of splatDetailNormalTex[1-4] are present. &lt;br /&gt;
&lt;br /&gt;
Specify splatDetailNormalDiffuseAlpha=1 to enable diffuse textures stored in alpha channels.&lt;br /&gt;
&lt;br /&gt;
splatDetailNormalDiffuseAlpha=0 is the default value, and will ignore all and any alpha channels in the splatDetailNormalTex&#039;s, resulting in a purely normal mapped surface, with no extra diffuse texturing. &lt;br /&gt;
&lt;br /&gt;
texScales and texMults work identically to [[Mapdev:splatdetail]]&lt;br /&gt;
&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      splatDistrTex = &amp;quot;splatDistributionTex.tga&amp;quot;,&lt;br /&gt;
      splatDetailNormalDiffuseAlpha = 1,&lt;br /&gt;
      splatDetailNormalTex = {&lt;br /&gt;
         &amp;quot;sandpebbles_NORM.tga&amp;quot;,&lt;br /&gt;
         &amp;quot;crystal_245_dnts.dds&amp;quot;,&lt;br /&gt;
         &amp;quot;grass_91_dnts.dds&amp;quot;,&lt;br /&gt;
         &amp;quot;pebbles_250_dnts_u8888.dds&amp;quot;,&lt;br /&gt;
          alpha = true,&lt;br /&gt;
      },&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
   splats = {&lt;br /&gt;
      texScales = {0.02, 0.02, 0.02, 0.02},&lt;br /&gt;
      texMults = {1.0, 1.0, 1.0, 1.0},&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:splatdetail&amp;diff=14010</id>
		<title>Mapdev:splatdetail</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:splatdetail&amp;diff=14010"/>
		<updated>2018-12-18T15:38:21Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Details =&lt;br /&gt;
Splat Detail textures extend the default single detail texture that is applied uniformly over the entire map, by allowing the mapper to specify 4 different greyscale detail textures, and offers control of the strength, spatial distribution and tiling resolution of each detail texture.&lt;br /&gt;
&lt;br /&gt;
Important: Splat Detail textures requires a specular texture [[Mapdev:specular]] to exist and be defined in order to be enabled!&lt;br /&gt;
&lt;br /&gt;
{{Caution|requires clients to have GLSL-spec hardware}}&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-splat-without.jpg|330px]] || [[File:Mapdev-splat-with.jpg|330px]]&lt;br /&gt;
|-&lt;br /&gt;
! Default Detail Map !! Splat Detail Maps&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | &#039;&#039;* Click on images for higher res&#039;&#039;&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      splatDistrTex = &amp;quot;splatDistributionTex.tga&amp;quot;,&lt;br /&gt;
      splatDetailTex = &amp;quot;splatDetailTex.tga&amp;quot;,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
   splats = {&lt;br /&gt;
      texScales = {0.02, 0.02, 0.02, 0.02},&lt;br /&gt;
      texMults = {1.0, 1.0, 1.0, 1.0},&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== texScales ===&lt;br /&gt;
&lt;br /&gt;
texScales offers a way to adjust the tiling resolution of each of the 4 splat detail textures. Values of 0.02 are the default values, lower values will increase the size of the textures on the ground, and higher values will decrease the tile size. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|[[File:Map measure.png|512px|measuring stick]]&lt;br /&gt;
|-&lt;br /&gt;
! texScales&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== texMults ===&lt;br /&gt;
&lt;br /&gt;
texMults offers a quick way to adjust the strength at which each detail texture will be blended onto the map. Values of 1.0 are the default values, lower values will make the detail texture fainter, higher values make it more pronounced. This is very useful for fine-tuning the strengths after generating the splat distribution texture, which is time-consuming to manipulate in an image editor, and cant be increased above a certain value there.&lt;br /&gt;
&lt;br /&gt;
== Distribution Image ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGBA&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be stretched over the terrain.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The RGBA Channels are individual greyscale distribution maps which define which detail textures to splat onto the ground. The intensity of the splatted textures is multipled by the pixel values for the corresponding channels.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-ddist.gif]] || [[File:Mapdev-ddist.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Detail Distribution maps !! Combined Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Detail Image ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGBA&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be tiled over the terrain.&lt;br /&gt;
|}&lt;br /&gt;
Each Channel represents a seperate greyscale image. The ground colour is multiplied by the pixel values of the channel. The intensity of the effect is also controlled per channel using the {{xtaglink|mapinfo.lua|texMults}} variables, low numbers = less effect. &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-details.gif]] || [[File:Mapdev-details.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Individual Detail Textures !! Combined Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Forum Discussion =&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?f=56&amp;amp;t=21565 Detail texture resource thread]&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?f=13&amp;amp;t=22564  Detail texture splatting is ready!]&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:detail&amp;diff=13772</id>
		<title>Mapdev:detail</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:detail&amp;diff=13772"/>
		<updated>2018-12-18T15:38:12Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Details =&lt;br /&gt;
{{FIXME}} Needs description here&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| {{FIXME}} needs image || [[File:Mapdev-splat-without.jpg|330px]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Detail Texture !! Ingame Result&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | &#039;&#039;* Click on images for higher res&#039;&#039;&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      detailTex = &amp;quot;&amp;quot;,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Image File ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA, BMP, DDS {{new|99.0}}&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGB&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any powers of two, eg. 256, 512, 1024...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:diffuse&amp;diff=13782</id>
		<title>Mapdev:diffuse</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:diffuse&amp;diff=13782"/>
		<updated>2018-12-18T15:37:49Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Diffuse =&lt;br /&gt;
The colour of the terrain, then modified with the lighting values in mapinfo.lua&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| [[File:Mapdev-diffuse.jpg]] || [[File:Mapdev-diffuse-example.png]]&lt;br /&gt;
|-&lt;br /&gt;
! Example Diffuse Map !! Ingame Result&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
The relevant sections of the mapinfo.lua file that effect the colour of the ground are in the [[Map_Making:mapinfo.lua#Lighting|Lighting subtable]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   lighting = {&lt;br /&gt;
      ...&lt;br /&gt;
      --// ground lighting&lt;br /&gt;
      groundAmbientColor  = {0.5, 0.5, 0.5},&lt;br /&gt;
      groundDiffuseColor  = {0.5, 0.5, 0.5},&lt;br /&gt;
      groundSpecularColor = {0.1, 0.1, 0.1},&lt;br /&gt;
      groundShadowDensity = 0.8,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Image File ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| The diffuse texture is chopped into 32x32 pixel tiles compressed using DXT1 and compiled into the smt using [[MapConv]] or [[MapConvNG]].&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| Any that Mapconv programs support&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGBA&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| &amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
!Spring Map Size&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
!pixels = Spring Map Size * 512&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 1024&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| 2048&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| 3072&lt;br /&gt;
|-&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
|-&lt;br /&gt;
| 32&lt;br /&gt;
| 16 384&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: left;font-style:italic&amp;quot; colspan=2 | * must be multiples of 2&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Compression ==&lt;br /&gt;
The DXT1 compression is lossy, but in a consistent manner. all 32x32 tiles will have exactly the same size. To reduce the number of tiles saved in tile file(SMT) you can align graphical elements to a 32x32 pixel grid. MapConv can detect that a tile is repeated and reference it only once. This means that any repetition of the diffuse image, so long as it is aligned to a 32x32 pixel grid will result in a reduction in size.&lt;br /&gt;
&lt;br /&gt;
* Use tiled textures that are multiples of 32x32 in dimensions.&lt;br /&gt;
* Place features like geovents and metal spots on a 32x32 grid.&lt;br /&gt;
* Repeat as much as possible on a 32x32 pixel grid.&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:parallax&amp;diff=13955</id>
		<title>Mapdev:parallax</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Mapdev:parallax&amp;diff=13955"/>
		<updated>2018-12-18T15:37:26Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* mapinfo.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Parallax Texture =&lt;br /&gt;
modifies the diffuse, normal, and specular&lt;br /&gt;
TEXTURE COORDINATES before sampling is done&lt;br /&gt;
&lt;br /&gt;
{{FIXME}} description as to why you want to use Parallax textures.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Example&lt;br /&gt;
| {{FIXME}} needs image file || {{FIXME}} needs image file&lt;br /&gt;
|-&lt;br /&gt;
! Without Parallax Map !! With Parallax Map&lt;br /&gt;
|}&amp;lt;/center&amp;gt;&lt;br /&gt;
= Specification =&lt;br /&gt;
== mapinfo.lua ==&lt;br /&gt;
The relevant sections of the [[Mapdev:mapinfo.lua|mapinfo.lua]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mapinfo = {&lt;br /&gt;
   ...&lt;br /&gt;
   resources = {&lt;br /&gt;
      ...&lt;br /&gt;
      parallaxHeightTex = &amp;quot;parallax.png&amp;quot;,&lt;br /&gt;
      ...&lt;br /&gt;
   },&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Image File==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! width=&amp;quot;15%&amp;quot; | File Location&lt;br /&gt;
| ./maps/&lt;br /&gt;
|-&lt;br /&gt;
! File Format&lt;br /&gt;
| PNG, TGA&lt;br /&gt;
|-&lt;br /&gt;
! Colour Depth&lt;br /&gt;
| 8bpp&lt;br /&gt;
|-&lt;br /&gt;
! Channels&lt;br /&gt;
| RGBA&lt;br /&gt;
|-&lt;br /&gt;
! Resolution&lt;br /&gt;
| Any, recommended powers of two, will be stretched over the terrain. Should be the same size as the [[Mapdev:specular]] image&lt;br /&gt;
|}&lt;br /&gt;
{{FIXME}} needs cleaning.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
height, scale, and bias parameters are packed&lt;br /&gt;
as follows to produce a texel offset-factor f&lt;br /&gt;
&lt;br /&gt;
h = (parallaxHeightTex.r * 65280 + parallaxHeightTex.g * 256) / 65536&lt;br /&gt;
s = (parallaxHeightTex.b)&lt;br /&gt;
b = (parallaxHeightTex.a - 0.5)&lt;br /&gt;
f = h * s + b&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Forum Discussions =&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?f=13&amp;amp;t=29108 Parallax Maps?]&lt;br /&gt;
&lt;br /&gt;
[[Category:Map Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Modrules.lua&amp;diff=14470</id>
		<title>Modrules.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Modrules.lua&amp;diff=14470"/>
		<updated>2018-12-18T11:29:24Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* system */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Location==&lt;br /&gt;
&amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; is a file in the &amp;lt;code&amp;gt;Gamedata/&amp;lt;/code&amp;gt; directory of a Spring game. &lt;br /&gt;
&lt;br /&gt;
==Purpose==&lt;br /&gt;
This file controls various global parameters of the game, for example how fast units gain experience, what unit types can be transported, how fine grained the LOS system is, etc.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which parses the data from this file is viewable here:&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/Sim/Misc/ModInfo.cpp}}&lt;br /&gt;
&lt;br /&gt;
==Data Types==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
&amp;lt;code&amp;gt;Modrules.lua&amp;lt;/code&amp;gt; is divided into several sub-tables containing tags specific to each section, as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===capture===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much of the original energy cost it requires to capture something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===construction===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecay&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Do uncompleted building frames begin to decay if no builder is working on them?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecayTime&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 6.66&lt;br /&gt;
|description = The time in seconds before abandoned building frames begin to decay.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecaySpeed&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.03&lt;br /&gt;
|description = How fast build progress decays for abandoned building frames. Note that the rate is inversely proportional to the {{xtaglink|Gamedev:UnitDefs|buildtime}} i.e. a building with a larger {{xtaglink|Gamedev:UnitDefs|buildtime}} will decay more slowly for a given value of this tag than a building with a shorter {{xtaglink|Gamedev:UnitDefs|buildtime}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===experience===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = experienceMult&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Controls the amount of experience gained by units engaging in combat. The formulae used are: &lt;br /&gt;
::&amp;lt;code&amp;gt;xp for damage = 0.1 * experienceMult * damage / target_HP * target_power / attacker_power&amp;lt;/code&amp;gt; &lt;br /&gt;
::&amp;lt;code&amp;gt;xp for kill = 0.1 * experienceMult * target_power / attacker_power&amp;lt;/code&amp;gt;. &lt;br /&gt;
: Where {{xtaglink|Gamedev:UnitDefs|power}} can be set by the UnitDef tag.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = powerScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Controls how gaining experience changes the relative {{xtaglink|Gamedev:UnitDefs|power}} of the unit. The formula used is &amp;lt;code&amp;gt;Power multiplier = powerScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = healthScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.7&lt;br /&gt;
|description = Controls how gaining experience increases the {{xtaglink|Gamedev:UnitDefs|maxDamage}} (total hitpoints) of the unit. The formula used is &amp;lt;code&amp;gt;Health multiplier = healthScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = reloadScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.4&lt;br /&gt;
|description = Controls how gaining experience decreases the {{xtaglink|Gamedev:UnitDefs|reloadTime}} of the unit&#039;s weapons. The formula used is &amp;lt;code&amp;gt;Rate of fire multiplier = reloadScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===featureLOS===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = featureVisibility&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 3&lt;br /&gt;
|description = Controls the visibility of features. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - no default LOS for features, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Gaia features always visible, &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - allyteam &amp;amp; Gaia features always visible, or &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; - all features always visible.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===fireAtDead===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = fireAtKilled&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Will units continue to target and fire on enemies which are running their &amp;lt;code&amp;gt;Killed()&amp;lt;/code&amp;gt; animation? (See [[Animation-LuaCallins#Generic]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = fireAtCrashing&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Will units continue to target and fire on enemy aircraft which are in the &#039;crashing&#039; state? (See [[Lua_SyncedCtrl#Unit_Control]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===flankingBonus===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = defaultMode&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = The default {{xtaglink|Gamedev:UnitDefs|flankingBonusMode}} for units. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - No flanking bonus. Mode &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; builds up the ability to move over time, and swings to face attacks, but does not respect the way the unit is facing. Mode &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; also can swing, but moves with the unit as it turns. Mode &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; stays with the unit as it turns and otherwise doesn&#039;t move, the ideal mode to simulate something such as tank armour. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====los====&lt;br /&gt;
{{tag&lt;br /&gt;
|name = losMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls the resolution of the LOS calculations. A higher value means lower resolution but increased performance. An increase by one level means half the resolution of the LOS map in both x and y direction. Must be between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;6&amp;lt;/code&amp;gt; inclusive.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = losMul&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|special = {{removed|101.0}}&lt;br /&gt;
|description = Multiplies all unit&#039;s {{xtaglink|Gamedev:UnitDefs|sightDistance}} by this value. Generally speaking you should always use the default.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = airMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls the resolution of the LOS vs. aircraft calculations. A higher value means lower resolution but increased performance. An increase by one level means half the resolution of the air-LOS map in both x and y direction. Must be between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;30&amp;lt;/code&amp;gt; inclusive. [http://springrts.com/mantis/view.php?id=4031#c11709] - jK describe for you what the value means.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = airLosMul&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|special = {{removed|101.0}}&lt;br /&gt;
|description = Multiplies all unit&#039;s {{xtaglink|Gamedev:UnitDefs|airSightDistance}} by this value. Generally speaking you should always use the default.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = radarMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 2&lt;br /&gt;
|description = Controls the resolution of the radar. See description of airMipLevel for details.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===movement===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAirPlanesToLeaveMap&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Are (gunship) aircraft allowed to fly outside the bounds of the map?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAircraftToHitGround&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|90.0}}&lt;br /&gt;
|description = Are aircraft allowed to hit the ground whilst manoeuvring?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowPushingEnemyUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|83.0}}&lt;br /&gt;
|description = Can enemy ground units push each other during collisions?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowCrushingAlliedUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|85.0}}&lt;br /&gt;
|description = Can allied ground units crush each other during collisions? Units still have to be explicitly set as crushable using the &amp;lt;code&amp;gt;crushable&amp;lt;/code&amp;gt; parameter of [[Lua_SyncedCtrl#Unit_Control|Spring.SetUnitBlocking]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowUnitCollisionDamage&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|85.0}}&lt;br /&gt;
|description = Do unit-unit (skidding) collisions cause damage?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowUnitCollisionOverlap&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|89.0}}&lt;br /&gt;
|description = Can mobile units collision volumes overlap one another? Allows unit movement like [http://www.youtube.com/watch?v=mRtePUdVk2o this (video)] at the cost of more &#039;clumping&#039;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowGroundUnitGravity&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|92.0}}&lt;br /&gt;
|description = Allows fast moving mobile units to &#039;catch air&#039; as they move over terrain.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowHoverUnitStrafing&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true if using QTPFS pathfinder&lt;br /&gt;
|special = {{new|92.0}}&lt;br /&gt;
|description = Allows hovercraft units to slide in turns.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = useClassicGroundMoveType&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|89.0}} {{removed|102.0}}&lt;br /&gt;
|description = A ticket back to unit movement circa 2009: no reversing, no {{xtaglink|Gamedev:UnitDefs|turninplace|false}}, no smooth collision handling, no nothing. For comparison of pathfinding code.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===paralyze===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = paralyzeOnMaxHealth&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Are units paralyzed when the level of emp is greater than their current health or their maximum health?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===reclaim===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = multiReclaim&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = Can multiple units reclaim a feature or only one? &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; implies the latter, all other values the former.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = reclaimMethod&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls how features are reclaimed. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - gradual reclaim, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - all reclaimed at end, any other positive value &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; - reclaim in &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; chunks.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitMethod&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls how units are reclaimed. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - gradual reclaim, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - all reclaimed at end, any other positive value &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; - reclaim in &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; chunks.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = featureEnergyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much energy should reclaiming a feature cost? Multiplier against the fraction of the features&#039; {{xtaglink|Gamedev:FeatureDefs|metal}} content reclaimed.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitEnergyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much energy should reclaiming a unit cost? Multiplier against the fraction of the unit&#039;s {{xtaglink|Gamedev:UnitDefs|buildCostEnergy}} reclaimed. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitEfficiency&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = How much metal should reclaiming a unit return? Multiplier against the unit&#039;s {{xtaglink|Gamedev:UnitDefs|buildCostMetal}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowEnemies&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can enemy units be reclaimed?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAllies&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can allied units be reclaimed?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===repair===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much of the original energy cost it requires to repair something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===resurrect===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.5&lt;br /&gt;
|description = How much of the original energy cost it requires to resurrect something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===sensors===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = requireSonarUnderWater&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = If &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; then when underwater, units only get LOS if they also have sonar.&lt;br /&gt;
}}&lt;br /&gt;
{{tag&lt;br /&gt;
|name = alwaysVisibleOverridesCloaked&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|101.0}}&lt;br /&gt;
|description = If &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; then units will be visible even when cloaked (probably?).&lt;br /&gt;
}}&lt;br /&gt;
{{tag&lt;br /&gt;
|name = separateJammers&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|101.0}}&lt;br /&gt;
|description = When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; each allyTeam only jams their own units.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===system===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pathFinderSystem&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|special={{new|85.0}}&lt;br /&gt;
|description = Which pathfinder does the game use? Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - The legacy default pathfinder, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Quad-Tree Pathfinder System ([[QTPFS]])}} or &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt; - disabled.&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pathFinderUpdateRate&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.007&lt;br /&gt;
|special={{new|98.0}}&lt;br /&gt;
|description = Controls how often the pathfinder updates; larger values means more rapid updates.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowTake&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|103.0}}&lt;br /&gt;
|description = Enables and disables the {{var|/take}} [[UI_commands|UI command]].}}&lt;br /&gt;
&lt;br /&gt;
===transportability===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportAir&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can aircraft be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportShip&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can ships be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportHover&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can hovercraft be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportGround&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can ground units be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = targetableTransportedUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|89.0}}&lt;br /&gt;
|description = Can transported units be targeted by weapons? &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; allows both manual and automatic targeting.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
===Empty===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; can simply return an empty table like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
return {}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you do this, Spring will use the default values.&lt;br /&gt;
&lt;br /&gt;
===Configurable by modoptions===&lt;br /&gt;
Interestingly &amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; can read [[Modoptions.lua|modoptions]], so these parameters can be scripted to be configurable from the lobby.&lt;br /&gt;
For example to allow selecting either legacy default pathfinder or [[QTPFS]] via a modoption:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  system = {&lt;br /&gt;
    pathFinderSystem = (Spring.GetModOptions() and (Spring.GetModOptions().qtpfs == &amp;quot;1&amp;quot;) and 1) or 0,&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===External Examples===&lt;br /&gt;
[http://imolarpg.dyndns.org/trac/balatest/browser/trunk/gamedata/modrules.lua &#039;Balanced Annihilation&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/conflictterra/source/browse/games/CT/gamedata/modrules.lua &#039;Conflict Terra&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[https://code.google.com/p/evolutionrts/source/browse/trunk/evolutiondev.sdd/Gamedata/modrules.lua &#039;Evolution RTS&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://spring1944.svn.sourceforge.net/viewvc/spring1944/trunk/S44Main.sdd/gamedata/modrules.lua?&amp;amp;view=markup &#039;Spring: 1944&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/zero-k/source/browse/trunk/mods/zk/gamedata/modrules.lua &#039;ZeroK&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:gamedata]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Modrules.lua&amp;diff=14469</id>
		<title>Modrules.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Modrules.lua&amp;diff=14469"/>
		<updated>2018-12-18T11:28:35Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* system */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Location==&lt;br /&gt;
&amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; is a file in the &amp;lt;code&amp;gt;Gamedata/&amp;lt;/code&amp;gt; directory of a Spring game. &lt;br /&gt;
&lt;br /&gt;
==Purpose==&lt;br /&gt;
This file controls various global parameters of the game, for example how fast units gain experience, what unit types can be transported, how fine grained the LOS system is, etc.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which parses the data from this file is viewable here:&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/Sim/Misc/ModInfo.cpp}}&lt;br /&gt;
&lt;br /&gt;
==Data Types==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
&amp;lt;code&amp;gt;Modrules.lua&amp;lt;/code&amp;gt; is divided into several sub-tables containing tags specific to each section, as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===capture===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much of the original energy cost it requires to capture something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===construction===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecay&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Do uncompleted building frames begin to decay if no builder is working on them?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecayTime&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 6.66&lt;br /&gt;
|description = The time in seconds before abandoned building frames begin to decay.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecaySpeed&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.03&lt;br /&gt;
|description = How fast build progress decays for abandoned building frames. Note that the rate is inversely proportional to the {{xtaglink|Gamedev:UnitDefs|buildtime}} i.e. a building with a larger {{xtaglink|Gamedev:UnitDefs|buildtime}} will decay more slowly for a given value of this tag than a building with a shorter {{xtaglink|Gamedev:UnitDefs|buildtime}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===experience===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = experienceMult&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Controls the amount of experience gained by units engaging in combat. The formulae used are: &lt;br /&gt;
::&amp;lt;code&amp;gt;xp for damage = 0.1 * experienceMult * damage / target_HP * target_power / attacker_power&amp;lt;/code&amp;gt; &lt;br /&gt;
::&amp;lt;code&amp;gt;xp for kill = 0.1 * experienceMult * target_power / attacker_power&amp;lt;/code&amp;gt;. &lt;br /&gt;
: Where {{xtaglink|Gamedev:UnitDefs|power}} can be set by the UnitDef tag.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = powerScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Controls how gaining experience changes the relative {{xtaglink|Gamedev:UnitDefs|power}} of the unit. The formula used is &amp;lt;code&amp;gt;Power multiplier = powerScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = healthScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.7&lt;br /&gt;
|description = Controls how gaining experience increases the {{xtaglink|Gamedev:UnitDefs|maxDamage}} (total hitpoints) of the unit. The formula used is &amp;lt;code&amp;gt;Health multiplier = healthScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = reloadScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.4&lt;br /&gt;
|description = Controls how gaining experience decreases the {{xtaglink|Gamedev:UnitDefs|reloadTime}} of the unit&#039;s weapons. The formula used is &amp;lt;code&amp;gt;Rate of fire multiplier = reloadScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===featureLOS===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = featureVisibility&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 3&lt;br /&gt;
|description = Controls the visibility of features. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - no default LOS for features, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Gaia features always visible, &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - allyteam &amp;amp; Gaia features always visible, or &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; - all features always visible.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===fireAtDead===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = fireAtKilled&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Will units continue to target and fire on enemies which are running their &amp;lt;code&amp;gt;Killed()&amp;lt;/code&amp;gt; animation? (See [[Animation-LuaCallins#Generic]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = fireAtCrashing&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Will units continue to target and fire on enemy aircraft which are in the &#039;crashing&#039; state? (See [[Lua_SyncedCtrl#Unit_Control]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===flankingBonus===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = defaultMode&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = The default {{xtaglink|Gamedev:UnitDefs|flankingBonusMode}} for units. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - No flanking bonus. Mode &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; builds up the ability to move over time, and swings to face attacks, but does not respect the way the unit is facing. Mode &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; also can swing, but moves with the unit as it turns. Mode &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; stays with the unit as it turns and otherwise doesn&#039;t move, the ideal mode to simulate something such as tank armour. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====los====&lt;br /&gt;
{{tag&lt;br /&gt;
|name = losMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls the resolution of the LOS calculations. A higher value means lower resolution but increased performance. An increase by one level means half the resolution of the LOS map in both x and y direction. Must be between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;6&amp;lt;/code&amp;gt; inclusive.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = losMul&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|special = {{removed|101.0}}&lt;br /&gt;
|description = Multiplies all unit&#039;s {{xtaglink|Gamedev:UnitDefs|sightDistance}} by this value. Generally speaking you should always use the default.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = airMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls the resolution of the LOS vs. aircraft calculations. A higher value means lower resolution but increased performance. An increase by one level means half the resolution of the air-LOS map in both x and y direction. Must be between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;30&amp;lt;/code&amp;gt; inclusive. [http://springrts.com/mantis/view.php?id=4031#c11709] - jK describe for you what the value means.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = airLosMul&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|special = {{removed|101.0}}&lt;br /&gt;
|description = Multiplies all unit&#039;s {{xtaglink|Gamedev:UnitDefs|airSightDistance}} by this value. Generally speaking you should always use the default.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = radarMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 2&lt;br /&gt;
|description = Controls the resolution of the radar. See description of airMipLevel for details.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===movement===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAirPlanesToLeaveMap&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Are (gunship) aircraft allowed to fly outside the bounds of the map?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAircraftToHitGround&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|90.0}}&lt;br /&gt;
|description = Are aircraft allowed to hit the ground whilst manoeuvring?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowPushingEnemyUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|83.0}}&lt;br /&gt;
|description = Can enemy ground units push each other during collisions?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowCrushingAlliedUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|85.0}}&lt;br /&gt;
|description = Can allied ground units crush each other during collisions? Units still have to be explicitly set as crushable using the &amp;lt;code&amp;gt;crushable&amp;lt;/code&amp;gt; parameter of [[Lua_SyncedCtrl#Unit_Control|Spring.SetUnitBlocking]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowUnitCollisionDamage&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|85.0}}&lt;br /&gt;
|description = Do unit-unit (skidding) collisions cause damage?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowUnitCollisionOverlap&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|89.0}}&lt;br /&gt;
|description = Can mobile units collision volumes overlap one another? Allows unit movement like [http://www.youtube.com/watch?v=mRtePUdVk2o this (video)] at the cost of more &#039;clumping&#039;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowGroundUnitGravity&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|92.0}}&lt;br /&gt;
|description = Allows fast moving mobile units to &#039;catch air&#039; as they move over terrain.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowHoverUnitStrafing&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true if using QTPFS pathfinder&lt;br /&gt;
|special = {{new|92.0}}&lt;br /&gt;
|description = Allows hovercraft units to slide in turns.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = useClassicGroundMoveType&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|89.0}} {{removed|102.0}}&lt;br /&gt;
|description = A ticket back to unit movement circa 2009: no reversing, no {{xtaglink|Gamedev:UnitDefs|turninplace|false}}, no smooth collision handling, no nothing. For comparison of pathfinding code.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===paralyze===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = paralyzeOnMaxHealth&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Are units paralyzed when the level of emp is greater than their current health or their maximum health?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===reclaim===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = multiReclaim&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = Can multiple units reclaim a feature or only one? &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; implies the latter, all other values the former.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = reclaimMethod&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls how features are reclaimed. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - gradual reclaim, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - all reclaimed at end, any other positive value &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; - reclaim in &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; chunks.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitMethod&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls how units are reclaimed. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - gradual reclaim, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - all reclaimed at end, any other positive value &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; - reclaim in &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; chunks.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = featureEnergyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much energy should reclaiming a feature cost? Multiplier against the fraction of the features&#039; {{xtaglink|Gamedev:FeatureDefs|metal}} content reclaimed.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitEnergyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much energy should reclaiming a unit cost? Multiplier against the fraction of the unit&#039;s {{xtaglink|Gamedev:UnitDefs|buildCostEnergy}} reclaimed. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitEfficiency&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = How much metal should reclaiming a unit return? Multiplier against the unit&#039;s {{xtaglink|Gamedev:UnitDefs|buildCostMetal}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowEnemies&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can enemy units be reclaimed?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAllies&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can allied units be reclaimed?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===repair===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much of the original energy cost it requires to repair something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===resurrect===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.5&lt;br /&gt;
|description = How much of the original energy cost it requires to resurrect something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===sensors===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = requireSonarUnderWater&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = If &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; then when underwater, units only get LOS if they also have sonar.&lt;br /&gt;
}}&lt;br /&gt;
{{tag&lt;br /&gt;
|name = alwaysVisibleOverridesCloaked&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|101.0}}&lt;br /&gt;
|description = If &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; then units will be visible even when cloaked (probably?).&lt;br /&gt;
}}&lt;br /&gt;
{{tag&lt;br /&gt;
|name = separateJammers&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|101.0}}&lt;br /&gt;
|description = When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; each allyTeam only jams their own units.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===system===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pathFinderSystem&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|special={{new|85.0}}&lt;br /&gt;
|description = Which pathfinder does the game use? Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - The legacy default pathfinder, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Quad-Tree Pathfinder System ([[QTPFS]]).}} or &amp;lt;code&amp;gt;-11&amp;lt;/code&amp;gt; - disabled&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pathFinderUpdateRate&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.007&lt;br /&gt;
|special={{new|98.0}}&lt;br /&gt;
|description = Controls how often the pathfinder updates; larger values means more rapid updates.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowTake&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|103.0}}&lt;br /&gt;
|description = Enables and disables the {{var|/take}} [[UI_commands|UI command]].}}&lt;br /&gt;
&lt;br /&gt;
===transportability===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportAir&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can aircraft be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportShip&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can ships be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportHover&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can hovercraft be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportGround&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can ground units be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = targetableTransportedUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|89.0}}&lt;br /&gt;
|description = Can transported units be targeted by weapons? &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; allows both manual and automatic targeting.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
===Empty===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; can simply return an empty table like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
return {}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you do this, Spring will use the default values.&lt;br /&gt;
&lt;br /&gt;
===Configurable by modoptions===&lt;br /&gt;
Interestingly &amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; can read [[Modoptions.lua|modoptions]], so these parameters can be scripted to be configurable from the lobby.&lt;br /&gt;
For example to allow selecting either legacy default pathfinder or [[QTPFS]] via a modoption:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  system = {&lt;br /&gt;
    pathFinderSystem = (Spring.GetModOptions() and (Spring.GetModOptions().qtpfs == &amp;quot;1&amp;quot;) and 1) or 0,&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===External Examples===&lt;br /&gt;
[http://imolarpg.dyndns.org/trac/balatest/browser/trunk/gamedata/modrules.lua &#039;Balanced Annihilation&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/conflictterra/source/browse/games/CT/gamedata/modrules.lua &#039;Conflict Terra&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[https://code.google.com/p/evolutionrts/source/browse/trunk/evolutiondev.sdd/Gamedata/modrules.lua &#039;Evolution RTS&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://spring1944.svn.sourceforge.net/viewvc/spring1944/trunk/S44Main.sdd/gamedata/modrules.lua?&amp;amp;view=markup &#039;Spring: 1944&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/zero-k/source/browse/trunk/mods/zk/gamedata/modrules.lua &#039;ZeroK&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:gamedata]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Sounds.lua&amp;diff=17041</id>
		<title>Sounds.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Sounds.lua&amp;diff=17041"/>
		<updated>2018-12-18T11:17:26Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* External Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Location==&lt;br /&gt;
&amp;lt;code&amp;gt;sounds.lua&amp;lt;/code&amp;gt; is a file in the &amp;lt;code&amp;gt;Gamedata/&amp;lt;/code&amp;gt; directory of a Spring Game.&lt;br /&gt;
&lt;br /&gt;
==Purpose==&lt;br /&gt;
The file is used to define &#039;&#039;&#039;SoundItems&#039;&#039;&#039;. Beside simply &amp;quot;linking&amp;quot; to an audio file, &#039;&#039;&#039;SoundItems&#039;&#039;&#039; can use various tags to alter the playback of the file.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which parses the data from this file is viewable here:&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/System/Sound/SoundItem.cpp}}&lt;br /&gt;
&lt;br /&gt;
==Data Types==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
Wherever a sound is played in Spring, be it associated with a [[Gamedev:UnitDefs|UnitDef]], [[Gamedev:WeaponDefs|WeaponDef]] or via the [[Lua_UnsyncedCtrl#Sounds|lua API]], a &#039;&#039;&#039;SoundItem&#039;&#039;&#039; is used. If you access a raw sound file, a &#039;&#039;&#039;SoundItem&#039;&#039;&#039; with the defaults is created for you.&lt;br /&gt;
&lt;br /&gt;
Additionally, multiple &#039;&#039;&#039;SoundItems&#039;&#039;&#039; can use one single file with different settings, this is very efficient, as they only use 1 shared buffer.&lt;br /&gt;
&lt;br /&gt;
{{new|89.0}}: All item names are treated in lowercase.&lt;br /&gt;
&lt;br /&gt;
==Tips==&lt;br /&gt;
You can update &amp;amp; reload your sounddefs at runtime via Spring.LoadSoundDef(&amp;quot;gamedata/sounds.lua&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
===Reserved SoundItems===&lt;br /&gt;
The following &#039;&#039;&#039;SoundItems&#039;&#039;&#039; are reserved for specific engine sounds:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;IncomingChat&amp;lt;/code&amp;gt; - Is played when a chat message is received.&lt;br /&gt;
* &amp;lt;code&amp;gt;MultiSelect&amp;lt;/code&amp;gt; - Is played when multiple units are selected simultaneously.&lt;br /&gt;
* &amp;lt;code&amp;gt;MapPoint&amp;lt;/code&amp;gt; - Is played when a map point is placed by the player or an ally.&lt;br /&gt;
* &amp;lt;code&amp;gt;FailedCommand&amp;lt;/code&amp;gt; - Is played when a unit fails to execute a command. e.g. When a unit cannot reach it&#039;s destination etc.&lt;br /&gt;
* &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt; - Used for all sounds that aren&#039;t listed in &amp;lt;code&amp;gt;sounds.lua&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===SoundItem Properties===&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = gain&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = This varies the loudness, &amp;gt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; is louder, &amp;lt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt;  is quieter. &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; is silent.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = gainmod&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = If &amp;gt; &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; then this adds a random amount to {{taglink|gain}} each time the sound is played. Clamped between &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt;. The result is in the range &#039;&#039;&#039;[&#039;&#039;&#039;({{taglink|gain}} * (1 + {{taglink|gainMod}}))&#039;&#039;&#039;,&#039;&#039;&#039; ({{taglink|gain}} * (1 - {{taglink|gainMod}}))&#039;&#039;&#039;]&#039;&#039;&#039;.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pitch&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Varies the pitch of the sound, &amp;gt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; is higher pitched, &amp;lt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; is lower.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pitchmod&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = If &amp;gt; &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; then this adds a random amount to {{taglink|pitch}} each time the sound is played. Clamped between &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt;. The result is in the range &#039;&#039;&#039;[&#039;&#039;&#039;({{taglink|pitch}} * (1 + {{taglink|pitchMod}}))&#039;&#039;&#039;,&#039;&#039;&#039; ({{taglink|pitch}} * (1 - {{taglink|pitchMod}}))&#039;&#039;&#039;]&#039;&#039;&#039;.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = dopplerscale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = How unit and camera speed affects the pitch of the sound, to exaggerate it, use values &amp;gt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt;. Use &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; to completely disable the effect.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = priority&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = When lots of sounds are played, sounds with lower {{taglink|priority}} are more likely to get cut off. A {{taglink|priority}} &amp;gt; &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; will never be cut of (priorities can be negative).}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = maxconcurrent&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 16&lt;br /&gt;
|description = How many copies of this sound can be played at once?}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = maxdist&lt;br /&gt;
|type = float&lt;br /&gt;
|default = MAX_FLOAT&lt;br /&gt;
|description = The cut-off distance (in [[elmo]]s) at which this sound will no longer be played.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = rolloff&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = How fast the sound becomes quieter with distance. &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; means always the same loudness regardless of distance.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = in3d&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Non-3d sounds always came out of the front-speakers (or the centre one). 3d sounds are, well, in 3d.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = looptime&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = The time in milliseconds the sound should loop for.}}&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===default sounds===&lt;br /&gt;
The following is the default &amp;lt;code&amp;gt;sounds.lua&amp;lt;/code&amp;gt; supplied in the base content [[springcontent.sdz]] archive, with some of the comments removed (As the information is presented here).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local Sounds = {&lt;br /&gt;
  SoundItems = {&lt;br /&gt;
    IncomingChat = {&lt;br /&gt;
      --- always play on the front speaker(s)&lt;br /&gt;
      file = &amp;quot;sounds/beep4.wav&amp;quot;,&lt;br /&gt;
      in3d = &amp;quot;false&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    MultiSelect = {&lt;br /&gt;
      --- always play on the front speaker(s)&lt;br /&gt;
      file = &amp;quot;sounds/button9.wav&amp;quot;,&lt;br /&gt;
      in3d = &amp;quot;false&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    MapPoint = {&lt;br /&gt;
      --- respect where the point was set, but don&#039;t attenuate in distance&lt;br /&gt;
      --- also, when moving the camera, don&#039;t pitch it&lt;br /&gt;
      file = &amp;quot;sounds/beep6.wav&amp;quot;,&lt;br /&gt;
      rolloff = 0,&lt;br /&gt;
      dopplerscale = 0,&lt;br /&gt;
    },&lt;br /&gt;
    ExampleSound = {&lt;br /&gt;
      --- some things you can do with this file&lt;br /&gt;
      --- can be either ogg or wav&lt;br /&gt;
      file = &amp;quot;somedir/subdir/soundfile.ogg&amp;quot;,&lt;br /&gt;
      gain = 1,&lt;br /&gt;
      pitch = 1,&lt;br /&gt;
      dopplerscale = 1,&lt;br /&gt;
      priority = 0,&lt;br /&gt;
      maxconcurrent = 16,&lt;br /&gt;
      maxdist = 20000,&lt;br /&gt;
      rolloff = 1,&lt;br /&gt;
      in3d = true,&lt;br /&gt;
      looptime = 0,&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    -- new since 89.0&lt;br /&gt;
    default = {&lt;br /&gt;
      gainmod = 0.35,&lt;br /&gt;
      pitchmod = 0.3,&lt;br /&gt;
      pitch = 0.7,&lt;br /&gt;
      in3d = true,&lt;br /&gt;
    },&lt;br /&gt;
  },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return Sounds&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Using PitchMod to prevent loud explosions====&lt;br /&gt;
Taken from this thread by jK: {{forumlink|topic=28819|title=Use PitchMod in sounds.lua to prevent loud explosions}}&lt;br /&gt;
&lt;br /&gt;
Explosions can sound louder than intended when they are started in the same simFrame and so are played in sync -&amp;gt; resonance. PitchMod now changes the playback time (e.g. with 0.3 the sounds should have a playback time of 100-130%) and so there isn&#039;t a resonance anymore even when the sound is started multiple times in the same simframe.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local files = VFS.DirList(&amp;quot;sounds/explosions/&amp;quot;)&lt;br /&gt;
local t = Sounds.SoundItems&lt;br /&gt;
for i=1,#files do&lt;br /&gt;
   local fileName = files[i]&lt;br /&gt;
   t[fileName] = {&lt;br /&gt;
      file     = fileName;&lt;br /&gt;
      pitchmod = 0.3;&lt;br /&gt;
      gainmod  = 0.2;&lt;br /&gt;
      maxconcurrent = 8;&lt;br /&gt;
   }&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===External Examples===&lt;br /&gt;
{{sourcelink|file=cont/base/springcontent/gamedata/sounds.lua}} - The original default &amp;lt;code&amp;gt;sounds.lua&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/ZeroK-RTS/Zero-K/blob/master/gamedata/sounds.lua ZeroK sounds.lua]&lt;br /&gt;
&lt;br /&gt;
==Further Reading==&lt;br /&gt;
{{forumlink|topic=17647&amp;amp;start=25|title=Information about sounds.lua}}&lt;br /&gt;
{{forumlink|topic=20685|title=Information about gainMod and pitchMod}}&lt;br /&gt;
[[Category:gamedata]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Modrules.lua&amp;diff=14468</id>
		<title>Modrules.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Modrules.lua&amp;diff=14468"/>
		<updated>2018-12-18T11:03:35Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Location==&lt;br /&gt;
&amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; is a file in the &amp;lt;code&amp;gt;Gamedata/&amp;lt;/code&amp;gt; directory of a Spring game. &lt;br /&gt;
&lt;br /&gt;
==Purpose==&lt;br /&gt;
This file controls various global parameters of the game, for example how fast units gain experience, what unit types can be transported, how fine grained the LOS system is, etc.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which parses the data from this file is viewable here:&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/Sim/Misc/ModInfo.cpp}}&lt;br /&gt;
&lt;br /&gt;
==Data Types==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
&amp;lt;code&amp;gt;Modrules.lua&amp;lt;/code&amp;gt; is divided into several sub-tables containing tags specific to each section, as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===capture===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much of the original energy cost it requires to capture something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===construction===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecay&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Do uncompleted building frames begin to decay if no builder is working on them?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecayTime&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 6.66&lt;br /&gt;
|description = The time in seconds before abandoned building frames begin to decay.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = constructionDecaySpeed&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.03&lt;br /&gt;
|description = How fast build progress decays for abandoned building frames. Note that the rate is inversely proportional to the {{xtaglink|Gamedev:UnitDefs|buildtime}} i.e. a building with a larger {{xtaglink|Gamedev:UnitDefs|buildtime}} will decay more slowly for a given value of this tag than a building with a shorter {{xtaglink|Gamedev:UnitDefs|buildtime}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===experience===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = experienceMult&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Controls the amount of experience gained by units engaging in combat. The formulae used are: &lt;br /&gt;
::&amp;lt;code&amp;gt;xp for damage = 0.1 * experienceMult * damage / target_HP * target_power / attacker_power&amp;lt;/code&amp;gt; &lt;br /&gt;
::&amp;lt;code&amp;gt;xp for kill = 0.1 * experienceMult * target_power / attacker_power&amp;lt;/code&amp;gt;. &lt;br /&gt;
: Where {{xtaglink|Gamedev:UnitDefs|power}} can be set by the UnitDef tag.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = powerScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Controls how gaining experience changes the relative {{xtaglink|Gamedev:UnitDefs|power}} of the unit. The formula used is &amp;lt;code&amp;gt;Power multiplier = powerScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = healthScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.7&lt;br /&gt;
|description = Controls how gaining experience increases the {{xtaglink|Gamedev:UnitDefs|maxDamage}} (total hitpoints) of the unit. The formula used is &amp;lt;code&amp;gt;Health multiplier = healthScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = reloadScale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.4&lt;br /&gt;
|description = Controls how gaining experience decreases the {{xtaglink|Gamedev:UnitDefs|reloadTime}} of the unit&#039;s weapons. The formula used is &amp;lt;code&amp;gt;Rate of fire multiplier = reloadScale * (1 + xp / (xp + 1))&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===featureLOS===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = featureVisibility&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 3&lt;br /&gt;
|description = Controls the visibility of features. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - no default LOS for features, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Gaia features always visible, &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; - allyteam &amp;amp; Gaia features always visible, or &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; - all features always visible.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===fireAtDead===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = fireAtKilled&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Will units continue to target and fire on enemies which are running their &amp;lt;code&amp;gt;Killed()&amp;lt;/code&amp;gt; animation? (See [[Animation-LuaCallins#Generic]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = fireAtCrashing&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Will units continue to target and fire on enemy aircraft which are in the &#039;crashing&#039; state? (See [[Lua_SyncedCtrl#Unit_Control]])&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===flankingBonus===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = defaultMode&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = The default {{xtaglink|Gamedev:UnitDefs|flankingBonusMode}} for units. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - No flanking bonus. Mode &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; builds up the ability to move over time, and swings to face attacks, but does not respect the way the unit is facing. Mode &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt; also can swing, but moves with the unit as it turns. Mode &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; stays with the unit as it turns and otherwise doesn&#039;t move, the ideal mode to simulate something such as tank armour. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====los====&lt;br /&gt;
{{tag&lt;br /&gt;
|name = losMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls the resolution of the LOS calculations. A higher value means lower resolution but increased performance. An increase by one level means half the resolution of the LOS map in both x and y direction. Must be between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;6&amp;lt;/code&amp;gt; inclusive.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = losMul&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|special = {{removed|101.0}}&lt;br /&gt;
|description = Multiplies all unit&#039;s {{xtaglink|Gamedev:UnitDefs|sightDistance}} by this value. Generally speaking you should always use the default.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = airMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls the resolution of the LOS vs. aircraft calculations. A higher value means lower resolution but increased performance. An increase by one level means half the resolution of the air-LOS map in both x and y direction. Must be between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;30&amp;lt;/code&amp;gt; inclusive. [http://springrts.com/mantis/view.php?id=4031#c11709] - jK describe for you what the value means.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = airLosMul&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|special = {{removed|101.0}}&lt;br /&gt;
|description = Multiplies all unit&#039;s {{xtaglink|Gamedev:UnitDefs|airSightDistance}} by this value. Generally speaking you should always use the default.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = radarMipLevel&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 2&lt;br /&gt;
|description = Controls the resolution of the radar. See description of airMipLevel for details.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===movement===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAirPlanesToLeaveMap&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Are (gunship) aircraft allowed to fly outside the bounds of the map?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAircraftToHitGround&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|90.0}}&lt;br /&gt;
|description = Are aircraft allowed to hit the ground whilst manoeuvring?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowPushingEnemyUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|83.0}}&lt;br /&gt;
|description = Can enemy ground units push each other during collisions?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowCrushingAlliedUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|85.0}}&lt;br /&gt;
|description = Can allied ground units crush each other during collisions? Units still have to be explicitly set as crushable using the &amp;lt;code&amp;gt;crushable&amp;lt;/code&amp;gt; parameter of [[Lua_SyncedCtrl#Unit_Control|Spring.SetUnitBlocking]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowUnitCollisionDamage&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|85.0}}&lt;br /&gt;
|description = Do unit-unit (skidding) collisions cause damage?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowUnitCollisionOverlap&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|89.0}}&lt;br /&gt;
|description = Can mobile units collision volumes overlap one another? Allows unit movement like [http://www.youtube.com/watch?v=mRtePUdVk2o this (video)] at the cost of more &#039;clumping&#039;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowGroundUnitGravity&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|92.0}}&lt;br /&gt;
|description = Allows fast moving mobile units to &#039;catch air&#039; as they move over terrain.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowHoverUnitStrafing&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true if using QTPFS pathfinder&lt;br /&gt;
|special = {{new|92.0}}&lt;br /&gt;
|description = Allows hovercraft units to slide in turns.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = useClassicGroundMoveType&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|89.0}} {{removed|102.0}}&lt;br /&gt;
|description = A ticket back to unit movement circa 2009: no reversing, no {{xtaglink|Gamedev:UnitDefs|turninplace|false}}, no smooth collision handling, no nothing. For comparison of pathfinding code.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===paralyze===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = paralyzeOnMaxHealth&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Are units paralyzed when the level of emp is greater than their current health or their maximum health?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===reclaim===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = multiReclaim&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = Can multiple units reclaim a feature or only one? &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; implies the latter, all other values the former.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = reclaimMethod&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls how features are reclaimed. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - gradual reclaim, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - all reclaimed at end, any other positive value &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; - reclaim in &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; chunks.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitMethod&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = Controls how units are reclaimed. Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - gradual reclaim, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - all reclaimed at end, any other positive value &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; - reclaim in &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; chunks.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = featureEnergyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much energy should reclaiming a feature cost? Multiplier against the fraction of the features&#039; {{xtaglink|Gamedev:FeatureDefs|metal}} content reclaimed.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitEnergyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much energy should reclaiming a unit cost? Multiplier against the fraction of the unit&#039;s {{xtaglink|Gamedev:UnitDefs|buildCostEnergy}} reclaimed. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unitEfficiency&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = How much metal should reclaiming a unit return? Multiplier against the unit&#039;s {{xtaglink|Gamedev:UnitDefs|buildCostMetal}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowEnemies&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can enemy units be reclaimed?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowAllies&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can allied units be reclaimed?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===repair===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much of the original energy cost it requires to repair something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===resurrect===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = energyCostFactor&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.5&lt;br /&gt;
|description = How much of the original energy cost it requires to resurrect something.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===sensors===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = requireSonarUnderWater&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = If &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; then when underwater, units only get LOS if they also have sonar.&lt;br /&gt;
}}&lt;br /&gt;
{{tag&lt;br /&gt;
|name = alwaysVisibleOverridesCloaked&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|101.0}}&lt;br /&gt;
|description = If &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; then units will be visible even when cloaked (probably?).&lt;br /&gt;
}}&lt;br /&gt;
{{tag&lt;br /&gt;
|name = separateJammers&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|101.0}}&lt;br /&gt;
|description = When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; each allyTeam only jams their own units.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===system===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pathFinderSystem&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|special={{new|85.0}}&lt;br /&gt;
|description = Which pathfinder does the game use? Can be &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; - The legacy default pathfinder or &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; - Quad-Tree Pathfinder System ([[QTPFS]]).}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pathFinderUpdateRate&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.007&lt;br /&gt;
|special={{new|98.0}}&lt;br /&gt;
|description = Controls how often the pathfinder updates; larger values means more rapid updates.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = allowTake&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|special = {{new|103.0}}&lt;br /&gt;
|description = Enables and disables the {{var|/take}} [[UI_commands|UI command]].}}&lt;br /&gt;
&lt;br /&gt;
===transportability===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportAir&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can aircraft be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportShip&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can ships be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportHover&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Can hovercraft be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = transportGround&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Can ground units be transported?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = targetableTransportedUnits&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|special = {{new|89.0}}&lt;br /&gt;
|description = Can transported units be targeted by weapons? &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; allows both manual and automatic targeting.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
===Empty===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; can simply return an empty table like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
return {}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you do this, Spring will use the default values.&lt;br /&gt;
&lt;br /&gt;
===Configurable by modoptions===&lt;br /&gt;
Interestingly &amp;lt;code&amp;gt;modrules.lua&amp;lt;/code&amp;gt; can read [[Modoptions.lua|modoptions]], so these parameters can be scripted to be configurable from the lobby.&lt;br /&gt;
For example to allow selecting either legacy default pathfinder or [[QTPFS]] via a modoption:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  system = {&lt;br /&gt;
    pathFinderSystem = (Spring.GetModOptions() and (Spring.GetModOptions().qtpfs == &amp;quot;1&amp;quot;) and 1) or 0,&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===External Examples===&lt;br /&gt;
[http://imolarpg.dyndns.org/trac/balatest/browser/trunk/gamedata/modrules.lua &#039;Balanced Annihilation&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/conflictterra/source/browse/games/CT/gamedata/modrules.lua &#039;Conflict Terra&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[https://code.google.com/p/evolutionrts/source/browse/trunk/evolutiondev.sdd/Gamedata/modrules.lua &#039;Evolution RTS&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://spring1944.svn.sourceforge.net/viewvc/spring1944/trunk/S44Main.sdd/gamedata/modrules.lua?&amp;amp;view=markup &#039;Spring: 1944&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/zero-k/source/browse/trunk/mods/zk/gamedata/modrules.lua &#039;ZeroK&#039; Modrules.lua]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:gamedata]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_SyncedRead&amp;diff=12062</id>
		<title>Lua SyncedRead</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_SyncedRead&amp;diff=12062"/>
		<updated>2018-12-15T14:56:07Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Features */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
== Game ==&lt;br /&gt;
&lt;br /&gt;
=== Special TeamID Variables ===&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(those special TeamIDs are not supported by all functions)&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.ALL_UNITS&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.MY_UNITS&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.ALLY_UNITS&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.ENEMY_UNITS&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;For Widgets, instead of Spring.MY_UNITS, use Spring.GetLocalTeamID()&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGaiaTeamID&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; number teamID&lt;br /&gt;
&lt;br /&gt;
=== GameStates ===&lt;br /&gt;
&#039;&#039;&#039;Spring.IsGodModeEnabled&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.IsCheatingEnabled&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.IsDevLuaEnabled&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.IsEditDefsEnabled&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.AreHelperAIsEnabled&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.FixedAllies&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; nil | boolean&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.IsGameOver&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
=== RulesParams ===&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Those functions allow to save data per Game,Team and Unit.&amp;lt;br&amp;gt;The advantage of it is that it can be read from anywhere (even from LuaUI and AIs!)&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span class=warning&amp;gt;string values are new since 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetRulesInfoMap&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;REMOVED in 0.82!&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( ) -&amp;gt; { [key1] = string value1, [key2] = string value2, ... }&lt;br /&gt;
  ( string &amp;quot;key&amp;quot; ) -&amp;gt; string&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGameRulesParam&#039;&#039;&#039;&lt;br /&gt;
  ( number ruleIndex | string ruleName ) -&amp;gt; nil | number value | string value&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGameRulesParams&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; nil | { [ruleName1] = number | string value1, ... }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamRulesParam&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, number index | string ruleName ) -&amp;gt; nil | number value | string value&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamRulesParams&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt; nil | { [ruleName1] = number | string value1, ... }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitRulesParam&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number index | string ruleName ) -&amp;gt; nil | number value | string value&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitRulesParams&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | { [ruleName1] = number | string value1, ... }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureRulesParam&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, number index | string ruleName ) -&amp;gt; nil | number value | string value&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureRulesParams&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | { [ruleName1] = number | string value1, ... }&lt;br /&gt;
&lt;br /&gt;
=== Mod-/Map-Options ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetModOptions&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; {} | { &amp;quot;keyName1&amp;quot; = string &amp;quot;value&amp;quot;, &amp;quot;keyName2&amp;quot; = string &amp;quot;value&amp;quot;, ... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetMapOptions&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; {} | { &amp;quot;keyName1&amp;quot; = string &amp;quot;value&amp;quot;, &amp;quot;keyName2&amp;quot; = string &amp;quot;value&amp;quot;, ... }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
! bool values are not transfered from C to Lua correctly, so in IF theres needed to use this condition:&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&amp;quot;if (tonumber(Spring.GetModOptions.exampleOption) == 1) then...end&amp;quot;&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
not only:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;&amp;quot;if (Spring.GetModOptions.exampleOption) then...end&amp;quot;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Speed/Time ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGameSpeed&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;As of 98.0 moved to [[Lua_UnsyncedRead]] due to desyncs in replays/demos&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( ) -&amp;gt; number userSpeedFactor, number speedFactor, boolean paused&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGameFrame&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; number frameNum%dayFrames, number frameNum/dayFrames&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGameSeconds&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; number seconds&lt;br /&gt;
&lt;br /&gt;
=== Vectors ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetWind&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; number dirX, number dirY, number dirZ, &lt;br /&gt;
         number strength,  number normDirX, number normDirY, number normDirZ&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetHeadingFromVector&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; number heading&lt;br /&gt;
&#039;&#039;&#039;Spring.GetVectorFromHeading&#039;&#039;&#039;&lt;br /&gt;
  ( number heading ) -&amp;gt; number x, number z&lt;br /&gt;
&lt;br /&gt;
== Sides/Factions ==&lt;br /&gt;
&#039;&#039;&#039;Spring.GetSideData&#039;&#039;&#039;&lt;br /&gt;
  ( string sideName ) -&amp;gt; nil | string startUnit, string caseSensitiveSideName&lt;br /&gt;
  ( number sideID ) -&amp;gt; nil | string sideName, string startUnit, string caseSensitiveSideName&lt;br /&gt;
  ( ) -&amp;gt; { [1] = { sideName=string,caseName=string,startUnit=string}, [2] = .., .. }&lt;br /&gt;
&lt;br /&gt;
== Teams ==&lt;br /&gt;
=== StartBoxes/StartPositions ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetAllyTeamStartBox&#039;&#039;&#039;&lt;br /&gt;
  ( number allyID ) -&amp;gt; nil | number xmin, number zmin, number xmax, number zmax&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamStartPosition&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt; nil | number x, number y, number z&lt;br /&gt;
&lt;br /&gt;
=== Player,Team,Ally Lists/Info ===&lt;br /&gt;
&lt;br /&gt;
Note: AIs are associated to teamIDs (and do not have playerIDs). Code to cycle through AI teamIDs can be found [https://springrts.com/phpbb/viewtopic.php?f=21&amp;amp;t=36873#p586026 here] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetPlayerList&#039;&#039;&#039;&lt;br /&gt;
  ( [number teamID = -1 | boolean onlyActive = false] [, number teamID | boolean onlyActive])&lt;br /&gt;
  -&amp;gt; nil | { [1] = number playerID, etc... }&lt;br /&gt;
From 104.0 onwards spectators will be ignored if a valid (&amp;gt;=0) teamID is given&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamList&#039;&#039;&#039;&lt;br /&gt;
  ( [number allyTeamID = -1] ) -&amp;gt; nil | { [1] = number teamID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetAllyTeamList&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; { [1] = number allyTeamID, etc... }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetPlayerInfo&#039;&#039;&#039;&lt;br /&gt;
  ( number playerID ) -&amp;gt; &lt;br /&gt;
    nil | string  &amp;quot;name&amp;quot;,  &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;(PRE-83.0: in synced code this is &amp;quot;SYNCED_NONAME&amp;quot;!)&amp;lt;/span&amp;gt;&lt;br /&gt;
          boolean active,&lt;br /&gt;
          boolean spectator,&lt;br /&gt;
          number  teamID,&lt;br /&gt;
          number  allyTeamID,&lt;br /&gt;
          number  pingTime,&lt;br /&gt;
          number  cpuUsage,&lt;br /&gt;
          string  country,&lt;br /&gt;
          number  rank&lt;br /&gt;
          table   customPlayerKeys&lt;br /&gt;
&#039;&#039;&#039;Spring.GetPlayerControlledUnit&#039;&#039;&#039;&lt;br /&gt;
  ( number playerID ) -&amp;gt; nil | number unitID&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetAIInfo&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt; &lt;br /&gt;
          number  skirmishAIID,&lt;br /&gt;
          string  name,&lt;br /&gt;
          number  hostingPlayerID,&lt;br /&gt;
          string  shortName, &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;(synced =&amp;gt; &amp;quot;SYNCED_NOSHORTNAME&amp;quot;; non-local =&amp;gt; &amp;quot;UNKNOWN&amp;quot;)&amp;lt;/span&amp;gt;&lt;br /&gt;
          string  version,   &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;(synced =&amp;gt; &amp;quot;SYNCED_NOVERSION&amp;quot;;   non-local =&amp;gt; &amp;quot;UNKNOWN&amp;quot;)&amp;lt;/span&amp;gt;&lt;br /&gt;
          table   options    &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;(synced &amp;amp; non-local =&amp;gt; empty-table)&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;Note: Before 0.82, the first argument was teamID, and then every other argument with a shifted position.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetAllyTeamInfo&#039;&#039;&#039;&lt;br /&gt;
  ( number allyteamID ) -&amp;gt; nil | table   customTeamKeys&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamInfo&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt;&lt;br /&gt;
    nil | number  teamID,&lt;br /&gt;
          number  leader, &amp;lt;span class=note&amp;gt;(:= a player id)&amp;lt;/span&amp;gt;&lt;br /&gt;
          boolean isDead,&lt;br /&gt;
          boolean isAiTeam,&lt;br /&gt;
          string  &amp;quot;side&amp;quot;,&lt;br /&gt;
          number  allyTeam,&lt;br /&gt;
          table   customTeamKeys,&lt;br /&gt;
          number  incomeMultiplier&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamResources&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, string &amp;quot;metal&amp;quot; | &amp;quot;energy&amp;quot; ) -&amp;gt;&lt;br /&gt;
    nil | number currentLevel,&lt;br /&gt;
          number storage,&lt;br /&gt;
          number pull,&lt;br /&gt;
          number income,&lt;br /&gt;
          number expense,&lt;br /&gt;
          number share,&lt;br /&gt;
          number sent,&lt;br /&gt;
          number received&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamUnitStats&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt;&lt;br /&gt;
    nil | number killed,&lt;br /&gt;
          number died,&lt;br /&gt;
          number capturedBy,&lt;br /&gt;
          number capturedFrom,&lt;br /&gt;
          number received,&lt;br /&gt;
          number sent&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamResourceStats&#039;&#039;&#039; &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;0.82 and later&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number teamID,  string &amp;quot;metal&amp;quot; | &amp;quot;energy&amp;quot; ) -&amp;gt;&lt;br /&gt;
    nil | number used,&lt;br /&gt;
          number produced,&lt;br /&gt;
          number excessed,&lt;br /&gt;
          number received,&lt;br /&gt;
          number sent&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamStatsHistory&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID [, number startIndex [, number endIndex = startIndex ]]) -&amp;gt;&lt;br /&gt;
    nil |&lt;br /&gt;
    number cur_max_index |&lt;br /&gt;
    {&lt;br /&gt;
      [1] = {&lt;br /&gt;
        &amp;quot;time&amp;quot;             = number,&lt;br /&gt;
        &amp;quot;frame&amp;quot;            = number,&lt;br /&gt;
        &amp;quot;metalUsed&amp;quot;        = number,&lt;br /&gt;
        &amp;quot;metalProduced&amp;quot;    = number,&lt;br /&gt;
        &amp;quot;metalExcess&amp;quot;      = number,&lt;br /&gt;
        &amp;quot;metalReceived&amp;quot;    = number,&lt;br /&gt;
        &amp;quot;metalSent&amp;quot;        = number,&lt;br /&gt;
        &amp;quot;energyUsed&amp;quot;       = number,&lt;br /&gt;
        &amp;quot;energyProduced&amp;quot;   = number,&lt;br /&gt;
        &amp;quot;energyExcess&amp;quot;     = number,&lt;br /&gt;
        &amp;quot;energyReceived&amp;quot;   = number,&lt;br /&gt;
        &amp;quot;energySent&amp;quot;       = number,&lt;br /&gt;
        &amp;quot;damageDealt&amp;quot;      = number,&lt;br /&gt;
        &amp;quot;damageReceived&amp;quot;   = number,&lt;br /&gt;
        &amp;quot;unitsProduced&amp;quot;    = number,&lt;br /&gt;
        &amp;quot;unitsDied&amp;quot;        = number,&lt;br /&gt;
        &amp;quot;unitsReceived&amp;quot;    = number,&lt;br /&gt;
        &amp;quot;unitsSent&amp;quot;        = number,&lt;br /&gt;
        &amp;quot;unitsCaptured&amp;quot;    = number,&lt;br /&gt;
        &amp;quot;unitsOutCaptured&amp;quot; = number,&lt;br /&gt;
        &amp;quot;unitsKilled&amp;quot;      = number&lt;br /&gt;
      }, ...&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;if called with just teamID as argument it returns the current possible range for startIndex/endIndex :={1..cur_max_index}&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamLuaAI&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt; string &amp;quot;luaAI&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Returns string containing name of AI defined in file LuaAI.lua as name=&amp;quot;&amp;lt;AI name&amp;gt;&amp;quot;. Maybe it returns whole table with all values there, so maybe depends, but in my LuaAI.lua name is on first position...&lt;br /&gt;
&lt;br /&gt;
=== Teams/PlayersAllied ===&lt;br /&gt;
&#039;&#039;&#039;Spring.AreTeamsAllied&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID1, number teamID2 ) -&amp;gt; nil | boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.ArePlayersAllied&#039;&#039;&#039;&lt;br /&gt;
  ( number playerID1, number playerID2 ) -&amp;gt; nil | boolean&lt;br /&gt;
&lt;br /&gt;
== Units ==&lt;br /&gt;
=== GetUnits ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetAllUnits&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; nil | unitTable = { [1] = number unitID, ... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamUnits&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt; nil | unitTable = { [1] = number unitID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamUnitsSorted&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt; nil |&lt;br /&gt;
    unitDefTable = {&lt;br /&gt;
      [number unitDefID] = { [1] = [number unitID], etc... },&lt;br /&gt;
      etc...&lt;br /&gt;
    }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamUnitsCounts&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt; nil | countTable = { [number unitDefID] = count, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamUnitsByDefs&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, number unitDefID | { number unitDefID1, ... } )&lt;br /&gt;
    -&amp;gt; nil | unitTable = { [1] = number unitID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamUnitDefCount&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, number unitDefID ) -&amp;gt; nil | number count&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTeamUnitCount&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID ) -&amp;gt; nil | number count&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitsInRectangle&#039;&#039;&#039;&lt;br /&gt;
  ( number xmin, number zmin, number xmax, number zmax [,number teamID] ) &lt;br /&gt;
    -&amp;gt; nil | unitTable = { [1] = number unitID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitsInBox&#039;&#039;&#039;&lt;br /&gt;
  ( number xmin, number ymin, number zmin,&lt;br /&gt;
    number xmax, number ymax, number zmax [,number teamID] )&lt;br /&gt;
    -&amp;gt; nil | unitTable = { [1] = number unitID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitsInSphere&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number y, number z, number radius [,number teamID] )&lt;br /&gt;
    -&amp;gt; nil | unitTable = { [1] = number unitID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitsInCylinder&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z, number radius [,number teamID] )&lt;br /&gt;
    -&amp;gt; nil | unitTable = { [1] = number unitID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitsInPlanes&#039;&#039;&#039;&lt;br /&gt;
  ( planes = { [1] = { number nx, number ny, number nz, number d }, etc... } )&lt;br /&gt;
    -&amp;gt; nil | unitTable = { [1] = number unitID, etc... }&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
  plane normals point towards accepted space,&lt;br /&gt;
  so the acceptance criteria for each plane is:&lt;br /&gt;
    radius     = unit radius&lt;br /&gt;
    px, py, pz = unit position&lt;br /&gt;
    [(nx * px) + (ny * py) + (nz * pz) + (d - radius)]  &amp;lt;=  0&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitNearestAlly&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number range ] ) -&amp;gt; nil | number unitID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitNearestEnemy&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number range [, bool useLOS]] ) -&amp;gt; nil | number unitID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Post 95.0 this no longer returns neutral units&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unit Informations ===&lt;br /&gt;
&#039;&#039;&#039;Spring.ValidUnitID&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitIsDead&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | boolean&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Returns false if unit exists and is alive, true for a brief period of time after unit dies, nil otherwise&amp;lt;br/&amp;gt;&lt;br /&gt;
keep this in mind when using (not Spring.GetUnitIsDead())&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitTooltip&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | string tooltip&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitDefID&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number unitDefID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitTeam&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number teamID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitAllyTeam&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number allyID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitLineage&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt; Removed from version 0.83.x&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number lineage | number lineage, boolean lineageIsRoot&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitNeutral&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | boolean neutral&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitHealth&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number health, number maxHealth, number paralyzeDamage,&lt;br /&gt;
                             number captureProgress, number buildProgress&lt;br /&gt;
build Progress is returned as floating Point between 0.0 and 1.0&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitArmored&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;armorMultiple new in version 0.83.x&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | boolean armored, number armorMultiple&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitIsStunned&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | boolean stunned_or_inbuild, boolean stunned, boolean inbuild&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitMaxRange&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number maxEngagementRange&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitResources&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number metalMake, number metalUse,&lt;br /&gt;
                             number energyMake, number energyUse&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitHarvestStorage&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number metal&lt;br /&gt;
&amp;lt;span class = &amp;quot;note&amp;quot;&amp;gt;See also {{xtaglink|Gamedev:UnitDefs|harvestStorage}} UnitDef tag.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitMetalExtraction&#039;&#039;&#039; &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;0.82+ and later&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitExperience&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number experience&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitStates&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | {&lt;br /&gt;
    &amp;quot;firestate&amp;quot; = number,&lt;br /&gt;
    &amp;quot;movestate&amp;quot; = number,&lt;br /&gt;
    &amp;quot;repeat&amp;quot; = boolean,&lt;br /&gt;
    &amp;quot;cloak&amp;quot; = boolean,&lt;br /&gt;
    &amp;quot;active&amp;quot; = boolean,&lt;br /&gt;
    &amp;quot;trajectory&amp;quot; = boolean,&lt;br /&gt;
    [&amp;quot;autoland&amp;quot; = boolean,]&lt;br /&gt;
    [&amp;quot;autorepairlevel&amp;quot; = number,]&lt;br /&gt;
    [&amp;quot;loopbackattack&amp;quot; = boolean]&lt;br /&gt;
  } &lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitIsActive&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitIsCloaked&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitSelfDTime&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitStockpile&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number numStockpiled, number numStockpileQued,&lt;br /&gt;
                             number buildPercent&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitHeight&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitRadius&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitMass&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitBlocking&#039;&#039;&#039; {{new|85.0}}&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | boolean blocking, boolean crushable&lt;br /&gt;
{{new|95.0}} Now return values are: &lt;br /&gt;
  boolean isBlocking,&lt;br /&gt;
  boolean isSolidObjectCollidable,&lt;br /&gt;
  boolean isProjectileCollidable,&lt;br /&gt;
  boolean isRaySegmentCollidable,&lt;br /&gt;
  boolean crushable,&lt;br /&gt;
  boolean blockEnemyPushing,&lt;br /&gt;
  boolean blockHeightChanges&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPosition&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, [, boolean midPos [, boolean aimPos ] ] ) -&amp;gt;&lt;br /&gt;
    nil |&lt;br /&gt;
    number bpx, number bpy, number bpz&lt;br /&gt;
    [, number mpx, number mpy, number mpz ]&lt;br /&gt;
    [, number apx, number apy, number apz ]&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;since 89.0, returns the base (default), middle or aim position of the unit.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitBasePosition&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;Deprecated in 89.0, use GetUnitPosition&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number x, number y, number z&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;returns the bottom of the unit.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitDirection&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number dx, number dy, number dz&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;returns the direction vector&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitHeading&#039;&#039;&#039; &lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number heading&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;returns heading directions used in COB scripts&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitRotation&#039;&#039;&#039; {{New|95.0}}&lt;br /&gt;
   (number unitID) --&amp;gt; nil | number pitch, number yaw, number roll &lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Marked as (WIP) in changelog&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitVelocity&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;velw new in 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number velx, number vely, number velz, number velLength&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitBuildFacing&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitIsBuilding&#039;&#039;&#039; &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;returns what unit a constructor/factory is currently building&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number unitID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitCurrentBuildPower&#039;&#039;&#039; {{new|92.0}}&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number buildPower&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitNanoPieces&#039;&#039;&#039; &lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | { [1] = number piece1, etc ... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitTransporter&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number unitID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitIsTransporting&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | { [1] = number unitID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitShieldState&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number weaponID = -1] ) -&amp;gt; nil | number isEnabled, number curPower&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitTravel&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number travel, number travelPeriod&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitFuel&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitFlanking&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string &amp;quot;dir&amp;quot; ) -&amp;gt; nil | number x, number y, number z&lt;br /&gt;
  ( number unitID, string &amp;quot;mode&amp;quot; | &amp;quot;moveFactor&amp;quot; | &amp;quot;minDamage&amp;quot; | &amp;quot;maxDamage&amp;quot; ) -&amp;gt; nil | number&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number mode, number modilityAdd,&lt;br /&gt;
    number minDamage, number maxDamage, number dirX, number dirY, number dirZ&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitSensorRadius&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string type ) -&amp;gt; nil | number radius&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;possible types are:&amp;lt;br&amp;gt;los, airLos, radar, sonar, seismic, radarJammer &amp;amp; sonarJammer&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitLosState&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;raw is only available in gadgets&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID [, number allyTeamID [, boolean raw] ] ) -&amp;gt; nil | number raw |&lt;br /&gt;
  { [&amp;quot;los&amp;quot; = true] [, &amp;quot;radar&amp;quot; = true] [, &amp;quot;typed&amp;quot; = true] }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitSeparation&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;surfaceDist new in 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID1, number unitID2 [, boolean 2D] [, boolean surfaceDist] ) -&amp;gt; nil | number distance&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;returns the distance of 2 units, surfaceDist calculates the distance between the unitsphere surfaces instead of their midpos&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitFeatureSeparation&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number featureID [, boolean 2D] ) -&amp;gt; nil | number distance&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitDefDimensions&#039;&#039;&#039;&lt;br /&gt;
  ( number unitDefID ) -&amp;gt; nil |&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;height&amp;quot; = number,&lt;br /&gt;
      &amp;quot;radius&amp;quot; = number,&lt;br /&gt;
      &amp;quot;midx&amp;quot;   = number,&lt;br /&gt;
      &amp;quot;minx&amp;quot;   = number,&lt;br /&gt;
      &amp;quot;maxx&amp;quot;   = number,&lt;br /&gt;
      &amp;quot;midy&amp;quot;   = number,&lt;br /&gt;
      &amp;quot;miny&amp;quot;   = number,&lt;br /&gt;
      &amp;quot;maxy&amp;quot;   = number,&lt;br /&gt;
      &amp;quot;midz&amp;quot;   = number,&lt;br /&gt;
      &amp;quot;minz&amp;quot;   = number,&lt;br /&gt;
      &amp;quot;maxz&amp;quot;   = number&lt;br /&gt;
    }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitLastAttacker&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | number unitID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitLastAttackedPiece&#039;&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | string pieceName, number gameframe&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitMoveTypeData&#039;&#039;&#039; &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;new in version 0.80+&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | { movetype data }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitCollisionVolumeData&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID )&lt;br /&gt;
  -&amp;gt; number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
  number offsetX, number offsetY, number offsetZ,&lt;br /&gt;
  number volumeType, number testType, number primaryAxis, boolean disabled&lt;br /&gt;
&lt;br /&gt;
==== Unit Weapon Informations ====&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponState&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number weaponNum ) -&amp;gt; nil |&lt;br /&gt;
    boolean angleGood, boolean loaded, number reloadFrame, number salvoLeft, number numStockpiled&lt;br /&gt;
  ( number unitID, number weaponNum, string tag ) -&amp;gt; nil | number&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;`tag` can be:&lt;br /&gt;
  &amp;quot;reloadState&amp;quot; == &amp;quot;reloadFrame&amp;quot;&lt;br /&gt;
  &amp;quot;reloadTime&amp;quot;&lt;br /&gt;
  &amp;quot;accuracy&amp;quot;&lt;br /&gt;
  &amp;quot;sprayAngle&amp;quot;&lt;br /&gt;
  &amp;quot;range&amp;quot;&lt;br /&gt;
  &amp;quot;projectileSpeed&amp;quot;&lt;br /&gt;
  &amp;quot;burst&amp;quot;&lt;br /&gt;
  &amp;quot;burstRate&amp;quot;&lt;br /&gt;
  &amp;quot;projectiles&amp;quot;&lt;br /&gt;
  The following 4 tags were added in 104.0:&lt;br /&gt;
  &amp;quot;salvoError&amp;quot;&lt;br /&gt;
  &amp;quot;salvoLeft&amp;quot;&lt;br /&gt;
  &amp;quot;nextSalvo&amp;quot;&lt;br /&gt;
  &amp;quot;targetMoveError&amp;quot;&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponDamages&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number weaponNum | &amp;quot;selfDestruct&amp;quot; | &amp;quot;explode&amp;quot;, string tag ) -&amp;gt; nil | number&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;`tag` can be:&lt;br /&gt;
  &amp;quot;paralyzeDamageTime&amp;quot;&lt;br /&gt;
  &amp;quot;impulseFactor&amp;quot;&lt;br /&gt;
  &amp;quot;impulseBoost&amp;quot;&lt;br /&gt;
  &amp;quot;craterMult&amp;quot;&lt;br /&gt;
  &amp;quot;craterBoost&amp;quot;&lt;br /&gt;
  &amp;quot;dynDamageExp&amp;quot;&lt;br /&gt;
  &amp;quot;dynDamageMin&amp;quot;&lt;br /&gt;
  &amp;quot;dynDamageRange&amp;quot;&lt;br /&gt;
  &amp;quot;dynDamageInverted&amp;quot;&lt;br /&gt;
  &amp;quot;craterAreaOfEffect&amp;quot;&lt;br /&gt;
  &amp;quot;damageAreaOfEffect&amp;quot;&lt;br /&gt;
  &amp;quot;edgeEffectiveness&amp;quot;&lt;br /&gt;
  &amp;quot;explosionSpeed&amp;quot;&lt;br /&gt;
  - or -&lt;br /&gt;
  an armor type index to get the damage against it.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponVectors&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number weaponNum ) -&amp;gt; nil | number posX, number posY, number posZ,&lt;br /&gt;
    number dirX, number dirY, number dirZ&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponTryTarget&#039;&#039;&#039; {{new|94.0}}&lt;br /&gt;
  ( number unitID, number weaponNum, &lt;br /&gt;
    number targetID | number posX, number posY, number posZ ) -&amp;gt; nil | boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponTestTarget&#039;&#039;&#039; {{new|94.0}}&lt;br /&gt;
  ( number unitID, number weaponNum, &lt;br /&gt;
    number targetID | number posX, number posY, number posZ ) -&amp;gt; nil | boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponTestRange&#039;&#039;&#039; {{new|94.0}}&lt;br /&gt;
  ( number unitID, number weaponNum, &lt;br /&gt;
    number targetID | number posX, number posY, number posZ ) -&amp;gt; nil | boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponHaveFreeLineOfFire&#039;&#039;&#039; {{new|94.0}}&lt;br /&gt;
  ( number unitID, number weaponNum, &lt;br /&gt;
    number targetID | number posX, number posY, number posZ ) -&amp;gt; nil | boolean success&lt;br /&gt;
&lt;br /&gt;
From 104.0 onwards the param list changes so that source firing position can also be passed:&lt;br /&gt;
&lt;br /&gt;
  ( unitID, weaponNum, &lt;br /&gt;
    targetID | [srcPosX [, srcPosY [, srcPosZ [, tgtPosX [, tgtPosY [, tgtPosZ ]]]]]] ) -&amp;gt; nil | boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponCanFire&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  ( number unitID, number weaponNum ) -&amp;gt; nil | boolean canFire&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitWeaponTarget&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  ( number unitID, number weaponNum ) -&amp;gt; nil |&lt;br /&gt;
  number 0 | number 1, bool isUserTarget, number unitID | &lt;br /&gt;
  number 2, bool isUserTarget, { number posX, number posY, number posZ } | &lt;br /&gt;
  number 3, bool isUserTarget, number ProjectileID&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;returned number of args is always 3 if targetType != None&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetRadarErrorParams&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  (number allyTeamID) --&amp;gt; nil | &lt;br /&gt;
  number allyteamErrorSize, number baseErrorSize, number baseErrorMult&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPosErrorParams&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  (number unitID) --&amp;gt; nil |&lt;br /&gt;
       number posErrorVector.x, number posErrorVector.y, number posErrorVector.z,&lt;br /&gt;
       number posErrorDelta.x, number posErrorDelta.y, number posErrorDelta.z,&lt;br /&gt;
       number nextPosErrorUpdate&lt;br /&gt;
&lt;br /&gt;
==== Unit LOS ====&lt;br /&gt;
&#039;&#039;&#039;Spring.IsUnitInLos&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number allyID ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.IsUnitInAirLos&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number allyID ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.IsUnitInRadar&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number allyID ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.IsUnitInJammer&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number allyID ) -&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
=== Unit Pieces ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitVectors&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | {frontX,frontY,frontZ}, {upX,upY,upZ}, {rightX,rightY,rightZ}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPiecePosition&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number piece ) -&amp;gt; number posx, number posy, number posz&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Returns piece position in unit space. Also remember to multiply the x-axis value with -1 if you want  move a piece to another piece.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPieceDirection&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Fixed since 101. Now returns the same direction as Spring.GetUnitPiecePosDir&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID, number piece ) -&amp;gt; number dirx, number diry, number dirz&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPiecePosDir&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number pieceNum ) -&amp;gt; nil | number posX, number posY, number posZ,&lt;br /&gt;
    number dirX, number dirZ, number dirY&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Returns piece position and direction in world space. The direction (dirX, dirY, dirZ) is not necessarily normalized. The position is defined as the position of the first vertex of the piece and it defines direction as the direction in which the line from the first vertex to the second vertex points.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPieceMatrix&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number piece ) -&amp;gt; { [1] = number, ... , [16] = number }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPieceList&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; { [1] = string &amp;quot;piecename&amp;quot;, ... , [pieceNumN] = string &amp;quot;piecename&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPieceMap&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; { &amp;quot;piecename1&amp;quot; = pieceNum1, ... , &amp;quot;piecenameN&amp;quot; = pieceNumN }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPieceInfo&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number piece ) -&amp;gt; {&lt;br /&gt;
    &amp;quot;name&amp;quot;     = string &amp;quot;piecename&amp;quot;,&lt;br /&gt;
    &amp;quot;isEmpty&amp;quot;  = boolean,&lt;br /&gt;
    &amp;quot;children&amp;quot; = { [1] = string &amp;quot;piecename&amp;quot;, ... },&lt;br /&gt;
    &amp;quot;min&amp;quot;      = { [1] = number x, [2] = number y, [3] = number z },&lt;br /&gt;
    &amp;quot;max&amp;quot;      = { [1] = number x, [2] = number y, [3] = number z },&lt;br /&gt;
    &amp;quot;offset&amp;quot;   = { [1] = number x, [2] = number y, [3] = number z }, &lt;br /&gt;
    &amp;quot;parent&amp;quot; = string &amp;quot;parentpiecename&amp;quot;,   &lt;br /&gt;
  }&lt;br /&gt;
{{new|95.0}} &amp;quot;parent&amp;quot; field&lt;br /&gt;
{{new|101.0}} parent for root pieces is now &amp;quot;[null]&amp;quot; instead of &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitScriptPiece&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number scriptPiece ] )&lt;br /&gt;
   -&amp;gt; nil | { scriptPieceNum = number modelPieceNum } | number modelPieceNum&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;This functions translate the COB ScriptPiece numbers into the ModelPiece numbers (the set of ScriptPieces is a subset of the ModelPieces, means #ScriptPieces &amp;lt;= #ModelPieces), which is used in all other functions (the &amp;quot;number piece&amp;quot; means always the modelpiece). So if you get via Cob2Lua a pieceID you have to translate it with this function. Btw the COB ScriptPiece number is equal with the piece position in the &amp;lt;i&amp;gt;piece&amp;lt;/i&amp;gt; definition in your cob/bos.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitScriptNames&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID )&lt;br /&gt;
   -&amp;gt; { &amp;quot;cobpiecename1&amp;quot; = ScriptPieceNum1, ... , &amp;quot;cobpiecenameN&amp;quot; = ScriptPieceNumN }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitPieceCollisionVolumeData&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number pieceID )&lt;br /&gt;
  -&amp;gt; number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
  number offsetX, number offsetY, number offsetZ,&lt;br /&gt;
  number volumeType, number testType, number primaryAxis, boolean disabled&lt;br /&gt;
As of 101.0 this is 1-based piece index argument (was 0-based).&lt;br /&gt;
&lt;br /&gt;
=== CommandQueues ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitCommands&#039;&#039;&#039; &amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.GetCommandQueue&#039;&#039;&#039; &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;(Alias)&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID, number count = 0 ) -&amp;gt; nil | number commandQueueSize {{new|96}}&lt;br /&gt;
  ( number unitID [, number count = -1] ) &lt;br /&gt;
  -&amp;gt; nil | table commandQueueTable = {&lt;br /&gt;
     [1] = {&lt;br /&gt;
       &amp;quot;id&amp;quot;      = number,&lt;br /&gt;
       &amp;quot;params&amp;quot;  = { [1] = number, ...},&lt;br /&gt;
       &amp;quot;options&amp;quot; = {&lt;br /&gt;
         &amp;quot;coded&amp;quot;    = number,&lt;br /&gt;
         &amp;quot;alt&amp;quot;      = boolean,&lt;br /&gt;
         &amp;quot;ctrl&amp;quot;     = boolean,&lt;br /&gt;
         &amp;quot;shift&amp;quot;    = boolean,&lt;br /&gt;
         &amp;quot;right&amp;quot;    = boolean,&lt;br /&gt;
         &amp;quot;internal&amp;quot; = boolean,&lt;br /&gt;
         &amp;quot;meta&amp;quot;    = boolean&lt;br /&gt;
       }&lt;br /&gt;
     }, ...&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;This function can trigger an error if called too often without passing a second parameter. Refer to [https://github.com/spring/spring/blob/92c54d5b15775c39a8c67b203c28fe9b9db51cea/rts/Lua/LuaSyncedRead.cpp#L3983-L3996 LuaSyncedRead.cpp#L3983-L3996]&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFullBuildQueue&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt;&lt;br /&gt;
  nil | buildOrders = {&lt;br /&gt;
          [1] = { [number unitDefID] = number count },  etc...&lt;br /&gt;
        }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetRealBuildQueue&#039;&#039;&#039; &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;(cleans the buildqueue of things the unit can&#039;t build itself)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID ) -&amp;gt;&lt;br /&gt;
  nil | buildOrders = {&lt;br /&gt;
          [1] = { [number unitDefID] = number count },  etc...&lt;br /&gt;
        }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFactoryCommands&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number count = 0 ) -&amp;gt; nil | number commandQueueSize {{new|96}}&lt;br /&gt;
  ( number unitID [, number count = -1 ] ) &lt;br /&gt;
  -&amp;gt; nil | table commandQueueTable = {&lt;br /&gt;
     [1] = {&lt;br /&gt;
       &amp;quot;id&amp;quot;      = number,&lt;br /&gt;
       &amp;quot;params&amp;quot;  = { [1] = number, ...},&lt;br /&gt;
       &amp;quot;options&amp;quot; = {&lt;br /&gt;
         &amp;quot;coded&amp;quot;    = number,&lt;br /&gt;
         &amp;quot;alt&amp;quot;      = boolean,&lt;br /&gt;
         &amp;quot;ctrl&amp;quot;     = boolean,&lt;br /&gt;
         &amp;quot;shift&amp;quot;    = boolean,&lt;br /&gt;
         &amp;quot;right&amp;quot;    = boolean,&lt;br /&gt;
         &amp;quot;internal&amp;quot; = boolean,&lt;br /&gt;
         &amp;quot;meta&amp;quot;    = boolean&lt;br /&gt;
       }&lt;br /&gt;
     }, ...&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFactoryCounts&#039;&#039;&#039; (used to get the buildqueue of a factory, seems screwed o_O)&lt;br /&gt;
  ( number unitID [, number count [, boolean addCMDs ] ] ) -&amp;gt; nil | commandQueueTable = {&lt;br /&gt;
     [2] = { [number unitDefID | number -cmdID] = number count }, ...&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
=== Command Descriptions/Buttons ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitCmdDescs&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number startIndex [, number endIndex ] ] ) -&amp;gt; nil | {&lt;br /&gt;
      [1] = {&lt;br /&gt;
        &amp;quot;id&amp;quot;          = number,&lt;br /&gt;
        &amp;quot;type&amp;quot;        = number,&lt;br /&gt;
        &amp;quot;name&amp;quot;        = string,&lt;br /&gt;
        &amp;quot;action&amp;quot;      = string,&lt;br /&gt;
        &amp;quot;tooltip&amp;quot;     = string,&lt;br /&gt;
        &amp;quot;texture&amp;quot;     = string,&lt;br /&gt;
        &amp;quot;cursor&amp;quot;      = string,&lt;br /&gt;
        &amp;quot;hidden&amp;quot;      = boolean,&lt;br /&gt;
        &amp;quot;disabled&amp;quot;    = boolean,&lt;br /&gt;
        &amp;quot;showUnique&amp;quot;  = boolean,&lt;br /&gt;
        &amp;quot;onlyTexture&amp;quot; = boolean,&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;params&amp;quot;      = { [1] = string, ... }&lt;br /&gt;
     }, ...&lt;br /&gt;
   }&lt;br /&gt;
&#039;&#039;&#039;Spring.FindUnitCmdDesc&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number cmdID ) -&amp;gt; nil | number index&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
=== GetFeatures ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturesInRectangle&#039;&#039;&#039;&lt;br /&gt;
  ( number xmin, number zmin, number xmax, number zmax )&lt;br /&gt;
    -&amp;gt; featureTable = { [1] = number featureID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturesInSphere&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number y, number z, number radius )&lt;br /&gt;
    -&amp;gt; featureTable = { [1] = number featureID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturesInCylinder&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z, number radius )&lt;br /&gt;
    -&amp;gt; featureTable = { [1] = number featureID, etc... }&lt;br /&gt;
&#039;&#039;&#039;Spring.GetAllFeatures&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; { [1] = number featureID, ... }&lt;br /&gt;
&lt;br /&gt;
=== Feature Informations ===&lt;br /&gt;
&#039;&#039;&#039;Spring.ValidFeatureID&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureDefID&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number featureDefID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureTeam&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number teamID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureAllyTeam&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number allyID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureHealth&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number health, number maxHealth, number resurrectProgress&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureHeight&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureRadius&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureMass&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureSeparation&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number featureID1, number featureID2 [, boolean 2D] ) -&amp;gt; nil | number distance&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePosition&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, [, boolean midPos [, boolean aimPos ] ] ) -&amp;gt;&lt;br /&gt;
  nil |&lt;br /&gt;
  number bpx, number bpy, number bpz [,&lt;br /&gt;
  number mpx, number mpy, number mpz [,&lt;br /&gt;
  number apx, number apy, number apz ]]&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;since 89.0, returns the base (default), middle or aim position of the feature.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureVelocity&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  ( number featureID [, boolean norm] )&lt;br /&gt;
  -&amp;gt; nil | number velx, number vely, number velz, number velLength&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureDirection&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number dirx, number diry, number dirz&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureRotation&#039;&#039;&#039; {{New|101.0}}&lt;br /&gt;
   (number featureID) --&amp;gt; nil | number pitch, number yaw, number roll &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureHeading&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number heading&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureResources&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;reclaimTime&amp;lt;/span&amp;gt; {{new|105.0}}&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | number RemainingMetal, number maxMetal,&lt;br /&gt;
                                number RemainingEnergy, number maxEnergy, number reclaimLeft, number reclaimTime&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureNoSelect&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | boolean noSelect&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureResurrect&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil | string UnitDefName, number buildFacing&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureCollisionVolumeData&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID )&lt;br /&gt;
  -&amp;gt; number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
  number offsetX, number offsetY, number offsetZ,&lt;br /&gt;
  number volumeType, number testType, number primaryAxis, boolean disabled&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePieceCollisionVolumeData&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number featuerID, number pieceID )&lt;br /&gt;
  -&amp;gt; number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
  number offsetX, number offsetY, number offsetZ,&lt;br /&gt;
  number volumeType, number testType, number primaryAxis, boolean disabled&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureBlocking&#039;&#039;&#039;&lt;br /&gt;
  (number featureID) --&amp;gt; boolean collidable, boolean crushable, boolean blocking&lt;br /&gt;
{{new|95.0}} Now return values are: &lt;br /&gt;
  boolean isBlocking,&lt;br /&gt;
  boolean isSolidObjectCollidable,&lt;br /&gt;
  boolean isProjectileCollidable,&lt;br /&gt;
  boolean isRaySegmentCollidable,&lt;br /&gt;
  boolean crushable,&lt;br /&gt;
  boolean blockEnemyPushing,&lt;br /&gt;
  boolean blockHeightChanges&lt;br /&gt;
&lt;br /&gt;
=== Feature Pieces ===&lt;br /&gt;
See #Unit_Pieces for full details.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeatureLastAttackedPiece&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePieceMap&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePieceList&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePieceInfo&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePiecePosition&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePieceDirection&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePiecePosDir&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetFeaturePieceMatrix&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== COB ==&lt;br /&gt;
&#039;&#039;&#039;Spring.GetCOBUnitVar&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, integer varID [, boolean unpack = false ] )&lt;br /&gt;
   -&amp;gt; nil | number value | number unpackedX, number unpackedY&lt;br /&gt;
&#039;&#039;&#039;Spring.GetCOBTeamVar&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, integer varID [, boolean unpack = false ] )&lt;br /&gt;
   -&amp;gt; nil | number value | number unpackedX, number unpackedY&lt;br /&gt;
&#039;&#039;&#039;Spring.GetCOBAllyTeamVar&#039;&#039;&#039;&lt;br /&gt;
  ( number allyID, integer varID [, boolean unpack = false ] )&lt;br /&gt;
   -&amp;gt; nil | number value | number unpackedX, number unpackedY&lt;br /&gt;
&#039;&#039;&#039;Spring.GetCOBGlobalVar&#039;&#039;&#039;&lt;br /&gt;
  ( integer varID [, boolean unpack = false ] )&lt;br /&gt;
   -&amp;gt; nil | number value | number unpackedX, number unpackedY&lt;br /&gt;
&lt;br /&gt;
== Ground ==&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Elevation is y. Water level is always at y=0. Ground height can be changed during play (terraform or deformation).&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGroundHeight&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; number y&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGroundOrigHeight&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; number y&lt;br /&gt;
&#039;&#039;This returns the ground original (before terraforming) height at a given x,z position&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGroundNormal&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z [, smoothedNormal] ) -&amp;gt; number x, number y, number z, number slope &lt;br /&gt;
{{new|100.0}}&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;: smoothedNormal and slope&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGroundInfo&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; string &amp;quot;Type&amp;quot;, number metal, number hardness,&lt;br /&gt;
                            number tankSpeed, number kbotSpeed, number hoverSpeed,&lt;br /&gt;
                            number shipSpeed, boolean receiveTracks&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGroundBlocked&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z |&lt;br /&gt;
    number x1, number z1, number x2, number z2 )&lt;br /&gt;
    -&amp;gt; nil |  string &amp;quot;feature&amp;quot;, number featureID  |  string &amp;quot;unit&amp;quot;, number unitID&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGroundExtremes&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; nil | number minHeight, number maxHeight&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetSmoothMeshHeight&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; number y&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetMetalMapSize&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; number sizeX, number sizeY&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetMetalAmount&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; number metalAmount &lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;where x &amp;amp; z are in metal map coordinates (worldspace/16)&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetMetalExtraction&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; number extractionAmount &lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;where x &amp;amp; z are in metal map coordinates (worldspace/16)&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetTerrainTypeData&#039;&#039;&#039; {{new|92.0}}&lt;br /&gt;
  ( number i )&lt;br /&gt;
    -&amp;gt; nil |  string &amp;quot;name&amp;quot;, number hardness,&lt;br /&gt;
              number tankSpeed, number kbotSpeed, number hoverSpeed, number shipSpeed,&lt;br /&gt;
              boolean receiveTracks&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetGrass&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; number 0 | 1 &lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;where x &amp;amp; z are in worldspace coordinates&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Test Orders ===&lt;br /&gt;
&#039;&#039;&#039;Spring.TestMoveOrder&#039;&#039;&#039;&lt;br /&gt;
  ( number unitDefID, number x, number y, number z) -&amp;gt; boolean validMove&lt;br /&gt;
{{New|95.0}} parameters now are:&lt;br /&gt;
    number unitDefID,&lt;br /&gt;
    number pos.x, number pos.y, number pos.z&lt;br /&gt;
    [, number dir.x&lt;br /&gt;
    [, number dir.y&lt;br /&gt;
    [, number dir.z&lt;br /&gt;
    [, boolean testTerrain&lt;br /&gt;
    [, boolean testObjects&lt;br /&gt;
    [, boolean centerOnly ]]]]]]&lt;br /&gt;
    ) --&amp;gt; boolean &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.TestBuildOrder&#039;&#039;&#039;&lt;br /&gt;
  ( number unitDefID, number x, number y, number z, number facing)&lt;br /&gt;
    -&amp;gt; number blocking [,number featureID]&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;blocking can be:&lt;br /&gt;
    0 - blocked&lt;br /&gt;
    1 - mobile unit in the way&lt;br /&gt;
    2 - free  (or if featureID is != nil then with a blocking feature that can be reclaimed)&lt;br /&gt;
  facing can be:&lt;br /&gt;
    0, &amp;quot;s&amp;quot;, &amp;quot;south&amp;quot;&lt;br /&gt;
    1, &amp;quot;e&amp;quot;, &amp;quot;east&amp;quot;&lt;br /&gt;
    2, &amp;quot;n&amp;quot;, &amp;quot;north&amp;quot;&lt;br /&gt;
    3, &amp;quot;w&amp;quot;, &amp;quot;west&amp;quot;&amp;lt;/font&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.Pos2BuildPos&#039;&#039;&#039; &amp;lt;font color=&amp;quot;#FF0000&amp;quot;&amp;gt;optional param &#039;&#039;facing&#039;&#039; supported in 0.83 and later&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitDefID, number x, number y, number z[, number facing] ) &lt;br /&gt;
    -&amp;gt; nil | number x, number y, number z&lt;br /&gt;
&lt;br /&gt;
=== PathFinding ===&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitEstimatedPath&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil | {&lt;br /&gt;
     [1] = { x,y,z }, ...&lt;br /&gt;
   },{&lt;br /&gt;
     [1] = startIdxOfDetailedPath,&lt;br /&gt;
     [2] = startIdxOfDetailedEstimatedPath1,&lt;br /&gt;
     [3] = startIdxOfDetailedEstimatedPath2,&lt;br /&gt;
   }&lt;br /&gt;
  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;GetUnitEstimatedPath() returns 2 tables:&lt;br /&gt;
    1 table the waypoints and 1 table with indices (in the waypoint table)&lt;br /&gt;
    when a new (more lazy) pathfinding algorithm  begins.&lt;br /&gt;
    So the waypoint table contains 3 different levels of details.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LOS ===&lt;br /&gt;
&#039;&#039;&#039;Spring.IsPosInLos&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number y, number z, number allyID ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.IsPosInRadar&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number y, number z, number allyID ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.IsPosInAirLos&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number y, number z, number allyID ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.GetPositionLosState&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;jammed new in 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number x, number y, number z [, number allyID] )&lt;br /&gt;
    -&amp;gt; boolean LosOrRadar, boolean inLos, boolean inRadar, boolean jammed&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;jammed indicates if a position is actively being radar- or sonar-jammed by &#039;&#039;&#039;any&#039;&#039;&#039; allyteam&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetClosestValidPosition&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;//NOT FINISHED YET&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitDefID, number x, number z, number r ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Projectiles ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectilesInRectangle&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 ( number xmin, number zmin, number xmax, number zmax&lt;br /&gt;
   [, boolean excludeWeaponProjectiles&lt;br /&gt;
   [, boolean excludePieceProjectiles] ] )&lt;br /&gt;
   -&amp;gt; nil | projectileTable = { [1] = number projectileID, etc... }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileOwnerID&#039;&#039;&#039; {{new|99.0}}&lt;br /&gt;
   (number projectileID) -&amp;gt; nil | number unitID&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileTeamID&#039;&#039;&#039; {{new|99.0}}&lt;br /&gt;
   (number projectileID) -&amp;gt; nil | number teamID&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileDefID&#039;&#039;&#039;&lt;br /&gt;
   (number projectileID) -&amp;gt; nil | number weaponDefID&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;using this to get a weaponDefID is HIGHLY preferred &amp;lt;br/&amp;gt; to indexing WeaponDefNames via GetProjectileName&amp;lt;span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileName&#039;&#039;&#039;&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | string name&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileType&#039;&#039;&#039;&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | boolean weapon, boolean piece&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileTarget&#039;&#039;&#039;&lt;br /&gt;
  ( number projectileID )&lt;br /&gt;
  &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;Pre 95.0:&amp;lt;/span&amp;gt;  -&amp;gt; nil | number targetID, string &amp;lt;span class=note&amp;gt;targetTypeStr&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;Post 95.0:&amp;lt;/span&amp;gt; -&amp;gt; nil | [number &amp;lt;span class=note&amp;gt;targetTypeInt&amp;lt;/span&amp;gt;, number targetID | table targetPos = {x, y, z}]&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;targetTypeStr can be one of: &lt;br /&gt;
    &#039;u&#039; - unit&lt;br /&gt;
    &#039;f&#039; - feature&lt;br /&gt;
    &#039;p&#039; - projectile&lt;br /&gt;
  while targetTypeInt is one of:&lt;br /&gt;
    string.byte(&#039;g&#039;) := GROUND&lt;br /&gt;
    string.byte(&#039;u&#039;) := UNIT&lt;br /&gt;
    string.byte(&#039;f&#039;) := FEATURE&lt;br /&gt;
    string.byte(&#039;p&#039;) := PROJECTILE&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileIntercepted&#039;&#039;&#039; {{new|99.0}}&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | boolean isBeingIntercepted&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectilePosition&#039;&#039;&#039;&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | number px, number py, number pz&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileVelocity&#039;&#039;&#039;&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | number vx, number vy, number vz&lt;br /&gt;
  {{new|95.0}}: returns (targetPos - startPos) for Beamlasers and similar weapons&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileGravity&#039;&#039;&#039;&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | number gravity&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetPieceProjectileParams&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil |  number explosionFlags, number spinAngle, &lt;br /&gt;
  number spinSpeed, number spinVector.x, number spinVector.y, number spinVector.z&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;Where explosionFlags use binary flags with the following integer equivalents: &lt;br /&gt;
   more info [http://springrts.com/wiki/Animation-CobConstants#explode here]&lt;br /&gt;
   SHATTER = 1,  EXPLODE = 2, EXPLODE_ON_HIT = 2, FALL = 4, SMOKE = 8, FIRE = 16&lt;br /&gt;
   NONE = 32, NO_CEG_TRAIL = 64, NO_HEATCLOUD = 128   &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileTimeToLive&#039;&#039;&#039; {{new|99.0}}&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | number ttl&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileDirection&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | number dir.x, number dir.y, number dir.z&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileSpinAngle&#039;&#039;&#039;  &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;Deprecated in 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | number angle&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileSpinSpeed&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;Deprecated in 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | number spinSpeed&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileSpinVec&#039;&#039;&#039;  &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;Deprecated in 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number projectileID ) -&amp;gt; nil | number x, number y, number z&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetProjectileDamages&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number weaponNum, string tag ) -&amp;gt; nil | number&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;`tag` can be:&lt;br /&gt;
  &amp;quot;paralyzeDamageTime&amp;quot;&lt;br /&gt;
  &amp;quot;impulseFactor&amp;quot;&lt;br /&gt;
  &amp;quot;impulseBoost&amp;quot;&lt;br /&gt;
  &amp;quot;craterMult&amp;quot;&lt;br /&gt;
  &amp;quot;craterBoost&amp;quot;&lt;br /&gt;
  &amp;quot;dynDamageExp&amp;quot;&lt;br /&gt;
  &amp;quot;dynDamageMin&amp;quot;&lt;br /&gt;
  &amp;quot;dynDamageRange&amp;quot;&lt;br /&gt;
  &amp;quot;dynDamageInverted&amp;quot;&lt;br /&gt;
  &amp;quot;craterAreaOfEffect&amp;quot;&lt;br /&gt;
  &amp;quot;damageAreaOfEffect&amp;quot;&lt;br /&gt;
  &amp;quot;edgeEffectiveness&amp;quot;&lt;br /&gt;
  &amp;quot;explosionSpeed&amp;quot;&lt;br /&gt;
  - or -&lt;br /&gt;
  an armor type index to get the damage against it.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Sounds.lua&amp;diff=17040</id>
		<title>Sounds.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Sounds.lua&amp;diff=17040"/>
		<updated>2018-12-09T23:11:21Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Location==&lt;br /&gt;
&amp;lt;code&amp;gt;sounds.lua&amp;lt;/code&amp;gt; is a file in the &amp;lt;code&amp;gt;Gamedata/&amp;lt;/code&amp;gt; directory of a Spring Game.&lt;br /&gt;
&lt;br /&gt;
==Purpose==&lt;br /&gt;
The file is used to define &#039;&#039;&#039;SoundItems&#039;&#039;&#039;. Beside simply &amp;quot;linking&amp;quot; to an audio file, &#039;&#039;&#039;SoundItems&#039;&#039;&#039; can use various tags to alter the playback of the file.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which parses the data from this file is viewable here:&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/System/Sound/SoundItem.cpp}}&lt;br /&gt;
&lt;br /&gt;
==Data Types==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
Wherever a sound is played in Spring, be it associated with a [[Gamedev:UnitDefs|UnitDef]], [[Gamedev:WeaponDefs|WeaponDef]] or via the [[Lua_UnsyncedCtrl#Sounds|lua API]], a &#039;&#039;&#039;SoundItem&#039;&#039;&#039; is used. If you access a raw sound file, a &#039;&#039;&#039;SoundItem&#039;&#039;&#039; with the defaults is created for you.&lt;br /&gt;
&lt;br /&gt;
Additionally, multiple &#039;&#039;&#039;SoundItems&#039;&#039;&#039; can use one single file with different settings, this is very efficient, as they only use 1 shared buffer.&lt;br /&gt;
&lt;br /&gt;
{{new|89.0}}: All item names are treated in lowercase.&lt;br /&gt;
&lt;br /&gt;
==Tips==&lt;br /&gt;
You can update &amp;amp; reload your sounddefs at runtime via Spring.LoadSoundDef(&amp;quot;gamedata/sounds.lua&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
===Reserved SoundItems===&lt;br /&gt;
The following &#039;&#039;&#039;SoundItems&#039;&#039;&#039; are reserved for specific engine sounds:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;IncomingChat&amp;lt;/code&amp;gt; - Is played when a chat message is received.&lt;br /&gt;
* &amp;lt;code&amp;gt;MultiSelect&amp;lt;/code&amp;gt; - Is played when multiple units are selected simultaneously.&lt;br /&gt;
* &amp;lt;code&amp;gt;MapPoint&amp;lt;/code&amp;gt; - Is played when a map point is placed by the player or an ally.&lt;br /&gt;
* &amp;lt;code&amp;gt;FailedCommand&amp;lt;/code&amp;gt; - Is played when a unit fails to execute a command. e.g. When a unit cannot reach it&#039;s destination etc.&lt;br /&gt;
* &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt; - Used for all sounds that aren&#039;t listed in &amp;lt;code&amp;gt;sounds.lua&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===SoundItem Properties===&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = gain&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = This varies the loudness, &amp;gt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; is louder, &amp;lt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt;  is quieter. &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; is silent.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = gainmod&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = If &amp;gt; &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; then this adds a random amount to {{taglink|gain}} each time the sound is played. Clamped between &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt;. The result is in the range &#039;&#039;&#039;[&#039;&#039;&#039;({{taglink|gain}} * (1 + {{taglink|gainMod}}))&#039;&#039;&#039;,&#039;&#039;&#039; ({{taglink|gain}} * (1 - {{taglink|gainMod}}))&#039;&#039;&#039;]&#039;&#039;&#039;.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pitch&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Varies the pitch of the sound, &amp;gt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; is higher pitched, &amp;lt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; is lower.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pitchmod&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = If &amp;gt; &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; then this adds a random amount to {{taglink|pitch}} each time the sound is played. Clamped between &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt;. The result is in the range &#039;&#039;&#039;[&#039;&#039;&#039;({{taglink|pitch}} * (1 + {{taglink|pitchMod}}))&#039;&#039;&#039;,&#039;&#039;&#039; ({{taglink|pitch}} * (1 - {{taglink|pitchMod}}))&#039;&#039;&#039;]&#039;&#039;&#039;.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = dopplerscale&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = How unit and camera speed affects the pitch of the sound, to exaggerate it, use values &amp;gt; &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt;. Use &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; to completely disable the effect.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = priority&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = When lots of sounds are played, sounds with lower {{taglink|priority}} are more likely to get cut off. A {{taglink|priority}} &amp;gt; &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; will never be cut of (priorities can be negative).}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = maxconcurrent&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 16&lt;br /&gt;
|description = How many copies of this sound can be played at once?}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = maxdist&lt;br /&gt;
|type = float&lt;br /&gt;
|default = MAX_FLOAT&lt;br /&gt;
|description = The cut-off distance (in [[elmo]]s) at which this sound will no longer be played.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = rolloff&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = How fast the sound becomes quieter with distance. &amp;lt;code&amp;gt;0.0&amp;lt;/code&amp;gt; means always the same loudness regardless of distance.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = in3d&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = true&lt;br /&gt;
|description = Non-3d sounds always came out of the front-speakers (or the centre one). 3d sounds are, well, in 3d.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = looptime&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = The time in milliseconds the sound should loop for.}}&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
===default sounds===&lt;br /&gt;
The following is the default &amp;lt;code&amp;gt;sounds.lua&amp;lt;/code&amp;gt; supplied in the base content [[springcontent.sdz]] archive, with some of the comments removed (As the information is presented here).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local Sounds = {&lt;br /&gt;
  SoundItems = {&lt;br /&gt;
    IncomingChat = {&lt;br /&gt;
      --- always play on the front speaker(s)&lt;br /&gt;
      file = &amp;quot;sounds/beep4.wav&amp;quot;,&lt;br /&gt;
      in3d = &amp;quot;false&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    MultiSelect = {&lt;br /&gt;
      --- always play on the front speaker(s)&lt;br /&gt;
      file = &amp;quot;sounds/button9.wav&amp;quot;,&lt;br /&gt;
      in3d = &amp;quot;false&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    MapPoint = {&lt;br /&gt;
      --- respect where the point was set, but don&#039;t attenuate in distance&lt;br /&gt;
      --- also, when moving the camera, don&#039;t pitch it&lt;br /&gt;
      file = &amp;quot;sounds/beep6.wav&amp;quot;,&lt;br /&gt;
      rolloff = 0,&lt;br /&gt;
      dopplerscale = 0,&lt;br /&gt;
    },&lt;br /&gt;
    ExampleSound = {&lt;br /&gt;
      --- some things you can do with this file&lt;br /&gt;
      --- can be either ogg or wav&lt;br /&gt;
      file = &amp;quot;somedir/subdir/soundfile.ogg&amp;quot;,&lt;br /&gt;
      gain = 1,&lt;br /&gt;
      pitch = 1,&lt;br /&gt;
      dopplerscale = 1,&lt;br /&gt;
      priority = 0,&lt;br /&gt;
      maxconcurrent = 16,&lt;br /&gt;
      maxdist = 20000,&lt;br /&gt;
      rolloff = 1,&lt;br /&gt;
      in3d = true,&lt;br /&gt;
      looptime = 0,&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    -- new since 89.0&lt;br /&gt;
    default = {&lt;br /&gt;
      gainmod = 0.35,&lt;br /&gt;
      pitchmod = 0.3,&lt;br /&gt;
      pitch = 0.7,&lt;br /&gt;
      in3d = true,&lt;br /&gt;
    },&lt;br /&gt;
  },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return Sounds&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Using PitchMod to prevent loud explosions====&lt;br /&gt;
Taken from this thread by jK: {{forumlink|topic=28819|title=Use PitchMod in sounds.lua to prevent loud explosions}}&lt;br /&gt;
&lt;br /&gt;
Explosions can sound louder than intended when they are started in the same simFrame and so are played in sync -&amp;gt; resonance. PitchMod now changes the playback time (e.g. with 0.3 the sounds should have a playback time of 100-130%) and so there isn&#039;t a resonance anymore even when the sound is started multiple times in the same simframe.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local files = VFS.DirList(&amp;quot;sounds/explosions/&amp;quot;)&lt;br /&gt;
local t = Sounds.SoundItems&lt;br /&gt;
for i=1,#files do&lt;br /&gt;
   local fileName = files[i]&lt;br /&gt;
   t[fileName] = {&lt;br /&gt;
      file     = fileName;&lt;br /&gt;
      pitchmod = 0.3;&lt;br /&gt;
      gainmod  = 0.2;&lt;br /&gt;
      maxconcurrent = 8;&lt;br /&gt;
   }&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===External Examples===&lt;br /&gt;
{{sourcelink|file=cont/base/springcontent/gamedata/sounds.lua}} - The original default &amp;lt;code&amp;gt;sounds.lua&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/zero-k/source/browse/trunk/mods/zk/gamedata/sounds.lua ZeroK sounds.lua]&lt;br /&gt;
&lt;br /&gt;
==Further Reading==&lt;br /&gt;
{{forumlink|topic=17647&amp;amp;start=25|title=Information about sounds.lua}}&lt;br /&gt;
{{forumlink|topic=20685|title=Information about gainMod and pitchMod}}&lt;br /&gt;
[[Category:gamedata]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_UnsyncedCtrl&amp;diff=12327</id>
		<title>Lua UnsyncedCtrl</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_UnsyncedCtrl&amp;diff=12327"/>
		<updated>2018-12-08T15:31:50Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* (Virtual-)FileSystem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
NOTE: Prior to 102.0, entries below marked &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt; require the setting ModUICtrl to be enabled in the users [[springrc]], if you want to use them in unsynced LuaRules/LuaGaia. It is enabled by default in previous versions and removed in 102.0 so you generally don&#039;t need to care.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= UI =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetLastMessagePosition&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number y, number z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Ingame Console =&lt;br /&gt;
&#039;&#039;&#039;Spring.Echo&#039;&#039;&#039;&lt;br /&gt;
  ( arg1 [, arg2 [, ... ] ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Useful for debugging.&amp;lt;br&amp;gt; Prints values in the spring chat console.&amp;lt;br&amp;gt; Hint: the default print() writes to STDOUT.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.Log&#039;&#039;&#039;&lt;br /&gt;
  ( string section, int logLevel | string logLevel,&lt;br /&gt;
    arg2 [, arg3 [, ... ] ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Possible values for logLevel are:&lt;br /&gt;
    &amp;quot;debug&amp;quot;   | LOG.DEBUG&lt;br /&gt;
    &amp;quot;info&amp;quot;    | LOG.INFO&lt;br /&gt;
    &amp;quot;notice&amp;quot;  | LOG.NOTICE (engine default) {{new|97}}&lt;br /&gt;
    &amp;quot;warning&amp;quot; | LOG.WARNING&lt;br /&gt;
    &amp;quot;error&amp;quot;   | LOG.ERROR&lt;br /&gt;
    &amp;quot;fatal&amp;quot;   | LOG.FATAL&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SendCommands&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string command1 [, string command2 [ ... ] ] ) -&amp;gt; nil&lt;br /&gt;
  ( {string command1, string command2, ...} ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== GUI ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetActiveCommand&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string action [, string actionExtra ] ) -&amp;gt; nil | boolean&lt;br /&gt;
  ( number cmdIndex [, number button = 1&lt;br /&gt;
    [, boolean leftClick, boolean rightClick,&lt;br /&gt;
     boolean alt, boolean ctrl, boolean meta, boolean shift]] ) -&amp;gt; nil | boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.LoadCmdColorsConfig&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string config ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.LoadCtrlPanelConfig&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string config ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.ForceLayoutUpdate&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetDrawSelectionInfo&#039;&#039;&#039; &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;disables the &amp;quot;Selected Units x&amp;quot; box in the GUI&amp;lt;/font&amp;gt; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( boolean enable ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Mouse ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetMouseCursor&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string cursorName [, number scale ] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.WarpMouse&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number x, number y ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== LOS Colors ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetLosViewColors&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=warning&amp;gt;New arguments since 100.0 (radar2 is the inside of radar edge):&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( always = {r,g,b}, LOS = {r,g,b}, radar = {r,g,b}, jam = {r,g,b}, radar2 = {r,g,b}) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=warning&amp;gt;Arguments for 99.0 and before:&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( table reds = { number always, number LOS, number radar, number jam }, &lt;br /&gt;
    table greens = { number always, number LOS, number radar, number jam },&lt;br /&gt;
    table blues = { number always, number LOS, number radar, number jam } ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== SendMessage ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SendMessage&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;message&amp;quot; ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SendMessageToPlayer&#039;&#039;&#039;&lt;br /&gt;
  ( number playerID, string &amp;quot;message&amp;quot; ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SendMessageToTeam&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, string &amp;quot;message&amp;quot; ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SendMessageToAllyTeam&#039;&#039;&#039;&lt;br /&gt;
  ( number allyID, string &amp;quot;message&amp;quot; ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SendMessageToSpectators&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;message&amp;quot; ) -&amp;gt; nil&lt;br /&gt;
Funfact:&lt;br /&gt;
&amp;lt;PLAYER#&amp;gt; (with # being a playerid) inside the string will be replaced with the players name.&lt;br /&gt;
ie&lt;br /&gt;
Spring.SendMessage (&amp;quot;&amp;lt;PLAYER1&amp;gt; did something&amp;quot;)&lt;br /&gt;
might display as &amp;quot;ProRusher did something&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Markers ==&lt;br /&gt;
&#039;&#039;&#039;Spring.MarkerAddPoint&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number x, number y, number z [, string text = &amp;quot;&amp;quot; [, bool localOnly] ] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.MarkerAddLine&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number x1, number y1, number z1, number x2, number y2, number z2 ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.MarkerErasePosition&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number x, number y, number z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Sounds =&lt;br /&gt;
&#039;&#039;&#039;Spring.LoadSoundDef&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;soundfile&amp;quot; ) -&amp;gt; nil | boolean success&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;Loads a SoundDefs file, the format is the same as in `gamedata/sounds.lua`.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.PlaySoundFile&#039;&#039;&#039;  &amp;lt;span class=note&amp;gt;Plays WAV or OGG sounds.&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( string &amp;quot;soundfile&amp;quot; [, number volume = 1.0&lt;br /&gt;
    [, number posx, number posy, number posz &lt;br /&gt;
    [, number speedx, number speedy, number speedz ] ] ], [string/number &amp;lt;span class=note&amp;gt;channel&amp;lt;/span&amp;gt; ] ) -&amp;gt; nil | boolean&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;`channel` is new in Spring0.83, and can be one of those:&lt;br /&gt;
    &amp;quot;general&amp;quot; || 0 || nil (default)&lt;br /&gt;
    &amp;quot;battle&amp;quot; || &amp;quot;sfx&amp;quot; | 1&lt;br /&gt;
    &amp;quot;unitreply&amp;quot; || &amp;quot;voice&amp;quot; || 2&lt;br /&gt;
    &amp;quot;userinterface&amp;quot; || &amp;quot;ui&amp;quot; || 3&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.PlaySoundStream&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;oggfile&amp;quot; [, number volume = 1.0&lt;br /&gt;
    [, bool enqueue ]] ) -&amp;gt; nil | boolean true&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;Allow you to play an Ogg Vorbis (.OGG) compressed sound file.&amp;lt;br&amp;gt; In 83.0 and up multiple sound streams may be played at once &amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.StopSoundStream&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;Terminates any SoundStream currently running.&amp;lt;/span&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.PauseSoundStream&#039;&#039;&#039;&lt;br /&gt;
  ( ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSoundStreamVolume&#039;&#039;&#039;&lt;br /&gt;
  ( number volume ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= SendLuaMessage =&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Very important! (allows synced inter-lua-enviroment communications)&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SendLuaUIMsg&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string message, string mode ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;possible modes are:&amp;lt;br&amp;gt;&amp;quot;s&amp;quot;/&amp;quot;specs&amp;quot; &amp;amp; &amp;quot;a&amp;quot;/&amp;quot;allies&amp;quot;&amp;lt;/font&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.SendLuaGaiaMsg&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string message ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SendLuaRulesMsg&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string message ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= AI =&lt;br /&gt;
&#039;&#039;&#039;Spring.SendSkirmishAIMessage&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( number aiTeam, string message )&lt;br /&gt;
  -&amp;gt; nil | boolean ai_processed, { [1] = string response1, etc... }&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Note there is nothing in this table due to &amp;quot;limitations&amp;quot; of the AI interface.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Units =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitLeaveTracks&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( number unitID, boolean leavetracks ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitSelectionVolumeData&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( number featureID, number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
    number offsetX, number offsetY, number offsetX,&lt;br /&gt;
    number vType, number tType, number Axis&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Unit Selection ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SelectUnitMap&#039;&#039;&#039;&lt;br /&gt;
  ( { [unitID] = anything, ...} [,boolean append] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SelectUnitArray&#039;&#039;&#039;&lt;br /&gt;
  ( { [1] = unitID1 , [2] = unitID2 , ...} [,boolean append] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetDrawSelectionInfo&#039;&#039;&#039;&lt;br /&gt;
  ( boolean drawSelectionInfo ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Unit Group ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitGroup&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID, number groupID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Give Order ==&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrder&#039;&#039;&#039; &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;gives order to all selected units&amp;lt;/font&amp;gt; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number cmdID,&lt;br /&gt;
    params = {number, etc...},&lt;br /&gt;
    options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;} ) -&amp;gt; nil | boolean true&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderToUnit&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID,&lt;br /&gt;
    number cmdID,&lt;br /&gt;
    params = {number, etc...},&lt;br /&gt;
    options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;} ) -&amp;gt; nil | boolean true&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderToUnitMap&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( unitMap = { [unitID] = dontCare, etc... },&lt;br /&gt;
    number cmdID,&lt;br /&gt;
    params = {number, etc...},&lt;br /&gt;
    options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;} ) -&amp;gt; nil | boolean true&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderToUnitArray&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( unitArray = { [1] = unitID, etc... },&lt;br /&gt;
    number cmdID,&lt;br /&gt;
    params = {number, etc...},&lt;br /&gt;
    options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;} ) -&amp;gt; nil | boolean true&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderArrayToUnitMap&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( unitMap = { [number unitID] = dontCare, etc... },&lt;br /&gt;
    orderArray = {&lt;br /&gt;
      { number cmdID,&lt;br /&gt;
        params = {number, etc...},&lt;br /&gt;
        options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;}&lt;br /&gt;
      }, ..&lt;br /&gt;
    }&lt;br /&gt;
  ) -&amp;gt; nil | boolean true&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderArrayToUnitArray&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( unitArray = { [1] = number unitID, etc... },&lt;br /&gt;
    orderArray = {&lt;br /&gt;
      { number cmdID,&lt;br /&gt;
        params = {number, etc...},&lt;br /&gt;
        options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;}&lt;br /&gt;
      }, ..&lt;br /&gt;
    },&lt;br /&gt;
    [boolean pairwise]&lt;br /&gt;
  ) -&amp;gt; nil | boolean true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;pairwise param ({{new|89.0}}) is used to send multiple units a single individual command&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetBuildFacing&#039;&#039;&#039;&lt;br /&gt;
  ( int Facing ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetBuildSpacing&#039;&#039;&#039;&lt;br /&gt;
  ( int Spacing ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Unit NoDraw,NoSelect,NoMinimap ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitNoDraw&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;LuaGadgets only!&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID, boolean noDraw ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitNoSelect&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;LuaGadgets only!&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID, boolean noSelect ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitNoMinimap&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;LuaGadgets only!&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID, boolean noMinimap ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Features =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureFade&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( int featureID, bool allow ) -&amp;gt; nil&lt;br /&gt;
Control whether a feature will fade or not when zoomed out.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureNoDraw&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;LuaGadgets only!&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number featureID, boolean noDraw ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureSelectionVolumeData&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( number featureID, number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
    number offsetX, number offsetY, number offsetX,&lt;br /&gt;
    number vType, number tType, number Axis&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Developers =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetDrawSky&#039;&#039;&#039;&lt;br /&gt;
  ( boolean drawSky ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetDrawWater&#039;&#039;&#039;&lt;br /&gt;
  ( boolean drawWater ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetDrawGround&#039;&#039;&#039;&lt;br /&gt;
  ( boolean drawGround ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetWaterParams&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;As of 104.0 no longer needs cheating enabled&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( table params ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Allows to change water params (mostly BumpWater ones) at runtime. You may want to set BumpWaterUseUniforms in your [[springrc]] to 1, then you don&#039;t even need to restart BumpWater via `/water 4`.&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;`params` table may contain:&lt;br /&gt;
  params = {&lt;br /&gt;
    absorb = {number r, number g, number b},&lt;br /&gt;
    baseColor = {number r, number g, number b},&lt;br /&gt;
    minColor = {number r, number g, number b},&lt;br /&gt;
    surfaceColor = {number r, number g, number b},&lt;br /&gt;
    diffuseColor = {number r, number g, number b},&lt;br /&gt;
    specularColor = {number r, number g, number b},&lt;br /&gt;
    planeColor = {number r, number g, number b},&lt;br /&gt;
    texture = string file,&lt;br /&gt;
    foamTexture = string file,&lt;br /&gt;
    normalTexture = string file,&lt;br /&gt;
    damage = number value,&lt;br /&gt;
    repeatX = number value,&lt;br /&gt;
    repeatY = number value,&lt;br /&gt;
    surfaceAlpha = number value,&lt;br /&gt;
    ambientFactor = number value,&lt;br /&gt;
    diffuseFactor = number value,&lt;br /&gt;
    specularFactor = number value,&lt;br /&gt;
    specularPower = number value,&lt;br /&gt;
    fresnelMin = number value,&lt;br /&gt;
    fresnelMax = number value,&lt;br /&gt;
    fresnelPower = number value,&lt;br /&gt;
    reflectionDistortion = number value,&lt;br /&gt;
    blurBase = number value,&lt;br /&gt;
    blurExponent = number value,&lt;br /&gt;
    perlinStartFreq = number value,&lt;br /&gt;
    perlinLacunarity = number value,&lt;br /&gt;
    perlinAmplitude = number value,&lt;br /&gt;
    numTiles = number value,&lt;br /&gt;
    shoreWaves = boolean value,&lt;br /&gt;
    forceRendering = boolean value,&lt;br /&gt;
    hasWaterPlane = boolean value,&lt;br /&gt;
  }&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetMapRenderingParams&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( table params ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;span class=note&amp;gt;Allows to change map rendering params at runtime.&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;`params` table may contain:&lt;br /&gt;
  params = {&lt;br /&gt;
    splatTexMults = {number r, number g, number b, number a},&lt;br /&gt;
    splatTexScales = {number r, number g, number b, number a},&lt;br /&gt;
    voidWater = boolean value,&lt;br /&gt;
    voidGround = boolean value,&lt;br /&gt;
    splatDetailNormalDiffuseAlpha = boolean value,&lt;br /&gt;
  }&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetLogSectionFilterLevel&#039;&#039;&#039; {{New|95.0}}&lt;br /&gt;
   ( string sectionName, string|number logLevel )&lt;br /&gt;
see [[infolog.txt]] for possible log sections (?)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetDrawGroundDeferred&#039;&#039;&#039; {{New|95.0}}&lt;br /&gt;
    ( boolean drawGroundDeferred [, boolean drawGroundForward] ) -&amp;gt; nil&lt;br /&gt;
{{new|101.0}} {{var|drawGroundForward}} allows disabling of the forward pass&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetDrawModelsDeferred&#039;&#039;&#039; {{New|95.0}}&lt;br /&gt;
    (     boolean drawUnitsDeferred,&lt;br /&gt;
          boolean drawFeaturesDeferred&lt;br /&gt;
       [, boolean drawUnitsForward&lt;br /&gt;
       [, boolean drawFeaturesForward ]]&lt;br /&gt;
     ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
{{new|101.0}} {{var|drawFeaturesForward}}, {{var|drawUnitsForward}} allows disabling of the respective forward passes&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetVideoCapturingMode&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
   ( boolean allowCaptureMode ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
This doesn&#039;t actually record the game in any way, it just regulates the framerate and interpolations.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetVideoCapturingTimeOffset&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
   ( number timeOffset ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= GUI =&lt;br /&gt;
&#039;&#039;&#039;Spring.DrawUnitCommands&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil&lt;br /&gt;
  ( { [1] = unitID, ... } [, false ] ) -&amp;gt; nil&lt;br /&gt;
  ( { [unitID] = anything, ... }, true  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetTeamColor&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, number r, number g, number b ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AssignMouseCursor&#039;&#039;&#039; &amp;lt;font class=note&amp;gt;changes/creates the cursor of a single CursorCmd&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string &amp;quot;cmdName&amp;quot;, string &amp;quot;iconFileName&amp;quot;&lt;br /&gt;
    [, boolean overwrite = true [, boolean hotSpotTopLeft = false] ] ) -&amp;gt; nil | boolean&lt;br /&gt;
&amp;lt;font class=note&amp;gt;Note, that iconFileName is not the full filename instead it is like this:&amp;lt;br/&amp;gt;&lt;br /&gt;
wanted filename: Anims/cursorattack_0.bmp&amp;lt;br/&amp;gt;&lt;br /&gt;
=&amp;gt; iconFileName: cursorattack&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.ReplaceMouseCursor&#039;&#039;&#039; &amp;lt;font class=note&amp;gt;mass replace all occurrence of the cursor in all CursorCmds&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string &amp;quot;oldFileName&amp;quot;, string &amp;quot;newFileName&amp;quot; [, boolean hotSpotTopLeft = false] ) -&amp;gt; nil | boolean&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetCustomCommandDrawData&#039;&#039;&#039; &amp;lt;font class=note&amp;gt;register your custom cmd so it gets visible in the unit&#039;s cmd queue&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number cmdID,&lt;br /&gt;
    number cmdID_cloneIcon | string iconname,&lt;br /&gt;
    { number r, number g, number b, number a } [, boolean showArea ] ) -&amp;gt; nil&lt;br /&gt;
  ( number cmdID, nil) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Sharing =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetShareLevel&#039;&#039;&#039; &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;note: shareLevel is 0&amp;lt;= x &amp;lt;= 1&amp;lt;/font&amp;gt; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string &amp;quot;metal&amp;quot; | &amp;quot;energy&amp;quot;, number shareLevel ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.ShareResources&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number teamID, string &amp;quot;units&amp;quot; ) -&amp;gt; nil&lt;br /&gt;
  ( number teamID, string &amp;quot;metal&amp;quot; | &amp;quot;energy&amp;quot;, number amount ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= UnitDef RadarIcons &amp;amp; BuildPics =&lt;br /&gt;
&#039;&#039;&#039;Spring.AddUnitIcon&#039;&#039;&#039;&lt;br /&gt;
  ( string iconName, string texFile [, number size [, number dist [, boolean radAdjust ]]] )&lt;br /&gt;
  -&amp;gt; nil | boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.FreeUnitIcon&#039;&#039;&#039;&lt;br /&gt;
  ( string iconName ) -&amp;gt; nil | boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitDefIcon&#039;&#039;&#039;  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;(RadarIcon)&amp;lt;/font&amp;gt; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitDefID, string iconName ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitDefImage&#039;&#039;&#039;   &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;(BuildPic)&amp;lt;/font&amp;gt; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitDefID, luaTexture | string texFile ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Camera =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetCameraState&#039;&#039;&#039;&lt;br /&gt;
  ( table camState, number camTime) -&amp;gt; nil | boolean&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;camState has the same format as the output of Spring.GetCameraState(). See [[Lua_camState]] for details about camState. &lt;br /&gt;
&lt;br /&gt;
The camState&#039;s mode/name must fit the rest of the state. Getting a state, changing its mode/name and then passing it to SetCameraState will have undesired results. [https://springrts.com/mantis/view.php?id=5028#c15491 Also see #5028]&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetCameraTarget&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number y, number z [,number transTime] ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;For Spring Engine XZ represents horizontal, from north west corner of map and Y vertical, from water level and rising.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetCameraOffset&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( [number px = 0 [, number py = 0 [, number pz = 0&lt;br /&gt;
     [, number tx = 0 [, number ty = 0 [, number tz = 0]]]]]] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= (Virtual-)FileSystem =&lt;br /&gt;
&#039;&#039;&#039;Spring.ExtractModArchiveFile&#039;&#039;&#039;&lt;br /&gt;
  ( string modfile ) -&amp;gt; boolean&lt;br /&gt;
&#039;&#039;&#039;Spring.CreateDir&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(needs ModUICtrl)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string path ) -&amp;gt; nil | boolean&lt;br /&gt;
&lt;br /&gt;
The full VFS API is available at [[Lua_VFS|link]].&lt;br /&gt;
&lt;br /&gt;
= Engine Config =&lt;br /&gt;
The following functions read the engine configs saved in [[Springsettings.cfg]], a version-ed instance of these or a custom file supplied on the command line.&lt;br /&gt;
If &#039;&#039;*Overlay&#039;&#039; is &#039;&#039;true&#039;&#039;, the value will only be set in memory, and not be restored for the next game&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetConfigInt&#039;&#039;&#039;&lt;br /&gt;
  ( string name, number value [, boolean useOverlay = false] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetConfigFloat&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( string name, number value [, boolean useOverlay = false] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetConfigString&#039;&#039;&#039;&lt;br /&gt;
  ( string name, string value [, boolean useOverlay = false] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= World Primitives =&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;outdated! use opengl api instead!&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AddWorldIcon&#039;&#039;&#039;&lt;br /&gt;
  ( number cmdID, number x, number y, number z ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.AddWorldText&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;text&amp;quot;, number x, number y, number z ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.AddWorldUnit&#039;&#039;&#039;&lt;br /&gt;
  ( number unitDefID,&lt;br /&gt;
    number x, number y, number z,&lt;br /&gt;
    number team, number facing) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Sun  =&lt;br /&gt;
The dynamic Sun must be invoked via /dynamicsun (Dynamic sun was removed in 104.0, use SetSunDirection, SetSunLighting &amp;amp; SetAtmosphere instead).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSunManualControl&#039;&#039;&#039; {{removed|104.0}}&lt;br /&gt;
  ( boolean setManualControl ) - &amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSunParameters&#039;&#039;&#039; {{removed|104.0}}&lt;br /&gt;
  ( number dirX, number dirY, number dirZ, number dist, number startTime, number orbitTime ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSunDirection&#039;&#039;&#039;&lt;br /&gt;
  ( number dirX, number dirY, number dirZ ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSunLighting&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( table params ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;It can be used to modify the following sun lighting parameters: &lt;br /&gt;
     {ground,unit}{Ambient,Diffuse,Specular}Color and specularExponent&lt;br /&gt;
     All Colourvalues have to in the Range from 0.0 to 1.0 for all colors and the alpha&lt;br /&gt;
     Example usage: Spring.SetSunLighting({groundAmbientColor = {1, 0.1, 1}, groundDiffuseColor = {1, 0.1, 1} })&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetAtmosphere&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( table params ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;It can be used to modify the following atmosphere parameters:&lt;br /&gt;
     fog{Start,End}, {sun,sky,cloud}Color&lt;br /&gt;
     Example usage: Spring.SetAtmosphere({ fogStart = 0, fogEnd   = 0.5, fogColor = { 0.7, 0.2, 0.2, 1 }})&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Misc =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.Reload&#039;&#039;&#039; {{new|99.0}}&lt;br /&gt;
  ( string startscript )&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;start-script is the CONTENT of the [[script.txt]] spring should use to start.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.Restart&#039;&#039;&#039; {{new|0.79}}&lt;br /&gt;
  ( string commandline_args, string startscript )&lt;br /&gt;
    -&amp;gt; if this call returns, something went wrong&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&#039;&#039;commandline_args&#039;&#039; are commandline arguments passed to spring executable&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.Start&#039;&#039;&#039; {{new|102.0}}&lt;br /&gt;
  ( string commandline_args, string startscript )&lt;br /&gt;
    -&amp;gt; if this call returns, something went wrong&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Launches a new Spring instance without terminating the existing one&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;start-script is the CONTENT of the [[script.txt]] spring should use to start (if empty, no start-script is added, you can still point spring to your custom script.txt when you add the file-path to &#039;&#039;commandline_args&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetWMIcon&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( string iconFileName ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Sets the icon for the process which is seen in the OS task-bar and other places (default: spring-logo).&amp;lt;br/&amp;gt;&lt;br /&gt;
Note: has to be 24bit or 32bit&amp;lt;br/&amp;gt;&lt;br /&gt;
Note: on windows, it has to be 32x32 pixels in size (recommended for cross-platform)&amp;lt;br/&amp;gt;&lt;br /&gt;
Note: &#039;&#039;*.bmp&#039;&#039; images have to be in BGR format (default for m$ ones).&amp;lt;br/&amp;gt;&lt;br /&gt;
Note: &#039;&#039;*.ico&#039;&#039; images are not supported.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetWMCaption&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( string title [, string titleShort = title ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;Sets the window &#039;&#039;title&#039;&#039; for the process (default: &amp;quot;Spring &amp;lt;version&amp;gt;&amp;quot;).&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;The &#039;&#039;shortTitle&#039;&#039; is displayed in the OS task-bar (default: &amp;quot;Spring &amp;lt;version&amp;gt;&amp;quot;).&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&#039;&#039;&#039;NOTE:&#039;&#039;&#039; &#039;&#039;shortTitle&#039;&#039; is only ever possibly used under X11 (Linux &amp;amp; OS X), but not with QT (KDE) and never under Windows. See [http://www.gpwiki.org/index.php/SDL:Tutorials:Initializing_SDL_Libraries#About_the_icon_.28.22Icon_Title.22.29_parameter_on_different_window-managers this site] for more details.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.ClearWatchDogTimer&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( [ string threadName = main ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetClipboard&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( string text) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Rendering =&lt;br /&gt;
== Preload ==&lt;br /&gt;
Allow the engine to load the unit&#039;s model (and texture) in a background thread. Wreckages and buildOptions of a unit are automatically preloaded.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.PreloadUnitDefModel&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitDefID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.PreloadFetureDefModel&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number featureDefID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Lighting ==&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;NOTE: these (0.83+) lighting callouts only work when called from unsynced gadgets!&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AddMapLight&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(requires MaxDynamicMapLights &amp;amp;gt; 0)&amp;lt;/font&amp;gt;&lt;br /&gt;
  (table lightParams) -&amp;gt; number lightHandle&lt;br /&gt;
&#039;&#039;&#039;Spring.AddModelLight&#039;&#039;&#039; &amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-weight:600&amp;quot;&amp;gt;(requires MaxDynamicModelLights &amp;amp;gt; 0)&amp;lt;/font&amp;gt;&lt;br /&gt;
  (table lightParams) -&amp;gt; number lightHandle&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.UpdateMapLight&#039;&#039;&#039;&lt;br /&gt;
  (number lightHandle, table lightParams) -&amp;gt; boolean success&lt;br /&gt;
&#039;&#039;&#039;Spring.UpdateModelLight&#039;&#039;&#039;&lt;br /&gt;
  (number lightHandle, table lightParams) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetMapLightTrackingState&#039;&#039;&#039;&lt;br /&gt;
  (number lightHandle, number unitOrProjectileID,&lt;br /&gt;
   boolean enableTracking, boolean unitOrProjectile) -&amp;gt; boolean success&lt;br /&gt;
&#039;&#039;&#039;Spring.SetModelLightTrackingState&#039;&#039;&#039;&lt;br /&gt;
  (number lightHandle, number unitOrProjectileID,&lt;br /&gt;
   boolean enableTracking, boolean unitOrProjectile) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;lightParams&#039;&#039;&#039; is a table that should contain at least one of the following recognized key/value pairs:&lt;br /&gt;
&lt;br /&gt;
    lightParams = {&lt;br /&gt;
        position = {px, py, pz},&lt;br /&gt;
        direction = {dx, dy, dz},&lt;br /&gt;
        ambientColor = {red, green, blue},&lt;br /&gt;
        diffuseColor = {red, green, blue},&lt;br /&gt;
        specularColor = {red, green, blue},&lt;br /&gt;
        intensityWeight = {ambientWeight, diffuseWeight, specularWeight},&lt;br /&gt;
&lt;br /&gt;
        -- per-frame decay of ambientColor (spread over TTL frames)&lt;br /&gt;
        ambientDecayRate = {ambientRedDecay, ambientGreenDecay, ambientBlueDecay},&lt;br /&gt;
        -- per-frame decay of diffuseColor (spread over TTL frames)&lt;br /&gt;
        diffuseDecayRate = {diffuseRedDecay, diffuseGreenDecay, diffuseBlueDecay},&lt;br /&gt;
        -- per-frame decay of specularColor (spread over TTL frames)&lt;br /&gt;
        specularDecayRate = {specularRedDecay, specularGreenDecay, specularBlueDecay},&lt;br /&gt;
        -- *DecayType = 0.0 -&amp;gt; interpret *DecayRate values as linear, else as exponential&lt;br /&gt;
        decayFunctionType = {ambientDecayType, diffuseDecayType, specularDecayType},&lt;br /&gt;
&lt;br /&gt;
        radius = number elmos,&lt;br /&gt;
        fov = number degrees,&lt;br /&gt;
        ttl = number frames,&lt;br /&gt;
        priority = number,&lt;br /&gt;
        ignoreLOS = boolean,&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
= Map =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSkyBoxTexture&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( string texName ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetMapShadingTexture&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( string texType, string texName ) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;Example usage: Spring.SetMapShadingTexture(&amp;quot;$ssmf_specular&amp;quot;, &amp;quot;name_of_my_shiny_texture&amp;quot;)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetMapSquareTexture&#039;&#039;&#039;&lt;br /&gt;
  ( number texSqrX, number texSqrY, string luaTexName ) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetMapShader&#039;&#039;&#039; {{101.0}}&lt;br /&gt;
  ( number standardShaderID, number deferredShaderID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;The ID&#039;s must refer to valid programs returned by gl.CreateShader. Passing in a value of 0 will cause the respective shader to revert back to its engine default. Custom map shaders that declare a uniform ivec2 named &amp;quot;texSquare&amp;quot; can sample from the default diffuse texture(s), which are always bound to TU 0.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_SyncedCtrl&amp;diff=11809</id>
		<title>Lua SyncedCtrl</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_SyncedCtrl&amp;diff=11809"/>
		<updated>2018-12-05T12:47:37Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Feature Control */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
= Game End =&lt;br /&gt;
&#039;&#039;&#039;Spring.KillTeam&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( number teamID ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Will declare a team to be dead ( no further orders can be assigned to such teams&#039;s units ), Gaia team cannot be killed.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GameOver&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( {number allyTeamID1, number allyTeamID2, ...} ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Will declare game over, a list of winning allyteams can be passed, if undecided ( like when dropped from the host ) it should be empty ( no winner ), in the case of a draw with multiple winners, all should be listed&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= RulesParams =&lt;br /&gt;
&amp;lt;span class=warning&amp;gt;string values are new since 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitRulesParam&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string paramName, number|string paramValue [, table &amp;lt;span class=note&amp;gt;losAccess&amp;lt;/span&amp;gt;] ) -&amp;gt; nil&lt;br /&gt;
   &amp;lt;span class=note&amp;gt;possible keys for the losAccess table are:&lt;br /&gt;
    `private` : only readable by the ally (default)&lt;br /&gt;
    `allied`  : readable by ally + ingame allied&lt;br /&gt;
    `inlos`   : readable if the unit is in LOS&lt;br /&gt;
    `inradar` : readable if the unit is in AirLOS&lt;br /&gt;
    `public`  : readable by all&lt;br /&gt;
   note: if one condition is fulfilled all beneath it are too (e.g. if an unit is in LOS it&amp;lt;br/&amp;gt;     can read params with `inradar=true` even if the param has `inlos=false`)&lt;br /&gt;
   note2: all GameRulesParam are public, TeamRulesParams can just be `private`,`allied`&amp;lt;br/&amp;gt;     and/or `public`&lt;br /&gt;
   note3: You can read RulesParams from &#039;&#039;&#039;any&#039;&#039;&#039; Lua enviroments! With those losAccess&amp;lt;br/&amp;gt;     policies you can limit their access.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureRulesParam&#039;&#039;&#039; &amp;lt;span class=warning&amp;gt;new since 102.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number featureID, string paramName, number|string paramValue [, table &amp;lt;span class=note&amp;gt;losAccess&amp;lt;/span&amp;gt;] ) -&amp;gt; nil&lt;br /&gt;
   &amp;lt;span class=note&amp;gt;see above for further documentation of losAccess&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetTeamRulesParam&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, string paramName, number|string paramValue [, table &amp;lt;span class=note&amp;gt;losAccess&amp;lt;/span&amp;gt;] ) -&amp;gt; nil&lt;br /&gt;
   &amp;lt;span class=note&amp;gt;see above for further documentation of losAccess&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetGameRulesParam&#039;&#039;&#039;&lt;br /&gt;
  ( string paramName, number|string paramValue [, table &amp;lt;span class=note&amp;gt;losAccess&amp;lt;/span&amp;gt;] ) -&amp;gt; nil&lt;br /&gt;
   &amp;lt;span class=note&amp;gt;see above for further documentation of losAccess&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Resources =&lt;br /&gt;
&#039;&#039;&#039;Spring.AddTeamResource&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, string &amp;quot;metal&amp;quot; | &amp;quot;energy&amp;quot;, number amount ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.UseTeamResource&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, &lt;br /&gt;
    string &amp;quot;metal&amp;quot; | &amp;quot;energy&amp;quot;,number amount |&lt;br /&gt;
    { metal = number amount, energy = number amount}&lt;br /&gt;
  ) -&amp;gt; nil | boolean hadEnough&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetTeamResource&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, string res, number amount ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
  possible values for res are:&lt;br /&gt;
    &amp;quot;m&amp;quot;  = metal&lt;br /&gt;
    &amp;quot;e&amp;quot;  = energy&lt;br /&gt;
    &amp;quot;ms&amp;quot;  = metal storage&lt;br /&gt;
    &amp;quot;es&amp;quot;  = energy storage&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetTeamShareLevel&#039;&#039;&#039;&lt;br /&gt;
  ( number teamID, string &amp;quot;metal&amp;quot; | &amp;quot;energy&amp;quot;, number amount ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.ShareTeamResource&#039;&#039;&#039; &amp;lt;span class=note&amp;gt;0.82 and later&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number teamID_src, number teamID_recv, string &amp;quot;metal&amp;quot; | &amp;quot;energy&amp;quot;, number amount ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Teams =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetAlly&#039;&#039;&#039; {{new|98.0}}&lt;br /&gt;
  ( number firstAllyTeamID, number secondAllyTeamID, boolean ally ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
Changes the value of the (one-sided) alliance between: firstAllyTeamID -&amp;gt; secondAllyTeamID&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AssignPlayerToTeam&#039;&#039;&#039; {{new|98.0}}  {{Sourcelinkhash|7ed9a7e34814c60e5ae16281520cccc4daf3c367}}&lt;br /&gt;
  ( number playerID, number teamID)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetGlobalLos&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number allyTeamID, bool globallos )&lt;br /&gt;
&lt;br /&gt;
= Unit Handling =&lt;br /&gt;
&#039;&#039;&#039;Spring.CreateUnit&#039;&#039;&#039; &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;note: offmap positions are clamped! (you still can use MoveCtrl todo so)&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( string &amp;quot;defName&amp;quot; | number unitDefID,&lt;br /&gt;
    number x, number y, number z,&lt;br /&gt;
    (number facing | string &amp;quot;facing&amp;quot;),&lt;br /&gt;
    number teamID&lt;br /&gt;
    [, boolean build = false] &lt;br /&gt;
    [, boolean flattenGround = true]&lt;br /&gt;
    [, number unitID]&lt;br /&gt;
    [, number builderID]) -&amp;gt; number unitID | nil (meaning unit was not created)&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
  possible values for facing are:&lt;br /&gt;
    &amp;quot;south&amp;quot; | &amp;quot;s&amp;quot; | 0&lt;br /&gt;
    &amp;quot;east&amp;quot;  | &amp;quot;e&amp;quot; | 1&lt;br /&gt;
    &amp;quot;north&amp;quot; | &amp;quot;n&amp;quot; | 2&lt;br /&gt;
    &amp;quot;west&amp;quot;  | &amp;quot;w&amp;quot; | 3&lt;br /&gt;
  if build is true the unit is created in &amp;quot;being built&amp;quot; state, with buildProgress = 0&lt;br /&gt;
  unitID and builderID are {{new|92.0}}, the former allowing to spawn a unit with&lt;br /&gt;
  a specific ID.&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.DestroyUnit&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID&lt;br /&gt;
    [, boolean selfd = false]&lt;br /&gt;
    [, boolean reclaimed = false]&lt;br /&gt;
    [, number attackerID ] ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
 selfd := makes the unit act like it self-destructed&lt;br /&gt;
 reclaimed := don&#039;t show any DeathSequences, don&#039;t leave a wreckage.&lt;br /&gt;
   NOTE this does _not_ give back the resources to the team!&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.TransferUnit&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID,&lt;br /&gt;
    numer newTeamID&lt;br /&gt;
    [, boolean given = true ] ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;if given=false, the unit is captured&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Unit Control ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitCosts&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, { &lt;br /&gt;
     [ buildTime  = number amount ],&lt;br /&gt;
     [ metalCost  = number amount ],&lt;br /&gt;
     [ energyCost = number amount ]&lt;br /&gt;
   } ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitTooltip&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string &amp;quot;tooltip&amp;quot; ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitHealth&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID,&lt;br /&gt;
    number health |&lt;br /&gt;
    { [ health   = number health ],&lt;br /&gt;
      [ capture  = number capture ],&lt;br /&gt;
      [ paralyze = number paralyze ],&lt;br /&gt;
      [ build    = number build ] }&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitMaxHealth&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number maxHealth ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AddUnitDamage&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number damage&lt;br /&gt;
    [, number paralyze = 0 [, number attackerID = -1 [, number weaponID = -1&lt;br /&gt;
      [, number impulse_x [, number impulse_y [, number impulse_z ]]] ]]] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitStockpile&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number stockpile [, number buildPercent ]]) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitExperience&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number experience ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitFuel&#039;&#039;&#039; {{removed|101.0}}&lt;br /&gt;
  ( number unitID, number fuel ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitCrashing&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( number unitID, boolean crashing ) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitLineage&#039;&#039;&#039; {{removed|83.0}}&lt;br /&gt;
  ( number unitID, number teamID [, boolean isRoot] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitNeutral&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, boolean neutral ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitTarget&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;userTarget &amp;amp; success new in version 95.0, setting nil target new in 99.0, weaponNum new in 102.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID,&lt;br /&gt;
    number enemyUnitID | number x, number y, number z, | nil,&lt;br /&gt;
    [ boolean dgun = false [, boolean userTarget = false [, number weaponNum = -1 ]]] ) -&amp;gt;  success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitMaxRange&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number maxRange ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitMass&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number mass ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitBlocking&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;crushable new in version 85.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID, boolean blocking [, boolean collide [, boolean crushable]] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitBlocking&#039;&#039;&#039; {{new|95.0}} changed parameters:&lt;br /&gt;
  number unitID,&lt;br /&gt;
  boolean isBlocking,&lt;br /&gt;
  boolean isSolidObjectCollidable,&lt;br /&gt;
  boolean isProjectileCollidable,&lt;br /&gt;
  boolean isRaySegmentCollidable,&lt;br /&gt;
  boolean crushable,&lt;br /&gt;
  boolean blockEnemyPushing,&lt;br /&gt;
  boolean blockHeightChanges&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitMetalExtraction&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;quot;depth&amp;quot; corresponds to metal extraction rate (value range similar to &amp;quot;extractsMetal&amp;quot; unitDef)&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID, number depth [,number range] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitBuildSpeed&#039;&#039;&#039;&lt;br /&gt;
  ( number builderID,&lt;br /&gt;
    number buildSpeed, [ number repairSpeed [, number reclaimSpeed&lt;br /&gt;
  [,number resurrectSpeed [, number captureSpeed [, number terraformSpeed ]] ]]] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitNanoPieces&#039;&#039;&#039; {{new|92.0}}&lt;br /&gt;
  ( number builderID, table pieces ) -&amp;gt; nil&lt;br /&gt;
This saves a lot of engine calls, by replacing:&lt;br /&gt;
function script.QueryNanoPiece() return currentpiece end&lt;br /&gt;
Use it!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.UnitAttach&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number transporterID, number passengerID, number pieceNum ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.UnitDetach&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number passengerID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.UnitDetachFromAir&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number passengerID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitLoadingTransport&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number passengerID, number transportID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Disables collisions between the two units to allow colvol intersection during the approach.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitPieceParent&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number AlteredPiece, number ParentPiece ) -&amp;gt; nil&lt;br /&gt;
Changes the pieces hierarchy of a unit, by attaching a piece to a new parent.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitPieceMatrix&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( number unitID, number pieceNum, table matrix )&lt;br /&gt;
&lt;br /&gt;
Sets the local (i.e. parent-relative) matrix of the given piece if any of the first three elements are non-zero, and also blocks all script animations from modifying it until {0, 0, 0} is passed (matrix should be an array of 16 floats, but is not otherwise sanity-checked).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitArmored&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;armorMultiple new in version 0.83.x&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID, boolean armored [, number armorMultiple] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitShieldState&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number weaponID = -1] [, boolean enabled] [, number power] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitFlanking&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string &amp;quot;mode&amp;quot;, number mode ) -&amp;gt; nil&lt;br /&gt;
  ( number unitID, string &amp;quot;moveFactor&amp;quot;, number factor) -&amp;gt; nil&lt;br /&gt;
  ( number unitID, string &amp;quot;minDamage&amp;quot;, number minDamage ) -&amp;gt; nil&lt;br /&gt;
  ( number unitID, string &amp;quot;mazDamage&amp;quot;, number maxDamage ) -&amp;gt; nil&lt;br /&gt;
  ( number unitID, string &amp;quot;dir&amp;quot;, number x, number y, number z) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitWeaponState&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number weaponNum, table states ) -&amp;gt; nil&lt;br /&gt;
  ( number unitID, number weaponNum, string key, number value ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;format of the states table:&lt;br /&gt;
    {&lt;br /&gt;
      [&amp;quot;reloadState&amp;quot;     = number value,]&lt;br /&gt;
      [&amp;quot;reloadFrame&amp;quot;     = number value,] (synonym for reloadState!)&lt;br /&gt;
      [&amp;quot;reloadTime&amp;quot;      = number value,]&lt;br /&gt;
      [&amp;quot;accuracy&amp;quot;        = number value,]&lt;br /&gt;
      [&amp;quot;sprayAngle&amp;quot;      = number value,]&lt;br /&gt;
      [&amp;quot;range&amp;quot;           = number value,] (*)&lt;br /&gt;
      [&amp;quot;projectileSpeed&amp;quot; = number value,]&lt;br /&gt;
      [&amp;quot;burst&amp;quot;           = number value,]&lt;br /&gt;
      [&amp;quot;burstRate&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;projectiles&amp;quot;     = number value,]&lt;br /&gt;
      [&amp;quot;salvoLeft&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;nextSalvo&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;aimReady&amp;quot;        = number value,] (&amp;lt;&amp;gt;0.0f := true)&lt;br /&gt;
    }&lt;br /&gt;
  (*) if you change the range of a weapon with dynamic damage&lt;br /&gt;
  make sure you use SetUnitWeaponDamages to change dynDamageRange as well.&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitWeaponDamages&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number weaponNum | &amp;quot;selfDestruct&amp;quot; | &amp;quot;explode&amp;quot;, table damages ) -&amp;gt; nil&lt;br /&gt;
  ( number unitID, number weaponNum | &amp;quot;selfDestruct&amp;quot; | &amp;quot;explode&amp;quot;, string key, number value ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;format of the damages table:&lt;br /&gt;
   {&lt;br /&gt;
      [&amp;quot;paralyzeDamageTime&amp;quot; = number value,]  &lt;br /&gt;
      [&amp;quot;impulseFactor&amp;quot;      = number value,]&lt;br /&gt;
      [&amp;quot;impulseBoost&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;craterMult&amp;quot;         = number value,]&lt;br /&gt;
      [&amp;quot;craterBoost&amp;quot;        = number value,]&lt;br /&gt;
      [&amp;quot;dynDamageExp&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;dynDamageMin&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;dynDamageRange&amp;quot;     = number value,]&lt;br /&gt;
      [&amp;quot;dynDamageInverted&amp;quot;  = number value,] (&amp;lt;&amp;gt;0.0f := true)&lt;br /&gt;
      [&amp;quot;craterAreaOfEffect&amp;quot; = number value,]&lt;br /&gt;
      [&amp;quot;damageAreaOfEffect&amp;quot; = number value,]&lt;br /&gt;
      [&amp;quot;edgeEffectiveness&amp;quot;  = number value,]&lt;br /&gt;
      [&amp;quot;explosionSpeed&amp;quot;     = number value,]&lt;br /&gt;
      [number armorType     = number value,] (changes the damage against this armor type)&lt;br /&gt;
    }&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitCollisionVolumeData&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
    number offsetX, number offsetY, number offsetX,&lt;br /&gt;
    number vType, number tType, number Axis&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;enum COLVOL_TYPES {&lt;br /&gt;
      COLVOL_TYPE_DISABLED = -1,&lt;br /&gt;
      COLVOL_TYPE_ELLIPSOID = 0,&lt;br /&gt;
      COLVOL_TYPE_CYLINDER,&lt;br /&gt;
      COLVOL_TYPE_BOX,&lt;br /&gt;
      COLVOL_TYPE_SPHERE,&lt;br /&gt;
      COLVOL_NUM_TYPES       // number of non-disabled collision volume types&lt;br /&gt;
    };&lt;br /&gt;
    enum COLVOL_TESTS {&lt;br /&gt;
      COLVOL_TEST_DISC = 0,&lt;br /&gt;
      COLVOL_TEST_CONT = 1,&lt;br /&gt;
      COLVOL_NUM_TESTS = 2   // number of tests&lt;br /&gt;
    };&lt;br /&gt;
    enum COLVOL_AXES {&lt;br /&gt;
      COLVOL_AXIS_X   = 0,&lt;br /&gt;
      COLVOL_AXIS_Y   = 1,&lt;br /&gt;
      COLVOL_AXIS_Z   = 2,&lt;br /&gt;
      COLVOL_NUM_AXES = 3    // number of collision volume axes&lt;br /&gt;
    };&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitPieceCollisionVolumeData&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number pieceIndex, boolean enable, &lt;br /&gt;
    number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
    number offsetX, number offsetY, number offsetZ&lt;br /&gt;
    [, number volumeType [, number primaryAxis]]&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
As of 101.0 this is 1-based piece index argument (was 0-based).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitTravel&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number travel [, number travelPeriod] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitMoveGoal&#039;&#039;&#039;   &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;used by default commands to get in build-,attackrange etc.&amp;lt;/span&amp;gt;&lt;br /&gt;
  (number unitID, number goalx, number goaly, number goalz &lt;br /&gt;
  [, number goalRadius [, number moveSpeed [, bool moveRaw ]]] )&lt;br /&gt;
{{new|98.0}} &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;moveRaw: [http://springrts.com/mantis/view.php?id=4412 allow unit to dumbly move to a coordinate without calculating path.]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitLandGoal&#039;&#039;&#039;   {{new|101.0}}&lt;br /&gt;
  (number unitID, number goalx, number goaly, number goalz [, number goalRadius ] ) -&amp;gt; nil&lt;br /&gt;
Used in conjunction with {{name|Spring.UnitAttach}} et al to re-implement old airbase &amp;amp; fuel system in lua.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.ClearUnitGoal&#039;&#039;&#039; {{new|102.0}}&lt;br /&gt;
  (number unitID) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitPhysics&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;drag new in version 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number unitID,&lt;br /&gt;
    number posx, number posy, number posz,&lt;br /&gt;
    number velx, number vely, number velz,&lt;br /&gt;
    number rotx, number roty, number rotz,&lt;br /&gt;
    number dragx, number dragy, number dragz,&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitPosition&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number x, number z [, boolean alwaysAboveSea] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitDirection&#039;&#039;&#039; {{new|90.0}}&lt;br /&gt;
  ( number unitID, number x, number y, number z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitVelocity&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number velx, number vely, number velz ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitRotation&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number rotx, number roty, number rotz ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AddUnitImpulse&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number x, number y, number z [, decayRate ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AddUnitSeismicPing&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number pingSize ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.RemoveBuildingDecal&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitMidAndAimPos&#039;&#039;&#039; {{new|89.0}}&lt;br /&gt;
  ( number unitID, &lt;br /&gt;
    number mpx, number mpy, number mpz, &lt;br /&gt;
    number apx, number apy, number apz, &lt;br /&gt;
    [, boolean relative] ) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
mpx, mpy, mpz: new middle position of unit&lt;br /&gt;
&lt;br /&gt;
apx, apy, apz: new position that enemies aim at on this unit&lt;br /&gt;
&lt;br /&gt;
relative: are the new coordinates relative to world or unit coordinates?&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitRadiusAndHeight&#039;&#039;&#039; {{new|89.0}}&lt;br /&gt;
  ( number unitID, number radius, number height ) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.UnitWeaponFire&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number weaponID ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.UnitWeaponHoldFire&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number weaponID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Unit LOS ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitCloak&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID,&lt;br /&gt;
    boolean cloaked | number scriptCloak,&lt;br /&gt;
    [ number decloakDistance | boolean decloakAbs ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
  If the 2nd argument is a number, the value works like this:&lt;br /&gt;
   1:=normal cloak&lt;br /&gt;
   2:=for free cloak (cost no E)&lt;br /&gt;
   3:=for free + no decloaking (except the unit is stunned)&lt;br /&gt;
   4&amp;gt;=ultimative cloak (no ecost, no decloaking, no stunned decloak)&lt;br /&gt;
&lt;br /&gt;
  The decloak distance is only changed if the 3th argument is a number or a boolean.&lt;br /&gt;
   If the boolean is false it takes the default decloak distance for that unitdef,&lt;br /&gt;
   if the boolean is true it takes the absolute value of it.&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitSonarStealth&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, boolean sonarStealth ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitStealth&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, boolean stealth ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitAlwaysVisible&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, boolean alwaysVisible ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitLosMask&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number allyTeam, number los | table losTypes ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;the 3th argument is either the bit-and combination of the following numbers:&lt;br /&gt;
  LOS_INLOS     = 1&lt;br /&gt;
  LOS_INRADAR   = 2&lt;br /&gt;
  LOS_PREVLOS   = 4&lt;br /&gt;
  LOS_CONTRADAR = 8&lt;br /&gt;
&amp;lt;/font&amp;gt;&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;or a table of the following form:&lt;br /&gt;
  losTypes = {&lt;br /&gt;
    [los = boolean,]&lt;br /&gt;
    [radar = boolean,]&lt;br /&gt;
    [prevLos = boolean,]&lt;br /&gt;
    [contRadar = boolean,]&lt;br /&gt;
  }&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitLosState&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number allyTeam, number los | table losTypes ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;see above for more info on the arguments&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitSensorRadius&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string type, number radius ) -&amp;gt; nil | number newRadius&lt;br /&gt;
  &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;type can be:&lt;br /&gt;
  &amp;quot;los&amp;quot;,&amp;quot;airLos&amp;quot;,&amp;quot;radar&amp;quot;,&amp;quot;sonar&amp;quot;,&amp;quot;seismic&amp;quot;,&amp;quot;radarJammer&amp;quot;,&amp;quot;sonarJammer&amp;quot;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetRadarErrorParams&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  (number allyTeamID, number allyteamErrorSize &lt;br /&gt;
  [, number baseErrorSize [, number baseErrorMult ]]) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitPosErrorParams&#039;&#039;&#039; {{new|95.0}}&lt;br /&gt;
  (number unitID, number posErrorVector.x, number posErrorVector.y, number posErrorVector.z,&lt;br /&gt;
  number posErrorDelta.x, number posErrorDelta.y, number posErrorDelta.z&lt;br /&gt;
  [ , number nextPosErrorUpdate]) --&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Unit Resourcing ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitResourcing&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID,&lt;br /&gt;
    string res, number amount |&lt;br /&gt;
    { res = number amount, ... }&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
  possible values for res are: &amp;quot;[u|c][u|m][m|e]&amp;quot;&lt;br /&gt;
       unconditional | conditional&lt;br /&gt;
                 use | make&lt;br /&gt;
               metal | energy&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AddUnitResource&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string &amp;quot;m&amp;quot; | &amp;quot;e&amp;quot;, number amount ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.UseUnitResource&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string &amp;quot;m&amp;quot; | &amp;quot;e&amp;quot;, number amount ) -&amp;gt; nil | boolean okay&lt;br /&gt;
  ( number unitID, { [&amp;quot;m&amp;quot; | &amp;quot;metal&amp;quot; | &amp;quot;e&amp;quot; | &amp;quot;energy&amp;quot;] = amount, ... } ) -&amp;gt; nil | boolean okay&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitHarvestStorage&#039;&#039;&#039; {{new|97.0}}&lt;br /&gt;
  ( number unitid, number metal )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class = &amp;quot;note&amp;quot;&amp;gt;See also {{xtaglink|Gamedev:UnitDefs|harvestStorage}} UnitDef tag.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Feature Handling =&lt;br /&gt;
&#039;&#039;&#039;Spring.CreateFeature&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;defName&amp;quot; | number featureDefID, &lt;br /&gt;
    number x, number y, number z&lt;br /&gt;
    [, number heading &lt;br /&gt;
    [, number AllyTeamID &lt;br /&gt;
    [, number featureID ]]] ) -&amp;gt; number featureID&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.DestroyFeature&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.TransferFeature&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, number teamID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Feature Control ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureHealth&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, number health) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureResources&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( number featureID, number metal, number energy [, number reclaimTime [, number reclaimLeft ]] )&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureReclaim&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, number reclaimLeft) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureResurrect&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, number unitDefID | string unitDefName [, number facing | string &amp;quot;facing&amp;quot; [, number progress ]] ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
  possible values for facing are:&lt;br /&gt;
    &amp;quot;south&amp;quot; | &amp;quot;s&amp;quot; | 0&lt;br /&gt;
    &amp;quot;east&amp;quot;  | &amp;quot;e&amp;quot; | 1&lt;br /&gt;
    &amp;quot;north&amp;quot; | &amp;quot;n&amp;quot; | 2&lt;br /&gt;
    &amp;quot;west&amp;quot;  | &amp;quot;w&amp;quot; | 3&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
{{new|104.0}} Second param can now be a number id instead of a string name, this also allows cancelling ressurection by passing {{value|-1}}. The level of progress can now be set via the additional 4th param.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeaturePosition&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, number x, number y, number z [, boolean snapToGround]) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureDirection&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, number x, number y, number z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureRotation&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number featureID, number x, number y, number z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureVelocity&#039;&#039;&#039; {{New|95.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeaturePhysics&#039;&#039;&#039; {{New|95.0}}&lt;br /&gt;
&lt;br /&gt;
(like their feature counterparts at [[Lua_SyncedCtrl#Unit_Control]])&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureMoveCtrl&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID [, boolean enable [, number* args]]) to control feature movement&lt;br /&gt;
   the number* arguments are parsed as follows and all optional&lt;br /&gt;
   if enable is true:&lt;br /&gt;
     [, velVector(x,y,z) -- initial velocity for feature&lt;br /&gt;
     [, accVector(x,y,z) -- acceleration added every frame&lt;br /&gt;
     ]]&lt;br /&gt;
   if enable is false:&lt;br /&gt;
     [, velocityMask(x,y,z) -- dimensions in which velocity is allowed to build when not using MoveCtrl&lt;br /&gt;
     [,  impulseMask(x,y,z) -- dimensions in which impulse is allowed to apply when not using MoveCtrl&lt;br /&gt;
     [, movementMask(x,y,z) -- dimensions in which feature is allowed to move when not using MoveCtrl&lt;br /&gt;
     ]]]&lt;br /&gt;
&lt;br /&gt;
As of spring 103.0 it is necessary to unlock feature movement on x,z axis before changing feature physics. For example use &amp;quot;Spring.SetFeatureMoveCtrl(featureID,false,1,1,1,1,1,1,1,1,1)&amp;quot; to unlock all movement prior to making SetFeatureVelocity calls.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureNoSelect&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, boolean noSelect ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureAlwaysVisible&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, boolean enable ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureCollisionVolumeData&#039;&#039;&#039;&lt;br /&gt;
  ( number featureID, number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
    number offsetX, number offsetY, number offsetX,&lt;br /&gt;
    number vType, number tType, number Axis&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;check Spring.SetUnitCollisionVolumeData for further explanation of the arguments&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeaturePieceCollisionVolumeData&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number featureID, number pieceIndex, boolean enable, &lt;br /&gt;
    number scaleX, number scaleY, number scaleZ,&lt;br /&gt;
    number offsetX, number offsetY, number offsetZ&lt;br /&gt;
    [, number volumeType [, number primaryAxis]]&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureMidAndAimPos&#039;&#039;&#039; {{new|89.0}}&lt;br /&gt;
  ( number unitID, &lt;br /&gt;
    number mpx, number mpy, number mpz, &lt;br /&gt;
    number apx, number apy, number apz, &lt;br /&gt;
    [, boolean relative] ) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;check Spring.SetUnitMidAndAimPos for further explanation of the arguments&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureRadiusAndHeight&#039;&#039;&#039; {{new|89.0}}&lt;br /&gt;
  ( number unitID, number radius, number height ) -&amp;gt; boolean success&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureMass&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number featureID, number mass ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureBlocking&#039;&#039;&#039;&lt;br /&gt;
  (number featureID, boolean blocking, boolean collidable) --&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetFeatureBlocking&#039;&#039;&#039; {{new|95.0}} changed parameters:&lt;br /&gt;
  number featureID,&lt;br /&gt;
  boolean isBlocking,&lt;br /&gt;
  boolean isSolidObjectCollidable,&lt;br /&gt;
  boolean isProjectileCollidable,&lt;br /&gt;
  boolean isRaySegmentCollidable,&lt;br /&gt;
  boolean crushable,&lt;br /&gt;
  boolean blockEnemyPushing,&lt;br /&gt;
  boolean blockHeightChanges&lt;br /&gt;
&lt;br /&gt;
= Lua to COB =&lt;br /&gt;
&#039;&#039;&#039;Spring.CallCOBScript&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number funcID | string funcName, number retArgs, COBArg1, COBArg2, ... )&lt;br /&gt;
    -&amp;gt; nil | number returnValue, number retArg1, number retArg2, ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.CallCOBScriptCB&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;font style=&amp;quot;color:red;font-weight:600&amp;quot;&amp;gt;broken in 0.78.2.1; will be removed with the introduction of Lua as COB replacement&amp;lt;/font&amp;gt;&lt;br /&gt;
  ( number unitID, number funcID | string funcName, number retArgs, COBArg1, COBArg2, ... )&lt;br /&gt;
    -&amp;gt; nil | number returnValue, number CallbackData, number retArg1, number retArg2, ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetCOBScriptID&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, string funcName ) -&amp;gt; nil | number funcID&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Note: Don&#039;t use Spring.[Get|Set]UnitCOBValue in LUS just because you are familar with it since bos/cob, use the mighty LuaSpringAPI instead!&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GetUnitCOBValue&#039;&#039;&#039; &lt;br /&gt;
  ( number unitID [, boolean splitData=false], number COBValue&lt;br /&gt;
    [, number param1 [,number param2 [, number param3 [, number param4 ] ] ] ] )&lt;br /&gt;
  -&amp;gt; number result | number result1, number result2&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;you find the possible values for `COBValue` in [[Lua_ConstCOB#Get.2FSet|Lua_ConstCOB]]&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;span class=note&amp;gt; also see [[Animation-CobConstants#Custom_Variables|Custom_Variables]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitCOBValue&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number COBValue, number param1 [,number param2] ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;you find the possible values for `COBValue` in [[Lua_ConstCOB#Get.2FSet|Lua_ConstCOB]]&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;span class=note&amp;gt; also see [[Animation-CobConstants#Custom_Variables|Custom_Variables]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Give Order =&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;options can also be a bitmask; e.g. 0 instead of an empty table (can avoid performance hit on table creation)&amp;lt;br&amp;gt;&lt;br /&gt;
see [[Lua CMDs]] for relevant constants&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderToUnit&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID,&lt;br /&gt;
    number cmdID,&lt;br /&gt;
    params = {number, etc...},&lt;br /&gt;
    options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;} ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderToUnitMap&#039;&#039;&#039;&lt;br /&gt;
  ( unitMap = { [unitID] = dontCare, etc... },&lt;br /&gt;
    number cmdID,&lt;br /&gt;
    params = {number, etc...},&lt;br /&gt;
    options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;} ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderToUnitArray&#039;&#039;&#039;&lt;br /&gt;
  ( unitArray = { [1] = unitID, etc... },&lt;br /&gt;
    number cmdID,&lt;br /&gt;
    params = {number, etc...},&lt;br /&gt;
    options = {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;} ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderArrayToUnitMap&#039;&#039;&#039;&lt;br /&gt;
  ( unitMap = { [number unitID] = dontCare, etc... },&lt;br /&gt;
    orderArray = {&lt;br /&gt;
      { number cmdID,&lt;br /&gt;
        {number, etc...},     &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;params&amp;lt;/font&amp;gt;&lt;br /&gt;
        {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;}   &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;options&amp;lt;/font&amp;gt;&lt;br /&gt;
      }, ..&lt;br /&gt;
    }&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.GiveOrderArrayToUnitArray&#039;&#039;&#039;&lt;br /&gt;
  ( unitArray = { [1] = number unitID, etc... },&lt;br /&gt;
    orderArray = {&lt;br /&gt;
      { number cmdID,&lt;br /&gt;
        {number, etc...},    &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;params&amp;lt;/font&amp;gt;&lt;br /&gt;
        {&amp;quot;alt&amp;quot;, &amp;quot;ctrl&amp;quot;, &amp;quot;shift&amp;quot;, &amp;quot;right&amp;quot;}   &amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;options&amp;lt;/font&amp;gt;&lt;br /&gt;
      }, ..&lt;br /&gt;
    }&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
=Ground=&lt;br /&gt;
== Grass ==&lt;br /&gt;
&#039;&#039;&#039;Spring.AddGrass&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.RemoveGrass&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
== Heightmap ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Note that x &amp;amp; z coords are in worldspace (Game.mapSizeX/Z), still the heightmap resolution is [[Lua_ConstGame|Game.squareSize]].&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.LevelHeightMap&#039;&#039;&#039;&lt;br /&gt;
  ( number x1, number z1 [, number x2, number z2], number height ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.AdjustHeightMap&#039;&#039;&#039; &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;(heightmap[x][z] += height;)&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number x1, number z1 [, number x2, number z2], number height ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.RevertHeightMap&#039;&#039;&#039;&lt;br /&gt;
  ( number x1, number z1 [, number x2, number z2], number origFactor ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetHeightMapFunc&#039;&#039;&#039;&lt;br /&gt;
  ( lua_function [, arg1 ,[ arg2 [, ... ] ] ) -&amp;gt; nil | number absTotalHeightMapAmountChanged&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;Example code:&amp;lt;/span&amp;gt;&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
Spring.SetHeightMapFunc(function()&lt;br /&gt;
	for z=0,Game.mapSizeZ, Game.squareSize do&lt;br /&gt;
		for x=0,Game.mapSizeX, Game.squareSize do&lt;br /&gt;
			Spring.SetHeightMap( x, z, 200 + 20 * math.cos((x + z) / 90) )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Spring.AddHeightMap&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;can only be called in SetHeightMapFunc()&amp;lt;/span&amp;gt; &lt;br /&gt;
  ( number x, number z, number height ) -&amp;gt; nil | number newHeight&lt;br /&gt;
&#039;&#039;&#039;Spring.SetHeightMap&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;can only be called in SetHeightMapFunc()&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number x, number z, number height [,number terraform = 1] ) -&amp;gt; nil | number absHeightDiff&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;the terraform argument is a scaling factor:&lt;br /&gt;
so if 0 nothing will be changed (the terraform starts) and if it is 1 the terraform will be finished.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.LevelSmoothMesh&#039;&#039;&#039;&lt;br /&gt;
  ( number x1, number z1 [, number x2, number z2], number height ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.AdjustSmoothMesh&#039;&#039;&#039;&lt;br /&gt;
  ( number x1, number z1 [, number x2, number z2], number height ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.RevertSmoothMesh&#039;&#039;&#039;&lt;br /&gt;
  ( number x1, number z1 [, number x2, number z2], number origFactor ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSmoothMeshFunc&#039;&#039;&#039;&lt;br /&gt;
  ( lua_function [, arg1 ,[ arg2 [, ... ] ] ) -&amp;gt; nil | number absTotalHeightMapAmountChanged&lt;br /&gt;
&#039;&#039;&#039;Spring.AddSmoothMesh&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;can only be called in SetSmoothMeshFunc()&amp;lt;/span&amp;gt; &lt;br /&gt;
  ( number x, number z, number height ) -&amp;gt; nil | number newHeight&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSmoothMesh&#039;&#039;&#039; &amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;can only be called in SetSmoothMeshFunc()&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number x, number z, number height [,number terraform = 1] ) -&amp;gt; nil | number absHeightDiff&lt;br /&gt;
&lt;br /&gt;
== TerrainTypes ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetMapSquareTerrainType&#039;&#039;&#039;&lt;br /&gt;
  ( number x, number z, int newType ) -&amp;gt; nil | int oldType&lt;br /&gt;
&#039;&#039;&#039;Spring.SetTerrainTypeData&#039;&#039;&#039;&lt;br /&gt;
  ( int typeIndex&lt;br /&gt;
  [, number speedTanks = nil ]&lt;br /&gt;
  [, number speedKBOTs = nil ]&lt;br /&gt;
  [, number speedHovers = nil ]&lt;br /&gt;
  [, number speedShips = nil ] ) -&amp;gt; nil | boolean true&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetSquareBuildingMask&#039;&#039;&#039; {{new|103.0}}&lt;br /&gt;
  ( number x, number z, int mask ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
See also {{xtaglink|Gamedev:UnitDefs|buildingMask}} unitdef tag.&lt;br /&gt;
&lt;br /&gt;
== MetalAmount ==&lt;br /&gt;
&#039;&#039;&#039;Spring.SetMetalAmount&#039;&#039;&#039; {{new|83.0}}&lt;br /&gt;
  ( number x, number z, number metalAmount)&lt;br /&gt;
&amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;x &amp;amp; z coords are in worldspace/16&amp;lt;br&amp;gt;metalAmount must be between 0 and 255*maxMetal (with maxMetal from the .smd or mapinfo.lua)&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Command Descriptions =&lt;br /&gt;
&amp;lt;font color=&amp;quot;red&amp;quot; style=&amp;quot;font-size:120%; font-weight:600&amp;quot;&amp;gt;Doesn&#039;t work in unsynced code!&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.EditUnitCmdDesc&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID, number cmdDescID, table cmdArray ) -&amp;gt; nil&lt;br /&gt;
&amp;lt;font color=&amp;quot;#55ee99&amp;quot;&amp;gt;&lt;br /&gt;
  structure of cmdArray:&lt;br /&gt;
  {&lt;br /&gt;
    [ id          = int ],&lt;br /&gt;
    [ type        = int ],&lt;br /&gt;
    [ name        = string ],&lt;br /&gt;
    [ action      = string ],&lt;br /&gt;
    [ tooltip     = string ],&lt;br /&gt;
    [ texture     = string ],&lt;br /&gt;
    [ cursor      = string ],&lt;br /&gt;
    [ queueing    = boolean ],&lt;br /&gt;
    [ hidden      = boolean ],&lt;br /&gt;
    [ disabled    = boolean ],&lt;br /&gt;
    [ showUnique  = boolean ],&lt;br /&gt;
    [ onlyTexture = boolean ],&lt;br /&gt;
    [ params      = { string = string, ... } ]&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
{{var|queueing}} is {{new|101.0}} and allows custom commands to be non-queueing (handy for state toggles).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.InsertUnitCmdDesc&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number cmdDescID ] , table cmdArray ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.RemoveUnitCmdDesc&#039;&#039;&#039;&lt;br /&gt;
  ( number unitID [, number cmdDescID ] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
= Other =&lt;br /&gt;
&#039;&#039;&#039;Spring.SetNoPause&#039;&#039;&#039;&lt;br /&gt;
  ( boolean noPause ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetUnitToFeature&#039;&#039;&#039;&lt;br /&gt;
  ( boolean tofeature ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
an ugly global switch that can be used to block units turning into features when they finish being built (like *A DT&#039;s do, which have the isFeature tag)&lt;br /&gt;
[http://springrts.com/phpbb/viewtopic.php?f=14&amp;amp;p=481521 thread]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetExperienceGrade&#039;&#039;&#039;&lt;br /&gt;
  ( number expGrade [, number ExpPowerScale [, number ExpHealthScale [, number ExpReloadScale ]]] ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
  expGrade defines how often UnitExperience() will be called,&lt;br /&gt;
  Prior to 104.0 it is based on the following equation:&lt;br /&gt;
     (int) [exp/(exp+1)] / expGrade&lt;br /&gt;
  Post 104.0 it is the raw change.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SpawnExplosion&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( number posX = 0, number posY = 0, number posZ = 0,&lt;br /&gt;
    number dirX = 0, number dirY = 0, number dirZ = 0,&lt;br /&gt;
    table explosionParams&lt;br /&gt;
  ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;possible keys of explosionParams are:&lt;br /&gt;
    weaponDef = number,&lt;br /&gt;
    owner = number,&lt;br /&gt;
    hitUnit = number,&lt;br /&gt;
    hitFeature = number,&lt;br /&gt;
    craterAreaOfEffect = number,&lt;br /&gt;
    damageAreaOfEffect = number,&lt;br /&gt;
    edgeEffectiveness = number,&lt;br /&gt;
    explosionSpeed = number,&lt;br /&gt;
    gfxMod = number,&lt;br /&gt;
    impactOnly = boolean,&lt;br /&gt;
    ignoreOwner = boolean,&lt;br /&gt;
    damageGround = boolean,&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SpawnCEG&#039;&#039;&#039;&lt;br /&gt;
  ( string &amp;quot;cegname&amp;quot; | number cegID,&lt;br /&gt;
    number posX = 0, number posY = 0, number posZ = 0,&lt;br /&gt;
    number dirX = 0, number dirY = 0, number dirZ = 0,&lt;br /&gt;
    number radius = 0, number damage = 0&lt;br /&gt;
  ) -&amp;gt; nil | boolean success, cegID&lt;br /&gt;
&amp;lt;span class=&amp;quot;warning&amp;quot;&amp;gt;cegID new in 95.0&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SpawnSFX&#039;&#039;&#039; {{new|104.0}}&lt;br /&gt;
  ( number unitID, number sfxID,&lt;br /&gt;
    number posX = 0, number posY = 0, number posZ = 0,&lt;br /&gt;
    number dirX = 0, number dirY = 0, number dirZ = 0,&lt;br /&gt;
    number radius = 0, number damage = 0&lt;br /&gt;
    [, boolean absolute ]&lt;br /&gt;
  ) -&amp;gt; nil | boolean success&lt;br /&gt;
&lt;br /&gt;
Equal to the [[Animation-LuaCallouts#Effects|UnitScript versions of EmitSFX]], but takes position and direction arguments (in either unit- or piece-space) instead of a piece index.&lt;br /&gt;
&lt;br /&gt;
= Projectiles =&lt;br /&gt;
&#039;&#039;&#039;Spring.SpawnProjectile&#039;&#039;&#039;&lt;br /&gt;
  ( number weaponDefID, table projectileParams ) -&amp;gt; nil | number projectileID&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;possible keys of projectileParams are:&lt;br /&gt;
    pos = {number x, number y, number z},&lt;br /&gt;
    end = {number x, number y, number z},&lt;br /&gt;
    speed = {number x, number y, number z},&lt;br /&gt;
    spread = {number x, number y, number z},&lt;br /&gt;
    error = {number x, number y, number z},&lt;br /&gt;
    owner = number,&lt;br /&gt;
    team = number,&lt;br /&gt;
    ttl = number,&lt;br /&gt;
    gravity = number,&lt;br /&gt;
    tracking = number,&lt;br /&gt;
    maxRange = number,&lt;br /&gt;
    startAlpha = number,&lt;br /&gt;
    endAlpha = number,&lt;br /&gt;
    model = string,&lt;br /&gt;
    cegTag = string,&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.DeleteProjectile&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number projID ) -&amp;gt; nil&lt;br /&gt;
Silently removes projectiles (no explosion).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileTarget&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class = &amp;quot;warning&amp;quot;&amp;gt;Pre 95.0:&amp;lt;/span&amp;gt;  ( number projectileID, &lt;br /&gt;
    [ number targetID, string targetTypeStr ] | [ number posX, number posY, number posZ ] ) &lt;br /&gt;
    -&amp;gt; nil | boolean validTarget&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class = &amp;quot;warning&amp;quot;&amp;gt;Post 95.0:&amp;lt;/span&amp;gt;  ( number projectileID, &lt;br /&gt;
    [ number targetID [, number targetType]]  |  [number posX, number posY, number posZ]) &lt;br /&gt;
    --&amp;gt; nil | boolean validTarget&lt;br /&gt;
  &amp;lt;span class=note&amp;gt;targetTypeStr can be one of: &lt;br /&gt;
    &#039;u&#039; - unit&lt;br /&gt;
    &#039;f&#039; - feature&lt;br /&gt;
    &#039;p&#039; - projectile&lt;br /&gt;
  while targetTypeInt is one of:&lt;br /&gt;
    string.byte(&#039;g&#039;) := GROUND&lt;br /&gt;
    string.byte(&#039;u&#039;) := UNIT&lt;br /&gt;
    string.byte(&#039;f&#039;) := FEATURE&lt;br /&gt;
    string.byte(&#039;p&#039;) := PROJECTILE&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileIgnoreTrackingError&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number projID, bool ignore ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileIsIntercepted&#039;&#039;&#039; {{new|99.0}}&lt;br /&gt;
  ( number projID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileMoveControl&#039;&#039;&#039; &amp;lt;span class=note&amp;gt;(disables engine movecontrol, so lua can fully control the physics)&amp;lt;/span&amp;gt;&lt;br /&gt;
  ( number projID, boolean enable ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectilePosition&#039;&#039;&#039;&lt;br /&gt;
  ( number projID [, number x = 0 [, number y = 0 [, number z = 0 ]]] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileVelocity&#039;&#039;&#039;&lt;br /&gt;
  ( number projID [, number x = 0 [, number y = 0 [, number z = 0 ]]] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileCollision&#039;&#039;&#039;&lt;br /&gt;
  ( number projID ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileGravity&#039;&#039;&#039; &lt;br /&gt;
  ( number projID [, number grav = 0] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileSpinAngle&#039;&#039;&#039; {{new|95.0}} Deprecated&lt;br /&gt;
  ( number projID [, number spinAngle = 0] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileSpinSpeed&#039;&#039;&#039; {{new|95.0}} Deprecated&lt;br /&gt;
  ( number projID [, number speed = 0] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileSpinVec&#039;&#039;&#039; {{new|95.0}} Deprecated&lt;br /&gt;
  ( number projID [, number x = 0 [, number y = 0 [, number z = 0]]] ) -&amp;gt; nil&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileCEG&#039;&#039;&#039;&lt;br /&gt;
  ( number projID, string ceg_name ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetPieceProjectileParams&#039;&#039;&#039; {{new|95.0}} &lt;br /&gt;
  (number projectileID,&lt;br /&gt;
  [ number explosionFlags, [ number spinAngle, [ number spinSpeed,&lt;br /&gt;
  [ number spinVector.x, [ number spinVector.y, [ number spinVector.z ]]]]]]) --&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileAlwaysVisible&#039;&#039;&#039; {{new|95.0}} &lt;br /&gt;
    (number projectileID, boolean alwaysVisible) --&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spring.SetProjectileDamages&#039;&#039;&#039; {{new|101.0}}&lt;br /&gt;
  ( number unitID, number weaponNum, table damages ) -&amp;gt; nil&lt;br /&gt;
  ( number unitID, number weaponNum, string key, number value ) -&amp;gt; nil&lt;br /&gt;
  &amp;lt;span class=&amp;quot;note&amp;quot;&amp;gt;format of the damages table:&lt;br /&gt;
   {&lt;br /&gt;
      [&amp;quot;paralyzeDamageTime&amp;quot; = number value,]  &lt;br /&gt;
      [&amp;quot;impulseFactor&amp;quot;      = number value,]&lt;br /&gt;
      [&amp;quot;impulseBoost&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;craterMult&amp;quot;         = number value,]&lt;br /&gt;
      [&amp;quot;craterBoost&amp;quot;        = number value,]&lt;br /&gt;
      [&amp;quot;dynDamageExp&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;dynDamageMin&amp;quot;       = number value,]&lt;br /&gt;
      [&amp;quot;dynDamageRange&amp;quot;     = number value,]&lt;br /&gt;
      [&amp;quot;dynDamageInverted&amp;quot;  = number value,] (&amp;lt;&amp;gt;0.0f := true)&lt;br /&gt;
      [&amp;quot;craterAreaOfEffect&amp;quot; = number value,]&lt;br /&gt;
      [&amp;quot;damageAreaOfEffect&amp;quot; = number value,]&lt;br /&gt;
      [&amp;quot;edgeEffectiveness&amp;quot;  = number value,]&lt;br /&gt;
      [&amp;quot;explosionSpeed&amp;quot;     = number value,]&lt;br /&gt;
      [number armorType     = number value,] (changes the damage against this armor type)&lt;br /&gt;
    }&lt;br /&gt;
  &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Icontypes.lua&amp;diff=9815</id>
		<title>Icontypes.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Icontypes.lua&amp;diff=9815"/>
		<updated>2018-12-03T03:08:01Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Location==&lt;br /&gt;
&amp;lt;code&amp;gt;icontypes.lua&amp;lt;/code&amp;gt; is a file in the &amp;lt;code&amp;gt;Gamedata/&amp;lt;/code&amp;gt; directory of a Spring Game. &lt;br /&gt;
&lt;br /&gt;
==Purpose==&lt;br /&gt;
This file defines the icons used to represent units on the minimap and rendered in place of 3d geometry when zoomed out.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which parses the data from this file is viewable here:&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/Rendering/IconHandler.cpp}}&lt;br /&gt;
&lt;br /&gt;
==Data Types==&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
&lt;br /&gt;
Game developers can set icons for different types of units, (such as land, air, sea), or go so far as to give every unit its own icon. The different types icons will be shown for friendly units, and enemy units within Line Of Sight. For enemy units in radar range Spring will use the &#039;default&#039; icon.&lt;br /&gt;
&lt;br /&gt;
===IconType Properties===&lt;br /&gt;
{{tag&lt;br /&gt;
|name = bitmap&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = The location of the custom icon image (not limited to bitmaps!). If it is missing or incorrect, Spring replaces it with the standard radar dot. The bitmap will get blended with the team color, so there is no special team color channel. In order to look nice, the image will need to have an alpha channel for transparency.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = size&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Acts as multiplier for the icon size. The larger the number, the larger the icon will be.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = distance&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 1.0&lt;br /&gt;
|description = Acts as a multiplier for the distance at which the unit will show up as an icon. The larger the number, the further away the camera has to be from the unit for it to turn into an icon.}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = radiusAdjust&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Whether or not the icon should scale with the unit radius.}}&lt;br /&gt;
&lt;br /&gt;
===Assigning IconTypes===&lt;br /&gt;
To assign units to a specific icon type, set the {{xtaglink|Gamedev:UnitDefs|iconType}} attribute of their UnitDef to the type name set in &amp;lt;code&amp;gt;icontypes.lua&amp;lt;/code&amp;gt; (see [[#Example]])&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
iconType = &amp;quot;circle&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the {{xtaglink|Gamedev:UnitDefs|iconType}} tag is missing, Spring sets it to the &amp;quot;default&amp;quot; icontype. If the &amp;quot;default&amp;quot; type is not specified, Spring will create it with the default values. Furthermore, enemy units that are within radar range, but not in your Line Of Sight, will be shown as the default icon. Thus if there is a bitmap specified for the &amp;quot;default&amp;quot; icon type it will override the standard radar blip.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local iconTypes = {&lt;br /&gt;
  default = {&lt;br /&gt;
    size = 1,&lt;br /&gt;
    radiusadjust = true,&lt;br /&gt;
  },&lt;br /&gt;
  flag = {&lt;br /&gt;
    bitmap = &amp;quot;icons/flag.png&amp;quot;,&lt;br /&gt;
    size = 6,&lt;br /&gt;
    radiusadjust = true,&lt;br /&gt;
    distance = 100,&lt;br /&gt;
  },&lt;br /&gt;
  circle = {&lt;br /&gt;
    bitmap = &amp;quot;icons/circle.png&amp;quot;,&lt;br /&gt;
    size = 4,&lt;br /&gt;
    radiusadjust = true,&lt;br /&gt;
    distance = 100,&lt;br /&gt;
  },&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return iconTypes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Gamedata]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=CEG:Defs&amp;diff=3889</id>
		<title>CEG:Defs</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=CEG:Defs&amp;diff=3889"/>
		<updated>2018-12-02T10:26:13Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Overall Format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= CEG Definitions =&lt;br /&gt;
&lt;br /&gt;
==Source== &lt;br /&gt;
The engine source code which loads the tags from these files is viewable here:&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/Sim/Projectiles/}} &lt;br /&gt;
* {{sourcelink|file=rts/Sim/Projectiles/Unsynced/}}&lt;br /&gt;
* {{sourcelink|file=rts/Rendering/GroundFlash.cpp}}&lt;br /&gt;
&lt;br /&gt;
== Data Types ==&lt;br /&gt;
CEGs use the following data types:&lt;br /&gt;
{{DataTypes}}&lt;br /&gt;
&lt;br /&gt;
You can use [[CEG:Operators]] to define floats that are not fixed.&lt;br /&gt;
&lt;br /&gt;
== CEG Textures ==&lt;br /&gt;
&lt;br /&gt;
* Textures on CEG definitions are referenced by name.&lt;br /&gt;
* The list of available textures and their names should be in [[resources.lua]]&lt;br /&gt;
* Texture definitions to be used in projectile classes should be placed within the &amp;lt;code&amp;gt;projectiletextures&amp;lt;/code&amp;gt; category and textures to be used with [[#CSimpleGroundFlash]] class should be placed within the &amp;lt;code&amp;gt;groundfx&amp;lt;/code&amp;gt; category.&lt;br /&gt;
* Texture images are usually placed in the &amp;quot;bitmaps&amp;quot; subfolder.&lt;br /&gt;
&lt;br /&gt;
== Overall Format ==&lt;br /&gt;
&lt;br /&gt;
A CEG file contains one or more CEGs. Each CEG follows this format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
return {&lt;br /&gt;
  [&amp;quot;ceg_name&amp;quot;] = {&lt;br /&gt;
    -- EXPLOSION LEVEL&lt;br /&gt;
    useDefaultExplosions = false,&lt;br /&gt;
&lt;br /&gt;
    spawner1_name = {&lt;br /&gt;
      -- SPAWNER LEVEL&lt;br /&gt;
      class         = &amp;quot;CClassName&amp;quot;,&lt;br /&gt;
      count              = 1,&lt;br /&gt;
      air                = true,&lt;br /&gt;
      ground             = true,&lt;br /&gt;
      water              = true,&lt;br /&gt;
      properties = {&lt;br /&gt;
        -- CLASS LEVEL&lt;br /&gt;
        },&lt;br /&gt;
      },&lt;br /&gt;
    },&lt;br /&gt;
    spawner2_name = {&lt;br /&gt;
      -- SPAWNER LEVEL&lt;br /&gt;
      -- each spawner follows the above format&lt;br /&gt;
    },&lt;br /&gt;
    groundflash = {&lt;br /&gt;
      -- groundflash is a special spawner name; it always generates a CStandardGroundFlash&lt;br /&gt;
      -- CStandardGroundFlash properties&lt;br /&gt;
    },&lt;br /&gt;
  },&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Explosion Level Tags ==&lt;br /&gt;
{{tag&lt;br /&gt;
|name = useDefaultExplosions&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = If this is set, the CEG will use the default explosion (based on damage and area of effect) in addition to any spawners you define. The default explosions are sometimes very performance heavy, especially for large damage values (leading to higher particle counts).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Spawner Level Tags ==&lt;br /&gt;
A CEG can contain any number of spawners. The name of the spawners don&#039;t really matter, as long as it&#039;s not &amp;lt;code&amp;gt;groundflash&amp;lt;/code&amp;gt;, which has a special meaning. You can think of each spawner as being one component of the overall explosion.&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = class&lt;br /&gt;
|type = string&lt;br /&gt;
|default = spawner_name&lt;br /&gt;
|description = Each spawner has a class that determines what kind of graphical effect it creates. Spring has a number of standard classes that you can choose from. Currently available classes are:&lt;br /&gt;
* [[#CExpGenSpawner|CExpGenSpawner]]&lt;br /&gt;
* [[#CBitmapMuzzleFlame|CBitmapMuzzleFlame]]&lt;br /&gt;
* [[#CExploSpikeProjectile|CExploSpikeProjectile]] &lt;br /&gt;
* [[#CHeatCloudProjectile|CHeatCloudProjectile]]&lt;br /&gt;
* [[#CSimpleParticleSystem|CSimpleParticleSystem]]&lt;br /&gt;
* [[#CSpherePartSpawner|CSpherePartSpawner]]&lt;br /&gt;
* [[#CSimpleGroundFlash|CSimpleGroundFlash]]&lt;br /&gt;
* [[#CStandardGroundFlash|CStandardGroundFlash]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = count&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = The count determines the number of times the spawner will run.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Visibility Conditions ===&lt;br /&gt;
These determine under what conditions the spawner will run. If you set the condition to true, the spawner will run if the explosion takes place under that condition. If you set more than one condition, the spawner will run if &#039;&#039;any&#039;&#039; of them are true. If you want a spawner to run only if two or more conditions are &#039;&#039;all&#039;&#039; true, you have to do a little trick with the [[#CExpGenSpawner]] class as explained in &amp;quot;suggested use&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = air&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = The CEG will run if at least 20 [[elmo]]s above ground/sea level.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = water&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = The CEG will run if in water to a depth of -5 [[elmo]]s.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = underwater&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = The CEG will run if under water deeper than 5 [[elmo]]s.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = ground&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = The CEG will run if less than 20 [[elmo]]s above ground.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = unit&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = The CEG will run if the weapon hits a unit.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = nounit&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = The CEG will run if the weapon does not hit a unit.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Class Level Tags ==&lt;br /&gt;
=== Common Properties ===&lt;br /&gt;
All classes have the following properties, although not all of them use them:&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = alwaysVisible&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = If true, the spawner is always visible, ignoring LoS. Note that prior to 98.0 this did not work correctly.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = useAirLos&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = Whether the spawner uses air LoS to determine if it is visible. This may allow the spawner to be seen from a further distance than normal.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = pos &lt;br /&gt;
|type = float[3]&lt;br /&gt;
|default = {0.0, 0.0, 0.0}&lt;br /&gt;
|description = The initial position vector of the spawner.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = speed&lt;br /&gt;
|type = float[3]&lt;br /&gt;
|default = {0.0, 0.0, 0.0}&lt;br /&gt;
|description = The initial speed vector of the spawner.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = dir&lt;br /&gt;
|type = float[3]&lt;br /&gt;
|description = The initial direction vector of the spawner.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== CExpGenSpawner ===&lt;br /&gt;
This is the closest thing CEG has to a function call. Instead of creating a graphical effect on its own, it creates another CEG.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
* If you use a spawner a lot of times, you may want to make it a separate CEG to avoid having to copy-paste many times.&lt;br /&gt;
* This is the only way to truly delay a graphical effect.&lt;br /&gt;
* The spawned CEG still checks conditions, so if you want to, say, spawn an effect only if it is in water &#039;&#039;and&#039;&#039; doesn&#039;t hit a unit, you can give the CExpGenSpawner &amp;lt;code&amp;gt;nounit = 1;&amp;lt;/code&amp;gt; and the spawned &amp;lt;code&amp;gt;CEG water = 1;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* This allows you to give a set of spawners the same (and possibly random) direction.&lt;br /&gt;
* You can animate an explosion flip-book style using delays and several bitmaps.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = delay&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 1&lt;br /&gt;
|description = How long to wait (in frames?) before spawning the CEG.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = damage&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The CEG will be called with this damage. The CEG doesn&#039;t actually deal any damage, but you can use this as a parameter and read it using the [[CEG:Operators#Damage_.28.27d.27.29|&#039;d&#039; operator]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = explosionGenerator&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = The name of the CEG you want to spawn.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== CBitmapMuzzleFlame ===&lt;br /&gt;
This creates three rectangular textures at right angles to each other. The {{taglink|frontTexture}} has {{taglink|dir}} as its normal.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
*Muzzle flames, obviously.&lt;br /&gt;
*You can use an upward-pointing CBitmapMuzzleFlame as a simple splash of water or dirt.&lt;br /&gt;
*Railgun trails.&lt;br /&gt;
*This is the only class that both obeys perspective and allows for a custom texture.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = sideTexture&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = Texture as viewed from the side.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = frontTexture&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = Texture as viewed from the front.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = colorMap&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = See [[CColorMap]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = size&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The initial width of the muzzle flame.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = length&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The initial length of the muzzle flame.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = sizeGrowth &lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = By the end of its life, the muzzle flame grows to &amp;lt;code&amp;gt;1 + sizeGrowth&amp;lt;/code&amp;gt; times its initial {{taglink|size}} and {{taglink|length}}. The flame grows quickly at first and more slowly toward the end.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = ttl&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = How long the muzzle flame lasts.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = frontOffset&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = Where the frontTexture is along the length of the muzzle flame. &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; means it is in the back, &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; is in the front.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== CExploSpikeProjectile ===&lt;br /&gt;
&lt;br /&gt;
This creates a glowy spike. Note that the spike is two sided, i.e., symmetric about the position of the spawner.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
* Anything glowy.&lt;br /&gt;
* For large, slow missiles, you can try using this as an extended engine flame. Set the width to something fairly large.&lt;br /&gt;
* Long and thin spikes will look spiky; meanwhile, shorter and wider spikes look more blobby.&lt;br /&gt;
* The colors of spikes add together, so if you have several spikes and all three color channels are non-zero, it will be white in the center.&lt;br /&gt;
* The length growth of the spike depends on the norm of the dir vector. The spike does not grow in width.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
{{tag&lt;br /&gt;
|name = length&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The initial length of (half) of the spike (multiplied by {{taglink|dir}}).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = lengthGrowth&lt;br /&gt;
|type = float&lt;br /&gt;
|default = dir.Length() * (0.5 + RandFloat() * 0.4)&lt;br /&gt;
|description = How much the length increases by per update.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = width&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = Half the initial width of of the spike. This is an absolute value.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = alpha&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The starting alpha of the spike.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = alphaDecay&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How quickly the alpha of the spike decreases.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = color&lt;br /&gt;
|type = rgb&lt;br /&gt;
|default = {1.0, 0.8, 0.5}&lt;br /&gt;
|description = The color of the spike.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== CHeatCloudProjectile ===&lt;br /&gt;
&lt;br /&gt;
Creates an expanding sprite. Simple but effective.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
* As the main background to an explosion.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
{{tag&lt;br /&gt;
|name = heat&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = Used in alpha calculations. See {{taglink|heatFalloff}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = maxheat&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = Used in alpha calculations. See {{taglink|heatFalloff}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = heatFalloff&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = This is really confusing way of representing alpha and alphaDecay. Basically &amp;lt;code&amp;gt;alpha = &amp;lt;/code&amp;gt;{{taglink|heat}}&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;{{taglink|maxheat}}, and &amp;lt;code&amp;gt;alphaDecay = &amp;lt;/code&amp;gt;{{taglink|heatFalloff}}&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;{{taglink|maxHeat}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = size&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The initial radius of the heatcloud.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = sizeGrowth&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The heatcloud grows by this amount every frame.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = sizeMod&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The size of the heatcloud is multiplied by &amp;lt;code&amp;gt;1 - sizeMod&amp;lt;/code&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = sizeModMod&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = Each frame, {{taglink|sizeMod}} is multiplied by {{taglink|sizeModMod}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = texture&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;heatcloud&amp;quot; as referenced in [[resources.lua]]&lt;br /&gt;
|description = The texture used for the heatcloud.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== CSimpleParticleSystem ===&lt;br /&gt;
&lt;br /&gt;
Creates a sprite that can undergo complex motion. Probably the most versatile class.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
* Anything moving that is not doing so at constant velocity.&lt;br /&gt;
* If you want something that expands (or shrinks) to some size then stops, set {{taglink|sizeMod}} to something less than &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, and {{taglink|sizeGrowth}} to something positive. The particle will grow to a size equal to &amp;lt;code&amp;gt;sizeGrowth / (1 - sizeMod)&amp;lt;/code&amp;gt; and stop. The smaller {{taglink|sizeMod}} is, the faster it will reach this size.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
===== Initial Velocity Properties =====&lt;br /&gt;
{{tag&lt;br /&gt;
|name = emitVector&lt;br /&gt;
|type = float[3]&lt;br /&gt;
|default = {0.0, 0.0, 0.0}&lt;br /&gt;
|description = The initial direction vector in which the particle is emitted. When spawning CEGs via EmitSfx you can make the particles go into the direction of the emiting piece with {{taglink|emitvector|dir}}. This is useful for e.g. fire coming out of a gun barrel.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = emitRot&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = At what angle to emit the particle relative to {{taglink|emitVector}}. &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; means that the particle will be emitted in {{taglink|emitVector}}&#039;s direction; &amp;lt;code&amp;gt;180&amp;lt;/code&amp;gt; will emit the particle in the opposite direction. &amp;lt;code&amp;gt;90&amp;lt;/code&amp;gt; will emit the particle in a random direction perpendicular to {{taglink|emitVector}}, which is good for creating rings.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = emitRotSpread&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = For each particle, a random number between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and {{taglink|emitRotSpread}} is added to the {{taglink|emitRot}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = emitMul&lt;br /&gt;
|type = float[3]&lt;br /&gt;
|default = {1.0, 1.0, 1.0}&lt;br /&gt;
|description = Scales the initial particle velocity; for this property, +y is considered to be in the direction of {{taglink|emitVector}}. Good if you want to create an egg-shaped explosion.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = particleSpeed &lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The particle&#039;s initial speed.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = particleSpeedSpread&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = For each particle, a random number between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and {{taglink|particleSpeedSpread}} is added to the {{taglink|particleSpeed}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Movement Properties =====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = gravity&lt;br /&gt;
|type = float[3]&lt;br /&gt;
|default = {0.0, 0.0, 0.0}&lt;br /&gt;
|description = This will be added to the particle&#039;s velocity every frame.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = airdrag&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The particle&#039;s velocity is multiplied by this every frame.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Size Properties =====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = particleSize &lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The initial size of the particle.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = particleSizeSpread&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = For each particle, a random number between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and {{taglink|particleSizeSpread}} is added to the {{taglink|particleSize}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = sizeGrowth&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much the particle grows each frame.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = sizeMod&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The size of the particle is multiplied by this each frame.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Visual Properties =====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = directional&lt;br /&gt;
|type = bool&lt;br /&gt;
|default = false&lt;br /&gt;
|description = If true, the particle will point in the direction it is moving.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = texture&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = The texture to use for the particle.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = colorMap&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = See [[CColorMap]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Life Properties =====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = numParticles&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = How many particles to create. This is not the same as &amp;lt;code&amp;gt;count&amp;lt;/code&amp;gt;; if you spawn multiple particles using &amp;lt;code&amp;gt;count&amp;lt;/code&amp;gt;, any [[CEG:Operators]] will be re-evaluated for each particle, whereas if you use {{taglink|numParticles}} they will not be. However, the spread properties are evaluated separately for each particle regardless of which one you use.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = particleLife&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How long each particle lasts. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = particleLifeSpread&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = For each particle, a random number between &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; and {{taglink|particleLifeSpread}} is added to the {{taglink|particleLife}}.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== CSpherePartSpawner ===&lt;br /&gt;
&lt;br /&gt;
Draws an expanding sphere.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
*Looks like a shockwave.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = alpha&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The alpha of the sphere.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = ttl&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = Time to live, in frames(?).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = expansionSpeed&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How quickly the sphere expands.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = color&lt;br /&gt;
|type = rgb&lt;br /&gt;
|default = {0.0, 0.0, 0.0}&lt;br /&gt;
|description = The color of the sphere.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== CSimpleGroundFlash ===&lt;br /&gt;
&lt;br /&gt;
Draws an expanding ground texture.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
* A short groundflash (~8 frames) is good for any explosion that gives off light. You can also use a longer groundflash to suggest the ground is glowing from heat.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = size&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The radius of the particle.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = sizeGrowth&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How much the particle grows each frame.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = ttl&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = Time to live, in frames(?).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = texture&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = The texture to use for the particle.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = colorMap&lt;br /&gt;
|type = string&lt;br /&gt;
|default = &amp;quot;&amp;quot;&lt;br /&gt;
|description = See [[CColorMap]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== CStandardGroundFlash ===&lt;br /&gt;
If you name a spawner &amp;quot;groundflash,&amp;quot; it will always generate a standard groundflash. &lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
A short groundflash (~8 frames) is good for any explosion that gives off light. You can also use a longer groundflash to suggest the ground is glowing from heat.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = flashSize&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = The radius of the groundflash.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = flashAlpha &lt;br /&gt;
|type = float&lt;br /&gt;
|range = [0, 1]&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How transparent the groundflash is. Generally the higher the brighter.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = circleGrowth &lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = A groundflash can have an additional circle that expands outwards. This controls how fast the circle grows.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = circleAlpha&lt;br /&gt;
|type = float&lt;br /&gt;
|range = [0, 1]&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How transparent the circle is.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = ttl&lt;br /&gt;
|type = int&lt;br /&gt;
|default = 0&lt;br /&gt;
|description = How long the groundflash lasts.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = color&lt;br /&gt;
|type = rgb&lt;br /&gt;
|default = {1.0, 1.0, 0.8}&lt;br /&gt;
|description = The color of the groundflash.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== CSmokeProjectile2 ===&lt;br /&gt;
( {{FIXME}} newly added to wiki. someone cross-check then remove this note )&lt;br /&gt;
&lt;br /&gt;
Particles that begin with a hard-coded yellow-red colorfade and then fade to monochrom. (shades of grey)&lt;br /&gt;
&lt;br /&gt;
Movement is influenced by the random wind.&lt;br /&gt;
Finer details of visual and position update are best explained by looking at the formulas in &amp;lt;code&amp;gt;CSmokeProjectile2::Update() &amp;amp; CSmokeProjectile2::Draw()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
Smoke. Smokestacks, rocket exhaust, burning wreckage,...&lt;br /&gt;
&lt;br /&gt;
For a nicer stream of smoke spawn it frequently over multiple frames, otherwise it looks rather bland.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
{{tag&lt;br /&gt;
|name = color&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.5&lt;br /&gt;
|description = How dark the final monochrom color of a particle is. 0 is black.&lt;br /&gt;
(Use &amp;gt;1 for slightly bugged funnies, like slightly non-monochrome colors or interessting black/white changes.)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = size&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = Size of a particle.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = ageSpeed&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.5&lt;br /&gt;
|description = How fast the particle ages. Every frame: &amp;lt;code&amp;gt;age += ageSpeed&amp;lt;/code&amp;gt; The particle is deleted at &amp;lt;code&amp;gt;if (age &amp;gt; 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = glowFalloff&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = How fast the particle fades to monochrom.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = wantedPos&lt;br /&gt;
|type = float3&lt;br /&gt;
|default = &amp;quot;0,0,0&amp;quot;&lt;br /&gt;
|description = In which direction the smoke tends to drift. Less effective in y-coordinate and influenced by random wind. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = speed&lt;br /&gt;
|type = float3&lt;br /&gt;
|default = &amp;quot;0,0,0&amp;quot;&lt;br /&gt;
|description = &amp;lt;code&amp;gt;wantedPos += speed;&amp;lt;/code&amp;gt; How fast and in which vector the particles move.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = texture&lt;br /&gt;
|type = hardcoded&lt;br /&gt;
|default = randomly chosen. &lt;br /&gt;
|description = Particles randomly pick one of the smoke textures (bitmaps\smoke) and remain with it until death.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== CSmokeProjectile ===&lt;br /&gt;
Monochrome particles that fade out.&lt;br /&gt;
A more &amp;quot;primitive&amp;quot; version of CSmokeProjectile2. &lt;br /&gt;
No hardcoded red-yellow start but it misses wantedPos to tweak the look a bit more detailed.&lt;br /&gt;
&lt;br /&gt;
==== Suggested Use ====&lt;br /&gt;
Smoke. &lt;br /&gt;
For a nicer stream of smoke spawn it frequently over multiple frames, otherwise it looks rather bland.&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
{{tag&lt;br /&gt;
|name = color&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.5&lt;br /&gt;
|description = Brightness of the particle. 0 is black.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = size&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.0&lt;br /&gt;
|description = Size of a particle&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = ageSpeed&lt;br /&gt;
|type = float&lt;br /&gt;
|default = 0.5&lt;br /&gt;
|description = How fast the particle ages. Every frame: &amp;lt;code&amp;gt;age += ageSpeed&amp;lt;/code&amp;gt; The particle is deleted at &amp;lt;code&amp;gt;if (age &amp;gt; 1)&amp;lt;/code&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = speed&lt;br /&gt;
|type = float3&lt;br /&gt;
|default = &amp;quot;0,0,0&amp;quot;&lt;br /&gt;
|description = &amp;lt;code&amp;gt;pos += speed;&amp;lt;/code&amp;gt; How fast and in which vector the particles move.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{tag&lt;br /&gt;
|name = texture&lt;br /&gt;
|type = hardcoded&lt;br /&gt;
|default = randomly chosen. &lt;br /&gt;
|description = Particles randomly pick one of the smoke textures (bitmaps\smoke) and remain with it until death.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- can&#039;t use the following until all games use effects/ rather than gamedata/explosions&lt;br /&gt;
{{ExampleRepoLinks&lt;br /&gt;
|path = effects/&lt;br /&gt;
|entity = CEGs&lt;br /&gt;
}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[http://imolarpg.dyndns.org/trac/balatest/browser/trunk/gamedata/explosions &#039;Balanced Annihilation&#039; CEGs] (TDF format)&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/conflictterra/source/browse/#svn%2Fgames%2FCT%2Fgamedata%2Fexplosions &#039;Conflict Terra&#039; CEGs]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/EvolutionRTS/Evolution-RTS/tree/master/Gamedata/explosions &#039;Evolution RTS&#039; CEGs]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/imperialwinter/swiw.sdd/tree/master/gamedata/explosions &#039;Imperial Winter&#039; CEGs] (TDF format)&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/journeywar/source/browse/#svn%2Ftrunk%2Fgamedata%2Fexplosions &#039;Journeywar&#039; CEGs]&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/p/mwspring/code/HEAD/tree/effects/ &#039;MechCommander: Legacy&#039; CEGs] (TDF format)&lt;br /&gt;
&lt;br /&gt;
[https://github.com/spring1944/spring1944/tree/master/effects &#039;Spring: 1944&#039; CEGs] (TDF format)&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/springtutorialgame/source/browse/#svn%2Ftrunk%2FSpringTutorialGame.sdd%2FGamedata%2Fexplosions &#039;Spring Tutorial Game&#039; CEGs]&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/xta-springrts/source/browse/#svn%2Ftrunk%2Fgamedata%2Fexplosions &#039;XTA&#039; CEGs] (TDF format)&lt;br /&gt;
&lt;br /&gt;
[https://github.com/ZeroK-RTS/Zero-K/tree/master/effects &#039;ZeroK&#039; CEGs]&lt;br /&gt;
&lt;br /&gt;
[[Category:CEG]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Resources.lua&amp;diff=15987</id>
		<title>Resources.lua</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Resources.lua&amp;diff=15987"/>
		<updated>2018-12-02T10:25:50Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Location==&lt;br /&gt;
&amp;lt;code&amp;gt;resources.lua&amp;lt;/code&amp;gt; is a file in the &amp;lt;code&amp;gt;Gamedata/&amp;lt;/code&amp;gt; directory of a Spring Game.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;resources_map.lua&amp;lt;/code&amp;gt; is a file in the &amp;lt;code&amp;gt;Gamedata/&amp;lt;/code&amp;gt; directory of a Spring Map.&lt;br /&gt;
&lt;br /&gt;
==Purpose==&lt;br /&gt;
This file is used by a game to reference textures for use in [[CEG|Custom Explosion Generators]], as well as various default explosions and other engine textures such as default trees and water etc. Maps have a corresponding file, &amp;lt;code&amp;gt;resources_map.lua&amp;lt;/code&amp;gt; which behaves in the same way.&lt;br /&gt;
&lt;br /&gt;
==Source==&lt;br /&gt;
The engine source code which parses the data from this file is viewable here:&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/Rendering/ProjectileDrawer.cpp}} (smoke, groundfx &amp;amp; projectiletextures) &amp;lt;code&amp;gt;resources_map.lua&amp;lt;/code&amp;gt; is only read here.&lt;br /&gt;
&lt;br /&gt;
* {{sourcelink|file=rts/Rendering/GroundDecalHandler.cpp}} (scars)&lt;br /&gt;
* {{sourcelink|file=rts/Rendering/Env/AdvTreeGenerator.cpp}} (trees)&lt;br /&gt;
* {{sourcelink|file=rts/Map/MapInfo.cpp}} (caustics &amp;amp; maps)&lt;br /&gt;
&lt;br /&gt;
==Details==&lt;br /&gt;
&lt;br /&gt;
The engine loads textures from seven subtables within the &amp;lt;code&amp;gt;graphics&amp;lt;/code&amp;gt; subtable of the returned resources table. Certain tables are automatically added by the engine if a game is not overriding them, they are numerical arrays whereas all others are key-value associative arrays. Engine defaults which are required to be present are included in the [[#Automatic]] example below.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;caustics&amp;lt;/code&amp;gt; - Textures used with bumpmapped water. Automatically added by the engine.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;smoke&amp;lt;/code&amp;gt; - Textures used for engine default smoke. Automatically added by the engine.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;scars&amp;lt;/code&amp;gt; - Textures used for the burn scars left on the map by weapon explosions. Automatically added by the engine.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;trees&amp;lt;/code&amp;gt; - Textures for engine default trees.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;maps&amp;lt;/code&amp;gt; - Base textures in case a map does not provide it&#039;s own.&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;groundfx&amp;lt;/code&amp;gt; - Game or Map specific textures for [[CEG-Classes#CSimpleGroundFlash|CSimpleGroundFlash]] CEG&#039;s as well as engine default explosion [[CEG-Format#groundflash|groundflash]].&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;projectiletextures&amp;lt;/code&amp;gt; - Game or Map specific textures for the other [[CEG-Classes]] as well as engine defaults. This is the only table that is read from &amp;lt;code&amp;gt;resources_map.lua&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
===Automatic===&lt;br /&gt;
The following example (which is becoming a [http://en.wikipedia.org/wiki/De_facto_standard de facto standard]) sets out the engine default textures, and recursively adds any textures from the game&#039;s &amp;lt;code&amp;gt;Bitmaps/projectileTextures/&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Bitmaps/groundFX/&amp;lt;/code&amp;gt; directories, respectively. It will ignore any directories created by [http://en.wikipedia.org/wiki/Apache_Subversion SVN], and can be easily edited to filter out [http://en.wikipedia.org/wiki/Git_(software) git] or any other version control software.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local  resources = {&lt;br /&gt;
    graphics = {&lt;br /&gt;
      -- Spring Defaults&lt;br /&gt;
      trees = {&lt;br /&gt;
        bark           = &#039;Bark.bmp&#039;,&lt;br /&gt;
        leaf           = &#039;bleaf.bmp&#039;,&lt;br /&gt;
        gran1          = &#039;gran.bmp&#039;,&lt;br /&gt;
        gran2          = &#039;gran2.bmp&#039;,&lt;br /&gt;
        birch1         = &#039;birch1.bmp&#039;,&lt;br /&gt;
        birch2         = &#039;birch2.bmp&#039;,&lt;br /&gt;
        birch3         = &#039;birch3.bmp&#039;,&lt;br /&gt;
      },&lt;br /&gt;
      maps = {&lt;br /&gt;
        detailtex      = &#039;detailtex2.bmp&#039;,&lt;br /&gt;
        watertex       = &#039;ocean.jpg&#039;,&lt;br /&gt;
      },&lt;br /&gt;
      groundfx = {&lt;br /&gt;
        groundflash    = &#039;groundflash.tga&#039;,&lt;br /&gt;
        groundring     = &#039;groundring.tga&#039;,&lt;br /&gt;
        seismic        = &#039;circles.tga&#039;,&lt;br /&gt;
      },&lt;br /&gt;
      projectiletextures = {&lt;br /&gt;
        circularthingy = &#039;circularthingy.tga&#039;,&lt;br /&gt;
        laserend       = &#039;laserend.tga&#039;,&lt;br /&gt;
        laserfalloff   = &#039;laserfalloff.tga&#039;,&lt;br /&gt;
        randdots       = &#039;randdots.tga&#039;, &lt;br /&gt;
        smoketrail     = &#039;smoketrail.tga&#039;,&lt;br /&gt;
        wake           = &#039;wake.tga&#039;,&lt;br /&gt;
        flare          = &#039;flare.tga&#039;,&lt;br /&gt;
        explo          = &#039;explo.tga&#039;,&lt;br /&gt;
        explofade      = &#039;explofade.tga&#039;,&lt;br /&gt;
        heatcloud      = &#039;explo.tga&#039;,&lt;br /&gt;
        flame          = &#039;flame.tga&#039;,&lt;br /&gt;
        muzzleside     = &#039;muzzleside.tga&#039;,&lt;br /&gt;
        muzzlefront    = &#039;muzzlefront.tga&#039;,&lt;br /&gt;
        largebeam      = &#039;largelaserfalloff.tga&#039;,&lt;br /&gt;
      },&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
local VFSUtils = VFS.Include(&#039;gamedata/VFSUtils.lua&#039;)&lt;br /&gt;
&lt;br /&gt;
local function AutoAdd(subDir, map, filter)&lt;br /&gt;
  local dirList = RecursiveFileSearch(&amp;quot;bitmaps/&amp;quot; .. subDir)&lt;br /&gt;
  for _, fullPath in ipairs(dirList) do&lt;br /&gt;
    local path, key, ext = fullPath:match(&amp;quot;bitmaps/(.*/(.*)%.(.*))&amp;quot;)&lt;br /&gt;
    if not fullPath:match(&amp;quot;/%.svn&amp;quot;) then&lt;br /&gt;
    local subTable = resources[&amp;quot;graphics&amp;quot;][subDir] or {}&lt;br /&gt;
    resources[&amp;quot;graphics&amp;quot;][subDir] = subTable&lt;br /&gt;
      if not filter or filter == ext then&lt;br /&gt;
        if not map then&lt;br /&gt;
          table.insert(subTable, path)&lt;br /&gt;
        else -- a mapped subtable&lt;br /&gt;
          subTable[key] = path&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Add mod projectiletextures and groundfx&lt;br /&gt;
AutoAdd(&amp;quot;projectiletextures&amp;quot;, true)&lt;br /&gt;
AutoAdd(&amp;quot;groundfx&amp;quot;, true)&lt;br /&gt;
&lt;br /&gt;
return resources&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===External===&lt;br /&gt;
{{sourcelink|file=cont/base/springcontent/gamedata/resources.lua}} - Engine base content &amp;lt;code&amp;gt;resources.lua&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Gamedata]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Template:Obtaining_The_Source_Code&amp;diff=23070</id>
		<title>Template:Obtaining The Source Code</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Template:Obtaining_The_Source_Code&amp;diff=23070"/>
		<updated>2018-11-23T00:29:19Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Tarballs ===&lt;br /&gt;
&#039;&#039;&#039;(For playing online)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Tarballs}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Git ===&lt;br /&gt;
[https://github.com/spring/spring Spring project page at github]&lt;br /&gt;
&lt;br /&gt;
Master repo URI: &amp;lt;code&amp;gt;{{GitCloneUrl}}&amp;lt;/code&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Backup repo: &amp;lt;code&amp;gt;git://git.code.sf.net/p/springrts/code&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Latest Stable (master branch)====&lt;br /&gt;
Assuming the GIT command line client is installed, you can clone the repository with&lt;br /&gt;
&amp;lt;pre&amp;gt;git clone --recursive git://github.com/spring/spring.git -b master&amp;lt;/pre&amp;gt;&lt;br /&gt;
and update it with:&lt;br /&gt;
&amp;lt;pre&amp;gt;git pull --rebase&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Bleeding-edge (develop branch)====&lt;br /&gt;
This will also allow you to make a patch out of the changes you make to the code, and send it to one of the developers with repository access. If you are new to git and github, you may want to have a look at [http://help.github.com/ this guide] to get you started.&lt;br /&gt;
&lt;br /&gt;
Just as above with a minimal change: {{code|git clone --recursive git://github.com/spring/spring.git -b develop}}&lt;br /&gt;
and update with: {{code|git pull --rebase}}&lt;br /&gt;
&lt;br /&gt;
Note: you can switch &amp;lt;code&amp;gt;branches&amp;lt;/code&amp;gt; this way:{{code|&lt;br /&gt;
# backup your current changes&lt;br /&gt;
git stash&lt;br /&gt;
&lt;br /&gt;
# switch branch&lt;br /&gt;
git checkout $MY_OTHER_BRANCH&lt;br /&gt;
&lt;br /&gt;
# sometimes needed&lt;br /&gt;
# note, it deletes all your unstashed changes and all non-pushed commits on the new branch,&lt;br /&gt;
# but it doesn&#039;t delete untracked files.&lt;br /&gt;
#git reset --hard &lt;br /&gt;
&lt;br /&gt;
# update/sync with remote repo&lt;br /&gt;
git pull --rebase&lt;br /&gt;
&lt;br /&gt;
#optional&lt;br /&gt;
#git stash pop # reapplies your changes and DELETES the backup&lt;br /&gt;
#or&lt;br /&gt;
#git stash apply --index 0  # reapplies your changes and keep the backup (see `git stash list`)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
====Submodules====&lt;br /&gt;
To obtain the submodules you should clone the repository with --recursive as mentioned above.&lt;br /&gt;
If you haven&#039;t done this, you can execute the following code&lt;br /&gt;
{{code|&lt;br /&gt;
git submodule sync&lt;br /&gt;
git submodule update --init&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
To update the submodules, you have to execute the same commands again or pull normally.&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Building_Spring_on_Linux&amp;diff=3408</id>
		<title>Building Spring on Linux</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Building_Spring_on_Linux&amp;diff=3408"/>
		<updated>2018-11-23T00:28:05Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Building_spring|Building Spring]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
= Build From Source on Linux =&lt;br /&gt;
If you prefer to use your distributions package system (release versions only), refer to the Linux [[SetupGuide]].&lt;br /&gt;
&lt;br /&gt;
If there is no package tailored for your distribution, you have to install from sources manually. Doing this for distributions where packages are available is not recommended.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=warning&amp;gt;&#039;&#039;&#039;Warning:&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Be careful when building from source.&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
You might encounter sync errors in online play if:&lt;br /&gt;
* you are using an untested compiler (&#039;&#039;gcc&#039;&#039; from the &amp;gt;=4.6 series should be safe)&lt;br /&gt;
* you use non-standard compiler settings (be careful about &#039;&#039;-march&#039;&#039;)!&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Obtaining the Source ==&lt;br /&gt;
{{Obtaining_The_Source_Code}}&lt;br /&gt;
&lt;br /&gt;
= Get Dependencies =&lt;br /&gt;
&lt;br /&gt;
To compile, you will have to install some development packages Spring depends on. These vary from distro to distro and may also depend on your specific configuration.&lt;br /&gt;
&lt;br /&gt;
If your distributions is not listed below, you should be able to figure out the correct package names from this.&lt;br /&gt;
&lt;br /&gt;
== Full list ==&lt;br /&gt;
* Programs necessary to build&lt;br /&gt;
** &#039;&#039;cmake&#039;&#039;&lt;br /&gt;
** &#039;&#039;7zip&#039;&#039; (aka &#039;&#039;p7zip&#039;&#039; or &#039;&#039;7z&#039;&#039;)&lt;br /&gt;
** The usual build toolchain&lt;br /&gt;
*** &#039;&#039;gcc&#039;&#039;&lt;br /&gt;
*** &#039;&#039;make&#039;&#039;&lt;br /&gt;
* Libraries&lt;br /&gt;
** SDL2&lt;br /&gt;
** &#039;&#039;libdeviL&#039;&#039; (IL)&lt;br /&gt;
** OpenAL (openal-soft, older openal-0.0.8 does not work)&lt;br /&gt;
** OpenGL headers (mesa, GLEW, etc.)&lt;br /&gt;
** &#039;&#039;zlib&#039;&#039;&lt;br /&gt;
** &#039;&#039;freetype&#039;&#039; (2)&lt;br /&gt;
** &#039;&#039;ogg&#039;&#039;, &#039;&#039;vorbis&#039;&#039; and &#039;&#039;vorbisfile&#039;&#039;&lt;br /&gt;
** &#039;&#039;curl&#039;&#039;&lt;br /&gt;
* Optional (for AI Interfaces, Skirmish AIs and unit tests)&lt;br /&gt;
** &#039;&#039;python&#039;&#039; (2.5+)&lt;br /&gt;
** &#039;&#039;jdk&#039;&#039; (1.5+)&lt;br /&gt;
** &#039;&#039;boost&#039;&#039; (version 1.47 or later)&lt;br /&gt;
*** &#039;&#039;chrono&#039;&#039;&lt;br /&gt;
*** &#039;&#039;filesystem&#039;&#039;&lt;br /&gt;
*** &#039;&#039;threads&#039;&#039;&lt;br /&gt;
*** &#039;&#039;system&#039;&#039;&lt;br /&gt;
*** &#039;&#039;chrono&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Debian ==&lt;br /&gt;
&lt;br /&gt;
For Jessie (debian 8.0 stable) this should work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential zlib1g-dev libfreetype6-dev cmake \&lt;br /&gt;
libsdl2-dev libopenal-dev libglew-dev zip libvorbis-dev libxcursor-dev \&lt;br /&gt;
libdevil-dev libboost-system1.55-dev libboost-thread1.55-dev \&lt;br /&gt;
libboost-regex1.55-dev libboost-serialization1.55-dev \&lt;br /&gt;
libboost-program-options1.55-dev libboost-chrono1.55-dev \&lt;br /&gt;
libunwind-dev  libboost-filesystem1.55-dev \&lt;br /&gt;
libboost-signals1.55-dev libboost-test1.55-dev \&lt;br /&gt;
xsltproc libfontconfig1-dev libcurl4-openssl-dev&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu  ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# compiler and build tools&lt;br /&gt;
sudo apt-get install build-essential cmake cmake-gui git &lt;br /&gt;
&lt;br /&gt;
# spring dependencies&lt;br /&gt;
sudo apt-get install libglew-dev libsdl2-dev libdevil-dev libopenal-dev \&lt;br /&gt;
 libogg-dev libvorbis-dev libfreetype6-dev p7zip-full libxcursor-dev \&lt;br /&gt;
 libboost-thread-dev libboost-regex-dev libboost-system-dev \&lt;br /&gt;
 libboost-program-options-dev libboost-signals-dev \&lt;br /&gt;
 libboost-chrono-dev libboost-filesystem-dev libunwind8-dev \&lt;br /&gt;
 default-jdk libcurl4-gnutls-dev&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to speed up compiling/linking, you can install gold, an alternative linker and when you plan to develop / recompile often ccache :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo apt-get install binutils-gold ccache&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
to make ccache useful, the cache size needs to be increased by:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ccache -M 5G&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to set it to 5GB.&lt;br /&gt;
&lt;br /&gt;
== Gentoo ==&lt;br /&gt;
This has been tested to work with a clean install of gentoo 2008.0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
emerge cmake \&amp;gt;=media-libs/freetype-2.0.0 \&amp;gt;=media-libs/libsdl-2&lt;br /&gt;
emerge media-libs/openal media-libs/glew dev-libs/boost&lt;br /&gt;
emerge app-arch/zip media-libs/libogg&lt;br /&gt;
USE=&amp;quot;png jpg tiff opengl&amp;quot; emerge media-libs/devil &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or better you install Spring via [http://springrts.com/wiki/Gentoo_install layman], it will install all dependencies.&lt;br /&gt;
&lt;br /&gt;
== Fedora ==&lt;br /&gt;
&lt;br /&gt;
On Fedora 12-21:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo yum install gcc-c++ cmake boost-devel DevIL-devel freetype-devel libunwind-devel \&lt;br /&gt;
glew-devel libvorbis-devel libXcursor-devel openal-devel SDL2-devel p7zip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On Fedora 8:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
yum install cmake boost-devel openal-devel SDL2-devel \&lt;br /&gt;
DevIL-devel glew-devel libvorbis-devel &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Slackware ==&lt;br /&gt;
&lt;br /&gt;
On Slackware 13, cmake, ogg &amp;amp; vorbis, boost, glew and SDL2 already come with the full regular install, both libs and headers. You can find helper scripts to easily compile and package DevIL, OpenAL and spring itself [http://slackbuilds.org/ here].&lt;br /&gt;
&lt;br /&gt;
Try to use [http://idlemoor.github.io/slackrepo/ slackrepo], will search, update and install spring and dependences.&lt;br /&gt;
&lt;br /&gt;
= Build And Install =&lt;br /&gt;
&lt;br /&gt;
== Using CMake (2.6 or newer) ==&lt;br /&gt;
Configure and build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake .&lt;br /&gt;
make spring&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make install-spring&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Default install paths are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/local/bin/spring&amp;lt;/code&amp;gt; Spring executable&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/local/share/games/spring&amp;lt;/code&amp;gt; read-only data&lt;br /&gt;
&lt;br /&gt;
If you want &amp;lt;code&amp;gt;~/spring&amp;lt;/code&amp;gt; prefix instead of &amp;lt;code&amp;gt;/usr/local&amp;lt;/code&amp;gt;, configure like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake -DCMAKE_INSTALL_PREFIX=~/spring .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For further ways of customizing your build, have a look at the variables shown with:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake -LH .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For other targets see the output of &amp;lt;code&amp;gt;make help&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= See Also: =&lt;br /&gt;
* [[Finalizing_linux_install]]&lt;br /&gt;
* [[Troubleshooting_linux]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Compiling]]&lt;br /&gt;
[[Category:Linux]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Coding_Standards&amp;diff=4498</id>
		<title>Coding Standards</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Coding_Standards&amp;diff=4498"/>
		<updated>2018-11-23T00:25:20Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span class=warning&amp;gt;&lt;br /&gt;
This document is not yet finished.&amp;lt;br&amp;gt;&lt;br /&gt;
Please add new points whenever they occur to you.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Compiler=&lt;br /&gt;
&lt;br /&gt;
Keep in mind that we use gcc (g++) as the main compiler, likewise for linux and windows builds. So be sure your code compiles and works with gcc.&lt;br /&gt;
&lt;br /&gt;
=Directory structure=&lt;br /&gt;
&lt;br /&gt;
http://github.com/spring/spring/blob/master/directories.txt&lt;br /&gt;
&lt;br /&gt;
=Style=&lt;br /&gt;
&lt;br /&gt;
==Indentation==&lt;br /&gt;
&lt;br /&gt;
Use tabs, not spaces. This allows anyone to choose their favorite indentation size.&lt;br /&gt;
&lt;br /&gt;
This implies that you should not use tabs in any other place then indentation. E.g. in the following sample use SPACE to align the constants.&lt;br /&gt;
{{code|&lt;br /&gt;
  #define LOS_INLOS   1&lt;br /&gt;
  #define LOS_INRADAR 2&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Do not attempt to align method parameters in a function call when breaking it over multiple lines. Just indent them using two tabs. Trying to align parameters with the opening parenthesis is unmaintainable: next time someone refactors the code and changes the function name, he has to go through all places it is used this way and waste his time inserting/removing spaces. Of course this applies to similar cases too; in general aligning stuff in such a way that an identifier rename requires realignment of all code using that identifier is bad practice.&lt;br /&gt;
&lt;br /&gt;
==Curly braces==&lt;br /&gt;
&lt;br /&gt;
For top-level types (struct/class/union/enum), braces go on the next line and for function definitions they may go on the same line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  class CMyClass&lt;br /&gt;
  {&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  void MyFunction()&lt;br /&gt;
  {&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // fine too&lt;br /&gt;
  void MyFunction2() {&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Non-top-level types may use the same style as control flow braces.&lt;br /&gt;
&lt;br /&gt;
For control flow, braces go on the same line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  if (condition) {&lt;br /&gt;
  } else {&lt;br /&gt;
  }&lt;br /&gt;
  for (int i = 0; i &amp;lt; 10; ++i) {&lt;br /&gt;
    do {&lt;br /&gt;
      while (condition2) {&lt;br /&gt;
      }&lt;br /&gt;
    } while (condition1);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For if-else statements (and similar), the following is also fine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  if (condition) {&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For if&#039;s with a single line statement, it is preferred to omit the braces if no braces belonging to another control block follow immediately after the statement:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function() { // recommended&lt;br /&gt;
  if (condition)&lt;br /&gt;
    statement;&lt;br /&gt;
  if (condition) {&lt;br /&gt;
    statement;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
function() { // okay&lt;br /&gt;
  if (condition) {&lt;br /&gt;
    statement;&lt;br /&gt;
  }&lt;br /&gt;
  if (condition)&lt;br /&gt;
    statement;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Naming==&lt;br /&gt;
&lt;br /&gt;
In Spring engine code, concrete classes are prefixed with C, interfaces with I, structs with S. Both use CamelCase. Functions and methods use CamelCase too. Parameters, fields, variables use pascalCase.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // interface&lt;br /&gt;
  class ISkirmishAI&lt;br /&gt;
  {&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  // concrete class implementing interface&lt;br /&gt;
  class CMySkirmishAI : public ISkirmishAI&lt;br /&gt;
  {&lt;br /&gt;
    void MyMethod(bool myParam);&lt;br /&gt;
    int myField;&lt;br /&gt;
    char* myStr;&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are two exception to this however:&lt;br /&gt;
* helper subclasses do not have any prefix, and&lt;br /&gt;
* value types neither (it is &amp;quot;&amp;lt;code&amp;gt;float3&amp;lt;/code&amp;gt;&amp;quot;, not &amp;quot;&amp;lt;code&amp;gt;Cfloat3&amp;lt;/code&amp;gt;&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
File-names are usually identical to the name of the main class that is inside, with the prefix stripped off. For example, &amp;lt;code&amp;gt;MySkirmishAI.cpp&amp;lt;/code&amp;gt; for class &amp;lt;code&amp;gt;CMySkirmishAI&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
&lt;br /&gt;
Try to keep code as readable as possible. This means, do not write very long functions, but split the problem in multiple functions. Use identifier names with an actual meaning as opposed to a,b,c, etc. The point is to allow other devs to &amp;quot;read&amp;quot; the code, as opposed to &amp;quot;figure it out&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Keep classes dedicated to a single function, do not create big monolithic classes which no one understands.&lt;br /&gt;
&lt;br /&gt;
Insert a blank line to separate two parts of a function that have very distinct functionality. Otherwise try to keep the code compact with as few lines as possible, but avoid putting multiple statements on a single line and do not write lines more than 120 characters long.&lt;br /&gt;
&lt;br /&gt;
We use comment tags (TODO, FIXME, ..) as described [http://en.wikipedia.org/wiki/Comment_%28computer_programming%29#Tags here].&lt;br /&gt;
&lt;br /&gt;
On pointer or reference types, try to keep the respective symbol adjacent to the type:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // better&lt;br /&gt;
  char* myStr;&lt;br /&gt;
  float* MyMethod(const char&amp;amp; myParam);&lt;br /&gt;
  int* MyVar = (int*)OtherVar;&lt;br /&gt;
  void MyMethod(const std::string&amp;amp; myParam);&lt;br /&gt;
  // okay&lt;br /&gt;
  char *myStr;&lt;br /&gt;
  float *MyMethod(const char &amp;amp;myParam);&lt;br /&gt;
  int *MyVar = (int *)OtherVar;&lt;br /&gt;
  void MyMethod(const std::string &amp;amp;myParam);&lt;br /&gt;
  // bad&lt;br /&gt;
  char * myStr;&lt;br /&gt;
  float * MyMethod(const char &amp;amp; myParam);&lt;br /&gt;
  int * MyVar = (int *)OtherVar;&lt;br /&gt;
  void MyMethod(const std::string &amp;amp; myParam);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there is no type, keep the symbol adjacent to the variable name:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // better&lt;br /&gt;
  char myChar, *myCharPointer, **myCharDoublePointer;&lt;br /&gt;
  // okay&lt;br /&gt;
  char myChar, * myCharPointer, ** myCharDoublePointer;&lt;br /&gt;
  // bad&lt;br /&gt;
  char myChar, * myCharPointer, * * myCharDoublePointer;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For items separated by commas, e.g. function parameters and enums, keep one space after each comma:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // good&lt;br /&gt;
  void MyFun(int a, int b, int c);&lt;br /&gt;
  int MyArr[3] = {1, 2, 3};&lt;br /&gt;
  // bad&lt;br /&gt;
  void MyFun(int a,int b,int c);&lt;br /&gt;
  int MyArr[3] = {1,2,3};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For operators, e.g. =, + and -, keep one space on each side. Avoid using extra spaces around parentheses:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // good&lt;br /&gt;
  void i = (1 - b);&lt;br /&gt;
  void j = ((1 / b) + 5) * c;&lt;br /&gt;
  // bad&lt;br /&gt;
  void i=( 1-b );&lt;br /&gt;
  void j=((1/b)+5)*c;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==External dependencies==&lt;br /&gt;
&lt;br /&gt;
Do not introduce new external dependencies without good motivation. The past has proven there are quite some libraries which just suck, do not build on some platform, are too buggy, make code unreadable, etc. If you really need to add a new dependency, be sure it is cross platform, and favor dependencies that are already packages in the major distributions like [http://www.debian.org/distrib/packages Debian] or [http://packages.ubuntu.com/ Ubuntu].&lt;br /&gt;
&lt;br /&gt;
When working on Linux, remember to (get someone to) compile the dependency on Windows, both for MinGW and MSVC.&lt;br /&gt;
&lt;br /&gt;
=Sources=&lt;br /&gt;
&lt;br /&gt;
(This is good material to at least skim through; the first one is a must have for every serious programmer.)&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Code_Complete Code complete 2] (commercial book)&lt;br /&gt;
* [http://www.tiobe.com/content/paperinfo/gemrcsharpcs.pdf Philips Medical Systems - Coding Standard: C#] (free online book)&lt;br /&gt;
&lt;br /&gt;
[[Category:Engine Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=RapidTools&amp;diff=15641</id>
		<title>RapidTools</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=RapidTools&amp;diff=15641"/>
		<updated>2018-11-19T00:58:34Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;RapidTools are for managing a [[rapid]] game/archive repository.&lt;br /&gt;
&lt;br /&gt;
Made by det&lt;br /&gt;
&lt;br /&gt;
=Source=&lt;br /&gt;
https://github.com/spring/pr-downloader&lt;br /&gt;
&lt;br /&gt;
=Bugs=&lt;br /&gt;
https://github.com/spring/pr-downloader/issues&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compile=&lt;br /&gt;
to compile it on ubuntu:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone https://github.com/spring/pr-downloader.git --recursive&lt;br /&gt;
sudo apt-get install liblua5.1-0-dev libzip-dev zlib1g-dev cmake libssl-dev&lt;br /&gt;
cmake .&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additional setup instructions: https://springrts.com/wiki/Admin:Rapid&lt;br /&gt;
&lt;br /&gt;
=Tool description=&lt;br /&gt;
==AddZip==&lt;br /&gt;
&lt;br /&gt;
takes a .zip and adds it to the repo with user specified tags:&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AddZip &amp;lt;Store Path&amp;gt; &amp;lt;Zip Path&amp;gt; [Tag1] ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==BuildGit==&lt;br /&gt;
&lt;br /&gt;
adds a git path to the repo and generates the tags automatically from the commit message, it also optimizes for incremental updates&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BuildGit &amp;lt;Git Path&amp;gt; &amp;lt;Mod Root&amp;gt; &amp;lt;Modinfo&amp;gt; &amp;lt;Store Path&amp;gt; &amp;lt;Git Hash&amp;gt; &amp;lt;Prefix&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Streamer==&lt;br /&gt;
&lt;br /&gt;
is a cgi program to serve some specific files of a .sdp. This is the fastest and official way to fetch a rapid archive.&lt;br /&gt;
&lt;br /&gt;
at client side you have to http POST:&lt;br /&gt;
http://packages.springrts.com/streamer.cgi?&amp;lt;hash of sdp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
post data is binary 0/1 if a file of the specified sdp is needed or not.&lt;br /&gt;
&lt;br /&gt;
streamer.cgi then returns all files in a single stream in the same order than in the sdp. it has to be in the root of a [[rapid]] file structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Usage: ./Streamer&lt;br /&gt;
Expects environment variables DOCUMENT_ROOT and QUERY_STRING&lt;br /&gt;
Expects a gziped bitarray as stdin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for details see the source-code:&lt;br /&gt;
https://github.com/spring/pr-downloader/blob/master/src/Streamer.cpp#L94&lt;br /&gt;
&lt;br /&gt;
==MakeZip==&lt;br /&gt;
&lt;br /&gt;
can create a zip from a .sdp&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MakeZip ~/.spring ba:stable ba.zip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
&lt;br /&gt;
If you get this error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Error on unknown tag lookup&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MakeZip doesn&#039;t find the tag specified in (for example) ~/.spring/versions.gz. To fix, copy the required versions.gz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cp ~/.spring/rapid/packages.springrts.com/versions.gz ~/.spring/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Download Systems]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=RapidTools&amp;diff=15640</id>
		<title>RapidTools</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=RapidTools&amp;diff=15640"/>
		<updated>2018-11-19T00:58:00Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;RapidTools are for managing a [[rapid]] game/archive repository.&lt;br /&gt;
&lt;br /&gt;
Made by det&lt;br /&gt;
&lt;br /&gt;
=Source=&lt;br /&gt;
https://github.com/spring/pr-downloader&lt;br /&gt;
&lt;br /&gt;
=Bugs=&lt;br /&gt;
https://github.com/spring/pr-downloader/issues&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Compile=&lt;br /&gt;
to compile it on ubuntu:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone https://github.com/spring/pr-downloader.git --recursive&lt;br /&gt;
sudo apt-get install liblua5.1-0-dev libzip-dev zlib1g-dev cmake libssl-dev&lt;br /&gt;
cmake .&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additional setup instructions: https://springrts.com/wiki/Admin:Rapid&lt;br /&gt;
&lt;br /&gt;
=Tool description=&lt;br /&gt;
==AddZip==&lt;br /&gt;
&lt;br /&gt;
takes a .zip and adds it to the repo with user specified tags:&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
AddZip &amp;lt;Store Path&amp;gt; &amp;lt;Zip Path&amp;gt; [Tag1] ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==BuildGit==&lt;br /&gt;
&lt;br /&gt;
adds a git path to the repo and generates the tags automatically from the commit message, it also optimizes for incremental updates&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
BuildGit &amp;lt;Git Path&amp;gt; &amp;lt;Mod Root&amp;gt; &amp;lt;Modinfo&amp;gt; &amp;lt;Store Path&amp;gt; &amp;lt;Git Hash&amp;gt; &amp;lt;Prefix&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Streamer==&lt;br /&gt;
&lt;br /&gt;
is a cgi program to serve some specific files of a .sdp. This is the fastest and official way to fetch a rapid archive.&lt;br /&gt;
&lt;br /&gt;
at client side you have to http POST:&lt;br /&gt;
http://packages.springrts.com/streamer.cgi?&amp;lt;hash of sdp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
post data is binary 0/1 if a file of the specified sdp is needed or not.&lt;br /&gt;
&lt;br /&gt;
streamer.cgi then returns all files in a single stream in the same order than in the sdp. it has to be in the root of a [[rapid]] file structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
Usage: ./Streamer&lt;br /&gt;
Expects environment variables DOCUMENT_ROOT and QUERY_STRING&lt;br /&gt;
Expects a gziped bitarray as stdin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for details see the source-code:&lt;br /&gt;
https://github.com/spring/pr-downloader/blob/master/src/Streamer.cpp#L94&lt;br /&gt;
&lt;br /&gt;
==MakeZip==&lt;br /&gt;
&lt;br /&gt;
can create a zip from a .sdp&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MakeZip ~/.spring ba:stable ba.zip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
&lt;br /&gt;
If you get this error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Error on unknown tag lookup&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MakeZip doesn&#039;t find the tag specified in (for example) ~/.spring/versions.gz. To fix, copy the required versions.gz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cp ~/.spring/rapid/packages.springrts.com/versions.gz ~/.spring/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Download Systems]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Libraries&amp;diff=11342</id>
		<title>Lua Libraries</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Libraries&amp;diff=11342"/>
		<updated>2018-11-11T04:21:23Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Lua libraries=&lt;br /&gt;
This page lists all common Lua libraries that can be used in Spring game and map archives.&lt;br /&gt;
&lt;br /&gt;
Libraries:&lt;br /&gt;
* [https://github.com/gajop/analytics analytics]: Usage analytics reporting&lt;br /&gt;
* [https://github.com/jk3064/chiliui ChiliUI]: UI framework [[Chili | docs]]&lt;br /&gt;
* [https://github.com/gajop/chilifx ChiliFX]: Chili effects&lt;br /&gt;
* [https://github.com/gajop/chotify Chotify]: Notification library in Chili&lt;br /&gt;
* [https://github.com/jk3064/Custom-Unit-Shader-Framework Custom Unit Shader Framework]: Unit rendering with shaders&lt;br /&gt;
* [https://github.com/gajop/i18n i18n]: Translations library&lt;br /&gt;
* [https://github.com/gajop/liblobby LibLobby]: Spring Lobby protocol library&lt;br /&gt;
* [https://github.com/gajop/Lua-Class-System LCS]: OOP (classes) in Lua&lt;br /&gt;
* [https://github.com/jk3064/lups LUPS]: Lua Particle System for Spring [[LUPS | docs]]&lt;br /&gt;
* [https://github.com/gajop/springmon springmon]: Spring file monitor and autoreloader&lt;br /&gt;
* [https://github.com/gajop/spring-wrapper-connector spring-wrapper-connector]: Wrapper program communication provider&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Single file libraries==&lt;br /&gt;
There is also a number of single file libraries that don&#039;t have their own repository but can technically still be considered libraries.&lt;br /&gt;
&lt;br /&gt;
Library files:&lt;br /&gt;
* [https://github.com/SpringMCLegacy/SpringMCLegacy/blob/master/LuaRules/Gadgets/api_vector.lua Vector]: Small utility for vector operations&lt;br /&gt;
* [https://github.com/Spring-SpringBoard/SpringBoard-Core/blob/master/libs_sb/json.lua JSON]: Serializing to the JSON format&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Gadgets/api_delay.lua Delay]: Delaying gadget calls&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Includes/network.lua Network]: Delta compression for binary strings&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Includes/camera.lua Camera]: Camera state serialization&lt;br /&gt;
* Deferred rendering [http://imolarpg.dyndns.org/svn/branches/BAR/shaders/deferred_lighting.glsl Shader] &amp;amp; [http://imolarpg.dyndns.org/svn/branches/BAR/luaui/widgets/gfx_deferred_rendering.lua Widget]: Deferred rendering (projectile) based lights&lt;br /&gt;
&lt;br /&gt;
===Misc===&lt;br /&gt;
* {{forumlink|topic=28341|title=ChangePiece}} - Switch piece geometry&lt;br /&gt;
&lt;br /&gt;
=== Additional resources ===&lt;br /&gt;
&lt;br /&gt;
Some additional libraries can be found using Github topics, such as [https://github.com/topics/springrts-lib springrts-lib] and [https://github.com/topics/springrts springrts]&lt;br /&gt;
&lt;br /&gt;
[[Category:Lua]] [[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Gamedev:Main&amp;diff=8290</id>
		<title>Gamedev:Main</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Gamedev:Main&amp;diff=8290"/>
		<updated>2018-11-11T04:19:25Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Lua API &amp;amp; Libraries (excerpt) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
= Game Development =&lt;br /&gt;
This information is meant to help newcomers learn how to develop their own games for the Spring Engine. If you are interested in creating maps for Spring, see [[Mapdev:Main]].&lt;br /&gt;
&lt;br /&gt;
= Templates &amp;amp; Examples =&lt;br /&gt;
* [[Gamedev:SpringABC|SpringABC]] - A hierarchical set of empty template games, without examples&lt;br /&gt;
* [[SpringTutorialGame|Spring Tutorial Game]] - A tutorial template game with full examples&lt;br /&gt;
* [[Gamedev:PublicRepos|Public Repos]] - Publicly readable Spring game code repositories&lt;br /&gt;
&lt;br /&gt;
= Technical Documentation =&lt;br /&gt;
== GameData ==&lt;br /&gt;
* [[Armordefs.lua]] - armor classes&lt;br /&gt;
* [[Icontypes.lua]] - strategic unit icons&lt;br /&gt;
* [[Modinfo.lua]] - game identifier file (name, version,...)&lt;br /&gt;
* [[Modrules.lua]] - Global game variables&lt;br /&gt;
* [[Movedefs.lua]] - MoveClasses for pathfinding&lt;br /&gt;
* [[Resources.lua]] - index file for textures&lt;br /&gt;
* [[Sidedata.lua]] - playable factions/races/sides&lt;br /&gt;
* [[Sounds.lua]] - index file for sounds&lt;br /&gt;
* [[Messages.lua]] - Team death messages {{new|95.0}}:deprecated&lt;br /&gt;
&lt;br /&gt;
== Definition Files ==&lt;br /&gt;
* [[Gamedev:UnitDefs]] - define the attributes of units&lt;br /&gt;
* [[Gamedev:WeaponDefs]] - define the attributes of weapons/projectiles&lt;br /&gt;
* [[Gamedev:FeatureDefs]] - define the attributes of static map features and wrecks&lt;br /&gt;
* [[CEG:Main]] Particle effects (explosions etc)&lt;br /&gt;
&lt;br /&gt;
== Lua API &amp;amp; Libraries (excerpt) ==&lt;br /&gt;
* [[Lua_Scripting|Lua API Documentation]]&lt;br /&gt;
* [[Lua_Libraries|Lua Libraries]]&lt;br /&gt;
&lt;br /&gt;
== Animation of units ==&lt;br /&gt;
Lua Animations (LUS)&lt;br /&gt;
*[[Animation-LuaScripting]]&lt;br /&gt;
**[[Animation-LuaCallins]]&lt;br /&gt;
**[[Animation-LuaCallouts]]&lt;br /&gt;
**[[Animation-CobLuaDifferences]]&lt;br /&gt;
&lt;br /&gt;
COB Animations (Antiquated)&lt;br /&gt;
*[[Animation-CobOverview]]&lt;br /&gt;
**[[Animation-CobAnimation]]&lt;br /&gt;
**[[Animation-CobCallins]]&lt;br /&gt;
**[[Animation-CobConstants]]&lt;br /&gt;
**[[Animation-CobThreads]]&lt;br /&gt;
**[[Animation-CobHitByWeaponID]]&lt;br /&gt;
**[[Lua-LuaCOB]] - how to interface COB with LUA&lt;br /&gt;
**[[CEG_For_Units|Game Development:Calling basic CEGs from COB]]&lt;br /&gt;
**{{forumlink|topic=7457|title=GPL COB Examples}}&lt;br /&gt;
&lt;br /&gt;
== Models &amp;amp; Textures ==&lt;br /&gt;
* [[About_s3o|.s3o]]&lt;br /&gt;
* [[Assimp]]&lt;br /&gt;
** [[3DModels:AssimpWorkflow]]&lt;br /&gt;
* [[3DModels:Textures]]&lt;br /&gt;
* [[Shaders:CustomUnitShadingFramework]]&lt;br /&gt;
** [[Shaders:PBRShaders]]&lt;br /&gt;
&lt;br /&gt;
== Misc ==&lt;br /&gt;
* [[Gamedev:DebugDrawModes]]&lt;br /&gt;
* [[Gamedev:Archives]] - packing game/map&lt;br /&gt;
* [[Gamedev:Buildpics]]&lt;br /&gt;
* [[Gamedev:CollisionVolumes]]&lt;br /&gt;
* [[Gamedev:Glossary]]&lt;br /&gt;
* [[Gamedev:MouseCursors]]&lt;br /&gt;
* [[Gamedev:Sidepics]]&lt;br /&gt;
* [[Gamedev:Structure]]&lt;br /&gt;
* [[VirtualFileSystem]]&lt;br /&gt;
&lt;br /&gt;
= Tools =&lt;br /&gt;
== In-Game Tools ==&lt;br /&gt;
*[http://springboard-core.readthedocs.io/en/latest/ SpringBoard] - Powerful map and scenario editor&lt;br /&gt;
*[[Map Making: Feature Placer|Feature Placer]] - A Map Feature &amp;amp; NPC Unit Placement Tool&lt;br /&gt;
&lt;br /&gt;
== External Tools ==&lt;br /&gt;
* [[Upspring]]&lt;br /&gt;
* [[Map,_Mod,_And_Unit_Development_Programs|Development Tools]]&lt;br /&gt;
&lt;br /&gt;
= Engine Related =&lt;br /&gt;
* [[Download_Testing]] - Test the compatibility of your game on upcoming versions of the Spring engine.&lt;br /&gt;
&lt;br /&gt;
* [[EngineChangelogForContentDevs]] - New engine versions sometimes require games to adjust. A list of common problems.&lt;br /&gt;
&lt;br /&gt;
* [[EngineSource_for_GameDevs]] - Notes about the engine source, from modding point of view.&lt;br /&gt;
&lt;br /&gt;
= Tutorials =&lt;br /&gt;
== Tips, Tricks &amp;amp; Testing ==&lt;br /&gt;
[[TestingYourGame|These tricks and commands]] are useful for testing or debugging.&lt;br /&gt;
&lt;br /&gt;
== Game Development Tutorials ==&lt;br /&gt;
*[[The Complete Guide To Making A Spring Game]] - A fairly comprehensive getting started tutorial.&lt;br /&gt;
*[http://springrts.com/phpbb/viewtopic.php?f=14&amp;amp;t=26409| Porting TA content to Spring]&lt;br /&gt;
*&amp;lt;strike&amp;gt;[[Simple Mod Tutorial|Simple Game Tutorial]]&amp;lt;/strike&amp;gt; - needs to be updated&lt;br /&gt;
&lt;br /&gt;
==Modelling Tutorials==&lt;br /&gt;
&#039;&#039;&#039;Wings3D&#039;&#039;&#039;&lt;br /&gt;
* [[3DModels:Wings3DTutorial]]&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?t=10612 Wings UV Mapping Tutorial]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Blender&#039;&#039;&#039;&lt;br /&gt;
* [[TutorialBlenderWorkFlow|Blender Workflow Tutorial]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3DS Max&#039;&#039;&#039;&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?t=10503 Runecrafter&#039;s 3DS Max UV Mapping Tutorial]&lt;br /&gt;
&lt;br /&gt;
==Texturing Tutorials==&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?f=57&amp;amp;t=22392 DDS Textures:  How To]&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?t=10947 Greeble Tutorial 1]&lt;br /&gt;
* [http://springrts.com/phpbb/viewtopic.php?f=9&amp;amp;t=12356 Greeble Tutorial 2]&lt;br /&gt;
&lt;br /&gt;
=Misc=&lt;br /&gt;
* [[Ren&#039;Py]]: a visual novel engine that can be used with Spring&lt;br /&gt;
* &amp;lt;strike&amp;gt;[http://answers.springlobby.info/ Q&amp;amp;A Site for the Spring Engine]&amp;lt;/strike&amp;gt; Currently down.&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Dev]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_WeaponDefs&amp;diff=12497</id>
		<title>Lua WeaponDefs</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_WeaponDefs&amp;diff=12497"/>
		<updated>2018-11-10T17:51:33Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;WeaponDefs[]&#039;&#039;&#039; table holds all information about the weapons used in a game.&lt;br /&gt;
&lt;br /&gt;
Works the same way as [[Lua_UnitDefs]] except the tables are called &#039;&#039;&#039;WeaponDefs[]&#039;&#039;&#039; and &#039;&#039;&#039;WeaponDefNames[]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note: Its entries are metatables, so you can&#039;t use the pairs() iterator on them, use this instead:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for id,weaponDef in pairs(WeaponDefs) do&lt;br /&gt;
    for name,param in weaponDef:pairs() do&lt;br /&gt;
      Spring.Echo(name,param)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Naming==&lt;br /&gt;
If a unit named &amp;quot;tank&amp;quot; has a weapon named &amp;quot;gun&amp;quot;, the resulting &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; will be &amp;quot;tank_gun&amp;quot; and you can get this weaponDefID like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;local gunID = WeaponDefNames[&amp;quot;tank_gun&amp;quot;].id&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
For a more detailed overview of tag definitions look at &lt;br /&gt;
[[Gamedev:WeaponDefs]] or look directly at the source at &lt;br /&gt;
https://github.com/spring/spring/blob/5f08624585852b8c8dfd1a16d020ae530269dc09/rts/Sim/Weapons/WeaponLoader.cpp&lt;br /&gt;
&lt;br /&gt;
In key = value format, where WeaponDefs[weaponDefID].key==value, with subtables at the end.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    accuracy = 0,&lt;br /&gt;
    avoidFeature = false,&lt;br /&gt;
    avoidFriendly = true,&lt;br /&gt;
    avoidNeutral = false,&lt;br /&gt;
    beamTTL = 0,&lt;br /&gt;
    beamburst = false,&lt;br /&gt;
    beamtime = 0.10000000149012,&lt;br /&gt;
    bouncerebound = 1,&lt;br /&gt;
    canAttackGround = true,&lt;br /&gt;
    cegTag = &amp;quot;&amp;quot;,&lt;br /&gt;
    collisionSize = 0.050000000745058,&lt;br /&gt;
    coverageRange = 0,&lt;br /&gt;
    craterAreaOfEffect = 0,&lt;br /&gt;
    cylinderTargeting = 1,&lt;br /&gt;
    cylinderTargetting = 1,&lt;br /&gt;
    damageAreaOfEffect = 6,&lt;br /&gt;
    dance = 0,&lt;br /&gt;
    description = &amp;quot;J7Laser&amp;quot;,&lt;br /&gt;
    duration = 0.050000000745058,&lt;br /&gt;
    dynDamageExp = 0,&lt;br /&gt;
    dynDamageInverted = false,&lt;br /&gt;
    dynDamageMin = 0,&lt;br /&gt;
    dynDamageRange = 0,&lt;br /&gt;
    edgeEffectiveness = 0.99000000953674,&lt;br /&gt;
    energyCost = 0,&lt;br /&gt;
    explosionSpeed = 3.233583688736,&lt;br /&gt;
    exteriorShield = false,&lt;br /&gt;
    fireStarter = 0.69999998807907,&lt;br /&gt;
    flightTime = 0,&lt;br /&gt;
    gravityAffected = false,&lt;br /&gt;
    groundbounce = false,&lt;br /&gt;
    groundslip = 1,&lt;br /&gt;
    heightBoostFactor = -1,&lt;br /&gt;
    heightMod = 1,&lt;br /&gt;
    highTrajectory = 2,&lt;br /&gt;
    id = 220,&lt;br /&gt;
    impactOnly = true,&lt;br /&gt;
    intensity = 0.89999997615814,&lt;br /&gt;
    interceptSolo = true,&lt;br /&gt;
    interceptedByShieldType = 2,&lt;br /&gt;
    interceptor = 0,&lt;br /&gt;
    isShield = false,&lt;br /&gt;
    largeBeamLaser = false,&lt;br /&gt;
    laserHardStop = false,&lt;br /&gt;
    leadBonus = 0,&lt;br /&gt;
    leadLimit = -1,&lt;br /&gt;
    manualFire = false,&lt;br /&gt;
    maxAngle = 0.95873802900314,&lt;br /&gt;
    metalCost = 0,&lt;br /&gt;
    minIntensity = 0,&lt;br /&gt;
    movingAccuracy = 0,&lt;br /&gt;
    myGravity = 0,&lt;br /&gt;
    name = &amp;quot;corcom_armcomlaser&amp;quot;,&lt;br /&gt;
    noAutoTarget = false,&lt;br /&gt;
    noEnemyCollide = false,&lt;br /&gt;
    noExplode = false,&lt;br /&gt;
    noFeatureCollide = false,&lt;br /&gt;
    noFriendlyCollide = false,&lt;br /&gt;
    noGroundCollide = false,&lt;br /&gt;
    noNeutralCollide = false,&lt;br /&gt;
    noSelfDamage = true,&lt;br /&gt;
    numbounce = -1,&lt;br /&gt;
    onlyForward = false,&lt;br /&gt;
    paralyzer = false,&lt;br /&gt;
    predictBoost = 0,&lt;br /&gt;
    projectiles = 1,&lt;br /&gt;
    projectilespeed = 30.000001907349,&lt;br /&gt;
    proximityPriority = 1,&lt;br /&gt;
    range = 300,&lt;br /&gt;
    reload = 0.40000000596046,&lt;br /&gt;
    salvoDelay = 0.10000000149012,&lt;br /&gt;
    salvoSize = 1,&lt;br /&gt;
    selfExplode = false,&lt;br /&gt;
    shieldAlpha = 0.20000000298023,&lt;br /&gt;
    shieldBadColorB = 0.5,&lt;br /&gt;
    shieldBadColorG = 0.5,&lt;br /&gt;
    shieldBadColorR = 1,&lt;br /&gt;
    shieldEnergyUse = 0,&lt;br /&gt;
    shieldForce = 0,&lt;br /&gt;
    shieldGoodColorB = 1,&lt;br /&gt;
    shieldGoodColorG = 0.5,&lt;br /&gt;
    shieldGoodColorR = 0.5,&lt;br /&gt;
    shieldInterceptType = 0,&lt;br /&gt;
    shieldMaxSpeed = 0,&lt;br /&gt;
    shieldPower = 0,&lt;br /&gt;
    shieldPowerRegen = 0,&lt;br /&gt;
    shieldPowerRegenEnergy = 0,&lt;br /&gt;
    shieldRadius = 0,&lt;br /&gt;
    shieldRechargeDelay = 0,&lt;br /&gt;
    shieldRepulser = false,&lt;br /&gt;
    size = 2.1875,&lt;br /&gt;
    sizeGrowth = 0.5,&lt;br /&gt;
    smartShield = false,&lt;br /&gt;
    soundTrigger = true,&lt;br /&gt;
    sprayAngle = 0,&lt;br /&gt;
    startvelocity = 0.0099999997764826,&lt;br /&gt;
    stockpile = false,&lt;br /&gt;
    stockpileTime = 30,&lt;br /&gt;
    sweepFire = false,&lt;br /&gt;
    targetBorder = 0,&lt;br /&gt;
    targetMoveError = 0.050000000745058,&lt;br /&gt;
    targetable = 0,&lt;br /&gt;
    tdfId = 0,&lt;br /&gt;
    tracks = false,&lt;br /&gt;
    trajectoryHeight = 0,&lt;br /&gt;
    turnRate = 0,&lt;br /&gt;
    turret = true,&lt;br /&gt;
    type = &amp;quot;BeamLaser&amp;quot;,&lt;br /&gt;
    uptime = 0,&lt;br /&gt;
    visibleShield = false,&lt;br /&gt;
    visibleShieldHitFrames = 0,&lt;br /&gt;
    visibleShieldRepulse = false,&lt;br /&gt;
    waterWeapon = false,&lt;br /&gt;
    waterbounce = false,&lt;br /&gt;
    weaponAcceleration = 0,&lt;br /&gt;
    wobble = 0,&lt;br /&gt;
    customParams = {},&lt;br /&gt;
    damages = {&lt;br /&gt;
        craterBoost = 0,&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
    fireSound = {&lt;br /&gt;
        [1] = {&lt;br /&gt;
            id = 36,&lt;br /&gt;
            name = &amp;quot;lasrfir1&amp;quot;,&lt;br /&gt;
            volume = 6.1237244606018,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
    hitSound = {&lt;br /&gt;
        [1] = {&lt;br /&gt;
            id = -1,&lt;br /&gt;
            name = &amp;quot;&amp;quot;,&lt;br /&gt;
            volume = 6.1237244606018,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
    visuals = {&lt;br /&gt;
        alphaDecay = 1,&lt;br /&gt;
        alwaysVisible = false,&lt;br /&gt;
        beamDecay = 1,&lt;br /&gt;
        beamWeapon = false,&lt;br /&gt;
        color2B = 1,&lt;br /&gt;
        color2G = 1,&lt;br /&gt;
        color2R = 1,&lt;br /&gt;
        colorB = 0,&lt;br /&gt;
        colorG = 0,&lt;br /&gt;
        colorR = 1,&lt;br /&gt;
        coreThickness = 0.10000000149012,&lt;br /&gt;
        laserFlareSize = 7,&lt;br /&gt;
        modelName = &amp;quot;&amp;quot;,&lt;br /&gt;
        noGap = true,&lt;br /&gt;
        pulseSpeed = 1,&lt;br /&gt;
        scrollSpeed = 5,&lt;br /&gt;
        separation = 1,&lt;br /&gt;
        sizeDecay = 0,&lt;br /&gt;
        smokeTrail = false,&lt;br /&gt;
        stages = 5,&lt;br /&gt;
        thickness = 2,&lt;br /&gt;
        tileLength = 200,&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_UnitDefs&amp;diff=12150</id>
		<title>Lua UnitDefs</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_UnitDefs&amp;diff=12150"/>
		<updated>2018-11-10T17:50:54Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
==What is this==&lt;br /&gt;
The &#039;&#039;&#039;UnitDefs[]&#039;&#039;&#039; table holds information about the unit&#039;&#039;&#039;types&#039;&#039;&#039; used in the game. It is indexed by a number, and normally refered to as unitDefID. It is read-only. To access its tags you write, for example,&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    UnitDefs[unitDefID].name&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The name of the keys often vary from the ones in the [[Gamedev:UnitDefs]] files.&lt;br /&gt;
For example &#039;&#039;maxDamage&#039;&#039; is named &#039;&#039;health&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==UnitDefs reverse lookup: UnitDefNames==&lt;br /&gt;
The &#039;&#039;&#039;UnitDefNames[]&#039;&#039;&#039; table holds the unitdefs and can be used to get the unitdef table for a known unitname:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    local unitDef = UnitDefNames[&amp;quot;supertank&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Print all unitDefs==&lt;br /&gt;
This example code prints all unitdefs, with all keys and their values (but not their subtables).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for id,unitDef in pairs(UnitDefs) do&lt;br /&gt;
    for name,param in unitDef:pairs() do&lt;br /&gt;
      Spring.Echo(name,param)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that unitDef is a metatable, and requires the special iterator unitDef:pairs()&lt;br /&gt;
&lt;br /&gt;
==Useful keys/snippets==&lt;br /&gt;
&amp;lt;code&amp;gt; UnitDefs[unitDefID].id &amp;lt;/code&amp;gt; - gives back the unitDefID &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; UnitDefs[unitDefID].name &amp;lt;/code&amp;gt; - the internal unit name&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; UnitDefs[unitDefID].humanName &amp;lt;/code&amp;gt; - the displayed unit name&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;UnitDefs[unitDefID].weapons&amp;lt;/code&amp;gt; - See [[Lua_WeaponDefs]], &amp;lt;code&amp;gt;UnitDefs[unitDefID].weapons[1].weaponDef&amp;lt;/code&amp;gt; returns the weaponDefID of the units first weapon, which apppears in the WeaponsDef table as &amp;lt;code&amp;gt;WeaponDefs[weaponDefID]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To read [[Gamedev:UnitDefs#customParams|custom parameters]] use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    local myCustomParameters = UnitDefs[unitDefID].customParams&lt;br /&gt;
    if (myCustomParameters) then&lt;br /&gt;
      blub = myCustomParameters.blubfactor&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Key-names of the customParams table written must be lowercase and their values can only be strings.&lt;br /&gt;
&lt;br /&gt;
===Types of Units===&lt;br /&gt;
Sometimes one wants to check type of unit. Like is it a factory, is it a transport and so on.&lt;br /&gt;
Complete list: &amp;lt;ref&amp;gt;&#039;&#039;Spring 95, commit message&#039;&#039;,{{Sourcelinkhash|4e58b8b0f7af04065878d34e5e17523246739b0c}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*isTransport&lt;br /&gt;
*isImmobile&lt;br /&gt;
*isBuilding&lt;br /&gt;
*isBuilder&lt;br /&gt;
*isMobileBuilder&lt;br /&gt;
*isStaticBuilder&lt;br /&gt;
*isFactory&lt;br /&gt;
*isExtractor&lt;br /&gt;
*isGroundUnit&lt;br /&gt;
*isAirUnit&lt;br /&gt;
*isStrafingAirUnit&lt;br /&gt;
*isHoveringAirUnit&lt;br /&gt;
*isFighterAirUnit&lt;br /&gt;
*isBomberAirUnit&lt;br /&gt;
&lt;br /&gt;
==Example UnitDef table==&lt;br /&gt;
In the form of key = value, where UnitDefs[unitDefID].key = value, with subtables at the bottom.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    activateWhenBuilt = true,&lt;br /&gt;
    airLosRadius = 5.2734375,&lt;br /&gt;
    airStrafe = true,&lt;br /&gt;
    armorType = 3,&lt;br /&gt;
    armoredMultiple = 1,&lt;br /&gt;
    autoHeal = 2.5,&lt;br /&gt;
    bankingAllowed = true,&lt;br /&gt;
    buildDistance = 112,&lt;br /&gt;
    buildRange3D = false,&lt;br /&gt;
    buildSpeed = 300,&lt;br /&gt;
    buildTime = 75000,&lt;br /&gt;
    builder = false,&lt;br /&gt;
    buildingDecalDecaySpeed = 0.10000000149012,&lt;br /&gt;
    buildingDecalSizeX = 4,&lt;br /&gt;
    buildingDecalSizeY = 4,&lt;br /&gt;
    buildingDecalType = -1,&lt;br /&gt;
    buildpicname = &amp;quot;CORCOM.DDS&amp;quot;,&lt;br /&gt;
    canAssist = true,&lt;br /&gt;
    canAttack = true,&lt;br /&gt;
    canAttackWater = true,&lt;br /&gt;
    canBeAssisted = true,&lt;br /&gt;
    canCapture = true,&lt;br /&gt;
    canCloak = true,&lt;br /&gt;
    canCrash = false,&lt;br /&gt;
    canDGun = false,&lt;br /&gt;
    canDropFlare = false,&lt;br /&gt;
    canFight = true,&lt;br /&gt;
    canFireControl = true,&lt;br /&gt;
    canFly = false,&lt;br /&gt;
    canGuard = true,&lt;br /&gt;
    canKamikaze = false,&lt;br /&gt;
    canLoopbackAttack = false,&lt;br /&gt;
    canManualFire = true,&lt;br /&gt;
    canMove = true,&lt;br /&gt;
    canParalyze = false,&lt;br /&gt;
    canPatrol = true,&lt;br /&gt;
    canReclaim = true,&lt;br /&gt;
    canRepair = true,&lt;br /&gt;
    canRepeat = true,&lt;br /&gt;
    canRestore = true,&lt;br /&gt;
    canResurrect = false,&lt;br /&gt;
    canSelfD = true,&lt;br /&gt;
    canSelfRepair = false,&lt;br /&gt;
    canStockpile = false,&lt;br /&gt;
    canSubmerge = false,&lt;br /&gt;
    cantBeTransported = false,&lt;br /&gt;
    capturable = true,&lt;br /&gt;
    captureSpeed = 900,&lt;br /&gt;
    cloakCost = 100,&lt;br /&gt;
    cloakCostMoving = 1000,&lt;br /&gt;
    cloakTimeout = 128,&lt;br /&gt;
    cobID = -1,&lt;br /&gt;
    collide = true,&lt;br /&gt;
    cost = 3111.4499511719,&lt;br /&gt;
    crashDrag = 0.0049999998882413,&lt;br /&gt;
    deathExplosion = &amp;quot;commander_blast&amp;quot;,&lt;br /&gt;
    decloakDistance = 50,&lt;br /&gt;
    decloakOnFire = true,&lt;br /&gt;
    decloakSpherical = true,&lt;br /&gt;
    dlHoverFactor = -1,&lt;br /&gt;
    energyCost = 26667,&lt;br /&gt;
    energyMake = 25,&lt;br /&gt;
    energyStorage = 0,&lt;br /&gt;
    energyUpkeep = 0,&lt;br /&gt;
    extractRange = 0,&lt;br /&gt;
    extractsMetal = 0,&lt;br /&gt;
    factoryHeadingTakeoff = true,&lt;br /&gt;
    fallSpeed = 0.20000000298023,&lt;br /&gt;
    fireState = -1,&lt;br /&gt;
    flankingBonusDirX = 0,&lt;br /&gt;
    flankingBonusDirY = 0,&lt;br /&gt;
    flankingBonusDirZ = 1,&lt;br /&gt;
    flankingBonusMax = 1.8999999761581,&lt;br /&gt;
    flankingBonusMin = 0.89999997615814,&lt;br /&gt;
    flankingBonusMobilityAdd = 0.0099999997764826,&lt;br /&gt;
    flankingBonusMode = 1,&lt;br /&gt;
    flareDelay = 0.30000001192093,&lt;br /&gt;
    flareDropVectorX = 0,&lt;br /&gt;
    flareDropVectorY = 0,&lt;br /&gt;
    flareDropVectorZ = 0,&lt;br /&gt;
    flareEfficiency = 0.5,&lt;br /&gt;
    flareReloadTime = 5,&lt;br /&gt;
    flareSalvoDelay = 0,&lt;br /&gt;
    flareSalvoSize = 4,&lt;br /&gt;
    flareTime = 90,&lt;br /&gt;
    floatOnWater = false,&lt;br /&gt;
    floater = false,&lt;br /&gt;
    frontToSpeed = 0.10000000149012,&lt;br /&gt;
    fullHealthFactory = false,&lt;br /&gt;
    hasShield = false,&lt;br /&gt;
    health = 3000,&lt;br /&gt;
    height = 50,&lt;br /&gt;
    hideDamage = true,&lt;br /&gt;
    highTrajectoryType = 0,&lt;br /&gt;
    holdSteady = false,&lt;br /&gt;
    hoverAttack = false,&lt;br /&gt;
    humanName = &amp;quot;Commander&amp;quot;,&lt;br /&gt;
    iconType = &amp;quot;corcom.user&amp;quot;,&lt;br /&gt;
    id = 261,&lt;br /&gt;
    idleAutoHeal = 2.5,&lt;br /&gt;
    idleTime = 1800,&lt;br /&gt;
    isAirBase = false,&lt;br /&gt;
    isAirUnit = false,&lt;br /&gt;
    isBomberAirUnit = false,&lt;br /&gt;
    isBuilder = true,&lt;br /&gt;
    isBuilding = false,&lt;br /&gt;
    isCommander = false,&lt;br /&gt;
    isExtractor = false,&lt;br /&gt;
    isFactory = false,&lt;br /&gt;
    isFeature = false,&lt;br /&gt;
    isFighterAirUnit = false,&lt;br /&gt;
    isFirePlatform = false,&lt;br /&gt;
    isGroundUnit = true,&lt;br /&gt;
    isHoveringAirUnit = false,&lt;br /&gt;
    isImmobile = false,&lt;br /&gt;
    isMobileBuilder = true,&lt;br /&gt;
    isStaticBuilder = false,&lt;br /&gt;
    isStrafingAirUnit = false,&lt;br /&gt;
    isTransport = false,&lt;br /&gt;
    jammerRadius = 0,&lt;br /&gt;
    kamikazeDist = 0,&lt;br /&gt;
    kamikazeUseLOS = false,&lt;br /&gt;
    leaveTracks = false,&lt;br /&gt;
    levelGround = true,&lt;br /&gt;
    loadingRadius = 220,&lt;br /&gt;
    losHeight = 40,&lt;br /&gt;
    losRadius = 14.0625,&lt;br /&gt;
    makesMetal = 0,&lt;br /&gt;
    mass = 5000,&lt;br /&gt;
    maxAcc = 0.18000000715256,&lt;br /&gt;
    maxAileron = 0.014999999664724,&lt;br /&gt;
    maxBank = 0.80000001192093,&lt;br /&gt;
    maxCoverage = 0,&lt;br /&gt;
    maxDec = 1.125,&lt;br /&gt;
    maxElevator = 0.0099999997764826,&lt;br /&gt;
    maxFuel = 0,&lt;br /&gt;
    maxHeightDif = 14.558809280396,&lt;br /&gt;
    maxPitch = 0.44999998807907,&lt;br /&gt;
    maxRepairSpeed = 300,&lt;br /&gt;
    maxRudder = 0.0040000001899898,&lt;br /&gt;
    maxSlope = -1,&lt;br /&gt;
    maxThisUnit = 32000,&lt;br /&gt;
    maxWaterDepth = 35,&lt;br /&gt;
    maxWeaponRange = 300,&lt;br /&gt;
    maxx = 17.423709869385,&lt;br /&gt;
    maxy = 48.386325836182,&lt;br /&gt;
    maxz = 14.10532283783,&lt;br /&gt;
    metalCost = 2667,&lt;br /&gt;
    metalMake = 1.5,&lt;br /&gt;
    metalStorage = 0,&lt;br /&gt;
    metalUpkeep = 0,&lt;br /&gt;
    midx = 0.66120779514313,&lt;br /&gt;
    midy = 19,&lt;br /&gt;
    midz = 1.7122877836227,&lt;br /&gt;
    minAirBasePower = 0,&lt;br /&gt;
    minCollisionSpeed = 1,&lt;br /&gt;
    minWaterDepth = -10000000,&lt;br /&gt;
    minx = -16.537784576416,&lt;br /&gt;
    miny = 0.058725833892822,&lt;br /&gt;
    minz = -9.709508895874,&lt;br /&gt;
    moveState = -1,&lt;br /&gt;
    myGravity = 0.40000000596046,&lt;br /&gt;
    name = &amp;quot;corcom&amp;quot;,&lt;br /&gt;
    nanoColorB = 0.20000000298023,&lt;br /&gt;
    nanoColorG = 0.69999998807907,&lt;br /&gt;
    nanoColorR = 0.20000000298023,&lt;br /&gt;
    needGeo = false,&lt;br /&gt;
    onOffable = false,&lt;br /&gt;
    power = 3111.4499511719,&lt;br /&gt;
    primaryWeapon = 2,&lt;br /&gt;
    rSpeed = 0,&lt;br /&gt;
    radarRadius = 700,&lt;br /&gt;
    radius = 22,&lt;br /&gt;
    reclaimSpeed = 300,&lt;br /&gt;
    reclaimable = false,&lt;br /&gt;
    refuelTime = 5,&lt;br /&gt;
    releaseHeld = false,&lt;br /&gt;
    reloadTime = 1,&lt;br /&gt;
    repairSpeed = 300,&lt;br /&gt;
    repairable = true,&lt;br /&gt;
    resurrectSpeed = 300,&lt;br /&gt;
    scriptName = &amp;quot;corcom.cob&amp;quot;,&lt;br /&gt;
    scriptPath = &amp;quot;corcom.cob&amp;quot;,&lt;br /&gt;
    seismicRadius = 0,&lt;br /&gt;
    seismicSignature = 0,&lt;br /&gt;
    selfDCountdown = 5,&lt;br /&gt;
    selfDExplosion = &amp;quot;commander_blast&amp;quot;,&lt;br /&gt;
    shieldPower = -1,&lt;br /&gt;
    showNanoFrame = true,&lt;br /&gt;
    showNanoSpray = true,&lt;br /&gt;
    showPlayerName = true,&lt;br /&gt;
    slideTolerance = 0,&lt;br /&gt;
    sonarJamRadius = 0,&lt;br /&gt;
    sonarRadius = 300,&lt;br /&gt;
    sonarStealth = false,&lt;br /&gt;
    speed = 37.5,&lt;br /&gt;
    speedToFront = 0.070000000298023,&lt;br /&gt;
    startCloaked = false,&lt;br /&gt;
    stealth = false,&lt;br /&gt;
    strafeToAttack = false,&lt;br /&gt;
    targfac = false,&lt;br /&gt;
    techLevel = 0,&lt;br /&gt;
    terraformSpeed = 1500,&lt;br /&gt;
    tidalGenerator = 0,&lt;br /&gt;
    tooltip = &amp;quot;Commander&amp;quot;,&lt;br /&gt;
    totalEnergyOut = 25,&lt;br /&gt;
    trackOffset = 0,&lt;br /&gt;
    trackStrength = 0,&lt;br /&gt;
    trackStretch = 1,&lt;br /&gt;
    trackType = -1,&lt;br /&gt;
    trackWidth = 32,&lt;br /&gt;
    transportByEnemy = false,&lt;br /&gt;
    transportCapacity = 0,&lt;br /&gt;
    transportMass = 100000,&lt;br /&gt;
    transportSize = 0,&lt;br /&gt;
    transportUnloadMethod = 0,&lt;br /&gt;
    turnInPlace = true,&lt;br /&gt;
    turnInPlaceSpeedLimit = 0.82499998807907,&lt;br /&gt;
    turnRadius = 500,&lt;br /&gt;
    turnRate = 1133,&lt;br /&gt;
    type = &amp;quot;&amp;quot;,&lt;br /&gt;
    unitFallSpeed = 0,&lt;br /&gt;
    upright = true,&lt;br /&gt;
    useBuildingGroundDecal = false,&lt;br /&gt;
    useSmoothMesh = true,&lt;br /&gt;
    verticalSpeed = 3,&lt;br /&gt;
    wantedHeight = 0,&lt;br /&gt;
    waterline = 0,&lt;br /&gt;
    windGenerator = 0,&lt;br /&gt;
    wingAngle = 0.079999998211861,&lt;br /&gt;
    wingDrag = 0.070000000298023,&lt;br /&gt;
    wreckName = &amp;quot;corcom_dead&amp;quot;,&lt;br /&gt;
    xsize = 4,&lt;br /&gt;
    zsize = 4,&lt;br /&gt;
&lt;br /&gt;
    buildOptions = {&lt;br /&gt;
        [1] = unitDefID1,&lt;br /&gt;
        [2] = unitDefID2,&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
    collisionVolume = {&lt;br /&gt;
        boundingRadius = 1.0893974967364e-026,&lt;br /&gt;
        defaultToFootPrint = false,&lt;br /&gt;
        defaultToPieceTree = false,&lt;br /&gt;
        defaultToSphere = false,&lt;br /&gt;
        offsetX = 0,&lt;br /&gt;
        offsetY = 1,&lt;br /&gt;
        offsetZ = 1.089395031546e-026,&lt;br /&gt;
        scaleX = 6.4911419586111e-027,&lt;br /&gt;
        scaleY = 1.9340968033141e-038,&lt;br /&gt;
        scaleZ = 1.0894122878784e-026,&lt;br /&gt;
        type = &amp;quot;ellipsoid&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    customParams = {&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
    modCategories = {&lt;br /&gt;
        all = true,&lt;br /&gt;
        commander = true,&lt;br /&gt;
        notair = true,&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
    model = {&lt;br /&gt;
        name = &amp;quot;CORCOM.s3o&amp;quot;,&lt;br /&gt;
        path = &amp;quot;objects3d/CORCOM.s3o&amp;quot;,&lt;br /&gt;
        type = &amp;quot;s3o&amp;quot;,&lt;br /&gt;
        textures = {&lt;br /&gt;
            tex1 = &amp;quot;Core_color.dds&amp;quot;,&lt;br /&gt;
            tex2 = &amp;quot;Core_other.dds&amp;quot;,&lt;br /&gt;
        },&lt;br /&gt;
    },&lt;br /&gt;
    moveDef = {&lt;br /&gt;
        crushStrength = 50,&lt;br /&gt;
        depth = 5000,&lt;br /&gt;
        depthMod = 0,&lt;br /&gt;
        family = &amp;quot;kbot&amp;quot;,&lt;br /&gt;
        heatMapping = false,&lt;br /&gt;
        heatMod = 0.0041666668839753,&lt;br /&gt;
        heatProduced = 60,&lt;br /&gt;
        id = 6,&lt;br /&gt;
        maxSlope = 0.41221469640732,&lt;br /&gt;
        name = &amp;quot;akbot2&amp;quot;,&lt;br /&gt;
        slopeMod = 9.6801977157593,&lt;br /&gt;
        type = &amp;quot;ground&amp;quot;,&lt;br /&gt;
        xsize = 3,&lt;br /&gt;
        zsize = 3,&lt;br /&gt;
    },&lt;br /&gt;
    noChaseCategories = {&lt;br /&gt;
        all = true,&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
    sounds = {&lt;br /&gt;
        activate = {},&lt;br /&gt;
        arrived = {},&lt;br /&gt;
        build = {&lt;br /&gt;
            [1] = {&lt;br /&gt;
                id = 208,&lt;br /&gt;
                name = &amp;quot;nanlath2&amp;quot;,&lt;br /&gt;
                volume = 1,&lt;br /&gt;
            },&lt;br /&gt;
            ...&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
    weapons = {&lt;br /&gt;
        [1] = {&lt;br /&gt;
            fuelUsage = 0,&lt;br /&gt;
            mainDirX = 0,&lt;br /&gt;
            mainDirY = 0,&lt;br /&gt;
            mainDirZ = 0.99999564886093,&lt;br /&gt;
            maxAngleDif = -1,&lt;br /&gt;
            slavedTo = 0,&lt;br /&gt;
            weaponDef = 221,&lt;br /&gt;
            badTargets = {&lt;br /&gt;
                vtol = true,&lt;br /&gt;
            },&lt;br /&gt;
            onlyTargets = {&lt;br /&gt;
                all = true,&lt;br /&gt;
                antiemg = true,&lt;br /&gt;
                ...&lt;br /&gt;
            },&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unit/Weapon damages and armor classes==&lt;br /&gt;
&lt;br /&gt;
For details on how to extract which units/weapons target/damage which units, see https://springrts.com/phpbb/viewtopic.php?f=44&amp;amp;t=34382&amp;amp;p=575738#p575738 (TODO: migrate info to wiki).&lt;br /&gt;
&lt;br /&gt;
==How to save unitDef tables to file==&lt;br /&gt;
To save all unitDefs to a file, including all tables, you can use&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    local unitDef = UnitDefs[unitDefID]&lt;br /&gt;
    local t = {}&lt;br /&gt;
    for k,v in unitDef:pairs() do&lt;br /&gt;
        t[k] = v&lt;br /&gt;
    end&lt;br /&gt;
    table.save(t, &amp;quot;lua_unitDef_&amp;quot; .. unitDef.name .. &amp;quot;.lua&amp;quot;, &amp;quot;-- generated by table.save&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The special iterator is needed because metatables. See https://springrts.com/phpbb/viewtopic.php?f=67&amp;amp;t=33778 for a widget to regenerate the example defs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_FeatureDefs&amp;diff=11283</id>
		<title>Lua FeatureDefs</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_FeatureDefs&amp;diff=11283"/>
		<updated>2018-11-10T17:49:14Z</updated>

		<summary type="html">&lt;p&gt;Gajop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[Lua_Scripting|Lua Scripting]] &amp;lt; {{FULLPAGENAME}}&lt;br /&gt;
&lt;br /&gt;
The FeatureDefs[] table holds all information about the features used in a game.&lt;br /&gt;
&lt;br /&gt;
Works the same way as [[Lua_UnitDefs]] except the tables are called &#039;&#039;&#039;FeatureDefs[]&#039;&#039;&#039; and &#039;&#039;&#039;FeatureDefNames[]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Looping==&lt;br /&gt;
Note: Its entries are metatables, so you can&#039;t use the pairs() iterator on them, use this instead:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for id,featureDef in pairs(FeatureDefs) do&lt;br /&gt;
    for name,param in featureDef:pairs() do&lt;br /&gt;
      Spring.Echo(name,param)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
In key = value form, where FeatureDefs[featureDefID].key==value, with subtables at the end.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    autoreclaim = true,&lt;br /&gt;
    blocking = true,&lt;br /&gt;
    burnable = false,&lt;br /&gt;
    deathFeatureID = 2,&lt;br /&gt;
    destructable = true,&lt;br /&gt;
    drawType = 0,&lt;br /&gt;
    drawTypeString = &amp;quot;model&amp;quot;,&lt;br /&gt;
    energy = 0,&lt;br /&gt;
    floating = false,&lt;br /&gt;
    geoThermal = false,&lt;br /&gt;
    height = 0,&lt;br /&gt;
    id = 1,&lt;br /&gt;
    mass = 4205.400390625,&lt;br /&gt;
    maxHealth = 16290,&lt;br /&gt;
    maxx = -10000,&lt;br /&gt;
    maxy = -10000,&lt;br /&gt;
    maxz = -10000,&lt;br /&gt;
    metal = 6441,&lt;br /&gt;
    midx = 0,&lt;br /&gt;
    midy = 0,&lt;br /&gt;
    midz = 0,&lt;br /&gt;
    minx = 10000,&lt;br /&gt;
    miny = 10000,&lt;br /&gt;
    minz = 10000,&lt;br /&gt;
    modelname = &amp;quot;objects3d/AAFUS_DEAD.s3o&amp;quot;,&lt;br /&gt;
    name = &amp;quot;aafus_dead&amp;quot;,&lt;br /&gt;
    noSelect = true,&lt;br /&gt;
    radius = 0,&lt;br /&gt;
    reclaimTime = 38646,&lt;br /&gt;
    reclaimable = true,&lt;br /&gt;
    resurrectable = -1,&lt;br /&gt;
    smokeTime = 300,&lt;br /&gt;
    tooltip = &amp;quot;Advanced Fusion Reactor Wreckage&amp;quot;,&lt;br /&gt;
    upright = false,&lt;br /&gt;
    xsize = 10,&lt;br /&gt;
    zsize = 8,&lt;br /&gt;
    collisionVolume = {&lt;br /&gt;
        boundingRadius = 5.8736290375751e-026,&lt;br /&gt;
        defaultToFootPrint = false,&lt;br /&gt;
        defaultToPieceTree = false,&lt;br /&gt;
        defaultToSphere = false,&lt;br /&gt;
        offsetX = 0,&lt;br /&gt;
        offsetY = 1,&lt;br /&gt;
        offsetZ = 6.3954851782821e-026,&lt;br /&gt;
        scaleX = 6.1349811206651e-026,&lt;br /&gt;
        scaleY = 1.9340968033141e-038,&lt;br /&gt;
        scaleZ = 6.3955048998047e-026,&lt;br /&gt;
        type = &amp;quot;ellipsoid&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    customParams = {&lt;br /&gt;
        ...&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Libraries&amp;diff=11341</id>
		<title>Lua Libraries</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Libraries&amp;diff=11341"/>
		<updated>2018-10-14T12:57:14Z</updated>

		<summary type="html">&lt;p&gt;Gajop: /* Lua libraries */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Lua libraries=&lt;br /&gt;
This page lists all common Lua libraries that can be used in Spring game and map archives.&lt;br /&gt;
&lt;br /&gt;
Libraries:&lt;br /&gt;
* [https://github.com/gajop/analytics analytics]: Usage analytics reporting&lt;br /&gt;
* [https://github.com/jk3064/chiliui ChiliUI]: UI framework [[Chili | docs]]&lt;br /&gt;
* [https://github.com/gajop/chilifx ChiliFX]: Chili effects&lt;br /&gt;
* [https://github.com/gajop/chotify Chotify]: Notification library in Chili&lt;br /&gt;
* [https://github.com/jk3064/Custom-Unit-Shader-Framework Custom Unit Shader Framework]: Unit rendering with shaders&lt;br /&gt;
* [https://github.com/gajop/i18n i18n]: Translations library&lt;br /&gt;
* [https://github.com/gajop/liblobby LibLobby]: Spring Lobby protocol library&lt;br /&gt;
* [https://github.com/gajop/Lua-Class-System LCS]: OOP (classes) in Lua&lt;br /&gt;
* [https://github.com/jk3064/lups LUPS]: Lua Particle System for Spring [[LUPS | docs]]&lt;br /&gt;
* [https://github.com/gajop/springmon springmon]: Spring file monitor and autoreloader&lt;br /&gt;
* [https://github.com/gajop/spring-wrapper-connector spring-wrapper-connector]: Wrapper program communication provider&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Single file libraries==&lt;br /&gt;
There is also a number of single file libraries that don&#039;t have their own repository but can technically still be considered libraries.&lt;br /&gt;
&lt;br /&gt;
Library files:&lt;br /&gt;
* [https://github.com/SpringMCLegacy/SpringMCLegacy/blob/master/LuaRules/Gadgets/api_vector.lua Vector]: Small utility for vector operations&lt;br /&gt;
* [https://github.com/Spring-SpringBoard/SpringBoard-Core/blob/master/libs_sb/json.lua JSON]: Serializing to the JSON format&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Gadgets/api_delay.lua Delay]: Delaying gadget calls&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Includes/network.lua Network]: Delta compression for binary strings&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Includes/camera.lua Camera]: Camera state serialization&lt;br /&gt;
* Deferred rendering [http://imolarpg.dyndns.org/svn/branches/BAR/shaders/deferred_lighting.glsl Shader] &amp;amp; [http://imolarpg.dyndns.org/svn/branches/BAR/luaui/widgets/gfx_deferred_rendering.lua Widget]: Deferred rendering (projectile) based lights&lt;br /&gt;
&lt;br /&gt;
=== Additional resources ===&lt;br /&gt;
&lt;br /&gt;
Some additional libraries can be found using Github topics, such as [https://github.com/topics/springrts-lib springrts-lib] and [https://github.com/topics/springrts springrts]&lt;br /&gt;
&lt;br /&gt;
[[Category:Lua]] [[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Libraries&amp;diff=11340</id>
		<title>Lua Libraries</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Libraries&amp;diff=11340"/>
		<updated>2018-10-13T17:14:51Z</updated>

		<summary type="html">&lt;p&gt;Gajop: sorted libs alphabetically and added two new ones&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Lua libraries=&lt;br /&gt;
This page lists all common Lua libraries that can be used in Spring game and map archives.&lt;br /&gt;
&lt;br /&gt;
If you want to extend this page, please only add working, well-documented libraries and frameworks, and their official links.&lt;br /&gt;
It&#039;s possible to add early work, but try to make sure it has some documentation, and keep it in its separate repository.&lt;br /&gt;
&lt;br /&gt;
Libraries:&lt;br /&gt;
* [https://github.com/gajop/analytics analytics]: Usage analytics reporting&lt;br /&gt;
* [https://github.com/jk3064/chiliui ChiliUI]: UI framework [[Chili | docs]]&lt;br /&gt;
* [https://github.com/gajop/chilifx ChiliFX]: Chili effects&lt;br /&gt;
* [https://github.com/gajop/chotify Chotify]: Notification library in Chili&lt;br /&gt;
* [https://github.com/jk3064/Custom-Unit-Shader-Framework Custom Unit Shader Framework]: Unit rendering with shaders&lt;br /&gt;
* [https://github.com/gajop/i18n i18n]: Translations library&lt;br /&gt;
* [https://github.com/gajop/liblobby LibLobby]: Spring Lobby protocol library&lt;br /&gt;
* [https://github.com/gajop/Lua-Class-System LCS]: OOP (classes) in Lua&lt;br /&gt;
* [https://github.com/jk3064/lups LUPS]: Lua Particle System for Spring [[LUPS | docs]]&lt;br /&gt;
* [https://github.com/gajop/springmon springmon]: Spring file monitor and autoreloader&lt;br /&gt;
* [https://github.com/gajop/spring-wrapper-connector spring-wrapper-connector]: Wrapper program communication provider&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Single file libraries==&lt;br /&gt;
There is also a number of single file libraries that don&#039;t have their own repository but can technically still be considered libraries.&lt;br /&gt;
&lt;br /&gt;
Library files:&lt;br /&gt;
* [https://github.com/SpringMCLegacy/SpringMCLegacy/blob/master/LuaRules/Gadgets/api_vector.lua Vector]: Small utility for vector operations&lt;br /&gt;
* [https://github.com/Spring-SpringBoard/SpringBoard-Core/blob/master/libs_sb/json.lua JSON]: Serializing to the JSON format&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Gadgets/api_delay.lua Delay]: Delaying gadget calls&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Includes/network.lua Network]: Delta compression for binary strings&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Includes/camera.lua Camera]: Camera state serialization&lt;br /&gt;
* Deferred rendering [http://imolarpg.dyndns.org/svn/branches/BAR/shaders/deferred_lighting.glsl Shader] &amp;amp; [http://imolarpg.dyndns.org/svn/branches/BAR/luaui/widgets/gfx_deferred_rendering.lua Widget]: Deferred rendering (projectile) based lights&lt;br /&gt;
&lt;br /&gt;
[[Category:Lua]] [[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Libraries&amp;diff=11339</id>
		<title>Lua Libraries</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Libraries&amp;diff=11339"/>
		<updated>2018-10-13T10:45:38Z</updated>

		<summary type="html">&lt;p&gt;Gajop: better json.lua link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Lua libraries=&lt;br /&gt;
This page lists all common Lua libraries that can be used in Spring game and map archives.&lt;br /&gt;
&lt;br /&gt;
If you want to extend this page, please only add working, well-documented libraries and frameworks, and their official links.&lt;br /&gt;
It&#039;s possible to add early work, but try to make sure it has some documentation, and keep it in its separate repository.&lt;br /&gt;
&lt;br /&gt;
Libraries:&lt;br /&gt;
* [https://github.com/jk3064/chiliui ChiliUI]: UI framework [[Chili | docs]]&lt;br /&gt;
* [https://github.com/jk3064/lups LUPS]: Lua Particle System for Spring [[LUPS | docs]]&lt;br /&gt;
* [https://github.com/jk3064/Custom-Unit-Shader-Framework Custom Unit Shader Framework]: Unit rendering with shaders&lt;br /&gt;
* [https://github.com/gajop/liblobby LibLobby]: Spring Lobby protocol library&lt;br /&gt;
* [https://github.com/gajop/i18n i18n]: Translations library&lt;br /&gt;
* [https://github.com/gajop/Lua-Class-System LCS]: OOP (classes) in Lua&lt;br /&gt;
* [https://github.com/gajop/analytics analytics]: Usage analytics reporting [WIP]&lt;br /&gt;
* [https://github.com/gajop/chilifx ChiliFX]: Chili effects [WIP]&lt;br /&gt;
* [https://github.com/gajop/chotify Chotify]: Notification library in Chili [WIP]&lt;br /&gt;
&lt;br /&gt;
==Single file libraries==&lt;br /&gt;
There is also a number of single file libraries that don&#039;t have their own repository but can technically still be considered libraries.&lt;br /&gt;
&lt;br /&gt;
Library files:&lt;br /&gt;
* [https://github.com/SpringMCLegacy/SpringMCLegacy/blob/master/LuaRules/Gadgets/api_vector.lua Vector]: Small utility for vector operations&lt;br /&gt;
* [https://github.com/Spring-SpringBoard/SpringBoard-Core/blob/master/libs_sb/json.lua JSON]: Serializing to the JSON format&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Gadgets/api_delay.lua Delay]: Delaying gadget calls&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Includes/network.lua Network]: Delta compression for binary strings&lt;br /&gt;
* [https://github.com/spring1944/spring1944/blob/master/LuaRules/Includes/camera.lua Camera]: Camera state serialization&lt;br /&gt;
* Deferred rendering [http://imolarpg.dyndns.org/svn/branches/BAR/shaders/deferred_lighting.glsl Shader] &amp;amp; [http://imolarpg.dyndns.org/svn/branches/BAR/luaui/widgets/gfx_deferred_rendering.lua Widget]: Deferred rendering (projectile) based lights&lt;br /&gt;
&lt;br /&gt;
[[Category:Lua]] [[Category:Libraries]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Performance&amp;diff=11557</id>
		<title>Lua Performance</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua_Performance&amp;diff=11557"/>
		<updated>2018-10-13T09:59:52Z</updated>

		<summary type="html">&lt;p&gt;Gajop: remove ugly code blocks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Overview=&lt;br /&gt;
&lt;br /&gt;
This page is copied from the [http://trac.caspring.org/wiki/LuaPerformance CA wiki]. The widget used in the performance tests is available from the [http://trac.caspring.org/browser/trunk/mods/ca-sandbox/LuaUI/Widgets/performance.lua CA SVN].&lt;br /&gt;
&lt;br /&gt;
=Other Considerations=&lt;br /&gt;
&lt;br /&gt;
It is a well known axiom in computing that&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;quot;We should forget about small efficiencies, say about 97% of the time: &#039;&#039;&#039;premature optimization is the root of all evil&#039;&#039;&#039;&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 - [http://en.wikipedia.org/wiki/Donald_Knuth Donald Knuth]&lt;br /&gt;
&lt;br /&gt;
Lua coders should keep that in mind, and especially when visiting this page. Readability and maintainability are in most cases just as important, and optimizing code for every last ounce of performance can severely impact those qualities. On the other hand, some of the optimizations suggested have little bearing on readability and should generally always be applied, e.g. localization of API functions, or actually make for neater code e.g. the use of &amp;lt;code&amp;gt;or&amp;lt;/code&amp;gt; rather than a nil-check. Generally speaking, optimize only once you are sure that there is or will be a performance bottleneck.&lt;br /&gt;
&lt;br /&gt;
=Performance Tests=&lt;br /&gt;
&lt;br /&gt;
==TEST 1: Localize==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  local min = math.min&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;Non-local: 0.719 (158%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;Localized: 0.453 (100%)&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Yes, we should localize all standard Lua and Spring API functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 2: Localized Class-Methods (with only 3 accesses!)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    local x = class.test()&lt;br /&gt;
    local y = class.test()&lt;br /&gt;
    local z = class.test()&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    local test = class.test&lt;br /&gt;
    local x = test()&lt;br /&gt;
    local y = test()&lt;br /&gt;
    local z = test()&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Normal way: 1.203 (102%)&lt;br /&gt;
:Localized: 1.172 (100%)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:No, it isn&#039;t faster to localize a class method IN the function call.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 3: Unpack A Table==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    local x = min( a[1],a[2],a[3],a[4] )&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  local unpack = unpack&lt;br /&gt;
  for i=1,1000000 do&lt;br /&gt;
    local x = min( unpack(a) )&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 3:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  local function unpack4(a)&lt;br /&gt;
    return a[1],a[2],a[3],a[4]&lt;br /&gt;
  end&lt;br /&gt;
  for i=1,1000000 do&lt;br /&gt;
    local x = min( unpack4(a) )&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;with [ ]: 0.485 (100%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;unpack(): 1.093 (225%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:custom unpack4: 0.641 (131%) &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Don&#039;t use &amp;lt;code&amp;gt;unpack()&amp;lt;/code&amp;gt; in time critical code!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 4: Determine Maximum And Set It (&#039;&amp;gt;&#039; vs. max)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  local max = math.max&lt;br /&gt;
  for i=1,1000000 do&lt;br /&gt;
     x = max(random(cnt),x)&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    local r = random(cnt)&lt;br /&gt;
    if (r&amp;gt;x) then x = r end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;math.max: 0.437 (156%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;&#039;if &amp;gt; then&#039;: 0.282 (100%)&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Don&#039;t use &amp;lt;code&amp;gt;math.[max|min]()&amp;lt;/code&amp;gt; in time critical code!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 5: Nil Checks (&#039;if&#039; vs. &#039;or&#039;)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    local y,x&lt;br /&gt;
    if (random()&amp;gt;0.5) then y=1 end &lt;br /&gt;
    if (y==nil) then x=1 else x=y end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    local y&lt;br /&gt;
    if (random()&amp;gt;0.5) then y=1 end &lt;br /&gt;
    local x=y or 1&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;nil-check: 0.297 (106%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;a=x or y: 0.281 (100%)&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:The &amp;lt;code&amp;gt;or&amp;lt;/code&amp;gt;-operator is faster than a nil-check. Use it!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 6: &#039;x^2&#039; vs. &#039;x*x&#039;==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
     local y = x^2&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
     local y = x*x&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;x^2: 1.422 (110%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;x*x: 1.297 (100%) &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:The second syntax is marginally faster&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 7: Modulus Operators (math.mod vs. %)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  local fmod = math.fmod&lt;br /&gt;
  for i=1,1000000 do&lt;br /&gt;
    if (fmod(i,30)&amp;lt;1) then&lt;br /&gt;
      local x = 1&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    if ((i%30)&amp;lt;1) then&lt;br /&gt;
      local x = 1&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;math.mod: 0.281 (355%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;%: 0.079 (100%) &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Don&#039;t use &amp;lt;code&amp;gt;math.fmod()&amp;lt;/code&amp;gt; for positive numbers (for negative ones &amp;lt;code&amp;gt;%&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fmod()&amp;lt;/code&amp;gt; have different results!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 8: Functions As Param For Other Functions==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039; &lt;br /&gt;
&amp;lt;pre&amp;gt;  local func1 = function(a,b,func) &lt;br /&gt;
    return func(a+b) &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  for i=1,1000000 do&lt;br /&gt;
    local x = func1(1,2,function(a) return a*2 end)&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  local func1 = function(a,b,func) &lt;br /&gt;
    return func(a+b) &lt;br /&gt;
  end&lt;br /&gt;
  local func2 = function(a) &lt;br /&gt;
    return a*2 &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  for i=1,1000000 do&lt;br /&gt;
    local x = func1(1,2,func2)&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;defined in function param: 3.890 (1144%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;defined as local: 0.344 (100%) &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:REALLY, LOCALIZE YOUR FUNCTIONS ALWAYS BEFORE SENDING THEM INTO ANOTHER FUNCTION!!! i.e if you use gl.BeginEnd(), gl.CreateList(), ...!!!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 9: for-loops==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    for j,v in pairs(a) do&lt;br /&gt;
      x=v&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    for j,v in ipairs(a) do&lt;br /&gt;
      x=v&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 3:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    for i=1,100 do&lt;br /&gt;
      x=a[i]&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 4:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    for i=1,#a do&lt;br /&gt;
      x=a[i]&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 5:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    local length = #a&lt;br /&gt;
    for i=1,length do&lt;br /&gt;
      x=a[i]&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:pairs: 3.078 (217%)&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;ipairs: 3.344 (236%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;for i=1,x do: 1.422 (100%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:for i=1,#atable do 1.422 (100%)&lt;br /&gt;
:for i=1,atable_length do: 1.562 (110%) &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Don&#039;t use &amp;lt;code&amp;gt;pairs()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ipairs()&amp;lt;/code&amp;gt; in critical code! Try to save the table-size somewhere and use &amp;lt;code&amp;gt;for i=1,x do&amp;lt;/code&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 10: Array Access (with [ ]) vs. Object Access (with .method)==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    x = a[&amp;quot;foo&amp;quot;]&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    x = a.foo&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:atable[&amp;quot;foo&amp;quot;]: 1.125 (100%)&lt;br /&gt;
:atable.foo: 1.141 (101%) &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:No difference.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 11: Buffered Table Item Access==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    for n=1,100 do&lt;br /&gt;
      a[n].x=a[n].x+1&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    for n=1,100 do&lt;br /&gt;
      local y = a[n]&lt;br /&gt;
      y.x=y.x+1&lt;br /&gt;
    end&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;&#039;a[n].x=a[n].x+1&#039;: 1.453 (127%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;&#039;local y=a[n]; y.x=y.x+1&#039;: 1.140 (100%) &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Buffering can speed up table item access.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 12: Adding Table Items (table.insert vs. [ ])==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 1:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  local tinsert = table.insert&lt;br /&gt;
  for i=1,1000000 do&lt;br /&gt;
    tinsert(a,i)&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 2:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    a[i]=i&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 3:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  for i=1,1000000 do&lt;br /&gt;
    a[#a+1]=i&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code 4:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;  local count = 1&lt;br /&gt;
  for i=1,1000000 do&lt;br /&gt;
    d[count]=i&lt;br /&gt;
    count=count+1&lt;br /&gt;
  end&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span class=warning&amp;gt;table.insert: 1.250 (727%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:&amp;lt;span class=note&amp;gt;a[i]: 0.172 (100%)&amp;lt;/span&amp;gt;&lt;br /&gt;
:a[#a+1]=x: 0.453 (263%)&lt;br /&gt;
:a[count++]=x: 0.203 (118%) &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Conclusion:&#039;&#039;&#039;&lt;br /&gt;
:Don&#039;t use &amp;lt;code&amp;gt;table.insert&amp;lt;/code&amp;gt;!!! Try to save the table-size somewhere and use &amp;lt;code&amp;gt;a[count+1]=x&amp;lt;/code&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TEST 12: Adding Table Items (mytable ={} vs. mytable={...})==&lt;br /&gt;
&lt;br /&gt;
When you write {true, true, true} , Lua knows beforehand that the table will need three slots in its array part, so Lua creates the table with that size. Similarly, if you write&lt;br /&gt;
{x = 1, y = 2, z = 3}, Lua will create a table with four slots in its hash part.&lt;br /&gt;
&lt;br /&gt;
As an example, the next loop runs in 2.0 seconds:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;for i = 1, 1000000 do&lt;br /&gt;
&lt;br /&gt;
local a = {}&lt;br /&gt;
&lt;br /&gt;
a[1] = 1; a[2] = 2; a[3] = 3&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If we create the tables with the right size, we reduce the run t&lt;br /&gt;
ime to 0.7 seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
for i = 1, 1000000 do&lt;br /&gt;
&lt;br /&gt;
local a = {true, true, true}&lt;br /&gt;
&lt;br /&gt;
a[1] = 1; a[2] = 2; a[3] = 3&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you write something like {[1] = true, [2] = true, [3] = true}, however, Lua is not smart enough to detect that the given expressions (literal numbers, in this case) describe array indices, so it creates a table with four slots in its hash part, wasting memory and CPU time&lt;br /&gt;
&lt;br /&gt;
[http://www.lua.org/gems/sample.pdf]&lt;br /&gt;
&lt;br /&gt;
=Test 13=&lt;br /&gt;
Table initialisation with local members and static intialisation. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local x = os.clock()&lt;br /&gt;
T={}&lt;br /&gt;
print(string.format(&amp;quot;start time: %.2f\n&amp;quot;, os.clock() - x))&lt;br /&gt;
local CachedTable= {&amp;quot;abc&amp;quot;,&amp;quot;def&amp;quot;,&amp;quot;ghk&amp;quot;}&lt;br /&gt;
for i=1 , 10000000, 1 do&lt;br /&gt;
T[i] = CachedTable&lt;br /&gt;
end&lt;br /&gt;
print(string.format(&amp;quot;elapsed time: %.2f\n&amp;quot;, os.clock() - x))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local x = os.clock()&lt;br /&gt;
A={}&lt;br /&gt;
print(string.format(&amp;quot;start time: %.2f\n&amp;quot;, os.clock() - x))&lt;br /&gt;
for i=1 , 10000000, 1 do&lt;br /&gt;
A[i] = {&amp;quot;abc&amp;quot;,&amp;quot;def&amp;quot;,&amp;quot;ghk&amp;quot;}&lt;br /&gt;
end&lt;br /&gt;
print(string.format(&amp;quot;elapsed time: %.2f\n&amp;quot;, os.clock() - x))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Result:&lt;br /&gt;
local table initializer = 100 %&lt;br /&gt;
static intializer = 500 %&lt;br /&gt;
&lt;br /&gt;
Analysis: Lua sucks at identifying static initializers, do not use them, use local initalizations instead.&lt;br /&gt;
&lt;br /&gt;
=Lua Garbage Collection=&lt;br /&gt;
Forum thread about {{forumlink|topic=31049|title= Lua Garbage collection info}} &lt;br /&gt;
&lt;br /&gt;
[[Category: Lua]]&lt;/div&gt;</summary>
		<author><name>Gajop</name></author>
	</entry>
</feed>