<?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=Coolfile</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=Coolfile"/>
	<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/wiki/Special:Contributions/Coolfile"/>
	<updated>2026-11-08T19:37:34Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Animation-LuaCallins&amp;diff=1991</id>
		<title>Animation-LuaCallins</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Animation-LuaCallins&amp;diff=1991"/>
		<updated>2010-11-25T11:39:45Z</updated>

		<summary type="html">&lt;p&gt;Coolfile: /* Builders and factories */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Call-ins are calls from the engine, into the unit script. In other words, these functions are called, if they are defined, when a particular â€œeventâ€ happens.&lt;br /&gt;
&lt;br /&gt;
For Lua unit scripts, a new callin mechanism has been implemented, which is faster than the regular callin mechanism which is used for widgets and gadgets.&lt;br /&gt;
&lt;br /&gt;
Types for arguments are only shown where they&#039;re ambiguous. For a number of (common) arguments, the types are:&lt;br /&gt;
&lt;br /&gt;
* unitID: number&lt;br /&gt;
* piece: number&lt;br /&gt;
* axis: number (1 = x axis, 2 = y axis, 3 = z axis)&lt;br /&gt;
* heading/pitch: number (radians)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Generic ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Create&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
This is called just after the unit script has been created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;StartMoving&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;StopMoving&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
These are called whenever the unit starts or stops moving. Typical use for them is to trigger wheels to start spinning, animate treads, or start/stop a walking animation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Killed&#039;&#039;&#039; ( number recentDamage, number maxHealth ) -&amp;gt; number corpseType&lt;br /&gt;
&lt;br /&gt;
This is called when the unit is killed. The severity of the kill may be calculated as severity=recentDamage/maxHealth. Typically, this function would play a death animation for the unit, and finally return a corpse type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WindChanged&#039;&#039;&#039; ( number heading, number strength ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
This is called for wind generators whenever the wind direction or strength changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ExtractionRateChanged&#039;&#039;&#039; ( number rate ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called for metal extractors each time their extraction rate (metal per second) changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setSFXoccupy&#039;&#039;&#039; ( number curTerrainType ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called when terrain type changes. Terrain type is calculated with the following rules (in this order):&lt;br /&gt;
&lt;br /&gt;
* If unit is being transported -&amp;gt; curTerrainType = 0&lt;br /&gt;
* If ground height &amp;lt; -5 and unit is always upright -&amp;gt; curTerrainType = 2&lt;br /&gt;
* If ground height &amp;lt; -5 and unit is not always upright -&amp;gt; curTerrainType = 1&lt;br /&gt;
* If ground height &amp;lt; 0 and unit is always upright -&amp;gt; curTerrainType = 1&lt;br /&gt;
* Otherwise -&amp;gt; curTerrainType = 4&lt;br /&gt;
&lt;br /&gt;
Where is curTerrainType = 3 ? :-)&lt;br /&gt;
&lt;br /&gt;
Candidate to be changed to something saner later on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MoveRate&#039;&#039;&#039; ( number curRate ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called only for certain types of aircraft (those which use &#039;&#039;CTAAirMoveType&#039;&#039;.) The move rate is determined by the following rules (in this order):&lt;br /&gt;
&lt;br /&gt;
* If the aircraft is landing or taking off -&amp;gt; curRate = 1&lt;br /&gt;
* Otherwise -&amp;gt; curRate = floor(curSpeed / maxSpeed * 3), clamped to be in the range [0, 2]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QueryLandingPads&#039;&#039;&#039; ( ) -&amp;gt; { number piece1, number piece2, ... }&lt;br /&gt;
&lt;br /&gt;
Called one time for units with landing pads. Should return a table with pieces which should be used as landing pads. The number of pieces returned also determines the number of pads, so for Lua unit scripts there is no QueryLandingPadCount.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Activate&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Deactivate&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Exact situation these are called depends a lot on the unit type. Factories are activated when they open their yard and deactivated when they close it. Aircraft are activated when they take off and deactivated when the land. Any unit that can be turned on or off is activated when it&#039;s turned on and deactivated when it&#039;s turned off. On &#039;&#039;SetUnitValue(COB.ACTIVATION, ...)&#039;&#039; one of these call-ins may be called too.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weapons ==&lt;br /&gt;
&lt;br /&gt;
Weapon functions come in two variants.&lt;br /&gt;
&lt;br /&gt;
* Separate function with numeric weapon number suffix. (e.g. &#039;&#039;AimWeapon&amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;(heading, pitch)&#039;&#039;)&lt;br /&gt;
* Combined function which gets weapon number as second argument. (e.g. &#039;&#039;AimWeapon(&amp;lt;u&amp;gt;weaponNum&amp;lt;/u&amp;gt;, heading, pitch)&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Only the first variant is listed here, so whenever you see a function whose name ends with a numeric one (&amp;quot;1&amp;quot;), you should either replace it with the actual weapon number, or you can write a single combined function that takes a &#039;&#039;weaponNum&#039;&#039; argument. For each script, all functions should use the same variant. Either all using name suffix, or all using combined functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QueryWeapon1&#039;&#039;&#039; ( ) -&amp;gt; number piece&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;AimFromWeapon1&#039;&#039;&#039; ( ) -&amp;gt; number piece&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;AimWeapon1&#039;&#039;&#039; ( heading, pitch ) -&amp;gt; boolean&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;AimShield1&#039;&#039;&#039; ( ) -&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
Weapon support. The return value of QueryWeapon and AimFromWeapon determines the pieces which will be used for aiming: typically e.g. the barrel for QueryWeapon and the turret for AimFromWeapon. AimWeapon is then called to allow the script to turn the weapons in the target direction, which is passed as the heading and pitch argument (in radians). Only if AimWeapon returns true, the weapon is actually fired.&lt;br /&gt;
&lt;br /&gt;
TODO: better explanation (?), note about AimWeapon being called very often etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FireWeapon1&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Shot1&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;EndBurst1&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
If after aiming the unit actually fires it&#039;s weapon, FireWeapon is called once at the beginning of the salvo. Shot is called just before each projectile is fired. RockUnit (see below) is called just after all projectiles for that frame have been fired. At the end of the salvo, EndBurst is called.&lt;br /&gt;
&lt;br /&gt;
Of these call-ins, FireWeapon is the more generic one and Shot and EndBurst are more specialized. FireWeapon is usually used to play a recoil animation or emit some smoke near the weapon&#039;s barrel using EmitSfx.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BlockShot1&#039;&#039;&#039; ( targetUnitID, boolean userTarget ) -&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
Allows you to block a weapon from shooting. TargetUnitID may be nil: in this case the unit has a ground-attack order.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TargetWeight1&#039;&#039;&#039; ( targetUnitID ) -&amp;gt; number&lt;br /&gt;
&lt;br /&gt;
Allows you to tweak the priority of the target for this particular weapon. The target priority is multiplied by the return value of this function. Lower priority targets are targeted first, so return a value smaller than 1 to prioritize a target, or return a value larger than 1 to avoid a target.&lt;br /&gt;
&lt;br /&gt;
The exact behavior of specific values shouldn&#039;t be relied upon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RockUnit&#039;&#039;&#039; ( x, z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
A bit like the weapon-specific FireWeapon function, although this is called after any weapon fires. As argument it gets a two dimensional vector in the direction the unit just fired. This may be used to â€œrockâ€ the unit as a whole a bit as part of the firing animation. Note though that this vector is in world space, so for a truly realistic rock direction it needs to be rotated according to the unit&#039;s current heading.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;HitByWeapon&#039;&#039;&#039; ( x, z, weaponDefID, damage ) -&amp;gt; nil | number newDamage&lt;br /&gt;
&lt;br /&gt;
This is called if a unit has been hit by a weapon. (x, z) is the direction from which the projectile came in unit space (the reverse direction of the impulse, to be exact.) It also gets the weaponDefID of the weapon which is dealing the damage, and the amount of damage. If HitByWeapon returns a number, this number will replace the damage value calculated by the engine.&lt;br /&gt;
&lt;br /&gt;
Note: these call-in runs just before the LuaRules UnitPreDamaged callin (see also [[LuaCallinReturn]]). If HitByWeapon overrides the damage, UnitPreDamaged will see the new damage value, and may override again the damage value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Builders and factories ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;StartBuilding&#039;&#039;&#039; ( heading, pitch ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;StartBuilding&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;StopBuilding&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
These notify the script when a builder or factory starts or stops building.&lt;br /&gt;
&lt;br /&gt;
The first variant (with heading and pitch arguments) is called for builders. For factories, the second variant is used. In this case the heading and pitch are not necessary, because the factory script specifies the build location itself using QueryBuildInfo.&lt;br /&gt;
&lt;br /&gt;
BTW, don&#039;t forget to set INBUILDSTANCE to 1 to start building! For lua script, that is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  function script.StartBuilding(heading, pitch)&lt;br /&gt;
&lt;br /&gt;
    SetUnitValue(COB.INBUILDSTANCE, 1)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  function script.StopBuilding()&lt;br /&gt;
    SetUnitValue(COB.INBUILDSTANCE, 0)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QueryBuildInfo&#039;&#039;&#039; ( ) -&amp;gt; number piece&lt;br /&gt;
&lt;br /&gt;
For factories only. Should return the piece to which the unit which is going to be build will be attached while it&#039;s being build.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QueryNanopiece&#039;&#039;&#039; ( ) -&amp;gt; number piece&lt;br /&gt;
&lt;br /&gt;
Called each time a nano particle is to be created. Should return the piece at which the particle will be spawned. This may be used to iterate through a few pieces, to simulate the factory/builder having multiple nanolathes.&lt;br /&gt;
&lt;br /&gt;
== Transports ==&lt;br /&gt;
&lt;br /&gt;
There are some different code paths inside Spring related to transports, each (unfortunately) also associated with a different set of unit script call-ins.&lt;br /&gt;
&lt;br /&gt;
This table shows for the three different transportUnloadMethods for both air transports and ground transports which callins are used and roughly when and how often they are called. Refer to the documentation below for a description of the call-ins.&lt;br /&gt;
&lt;br /&gt;
The entire behavior around transports should be considered subject to change; it is obvious it is far from a perfect design currently.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; style=&amp;quot;border-spacing:0px;&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!&lt;br /&gt;
!Load&lt;br /&gt;
!UnloadLand (0)&lt;br /&gt;
!UnloadDrop (1)&lt;br /&gt;
!UnloadLandFlood (2)&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|default unload&lt;br /&gt;
|fly over and drop unit&lt;br /&gt;
|land, then release all units at once&lt;br /&gt;
|-&lt;br /&gt;
|air&lt;br /&gt;
|BeginTransport (each)&amp;lt;br&amp;gt;QueryTransport (each)&lt;br /&gt;
|EndTransport (last)&lt;br /&gt;
|EndTransport (each)&lt;br /&gt;
|StartUnload (first)&amp;lt;br&amp;gt;TransportDrop (each)&amp;lt;br&amp;gt;EndTransport (last)&lt;br /&gt;
|-&lt;br /&gt;
|ground&lt;br /&gt;
|TransportPickup (each)&lt;br /&gt;
|TransportDrop (each)&lt;br /&gt;
|TransportDrop (each)&lt;br /&gt;
|TransportDrop (each)&amp;lt;br&amp;gt;EndTransport (last)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Air transports ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BeginTransport&#039;&#039;&#039; ( passengerID ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;QueryTransport&#039;&#039;&#039; ( passengerID ) -&amp;gt; number piece&lt;br /&gt;
&lt;br /&gt;
For an air transport, if any one unit is picked up, these two are called in succession and the passenger is attached to the piece returned by the second one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;StartUnload&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Only called in UnloadLandFlood behavior. Signals the start of an unload cycle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TransportDrop&#039;&#039;&#039; ( passengerID, x, y, z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Only called in UnloadLandFlood behavior. Called when a passenger will be unloaded. Contrary to ground transports, Spring will detach the passenger after the call.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EndTransport&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
In UnloadLand and UnloadLandFlood behaviors, these are called one time after all units are unloaded. (The transport is empty.) For the UnloadDrop behavior, this is called for every unit that is unloaded.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ground transports ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TransportPickup&#039;&#039;&#039; ( passengerID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called when a passenger should be loaded into the transport. This should eventually call AttachUnit to actually attach the unit. Assuming the transport is in range of the next passenger, this will be called again for the next passenger 16 frames later, &#039;&#039;unless&#039;&#039; the script enters the BUSY state: then Spring will not move on to the next passenger until the script leaves the BUSY state.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TransportDrop&#039;&#039;&#039; ( passengerID, x, y, z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called when a passenger should be unloaded. This should eventually call DetachUnit to actually detach the unit, &#039;&#039;unless&#039;&#039; the used unload method is UnloadLandFlood, in which case Spring will actually detach the unit after the call.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EndTransport&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Only called in UnloadLandFlood behavior, after the last unit has been unloaded.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Passenger ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Falling&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
For a unit dropped from an UnloadDrop transport, this is called every frame to inform the script the unit is still falling. It may be used to show a parachute for example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landed&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
This is called one time after the unit reached the ground. May be used to hide a parachute for example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Internal ==&lt;br /&gt;
&lt;br /&gt;
These call-ins are NOT available to Lua unit scripts. They are called by the engine however, but always &#039;intercepted&#039; by the framework gadget. For completeness (or if you are poking at the gadget), they are listed here anyway.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MoveFinished&#039;&#039;&#039; ( piece, axis ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;TurnFinished&#039;&#039;&#039; ( piece, axis ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called when a move or turn finished. The framework gadget uses this to resume the coroutines which are waiting for the particular move or turn to be finished.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Destroy&#039;&#039;&lt;br /&gt;
&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called right before the unit&#039;s script is destroyed. This may happen if the unit is being destroyed, but also if the unit&#039;s script is being replaced by another script. The framework gadget uses this to stop all threads and remove the unit from some internal data structures.&lt;br /&gt;
[[Category:Unit_development]]&lt;br /&gt;
[[Category:Animation]]&lt;br /&gt;
[[Category:Lua]]&lt;/div&gt;</summary>
		<author><name>Coolfile</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Animation-LuaCallins&amp;diff=1990</id>
		<title>Animation-LuaCallins</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Animation-LuaCallins&amp;diff=1990"/>
		<updated>2010-11-25T11:38:59Z</updated>

		<summary type="html">&lt;p&gt;Coolfile: /* Builders and factories */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Call-ins are calls from the engine, into the unit script. In other words, these functions are called, if they are defined, when a particular â€œeventâ€ happens.&lt;br /&gt;
&lt;br /&gt;
For Lua unit scripts, a new callin mechanism has been implemented, which is faster than the regular callin mechanism which is used for widgets and gadgets.&lt;br /&gt;
&lt;br /&gt;
Types for arguments are only shown where they&#039;re ambiguous. For a number of (common) arguments, the types are:&lt;br /&gt;
&lt;br /&gt;
* unitID: number&lt;br /&gt;
* piece: number&lt;br /&gt;
* axis: number (1 = x axis, 2 = y axis, 3 = z axis)&lt;br /&gt;
* heading/pitch: number (radians)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Generic ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Create&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
This is called just after the unit script has been created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;StartMoving&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;StopMoving&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
These are called whenever the unit starts or stops moving. Typical use for them is to trigger wheels to start spinning, animate treads, or start/stop a walking animation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Killed&#039;&#039;&#039; ( number recentDamage, number maxHealth ) -&amp;gt; number corpseType&lt;br /&gt;
&lt;br /&gt;
This is called when the unit is killed. The severity of the kill may be calculated as severity=recentDamage/maxHealth. Typically, this function would play a death animation for the unit, and finally return a corpse type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WindChanged&#039;&#039;&#039; ( number heading, number strength ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
This is called for wind generators whenever the wind direction or strength changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ExtractionRateChanged&#039;&#039;&#039; ( number rate ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called for metal extractors each time their extraction rate (metal per second) changes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setSFXoccupy&#039;&#039;&#039; ( number curTerrainType ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called when terrain type changes. Terrain type is calculated with the following rules (in this order):&lt;br /&gt;
&lt;br /&gt;
* If unit is being transported -&amp;gt; curTerrainType = 0&lt;br /&gt;
* If ground height &amp;lt; -5 and unit is always upright -&amp;gt; curTerrainType = 2&lt;br /&gt;
* If ground height &amp;lt; -5 and unit is not always upright -&amp;gt; curTerrainType = 1&lt;br /&gt;
* If ground height &amp;lt; 0 and unit is always upright -&amp;gt; curTerrainType = 1&lt;br /&gt;
* Otherwise -&amp;gt; curTerrainType = 4&lt;br /&gt;
&lt;br /&gt;
Where is curTerrainType = 3 ? :-)&lt;br /&gt;
&lt;br /&gt;
Candidate to be changed to something saner later on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MoveRate&#039;&#039;&#039; ( number curRate ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called only for certain types of aircraft (those which use &#039;&#039;CTAAirMoveType&#039;&#039;.) The move rate is determined by the following rules (in this order):&lt;br /&gt;
&lt;br /&gt;
* If the aircraft is landing or taking off -&amp;gt; curRate = 1&lt;br /&gt;
* Otherwise -&amp;gt; curRate = floor(curSpeed / maxSpeed * 3), clamped to be in the range [0, 2]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QueryLandingPads&#039;&#039;&#039; ( ) -&amp;gt; { number piece1, number piece2, ... }&lt;br /&gt;
&lt;br /&gt;
Called one time for units with landing pads. Should return a table with pieces which should be used as landing pads. The number of pieces returned also determines the number of pads, so for Lua unit scripts there is no QueryLandingPadCount.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Activate&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Deactivate&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Exact situation these are called depends a lot on the unit type. Factories are activated when they open their yard and deactivated when they close it. Aircraft are activated when they take off and deactivated when the land. Any unit that can be turned on or off is activated when it&#039;s turned on and deactivated when it&#039;s turned off. On &#039;&#039;SetUnitValue(COB.ACTIVATION, ...)&#039;&#039; one of these call-ins may be called too.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weapons ==&lt;br /&gt;
&lt;br /&gt;
Weapon functions come in two variants.&lt;br /&gt;
&lt;br /&gt;
* Separate function with numeric weapon number suffix. (e.g. &#039;&#039;AimWeapon&amp;lt;u&amp;gt;1&amp;lt;/u&amp;gt;(heading, pitch)&#039;&#039;)&lt;br /&gt;
* Combined function which gets weapon number as second argument. (e.g. &#039;&#039;AimWeapon(&amp;lt;u&amp;gt;weaponNum&amp;lt;/u&amp;gt;, heading, pitch)&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Only the first variant is listed here, so whenever you see a function whose name ends with a numeric one (&amp;quot;1&amp;quot;), you should either replace it with the actual weapon number, or you can write a single combined function that takes a &#039;&#039;weaponNum&#039;&#039; argument. For each script, all functions should use the same variant. Either all using name suffix, or all using combined functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QueryWeapon1&#039;&#039;&#039; ( ) -&amp;gt; number piece&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;AimFromWeapon1&#039;&#039;&#039; ( ) -&amp;gt; number piece&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;AimWeapon1&#039;&#039;&#039; ( heading, pitch ) -&amp;gt; boolean&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;AimShield1&#039;&#039;&#039; ( ) -&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
Weapon support. The return value of QueryWeapon and AimFromWeapon determines the pieces which will be used for aiming: typically e.g. the barrel for QueryWeapon and the turret for AimFromWeapon. AimWeapon is then called to allow the script to turn the weapons in the target direction, which is passed as the heading and pitch argument (in radians). Only if AimWeapon returns true, the weapon is actually fired.&lt;br /&gt;
&lt;br /&gt;
TODO: better explanation (?), note about AimWeapon being called very often etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FireWeapon1&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Shot1&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;EndBurst1&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
If after aiming the unit actually fires it&#039;s weapon, FireWeapon is called once at the beginning of the salvo. Shot is called just before each projectile is fired. RockUnit (see below) is called just after all projectiles for that frame have been fired. At the end of the salvo, EndBurst is called.&lt;br /&gt;
&lt;br /&gt;
Of these call-ins, FireWeapon is the more generic one and Shot and EndBurst are more specialized. FireWeapon is usually used to play a recoil animation or emit some smoke near the weapon&#039;s barrel using EmitSfx.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BlockShot1&#039;&#039;&#039; ( targetUnitID, boolean userTarget ) -&amp;gt; boolean&lt;br /&gt;
&lt;br /&gt;
Allows you to block a weapon from shooting. TargetUnitID may be nil: in this case the unit has a ground-attack order.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TargetWeight1&#039;&#039;&#039; ( targetUnitID ) -&amp;gt; number&lt;br /&gt;
&lt;br /&gt;
Allows you to tweak the priority of the target for this particular weapon. The target priority is multiplied by the return value of this function. Lower priority targets are targeted first, so return a value smaller than 1 to prioritize a target, or return a value larger than 1 to avoid a target.&lt;br /&gt;
&lt;br /&gt;
The exact behavior of specific values shouldn&#039;t be relied upon.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RockUnit&#039;&#039;&#039; ( x, z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
A bit like the weapon-specific FireWeapon function, although this is called after any weapon fires. As argument it gets a two dimensional vector in the direction the unit just fired. This may be used to â€œrockâ€ the unit as a whole a bit as part of the firing animation. Note though that this vector is in world space, so for a truly realistic rock direction it needs to be rotated according to the unit&#039;s current heading.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;HitByWeapon&#039;&#039;&#039; ( x, z, weaponDefID, damage ) -&amp;gt; nil | number newDamage&lt;br /&gt;
&lt;br /&gt;
This is called if a unit has been hit by a weapon. (x, z) is the direction from which the projectile came in unit space (the reverse direction of the impulse, to be exact.) It also gets the weaponDefID of the weapon which is dealing the damage, and the amount of damage. If HitByWeapon returns a number, this number will replace the damage value calculated by the engine.&lt;br /&gt;
&lt;br /&gt;
Note: these call-in runs just before the LuaRules UnitPreDamaged callin (see also [[LuaCallinReturn]]). If HitByWeapon overrides the damage, UnitPreDamaged will see the new damage value, and may override again the damage value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Builders and factories ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;StartBuilding&#039;&#039;&#039; ( heading, pitch ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;StartBuilding&#039;&#039;&#039; ( ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;StopBuilding&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
These notify the script when a builder or factory starts or stops building.&lt;br /&gt;
&lt;br /&gt;
The first variant (with heading and pitch arguments) is called for builders. For factories, the second variant is used. In this case the heading and pitch are not necessary, because the factory script specifies the build location itself using QueryBuildInfo.&lt;br /&gt;
&lt;br /&gt;
in StartBuilding&lt;br /&gt;
BTW, don&#039;t forget to set INBUILDSTANCE to 1 to start building! For lua script, that is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  function script.StartBuilding(heading, pitch)&lt;br /&gt;
&lt;br /&gt;
    SetUnitValue(COB.INBUILDSTANCE, 1)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  function script.StopBuilding()&lt;br /&gt;
    SetUnitValue(COB.INBUILDSTANCE, 0)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QueryBuildInfo&#039;&#039;&#039; ( ) -&amp;gt; number piece&lt;br /&gt;
&lt;br /&gt;
For factories only. Should return the piece to which the unit which is going to be build will be attached while it&#039;s being build.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QueryNanopiece&#039;&#039;&#039; ( ) -&amp;gt; number piece&lt;br /&gt;
&lt;br /&gt;
Called each time a nano particle is to be created. Should return the piece at which the particle will be spawned. This may be used to iterate through a few pieces, to simulate the factory/builder having multiple nanolathes.&lt;br /&gt;
&lt;br /&gt;
== Transports ==&lt;br /&gt;
&lt;br /&gt;
There are some different code paths inside Spring related to transports, each (unfortunately) also associated with a different set of unit script call-ins.&lt;br /&gt;
&lt;br /&gt;
This table shows for the three different transportUnloadMethods for both air transports and ground transports which callins are used and roughly when and how often they are called. Refer to the documentation below for a description of the call-ins.&lt;br /&gt;
&lt;br /&gt;
The entire behavior around transports should be considered subject to change; it is obvious it is far from a perfect design currently.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; style=&amp;quot;border-spacing:0px;&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!&lt;br /&gt;
!Load&lt;br /&gt;
!UnloadLand (0)&lt;br /&gt;
!UnloadDrop (1)&lt;br /&gt;
!UnloadLandFlood (2)&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|default unload&lt;br /&gt;
|fly over and drop unit&lt;br /&gt;
|land, then release all units at once&lt;br /&gt;
|-&lt;br /&gt;
|air&lt;br /&gt;
|BeginTransport (each)&amp;lt;br&amp;gt;QueryTransport (each)&lt;br /&gt;
|EndTransport (last)&lt;br /&gt;
|EndTransport (each)&lt;br /&gt;
|StartUnload (first)&amp;lt;br&amp;gt;TransportDrop (each)&amp;lt;br&amp;gt;EndTransport (last)&lt;br /&gt;
|-&lt;br /&gt;
|ground&lt;br /&gt;
|TransportPickup (each)&lt;br /&gt;
|TransportDrop (each)&lt;br /&gt;
|TransportDrop (each)&lt;br /&gt;
|TransportDrop (each)&amp;lt;br&amp;gt;EndTransport (last)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Air transports ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BeginTransport&#039;&#039;&#039; ( passengerID ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;QueryTransport&#039;&#039;&#039; ( passengerID ) -&amp;gt; number piece&lt;br /&gt;
&lt;br /&gt;
For an air transport, if any one unit is picked up, these two are called in succession and the passenger is attached to the piece returned by the second one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;StartUnload&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Only called in UnloadLandFlood behavior. Signals the start of an unload cycle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TransportDrop&#039;&#039;&#039; ( passengerID, x, y, z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Only called in UnloadLandFlood behavior. Called when a passenger will be unloaded. Contrary to ground transports, Spring will detach the passenger after the call.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EndTransport&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
In UnloadLand and UnloadLandFlood behaviors, these are called one time after all units are unloaded. (The transport is empty.) For the UnloadDrop behavior, this is called for every unit that is unloaded.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ground transports ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TransportPickup&#039;&#039;&#039; ( passengerID ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called when a passenger should be loaded into the transport. This should eventually call AttachUnit to actually attach the unit. Assuming the transport is in range of the next passenger, this will be called again for the next passenger 16 frames later, &#039;&#039;unless&#039;&#039; the script enters the BUSY state: then Spring will not move on to the next passenger until the script leaves the BUSY state.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TransportDrop&#039;&#039;&#039; ( passengerID, x, y, z ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called when a passenger should be unloaded. This should eventually call DetachUnit to actually detach the unit, &#039;&#039;unless&#039;&#039; the used unload method is UnloadLandFlood, in which case Spring will actually detach the unit after the call.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EndTransport&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Only called in UnloadLandFlood behavior, after the last unit has been unloaded.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Passenger ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Falling&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
For a unit dropped from an UnloadDrop transport, this is called every frame to inform the script the unit is still falling. It may be used to show a parachute for example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Landed&#039;&#039;&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
This is called one time after the unit reached the ground. May be used to hide a parachute for example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Internal ==&lt;br /&gt;
&lt;br /&gt;
These call-ins are NOT available to Lua unit scripts. They are called by the engine however, but always &#039;intercepted&#039; by the framework gadget. For completeness (or if you are poking at the gadget), they are listed here anyway.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MoveFinished&#039;&#039;&#039; ( piece, axis ) -&amp;gt; nil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;TurnFinished&#039;&#039;&#039; ( piece, axis ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called when a move or turn finished. The framework gadget uses this to resume the coroutines which are waiting for the particular move or turn to be finished.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Destroy&#039;&#039;&lt;br /&gt;
&#039; ( ) -&amp;gt; nil&lt;br /&gt;
&lt;br /&gt;
Called right before the unit&#039;s script is destroyed. This may happen if the unit is being destroyed, but also if the unit&#039;s script is being replaced by another script. The framework gadget uses this to stop all threads and remove the unit from some internal data structures.&lt;br /&gt;
[[Category:Unit_development]]&lt;br /&gt;
[[Category:Animation]]&lt;br /&gt;
[[Category:Lua]]&lt;/div&gt;</summary>
		<author><name>Coolfile</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Simple_Game_Tutorial&amp;diff=16873</id>
		<title>Simple Game Tutorial</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Simple_Game_Tutorial&amp;diff=16873"/>
		<updated>2010-10-24T06:13:51Z</updated>

		<summary type="html">&lt;p&gt;Coolfile: /* sidedata.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Until I Finish [[Mod Development]] is the place to go.&lt;br /&gt;
&lt;br /&gt;
This Tutorial Aims to get a person from knowing nothing about Spring to the point where they can create and edit mods.&lt;br /&gt;
&lt;br /&gt;
Right now I am working from memory so you may want to correct me when I&#039;m wrong, I will try to cross link from my summaries to the appropriate articles available in other places.&lt;br /&gt;
&lt;br /&gt;
I will not go too deep into making 3do&#039;s because they are old and dumb... but I&#039;ll try to make note of the differences here.&lt;br /&gt;
&lt;br /&gt;
I don&#039;t know anything about scripting right now, so that section is likely to be sparse when I write it, I hope that someone will expand on it.&lt;br /&gt;
&lt;br /&gt;
=Book 1: The First Unit=&lt;br /&gt;
&lt;br /&gt;
==Step 1:Planning==&lt;br /&gt;
Who cares about planning, you know what you&#039;re doing... just come up with an idea for a mod... I made a chess set... if you don&#039;t have a real idea and just want to make a model show up in the game... then yeah... this is the place to start... I&#039;d do that if I were you.&lt;br /&gt;
&lt;br /&gt;
Another good thing to do at this point is to creat a &amp;quot;working directory&amp;quot;, and inside it create a directory with the name that your mod will have... after many headaches I decided it&#039;s best to put this in the root directory of your system so it&#039;s really easy to find when you are switching around back and forth between folders and keep having to find your files over and over again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Step 2:Getting The Tools==&lt;br /&gt;
You will need a bunch of stuff... here&#039;s the list (I assume you are using windows)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Want:&#039;&#039;&lt;br /&gt;
*[http://taspring.clan-sy.com/download.php Spring] - The main program, you will likely need this to test if you&#039;ve screwed up&lt;br /&gt;
*A Tiny Map (2x2) - to test your mod fast (suggest [http://www.fileuniverse.com/?p=showitem&amp;amp;ID=2534 Simple Chess Map])&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Need:&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;Program listings can be found here:&#039;&#039;&#039; &#039;&#039;&#039;[http://taspring.clan-sy.com/wiki/Map%2C_Mod%2C_And_Unit_Development_Programs Map, Mod, And Unit Development Programs]&#039;&#039;&#039;&lt;br /&gt;
*3D Modeling Program - &#039;&#039;&#039;See above link&#039;&#039;&#039;&lt;br /&gt;
*Notepad - to edit all the miriad of text files&lt;br /&gt;
*A Graphical Editing Program - needs to handle RGBA TGAs (aka tga&#039;s with alpha channels), I suggest Photoshop if you have it, or The GIMP... needed for all of the texture making for UVmapping stuff... &#039;&#039;&#039;See above link&#039;&#039;&#039;&lt;br /&gt;
*Upspring 1.3 - To convert your models to the approprite s3o format (if you want to fight with 3do builder, then go ahead... a good trick is to get your model into upspring first and adjust all the hierachy, then save it as an 3do... but why bother?). &#039;&#039;&#039;See above link&#039;&#039;&#039;&lt;br /&gt;
*Scriptor - to make and compile your units &amp;quot;animation script&amp;quot;... or steal someone else&#039;s and make it work for your unit. &#039;&#039;&#039;See above link&#039;&#039;&#039;&lt;br /&gt;
*Compression Utility - (I suggest [http://www.7-zip.org/ 7zip] - even if you are using zip compression and not 7zip, it&#039;s still good to have)&lt;br /&gt;
&lt;br /&gt;
==Step 3:Making a 3D Model==&lt;br /&gt;
&lt;br /&gt;
Go into your 3D modelling program and make a 3D model, [http://taspring.clan-sy.com/w/images/b/b4/WingsCombine.PNG combine] all the objects and UV map the model, then separate it out into any parts that need to move independently of each other.  Then Export the UV map as an Image File and Export the whole thing as a 3ds file.  Put the original wings file, the UVMap image and the 3ds file into your working directory so you can find them later.&lt;br /&gt;
&lt;br /&gt;
Wings 3D UV Mapping tutorial has been started here - [[Units:CreateModel]]&lt;br /&gt;
&lt;br /&gt;
==Step 4:Fixing Your Images==&lt;br /&gt;
&lt;br /&gt;
[[Basic s3o unit making guide|This Article includes a UVMapping Guide]]&lt;br /&gt;
&lt;br /&gt;
Open up your UVMap in Photoshop (or whatever) go to the layer/chooser thingy and go to the Channels Tab, add a new layer (it should default to alpha) and fill it with 99% black so you can see your texture in upspring.  If you want to can paint the UVmap and put white (1% black) on the alpha channel where you want your team colours to show up (you can use something between 1% and 99% to get a blend of your team colour along with the texture... for example 50% will give you your texture with 50% of the team colour mixed in...)&lt;br /&gt;
&lt;br /&gt;
I don&#039;t know how to do glow maps... XXreminder for someone to create a Glowmapping tutorial... you don&#039;t acctually need one for the model to show up.&lt;br /&gt;
&lt;br /&gt;
Save these images both in the working directory.&lt;br /&gt;
&lt;br /&gt;
Save a copy of these images in tga format into &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/unittextures&lt;br /&gt;
&lt;br /&gt;
==Step 5:Upspring==&lt;br /&gt;
&lt;br /&gt;
===Importing Your 3ds===&lt;br /&gt;
Open Upspring 1.3, go to file&amp;gt;load model and navigate to and open your 3DS model you exported, you should see the model in upspring as a 3d mesh.  Go to the model tab and set the radius and height values to something other then zero... this defines where the health bar will show up, and more importantly, how big the collision sphere will be.&lt;br /&gt;
&lt;br /&gt;
You will also need to use all of the other tools on those tabs to resize and rotate and move your model to the right place... wings makes models that are 90 degrees off and about 30 times smaller than most spring models... make sure you click the &amp;quot;apply transform&amp;quot; button after any changes that you actually want to show up in the game.&lt;br /&gt;
&lt;br /&gt;
Also, you will want to make the hierachy work using the cut, paste, and add empty buttons.  You will need an object called &amp;quot;base&amp;quot; that all the other objects are connected to... the &amp;quot;origin object&amp;quot;... sometimes you get lucky and wings exports it properly... usually not.&lt;br /&gt;
&lt;br /&gt;
===Importing Your UV and Glowmaps===&lt;br /&gt;
&lt;br /&gt;
Go to the textures tab and make your UV/texture/team-colour map as &amp;quot;texture1&amp;quot; and your UV/glow/reflectivity map as &amp;quot;texture2&amp;quot;... it should show up correctly in the preview pane.&lt;br /&gt;
&lt;br /&gt;
===Exporting Your s3o===&lt;br /&gt;
Choose File&amp;gt;Save Model As then in the drop down select &amp;quot;s3o&amp;quot; and type an appropriate name. This model should be saved to your working directory, and a copy of it made to &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/objects3d/&lt;br /&gt;
&lt;br /&gt;
==Step 6: Lua files==&lt;br /&gt;
&lt;br /&gt;
===UnitName.lua===&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
For Reference visit [[Units:FBI]], but again, the easiest way to do this is to extract an existing mod and find the fbi for a unit that behaves similarly to the one you are trying to make and rename and modify it.&lt;br /&gt;
&lt;br /&gt;
Some More Specific Information Not Clear in the &amp;quot;Units:FBI&amp;quot; article:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name+&amp;quot; &amp;quot;+Description=Spring Display Name&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
So if you have the following settings:&lt;br /&gt;
&lt;br /&gt;
 Name=Tiger;&lt;br /&gt;
 Description=Fast Attack C.A.T.;&lt;br /&gt;
&lt;br /&gt;
The Tooltip will show &amp;quot;Tiger Fast Attack C.A.T.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BuildPic Defaults to UnitName.bmp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
So if you leave out &amp;quot;BuildPic=filename.bmp;&amp;quot; Spring will look in /unitpics/ for a file called &amp;quot;UnitName.bmp&amp;quot; to use as your buildpic.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ObjectName&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you want to use an s3o object, you will need to specify with &amp;quot;ObjectName=UnitName&#039;&#039;&#039;.S3O;&#039;&#039;&#039;&amp;quot; otherwise it will look for &amp;quot;UnitName.3do&amp;quot;.  Also, you don&#039;t have to use &amp;quot;UnitName&amp;quot; as the filename and, in fact, multiple Unit&#039;s fbi files can reference the same 3D models. It is easier, however, for people to figure out what you are doing in your mod if you follow the standards.&lt;br /&gt;
&lt;br /&gt;
Save this file as plain text in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/units/&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
unitDef = {&lt;br /&gt;
  unitname           = [[arm_spider]],&lt;br /&gt;
  name               = [[Weaver]],&lt;br /&gt;
  description        = [[Cloaking Construction Spider, Builds at 9 m/s]],&lt;br /&gt;
  acceleration       = 0.15,&lt;br /&gt;
  bmcode             = [[1]],&lt;br /&gt;
  brakeRate          = 0.15,&lt;br /&gt;
  buildCostEnergy    = 230,&lt;br /&gt;
  buildCostMetal     = 230,&lt;br /&gt;
  buildDistance      = 80,&lt;br /&gt;
  builder            = true,&lt;br /&gt;
&lt;br /&gt;
  buildoptions       = {&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  buildPic           = [[arm_spider.png]],&lt;br /&gt;
  buildTime          = 230,&lt;br /&gt;
  canAttack          = false,&lt;br /&gt;
  canGuard           = true,&lt;br /&gt;
  canMove            = true,&lt;br /&gt;
  canPatrol          = true,&lt;br /&gt;
  canreclamate       = [[1]],&lt;br /&gt;
  canstop            = [[1]],&lt;br /&gt;
  category           = [[LAND UNARMED]],&lt;br /&gt;
  cloakCost          = 1,&lt;br /&gt;
  cloakCostMoving    = 2,&lt;br /&gt;
  corpse             = [[DEAD]],&lt;br /&gt;
&lt;br /&gt;
  customParams       = {&lt;br /&gt;
    description_bp = [[Aranha e de construÃƒÂ§?o, ConstrÃƒÂ³i a 6 m/s]],&lt;br /&gt;
    description_es = [[Ara?a de construcciÃƒÂ³n, construye a 6 m/s]],&lt;br /&gt;
    description_fi = [[Rakentaja/kaikuluotainkiipeilij?, rakentaa 6m/s nopeudella]],&lt;br /&gt;
    description_fr = [[Araign?e de Construction, Construit ? 6 m/s]],&lt;br /&gt;
    description_it = [[Ragno do costruzione occultante, costruisce a 6 m/s]],&lt;br /&gt;
    description_pl = [[Paj?k konstruktor, buduje z pr?dko?ci? 6m/s]],&lt;br /&gt;
    helptext       = [[The Weaver is a constructor that can climb over any obstacle and build defenses on high ground.]],&lt;br /&gt;
    helptext_bp    = [[Weaver ÃƒÂ© o construtor escalador camuflÃƒÂ¡vel de NOVA. Pode subir qualquer obstÃƒÂ¡culo, mas constrÃƒÂ³i mais devagar que construtores normais.]],&lt;br /&gt;
    helptext_es    = [[El Weaver es el constructor que puede treparse sobre qualquier obstÃƒÂ¡culo y construir defensas en terreno alto]],&lt;br /&gt;
    helptext_fi    = [[Weaver pystyy liikkumaan vaikeakulkuisimmassakin maastossa ja rakentamaan vaivatta my?s useimmille muille rakentajille saavuttamattomiin paikkoihin.]],&lt;br /&gt;
    helptext_fr    = [[Le weaver est un robot de construction tout terrain qui peut batir des d?fenses en terrain ?lev?.]],&lt;br /&gt;
    helptext_it    = [[Il Weaver ÃƒÂ© un costruttore che puo arrampicarsi su qualunque ostacolo e costruire difese nel terreno alto]],&lt;br /&gt;
    helptext_pl    = [[Weaver jest konstruktorem mog?cym wspina? si? po ka?dej powierzchni oraz posiadaj?cym mo?liwo?? maskowania si?]],&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  defaultmissiontype = [[Standby]],&lt;br /&gt;
  designation        = [[ARM-MLSPD]],&lt;br /&gt;
  energyMake         = 0.15,&lt;br /&gt;
  energyUse          = 0,&lt;br /&gt;
  explodeAs          = [[BIG_UNITEX]],&lt;br /&gt;
  footprintX         = 3,&lt;br /&gt;
  footprintZ         = 3,&lt;br /&gt;
  iconType           = [[builder]],&lt;br /&gt;
  mass               = 115,&lt;br /&gt;
  maxDamage          = 750,&lt;br /&gt;
  maxslope           = 16,&lt;br /&gt;
  maxSlope           = 72,&lt;br /&gt;
  maxVelocity        = 1.7,&lt;br /&gt;
  maxWaterDepth      = 22,&lt;br /&gt;
  metalMake          = 0.15,&lt;br /&gt;
  movementClass      = [[TKBOT3]],&lt;br /&gt;
  noAutoFire         = false,&lt;br /&gt;
  noChaseCategory    = [[TERRAFORM SATELLITE FIXEDWING GUNSHIP HOVER SHIP SWIM SUB LAND FLOAT SINK]],&lt;br /&gt;
  objectName         = [[ARMMLSPD]],&lt;br /&gt;
  radarDistanceJam   = 256,&lt;br /&gt;
  seismicSignature   = 16,&lt;br /&gt;
  selfDestructAs     = [[BIG_UNITEX]],&lt;br /&gt;
  showNanoSpray      = false,&lt;br /&gt;
  side               = [[ARM]],&lt;br /&gt;
  sightDistance      = 295,&lt;br /&gt;
  smoothAnim         = true,&lt;br /&gt;
  steeringmode       = [[1]],&lt;br /&gt;
  TEDClass           = [[CNSTR]],&lt;br /&gt;
  terraformSpeed     = 450,&lt;br /&gt;
  threed             = [[1]],&lt;br /&gt;
  turninplace        = 0,&lt;br /&gt;
  turnRate           = 1020,&lt;br /&gt;
  workerTime         = 9,&lt;br /&gt;
  zbuffer            = [[1]],&lt;br /&gt;
&lt;br /&gt;
  featureDefs        = {&lt;br /&gt;
&lt;br /&gt;
    DEAD  = {&lt;br /&gt;
      description      = [[Wreckage - Weaver]],&lt;br /&gt;
      blocking         = true,&lt;br /&gt;
      category         = [[arm_corpses]],&lt;br /&gt;
      damage           = 850,&lt;br /&gt;
      featureDead      = [[DEAD2]],&lt;br /&gt;
      featurereclamate = [[smudge01]],&lt;br /&gt;
      footprintX       = 3,&lt;br /&gt;
      footprintZ       = 3,&lt;br /&gt;
      height           = [[40]],&lt;br /&gt;
      hitdensity       = [[100]],&lt;br /&gt;
      metal            = 92,&lt;br /&gt;
      object           = [[ARMMLSPD_dead]],&lt;br /&gt;
      reclaimable      = true,&lt;br /&gt;
      reclaimTime      = 92,&lt;br /&gt;
      seqnamereclamate = [[tree1reclamate]],&lt;br /&gt;
      world            = [[All Worlds]],&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    DEAD2 = {&lt;br /&gt;
      description      = [[Debris - Weaver]],&lt;br /&gt;
      blocking         = false,&lt;br /&gt;
      category         = [[heaps]],&lt;br /&gt;
      damage           = 850,&lt;br /&gt;
      featureDead      = [[HEAP]],&lt;br /&gt;
      featurereclamate = [[smudge01]],&lt;br /&gt;
      footprintX       = 3,&lt;br /&gt;
      footprintZ       = 3,&lt;br /&gt;
      height           = [[4]],&lt;br /&gt;
      hitdensity       = [[100]],&lt;br /&gt;
      metal            = 92,&lt;br /&gt;
      object           = [[debris3x3b.s3o]],&lt;br /&gt;
      reclaimable      = true,&lt;br /&gt;
      reclaimTime      = 92,&lt;br /&gt;
      seqnamereclamate = [[tree1reclamate]],&lt;br /&gt;
      world            = [[All Worlds]],&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    HEAP  = {&lt;br /&gt;
      description      = [[Debris - Weaver]],&lt;br /&gt;
      blocking         = false,&lt;br /&gt;
      category         = [[heaps]],&lt;br /&gt;
      damage           = 850,&lt;br /&gt;
      featurereclamate = [[smudge01]],&lt;br /&gt;
      footprintX       = 3,&lt;br /&gt;
      footprintZ       = 3,&lt;br /&gt;
      height           = [[4]],&lt;br /&gt;
      hitdensity       = [[100]],&lt;br /&gt;
      metal            = 46,&lt;br /&gt;
      object           = [[debris3x3b.s3o]],&lt;br /&gt;
      reclaimable      = true,&lt;br /&gt;
      reclaimTime      = 46,&lt;br /&gt;
      seqnamereclamate = [[tree1reclamate]],&lt;br /&gt;
      world            = [[All Worlds]],&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return lowerkeys({ arm_spider = unitDef })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save this file as a lua file in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/units/&lt;br /&gt;
&lt;br /&gt;
===modinfo.lua===&lt;br /&gt;
&lt;br /&gt;
modinfo.lua is a lua file that defines a number of things that are used when loading a mod, most of the information is self explanitory but basically what you are doing is defining what is going to show up in whatever mod-selection interface you use as well as what other files need to be loaded into memory in order for your mod to work.&lt;br /&gt;
&lt;br /&gt;
====Making a New Mod with your unit/units====&lt;br /&gt;
The following is an example of what will be in your modinfo.lua file if you are starting from scratch and making your own mod. This is also good when you are just testing one unit to see if it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
return {&lt;br /&gt;
		-- The name is shown in the selection interface&lt;br /&gt;
		game = &amp;quot;MyMod&amp;quot;,&lt;br /&gt;
		shortGame = &amp;quot;MM&amp;quot;,&lt;br /&gt;
		name = &amp;quot;My Mod&amp;quot;,&lt;br /&gt;
		shortName = &amp;quot;MM&amp;quot;,&lt;br /&gt;
		version = &amp;quot;4.0&amp;quot;,&lt;br /&gt;
		mutator = &amp;quot;Heroes&amp;quot;,&lt;br /&gt;
		-- These can be shown by the selection interface&lt;br /&gt;
		description = &amp;quot;My Mod That I Made&amp;quot;,&lt;br /&gt;
		url = &amp;quot;http://www.theplacepeoplecangetthelatestversionofyourmod.com&amp;quot;,&lt;br /&gt;
		-- What kind of mod this is &lt;br /&gt;
		--  0 - Hidden (support mod that can&#039;t be selected, such as OTA_textures) &lt;br /&gt;
		--  1 - Normal, only one can be selected at a time &lt;br /&gt;
		--  2 - Addon, any number of these can be selected. Could be used &lt;br /&gt;
		--      for single units for example. &lt;br /&gt;
		--  others - perhaps mutators and addon races that can be &lt;br /&gt;
		--           enabled in addition to xta for example? &lt;br /&gt;
		modtype = &amp;quot;1&amp;quot;,&lt;br /&gt;
		-- Number of other archives this one depends on &lt;br /&gt;
		depend= {&lt;br /&gt;
			&amp;quot;Spring content v1&amp;quot;,&lt;br /&gt;
			&amp;quot;Spring Cursors&amp;quot;,&lt;br /&gt;
			&amp;quot;Spring Bitmaps&amp;quot;,&lt;br /&gt;
			-- Number of other content names this one replaces&lt;br /&gt;
                        added comment about filename vs unitsync name for dependency&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Adding Your Unit to an Existing Mod====&lt;br /&gt;
The following is an example of what will be in your modinfo.lua file if you are adding new units to an existing mod (in this case XTA SE v066), this is good for adding units to the build tree of an existing mod or adding a whole new team.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- Description of the mod control file recognized by spring:&lt;br /&gt;
return {&lt;br /&gt;
		-- The name is shown in the selection interface&lt;br /&gt;
		game = &amp;quot;XTASE_MyUnits&amp;quot;,&lt;br /&gt;
		shortGame = &amp;quot;XTASEMU&amp;quot;,&lt;br /&gt;
		name = &amp;quot;XTASEv0.66 with+My Units&amp;quot;,&lt;br /&gt;
		shortName = &amp;quot;XTASEMU&amp;quot;,&lt;br /&gt;
		version = &amp;quot;4.0&amp;quot;,&lt;br /&gt;
		mutator = &amp;quot;Heroes&amp;quot;,&lt;br /&gt;
		-- These can be shown by the selection interface&lt;br /&gt;
		description = &amp;quot;xta_se_v066 with the cool tank I made&amp;quot;,&lt;br /&gt;
		url = &amp;quot;http://www.fileuniverse.com/exactlocationblahblahblah&amp;quot;,&lt;br /&gt;
		-- What kind of mod this is &lt;br /&gt;
		--  0 - Hidden (support mod that can&#039;t be selected, such as OTA_textures) &lt;br /&gt;
		--  1 - Normal, only one can be selected at a time &lt;br /&gt;
		--  2 - Addon, any number of these can be selected. Could be used &lt;br /&gt;
		--      for single units for example. &lt;br /&gt;
		--  others - perhaps mutators and addon races that can be &lt;br /&gt;
		--           enabled in addition to xta for example? &lt;br /&gt;
		modtype = &amp;quot;1&amp;quot;,&lt;br /&gt;
		-- Number of other archives this one depends on &lt;br /&gt;
		depend= {&lt;br /&gt;
			&amp;quot;XTAsev066&amp;quot;,&lt;br /&gt;
                        &amp;quot;Spring Cursors&amp;quot;,&lt;br /&gt;
                        &amp;quot;Spring content v1&amp;quot;,&lt;br /&gt;
			-- Number of other archives this one replaces&lt;br /&gt;
                                        --do not used filenames, use the internal name, or downloader programs will fail to download the dependencies automatically&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are not depending on OTA files, you will have to supply your own cursors.&lt;br /&gt;
&lt;br /&gt;
There are some extra bits in these examples, but I work on the &amp;quot;better safe than sorry&amp;quot; principle... which is to wait for someone who knows what they are doing to fix my articles. &lt;br /&gt;
&lt;br /&gt;
You will want to save this file as plain text in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/&lt;br /&gt;
&lt;br /&gt;
===armorDefs.lua===&lt;br /&gt;
&lt;br /&gt;
I&#039;m not exactly sure how this works, but the file needs to exist, so either steal one from another mod and modify it... or just make a file that looks like this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local armorDefs = {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will want to save this file as a lua file in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/gamedata&lt;br /&gt;
&lt;br /&gt;
===sidedata.lua===&lt;br /&gt;
&lt;br /&gt;
Start by stealing the sidedata.lua file from your dependency mod if you have one, then edit it to include your units/side.&lt;br /&gt;
&lt;br /&gt;
Basically this file is in the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local sideData = {&lt;br /&gt;
	[1] = {&lt;br /&gt;
		name      = &#039;Good Guys&#039;,&lt;br /&gt;
		startunit = &#039;GG_comm&#039;,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also additional &amp;quot;[X]&amp;quot; entries for each side/team/commander-choice available in the mod-selector you choose.&lt;br /&gt;
&lt;br /&gt;
You will save this file as lua file in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/gamedata/&lt;br /&gt;
&lt;br /&gt;
-------------------&lt;br /&gt;
&lt;br /&gt;
Coolfile:&lt;br /&gt;
&lt;br /&gt;
The engine will stop spawning start units and resources anymore. &lt;br /&gt;
Please read this[http://springrts.com/phpbb/viewtopic.php?f=14&amp;amp;t=21883] for more information.&lt;br /&gt;
&lt;br /&gt;
(annotated on 2010-10-23)&lt;br /&gt;
&lt;br /&gt;
Moved the buildOptions definitions into the unitDef definitions, LuaParser &lt;br /&gt;
Please read the change log line 77 [http://springrts.com/wiki/The_Talking_Changelog] for more information.&lt;br /&gt;
&lt;br /&gt;
(annotated on 2010-10-24)&lt;br /&gt;
&lt;br /&gt;
===moveDefs.lua===&lt;br /&gt;
This file determines the footprint of your units, the angle of slopes they can climb and in how deep water they can drive. It contains several entries, all in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local moveDefs = {&lt;br /&gt;
	KBOT1 = { -- This is the name. Unit files refer to this name.&lt;br /&gt;
		footprintx = 1, -- This is how big the X dimension is of the footprint in Spring units probably?&lt;br /&gt;
		footprintz = 1, -- This is how big the Y dimension is of the footprint in Spring units probably?&lt;br /&gt;
		maxwaterdepth = 15, -- This is how big the Y dimension is of the footprint in Spring units probably?&lt;br /&gt;
		maxslope = 36, -- The maximum angle of slopes this unit can climb.&lt;br /&gt;
		crushstrength = 5, -- This determines if the unit/unit class can crush certain features&lt;br /&gt;
	},&lt;br /&gt;
	-- etc..&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===sounds.lua===&lt;br /&gt;
This file refers to all the sounds your units make, so Spring knows which sound file is linked to what action. It contains entries in the following format.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local Sounds = {&lt;br /&gt;
   SoundItems = {&lt;br /&gt;
      IncomingChat = {&lt;br /&gt;
         file = &amp;quot;sounds/nexuiz/talk.wav&amp;quot;,&lt;br /&gt;
         priority = 15,&lt;br /&gt;
         preload = true,&lt;br /&gt;
      },&lt;br /&gt;
      MultiSelect = {&lt;br /&gt;
         file = &amp;quot;sounds/ota/button9.wav&amp;quot;,&lt;br /&gt;
         priority = 15,&lt;br /&gt;
         preload = true,&lt;br /&gt;
         rolloff = 0.1,&lt;br /&gt;
      },&lt;br /&gt;
      MapPoint = {&lt;br /&gt;
         file = &amp;quot;sounds/bzflag/teamgrab.wav&amp;quot;,&lt;br /&gt;
         priority = 15,&lt;br /&gt;
         preload = true,&lt;br /&gt;
         rolloff = 0.1,&lt;br /&gt;
      },&lt;br /&gt;
      FailedCommand = {&lt;br /&gt;
         file = &amp;quot;sounds/openQuarz/pkup.wav&amp;quot;,&lt;br /&gt;
         gain = 0.75,&lt;br /&gt;
         priority = 15,&lt;br /&gt;
         preload = true,&lt;br /&gt;
         in3d = false,&lt;br /&gt;
      },&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
==Step 7:Adding a Build Pic==&lt;br /&gt;
&lt;br /&gt;
Add a 96x96 BMP to your &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/unitpics/ folder named either &amp;quot;UnitName.bmp&amp;quot; or whatever you specified in the &amp;quot;BuildPic=&amp;quot; line of your fbi.&lt;br /&gt;
&lt;br /&gt;
==Step 8:Adding a Side Pic==&lt;br /&gt;
&lt;br /&gt;
Add a 16x16 BMP to your &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/sidepics/ folder named &amp;quot;teamname.bmp&amp;quot; or whatever you specified in the &amp;quot;name=&amp;quot; line of your SIDEDATA.TDF for each side/team you have added.&lt;br /&gt;
&lt;br /&gt;
==Step 9:Scriptor==&lt;br /&gt;
&lt;br /&gt;
===Stealing a Script===&lt;br /&gt;
Open someone else&#039;s script in scriptor that works the way you want your script to work, look at the top where it&#039;s talking about &amp;quot;piece names&amp;quot;... then change those piece names to be the piece names of your unit and do a find/replace to make all the places where those pieces show up to be your pieces too.  Compile it so its name is the same as the &amp;quot;UnitName=&amp;quot; value in your &amp;quot;UnitName.fbi&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
XXreminder to someone to link to a proper scripting tutorial&lt;br /&gt;
&lt;br /&gt;
Put the bos and cob files for your unit script in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/scripts&lt;br /&gt;
&lt;br /&gt;
==Step 10:Compiling Your Mod==&lt;br /&gt;
&lt;br /&gt;
You may want to check your mod directory and make sure it follows the structure defined [[Mod_Development:Archives|here]].&lt;br /&gt;
&lt;br /&gt;
navigate to your &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt; and select everything and choose &amp;quot;add to archive &amp;lt;mod name&amp;gt;.7z&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
make a copy of this file called &amp;lt;mod name&amp;gt;v0.7z in your working directory so you don&#039;t screw anything up later, then make a copy of it called &amp;lt;mod name&amp;gt;.sd7 in the mods directory of spring.&lt;br /&gt;
&lt;br /&gt;
An alternative, added in more recent versions is the &amp;quot;.SDD&amp;quot; folder, to use this, copy the entire &amp;lt;mod name&amp;gt; folder in the mods directory of spring and rename it as &amp;quot;&amp;lt;mod name&amp;gt;.SDD&amp;quot;.  The advantage to the &amp;quot;.SDD&amp;quot; method is that you can tweak settings and add files without recompressing your mod all the time.  When it comes time to distribute your mod use &amp;quot;.sd7&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
EXAMPLES:&lt;br /&gt;
If your mod is called JoesMod you will have a file called &amp;quot;JoesMod.sd7&amp;quot; or a folder called &amp;quot;JoesMod.SDD&amp;quot; in your spring mods directory.&lt;br /&gt;
&lt;br /&gt;
==Step 11:Testing Your Mod==&lt;br /&gt;
Open Up your lobby client, pick your mod from the drop-down list of the games in host battle or singleplayer mode if your lobby supports it(if it doesn&#039;t show up you screwed up your modinfo.txt), choose your tiny map from the map list and press start.  If it doesn&#039;t break and your unit shows up, you have created all the neccessary files... yay!&lt;br /&gt;
&lt;br /&gt;
Gotchas:&lt;br /&gt;
*If it doesn&#039;t work, check you didn&#039;t zip the folder itself, but the contents, ie if you open mymod.sd7 with 7zip, you should see folders such as &amp;quot;unittextures&amp;quot; rather than a folder &amp;quot;mymod&amp;quot; containing unittextures.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mod development]]&lt;/div&gt;</summary>
		<author><name>Coolfile</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Simple_Game_Tutorial&amp;diff=16872</id>
		<title>Simple Game Tutorial</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Simple_Game_Tutorial&amp;diff=16872"/>
		<updated>2010-10-23T02:48:39Z</updated>

		<summary type="html">&lt;p&gt;Coolfile: /* sidedata.lua */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Until I Finish [[Mod Development]] is the place to go.&lt;br /&gt;
&lt;br /&gt;
This Tutorial Aims to get a person from knowing nothing about Spring to the point where they can create and edit mods.&lt;br /&gt;
&lt;br /&gt;
Right now I am working from memory so you may want to correct me when I&#039;m wrong, I will try to cross link from my summaries to the appropriate articles available in other places.&lt;br /&gt;
&lt;br /&gt;
I will not go too deep into making 3do&#039;s because they are old and dumb... but I&#039;ll try to make note of the differences here.&lt;br /&gt;
&lt;br /&gt;
I don&#039;t know anything about scripting right now, so that section is likely to be sparse when I write it, I hope that someone will expand on it.&lt;br /&gt;
&lt;br /&gt;
=Book 1: The First Unit=&lt;br /&gt;
&lt;br /&gt;
==Step 1:Planning==&lt;br /&gt;
Who cares about planning, you know what you&#039;re doing... just come up with an idea for a mod... I made a chess set... if you don&#039;t have a real idea and just want to make a model show up in the game... then yeah... this is the place to start... I&#039;d do that if I were you.&lt;br /&gt;
&lt;br /&gt;
Another good thing to do at this point is to creat a &amp;quot;working directory&amp;quot;, and inside it create a directory with the name that your mod will have... after many headaches I decided it&#039;s best to put this in the root directory of your system so it&#039;s really easy to find when you are switching around back and forth between folders and keep having to find your files over and over again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Step 2:Getting The Tools==&lt;br /&gt;
You will need a bunch of stuff... here&#039;s the list (I assume you are using windows)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Want:&#039;&#039;&lt;br /&gt;
*[http://taspring.clan-sy.com/download.php Spring] - The main program, you will likely need this to test if you&#039;ve screwed up&lt;br /&gt;
*A Tiny Map (2x2) - to test your mod fast (suggest [http://www.fileuniverse.com/?p=showitem&amp;amp;ID=2534 Simple Chess Map])&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Need:&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;Program listings can be found here:&#039;&#039;&#039; &#039;&#039;&#039;[http://taspring.clan-sy.com/wiki/Map%2C_Mod%2C_And_Unit_Development_Programs Map, Mod, And Unit Development Programs]&#039;&#039;&#039;&lt;br /&gt;
*3D Modeling Program - &#039;&#039;&#039;See above link&#039;&#039;&#039;&lt;br /&gt;
*Notepad - to edit all the miriad of text files&lt;br /&gt;
*A Graphical Editing Program - needs to handle RGBA TGAs (aka tga&#039;s with alpha channels), I suggest Photoshop if you have it, or The GIMP... needed for all of the texture making for UVmapping stuff... &#039;&#039;&#039;See above link&#039;&#039;&#039;&lt;br /&gt;
*Upspring 1.3 - To convert your models to the approprite s3o format (if you want to fight with 3do builder, then go ahead... a good trick is to get your model into upspring first and adjust all the hierachy, then save it as an 3do... but why bother?). &#039;&#039;&#039;See above link&#039;&#039;&#039;&lt;br /&gt;
*Scriptor - to make and compile your units &amp;quot;animation script&amp;quot;... or steal someone else&#039;s and make it work for your unit. &#039;&#039;&#039;See above link&#039;&#039;&#039;&lt;br /&gt;
*Compression Utility - (I suggest [http://www.7-zip.org/ 7zip] - even if you are using zip compression and not 7zip, it&#039;s still good to have)&lt;br /&gt;
&lt;br /&gt;
==Step 3:Making a 3D Model==&lt;br /&gt;
&lt;br /&gt;
Go into your 3D modelling program and make a 3D model, [http://taspring.clan-sy.com/w/images/b/b4/WingsCombine.PNG combine] all the objects and UV map the model, then separate it out into any parts that need to move independently of each other.  Then Export the UV map as an Image File and Export the whole thing as a 3ds file.  Put the original wings file, the UVMap image and the 3ds file into your working directory so you can find them later.&lt;br /&gt;
&lt;br /&gt;
Wings 3D UV Mapping tutorial has been started here - [[Units:CreateModel]]&lt;br /&gt;
&lt;br /&gt;
==Step 4:Fixing Your Images==&lt;br /&gt;
&lt;br /&gt;
[[Basic s3o unit making guide|This Article includes a UVMapping Guide]]&lt;br /&gt;
&lt;br /&gt;
Open up your UVMap in Photoshop (or whatever) go to the layer/chooser thingy and go to the Channels Tab, add a new layer (it should default to alpha) and fill it with 99% black so you can see your texture in upspring.  If you want to can paint the UVmap and put white (1% black) on the alpha channel where you want your team colours to show up (you can use something between 1% and 99% to get a blend of your team colour along with the texture... for example 50% will give you your texture with 50% of the team colour mixed in...)&lt;br /&gt;
&lt;br /&gt;
I don&#039;t know how to do glow maps... XXreminder for someone to create a Glowmapping tutorial... you don&#039;t acctually need one for the model to show up.&lt;br /&gt;
&lt;br /&gt;
Save these images both in the working directory.&lt;br /&gt;
&lt;br /&gt;
Save a copy of these images in tga format into &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/unittextures&lt;br /&gt;
&lt;br /&gt;
==Step 5:Upspring==&lt;br /&gt;
&lt;br /&gt;
===Importing Your 3ds===&lt;br /&gt;
Open Upspring 1.3, go to file&amp;gt;load model and navigate to and open your 3DS model you exported, you should see the model in upspring as a 3d mesh.  Go to the model tab and set the radius and height values to something other then zero... this defines where the health bar will show up, and more importantly, how big the collision sphere will be.&lt;br /&gt;
&lt;br /&gt;
You will also need to use all of the other tools on those tabs to resize and rotate and move your model to the right place... wings makes models that are 90 degrees off and about 30 times smaller than most spring models... make sure you click the &amp;quot;apply transform&amp;quot; button after any changes that you actually want to show up in the game.&lt;br /&gt;
&lt;br /&gt;
Also, you will want to make the hierachy work using the cut, paste, and add empty buttons.  You will need an object called &amp;quot;base&amp;quot; that all the other objects are connected to... the &amp;quot;origin object&amp;quot;... sometimes you get lucky and wings exports it properly... usually not.&lt;br /&gt;
&lt;br /&gt;
===Importing Your UV and Glowmaps===&lt;br /&gt;
&lt;br /&gt;
Go to the textures tab and make your UV/texture/team-colour map as &amp;quot;texture1&amp;quot; and your UV/glow/reflectivity map as &amp;quot;texture2&amp;quot;... it should show up correctly in the preview pane.&lt;br /&gt;
&lt;br /&gt;
===Exporting Your s3o===&lt;br /&gt;
Choose File&amp;gt;Save Model As then in the drop down select &amp;quot;s3o&amp;quot; and type an appropriate name. This model should be saved to your working directory, and a copy of it made to &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/objects3d/&lt;br /&gt;
&lt;br /&gt;
==Step 6: Lua files==&lt;br /&gt;
&lt;br /&gt;
===UnitName.lua===&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
For Reference visit [[Units:FBI]], but again, the easiest way to do this is to extract an existing mod and find the fbi for a unit that behaves similarly to the one you are trying to make and rename and modify it.&lt;br /&gt;
&lt;br /&gt;
Some More Specific Information Not Clear in the &amp;quot;Units:FBI&amp;quot; article:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name+&amp;quot; &amp;quot;+Description=Spring Display Name&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
So if you have the following settings:&lt;br /&gt;
&lt;br /&gt;
 Name=Tiger;&lt;br /&gt;
 Description=Fast Attack C.A.T.;&lt;br /&gt;
&lt;br /&gt;
The Tooltip will show &amp;quot;Tiger Fast Attack C.A.T.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BuildPic Defaults to UnitName.bmp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
So if you leave out &amp;quot;BuildPic=filename.bmp;&amp;quot; Spring will look in /unitpics/ for a file called &amp;quot;UnitName.bmp&amp;quot; to use as your buildpic.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ObjectName&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you want to use an s3o object, you will need to specify with &amp;quot;ObjectName=UnitName&#039;&#039;&#039;.S3O;&#039;&#039;&#039;&amp;quot; otherwise it will look for &amp;quot;UnitName.3do&amp;quot;.  Also, you don&#039;t have to use &amp;quot;UnitName&amp;quot; as the filename and, in fact, multiple Unit&#039;s fbi files can reference the same 3D models. It is easier, however, for people to figure out what you are doing in your mod if you follow the standards.&lt;br /&gt;
&lt;br /&gt;
Save this file as plain text in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/units/&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
unitDef = {&lt;br /&gt;
  unitname           = [[arm_spider]],&lt;br /&gt;
  name               = [[Weaver]],&lt;br /&gt;
  description        = [[Cloaking Construction Spider, Builds at 9 m/s]],&lt;br /&gt;
  acceleration       = 0.15,&lt;br /&gt;
  bmcode             = [[1]],&lt;br /&gt;
  brakeRate          = 0.15,&lt;br /&gt;
  buildCostEnergy    = 230,&lt;br /&gt;
  buildCostMetal     = 230,&lt;br /&gt;
  buildDistance      = 80,&lt;br /&gt;
  builder            = true,&lt;br /&gt;
&lt;br /&gt;
  buildoptions       = {&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  buildPic           = [[arm_spider.png]],&lt;br /&gt;
  buildTime          = 230,&lt;br /&gt;
  canAttack          = false,&lt;br /&gt;
  canGuard           = true,&lt;br /&gt;
  canMove            = true,&lt;br /&gt;
  canPatrol          = true,&lt;br /&gt;
  canreclamate       = [[1]],&lt;br /&gt;
  canstop            = [[1]],&lt;br /&gt;
  category           = [[LAND UNARMED]],&lt;br /&gt;
  cloakCost          = 1,&lt;br /&gt;
  cloakCostMoving    = 2,&lt;br /&gt;
  corpse             = [[DEAD]],&lt;br /&gt;
&lt;br /&gt;
  customParams       = {&lt;br /&gt;
    description_bp = [[Aranha e de construÃƒÂ§?o, ConstrÃƒÂ³i a 6 m/s]],&lt;br /&gt;
    description_es = [[Ara?a de construcciÃƒÂ³n, construye a 6 m/s]],&lt;br /&gt;
    description_fi = [[Rakentaja/kaikuluotainkiipeilij?, rakentaa 6m/s nopeudella]],&lt;br /&gt;
    description_fr = [[Araign?e de Construction, Construit ? 6 m/s]],&lt;br /&gt;
    description_it = [[Ragno do costruzione occultante, costruisce a 6 m/s]],&lt;br /&gt;
    description_pl = [[Paj?k konstruktor, buduje z pr?dko?ci? 6m/s]],&lt;br /&gt;
    helptext       = [[The Weaver is a constructor that can climb over any obstacle and build defenses on high ground.]],&lt;br /&gt;
    helptext_bp    = [[Weaver ÃƒÂ© o construtor escalador camuflÃƒÂ¡vel de NOVA. Pode subir qualquer obstÃƒÂ¡culo, mas constrÃƒÂ³i mais devagar que construtores normais.]],&lt;br /&gt;
    helptext_es    = [[El Weaver es el constructor que puede treparse sobre qualquier obstÃƒÂ¡culo y construir defensas en terreno alto]],&lt;br /&gt;
    helptext_fi    = [[Weaver pystyy liikkumaan vaikeakulkuisimmassakin maastossa ja rakentamaan vaivatta my?s useimmille muille rakentajille saavuttamattomiin paikkoihin.]],&lt;br /&gt;
    helptext_fr    = [[Le weaver est un robot de construction tout terrain qui peut batir des d?fenses en terrain ?lev?.]],&lt;br /&gt;
    helptext_it    = [[Il Weaver ÃƒÂ© un costruttore che puo arrampicarsi su qualunque ostacolo e costruire difese nel terreno alto]],&lt;br /&gt;
    helptext_pl    = [[Weaver jest konstruktorem mog?cym wspina? si? po ka?dej powierzchni oraz posiadaj?cym mo?liwo?? maskowania si?]],&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  defaultmissiontype = [[Standby]],&lt;br /&gt;
  designation        = [[ARM-MLSPD]],&lt;br /&gt;
  energyMake         = 0.15,&lt;br /&gt;
  energyUse          = 0,&lt;br /&gt;
  explodeAs          = [[BIG_UNITEX]],&lt;br /&gt;
  footprintX         = 3,&lt;br /&gt;
  footprintZ         = 3,&lt;br /&gt;
  iconType           = [[builder]],&lt;br /&gt;
  mass               = 115,&lt;br /&gt;
  maxDamage          = 750,&lt;br /&gt;
  maxslope           = 16,&lt;br /&gt;
  maxSlope           = 72,&lt;br /&gt;
  maxVelocity        = 1.7,&lt;br /&gt;
  maxWaterDepth      = 22,&lt;br /&gt;
  metalMake          = 0.15,&lt;br /&gt;
  movementClass      = [[TKBOT3]],&lt;br /&gt;
  noAutoFire         = false,&lt;br /&gt;
  noChaseCategory    = [[TERRAFORM SATELLITE FIXEDWING GUNSHIP HOVER SHIP SWIM SUB LAND FLOAT SINK]],&lt;br /&gt;
  objectName         = [[ARMMLSPD]],&lt;br /&gt;
  radarDistanceJam   = 256,&lt;br /&gt;
  seismicSignature   = 16,&lt;br /&gt;
  selfDestructAs     = [[BIG_UNITEX]],&lt;br /&gt;
  showNanoSpray      = false,&lt;br /&gt;
  side               = [[ARM]],&lt;br /&gt;
  sightDistance      = 295,&lt;br /&gt;
  smoothAnim         = true,&lt;br /&gt;
  steeringmode       = [[1]],&lt;br /&gt;
  TEDClass           = [[CNSTR]],&lt;br /&gt;
  terraformSpeed     = 450,&lt;br /&gt;
  threed             = [[1]],&lt;br /&gt;
  turninplace        = 0,&lt;br /&gt;
  turnRate           = 1020,&lt;br /&gt;
  workerTime         = 9,&lt;br /&gt;
  zbuffer            = [[1]],&lt;br /&gt;
&lt;br /&gt;
  featureDefs        = {&lt;br /&gt;
&lt;br /&gt;
    DEAD  = {&lt;br /&gt;
      description      = [[Wreckage - Weaver]],&lt;br /&gt;
      blocking         = true,&lt;br /&gt;
      category         = [[arm_corpses]],&lt;br /&gt;
      damage           = 850,&lt;br /&gt;
      featureDead      = [[DEAD2]],&lt;br /&gt;
      featurereclamate = [[smudge01]],&lt;br /&gt;
      footprintX       = 3,&lt;br /&gt;
      footprintZ       = 3,&lt;br /&gt;
      height           = [[40]],&lt;br /&gt;
      hitdensity       = [[100]],&lt;br /&gt;
      metal            = 92,&lt;br /&gt;
      object           = [[ARMMLSPD_dead]],&lt;br /&gt;
      reclaimable      = true,&lt;br /&gt;
      reclaimTime      = 92,&lt;br /&gt;
      seqnamereclamate = [[tree1reclamate]],&lt;br /&gt;
      world            = [[All Worlds]],&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    DEAD2 = {&lt;br /&gt;
      description      = [[Debris - Weaver]],&lt;br /&gt;
      blocking         = false,&lt;br /&gt;
      category         = [[heaps]],&lt;br /&gt;
      damage           = 850,&lt;br /&gt;
      featureDead      = [[HEAP]],&lt;br /&gt;
      featurereclamate = [[smudge01]],&lt;br /&gt;
      footprintX       = 3,&lt;br /&gt;
      footprintZ       = 3,&lt;br /&gt;
      height           = [[4]],&lt;br /&gt;
      hitdensity       = [[100]],&lt;br /&gt;
      metal            = 92,&lt;br /&gt;
      object           = [[debris3x3b.s3o]],&lt;br /&gt;
      reclaimable      = true,&lt;br /&gt;
      reclaimTime      = 92,&lt;br /&gt;
      seqnamereclamate = [[tree1reclamate]],&lt;br /&gt;
      world            = [[All Worlds]],&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    HEAP  = {&lt;br /&gt;
      description      = [[Debris - Weaver]],&lt;br /&gt;
      blocking         = false,&lt;br /&gt;
      category         = [[heaps]],&lt;br /&gt;
      damage           = 850,&lt;br /&gt;
      featurereclamate = [[smudge01]],&lt;br /&gt;
      footprintX       = 3,&lt;br /&gt;
      footprintZ       = 3,&lt;br /&gt;
      height           = [[4]],&lt;br /&gt;
      hitdensity       = [[100]],&lt;br /&gt;
      metal            = 46,&lt;br /&gt;
      object           = [[debris3x3b.s3o]],&lt;br /&gt;
      reclaimable      = true,&lt;br /&gt;
      reclaimTime      = 46,&lt;br /&gt;
      seqnamereclamate = [[tree1reclamate]],&lt;br /&gt;
      world            = [[All Worlds]],&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return lowerkeys({ arm_spider = unitDef })&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save this file as a lua file in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/units/&lt;br /&gt;
&lt;br /&gt;
===modinfo.lua===&lt;br /&gt;
&lt;br /&gt;
modinfo.lua is a lua file that defines a number of things that are used when loading a mod, most of the information is self explanitory but basically what you are doing is defining what is going to show up in whatever mod-selection interface you use as well as what other files need to be loaded into memory in order for your mod to work.&lt;br /&gt;
&lt;br /&gt;
====Making a New Mod with your unit/units====&lt;br /&gt;
The following is an example of what will be in your modinfo.lua file if you are starting from scratch and making your own mod. This is also good when you are just testing one unit to see if it works.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
return {&lt;br /&gt;
		-- The name is shown in the selection interface&lt;br /&gt;
		game = &amp;quot;MyMod&amp;quot;,&lt;br /&gt;
		shortGame = &amp;quot;MM&amp;quot;,&lt;br /&gt;
		name = &amp;quot;My Mod&amp;quot;,&lt;br /&gt;
		shortName = &amp;quot;MM&amp;quot;,&lt;br /&gt;
		version = &amp;quot;4.0&amp;quot;,&lt;br /&gt;
		mutator = &amp;quot;Heroes&amp;quot;,&lt;br /&gt;
		-- These can be shown by the selection interface&lt;br /&gt;
		description = &amp;quot;My Mod That I Made&amp;quot;,&lt;br /&gt;
		url = &amp;quot;http://www.theplacepeoplecangetthelatestversionofyourmod.com&amp;quot;,&lt;br /&gt;
		-- What kind of mod this is &lt;br /&gt;
		--  0 - Hidden (support mod that can&#039;t be selected, such as OTA_textures) &lt;br /&gt;
		--  1 - Normal, only one can be selected at a time &lt;br /&gt;
		--  2 - Addon, any number of these can be selected. Could be used &lt;br /&gt;
		--      for single units for example. &lt;br /&gt;
		--  others - perhaps mutators and addon races that can be &lt;br /&gt;
		--           enabled in addition to xta for example? &lt;br /&gt;
		modtype = &amp;quot;1&amp;quot;,&lt;br /&gt;
		-- Number of other archives this one depends on &lt;br /&gt;
		depend= {&lt;br /&gt;
			&amp;quot;Spring content v1&amp;quot;,&lt;br /&gt;
			&amp;quot;Spring Cursors&amp;quot;,&lt;br /&gt;
			&amp;quot;Spring Bitmaps&amp;quot;,&lt;br /&gt;
			-- Number of other content names this one replaces&lt;br /&gt;
                        added comment about filename vs unitsync name for dependency&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Adding Your Unit to an Existing Mod====&lt;br /&gt;
The following is an example of what will be in your modinfo.lua file if you are adding new units to an existing mod (in this case XTA SE v066), this is good for adding units to the build tree of an existing mod or adding a whole new team.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- Description of the mod control file recognized by spring:&lt;br /&gt;
return {&lt;br /&gt;
		-- The name is shown in the selection interface&lt;br /&gt;
		game = &amp;quot;XTASE_MyUnits&amp;quot;,&lt;br /&gt;
		shortGame = &amp;quot;XTASEMU&amp;quot;,&lt;br /&gt;
		name = &amp;quot;XTASEv0.66 with+My Units&amp;quot;,&lt;br /&gt;
		shortName = &amp;quot;XTASEMU&amp;quot;,&lt;br /&gt;
		version = &amp;quot;4.0&amp;quot;,&lt;br /&gt;
		mutator = &amp;quot;Heroes&amp;quot;,&lt;br /&gt;
		-- These can be shown by the selection interface&lt;br /&gt;
		description = &amp;quot;xta_se_v066 with the cool tank I made&amp;quot;,&lt;br /&gt;
		url = &amp;quot;http://www.fileuniverse.com/exactlocationblahblahblah&amp;quot;,&lt;br /&gt;
		-- What kind of mod this is &lt;br /&gt;
		--  0 - Hidden (support mod that can&#039;t be selected, such as OTA_textures) &lt;br /&gt;
		--  1 - Normal, only one can be selected at a time &lt;br /&gt;
		--  2 - Addon, any number of these can be selected. Could be used &lt;br /&gt;
		--      for single units for example. &lt;br /&gt;
		--  others - perhaps mutators and addon races that can be &lt;br /&gt;
		--           enabled in addition to xta for example? &lt;br /&gt;
		modtype = &amp;quot;1&amp;quot;,&lt;br /&gt;
		-- Number of other archives this one depends on &lt;br /&gt;
		depend= {&lt;br /&gt;
			&amp;quot;XTAsev066&amp;quot;,&lt;br /&gt;
                        &amp;quot;Spring Cursors&amp;quot;,&lt;br /&gt;
                        &amp;quot;Spring content v1&amp;quot;,&lt;br /&gt;
			-- Number of other archives this one replaces&lt;br /&gt;
                                        --do not used filenames, use the internal name, or downloader programs will fail to download the dependencies automatically&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you are not depending on OTA files, you will have to supply your own cursors.&lt;br /&gt;
&lt;br /&gt;
There are some extra bits in these examples, but I work on the &amp;quot;better safe than sorry&amp;quot; principle... which is to wait for someone who knows what they are doing to fix my articles. &lt;br /&gt;
&lt;br /&gt;
You will want to save this file as plain text in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/&lt;br /&gt;
&lt;br /&gt;
===armorDefs.lua===&lt;br /&gt;
&lt;br /&gt;
I&#039;m not exactly sure how this works, but the file needs to exist, so either steal one from another mod and modify it... or just make a file that looks like this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local armorDefs = {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will want to save this file as a lua file in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/gamedata&lt;br /&gt;
&lt;br /&gt;
===sidedata.lua===&lt;br /&gt;
&lt;br /&gt;
Start by stealing the sidedata.lua file from your dependency mod if you have one, then edit it to include your units/side.&lt;br /&gt;
&lt;br /&gt;
Basically this file is in the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local sideData = {&lt;br /&gt;
	[1] = {&lt;br /&gt;
		name      = &#039;Good Guys&#039;,&lt;br /&gt;
		startunit = &#039;GG_comm&#039;,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also additional &amp;quot;[X]&amp;quot; entries for each side/team/commander-choice available in the mod-selector you choose.&lt;br /&gt;
&lt;br /&gt;
You will save this file as lua file in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/gamedata/&lt;br /&gt;
&lt;br /&gt;
-------------------&lt;br /&gt;
&lt;br /&gt;
Coolfile:&lt;br /&gt;
&lt;br /&gt;
The engine will stop spawning start units and resources anymore. &lt;br /&gt;
Please read this[http://springrts.com/phpbb/viewtopic.php?f=14&amp;amp;t=21883] for more information.&lt;br /&gt;
&lt;br /&gt;
(annotated on 2010-10-23)&lt;br /&gt;
&lt;br /&gt;
===moveDefs.lua===&lt;br /&gt;
This file determines the footprint of your units, the angle of slopes they can climb and in how deep water they can drive. It contains several entries, all in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local moveDefs = {&lt;br /&gt;
	KBOT1 = { -- This is the name. Unit files refer to this name.&lt;br /&gt;
		footprintx = 1, -- This is how big the X dimension is of the footprint in Spring units probably?&lt;br /&gt;
		footprintz = 1, -- This is how big the Y dimension is of the footprint in Spring units probably?&lt;br /&gt;
		maxwaterdepth = 15, -- This is how big the Y dimension is of the footprint in Spring units probably?&lt;br /&gt;
		maxslope = 36, -- The maximum angle of slopes this unit can climb.&lt;br /&gt;
		crushstrength = 5, -- This determines if the unit/unit class can crush certain features&lt;br /&gt;
	},&lt;br /&gt;
	-- etc..&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===sounds.lua===&lt;br /&gt;
This file refers to all the sounds your units make, so Spring knows which sound file is linked to what action. It contains entries in the following format.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local Sounds = {&lt;br /&gt;
   SoundItems = {&lt;br /&gt;
      IncomingChat = {&lt;br /&gt;
         file = &amp;quot;sounds/nexuiz/talk.wav&amp;quot;,&lt;br /&gt;
         priority = 15,&lt;br /&gt;
         preload = true,&lt;br /&gt;
      },&lt;br /&gt;
      MultiSelect = {&lt;br /&gt;
         file = &amp;quot;sounds/ota/button9.wav&amp;quot;,&lt;br /&gt;
         priority = 15,&lt;br /&gt;
         preload = true,&lt;br /&gt;
         rolloff = 0.1,&lt;br /&gt;
      },&lt;br /&gt;
      MapPoint = {&lt;br /&gt;
         file = &amp;quot;sounds/bzflag/teamgrab.wav&amp;quot;,&lt;br /&gt;
         priority = 15,&lt;br /&gt;
         preload = true,&lt;br /&gt;
         rolloff = 0.1,&lt;br /&gt;
      },&lt;br /&gt;
      FailedCommand = {&lt;br /&gt;
         file = &amp;quot;sounds/openQuarz/pkup.wav&amp;quot;,&lt;br /&gt;
         gain = 0.75,&lt;br /&gt;
         priority = 15,&lt;br /&gt;
         preload = true,&lt;br /&gt;
         in3d = false,&lt;br /&gt;
      },&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
==Step 7:Adding a Build Pic==&lt;br /&gt;
&lt;br /&gt;
Add a 96x96 BMP to your &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/unitpics/ folder named either &amp;quot;UnitName.bmp&amp;quot; or whatever you specified in the &amp;quot;BuildPic=&amp;quot; line of your fbi.&lt;br /&gt;
&lt;br /&gt;
==Step 8:Adding a Side Pic==&lt;br /&gt;
&lt;br /&gt;
Add a 16x16 BMP to your &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/sidepics/ folder named &amp;quot;teamname.bmp&amp;quot; or whatever you specified in the &amp;quot;name=&amp;quot; line of your SIDEDATA.TDF for each side/team you have added.&lt;br /&gt;
&lt;br /&gt;
==Step 9:Scriptor==&lt;br /&gt;
&lt;br /&gt;
===Stealing a Script===&lt;br /&gt;
Open someone else&#039;s script in scriptor that works the way you want your script to work, look at the top where it&#039;s talking about &amp;quot;piece names&amp;quot;... then change those piece names to be the piece names of your unit and do a find/replace to make all the places where those pieces show up to be your pieces too.  Compile it so its name is the same as the &amp;quot;UnitName=&amp;quot; value in your &amp;quot;UnitName.fbi&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
XXreminder to someone to link to a proper scripting tutorial&lt;br /&gt;
&lt;br /&gt;
Put the bos and cob files for your unit script in &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt;/scripts&lt;br /&gt;
&lt;br /&gt;
==Step 10:Compiling Your Mod==&lt;br /&gt;
&lt;br /&gt;
You may want to check your mod directory and make sure it follows the structure defined [[Mod_Development:Archives|here]].&lt;br /&gt;
&lt;br /&gt;
navigate to your &amp;lt;working directory&amp;gt;/&amp;lt;mod name&amp;gt; and select everything and choose &amp;quot;add to archive &amp;lt;mod name&amp;gt;.7z&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
make a copy of this file called &amp;lt;mod name&amp;gt;v0.7z in your working directory so you don&#039;t screw anything up later, then make a copy of it called &amp;lt;mod name&amp;gt;.sd7 in the mods directory of spring.&lt;br /&gt;
&lt;br /&gt;
An alternative, added in more recent versions is the &amp;quot;.SDD&amp;quot; folder, to use this, copy the entire &amp;lt;mod name&amp;gt; folder in the mods directory of spring and rename it as &amp;quot;&amp;lt;mod name&amp;gt;.SDD&amp;quot;.  The advantage to the &amp;quot;.SDD&amp;quot; method is that you can tweak settings and add files without recompressing your mod all the time.  When it comes time to distribute your mod use &amp;quot;.sd7&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
EXAMPLES:&lt;br /&gt;
If your mod is called JoesMod you will have a file called &amp;quot;JoesMod.sd7&amp;quot; or a folder called &amp;quot;JoesMod.SDD&amp;quot; in your spring mods directory.&lt;br /&gt;
&lt;br /&gt;
==Step 11:Testing Your Mod==&lt;br /&gt;
Open Up your lobby client, pick your mod from the drop-down list of the games in host battle or singleplayer mode if your lobby supports it(if it doesn&#039;t show up you screwed up your modinfo.txt), choose your tiny map from the map list and press start.  If it doesn&#039;t break and your unit shows up, you have created all the neccessary files... yay!&lt;br /&gt;
&lt;br /&gt;
Gotchas:&lt;br /&gt;
*If it doesn&#039;t work, check you didn&#039;t zip the folder itself, but the contents, ie if you open mymod.sd7 with 7zip, you should see folders such as &amp;quot;unittextures&amp;quot; rather than a folder &amp;quot;mymod&amp;quot; containing unittextures.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mod development]]&lt;/div&gt;</summary>
		<author><name>Coolfile</name></author>
	</entry>
</feed>