LUA <--> COB

LUA <--> COB

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

trepan
Former Engine Dev
Posts: 1200
Joined: 17 Nov 2005, 00:52

LUA <--> COB

Post by trepan »

A couple of things I've been playing with. Note that the lua GetNearestEnemy()
call will probably be replaced with a direct call-out placed into the Sim table, as
well as some of its sub-routines (like finding the square of the distance between
2 points).

The LuaSim scripts (I've currently got 3 defined, mod rules, map gaia, and cob
helper), all receive the standard call-ins for unit events (creation, deletion, team
change), They also get some type specific call-ins (ex: the mod rules script gets
the AllowUnitCreation() call-in, so that it can block unit creation under custom
conditions).

Mod Rules: let's the mod have finer control of the game, optional
Map Gaia: allows map creators to place gaia units in their maps, optional
COB helper: COB->LUA calls, probably wont be optional


COB -> LUA calls:

BOS:

Code: Select all

  // the "lua_" prefix is the key
  var = lua_GetNearestEnemy(300)
cobhelp.lua:

Code: Select all

function GetNearestEnemy(unitID, radius)
  local px, py, pz = Sim.GetUnitPosition(unitID)
  if (px == nil) then
    return
  end
     
  local nearDist = 1.0e20
  local nearUnit
  local units = Sim.GetUnitsInCylinder(px, pz, radius)
  for _,enemyID in ipairs(units) do
    if (not Sim.IsUnitAllied(enemyID)) then             
      local ex, ey, ez = Sim.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

LUA -> COB calls:

modrules.lua:

Code: Select all

  Sim.COBScript(unitID, "CustomScript", arg1, arg2, arg3)
BOS:

Code: Select all

  CustomScript(arg1, arg2, arg3) ...
trepan
Former Engine Dev
Posts: 1200
Joined: 17 Nov 2005, 00:52

Post by trepan »

Looks like the "var = lua_GetNearestEnemy(300)"
BOS format will have to be changed. Maybe something like:

Code: Select all

call-script lua_CustomFunc(arg1, ..., argn);
var1 = get LUAVAL1;
var2 = get LUAVAL2;
var3 = get LUAVAL3;
User avatar
FLOZi
MC: Legacy & Spring 1944 Developer
Posts: 6241
Joined: 29 Apr 2005, 01:14

Post by FLOZi »

This looks tremendously exciting. 8)
User avatar
yuritch
Spring 1944 Developer
Posts: 1018
Joined: 11 Oct 2005, 07:18

Post by yuritch »

How are we supposed to declare such "external" scripts in BOS/COB? As it is now, I'm mostly sure Scriptor won't allow to compile anything that references undeclared script functions.
trepan
Former Engine Dev
Posts: 1200
Joined: 17 Nov 2005, 00:52

Post by trepan »

So declare them... It's also a good place to
document the input and output arguments.

Code: Select all

lua_GetNearestEnemy(radius)
{
  // proxied to cobhelp.lua
  // LUA0 is true (1) if the call was successful
  // LUA1 will contain the unitID
  // LUA2 will contain the distance to the unit
  return (0);
}
P.S. If the COB compiler discards empty scripts, then
you can throw some junk code into the dummy scripts
to keep them alive. All that's used from them are the
names, and the number of arguments.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

I see this as purely an excuse to throw away the cob in its entirety and put it into the 'legacy support' box
User avatar
Guessmyname
Posts: 3301
Joined: 28 Apr 2005, 21:07

Post by Guessmyname »

Are we going to get some documentation for this?
trepan
Former Engine Dev
Posts: 1200
Joined: 17 Nov 2005, 00:52

Post by trepan »

AF
You can see it however you want, but the reality is that this will not be
a substitute for COB scripting because of the speed penalty inherent
to the COB->LUA calls (and LUA->COB calls). This is being coded so
that modsters get a little more flexibility, access to more global calls,
global variables, and a tie in to the synced simulation controllers. I've
even changed some of the core lua code to speed things up a little, but
it won't help that much.

GuessMyName
Eventually. The synced simulation lua code is based on the applicable
LuaUI code, so it will look much the same. Actually, I'll be ripping up the
LuaUI code to use the new libraries once it's all done.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Nah I meant as an excuse to remove cob from the process completely shoudl we wish to have purely lua scripting with no cob calls involved to begin with, hence no speed penalties in engine->cob->lua because your using engine->lua instead.
User avatar
Nemo
Spring 1944 Developer
Posts: 1376
Joined: 30 Jan 2005, 19:44

Post by Nemo »

I think LUA is slower than COB to begin with. Hence why supcom is such a demanding engine - EVERYTHING is done in LUA.

I could be wrong though.
trepan
Former Engine Dev
Posts: 1200
Joined: 17 Nov 2005, 00:52

Post by trepan »

