<?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=Bla</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=Bla"/>
	<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/wiki/Special:Contributions/Bla"/>
	<updated>2026-11-08T18:36:17Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Gamedev:PublicRepos&amp;diff=8357</id>
		<title>Gamedev:PublicRepos</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Gamedev:PublicRepos&amp;diff=8357"/>
		<updated>2016-06-21T07:06:46Z</updated>

		<summary type="html">&lt;p&gt;Bla: /* Known Repos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==What Is This?==&lt;br /&gt;
This is a small collection of publicly known and readable code repositories for established Spring games. The intention being to provide a wealth of examples to all game developers from noob to pro.&lt;br /&gt;
&lt;br /&gt;
Most of these repositories can be downloaded with one of the [[Rapid_Tags]].&lt;br /&gt;
&lt;br /&gt;
== Known Repos ==&lt;br /&gt;
[https://github.com/KingRaptor/air-raid-spring Air Raid]&lt;br /&gt;
&lt;br /&gt;
[http://imolarpg.dyndns.org/trac/balatest/browser/trunk/ Balanced Annihilation]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/spring-archive/basically-ota BOTA]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/spring-archive/conflictterra Conflict Terra]&lt;br /&gt;
&lt;br /&gt;
[http://www.petro.darkstars.co.uk/damned/ Damned]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/EvolutionRTS/Evolution-RTS Evolution RTS]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SpringCabal/Gravitas Gravitas]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/n3wm1nd/TA Tech Annihilation]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/imperialwinter/swiw.sdd Imperial Winter]&lt;br /&gt;
&lt;br /&gt;
[https://bitbucket.org/PicassoCT/journeywar Journeywar]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jk3064?tab=repositories jK]&lt;br /&gt;
* [[Chili]]&lt;br /&gt;
* [[LUPS]]&lt;br /&gt;
* Custom-Unit-Shader-Framework&lt;br /&gt;
* [[Mapdev:Main#Blueprint | Map-Blueprint]]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/David-Becker/mods KDR_11k] &lt;br /&gt;
* Cuberors&#039; Finest&lt;br /&gt;
* CvC&lt;br /&gt;
* Doserz&lt;br /&gt;
* Fibre&lt;br /&gt;
* GINTA&lt;br /&gt;
* Gun Wings Test&lt;br /&gt;
* Light Side of Spring&lt;br /&gt;
* MicroModules&lt;br /&gt;
* Pong&lt;br /&gt;
&lt;br /&gt;
[https://github.com/SpringMCLegacy/SpringMCLegacy MechCommander: Legacy]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/spring1944/spring1944 Spring: 1944]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/spring-archive/springtanks Spring Tanks]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/spring-archive/springtutorialgame/tree/master/SpringTutorialGame.sdd Spring Tutorial Game]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/KingRaptor/THIS THIS]&lt;br /&gt;
&lt;br /&gt;
[http://code.google.com/p/xta-springrts/ XTA]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/ZeroK-RTS/Zero-K/ Zero-K]&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Dev]]&lt;br /&gt;
[[Category:Download Systems]]&lt;/div&gt;</summary>
		<author><name>Bla</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Kernel_Panic&amp;diff=10043</id>
		<title>Kernel Panic</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Kernel_Panic&amp;diff=10043"/>
		<updated>2014-05-15T16:06:34Z</updated>

		<summary type="html">&lt;p&gt;Bla: /* Playing Guide for System: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://img390.imageshack.us/img390/6289/kernelhd0.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview:==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;For the latest news and/or assistance, try the [http://springrts.com/phpbb/viewforum.php?f=43&#039;&#039;&#039;KP forum&#039;&#039;&#039;] or go to #kp when you log onto the lobby.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Kernel Panic&#039;&#039;&#039; is a game about computers. Systems, Hackers and Networks wage war in a matrix of DOOM! The only constraints are time and space; unlike other real time strategy games, no resource economy exists in KP. &lt;br /&gt;
&lt;br /&gt;
All units are free in this game, every factory built will be spamming units at all times. You can build more factories, but only on pre-defined areas (geothermal vents). All that remains is pure strategy and tactics. &lt;br /&gt;
&lt;br /&gt;
KP makes for a frantically fast-paced, action-oriented game, with a very unique graphical style.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Download links:==&lt;br /&gt;
&lt;br /&gt;
Current Version of Kernel Panic is 4.6&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;u&amp;gt;Newcomers:&amp;lt;/u&amp;gt;&lt;br /&gt;
** If you run &#039;&#039;&#039;Windows&#039;&#039;&#039; (2000,XP,Vista,7):&lt;br /&gt;
*** Here you can get a complete installer:&lt;br /&gt;
*** http://springfiles.com/spring/game-installers/kernel-panic-installer&lt;br /&gt;
*** Use it to install both Spring and Kernel Panic in one go.&lt;br /&gt;
*** Then use the shortcuts created in your Start Menu or Desktop.&lt;br /&gt;
** If you run &#039;&#039;&#039;Linux&#039;&#039;&#039;:&lt;br /&gt;
*** Read the [[SetupGuide]] how to install the Spring engine on Linux systems&lt;br /&gt;
*** Get and unzip that file: http://springfiles.com/spring/game-installers/kernel-panic-zip&lt;br /&gt;
*** Put the content of /games/ into ~/.spring/games&lt;br /&gt;
*** Put the content of /maps/ into ~/.spring/maps &lt;br /&gt;
*** Discard the rest.&lt;br /&gt;
*** Run Spring directly, a greenish menu should pop up.&lt;br /&gt;
*** Click skirmish, duel, easy, run.&lt;br /&gt;
*** For multiplayer or advanced options, run SpringLobby&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;u&amp;gt;Experienced Users:&amp;lt;/u&amp;gt;&lt;br /&gt;
** If you have already the Spring engine (or prefer to install it yourself): Here you can get a zip with the mod file, the maps, and a tiny exe for single player frontend. Unzip into your Spring root folder: http://springfiles.com/spring/game-installers/kernel-panic-zip&lt;br /&gt;
** If you are certain you have all the maps and just need a quick link to the mod file itself: http://springfiles.com/spring/games/kernel-panic-mod&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Media:==&lt;br /&gt;
&lt;br /&gt;
===Youtube Videos:===&lt;br /&gt;
&lt;br /&gt;
[http://youtube.com/watch?v=doF7owZ0blk&amp;amp;fmt=18 http://i.ytimg.com/vi/doF7owZ0blk/default.jpg] &lt;br /&gt;
[http://youtube.com/watch?v=Ug1c19yaZac http://i.ytimg.com/vi/Ug1c19yaZac/default.jpg] [http://youtube.com/watch?v=GAZQhRlt5bU http://i.ytimg.com/vi/GAZQhRlt5bU/default.jpg]&lt;br /&gt;
[http://www.youtube.com/watch?v=3q48ys5hFtI&amp;amp;fmt=18 http://i.ytimg.com/vi/3q48ys5hFtI/default.jpg]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
===Still shots:===&lt;br /&gt;
&lt;br /&gt;
[http://img228.imageshack.us/img228/6554/kernelpanicdirectmemoryoe1.jpg http://img228.imageshack.us/img228/6554/kernelpanicdirectmemoryoe1.th.jpg] [http://img231.imageshack.us/img231/1598/kernelpanicdirectmemoryob8.jpg http://img231.imageshack.us/img231/1598/kernelpanicdirectmemoryob8.th.jpg] [http://img223.imageshack.us/img223/3379/kernelpanicmajormadnesswn6.jpg http://img223.imageshack.us/img223/3379/kernelpanicmajormadnesswn6.th.jpg] [http://img223.imageshack.us/img223/3757/kernelpanicspeedballs16tm1.jpg http://img223.imageshack.us/img223/3757/kernelpanicspeedballs16tm1.th.jpg] [http://img231.imageshack.us/img231/5962/kernelpanickdr8z1scr6nn7.jpg http://img231.imageshack.us/img231/5962/kernelpanickdr8z1scr6nn7.th.jpg] [http://img143.imageshack.us/img143/2093/kernelpanicdigitaldividhq1.jpg http://img143.imageshack.us/img143/2093/kernelpanicdigitaldividhq1.th.jpg] &lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==License:==&lt;br /&gt;
Extracted from the &amp;lt;code&amp;gt;Kernel_Panic_readme.txt&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
========--------------------------------------------&lt;br /&gt;
License:&lt;br /&gt;
--------&lt;br /&gt;
- The content of the /games/Kernel*.sd7 is Public Domain, save:&lt;br /&gt;
  /LuaUI/Widgets/kp_buildbar.lua&lt;br /&gt;
  /LuaRules/Gadgets/autohold.lua&lt;br /&gt;
  /LuaRules/Gadgets/Burrow.lua&lt;br /&gt;
  /LuaRules/Gadgets/game_spawn.lua&lt;br /&gt;
  which are GPL, taken from http://www.caspring.org or http://springrts.com&lt;br /&gt;
- The maps Marble Madness and Direct Memory Access are Public Domain&lt;br /&gt;
- The maps Major Madness and Speed Balls 16 Way status are unknown&lt;br /&gt;
- The maps Central Hub, Corrupted Core, Dual Core, Quad Core were initially CC BY-NC-SA.&lt;br /&gt;
  Then the author removed the CC cause ( http://cpc.cx/4u3 )&lt;br /&gt;
- The Spring engine is GPL, available from http://spring.clan-sy.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== AIs and Game Modes:==&lt;br /&gt;
You can read a description of what they do here: http://www.springinfo.info/?p=681&lt;br /&gt;
----&lt;br /&gt;
==Units and Buildings:==&lt;br /&gt;
&lt;br /&gt;
===System units:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img256.imageshack.us/img256/1126/96x96kernelzu8.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Kernel:&#039;&#039;&#039; You start with one of these. It can build all mobile units in the game. Has rapid auto-heal and lots of health.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img209.imageshack.us/img209/1599/96x96socketnl5.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Socket:&#039;&#039;&#039; The socket is a factory which can only be built on a geothermal vent. It can solely build bits, and slower than the kernel can. It autoheals, and has a decent amount of health.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img88.imageshack.us/img88/9685/96x96terminalab6.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Terminal:&#039;&#039;&#039;(only available in Division Zero) This is a new structure that gets placed on geovents. It can dispatch a nuclear bomber once every 90 seconds that will deal about 16000 damage to a large target area, i.e. it destroys everything except factories. It does much less damage to the kernel and hole. The bomber can strike any position on the map, there is no defense.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img267.imageshack.us/img267/3489/96x96assemblerdt2.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Assembler:&#039;&#039;&#039; The assembler is a construction unit. It can build sockets, but it cannot assist-build. Slow, little health. Equipped with a radar to detect mines and other cloacked units.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img214.imageshack.us/img214/5237/96x96bitsn1.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Bit:&#039;&#039;&#039; Your basic attacking unit. Cheap, fast, small, not very much health. Is armed with a SPARCling laser. Can be built by a kernel or a socket.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img214.imageshack.us/img214/1451/96x96byteum3.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Byte:&#039;&#039;&#039; A large, strong, and slow attacking unit. Can holds it&#039;s own against many bits, as it has lots of health and a powerful gun. More armored when closed. Can plow through bad blocks. The byte has an alternate firing mode, the mine launcher, which throws 5 mines at the cost of much health.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img256.imageshack.us/img256/9260/96x96pointerfk5.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Pointer:&#039;&#039;&#039; An artillery unit. Its normal shot is not so useful against moving units, but can kill kernels and sockets pretty quickly. Is slow and has little health, so it needs protection. The pointer has an alternate firing mode, the NX Flag, which set a wide area ablaze for a minute, causing constant damage to all units, or buildings within it&#039;s range.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Hacker units:===&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img222.imageshack.us/img222/2233/96x96newholelowvp3.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Security Hole:&#039;&#039;&#039; The Hacker kernel equivalent.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img220.imageshack.us/img220/2663/96x96windowxr7.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Window:&#039;&#039;&#039; The Hacker socket equivalent.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img90.imageshack.us/img90/1047/96x96obeliskze5.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Obelisk:&#039;&#039;&#039; This building is a stationary artillery weapon, it can fire an infection shot every 40 seconds (the obelisk has a pink fire on top when it&#039;s ready to shoot) that will cover a large area in poison. The poison does a bit of damage (about 1000) and turns any enemy that dies inside the cloud into a Virus. The weapon&#039;s range is fairly limited. Best used against stationnary herds of Bits/Bugs.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img222.imageshack.us/img222/7033/96x96newtrojanlt6.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Trojan:&#039;&#039;&#039; This unit is your constructor as well as radar platform (needed for detecting mines and cloaked units), just like the assembler. It builds all the same stuff as the assembler, except it has the window instead of the socket and the obelisk instead of the terminal.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img88.imageshack.us/img88/3961/96x96viruslg6.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Virus:&#039;&#039;&#039; A crappy little swarm unit. It cannot be built but is produced when killing enemy units with certain weapons. Namely, the Virus, the Worm, and the Obelisk.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img230.imageshack.us/img230/1895/96x96newbugjw5.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Bug:&#039;&#039;&#039; The Hacker spam unit. The Bug is weaker than the Bit but can sense movement outside of its LOS. It has a stronger weapon and more range but cannot shoot at things behind it or through friendly units and won&#039;t take much damage before dying. The mine ability of the old bug has been removed. Instead it can now morph into the Exploit with the deploy button, or the bombard button.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img222.imageshack.us/img222/2277/96x96exploitjb7.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Exploit:&#039;&#039;&#039; This is the new name for the bug cannon. It&#039;s a building the Bug morphs into with the deploy or bombard command. The Exploit is a stationary artillery emplacement that does more damage the further the target is away. Even more frail than the Bug, so don&#039;t let any foe come near.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img220.imageshack.us/img220/3277/96x96newwormpv5.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Worm:&#039;&#039;&#039; The worm is a sneaky assassin, travelling cloacked, then surfacing only to kill many bits at once with its large area of effect weapon, which turn any slain units into virus. The worm large splash damage will damage your own units. However, it does practicaly no damage against other worms or virus. When cloacked, the worm does not automatically attack, you have to give attack orders manually. If you&#039;d rather have your worms auto-attack even when cloacked, set autohold to off. The autohold setting of new worms is inherited from the Security Hole.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img86.imageshack.us/img86/6420/96x96dosxp1.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Denial of Service:&#039;&#039;&#039; Not an artillery, but close: fire a beam that stun units. For bigger targets it&#039;ll take longer to stun them so perform a DDoS (use multiple) to stun them fast. Once the DoS stops firing the target will quickly unfreeze. It moves faster than the pointer but causes a particle trail that can be seen from far away.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Network units:===&lt;br /&gt;
The network faction is built around mobility, its small factories (Ports) don&#039;t produce units openly but instead increment a virtual counter (the Buffer). Packets in the Buffer can be materialized at any teleporter unit (currently that means the Port and the Connection), it&#039;s also possible to dematerialize the Packets back into the Buffer by making them enter a teleport.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img146.imageshack.us/img146/2470/96x96carrierll0.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Carrier:&#039;&#039;&#039; The base building, like a Kernel or Security Hole.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img292.imageshack.us/img292/6262/96x96portto5.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Port:&#039;&#039;&#039; The production building. It puts Packets into the Buffer, to materialize them select the Dispatch command. Dispatch will send 12 Packets if available, you can hold ALT when giving the order to make the Port dispatch until the Buffer is empty.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img167.imageshack.us/img167/5972/96x96firewallqj4.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Firewall:&#039;&#039;&#039; This building can cover units (affects friendly units in a certain radius around the target location) in a protective shield for 20 seconds. The shield halves all damage the unit receives and throws the other half back at the attacker.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img30.imageshack.us/img30/9761/96x96gateway.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Gateway:&#039;&#039;&#039; The constructor. It is lightly armed to help against enemy raids.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img233.imageshack.us/img233/3282/96x96packetnn1.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Packet:&#039;&#039;&#039; The basic light spam unit, it&#039;s weaker in combat than both competitors but much faster.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img233.imageshack.us/img233/7595/96x96connectionfz5.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Connection:&#039;&#039;&#039; Mostly a mobile teleporter (i.e. can dispatch Packets and let them enter like a Port). The Connection has decent armor and an arc beam that can do a lot of damage to single targets and has good range. It can defeat most large units one on one but engaging Bytes will probably result in pointer fire which the Connection cannot withstand and the arc beam is not optimal for engaging swarms.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img233.imageshack.us/img233/598/96x96flowml4.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;Flow:&#039;&#039;&#039; An air unit. The Flow moves fairly slowly but can of course cross any terrain. It&#039;s equipped to attack light targets (spam units and fire support) but it&#039;s highly vulnerable to return fire. If you want to use them in open combat give them a meatshield and hope the enemy doesn&#039;t field long range units, Pointers, DoSes and Connections make short work of Flows if they hit.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===All side Units:===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img266.imageshack.us/img266/7149/96x96badblockee7.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Bad Block:&#039;&#039;&#039; A tiny wall, built by Assembler/Trojan/Gateway. Blocks small units movement. Do not block shots however. Easily removed by the Debug or simply crushing them with a Byte or Connection.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img516.imageshack.us/img516/3648/96x96minelk9.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Logic Bomb:&#039;&#039;&#039; A mine that can be built by the Assembler/Trojan/Gateway. And also launched by Bytes since Div0 2.2. It takes out Bits &amp;amp; Bugs in a single blow, has a decent damage radius, and doesn&#039;t chain explode. Use with care, as the blast hurts your own units too. Limited to 32.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&amp;lt;td&amp;gt;http://img37.imageshack.us/img37/9901/96x96mineblaster.png&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&#039;&#039;&#039;The Debug:&#039;&#039;&#039; An easy way to clear an area of all mines and walls, this is a one shot weapon built by the Assembler/Trojan/Gateway.&amp;lt;/td&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Playing Guide for System:==&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
Attention all editors: Try and improve this playing guide to make less assumptions about the setup, and allow for team maps, larger maps, and generally teach more general strategy &lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Playing Kernel Panic is fairly simple and quickly learned, but can be hard to master and can be very complex. It is recommended that beginners start with play the System faction, as they can be considered the least &amp;quot;gimmicky&amp;quot; of the factions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
Maybe it might be a good idea to move this to after the next two paragraphs.&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
One rather effective general strategy for a duel on small maps is to send three to five bits to destroy your enemy&#039;s early game units, and, to a lesser degree, for scouting purposes. This is most effective if they started with construction units, as this will likely cripple their plans for an early expansion, and gives you a slight head start. After the initial attack, if your scouting shows that your enemy started with offensive units, build a byte for defense, and place it between your Kernel and the hill. After that, build an assembler and use it to build a socket on one the three closest building locations, which should automatically start producing bits. After this, you should order your assembler to build more sockets on free spots close to it. It is crucial that all sockets&#039; rally points are below them, as bits turning inside a socket will stall production until it is able to exit the factory. It is sometimes wise to repeat the prior process with one or two other assemblers. After this is done, construct about ten bits from your factor, and set your kernel to alternate between building bytes and pointers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
 A section on the uses of the faction&#039;s special units, and buildings (sigterm, pointer&#039;s fire, and byte&#039;s mine layer) could be useful, and these paragraphs might need modification.&lt;br /&gt;
&lt;br /&gt;
Making them flow better, and more coherent will help.&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
What units you build at your kernel, and what you use them for, is an important factor in winning. As buildings can&#039;t be resumed, sending in groups of bits to kill construction units creating buildings can be very effective at stopping expansion attempts. Building too many pointers, will result in them being destroyed by connections, bits and especially worms, due to their stealth. Also, bytes are easily destroyer by and pointers, and exploits. A good general purpose ratio seems to be to queue one byte and one pointer, but this will need adapting as the game develops, and depending on the enemy&#039;s play style. &lt;br /&gt;
&lt;br /&gt;
Scouting is important too, as many enemies will leave their factories undefended, and knowing their build, and general unit use can help you in adapting the units you use to better fight them. Note that the Network can instantly spawn packets at any of their ports, or connections with their buffer system, meaning that all their factories should be considered defended. Single bits can be used to scout to find the enemy&#039;s current expansion attempts. &lt;br /&gt;
&lt;br /&gt;
When attacking a Byte or Connection with bits, it is important to overwhelm it with large numbers of bits. For bytes, try to exploit a byte&#039;s blind spot directly under it, by moving bits into that area. If your byte is under attack, moving it backwards to keep the attacking units in it&#039;s shooting arc can help repel the attack. It is not recommended to engage a worm with bits, as it&#039;s attack will convert your bits to viruses on the worm&#039;s owner&#039;s side.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
Might reposition this section. Feel free to add map specific paragraphs for other maps as well. In fact, this will be very helpful to newcomers, I bet.&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
On Marble Madness, there are two main ways paths to victory. The simplest one is to control the hill and use pointers stationed on the hill to destroy the enemy&#039;s factories, and kernel. Gaining control of the hilltop will likely not be without resistance, because it requires a decent amount of time for units to reach the top of the hill, meaning most units involved will be spam units from your factories on it, and the fact that it will likely be highly contended. However, if you control it, you have a large advantage over the enemy as you can shell your opponents home base with ease. The other way is around the hill, which can be very effective if you control terrain you can use pointers to great effect. In both strategies, using pointers is the crucial factor. While they are hard to use correctly, they are game-winners as they destroy home bases and enemy units with ease.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Credits:==&lt;br /&gt;
- Original concept by Boirunner&amp;lt;br&amp;gt;&lt;br /&gt;
- About all the work done by KDR_11k&amp;lt;br&amp;gt;&lt;br /&gt;
- Sounds by Noruas&amp;lt;br&amp;gt;&lt;br /&gt;
- Minor edits by zwzsg&amp;lt;br&amp;gt;&lt;br /&gt;
- Maps by Boirunner, Runecrafter, zwzsg, and TradeMark&amp;lt;br&amp;gt;&lt;br /&gt;
- Some LUA interface upgrade based of jK and trepan code&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Back to [[Games]]&lt;br /&gt;
[[Category:Games]]&lt;/div&gt;</summary>
		<author><name>Bla</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=AI:Development:Lang:Java&amp;diff=642</id>
		<title>AI:Development:Lang:Java</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=AI:Development:Lang:Java&amp;diff=642"/>
		<updated>2014-05-15T16:03:06Z</updated>

		<summary type="html">&lt;p&gt;Bla: /* Telling the commander to build the solar plant */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[AI:Development|AI Development]] &amp;lt; Java AI Development&lt;br /&gt;
