Lua-LuaCOB: Difference between revisions

From Spring
Jump to navigationJump to search
No edit summary
 
Flozi (talk | contribs)
m Flozi moved page Units:LuaCOB to Lua-LuaCOB without leaving a redirect: standardise
 
(24 intermediate revisions by 7 users not shown)
Line 1: Line 1:
Lua is small, embedded, highly dynamic programming language, which has been integrated into Spring.
{{deprecated}}
[[Engine_Development|Development]] < [[Lua_Scripting|Lua Scripting]] < {{FULLPAGENAME}}
 
 
'''<font size="4"><font color="red">NOTE</font> LuaCob will merged with LuaRules in 76b2</font>'''


=Introduction=
=Introduction=
To use Lua code in your BOS/COB files, you must:
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:
*create a mod-level directory LuaCOB/,
*create a mod-level directory LuaCOB/,
*make a LuaCOB/main.lua file.
*make a LuaCOB/main.lua file. (Note: it's LuaRules/main.lua now)
Any additional files need to be included with a
Any additional files need to be included with a


  include("LuaCOB/additional_file.lua" [, fenvTable])
  include("LuaCOB/additional_file.lua" [, fenvTable])


If you don't know what a fenvTable is, don't worry, you probably don't need it anyway. 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's Lua version is 5.0.3, so please take note which version of the manual you're reading.
If you don't know what a fenvTable is, don't worry, you probably don't need it anyway.
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're reading.
 
Also note that the usual Lua functions for executing code in other files (<tt>dofiles()</tt>, <tt>require()</tt>) are disabled for technical reasons.


=Intefacing COB->Lua=
=Interfacing COB->Lua=
All Lua functions that are called by COB are given three parameters:
All Lua functions that are called by COB are given three parameters:
*unitID - ID of the unit calling the function,
*unitID - ID of the unit calling the function,
Line 21: Line 28:


   function GetNearestEnemy(unitID, unitDefID, teamID, radius)
   function GetNearestEnemy(unitID, unitDefID, teamID, radius)
     local px, py, pz = Sim.GetUnitPosition(unitID)
     local px, py, pz = Spring.GetUnitPosition(unitID)
     if (px == nil) then
     if (px == nil) then
       return
       return
Line 28: Line 35:
     local nearDist = 1.0e20
     local nearDist = 1.0e20
     local nearUnit
     local nearUnit
     local units = Sim.GetUnitsInCylinder(px, pz, radius)
     local units = Spring.GetUnitsInCylinder(px, pz, radius)
     for _,enemyID in ipairs(units) do
     for _,enemyID in ipairs(units) do
       if (not Sim.IsUnitAllied(enemyID)) then             
       if (not Sim.IsUnitAllied(enemyID)) then             
         local ex, ey, ez = Sim.GetUnitPosition(enemyID)
         local ex, ey, ez = Spring.GetUnitPosition(enemyID)
         if (ex ~= nil) then
         if (ex ~= nil) then
           local dx, dy, dz = (px - ex), (py - ey), (pz - ez)
           local dx, dy, dz = (px - ex), (py - ey), (pz - ez)
Line 62: Line 69:
Then just call this script. The <tt>lua_</tt> prefix does its magic and routes the call to Lua code instead of calling the usual BOS code. Note that arguments don't matter, they are passed anyway:
Then just call this script. The <tt>lua_</tt> prefix does its magic and routes the call to Lua code instead of calling the usual BOS code. Note that arguments don't matter, they are passed anyway:
  call-script lua_MyFunction(arg1, arg2);
  call-script lua_MyFunction(arg1, arg2);
===Getting output===
If you wish to print out some debugging info, please note that <tt>print</tt> and <tt>io.write</tt> don't quite work in Windows versions of Spring, since stdout isn't availible (or is well-hidden.) Use <tt>Spring.Echo("a string")</tt>, this will print a message to the Spring console and into the infolog.
===LUA0..9===
// the GET/SET constants
#define LUA0 110
#define LUA1 111
#define LUA2 112
#define LUA3 113
#define LUA4 114
#define LUA5 115
#define LUA6 116
#define LUA7 117
#define LUA8 118
#define LUA9 119
<tt>get LUA0</tt> is used to check whether call succeeded (1 if true, 0 otherwise.) LUA1..9 store return values, e.g. <tt>lua_ReturnSomeValues</tt> above would put its first argument into <tt>get LUA1</tt>, second into <tt>get LUA2</tt>, and so on.


==Summary==
==Summary==
Line 70: Line 94:
*return values can be found in <tt>get LUA1..9</tt>
*return values can be found in <tt>get LUA1..9</tt>
*<tt>get LUA0</tt> returns 1 when call was successful (regardless of its return values) and 0 in case of failure.
*<tt>get LUA0</tt> returns 1 when call was successful (regardless of its return values) and 0 in case of failure.
===Examples of code===
*[http://neoteric.pl/~imbaczek/spring/messages_lua.zip Inter-unit communication]  <small>(shameless plug ;p)</small> - 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.
* <big>Your own!</big>


=Interfacing Lua->COB=
=Interfacing Lua->COB=


Lua:
Lua:
  Sim.COBScript(unitID, "CustomScript", arg1, arg2, arg3)
  Spring.CallCOBScript(unitID, "CustomScript", retArgCount, arg1, ..., argN)
Spring.CallCOBScriptCB(unitID, "CustomScript", retArgCount, callbackData, arg1, ..., argN)
 
'''retArgCount:'''  the number of arguments expected to be returned'''
'''callbackData:''' number passed to CobCallback() when the cob call completes


COB:
COB:
  CustomScript(arg1, arg2, arg3) { ... }
  CustomScript(arg1, ..., argN) { ... }
 
One particularly useful COB script, since Lua doesn't seem to have a way of making <tt>get SOMETHING(args)</tt> requests (but it may provide other ways of getting the same information):
LuaGet(r, cmd, p1, p2, p3, p4)
{
  if (r == 0) { r = get cmd;                return r }
  if (r == 1) { r = get cmd(p1,  0,  0,  0); return r }
  if (r == 2) { r = get cmd(p1, p2,  0,  0); return r }
  if (r == 3) { r = get cmd(p1, p2, p3,  0); return r }
  if (r == 4) { r = get cmd(p1, p2, p3, p4); return r }
 
  return 1234;
}
 
=References=
#[http://spring.clan-sy.com/phpbb/viewforum.php?f=23 Spring Lua Scripts forum]
#[http://spring.clan-sy.com/phpbb/viewtopic.php?t=9329 trepan's description of Lua-COB interface] - a little bit outdated, but still worth a read
 
=Thanks=
trepan for doing the hard work of integrating Lua into Spring!
 
 
NOTE from trepan:
  Thanks, but there were lua startscripts before I started doing
  any Spring coding. The benefits of the new LuaCob, LuaGaia, and
  LuaRules scripts are that they can be loaded from map/mod archives,
  and that they all use the same base libraries (as does LuaUI).
  They also have significantly more features then the current
  startscript code (ex: more call-ins and call-outs, the ability to
  render graphics in several different modes, play sounds, etc...)
[[Category: Lua]]

Latest revision as of 19:19, 29 October 2013

Warning! This page is outdated! The information displayed may no longer be valid, or has not been updated in a long time. Please refer to a different page for current information.


Development < Lua Scripting < Lua-LuaCOB


NOTE LuaCob will merged with LuaRules in 76b2

Introduction

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:

  • create a mod-level directory LuaCOB/,
  • make a LuaCOB/main.lua file. (Note: it's LuaRules/main.lua now)

Any additional files need to be included with a

include("LuaCOB/additional_file.lua" [, fenvTable])

If you don't know what a fenvTable is, don't worry, you probably don't need it anyway. More information can be found on 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're reading.

Also note that the usual Lua functions for executing code in other files (dofiles(), require()) are disabled for technical reasons.

Interfacing COB->Lua

All Lua functions that are called by COB are given three parameters:

  • unitID - ID of the unit calling the function,
  • unitDefID - ID of the unitDef,
  • teamID - self-explanatory.

You can call scripts with any (enough for all practical purpouses) amount of additional arguments.

Example functions:

 function GetNearestEnemy(unitID, unitDefID, teamID, radius)
   local px, py, pz = Spring.GetUnitPosition(unitID)
   if (px == nil) then
     return
   end
      
   local nearDist = 1.0e20
   local nearUnit
   local units = Spring.GetUnitsInCylinder(px, pz, radius)
   for _,enemyID in ipairs(units) do
     if (not Sim.IsUnitAllied(enemyID)) then             
       local ex, ey, ez = Spring.GetUnitPosition(enemyID)
       if (ex ~= nil) then
         local dx, dy, dz = (px - ex), (py - ey), (pz - ez)
         local dist = (dx * dx) + (dy * dy) + (dz + dz)
         if (dist < nearDist) then
           nearUnit = enemyID
           nearDist = dist
         end
       end 
     end   
   end   
   if (nearUnit == nil) then
     return -1
   else
     return nearUnit
   end
 end

Please note that returning tables doesn't currently work as one could expect. (Description what it does here) If you want to return multiple values from a table, you need to do it like this:

function ReturnSomeValues(u, ud, t, ...)
    return arg[1], arg[2], arg[3]  -- instead of arg
end

Calling Lua from BOS

To call a Lua function from BOS code, you need to declare it first:

// BOS
lua_MyFunction() { return 0; }

Then just call this script. The lua_ prefix does its magic and routes the call to Lua code instead of calling the usual BOS code. Note that arguments don't matter, they are passed anyway:

call-script lua_MyFunction(arg1, arg2);

Getting output

If you wish to print out some debugging info, please note that print and io.write don't quite work in Windows versions of Spring, since stdout isn't availible (or is well-hidden.) Use Spring.Echo("a string"), this will print a message to the Spring console and into the infolog.

LUA0..9

// the GET/SET constants
#define LUA0 110
#define LUA1 111
#define LUA2 112
#define LUA3 113
#define LUA4 114
#define LUA5 115
#define LUA6 116
#define LUA7 117
#define LUA8 118
#define LUA9 119

get LUA0 is used to check whether call succeeded (1 if true, 0 otherwise.) LUA1..9 store return values, e.g. lua_ReturnSomeValues above would put its first argument into get LUA1, second into get LUA2, and so on.

Summary

Steps needed to call a Lua function in a BOS call-script call:

  • define a Lua function MyFunction(unitID, unitDefID, teamID, ...) in LuaCOB/main.lua or a file included by it
  • define a BOS/COB script lua_MyFunction() { return 0; } so the compiler knows about it
  • call your function with call-script lua_MyFunction()
  • return values can be found in get LUA1..9
  • get LUA0 returns 1 when call was successful (regardless of its return values) and 0 in case of failure.

Examples of code

  • Inter-unit communication (shameless plug ;p) - 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.
  • Your own!

Interfacing Lua->COB

Lua:

Spring.CallCOBScript(unitID, "CustomScript", retArgCount, arg1, ..., argN)
Spring.CallCOBScriptCB(unitID, "CustomScript", retArgCount, callbackData, arg1, ..., argN)
retArgCount:  the number of arguments expected to be returned
callbackData: number passed to CobCallback() when the cob call completes

COB:

CustomScript(arg1, ..., argN) { ... }

One particularly useful COB script, since Lua doesn't seem to have a way of making get SOMETHING(args) requests (but it may provide other ways of getting the same information):

LuaGet(r, cmd, p1, p2, p3, p4)
{
 if (r == 0) { r = get cmd;                 return r }
 if (r == 1) { r = get cmd(p1,  0,  0,  0); return r }
 if (r == 2) { r = get cmd(p1, p2,  0,  0); return r }
 if (r == 3) { r = get cmd(p1, p2, p3,  0); return r }
 if (r == 4) { r = get cmd(p1, p2, p3, p4); return r }
 return 1234;
}

References

  1. Spring Lua Scripts forum
  2. trepan's description of Lua-COB interface - a little bit outdated, but still worth a read

Thanks

trepan for doing the hard work of integrating Lua into Spring!


NOTE from trepan:

 Thanks, but there were lua startscripts before I started doing
 any Spring coding. The benefits of the new LuaCob, LuaGaia, and
 LuaRules scripts are that they can be loaded from map/mod archives,
 and that they all use the same base libraries (as does LuaUI).
 They also have significantly more features then the current
 startscript code (ex: more call-ins and call-outs, the ability to
 render graphics in several different modes, play sounds, etc...)