<?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=Brathering</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=Brathering"/>
	<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/wiki/Special:Contributions/Brathering"/>
	<updated>2026-11-08T20:42:50Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua-LuaCOB&amp;diff=10695</id>
		<title>Lua-LuaCOB</title>
		<link rel="alternate" type="text/html" href="https://springrts-wiki.p2004a.com/mediawiki/index.php?title=Lua-LuaCOB&amp;diff=10695"/>
		<updated>2008-11-12T14:13:01Z</updated>

		<summary type="html">&lt;p&gt;Brathering: a small extra note to use LuaRules/main.lua instead of LuaCOB/main.lua. I&amp;#039;ve needed some hours to find this error in my tests.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&amp;lt;font size=&amp;quot;4&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;NOTE&amp;lt;/font&amp;gt; LuaCob will merged with LuaRules in 76b2&amp;lt;/font&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
To use Lua code in your BOS/COB files, you can either include the gadgetHandler (include it in the mod, see the CA mod or include it from the springcontent.sdz) or you create your own enviroment:&lt;br /&gt;
*create a mod-level directory LuaCOB/,&lt;br /&gt;
*make a LuaCOB/main.lua file. (Note: it&#039;s LuaRules/main.lua now)&lt;br /&gt;
Any additional files need to be included with a&lt;br /&gt;
&lt;br /&gt;
 include(&amp;quot;LuaCOB/additional_file.lua&amp;quot; [, fenvTable])&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t know what a fenvTable is, don&#039;t worry, you probably don&#039;t need it anyway.&lt;br /&gt;
More information can be found on [http://www.lua.org the Lua site]. It it highly recommended to read the manual and the tutorials found there. Note that Spring 76b1 used Lua version is 5.1.2, so please take note which version of the manual you&#039;re reading.&lt;br /&gt;
&lt;br /&gt;
Also note that the usual Lua functions for executing code in other files (&amp;lt;tt&amp;gt;dofiles()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;require()&amp;lt;/tt&amp;gt;) are disabled for technical reasons.&lt;br /&gt;
&lt;br /&gt;
=Interfacing COB-&amp;gt;Lua=&lt;br /&gt;
All Lua functions that are called by COB are given three parameters:&lt;br /&gt;
*unitID - ID of the unit calling the function,&lt;br /&gt;
*unitDefID - ID of the unitDef,&lt;br /&gt;
*teamID - self-explanatory.&lt;br /&gt;
You can call scripts with any (enough for all practical purpouses) amount of additional arguments.&lt;br /&gt;
&lt;br /&gt;
Example functions:&lt;br /&gt;
&lt;br /&gt;
  function GetNearestEnemy(unitID, unitDefID, teamID, radius)&lt;br /&gt;
    local px, py, pz = Spring.GetUnitPosition(unitID)&lt;br /&gt;
    if (px == nil) then&lt;br /&gt;
      return&lt;br /&gt;
    end&lt;br /&gt;
       &lt;br /&gt;
    local nearDist = 1.0e20&lt;br /&gt;
    local nearUnit&lt;br /&gt;
    local units = Spring.GetUnitsInCylinder(px, pz, radius)&lt;br /&gt;
    for _,enemyID in ipairs(units) do&lt;br /&gt;
      if (not Sim.IsUnitAllied(enemyID)) then             &lt;br /&gt;
        local ex, ey, ez = Spring.GetUnitPosition(enemyID)&lt;br /&gt;
        if (ex ~= nil) then&lt;br /&gt;
          local dx, dy, dz = (px - ex), (py - ey), (pz - ez)&lt;br /&gt;
          local dist = (dx * dx) + (dy * dy) + (dz + dz)&lt;br /&gt;
          if (dist &amp;lt; nearDist) then&lt;br /&gt;
            nearUnit = enemyID&lt;br /&gt;
            nearDist = dist&lt;br /&gt;
          end&lt;br /&gt;
        end &lt;br /&gt;
      end   &lt;br /&gt;
    end   &lt;br /&gt;
&lt;br /&gt;
    if (nearUnit == nil) then&lt;br /&gt;
      return -1&lt;br /&gt;
    else&lt;br /&gt;
      return nearUnit&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Please note that returning tables doesn&#039;t currently work as one could expect. &#039;&#039;(Description what it does here)&#039;&#039; If you want to return multiple values from a table, you need to do it like this:&lt;br /&gt;
&lt;br /&gt;
 function ReturnSomeValues(u, ud, t, ...)&lt;br /&gt;
     return arg[1], arg[2], arg[3]  -- instead of arg&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Calling Lua from BOS==&lt;br /&gt;
To call a Lua function from BOS code, you need to declare it first:&lt;br /&gt;
 // BOS&lt;br /&gt;
 lua_MyFunction() { return 0; }&lt;br /&gt;
Then just call this script. The &amp;lt;tt&amp;gt;lua_&amp;lt;/tt&amp;gt; prefix does its magic and routes the call to Lua code instead of calling the usual BOS code. Note that arguments don&#039;t matter, they are passed anyway:&lt;br /&gt;
 call-script lua_MyFunction(arg1, arg2);&lt;br /&gt;
===Getting output===&lt;br /&gt;
If you wish to print out some debugging info, please note that &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;io.write&amp;lt;/tt&amp;gt; don&#039;t quite work in Windows versions of Spring, since stdout isn&#039;t availible (or is well-hidden.) Use &amp;lt;tt&amp;gt;Spring.Echo(&amp;quot;a string&amp;quot;)&amp;lt;/tt&amp;gt;, this will print a message to the Spring console and into the infolog.&lt;br /&gt;
&lt;br /&gt;
===LUA0..9===&lt;br /&gt;
 // the GET/SET constants&lt;br /&gt;
 #define LUA0 110&lt;br /&gt;
 #define LUA1 111&lt;br /&gt;
 #define LUA2 112&lt;br /&gt;
 #define LUA3 113&lt;br /&gt;
 #define LUA4 114&lt;br /&gt;
 #define LUA5 115&lt;br /&gt;
 #define LUA6 116&lt;br /&gt;
 #define LUA7 117&lt;br /&gt;
 #define LUA8 118&lt;br /&gt;
 #define LUA9 119&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;get LUA0&amp;lt;/tt&amp;gt; is used to check whether call succeeded (1 if true, 0 otherwise.) LUA1..9 store return values, e.g. &amp;lt;tt&amp;gt;lua_ReturnSomeValues&amp;lt;/tt&amp;gt; above would put its first argument into &amp;lt;tt&amp;gt;get LUA1&amp;lt;/tt&amp;gt;, second into &amp;lt;tt&amp;gt;get LUA2&amp;lt;/tt&amp;gt;, and so on.&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
Steps needed to call a Lua function in a BOS call-script call:&lt;br /&gt;
*define a Lua function &amp;lt;tt&amp;gt;MyFunction(unitID, unitDefID, teamID, ...)&amp;lt;/tt&amp;gt; in LuaCOB/main.lua or a file included by it&lt;br /&gt;
*define a BOS/COB script &amp;lt;tt&amp;gt;lua_MyFunction() { return 0; }&amp;lt;/tt&amp;gt; so the compiler knows about it&lt;br /&gt;
*call your function with &amp;lt;tt&amp;gt;call-script lua_MyFunction()&amp;lt;/tt&amp;gt;&lt;br /&gt;
*return values can be found in &amp;lt;tt&amp;gt;get LUA1..9&amp;lt;/tt&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;get LUA0&amp;lt;/tt&amp;gt; returns 1 when call was successful (regardless of its return values) and 0 in case of failure.&lt;br /&gt;
&lt;br /&gt;
===Examples of code===&lt;br /&gt;
*[http://neoteric.pl/~imbaczek/spring/messages_lua.zip Inter-unit communication]  &amp;lt;small&amp;gt;(shameless plug ;p)&amp;lt;/small&amp;gt; - a library that allows passing messages between units and reading/writing of public variables exposed by them.Included is a tech demo involving modified [[Nanoblobs]] 0.64. Patch, start the game, make a sheep and see for yourself.&lt;br /&gt;
* &amp;lt;big&amp;gt;Your own!&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Interfacing Lua-&amp;gt;COB=&lt;br /&gt;
&lt;br /&gt;
Lua:&lt;br /&gt;
 Spring.CallCOBScript(unitID, &amp;quot;CustomScript&amp;quot;, retArgCount, arg1, ..., argN)&lt;br /&gt;
 Spring.CallCOBScriptCB(unitID, &amp;quot;CustomScript&amp;quot;, retArgCount, callbackData, arg1, ..., argN)&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;retArgCount:&#039;&#039;&#039;  the number of arguments expected to be returned&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;callbackData:&#039;&#039;&#039; number passed to CobCallback() when the cob call completes&lt;br /&gt;
&lt;br /&gt;
COB:&lt;br /&gt;
 CustomScript(arg1, ..., argN) { ... }&lt;br /&gt;
&lt;br /&gt;
One particularly useful COB script, since Lua doesn&#039;t seem to have a way of making &amp;lt;tt&amp;gt;get SOMETHING(args)&amp;lt;/tt&amp;gt; requests (but it may provide other ways of getting the same information):&lt;br /&gt;
 LuaGet(r, cmd, p1, p2, p3, p4)&lt;br /&gt;
 {&lt;br /&gt;
  if (r == 0) { r = get cmd;                 return r }&lt;br /&gt;
  if (r == 1) { r = get cmd(p1,  0,  0,  0); return r }&lt;br /&gt;
  if (r == 2) { r = get cmd(p1, p2,  0,  0); return r }&lt;br /&gt;
  if (r == 3) { r = get cmd(p1, p2, p3,  0); return r }&lt;br /&gt;
  if (r == 4) { r = get cmd(p1, p2, p3, p4); return r }&lt;br /&gt;
&lt;br /&gt;
  return 1234;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
#[http://spring.clan-sy.com/phpbb/viewforum.php?f=23 Spring Lua Scripts forum]&lt;br /&gt;
#[http://spring.clan-sy.com/phpbb/viewtopic.php?t=9329 trepan&#039;s description of Lua-COB interface] - a little bit outdated, but still worth a read&lt;br /&gt;
&lt;br /&gt;
=Thanks=&lt;br /&gt;
trepan for doing the hard work of integrating Lua into Spring!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTE from trepan:&lt;br /&gt;
  Thanks, but there were lua startscripts before I started doing&lt;br /&gt;
  any Spring coding. The benefits of the new LuaCob, LuaGaia, and&lt;br /&gt;
  LuaRules scripts are that they can be loaded from map/mod archives,&lt;br /&gt;
  and that they all use the same base libraries (as does LuaUI).&lt;br /&gt;
  They also have significantly more features then the current&lt;br /&gt;
  startscript code (ex: more call-ins and call-outs, the ability to&lt;br /&gt;
  render graphics in several different modes, play sounds, etc...)&lt;/div&gt;</summary>
		<author><name>Brathering</name></author>
	</entry>
</feed>