&lt;br /&gt;
== Getting Started on your own Java AI ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; This tutorial assumes you have Spring working on your machine. The Spring directory will be referred to as &#039;Spring&#039; from here on.&lt;br /&gt;
&lt;br /&gt;
You will also need to make sure that Java AI&#039;s run properly on your machine. This is most easily done by running a Spring game with the &#039;&#039;NullOOJavaAI&#039;&#039; that comes with the engine. You will need the JRE 1.5 or greater, and to set the &#039;&#039;JAVA_HOME&#039;&#039; environment variable on your system to point to the correct location.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; if you&#039;re using a &#039;&#039;64 bit&#039;&#039; version of &#039;&#039;Windows&#039;&#039;, you will need a 32 bit Java Runtime Environment/Java Development Kit anyway, because Spring is (as of July 2012) not yet available as a 64bit version for Windows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setting up a Java Project ===&lt;br /&gt;
&lt;br /&gt;
To start working on your own Java AI, you should first set up a project in your favorite Java IDE. You need to import the Spring Java AI Interface libraries, and then create an AI class and an AI Factory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OUTDATED&#039;&#039;&#039; If you are using &#039;&#039;&#039;Netbeans IDE&#039;&#039;&#039;, you can find a detailed tutorial [http://springrts.com/phpbb/download/file.php?id=4970 here] (from [http://springrts.com/phpbb/viewtopic.php?p=448743#p448743 this forum thread]). Otherwise, please continue reading this page.&lt;br /&gt;
&lt;br /&gt;
==== Importing the interface libraries ====&lt;br /&gt;
&lt;br /&gt;
In order to use the Java Interface, you will need to import the Java Interface libraries, located in &#039;&#039;Spring/AI/Interfaces/Java/[version]/&#039;&#039;. Replace &#039;&#039;[version]&#039;&#039; with the number of the latest Java Interface version. As of this writing, only &#039;&#039;0.1&#039;&#039; is available.&lt;br /&gt;
&lt;br /&gt;
The file you need is &#039;&#039;AIInterface.jar&#039;&#039;. You also need the additional library &#039;&#039;vecmath.jar&#039;&#039;, located in the &#039;&#039;jlib/&#039;&#039; subfolder. Optionally, you can attach the file &#039;&#039;AIInterface-src.jar&#039;&#039; as source to the &#039;&#039;AIInterface.jar&#039;&#039; file for JavaDoc support in your editor.&lt;br /&gt;
&lt;br /&gt;
Your project should now contain the following libraries:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Spring/AI/Interfaces/Java/[version]/AIInterface.jar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Spring/AI/Interfaces/Java/[version]/jlib/AIInterface-src.jar&amp;lt;/code&amp;gt; (optional)&lt;br /&gt;
* &amp;lt;code&amp;gt;Spring/AI/Interfaces/Java/[version]/jlib/vecmath.jar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Creating the required classes ====&lt;br /&gt;
&lt;br /&gt;
Now that you have the libraries, the next step is to create your AI&#039;s main class. Firstly, you may want to create a package to put your classes in, for example, &#039;&#039;myjavaai&#039;&#039;. Create a new class, named MyJavaAI (or whatever you would like your AI to be called). MyJavaAI should extend com.springrts.ai.oo.AbstractOOAI. After that you&#039;ll need another class, named &#039;&#039;MyJavaAIFactory&#039;&#039;. This class should extend &#039;&#039;com.springrts.ai.oo.OOAIFactory&#039;&#039;.&lt;br /&gt;
The class MyJavaAIFactory only has to implement a single method: &#039;&#039;public OOAI createAI(int teamId, OOAICallback callback)&#039;&#039;. This is the method that the Java interface calls to get an instance of your AI. If you wanted to, you could create a different AI depending on circumstances, but for now it is probably easiest to simply return a new MyJavaAI(), until you decide you require something more elaborate.&lt;br /&gt;
You should now have two classes, &#039;&#039;myjavaai.MyJavaAI&#039;&#039; and &#039;&#039;myjavaai.MyJavaAIFactory&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding your AI to Spring ===&lt;br /&gt;
&lt;br /&gt;
Your AI needs to have its own folder, and the engine will need to know your AI&#039;s attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Creating an AI folder ====&lt;br /&gt;
&lt;br /&gt;
Every Spring AI is stored in &#039;&#039;Spring/AI/Skirmish&#039;&#039;. You will have to create a folder for your AI as well. It is easiest to go to the directory &#039;&#039;Spring/AI/Skirmish&#039;&#039;, make a copy of the folder &#039;&#039;NullOOJavaAI&#039;&#039;, and rename the copy to &#039;&#039;MyJavaAI&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Telling the Engine about your AI ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;MyJavaAI&#039;&#039; folder you created contains the different versions of your AI. As of this writing, the &#039;&#039;NullOOJavaAI&#039;&#039; only has a version &#039;&#039;0.1&#039;&#039;, so there should be a folder &#039;&#039;0.1&#039;&#039; inside the &#039;&#039;MyJavaAI&#039;&#039; folder. Inside you will find a number of files.&lt;br /&gt;
These files are:&lt;br /&gt;
* &#039;&#039;SkirmishAI.jar&#039;&#039;: the jar file that contains the AI code.&lt;br /&gt;
* &#039;&#039;AIInfo.lua&#039;&#039;: contains information about the AI.&lt;br /&gt;
* &#039;&#039;AIOptions.lua&#039;&#039;: you can specify your AI&#039;s options in here.&lt;br /&gt;
* Possibly some text files: these are log files generated by the &#039;&#039;NullOOJavaAI&#039;&#039;. If you don&#039;t plan on using the same files, you may as well delete these.&lt;br /&gt;
&lt;br /&gt;
Additionally, there is a folder named &#039;&#039;jlib&#039;&#039;. This is where you should place any additional libraries you use in your AI.&lt;br /&gt;
&lt;br /&gt;
In order to let Spring recognize your AI, you will have to edit &#039;&#039;AIInfo.lua&#039;&#039;. You can do this with any regular text editor.&lt;br /&gt;
When you open it, the file will look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
local infos = {&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;shortName&#039;,&lt;br /&gt;
      value  = &#039;NullOOJavaAI&#039;,&lt;br /&gt;
      desc   = &#039;machine conform name.&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;version&#039;,&lt;br /&gt;
      value  = &#039;0.1&#039;, -- AI version - !This comment is used for parsing!&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;className&#039;,&lt;br /&gt;
      value  = &#039;nulloojavaai.NullOOJavaAIFactory&#039;,&lt;br /&gt;
      desc   = &#039;fully qualified name of a class that implements interface com.springrts.ai.AI&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;name&#039;,&lt;br /&gt;
      value  = &#039;high-level Java stub Skirmish AI&#039;,&lt;br /&gt;
      desc   = &#039;human readable name.&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;loadSupported&#039;,&lt;br /&gt;
      value  = &#039;no&#039;,&lt;br /&gt;
      desc   = &#039;whether this AI supports loading or not&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;interfaceShortName&#039;,&lt;br /&gt;
      value  = &#039;Java&#039;, -- AI Interface name - !This comment is used for parsing!&lt;br /&gt;
      desc   = &#039;the shortName of the AI interface this AI needs&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;interfaceVersion&#039;,&lt;br /&gt;
      value  = &#039;0.1&#039;, -- AI Interface version - !This comment is used for parsing!&lt;br /&gt;
      desc   = &#039;the minimum version of the AI interface required by this AI&#039;,&lt;br /&gt;
   },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return infos&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The file describes a number of attributes. Each attribute has a key, a value and a desc(ription). The key is the name of the attribute, the description tells you what the attribute is used for, and the value is what you will want to edit.&lt;br /&gt;