Nemo
You're probably right. I've been playing around in both
sources the last couple of days, and I don't see moving
towards pure lua unit scripting as being the right path to
take.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

cob is backwards, it doesnt even support strings, there are many features in cob that dont exist because the language doesnt allow it, or the workarounds involve such horrible code and a horrible usage, its just not flexible enough.

However a cob script should perform slower than the equivilant compiled lua script, as the lua script is more tested, and has a much better script compile than the BOS compiler. Its the extra stuff that'll make lua slower, stuff that'll be there anyway only itll be even slower because of cob<->lua traffic.

And indeed our lua library has a lot of potential for performance tuning to our specific needs versus the generic library the lua people put out.

It also eliminates the need for noobs to learn both bos and lua.
User avatar
smoth
Posts: 22309
Joined: 13 Jan 2005, 00:46

Post by smoth »

Af, I am going to argue with you in a VERY strong stance of NO. You are wrong on this one.

Bos is easier for noobs to learn there are almost 10 years of TA units that have done damn near everything. So no bos has a place.

*edit that being said, depending on the time, if lua is implemented as an option and it has better performance I would start using it over bos. Provided that I would not have to ... Oh, I don't know... retime EVERY animation(which FYI just to speed the mod up took over a month).
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

supcom animation format support anybody?
trepan
Former Engine Dev
Posts: 1200
Joined: 17 Nov 2005, 00:52

Post by trepan »

Based on the properties of the languages, LUA would not have better performance
(especially if COB was speed-tweaked a little more). I don't know what information
AF would use to backup his statement. A limited language like COB is much easier
to optimize. As an example, its instruction set can be compressed into a linear
lookup table for interpreting the calls. The same can not be said for dynamic
languages. If you optimized LUA to the same level, you'd end up with LUA--.

The best situation for scripting languages is to provide link bindings from the engine,
and script interpreters and binders. Ideally, the script language could be compiled
down to native assembly (or have a bytecode interpreter that it makes little
difference), and would be user safe (read: no SEGVs).

P.S. Yes, the spring lua library is modified a little for multi-OS floating point
handling and a little speed tweak for call-ins, but it is mostly lua-5.0.3. If we
customized it too much, then merging in new code for future lua releases
becomes an issue.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

like lua 5.1?
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post by Tobi »

yes
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

LuaJIT anyone? ;)
trepan
Former Engine Dev
Posts: 1200
Joined: 17 Nov 2005, 00:52

Post by trepan »

Looked at it a while ago... it isn't quite ready for Spring out of the box
(see the restrictions listed in the Features section).
trepan
Former Engine Dev
Posts: 1200
Joined: 17 Nov 2005, 00:52

Post by trepan »

Examples of the interface:


LuaCob/main.lua

Code: Select all

function CobToLua(unitID, unitDefID, teamID, ...)
  // use call-script lua_CobToLua() in the COB script
  // access is limited to teamID during the call-in
  print("CobToLua: "..unitID.." "..unitDefID.." "..teamID)
  print("  --> " .. table.concat(arg, " "))
end


function FillConstants(unitID, unitDefID, teamID, ...)
  // use call-script lua_FillConstants() in the COB script
  return 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009
end
ARMDFLY.BOS

Code: Select all

// dummy LUA functions
lua_CobToLua()      { return 0; }
lua_FillConstants() { return 0; }

// has a sleep call, for testing callbacks (returns 1)
LuaToCob(v1, v2, v3)
{
  sleep v2;
  call-script lua_CobToLua(v1, v2, v3)
  return v1;
}

// direct call (returns 0) 
LuaToCob2(v1, v2, v3)
{
  call-script lua_CobToLua(v1, v2, v3)
  return v1;
}
 
LuaGet(r, cmd, p1, p2, p3, p4)
{
  if (r == 0) { call-script lua_CobToLua(cmd) }
  if (r == 1) { call-script lua_CobToLua(cmd, p1) }
  if (r == 2) { call-script lua_CobToLua(cmd, p1, p2) }
  if (r == 3) { call-script lua_CobToLua(cmd, p1, p2, p3) }
  if (r == 4) { call-script lua_CobToLua(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;
}


// 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

// fill the parameters with constants from lua,
// and then send them back to lua to print them
TestLuaData()
{
  call-script lua_FillConstants();
  var lua0 = get LUA0; // 0 for failure, 1 for success
  var lua1 = get LUA1;
  var lua2 = get LUA2;
  var lua3 = get LUA3;
  var lua4 = get LUA4;
  var lua5 = get LUA5;
  var lua6 = get LUA6;
  var lua7 = get LUA7;
  var lua8 = get LUA8;
  var lua9 = get LUA9;
  call-script lua_CobToLua(lua0, lua1, lua2, lua3, lua4, lua5, lua6, lua7, lua8, lua9);
}
Post Reply

Return to “Lua Scripts”