Page 1 of 2

LuaCob is dead, long live LuaRules

Posted: 17 Jan 2008, 16:53
by trepan
The LuaCob script has been completely removed from
the Spring code in SVN. The COB -> LUA calls have been
redirected so that they now access the LuaRules global
namespace.

Re: LuaCob is dead, long live LuaRules

Posted: 17 Jan 2008, 22:57
by Argh
So, um, what does that mean, for people maintaining / developing games using a lot of stuff in LuaCOB as of right now? Do we have to move our files, rename things, or what?

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 10:03
by KDR_11k
You move your LuaCOB functions into a gadget(s) and uswe gadgetHandler:RegisterGlobal(function, name) to make them global.

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 10:17
by Argh
Hmmk. I suppose that moving this direction will mean that I'm facing a lot of broken code. Yay. I'll get a SVN copy and test this when I've gotten some sleep.

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 16:05
by Argh
I've tested this, and what you're saying doesn't work, KDR. Cob2LUA reports it cannot find my Functions. It sees that I have a Gadget, but it doesn't find the Functions. Nor does what you're talking about seem to give it a name.

Trepan, please provide a simple example of some code using this, so that I can fix my 20+ LuaCOB Functions you just broke, which are vital for PURE's gameplay at this point, and were supposed to go out to the AI folks for a testing rollout today :roll:

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 16:29
by Zpock
At first I read this like, "COB is dead, I have removed it from spring and replaced with LUA!"

that would be hilarious.

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 16:38
by Argh
No, I think what he is doing is resolving namespace stuff, so that LuaCOB can be loaded as LuaRules, solving the precedence problems. That'd be my best guess for why he did something that breaks backwards compatibility. <shrugs> I dunno, all I know is that until I have a fix that allows my COBs to call LUA functions properly, I'm hosed.

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 17:19
by Argh
Here's what I tried. Why is this not working? I assume it's something basic wrong with the RegisterGlobal part.

Code: Select all

if (gadgetHandler:IsSyncedCode()) then

gadgetHandler:RegisterGlobal(BuildSixPack, BuildSixPack)

function BuildSixPack(u, ud, team)

	-- do some stuff

end

end

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 17:44
by imbaczek
I'd do it like this:

Code: Select all

  if (gadgetHandler:IsSyncedCode()) then
  function BuildSixPack(u, ud, team)
     -- do some stuff
  end
  Spring.Echo("registering global")
  gadgetHandler:RegisterGlobal(BuildSixPack, "BuildSixPack")
end
but I'm no spring Lua expert.

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 17:53
by Argh
Hmm. I think I tried it with the quotes... lemme try that one more time, I'm very tired, could have screwed that up.

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 17:58
by Argh
Nope, didn't work. Code:

Code: Select all

function gadget:GetInfo()
	return {
		name = "COB Gadgets for P.U.R.E.",
		desc = "Standard Gadgets that communicate with COB, for P.U.R.E.",
		author = "Argh",
		date = "January 18th, 2007",
		license = "GPL, v. 2 or later",
		layer = 1,
		enabled = true,
	}
end


if (gadgetHandler:IsSyncedCode()) then

gadgetHandler:RegisterGlobal(BuildSixPack, "BuildSixPack")

function BuildSixPack(u, ud, team)
-- Do some stuff
end

end
Results in latest SVN Spring telling me:

CLuaRules::Cob2Lua() missing function: BuildSixPack

So, guys, what's missing? Maybe... hmm... nope.

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 18:03
by trepan
gadgetHandler:RegisterGlobal(name, value) -- not value, name

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 18:05
by Argh
Ah. Quotes first, then. <changes>

gadgetHandler:RegisterGlobal("BuildSixPack", BuildSixPack)

... did not result in a change. Cob2LUA reports it cannot find the function. So, do I need to make it "lua_BuildSixPack"?

Nope, that doesn't work, either.

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 18:10
by jK
you still need to define BuildSixPack() before calling RegisterGlobal ...

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 18:14
by KDR_11k
EDIT: Got it to work, user error...

Code: Select all

function gadget:GetInfo()
	return {
		name = "COB",
		desc = "All the former LuaCOB stuff",
		author = "KDR_11k (David Becker)",
		date = "2007-08-26",
		license = "Public domain",
		layer = 1,
		enabled = true
	}
end

if (gadgetHandler:IsSyncedCode()) then

--SYNCED

local destroyQueue = {}
local replaceQueue={}
local createQueue={}

function gadget:GameFrame(t)
	for i,u in pairs(destroyQueue) do
		Spring.DestroyUnit(u, true) --using selfD to prevent plane crashing anim
		destroyQueue[i]=nil
	end
	for i,u in pairs(replaceQueue) do
		local x, y, z
		x, y, z = Spring.GetUnitPosition(u.unit)
		nu = Spring.CreateUnit(u.target,x,y,z,0,u.team)
		Spring.SetUnitBlocking(nu, false)
		Spring.SetUnitCOBValue(nu, 82, Spring.GetUnitHeading(u.unit))
		Spring.SetUnitHealth(nu, Spring.GetUnitHealth(u.unit) / UnitDefs[Spring.GetUnitDefID(u.unit)].health * UnitDefs[Spring.GetUnitDefID(nu)].health)
		Spring.DestroyUnit(u.unit, false, true)
		replaceQueue[i] = nil
	end
	for i,u in pairs(createQueue) do
		Spring.CreateUnit(u.target,u.x,u.y,u.z,0,u.team)
		createQueue[i] = nil
	end
end