&lt;br /&gt;
The shortName attribute is the name used for your AI internally. It&#039;s most logical to change this into to the same name you gave your AI class. (MyJavaAI.)&lt;br /&gt;
&lt;br /&gt;
&#039;version&#039; tells the engine which version of your AI this is. If you&#039;re in the 0.1 folder, make this 0.1. Your AI should be located at AI/Skirmish/&#039;&#039;shortName&#039;&#039;/&#039;&#039;version&#039;&#039;/.&lt;br /&gt;
&lt;br /&gt;
&#039;classname&#039; tells the interface which class is your AIFactory class. Take care that you use the fully qualified class name, or it won&#039;t work. In this example, this should be myjavaai.MyJavaAIFactory.&lt;br /&gt;
&lt;br /&gt;
&#039;name&#039; describes your AI to the user. In this example, you might put &#039;A simple Java AI to learn about AI programming in Spring.&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;loadSupported&#039; is rather self-explanatory. Since you have just started working on your AI, you may not get around to implementing loading support for some time, so it&#039;s best to put &#039;no,&#039; for now.&lt;br /&gt;
&lt;br /&gt;
&#039;interfaceShortName&#039; and &#039;interfaceversion&#039; tell the engine about the interface your AI uses. Since MyJavaAI uses the same interface as the NullOOJavaAI, leave these as they are.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, the last thing you should do is exporting your AI to SkirmishAI.jar. The way to do this varies depending on your Java editor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test your AI ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After following all the above steps, you should be able to run your AI. Either use SpringLobby to start a new game and see if you can add your AI as a bot, or run &#039;&#039;spring.exe&#039;&#039; to see if you can start the script MyJavaAI Test.&lt;br /&gt;
Of course, since you haven&#039;t told the AI what to do, your starting unit(s) will sit there doing nothing.&lt;br /&gt;
&lt;br /&gt;
== Getting your AI to Do Something ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After getting your AI running, you will want to make it do something. Traditionally, the first thing to get your AI to is to build a solar plant, assuming you want it to play BA. If not, it is quite straightforward to build other units once you have the general idea.&lt;br /&gt;
You will need four things to get your AI to build a solar plant:&lt;br /&gt;
* A reference to the callback&lt;br /&gt;
* A reference to the commander (your starting unit in BA)&lt;br /&gt;
* A reference to the solar plant definition object&lt;br /&gt;
* To tell the commander to build the solar plant&lt;br /&gt;
&lt;br /&gt;
However, before we go about building solar plants, first you should know about events. We will use these to get the required object references.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
&lt;br /&gt;
Nearly everything that happens in the game is an event. When a unit is created, this is an event. Enemy spotted? Also an event. A player sends your AI a message? You got it, this is an event as well.&lt;br /&gt;
&lt;br /&gt;
Every event is made known to your AI. Have a look at the &amp;lt;code&amp;gt;MyJavaAI&amp;lt;/code&amp;gt; class again. &amp;lt;code&amp;gt;MyJavaAI&amp;lt;/code&amp;gt; extends &amp;lt;code&amp;gt;AbstractOOA&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;AbstractOOAI&amp;lt;/code&amp;gt; implements a number of methods like &amp;lt;code&amp;gt;unitCreated()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;enemyEnterRadar()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;message()&amp;lt;/code&amp;gt;.&lt;br /&gt;
Sound familiar? The method &amp;lt;code&amp;gt;unitCreated(Unit unit, Unit builder)&amp;lt;/code&amp;gt; is called every time a unit is created, and tells you the unit that was created and the unit that built it. Similarly, enemyEnterRadar(Unit enemy) and message(int player, String message) tell you about an enemy unit entering radar range and receiving a message from another player respectively.&lt;br /&gt;
There are many other events that all have corresponding methods. To have your AI respond to these events, simply override the method in your &amp;lt;code&amp;gt;MyJavaAI&amp;lt;/code&amp;gt; class.&lt;br /&gt;
The return type of these methods is an integer. The return value can be used for debugging. 0 means that no errors occurred, while any other value is threated as an error. This system can be used for debugging, but is it much easier to implement proper logging.&lt;br /&gt;
&lt;br /&gt;
In the sections below you will see an example of the use of these events.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Getting a reference to the callback ===&lt;br /&gt;
&lt;br /&gt;
The callback is the object through which the AI communicates with the engine. All information that does not change the state of the engine can be retrieved through individual methods in the callback, and state changing commands (eg to units) will go through a single, specialized method, which is in the callback as well.&lt;br /&gt;
Getting a reference to the callback is easy.&lt;br /&gt;
First create a class field &amp;lt;code&amp;gt;OOAICallback callback&amp;lt;/code&amp;gt; to put the reference in, then overwrite the method &amp;lt;code&amp;gt;init(int teamId, OOAICallback callback)&amp;lt;/code&amp;gt;. The init method is called at the start of every game (right at the end of the countdown).&lt;br /&gt;
As you can see, all that you need to do is set the parameter value callback to the field callback:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int init(int teamId, OOAICallback callback)&lt;br /&gt;
{&lt;br /&gt;
    this.callback = callback;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Getting a reference to the commander ===&lt;br /&gt;
&lt;br /&gt;
In order to have your AI build a solar plant, the first thing you need is a reference to your commander. You first need an instance field &#039;Unit commander&#039; to put the reference in, then we need to get the reference itself.&lt;br /&gt;
A UnitFinished event is triggered whenever a unit has been built. (This may sound similar to &amp;lt;code&amp;gt;unitCreated()&amp;lt;/code&amp;gt;. For a quick explanation of the difference, see the FAQ below.)&lt;br /&gt;
At the start of the game, the engine will send a UnitFinished event for every starting unit. When playing BA, this means you will get a UnitFinished event for the commander. Therefore, the most straightforward way of finding the reference to the commander is overriding the &amp;lt;code&amp;gt;unitFinished()&amp;lt;/code&amp;gt; method. &lt;br /&gt;
&lt;br /&gt;
To get a reference to the commander, you need to check if the unit is indeed the command, and if so, assign the value of the unit parameter to the commander field:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int unitFinished(Unit unit)&lt;br /&gt;
{&lt;br /&gt;
    if (unit.getDef().getName().equals(&amp;quot;armcom&amp;quot;))&lt;br /&gt;
        this.commander = unit;&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Getting a reference to the solar plant definition ===&lt;br /&gt;
&lt;br /&gt;
Every unit in Spring has a UnitDef (a &#039;unit defintion&#039;). This object tells you all there is to know about the properties of the unit type, such as maximum speed, turn rate and what weapons it carries.&lt;br /&gt;
One way to get the reference to the definition of a solar plant is to use &amp;lt;code&amp;gt;callback.getUnitDefs()&amp;lt;/code&amp;gt;. This will give you a list of all the available unit types in the game that is currently being played.&lt;br /&gt;
The name of the unit def we are looking for is &#039;armsolar&#039;, so we can just iterate through the list and find the one named armsolar, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
List&amp;lt;UnitDef&amp;gt; unitDefs = this.callback.getUnitDefs();&lt;br /&gt;
UnitDef solarPlant = null;&lt;br /&gt;
for (UnitDef def : unitDefs)&lt;br /&gt;
   if (def.getName().equals(&amp;quot;armsolar&amp;quot;))&lt;br /&gt;
   {&lt;br /&gt;
       solarPlant = def;&lt;br /&gt;
       break;&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Telling the commander to build the solar plant ===&lt;br /&gt;
&lt;br /&gt;
Now, the only thing left to do is to tell the commander that we want it to build the solar plant, and where to place it. In short, we need to give the commander a build command.&lt;br /&gt;
&lt;br /&gt;
We want to give this command only once at the first frame of the game. For this we can use the &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; method, which is called at every frame of the game. All we need to do is overwrite the &amp;lt;code&amp;gt;update(int frame)&amp;lt;/code&amp;gt; method and give the command if the frame is 1. This results in the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int update(int frame)&lt;br /&gt;
{&lt;br /&gt;
    if (frame == 0)&lt;br /&gt;
    {&lt;br /&gt;
        // give command here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Giving a command is straightforward. All we need to do is to create the appropriate command object and pass it through the callback to the engine.&lt;br /&gt;
&lt;br /&gt;
EDIT: the command class is outdated and not included in the current oo wrapper. Commands are now given via the unit class. See: http://spring.abma.de/doc-Interface-JavaOO/com/springrts/ai/oo/clb/Unit.html&lt;br /&gt;
&lt;br /&gt;
The command we need to tell commander to build a solar plant is a &amp;lt;code&amp;gt;BuildUnitAICommand&amp;lt;/code&amp;gt;. This command takes a number of arguments:&lt;br /&gt;
&lt;br /&gt;
; Unit unit : the unit we want to give to order to&lt;br /&gt;
; int groupId : the group we want to give the order to&lt;br /&gt;
; List&amp;lt;AICommand.Option&amp;gt; optionsList : a list addional options. See the values of AICommand.Option for details&lt;br /&gt;
; int timeOut : the number of frames after which the command times out&lt;br /&gt;
; UnitDef toBuildUnitDef : the UnitDef of the unit we want to build&lt;br /&gt;
; AIFloat3 buildPos : the position to build the unit at&lt;br /&gt;
; int facing : the direction the new unit should face&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see above, we can give a command to either a single unit or a group of units. In this example we only have a single unit. This means that unit should be a reference to our commander, and &amp;lt;code&amp;gt;groupId&amp;lt;/code&amp;gt; should be -1.&lt;br /&gt;
To keep things simple, we will not use any options, set the timeout to a large number, and set facing to 0.&lt;br /&gt;
The value of &amp;lt;code&amp;gt;toBuildUnitDef&amp;lt;/code&amp;gt; should be the object reference stored int UnitDef solarPlant.&lt;br /&gt;
That only leaves &amp;lt;code&amp;gt;buildPos&amp;lt;/code&amp;gt;, for which we will just use the current position of our commander. This means that our &amp;lt;code&amp;gt;BuildUnitAICommand&amp;lt;/code&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int update(int frame)&lt;br /&gt;
{&lt;br /&gt;
    if (frame == 0)&lt;br /&gt;
    {&lt;br /&gt;
        AICommand command = new BuildUnitAICommand(this.commander, -1,&lt;br /&gt;
            new ArrayList&amp;lt;AICommand.Option&amp;gt;(), 10000, solarPlant,&lt;br /&gt;
            this.commander.getPos(), 0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we should give the command to the engine. We do this through the method &amp;lt;code&amp;gt;callback.getEngine().handleCommand()&amp;lt;/code&amp;gt;. This method takes three arguments: the id of the recipient of the command, a &amp;lt;code&amp;gt;commandID&amp;lt;/code&amp;gt; and the command itself.&lt;br /&gt;
The command should be sent to the engine, and for now we will use a &amp;lt;code&amp;gt;commandID&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;, as this is a feature which is not yet supported by spring (asynchronous command tracking).&lt;br /&gt;
Our code will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int update(int frame)&lt;br /&gt;
{&lt;br /&gt;
    if (frame == 0)&lt;br /&gt;
    {&lt;br /&gt;
        AICommand command = new BuildUnitAICommand(this.commander, -1,&lt;br /&gt;
            new ArrayList&amp;lt;AICommand.Option&amp;gt;(), 10000, solarPlant,&lt;br /&gt;
            this.commander.getPos(), 0);&lt;br /&gt;
&lt;br /&gt;
        this.callback.getEngine().handleCommand(AICommandWrapper.COMMAND_TO_ID_ENGINE,&lt;br /&gt;
            -1, command);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you will want to see if your AI actually works. Export your code to &#039;&#039;Spring/AI/Skirmish/MyJavaAI/SkirmishAI.jar&#039;&#039; and start up a game. Your AI should now build a solar plant at its start position.&lt;br /&gt;
&lt;br /&gt;
===Building a metal extractor===&lt;br /&gt;
Building a metal extractor is slightly more complicated. Assuming you&#039;re not on a metal map, you will need to find a suitable site to place the extractor. Generally, it&#039;s preferable to select a site closest to wherever your construction unit (commander) is located.&lt;br /&gt;
&lt;br /&gt;
Modify your code that got a reference to the solar plant by making the following changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
List&amp;lt;UnitDef&amp;gt; unitDefs = this.callback.getUnitDefs(); UnitDef solarPlant = null; for (UnitDef def : unitDefs)&lt;br /&gt;
&lt;br /&gt;
  if (def.getName().equals(&amp;quot;armsolar&amp;quot;))&lt;br /&gt;
  {&lt;br /&gt;
      solarPlant = def;&lt;br /&gt;
  }&lt;br /&gt;
  else if (def.getName().equals(&amp;quot;armmex&amp;quot;))&lt;br /&gt;
  {&lt;br /&gt;
       metalExtractor=def;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again, you will need to create a Unitdef metalExtractor field by where you declared your solarPlant field.&lt;br /&gt;
&lt;br /&gt;
Next, you need a method for determining the distance between two 3D coordinates (since Spring locations are three dimensional). A slightly modified version of a distance function is found below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public float calculateDistance(AIFloat3 a, AIFloat3 b)&lt;br /&gt;
    {&lt;br /&gt;
    float xDistance = a.x - b.x;&lt;br /&gt;
    float yDistance = a.y - b.y;&lt;br /&gt;
    float zDistance = a.z - b.z;&lt;br /&gt;
    float totalDistanceSquared = xDistance*xDistance + yDistance*yDistance + zDistance*zDistance;&lt;br /&gt;
    return totalDistanceSquared;&lt;br /&gt;
    } &lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code actually returns the distance squared, but it will work for our purposes. In your init function, you will want to add the following code above the return statement but below the line defining the callback:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
checkForMetal();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will call the following function you need to place in your code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public void checkForMetal()&lt;br /&gt;
    {&lt;br /&gt;
    Resource metal=Resource.getInstance(clb, 0);&lt;br /&gt;
    availablemetalspots=clb.getMap().getResourceMapSpotsPositions(metal);&lt;br /&gt;
    if(availablemetalspots.isEmpty())&lt;br /&gt;
        {&lt;br /&gt;
        sendTextMsg(&amp;quot;This is a map with no metal spots&amp;quot;);&lt;br /&gt;
        metalmap=false;&lt;br /&gt;
        }&lt;br /&gt;
    else&lt;br /&gt;
        {metalmap=true;&lt;br /&gt;
        sendTextMsg(&amp;quot;This is a map with metal spots. Listing Values...&amp;quot;);&lt;br /&gt;
        for (AIFloat3 metalspot : availablemetalspots) {&lt;br /&gt;
            sendTextMsg(&amp;quot;Metal Spot at X: &amp;quot;+metalspot.x + &amp;quot;, Y: &amp;quot;+metalspot.y +&amp;quot;, Z: &amp;quot;+metalspot.z);&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the above code to function properly, you will need to create a Boolean named metalmap and a List&amp;lt;AIFloat3&amp;gt; availablemetalspots. You will now have a function set up for calculating distance between two points, and a data structure holding a list of positions of metal spots. The next step is to tie these two together:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public AIFloat3 closestMetalSpot(AIFloat3 unitposition)&lt;br /&gt;
    {&lt;br /&gt;
    AIFloat3 closestspot=null;&lt;br /&gt;
    for (AIFloat3 metalspot : availablemetalspots) {&lt;br /&gt;
            if (closestspot==null)&lt;br /&gt;
                {&lt;br /&gt;
                closestspot=metalspot;&lt;br /&gt;
                }&lt;br /&gt;
        else if(calculateDistance(metalspot, unitposition) &amp;lt; calculateDistance(closestspot, unitposition) &amp;amp;&amp;amp; metalspot.hashCode()!=unitposition.hashCode())&lt;br /&gt;
                    {&lt;br /&gt;
                    closestspot=metalspot;&lt;br /&gt;
                    }&lt;br /&gt;
        }&lt;br /&gt;
    availablemetalspots.remove(closestspot);&lt;br /&gt;
    return closestspot;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function accepts an AIFloat3 containing the location of your construction unit (commander). It will then find the closest metal spot and return that location. The next step is to have your commander make use of this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
  if (frame == 600)&lt;br /&gt;
  {&lt;br /&gt;
       if(metalmap){       sendTextMsg(&amp;quot;About to build mex at frame &amp;quot; + frame);&lt;br /&gt;
       AIFloat3 closestspot=closestMetalSpot(commander.getPos());&lt;br /&gt;
       BuildUnitAICommand command2=new BuildUnitAICommand(this.commander, -1,&lt;br /&gt;
               new ArrayList&amp;lt;AICommand.Option&amp;gt;(), 10000,&lt;br /&gt;
               metalExtractor,closestspot, 0);&lt;br /&gt;
       handleEngineCommand(command2);}&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Place the above code in your update() method. When the frame count reaches 600, your commander will start to build a metal extractor at the closest metal spot. The extractor may not be right on top of where the metal spot appears to be, but you can mouse over the extractor to make sure it&#039;s drawing the metal properly.&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q:&#039;&#039;&#039; What is the difference between &amp;lt;code&amp;gt;unitCreated()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unitFinished()&amp;lt;/code&amp;gt;?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A:&#039;&#039;&#039; The difference is that &amp;lt;code&amp;gt;unitCreated()&amp;lt;/code&amp;gt; is called when construction of a unit starts, while &amp;lt;code&amp;gt;unitFinished()&amp;lt;/code&amp;gt; when construction on the unit has been completed. Any number of things may happen in-between, including the unit under construction being destroyed, so it is important to remember this distinction.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q:&#039;&#039;&#039; Do I have to copy and paste my jar file to the directory in Spring/AI/Skirmish/MyAI/0.1 each time I want to test my AI out?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A:&#039;&#039;&#039; Yes, but it is much easier if you automate the process. In Windows, a simple batch file can be created to move the files over for you. For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
copy C:\Users\msm8bball\Documents\NetBeansProjects\MyAI\dist\MyAI.jar &amp;quot;C:\Program Files (x86)\Spring\AI\Skirmish\MyAI\0.1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
del &amp;quot;C:\Program Files (x86)\Spring\AI\Skirmish\MyAI\0.1\SkirmishAI.jar&amp;quot;&lt;br /&gt;
rename &amp;quot;C:\Program Files (x86)\Spring\AI\Skirmish\MyAI\0.1\MyAI.jar&amp;quot; SkirmishAI.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modify the above code to match your computer&#039;s directories. Place it in a text file and save it as MoveAI.bat. This will create a batch file that you can double click and it will automatically move your AI to the proper location and rename it. You might wish to put a shortcut to this in your Start menu or taskbar. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q:&#039;&#039;&#039; I have problems with the class-loader in my AI, any idea? &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A:&#039;&#039;&#039; Each Java AI implementation is loaded by a separate class loader. This is used to load all the AI&#039;s class files and dependency libraries (in the &#039;&#039;jlib&#039;&#039; dir). Some libraries though, use the Thread contexts class loader, instead of the one of the current class. Therefore, if you want to load something from the AI&#039;s own class-path, make sure to let these libraries use the class-path of your AI classes, eg:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
ClassLoader myClassLoader = AIFactory.class.getClassLoader();&lt;br /&gt;
MySpecialUtil msp = new MySpecialUtil();&lt;br /&gt;
msp.setClassLoader(myClassLoader);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Please do not set this class-loader on the thread with &amp;lt;code&amp;gt;Thread.currentThread().setContextClassLoader(myClassLoader)&amp;lt;/code&amp;gt;, because all AI&#039;s are run in the same Java thread, and therefore this will cause problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [[AIInterface:Java|Java AI Interface]]&lt;br /&gt;
* [http://spring.abma.de/doc-Interface-JavaOO/ Javadoc of the Java AI OO Wrapper] (generated daily from source by [[User:Abma|abma]])&lt;br /&gt;
* &#039;&#039;&#039;OUTDATED&#039;&#039;&#039; [http://springrts.com/phpbb/download/file.php?id=4970 Netbeans Java Skirmish AI Tutorial] (from [http://springrts.com/phpbb/viewtopic.php?p=448743#p448743 this forum thread])&lt;br /&gt;
* [http://modinfo.adune.nl/index.php?MOD=ba712 ModInfo] (contains a list of units and their short names)&lt;br /&gt;
&lt;br /&gt;
[[Category: AI Dev]]&lt;/div&gt;</summary>
		<author><name>Bla</name></author>
	</entry>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=AI:Development:Lang:Java&amp;diff=641</id>
		<title>AI:Development:Lang:Java</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=AI:Development:Lang:Java&amp;diff=641"/>
		<updated>2014-05-15T16:02:21Z</updated>

		<summary type="html">&lt;p&gt;Bla: /* Telling the commander to build the solar plant */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Engine_Development|Development]] &amp;lt; [[AI:Development|AI Development]] &amp;lt; Java AI Development&lt;br /&gt;
&lt;br /&gt;
== Getting Started on your own Java AI ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; This tutorial assumes you have Spring working on your machine. The Spring directory will be referred to as &#039;Spring&#039; from here on.&lt;br /&gt;
&lt;br /&gt;
You will also need to make sure that Java AI&#039;s run properly on your machine. This is most easily done by running a Spring game with the &#039;&#039;NullOOJavaAI&#039;&#039; that comes with the engine. You will need the JRE 1.5 or greater, and to set the &#039;&#039;JAVA_HOME&#039;&#039; environment variable on your system to point to the correct location.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; if you&#039;re using a &#039;&#039;64 bit&#039;&#039; version of &#039;&#039;Windows&#039;&#039;, you will need a 32 bit Java Runtime Environment/Java Development Kit anyway, because Spring is (as of July 2012) not yet available as a 64bit version for Windows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setting up a Java Project ===&lt;br /&gt;
&lt;br /&gt;
To start working on your own Java AI, you should first set up a project in your favorite Java IDE. You need to import the Spring Java AI Interface libraries, and then create an AI class and an AI Factory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OUTDATED&#039;&#039;&#039; If you are using &#039;&#039;&#039;Netbeans IDE&#039;&#039;&#039;, you can find a detailed tutorial [http://springrts.com/phpbb/download/file.php?id=4970 here] (from [http://springrts.com/phpbb/viewtopic.php?p=448743#p448743 this forum thread]). Otherwise, please continue reading this page.&lt;br /&gt;
&lt;br /&gt;
==== Importing the interface libraries ====&lt;br /&gt;
&lt;br /&gt;
In order to use the Java Interface, you will need to import the Java Interface libraries, located in &#039;&#039;Spring/AI/Interfaces/Java/[version]/&#039;&#039;. Replace &#039;&#039;[version]&#039;&#039; with the number of the latest Java Interface version. As of this writing, only &#039;&#039;0.1&#039;&#039; is available.&lt;br /&gt;
&lt;br /&gt;
The file you need is &#039;&#039;AIInterface.jar&#039;&#039;. You also need the additional library &#039;&#039;vecmath.jar&#039;&#039;, located in the &#039;&#039;jlib/&#039;&#039; subfolder. Optionally, you can attach the file &#039;&#039;AIInterface-src.jar&#039;&#039; as source to the &#039;&#039;AIInterface.jar&#039;&#039; file for JavaDoc support in your editor.&lt;br /&gt;
&lt;br /&gt;
Your project should now contain the following libraries:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Spring/AI/Interfaces/Java/[version]/AIInterface.jar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Spring/AI/Interfaces/Java/[version]/jlib/AIInterface-src.jar&amp;lt;/code&amp;gt; (optional)&lt;br /&gt;
* &amp;lt;code&amp;gt;Spring/AI/Interfaces/Java/[version]/jlib/vecmath.jar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Creating the required classes ====&lt;br /&gt;
&lt;br /&gt;
Now that you have the libraries, the next step is to create your AI&#039;s main class. Firstly, you may want to create a package to put your classes in, for example, &#039;&#039;myjavaai&#039;&#039;. Create a new class, named MyJavaAI (or whatever you would like your AI to be called). MyJavaAI should extend com.springrts.ai.oo.AbstractOOAI. After that you&#039;ll need another class, named &#039;&#039;MyJavaAIFactory&#039;&#039;. This class should extend &#039;&#039;com.springrts.ai.oo.OOAIFactory&#039;&#039;.&lt;br /&gt;
The class MyJavaAIFactory only has to implement a single method: &#039;&#039;public OOAI createAI(int teamId, OOAICallback callback)&#039;&#039;. This is the method that the Java interface calls to get an instance of your AI. If you wanted to, you could create a different AI depending on circumstances, but for now it is probably easiest to simply return a new MyJavaAI(), until you decide you require something more elaborate.&lt;br /&gt;
You should now have two classes, &#039;&#039;myjavaai.MyJavaAI&#039;&#039; and &#039;&#039;myjavaai.MyJavaAIFactory&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding your AI to Spring ===&lt;br /&gt;
&lt;br /&gt;
Your AI needs to have its own folder, and the engine will need to know your AI&#039;s attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Creating an AI folder ====&lt;br /&gt;
&lt;br /&gt;
Every Spring AI is stored in &#039;&#039;Spring/AI/Skirmish&#039;&#039;. You will have to create a folder for your AI as well. It is easiest to go to the directory &#039;&#039;Spring/AI/Skirmish&#039;&#039;, make a copy of the folder &#039;&#039;NullOOJavaAI&#039;&#039;, and rename the copy to &#039;&#039;MyJavaAI&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Telling the Engine about your AI ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;MyJavaAI&#039;&#039; folder you created contains the different versions of your AI. As of this writing, the &#039;&#039;NullOOJavaAI&#039;&#039; only has a version &#039;&#039;0.1&#039;&#039;, so there should be a folder &#039;&#039;0.1&#039;&#039; inside the &#039;&#039;MyJavaAI&#039;&#039; folder. Inside you will find a number of files.&lt;br /&gt;
These files are:&lt;br /&gt;
* &#039;&#039;SkirmishAI.jar&#039;&#039;: the jar file that contains the AI code.&lt;br /&gt;
* &#039;&#039;AIInfo.lua&#039;&#039;: contains information about the AI.&lt;br /&gt;
* &#039;&#039;AIOptions.lua&#039;&#039;: you can specify your AI&#039;s options in here.&lt;br /&gt;
* Possibly some text files: these are log files generated by the &#039;&#039;NullOOJavaAI&#039;&#039;. If you don&#039;t plan on using the same files, you may as well delete these.&lt;br /&gt;
&lt;br /&gt;
Additionally, there is a folder named &#039;&#039;jlib&#039;&#039;. This is where you should place any additional libraries you use in your AI.&lt;br /&gt;
&lt;br /&gt;
In order to let Spring recognize your AI, you will have to edit &#039;&#039;AIInfo.lua&#039;&#039;. You can do this with any regular text editor.&lt;br /&gt;
When you open it, the file will look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
local infos = {&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;shortName&#039;,&lt;br /&gt;
      value  = &#039;NullOOJavaAI&#039;,&lt;br /&gt;
      desc   = &#039;machine conform name.&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;version&#039;,&lt;br /&gt;
      value  = &#039;0.1&#039;, -- AI version - !This comment is used for parsing!&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;className&#039;,&lt;br /&gt;
      value  = &#039;nulloojavaai.NullOOJavaAIFactory&#039;,&lt;br /&gt;
      desc   = &#039;fully qualified name of a class that implements interface com.springrts.ai.AI&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;name&#039;,&lt;br /&gt;
      value  = &#039;high-level Java stub Skirmish AI&#039;,&lt;br /&gt;
      desc   = &#039;human readable name.&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;loadSupported&#039;,&lt;br /&gt;
      value  = &#039;no&#039;,&lt;br /&gt;
      desc   = &#039;whether this AI supports loading or not&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;interfaceShortName&#039;,&lt;br /&gt;
      value  = &#039;Java&#039;, -- AI Interface name - !This comment is used for parsing!&lt;br /&gt;
      desc   = &#039;the shortName of the AI interface this AI needs&#039;,&lt;br /&gt;
   },&lt;br /&gt;
   {&lt;br /&gt;
      key    = &#039;interfaceVersion&#039;,&lt;br /&gt;
      value  = &#039;0.1&#039;, -- AI Interface version - !This comment is used for parsing!&lt;br /&gt;
      desc   = &#039;the minimum version of the AI interface required by this AI&#039;,&lt;br /&gt;
   },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return infos&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The file describes a number of attributes. Each attribute has a key, a value and a desc(ription). The key is the name of the attribute, the description tells you what the attribute is used for, and the value is what you will want to edit.&lt;br /&gt;
&lt;br /&gt;
The shortName attribute is the name used for your AI internally. It&#039;s most logical to change this into to the same name you gave your AI class. (MyJavaAI.)&lt;br /&gt;
&lt;br /&gt;
&#039;version&#039; tells the engine which version of your AI this is. If you&#039;re in the 0.1 folder, make this 0.1. Your AI should be located at AI/Skirmish/&#039;&#039;shortName&#039;&#039;/&#039;&#039;version&#039;&#039;/.&lt;br /&gt;
&lt;br /&gt;
&#039;classname&#039; tells the interface which class is your AIFactory class. Take care that you use the fully qualified class name, or it won&#039;t work. In this example, this should be myjavaai.MyJavaAIFactory.&lt;br /&gt;
&lt;br /&gt;
&#039;name&#039; describes your AI to the user. In this example, you might put &#039;A simple Java AI to learn about AI programming in Spring.&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;loadSupported&#039; is rather self-explanatory. Since you have just started working on your AI, you may not get around to implementing loading support for some time, so it&#039;s best to put &#039;no,&#039; for now.&lt;br /&gt;
&lt;br /&gt;
&#039;interfaceShortName&#039; and &#039;interfaceversion&#039; tell the engine about the interface your AI uses. Since MyJavaAI uses the same interface as the NullOOJavaAI, leave these as they are.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, the last thing you should do is exporting your AI to SkirmishAI.jar. The way to do this varies depending on your Java editor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Test your AI ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After following all the above steps, you should be able to run your AI. Either use SpringLobby to start a new game and see if you can add your AI as a bot, or run &#039;&#039;spring.exe&#039;&#039; to see if you can start the script MyJavaAI Test.&lt;br /&gt;
Of course, since you haven&#039;t told the AI what to do, your starting unit(s) will sit there doing nothing.&lt;br /&gt;
&lt;br /&gt;
== Getting your AI to Do Something ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After getting your AI running, you will want to make it do something. Traditionally, the first thing to get your AI to is to build a solar plant, assuming you want it to play BA. If not, it is quite straightforward to build other units once you have the general idea.&lt;br /&gt;
You will need four things to get your AI to build a solar plant:&lt;br /&gt;
* A reference to the callback&lt;br /&gt;
* A reference to the commander (your starting unit in BA)&lt;br /&gt;
* A reference to the solar plant definition object&lt;br /&gt;
* To tell the commander to build the solar plant&lt;br /&gt;
&lt;br /&gt;
However, before we go about building solar plants, first you should know about events. We will use these to get the required object references.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
&lt;br /&gt;
Nearly everything that happens in the game is an event. When a unit is created, this is an event. Enemy spotted? Also an event. A player sends your AI a message? You got it, this is an event as well.&lt;br /&gt;
&lt;br /&gt;
Every event is made known to your AI. Have a look at the &amp;lt;code&amp;gt;MyJavaAI&amp;lt;/code&amp;gt; class again. &amp;lt;code&amp;gt;MyJavaAI&amp;lt;/code&amp;gt; extends &amp;lt;code&amp;gt;AbstractOOA&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;AbstractOOAI&amp;lt;/code&amp;gt; implements a number of methods like &amp;lt;code&amp;gt;unitCreated()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;enemyEnterRadar()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;message()&amp;lt;/code&amp;gt;.&lt;br /&gt;
Sound familiar? The method &amp;lt;code&amp;gt;unitCreated(Unit unit, Unit builder)&amp;lt;/code&amp;gt; is called every time a unit is created, and tells you the unit that was created and the unit that built it. Similarly, enemyEnterRadar(Unit enemy) and message(int player, String message) tell you about an enemy unit entering radar range and receiving a message from another player respectively.&lt;br /&gt;
There are many other events that all have corresponding methods. To have your AI respond to these events, simply override the method in your &amp;lt;code&amp;gt;MyJavaAI&amp;lt;/code&amp;gt; class.&lt;br /&gt;
The return type of these methods is an integer. The return value can be used for debugging. 0 means that no errors occurred, while any other value is threated as an error. This system can be used for debugging, but is it much easier to implement proper logging.&lt;br /&gt;
&lt;br /&gt;
In the sections below you will see an example of the use of these events.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Getting a reference to the callback ===&lt;br /&gt;
&lt;br /&gt;
The callback is the object through which the AI communicates with the engine. All information that does not change the state of the engine can be retrieved through individual methods in the callback, and state changing commands (eg to units) will go through a single, specialized method, which is in the callback as well.&lt;br /&gt;
Getting a reference to the callback is easy.&lt;br /&gt;
First create a class field &amp;lt;code&amp;gt;OOAICallback callback&amp;lt;/code&amp;gt; to put the reference in, then overwrite the method &amp;lt;code&amp;gt;init(int teamId, OOAICallback callback)&amp;lt;/code&amp;gt;. The init method is called at the start of every game (right at the end of the countdown).&lt;br /&gt;
As you can see, all that you need to do is set the parameter value callback to the field callback:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int init(int teamId, OOAICallback callback)&lt;br /&gt;
{&lt;br /&gt;
    this.callback = callback;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Getting a reference to the commander ===&lt;br /&gt;
&lt;br /&gt;
In order to have your AI build a solar plant, the first thing you need is a reference to your commander. You first need an instance field &#039;Unit commander&#039; to put the reference in, then we need to get the reference itself.&lt;br /&gt;
A UnitFinished event is triggered whenever a unit has been built. (This may sound similar to &amp;lt;code&amp;gt;unitCreated()&amp;lt;/code&amp;gt;. For a quick explanation of the difference, see the FAQ below.)&lt;br /&gt;
At the start of the game, the engine will send a UnitFinished event for every starting unit. When playing BA, this means you will get a UnitFinished event for the commander. Therefore, the most straightforward way of finding the reference to the commander is overriding the &amp;lt;code&amp;gt;unitFinished()&amp;lt;/code&amp;gt; method. &lt;br /&gt;
&lt;br /&gt;
To get a reference to the commander, you need to check if the unit is indeed the command, and if so, assign the value of the unit parameter to the commander field:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int unitFinished(Unit unit)&lt;br /&gt;
{&lt;br /&gt;
    if (unit.getDef().getName().equals(&amp;quot;armcom&amp;quot;))&lt;br /&gt;
        this.commander = unit;&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Getting a reference to the solar plant definition ===&lt;br /&gt;
&lt;br /&gt;
Every unit in Spring has a UnitDef (a &#039;unit defintion&#039;). This object tells you all there is to know about the properties of the unit type, such as maximum speed, turn rate and what weapons it carries.&lt;br /&gt;
One way to get the reference to the definition of a solar plant is to use &amp;lt;code&amp;gt;callback.getUnitDefs()&amp;lt;/code&amp;gt;. This will give you a list of all the available unit types in the game that is currently being played.&lt;br /&gt;
The name of the unit def we are looking for is &#039;armsolar&#039;, so we can just iterate through the list and find the one named armsolar, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
List&amp;lt;UnitDef&amp;gt; unitDefs = this.callback.getUnitDefs();&lt;br /&gt;
UnitDef solarPlant = null;&lt;br /&gt;
for (UnitDef def : unitDefs)&lt;br /&gt;
   if (def.getName().equals(&amp;quot;armsolar&amp;quot;))&lt;br /&gt;
   {&lt;br /&gt;
       solarPlant = def;&lt;br /&gt;
       break;&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Telling the commander to build the solar plant ===&lt;br /&gt;
&lt;br /&gt;
Now, the only thing left to do is to tell the commander that we want it to build the solar plant, and where to place it. In short, we need to give the commander a build command.&lt;br /&gt;
&lt;br /&gt;
We want to give this command only once at the first frame of the game. For this we can use the &amp;lt;code&amp;gt;update()&amp;lt;/code&amp;gt; method, which is called at every frame of the game. All we need to do is overwrite the &amp;lt;code&amp;gt;update(int frame)&amp;lt;/code&amp;gt; method and give the command if the frame is 1. This results in the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int update(int frame)&lt;br /&gt;
{&lt;br /&gt;
    if (frame == 0)&lt;br /&gt;
    {&lt;br /&gt;
        // give command here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Giving a command is straightforward. All we need to do is to create the appropriate command object and pass it through the callback to the engine. EDIT: the command class is outdated and not included in the current oo wrapper. Commands are not given via the unit class. See: http://spring.abma.de/doc-Interface-JavaOO/com/springrts/ai/oo/clb/Unit.html&lt;br /&gt;
&lt;br /&gt;
The command we need to tell commander to build a solar plant is a &amp;lt;code&amp;gt;BuildUnitAICommand&amp;lt;/code&amp;gt;. This command takes a number of arguments:&lt;br /&gt;
&lt;br /&gt;
; Unit unit : the unit we want to give to order to&lt;br /&gt;
; int groupId : the group we want to give the order to&lt;br /&gt;
; List&amp;lt;AICommand.Option&amp;gt; optionsList : a list addional options. See the values of AICommand.Option for details&lt;br /&gt;
; int timeOut : the number of frames after which the command times out&lt;br /&gt;
; UnitDef toBuildUnitDef : the UnitDef of the unit we want to build&lt;br /&gt;
; AIFloat3 buildPos : the position to build the unit at&lt;br /&gt;
; int facing : the direction the new unit should face&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see above, we can give a command to either a single unit or a group of units. In this example we only have a single unit. This means that unit should be a reference to our commander, and &amp;lt;code&amp;gt;groupId&amp;lt;/code&amp;gt; should be -1.&lt;br /&gt;
To keep things simple, we will not use any options, set the timeout to a large number, and set facing to 0.&lt;br /&gt;
The value of &amp;lt;code&amp;gt;toBuildUnitDef&amp;lt;/code&amp;gt; should be the object reference stored int UnitDef solarPlant.&lt;br /&gt;
That only leaves &amp;lt;code&amp;gt;buildPos&amp;lt;/code&amp;gt;, for which we will just use the current position of our commander. This means that our &amp;lt;code&amp;gt;BuildUnitAICommand&amp;lt;/code&amp;gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int update(int frame)&lt;br /&gt;
{&lt;br /&gt;
    if (frame == 0)&lt;br /&gt;
    {&lt;br /&gt;
        AICommand command = new BuildUnitAICommand(this.commander, -1,&lt;br /&gt;
            new ArrayList&amp;lt;AICommand.Option&amp;gt;(), 10000, solarPlant,&lt;br /&gt;
            this.commander.getPos(), 0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we should give the command to the engine. We do this through the method &amp;lt;code&amp;gt;callback.getEngine().handleCommand()&amp;lt;/code&amp;gt;. This method takes three arguments: the id of the recipient of the command, a &amp;lt;code&amp;gt;commandID&amp;lt;/code&amp;gt; and the command itself.&lt;br /&gt;
The command should be sent to the engine, and for now we will use a &amp;lt;code&amp;gt;commandID&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;, as this is a feature which is not yet supported by spring (asynchronous command tracking).&lt;br /&gt;
Our code will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
@Override&lt;br /&gt;
public int update(int frame)&lt;br /&gt;
{&lt;br /&gt;
    if (frame == 0)&lt;br /&gt;
    {&lt;br /&gt;
        AICommand command = new BuildUnitAICommand(this.commander, -1,&lt;br /&gt;
            new ArrayList&amp;lt;AICommand.Option&amp;gt;(), 10000, solarPlant,&lt;br /&gt;
            this.commander.getPos(), 0);&lt;br /&gt;
&lt;br /&gt;
        this.callback.getEngine().handleCommand(AICommandWrapper.COMMAND_TO_ID_ENGINE,&lt;br /&gt;
            -1, command);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point you will want to see if your AI actually works. Export your code to &#039;&#039;Spring/AI/Skirmish/MyJavaAI/SkirmishAI.jar&#039;&#039; and start up a game. Your AI should now build a solar plant at its start position.&lt;br /&gt;
&lt;br /&gt;
===Building a metal extractor===&lt;br /&gt;
Building a metal extractor is slightly more complicated. Assuming you&#039;re not on a metal map, you will need to find a suitable site to place the extractor. Generally, it&#039;s preferable to select a site closest to wherever your construction unit (commander) is located.&lt;br /&gt;
&lt;br /&gt;
Modify your code that got a reference to the solar plant by making the following changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
List&amp;lt;UnitDef&amp;gt; unitDefs = this.callback.getUnitDefs(); UnitDef solarPlant = null; for (UnitDef def : unitDefs)&lt;br /&gt;
&lt;br /&gt;
  if (def.getName().equals(&amp;quot;armsolar&amp;quot;))&lt;br /&gt;
  {&lt;br /&gt;
      solarPlant = def;&lt;br /&gt;
  }&lt;br /&gt;
  else if (def.getName().equals(&amp;quot;armmex&amp;quot;))&lt;br /&gt;
  {&lt;br /&gt;
       metalExtractor=def;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again, you will need to create a Unitdef metalExtractor field by where you declared your solarPlant field.&lt;br /&gt;
&lt;br /&gt;
Next, you need a method for determining the distance between two 3D coordinates (since Spring locations are three dimensional). A slightly modified version of a distance function is found below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public float calculateDistance(AIFloat3 a, AIFloat3 b)&lt;br /&gt;
    {&lt;br /&gt;
    float xDistance = a.x - b.x;&lt;br /&gt;
    float yDistance = a.y - b.y;&lt;br /&gt;
    float zDistance = a.z - b.z;&lt;br /&gt;
    float totalDistanceSquared = xDistance*xDistance + yDistance*yDistance + zDistance*zDistance;&lt;br /&gt;
    return totalDistanceSquared;&lt;br /&gt;
    } &lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code actually returns the distance squared, but it will work for our purposes. In your init function, you will want to add the following code above the return statement but below the line defining the callback:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
checkForMetal();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will call the following function you need to place in your code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public void checkForMetal()&lt;br /&gt;
    {&lt;br /&gt;
    Resource metal=Resource.getInstance(clb, 0);&lt;br /&gt;
    availablemetalspots=clb.getMap().getResourceMapSpotsPositions(metal);&lt;br /&gt;
    if(availablemetalspots.isEmpty())&lt;br /&gt;
        {&lt;br /&gt;
        sendTextMsg(&amp;quot;This is a map with no metal spots&amp;quot;);&lt;br /&gt;
        metalmap=false;&lt;br /&gt;
        }&lt;br /&gt;
    else&lt;br /&gt;
        {metalmap=true;&lt;br /&gt;
        sendTextMsg(&amp;quot;This is a map with metal spots. Listing Values...&amp;quot;);&lt;br /&gt;
        for (AIFloat3 metalspot : availablemetalspots) {&lt;br /&gt;
            sendTextMsg(&amp;quot;Metal Spot at X: &amp;quot;+metalspot.x + &amp;quot;, Y: &amp;quot;+metalspot.y +&amp;quot;, Z: &amp;quot;+metalspot.z);&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the above code to function properly, you will need to create a Boolean named metalmap and a List&amp;lt;AIFloat3&amp;gt; availablemetalspots. You will now have a function set up for calculating distance between two points, and a data structure holding a list of positions of metal spots. The next step is to tie these two together:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public AIFloat3 closestMetalSpot(AIFloat3 unitposition)&lt;br /&gt;
    {&lt;br /&gt;
    AIFloat3 closestspot=null;&lt;br /&gt;
    for (AIFloat3 metalspot : availablemetalspots) {&lt;br /&gt;
            if (closestspot==null)&lt;br /&gt;
                {&lt;br /&gt;
                closestspot=metalspot;&lt;br /&gt;
                }&lt;br /&gt;
        else if(calculateDistance(metalspot, unitposition) &amp;lt; calculateDistance(closestspot, unitposition) &amp;amp;&amp;amp; metalspot.hashCode()!=unitposition.hashCode())&lt;br /&gt;
                    {&lt;br /&gt;
                    closestspot=metalspot;&lt;br /&gt;
                    }&lt;br /&gt;
        }&lt;br /&gt;
    availablemetalspots.remove(closestspot);&lt;br /&gt;
    return closestspot;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function accepts an AIFloat3 containing the location of your construction unit (commander). It will then find the closest metal spot and return that location. The next step is to have your commander make use of this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
  if (frame == 600)&lt;br /&gt;
  {&lt;br /&gt;
       if(metalmap){       sendTextMsg(&amp;quot;About to build mex at frame &amp;quot; + frame);&lt;br /&gt;
       AIFloat3 closestspot=closestMetalSpot(commander.getPos());&lt;br /&gt;
       BuildUnitAICommand command2=new BuildUnitAICommand(this.commander, -1,&lt;br /&gt;
               new ArrayList&amp;lt;AICommand.Option&amp;gt;(), 10000,&lt;br /&gt;
               metalExtractor,closestspot, 0);&lt;br /&gt;
       handleEngineCommand(command2);}&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Place the above code in your update() method. When the frame count reaches 600, your commander will start to build a metal extractor at the closest metal spot. The extractor may not be right on top of where the metal spot appears to be, but you can mouse over the extractor to make sure it&#039;s drawing the metal properly.&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q:&#039;&#039;&#039; What is the difference between &amp;lt;code&amp;gt;unitCreated()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unitFinished()&amp;lt;/code&amp;gt;?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A:&#039;&#039;&#039; The difference is that &amp;lt;code&amp;gt;unitCreated()&amp;lt;/code&amp;gt; is called when construction of a unit starts, while &amp;lt;code&amp;gt;unitFinished()&amp;lt;/code&amp;gt; when construction on the unit has been completed. Any number of things may happen in-between, including the unit under construction being destroyed, so it is important to remember this distinction.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q:&#039;&#039;&#039; Do I have to copy and paste my jar file to the directory in Spring/AI/Skirmish/MyAI/0.1 each time I want to test my AI out?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A:&#039;&#039;&#039; Yes, but it is much easier if you automate the process. In Windows, a simple batch file can be created to move the files over for you. For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
copy C:\Users\msm8bball\Documents\NetBeansProjects\MyAI\dist\MyAI.jar &amp;quot;C:\Program Files (x86)\Spring\AI\Skirmish\MyAI\0.1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
del &amp;quot;C:\Program Files (x86)\Spring\AI\Skirmish\MyAI\0.1\SkirmishAI.jar&amp;quot;&lt;br /&gt;
rename &amp;quot;C:\Program Files (x86)\Spring\AI\Skirmish\MyAI\0.1\MyAI.jar&amp;quot; SkirmishAI.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modify the above code to match your computer&#039;s directories. Place it in a text file and save it as MoveAI.bat. This will create a batch file that you can double click and it will automatically move your AI to the proper location and rename it. You might wish to put a shortcut to this in your Start menu or taskbar. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q:&#039;&#039;&#039; I have problems with the class-loader in my AI, any idea? &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A:&#039;&#039;&#039; Each Java AI implementation is loaded by a separate class loader. This is used to load all the AI&#039;s class files and dependency libraries (in the &#039;&#039;jlib&#039;&#039; dir). Some libraries though, use the Thread contexts class loader, instead of the one of the current class. Therefore, if you want to load something from the AI&#039;s own class-path, make sure to let these libraries use the class-path of your AI classes, eg:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
ClassLoader myClassLoader = AIFactory.class.getClassLoader();&lt;br /&gt;
MySpecialUtil msp = new MySpecialUtil();&lt;br /&gt;
msp.setClassLoader(myClassLoader);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Please do not set this class-loader on the thread with &amp;lt;code&amp;gt;Thread.currentThread().setContextClassLoader(myClassLoader)&amp;lt;/code&amp;gt;, because all AI&#039;s are run in the same Java thread, and therefore this will cause problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [[AIInterface:Java|Java AI Interface]]&lt;br /&gt;
* [http://spring.abma.de/doc-Interface-JavaOO/ Javadoc of the Java AI OO Wrapper] (generated daily from source by [[User:Abma|abma]])&lt;br /&gt;
* &#039;&#039;&#039;OUTDATED&#039;&#039;&#039; [http://springrts.com/phpbb/download/file.php?id=4970 Netbeans Java Skirmish AI Tutorial] (from [http://springrts.com/phpbb/viewtopic.php?p=448743#p448743 this forum thread])&lt;br /&gt;
* [http://modinfo.adune.nl/index.php?MOD=ba712 ModInfo] (contains a list of units and their short names)&lt;br /&gt;
&lt;br /&gt;
[[Category: AI Dev]]&lt;/div&gt;</summary>
		<author><name>Bla</name></author>
	</entry>
</feed>