LUA <--> COB
Moderator: Moderators
So, if I get it, whenever the Spring COB interpreter see a function name starting by "lua_", it looks for a LUA function from "LuaCob/main.lua" instead of calling the function from the COB (which has to be here just so Scriptor allow to compile but is otherwise unused)? And to get the values returned by the LUA function, we use get 110 for first argument, get 111 for second argument, etc...?
Hmm, where to we put our LUA function for COB exactly? All /LuaCob/*.lua ? Is there any limit to the number of argument a LUA function can return?
I don't understand the syntax of "get cmd(p1, p2, p3, p4);". I'm used to get such as "get HEALTH" or get UNIT_XZ(id); where there is first "get", then a constant telling what to get, then eventually an argument, but I fail to understand the meaning of "get cmd(p1,p2,p3,0);"
What's with the "return 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009 " in the LUA function FillConstants? Are those 1001,1002,etc.. some filler so we see how to return values, or have those numbers some special meanings? How comes the argument of FillConstants in the LUA files don't fit the arguments of FillConstants in the BOS file? Do I need to study LUA before it makes sense?
Hmm, where to we put our LUA function for COB exactly? All /LuaCob/*.lua ? Is there any limit to the number of argument a LUA function can return?
I don't understand the syntax of "get cmd(p1, p2, p3, p4);". I'm used to get such as "get HEALTH" or get UNIT_XZ(id); where there is first "get", then a constant telling what to get, then eventually an argument, but I fail to understand the meaning of "get cmd(p1,p2,p3,0);"
What's with the "return 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009 " in the LUA function FillConstants? Are those 1001,1002,etc.. some filler so we see how to return values, or have those numbers some special meanings? How comes the argument of FillConstants in the LUA files don't fit the arguments of FillConstants in the BOS file? Do I need to study LUA before it makes sense?
Paragraph #1: yup, you've got it
Paragraph #2:
There are 3 directories (one for each script)
1.LuaCob/
2. LuaMod/
3. LuaGaia/
Each script set has 2 main files, main.lua and draw.lua. The synced part
of the script goes into main.lua. The unsynced part goes into draw.lua.
The draw.lua script is put into a sandbox that can not be read from
main.lua. It is given access to main.lua's data by way of a special lua
table called SYNCED. An include("filename"[, fenvTable]) call is
provided so that you can load code into the two main files.
Paragraph #3:
"get cmd(p1, p2, p3, 0)" is the same syntax that you are used to except
that "cmd" is a variable instead of a constant. I wrote the script that way
so that I could test COB data access from lua without having to write a
separate COB function for each "get" type.
Paragraph #4:
The 1001-1009 values are constants that I chose to be easily recognized
during testing. There is no 1000 passed back because LUA0 is used to
tell the COB script whether or not its lua_XXX call succeeded.
Paragraph #2:
There are 3 directories (one for each script)
1.LuaCob/
2. LuaMod/
3. LuaGaia/
Each script set has 2 main files, main.lua and draw.lua. The synced part
of the script goes into main.lua. The unsynced part goes into draw.lua.
The draw.lua script is put into a sandbox that can not be read from
main.lua. It is given access to main.lua's data by way of a special lua
table called SYNCED. An include("filename"[, fenvTable]) call is
provided so that you can load code into the two main files.
Paragraph #3:
"get cmd(p1, p2, p3, 0)" is the same syntax that you are used to except
that "cmd" is a variable instead of a constant. I wrote the script that way
so that I could test COB data access from lua without having to write a
separate COB function for each "get" type.
Paragraph #4:
The 1001-1009 values are constants that I chose to be easily recognized
during testing. There is no 1000 passed back because LUA0 is used to
tell the COB script whether or not its lua_XXX call succeeded.
I've compiled all I know about LuaCOB in this wiki article:
http://spring.clan-sy.com/wiki/Units:LuaCOB
Hopefully trepan will correct any mistakes an eager mod devs add more information as their work progresses.
http://spring.clan-sy.com/wiki/Units:LuaCOB
Hopefully trepan will correct any mistakes an eager mod devs add more information as their work progresses.
imbaczek
Thanks for writing that up, once I get some of my documenting finished,
maybe you could write another tutorial or two as to how to use it
I changed the Sim references to Spring (I changed that a while back),
added the CobScriptCB() call (to show that cob callbacks can be used),
and corrected the retArgCount parameter to CobScript().
Thanks for writing that up, once I get some of my documenting finished,
maybe you could write another tutorial or two as to how to use it

I changed the Sim references to Spring (I changed that a while back),
added the CobScriptCB() call (to show that cob callbacks can be used),
and corrected the retArgCount parameter to CobScript().
I'll see what I can do. I need to figure out several things so I can do a techdemo mod on a mod:
1) how to invoke COB/Lua code on user action (that is, create a spell/ability button)
2) how to put that button on a cooldown
3) how to make a unit fire a weapon at any given coordinate in its range
4) how to create missiles/bullets in mid-air well above ground (I mean *well* so I can rain fire from the orbit :>)
5) how to create a temporary decal (eg. a laser dot (Terran ghost) or a crosshair (Tau missile truck))
Probably all this is doable without hacking the spring core, but I'd like to give AIs some ways to invoke suffering on puny humans, too ^^
1) how to invoke COB/Lua code on user action (that is, create a spell/ability button)
2) how to put that button on a cooldown
3) how to make a unit fire a weapon at any given coordinate in its range
4) how to create missiles/bullets in mid-air well above ground (I mean *well* so I can rain fire from the orbit :>)
5) how to create a temporary decal (eg. a laser dot (Terran ghost) or a crosshair (Tau missile truck))
Probably all this is doable without hacking the spring core, but I'd like to give AIs some ways to invoke suffering on puny humans, too ^^
1. Spring.InsertUnitCmdDesc()
2. Spring.EditUnitCmdDesc()
3. Not supported? You can give units the standard attack commands,
but I have not yet provided direct control of weapons, and may never.
4. Drop units and make them explode? I suppose you could also rig
something with a custom invisible unit that you moved around to drop
weapons. Probably easiest to try this using LuaGaia.
5. gl.Shape(GL_POINTS, {}) or gl.BeginEnd(GL_POINTS, {})
make sure you offset by the ground height, you'll probably
want the depth test enable (and blending). If that isn't getting the job
done, try drawing a vertical line. The rendering can be different
targetted to specific teams if you use the Spring.GetLocalTeamID() or
GetLocalAllyTeamID() calls in draw.lua (where rendering code has to go).
2. Spring.EditUnitCmdDesc()
3. Not supported? You can give units the standard attack commands,
but I have not yet provided direct control of weapons, and may never.
4. Drop units and make them explode? I suppose you could also rig
something with a custom invisible unit that you moved around to drop
weapons. Probably easiest to try this using LuaGaia.
5. gl.Shape(GL_POINTS, {}) or gl.BeginEnd(GL_POINTS, {})
make sure you offset by the ground height, you'll probably
want the depth test enable (and blending). If that isn't getting the job
done, try drawing a vertical line. The rendering can be different
targetted to specific teams if you use the Spring.GetLocalTeamID() or
GetLocalAllyTeamID() calls in draw.lua (where rendering code has to go).
Guess it's too late now for my brain to think or something, but I can't figure out a way to call Lua or BOS when the user clicks my fantastic new button.trepan wrote:1. Spring.InsertUnitCmdDesc()
What I want to do:
- user clicks "Barrage", which is a CMD_ICON_MAP type command, and targets it somewhere
- a Lua (or COB) function is called which checks if the spot the user clicked is in range, if so spawns a Gaia invisible unit that targets the spot and fires some stuff at it, then disappears. After that, the unit's "Barrage" button is disabled for some specified time.
My question is: how to invoke that function? I imagine the command needs some kind of a special action value, or maybe it's LuaUI that has to invoke LuaCOB part?
There are 2 ways to hook a custom command. LuaUI can use the CommandNotify()
call-in, and LuaRules can use the AllowCommand() call-in. In your case, you'll probably
want to use LuaRules with AllowCommnd(), and check the commandID for a match
with the command id that you've chosen.
Note that I did not give the LobCob script any of the following call-ins, they are only
available to the LuaRules script (it is assigned to customizing game rules) That may
change later, stuff might get moved around and copied... dunno
AllowCommand()
AllowUnitCreation()
AllowUnitTransfer()
AllowFeatureCreation()
call-in, and LuaRules can use the AllowCommand() call-in. In your case, you'll probably
want to use LuaRules with AllowCommnd(), and check the commandID for a match
with the command id that you've chosen.
Note that I did not give the LobCob script any of the following call-ins, they are only
available to the LuaRules script (it is assigned to customizing game rules) That may
change later, stuff might get moved around and copied... dunno

AllowCommand()
AllowUnitCreation()
AllowUnitTransfer()
AllowFeatureCreation()
Orbital bombardment weapons were done before, basically you just need to move the firepoint to y-axis [very_high_number_there] via COB script. Of course, the piece should be either a point (null object) or hidden via script so that no weird visual things happen.imbaczek wrote:...4) how to create missiles/bullets in mid-air well above ground (I mean *well* so I can rain fire from the orbit :>)
...
The other solution would be to spawn projectiles via EmitSFX() COB fucntion. I'm not sure what kinds of projectiles work with that (pulse lasers seem to work, beam laser don't), the things to try would be ballistic projectiles and rockets with low speed (so they fall nearly straight down), probably bombs.
trepan: ok, guess it's time to hack there.
yurich: I thought about it and see problems with that approach:
- what happens when the unit that ordered the bombardment gets killed?
- how do I make bombardment a completely different type of attack (so it doesn't happen when I have the unit do a usual attack?)
- how do I put it on a visible cooldown (a progress bar, counter or something similar?)
yurich: I thought about it and see problems with that approach:
- what happens when the unit that ordered the bombardment gets killed?
- how do I make bombardment a completely different type of attack (so it doesn't happen when I have the unit do a usual attack?)
- how do I put it on a visible cooldown (a progress bar, counter or something similar?)
Ok I looked around in the source and found no way of calling a Lua script when a command finishes. LuaRules does not receive any information about commands that pass all the way down through SlowUpdate, which means LuaRules can't define a command that gets queued -- an essential thing for spells.
So I added it: http://spring.clan-sy.com/mantis/view.php?id=519
Orbtial bombardment soon, tune in for more details...
So I added it: http://spring.clan-sy.com/mantis/view.php?id=519
Orbtial bombardment soon, tune in for more details...
I'll commit the patch, but with some fixes:
- fixed a crash bug when luaRules is not enabled
- avoided running the call-in for existing state commands
- changed the return value semantics, you can now leave
the command at the front of the stack and remove it using
CMD_REMOVE when it has been completed.
- fixed a crash bug when luaRules is not enabled
- avoided running the call-in for existing state commands
- changed the return value semantics, you can now leave
the command at the front of the stack and remove it using
CMD_REMOVE when it has been completed.
Code: Select all
CommandFallback(unitID, unitDefID, teamID,
cmdID, cmdParams, cmdOptions) -> boolean removeCommand
Last edited by trepan on 10 Apr 2007, 22:46, edited 2 times in total.
Thanks for the commit. My only nit is that calling any interesting functions (such as CreateUnit, GiveOrderToUnit) need to be preceded with AllowUnsafeChanges(), but for now possibilities are endless.
demo: http://neoteric.pl/~imbaczek/spring/poo ... arrage.avi - like that, COB fans?
demo: http://neoteric.pl/~imbaczek/spring/poo ... arrage.avi - like that, COB fans?

For those who don't read SVN commits, the exact required call is:
AllowUnsafeChanges("USE AT YOUR OWN PERIL")
You'd be even worst off if I hadn't added it at all
Note that it does not have to precede every 'unsafe' call, you can
set and forget (unless something is broken... let me know)
There are 'technical' reasons for requiring that call, I'd rather
be safe then sorry. It would be nice to get rid of the checks by
making sure that everything is re-entrant safe, but for now:
USE AT YOUR OWN PERIL, or queue commands to be run
in Update().
P.S. nice vid
AllowUnsafeChanges("USE AT YOUR OWN PERIL")
You'd be even worst off if I hadn't added it at all

Note that it does not have to precede every 'unsafe' call, you can
set and forget (unless something is broken... let me know)
There are 'technical' reasons for requiring that call, I'd rather
be safe then sorry. It would be nice to get rid of the checks by
making sure that everything is re-entrant safe, but for now:
USE AT YOUR OWN PERIL, or queue commands to be run
in Update().
P.S. nice vid