function Destroy(u, ud, team)
	table.insert(destroyQueue, u)
end

function GetCentralHeading(unit, ud, team)
	local x=0
	local z=0
	local count = 0
	for _,u in ipairs(Spring.GetAllUnits()) do
		local tempx, tempz
		tempx, _, tempz = Spring.GetUnitPosition(u)
		x = x + tempx
		z = z + tempz
		count = count + 1
	end
	local ux, uz
	ux, _, uz = Spring.GetUnitPosition(unit)
	return Spring.GetHeadingFromVector(x/count-ux, x/count-uz)
end

function SwitchToExploit(u,ud,team)
	table.insert(replaceQueue, {unit=u, team=team, target="exploit" })
end

function SwitchToBug(u,ud,team)
	table.insert(replaceQueue, {unit=u, team=team, target="bug" })
end

function GetHealth(u, ud, team, target)
	return Spring.GetUnitHealth(target)
end

function GiveExpMobile(u, ud, team)
	local x, y, z
	x, y, z = Spring.GetUnitPosition(u)
	z=z+80
	table.insert(createQueue, {x=x, y=y, z=z, team=team, target="expmobile" })
end

function IsParalyzed(u,ud,team)
	return Spring.GetUnitIsStunned(u)
end

function gadget:Initialize()
	gadgetHandler:RegisterGlobal("Destroy", Destroy)
	gadgetHandler:RegisterGlobal("GetCentralHeading", GetCentralHeading)
	gadgetHandler:RegisterGlobal("SwitchToExploit", SwitchToExploit)
	gadgetHandler:RegisterGlobal("SwitchToBug", SwitchToBug)
	gadgetHandler:RegisterGlobal("GetHealth", GetHealth)
	gadgetHandler:RegisterGlobal("GiveExpMobile", GiveExpMobile)
	gadgetHandler:RegisterGlobal("IsParalyzed", IsParalyzed)
end
only produces errors

That's KP Div0's LuaCOB, BTW.

EDIT: Ooops, forgot an end at the end. Now it works

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 18:25
by Argh
Ok, I got it working on my end- I didn't put it in Initialize, but after the Function, and it registered the global variable correctly. Now I get an error about invoking AllowUnsafeChanges- Spring states that the value is nil, then halts the script.

It worked when it was just a LuaCOB... any idea what I need to change?

Here's some example code:

Code: Select all

function BuildEngineeringTeamThreePack(u, ud, team)

	AllowUnsafeChanges("USE AT YOUR OWN PERIL")

	-- do some stuff

	AllowUnsafeChanges("thanks")

end
gadgetHandler:RegisterGlobal("BuildEngineeringTeamThreePack", BuildEngineeringTeamThreePack)
... results in: LuaRules::RunCallIn: error = 2, BuildEngineeringTeamThreePack, [string "LuaRules/Gadgets/cob_gadgets.lua"]:26: attempt to call global 'AllowUnsafeChanges' (a nil value)

It didn't do this before. I guess I'll go check CA's code for that, and see what I might be doing wrong...

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 19:00
by Argh
Oh, duh. AllowUnsafeChanges("USE AT YOUR OWN PERIL") must be invoked in Main.lua... duh.

Ok, everything's working again, and Trepan only had to call me an idiot once, all is well...

Re: LuaCob is dead, long live LuaRules

Posted: 18 Jan 2008, 20:09
by KDR_11k
Don't use AllowUnsafeChanges then :P

Re: LuaCob is dead, long live LuaRules

Posted: 19 Jan 2008, 01:55
by zwzsg
Does that mean every mod that use LuaCob will break in next Spring? :|

I'd write a long post explaining why it's bad and scary but then you'd just scoff it.

Re: LuaCob is dead, long live LuaRules

Posted: 19 Jan 2008, 02:31
by Argh
Yes. Every mod using LuaCOB will be broken, until they migrate their code. However, LuaCOB still works perfectly, assuming the code is migrated correctly.

Here's a migration path:

1. If your game does not have a LuaRules folder, create one.

2. If your game does not have a main.lua in your LuaRules folder, create one, with code like this:

Code: Select all

AllowUnsafeChanges("USE AT YOUR OWN PERIL")

VFS.Include("LuaGadgets/gadgets.lua",nil, VFS.BASE)
This allows you to invoke AllowUnsafeChanges, if you need it. If you don't, remove the first line, and simply use the VFS.Include to make use of the gadget code from Spring's base. Or write a custom main.lua, as required.

3. Now, port your LuaCOB over to a Gadget. Here is the format that I've used (keep in mind, there may be more than one way to do this, and I'm not claiming it's the "right" way, but it works when tested):

Code: Select all

function gadget:GetInfo()
	return {
		name = "COB_Gadgets.lua",
		desc = "LuaCob, via Gadget code.",
		author = "Myname",
		date = "Today's Date",
		license = "Your License Here",
		layer = 1,
		enabled = true,
	}
end

if (gadgetHandler:IsSyncedCode()) then

function MyLuaCobFunction(u, ud, team)

-- Do stuff

end
gadgetHandler:RegisterGlobal("MyLuaCobFunction", MyLuaCobFunction)

end
Basically, what this does (yes, feel free to correct me if I'm wrong, by all means) is to put the functions, which were previously just stuck in main.lua in the LuaCob area, into a Gadget, then, when the function's names have been initialized as a variable, you register the function and provide a handle to call it via LuaCOB again, which is why it's at the end.

Migrating your code is straightforward at that point, it's just minor drudgery, took me maybe half an hour for all of the functions in my two projects.