BLitzmax - LUA ?

BlitzMax Forums/BlitzMax Programming/BLitzmax - LUA ?

slenkar(Posted 2009) [#1]
Does anyone know where I can download an LUA mod?

or any other scripting language.

I tried BriskVm but it crashes when I use lists.


Gabriel(Posted 2009) [#2]
I *think* this is the latest.

http://www.blitzbasic.com/Community/posts.php?topic=69429


Htbaa(Posted 2009) [#3]
And from the Lua-users wiki: http://lua-users.org/wiki/BlitzMax

I've got a local copy I updated to use Lua-5.1.4. If you want I can post it here.


slenkar(Posted 2009) [#4]
thanks both of y'all

yeh could I have the 5.1.4 please?


Htbaa(Posted 2009) [#5]
Here you go: http://www.htbaa.com/download/axe.mod.lua.mod-5.1.4.zip
You still need to compile it though, I hope that's not a problem. I wasn't sure which files needed to be included for that. I presume the .a and .i files?


slenkar(Posted 2009) [#6]
thanks,

has anyone got a tutorial or set of examples ?


Htbaa(Posted 2009) [#7]
http://www.lua.org/pil/ is a nice book. The 1st edition is available online. I've got a hardcopy of the 2nd edition myself.

What exactly do you want to know? Lua is fairly new for me as well but I've been playing quite a bit with making Lua and BlitzMax interact.

Here a small example to help you started, to expose a BlitzMax function to Lua:

LuaState:Byte Ptr
LuaState = luaL_newstate()
luaL_openlibs(LuaState)

lua_register(LuaState, "bmxCameraMove", LuaCameraMove)
luaL_dostring("bmxCameraMove(100,200)")
lua_close(LuaState)

Function LuaCameraMove:Int(LuaState:Byte Ptr)
	Local x:Int = luaL_checkinteger(LuaState, 1)
	Local y:Int = luaL_checkinteger(LuaState, 2)
	TCamera.GetInstance().RemoveFocus()
	TCamera.GetInstance().SetPosition(x, y)
	Return 0
End Function


Important to know, every BlitzMax function exposed to Lua must return an integer containing the amount of values you pushed on to the stack.

Have fun with Lua.


slenkar(Posted 2009) [#8]
thanks,

An ideal tutorial would consist of
1.blitzmax code as above - to expose functions
2.a small sample LUA script just to see things running
3.blitzmax code to run the script

I tried this but nothing was printed:
Import axe.lua
Import axe.luascript

Local LuaState:Byte Ptr
LuaState = luaL_newstate()
luaL_openlibs(LuaState)

lua_register(LuaState, "bmxCameraMove", LuaCameraMove)
luaL_dostring(luastate,"bmxCameraMove(100,200)")
lua_close(LuaState)

Function LuaCameraMove:Int(LuaState:Byte Ptr)
Local x:Int = luaL_checkinteger(LuaState, 1)
	Local y:Int = luaL_checkinteger(LuaState, 2)
 Print "x "+x+" y "+y
	Return 0
End Function



Htbaa(Posted 2009) [#9]
I ran it without axe.luascript (I don't have that module) and it worked fine.


slenkar(Posted 2009) [#10]
i tried without luascript module and it didnt work, ah dunno why man

The program ran but nothing was printed


Could someone make a small tutorial please please please?


Htbaa(Posted 2009) [#11]
Try compiling it with the GUI flag on.


slenkar(Posted 2009) [#12]
I tried experimenting with all the flags but no joy

You are just running that blitzmax code with no external scripts?


Htbaa(Posted 2009) [#13]
Yes. I tried it in BLIde and MaxIDE.

Are you sure mod.lua compiled without errors/warnings?


slenkar(Posted 2009) [#14]
yeah it compiles and executes, then the output cursor just blinks until I press the red stop button on the IDE


Htbaa(Posted 2009) [#15]
Why do you need to press the stop button? It justs runs and quits...?


slenkar(Posted 2009) [#16]
It runs but doesnt quit by itself

Maybe we are using different versions of axe.lua ??

I downloaded the one supplied by Gabriel first and I was using that one,

I downloaded the one you supplied and it worked! sorry for the confusion

Thanks for the help


slenkar(Posted 2009) [#17]
do you know how to debug a script?

e.g. get the line that caused the error?


Gabriel(Posted 2009) [#18]
When you execute a lua script with lua_pcall, lua_dofile, lua_dostring or something like that, the return value will be 0 if the function executed correctly. If the result is non-zero, the error is placed on the stack. You can get it back off the stack with lua_tostring()


slenkar(Posted 2009) [#19]
lua_tostring() retrieves a string from the stack? - EDIT oh yeah it does thanks

also how do you return a value from a blitzmax function in Lua? (put it onto the stack)

e.g.

Function luakeyhit:Int(luastate:Byte Ptr)
Local key:Int=lual_checkinteger(luastate,1)
lua_pushinteger (luastate,KeyHit(key))
Return 1
EndFunction

the above function just returns 1 all the time


N(Posted 2009) [#20]
also how do you return a value from a blitzmax function in Lua? (put it onto the stack)
Read http://www.lua.org/pil/26.1.html


slenkar(Posted 2009) [#21]
ive tried several things

LUACODE
if keyhit(1)==1
then
end_game()
end;

BLITZCODE
Function luakeyhit:Int(luastate:Byte Ptr)
Local key:Int=lual_checkinteger(luastate,1)
lua_pushinteger (luastate,KeyHit(key))
Return 1
EndFunction

EDIT it turns out that booleans dont work and escape is keycode 27 not keycode 1 like it used to be in bltiz3d


N(Posted 2009) [#22]
You know that 1 is not KEY_ESCAPE, right?


slenkar(Posted 2009) [#23]
yep just figured that out he he he he


N(Posted 2009) [#24]
For the sake of example, see this: http://gist.github.com/79663

And for the sake of a vaguely complicated example, see this: http://github.com/nilium/bmax-misc/blob/1d0953d886051eaa1f93bd572b447077221f69ad/lua-reflection/lua-reflection.bmx


slenkar(Posted 2009) [#25]
what would be a good LUA script to use with the first example?
That would help me understand what it does

EDIT - OOPS I just noticed it at the bottom of the page

Is it possible to have multiple scripts with the same function?

e.g.

Cast_spell()

If I wanted to make ten different spells (lets say they do 10 different damages) then in BriskVM you can create 10 scripts with the same function name but each function is different. The functions are loaded at execution and mapped to the name of the spell.

e.g.
1.magicmissile.lua would have the function cast_Spell() which returns a random number from 1-6
2.Freeze.lua would have the function cast_spell() which returns a random number from 1-10


The Luareflection looks interesting, I made this small program to test it out:
Import axe.lua
Import axe.luareflect

Local LuaState:Byte Ptr
LuaState = luaL_newstate()
luaL_openlibs(LuaState)

Type wizard {expose}
Field x,y,health
EndType

lua_implementtypes(luastate)

If luaL_dostring(luastate,"???")<>0
Print lua_tostring(luastate,1)
EndIf


What would I put in place of the question marks or what would be a good script to test it out?


N(Posted 2009) [#26]
Something like
local wizard
wizard = Newwizard()
wizard.x = 5
wizard.y = 10
wizard.health = 100


Anything else you do with it, that's mostly up to you. Helps to capitalize the first letter of the type name, also, since it'll look odd otherwise.

As for the functions with the same name, that's a bad idea in the first place (same name for a global function, that is). You'd probably have to have multiple VMs, give them different names, or put them in a table and get the functions through that.

Latter option:
-- function table..

spells = {}
-- options:
-- function spells.magic_missile
-- spells["magic_missile"]
-- there is also the syntactic sugar function spells:magic_missile(), where the function has a hidden self argument.
spells.magic_missile = function()
    return 20 -- damage
end
spells.chain_lightning = function()
    return 12 -- damage
end
spells.firebolt = function()
    return 22 -- damage
end




slenkar(Posted 2009) [#27]
newwizard() is a blitz function that returns an integer handle?

That spell table that has different functions looks good, how would you call one of those functions from blitz?

The example 3 posts above calls global functions but these functions are in a table.


N(Posted 2009) [#28]
Newwizard (case is important) is a generic function implemented by the Lua reflection code that has a few upvalues to know which type of object to allocate when you call it. In this case, it would have the TTypeId for wizard associated with it, as well as cached values for the type's metadata (expose, noclass, etc.). That function allocates an object of type wizard and adds it to the code that retains references to BMax objects (since ordinarily, once an object is created in Lua and not accessed by BMax, it will be unreferenced by BMax- I'm currently looking at manually incrementing/decrementing the object's reference count, but that's experimental for now) until they're either freed or collected by Lua's GC.

In the case of the spells table:
lua_pushstring(lvm, "spells")
lua_gettable(lvm, LUA_GLOBALSINDEX)

lua_pushstring(lvm, "magic_missile")
lua_gettable(lvm, -2)

lua_pcall(lvm, 0, 1, 0) ' Ignoring error code here
Local damage:Int = Int lua_tonumber(lvm, -1)
lua_pop(lvm, 2) ' Pop return value (-1) and table (-2)



slenkar(Posted 2009) [#29]
do you have to pop every table and value from the stack?

I thought you could just do lua_tonumber and that popped it automatically.

thanks for the example


N(Posted 2009) [#30]
The only values that are automatically popped are functions and their arguments, the key/value pairs for when you call lua_settable, and the key value for when you get a value from a table.

lua_to* functions don't pop values, seeing as how that would be rather troublesome.


slenkar(Posted 2009) [#31]
ok thanks