Lua Module Tweaks

BlitzMax Forums/BlitzMax Module Tweaks/Lua Module Tweaks

N(Posted 2005) [#1]
Some Lua module tweaks to make it easier to work with (less calling "String.ToCString" and "String.FromCString").

Refer to the History if you want to read the exact explanation.


Strict

Rem
bbdoc: LUA Core
End Rem
Module Pub.lua

ModuleInfo "Version: 1.13"
ModuleInfo "Author: Tecgraf, PUC-Rio"
ModuleInfo "License: MIT License"
ModuleInfo "Modserver: BRL"
ModuleInfo "Credit: Adapted for BlitzMax by Thomas Mayer & Noel Cower"

ModuleInfo "History: Added luaopen_debug and ldblib.c"
ModuleInfo "History: Replaced Byte Ptr with $z (CString) where a C string is expected"
ModuleInfo "History: Release 1.13"
ModuleInfo "History: Release 1.12"
ModuleInfo "History: Removed lua.h import"

Import "lstate.c"
Import "llex.c"
Import "ltm.c"
Import "lstring.c"
Import "ltable.c"
Import "lfunc.c"
Import "ldo.c"
Import "lgc.c"
Import "lzio.c"
Import "lobject.c"
Import "lparser.c"
Import "lvm.c"
Import "lundump.c"
Import "lmem.c"
Import "lcode.c"
Import "ldebug.c"
Import "lopcodes.c"
Import "lapi.c"
Import "ldump.c"
Import "lbaselib.c"
Import "lauxlib.c"
Import "liolib.c"
Import "lmathlib.c"
Import "lstrlib.c"
Import "ltablib.c"
Import "ldblib.c"

Const LUA_TNONE				= -1

Const LUA_TNIL				= 0
Const LUA_TBOOLEAN			= 1
Const LUA_TLIGHTUSERDATA		= 2
Const LUA_TNUMBER				= 3
Const LUA_TSTRING				= 4
Const LUA_TTABLE				= 5
Const LUA_TFUNCTION			= 6
Const LUA_TUSERDATA			= 7
Const LUA_TTHREAD				= 8

Const LUA_REGISTRYINDEX		= -10000
Const LUA_GLOBALSINDEX			= -10001


Extern
	''' INIT FUNCTIONS '''
	Function lua_open:Byte Ptr()
	Function lua_close(lua_state:Byte Ptr)
	Function luaopen_base(lua_state:Byte Ptr)
	Function luaopen_table(lua_state:Byte Ptr)
	Function luaopen_io(lua_state:Byte Ptr)
	Function luaopen_string(lua_state:Byte Ptr)
	Function luaopen_math(lua_state:Byte Ptr)
	Function luaopen_debug(lua_state:Byte Ptr)
	''' END INIT FUNCTIONS '''
	
	''' LOADING FUNCTIONS '''
	Function luaL_loadbuffer(lua_state:Byte Ptr, buffer:Byte Ptr, buffersize, name$z)
	''' END LOADING FUNCTIONS '''
	
	''' EXECUTION FUNCTIONS '''
	Function lua_dofile(lua_state:Byte Ptr, filename$z) 
	Function lua_pcall(lua_state:Byte Ptr, nargs:Int, nresults:Int, errfunc:Int)
	''' END EXECUTION FUNCTIONS '''
	
	''' CONVERT FUNCTIONS '''
	Function lua_tostring$z(lua_state:Byte Ptr, index:Int)
	Function lua_toboolean:Int(lua_state:Byte Ptr, index:Int)
	Function lua_tonumber:Double(lua_state:Byte Ptr, index:Int)
	Function lua_strlen:Int(lua_state:Byte Ptr, index:Int)
	Function lua_tothread:Byte Ptr(ls:Byte Ptr,index:Int)
	Function lua_touserdata:Byte Ptr(ls:Byte Ptr,index:Int)
	''' END CONVERT FUNCTIONS '''
	
	''' TYPE INFO FUNCTIONS '''
	Function lua_typename:Byte Ptr(lua_state:Byte Ptr, typenumber:Int)
	Function lua_type:Int(lua_state:Byte Ptr, index:Int)
	Function lua_isnumber:Int(lua_state:Byte Ptr, index:Int)
	Function lua_isstring:Int(lua_state:Byte Ptr, index:Int)
	Function lua_isuserdata:Int(ls:Byte Ptr, index:Int)
	Function lua_iscfunction:Int(ls:Byte Ptr, index:Int)
	''' END TYPE INFO FUNCTIONS '''
	
	''' STACK AND DATA FUNCTIONS '''
	Function lua_next(lua_state:Byte Ptr, idx:Int)
	Function lua_error(lua_state:Byte Ptr)
	Function lua_call(lua_state:Byte Ptr,nargs:Int, nres:Int)
	Function lua_newtable(lua_state:Byte Ptr)
	Function lua_getfield(name:Byte Ptr)
	Function lua_gettable(lua_state:Byte Ptr, tableIndex:Int)
	Function lua_settable(lua_state:Byte Ptr, tableIndex:Int)
	Function lua_settop(lua_state:Byte Ptr, index:Int)
	Function lua_gettop:Int(lua_state:Byte Ptr)
	Function lua_rawset(lua_state:Byte Ptr, idx:Int)
	Function lua_rawget(lua_state:Byte Ptr, idx:Int)
	Function lua_pushvalue(lua_state:Byte Ptr, value:Int)
	Function lua_remove(lua_state:Byte Ptr, value:Int)
	Function lua_insert(lua_state:Byte Ptr, value:Int)
	Function lua_replace(lua_state:Byte Ptr, value:Int)
	Function lua_pushcclosure(lua_state:Byte Ptr, func:Int(ls:Byte Ptr), val:Int)
	Function lua_pushnil(lua_state:Byte Ptr)
	Function lua_pushnumber(lua_state:Byte Ptr, value:Double)
	Function lua_pushboolean(lua_state:Byte Ptr, value:Int)
	Function lua_pushlstring(lua_state:Byte Ptr, value$z, size:Int)
	Function lua_pushstring(lua_state:Byte Ptr, value$z)
	Function lua_pushlightuserdata(lua_state:Byte Ptr, p:Byte Ptr)
	Function lua_checkstack:Int(lua_state:Byte Ptr, size:Int)
	Function luaL_checklstring:Byte Ptr(lua_state:Byte Ptr, argNum:Int, size:Int)
	Function luaL_checknumber:Double(lua_state:Byte Ptr, argNum:Int)
	''' END STACK AND DATA FUNCTIONS '''
	
End Extern

' Re-written from LUA.H, Macro was not expanding correctly
Function lua_pop(lua_state:Byte Ptr, index:Int)
	lua_settop(lua_state, -(index)-1)
End Function

Function lua_isboolean:Int(lua_state:Byte Ptr, index:Int)
	Return (lua_type(lua_state, index) = LUA_TBOOLEAN)
End Function

Function lua_getglobal(lua_state:Byte Ptr, name$z)
	lua_pushstring(lua_state, name)
	lua_gettable(lua_state, LUA_GLOBALSINDEX)
End Function

Function lua_pushcfunction(lua_state:Byte Ptr, func:Int(ls:Byte Ptr))
	lua_pushcclosure(lua_state, func, 0)
End Function

Function lua_setglobal(lua_state:Byte Ptr, name$z)
	lua_pushstring(lua_state, name)
	lua_insert(lua_state, -2)
	lua_settable(lua_state, LUA_GLOBALSINDEX)
End Function

Function lua_register(lua_state:Byte Ptr, name$z, func:Int(ls:Byte Ptr))
	lua_pushstring(lua_state, name)
	lua_pushcfunction(lua_state, func)
	lua_settable(lua_state, LUA_GLOBALSINDEX)
End Function

Function luaL_checkstring:Byte Ptr(lua_state:Byte Ptr, index:Int) 
	Return luaL_checklstring(lua_state, index, Null)
End Function

Function luaL_checkint:Int(lua_state:Byte Ptr, argNum:Int)
	Return luaL_checknumber(lua_state, argNum)
End Function

Function lua_istable:Int(lua_state:Byte Ptr, index:Int)
	Return (lua_type(lua_state,index) = LUA_TTABLE)
End Function 



null_term(Posted 2005) [#2]
Could you add access to luaopen_debug? This would be very helpful for being able to write error handling functions in Lua, able to pull out callstack information.


N(Posted 2005) [#3]
Done, plus a minor tweak to luaL_loadbuffer.


N(Posted 2005) [#4]
What's with the forum times?


Mark Tiffany(Posted 2005) [#5]
They freak around month end. I think that on the first day of each month, any posts onthe last day of the previous month think they were made that day. There's a +1 missing somehwere...


null_term(Posted 2005) [#6]
Are the changes not reflected in the current sync mods?


Rimmsy(Posted 2005) [#7]
I have a tiny question about using LUA. I'm using it to do missions for my game. Say I have a mission type, LUAMission which runs a LUA file and uses the file to perform update(), etc, like this:

LUA:
function update()
print("I'm updating...")
end

updateVar = 1


Do I need to run each mission using a seperate ScriptEngine? As I was wondering whether the globals in each mission would be added to the scriptEngine, if I was only using one script engine I'd be overwriting globals.

Anyone know if it's the way you're supposed to do it?


Rimmsy(Posted 2005) [#8]
I think I'll make my problem clearer as I really need to solve it. I have a mission (courier mission) based on a LUA script. In bmx I've got:
Global activeMissions:TList=CreateList()
Global scriptEngine1:ScriptEngine=New ScriptEngine

ScriptEngine1.AddFunction(LUA_getRandomSystem, 	"getRandomSystem")	' 	returns a system's name


' this function gets a random System from the game and passes the name back to then LUA script
Function LUA_getRandomSystem(ls:Byte Ptr)
	Local s:system=getRandomSystem()
	ScriptEngine1.ReturnStringToLua(ls,Lower(s.name))
	Return 1	
End Function


Type LUAMission
	Field description$ ' comes from LUA using functions added to the global ScriptEngine

	Function createMission:LUAMission(file$)
		Local i:LUAMission=New LUAMission
		ScriptEngine1.RunScriptFile(file)
		i.createPrototype()
				
		ScriptEngine1.BeginLUAFunctionCall()
		ScriptEngine1.CallFunction("getDescription", True)
		i.description = ScriptEngine1.GetResultString()	 ' get the description generated from LUA using the above added function
	End Function

	Method CreatePrototype() ' runs a function in the LUA file to get a description of the mission and pass it back.
		ScriptEngine1.BeginLUAFunctionCall()
		ScriptEngine1.CallFunction("prototype", True)
		Return Int(ScriptEngine1.GetResultNumber())	' worked ok?
	End Method
	
	Method update()
		ScriptEngine1.BeginLUAFunctionCall()
		ScriptEngine1.CallFunction("update", True)
		
		Local result=Int(ScriptEngine1.GetResultNumber())		
		
		If result=1
			' mission is complete. and a success! give the player some money			
		ElseIf result=-1' failure
			' what a failure	
		EndIf
		ListRemove(activeMissions,Self)
	End Method
End Type

Function updateMissions()
	For Local i:LUAMission=EachIn activeMissions
		i.update()
	Next	
End Function

' ------------------------------------------ SCRIPT FROM LUA

randomSystem = getRandomSystem() ' calls attached function

Print("LUA -> Main run OK.")
Print("LUA -> Random System: "+randomSystem) ' this works fine.

Function getDescription()
	Return "Get my package to "..randomSystem 
End

Function updateMission()
    ' this is called to update mission objectives...
    ' specifics not important, but suffice to say this function check to see whether the player is in the 
	' system and docked at the right station.
	' if it's successful it'll return 1
	' otherwise it'll return 0
	' if it's completely unsuccessful it'll return -1
	
	' the problem is when I've taken more than one mission the 'randomSystem' 
	' variable gets overridden by the most recent run of the script.	
End
      
End


What I'm really looking for is a way to make variables defined in this script local to this script. So if I run "courier.lua" and it generates a system name and puts it in its own randomSystem variable, if I run it again it won't override.

Hmmm... I must have to run it in a seperate context. Like another scriptEngine. But does that mean I have to add all the functions I'm using to that scriptEngine? And if so, how do I associate the LUA linked functions like this:
Function LUA_getRandomSystem(ls:Byte Ptr)
	Local s:system=getRandomSystem()
	If s <> Null
		ScriptEngine1.ReturnStringToLua(ls,Lower(s.name))
	Else
		ScriptEngine1.ReturnStringToLua(ls,"BMX<->LUA ERROR")
	EndIf	
	Return 1	
End Function

to my game. Can I specify another parameter to that function that passes the scriptEngine I'm using? Won't it mess with something?

Can anyone gimme a hand?

Matt


Rimmsy(Posted 2005) [#9]
Ok, I seem to understand it a bit better now. The scriptEngine interface was hiding a bit too much plus I finally noticed the ls:byte Ptr was the lua state the script engine was holding. I made my mission type use the script engine but passed the lua state to the attached functions.

I think it'll work but bmx stops at:
lua_pushstring(ls, file.ToCString())

with an "enable to convert from 'byte ptr' to 'CString'

Anyone know what's up with that?

Thanks to
http://www.blitzbasic.com/Community/posts.php?topic=48411
and Noel's LUA tutorial wiki sample code.


Rimmsy(Posted 2005) [#10]
OK, never mind. I just reinstalled the latest update. Something must have overwritten something cost toCString didn't get recognised at all. Works now.


N(Posted 2005) [#11]
Rimmsy: I don't use the ScriptEngine class and I would honestly advise against it. It would be far wiser to write a specialized system so that you don't have to work around stuff in the class. Plus, my brain isn't working right now.

null_term: No.


Rimmsy(Posted 2005) [#12]
Thanks Noel. I haven't got time to do what you suggest although I'd really like to. Seems like scriptEngine works against you slightly by hiding some important stuff. Once you get a look at the core it's a lot more straight forward. I'll have a go at doing as you suggest and adding to the tutorial section as it's been a learning process... which you've helped. Thanks.


N(Posted 2005) [#13]
Bump.

These changes aren't in the update, so anyone who was using them you'll have to apply them again.

BRL: Keep an eye on the module tweaks forum, ok?


Hotcakes(Posted 2005) [#14]
They do. They implemented Tim's improved ImageFonts stuff.


N(Posted 2005) [#15]
Bump. Still not added.


skidracer(Posted 2005) [#16]
I got some conflicts with luascript.bmx with the $z changes so have converted everything to use :byte ptr to avoid confusion, but now I'm thinking you probably wanted to convert everything to go to $z, if so, can you post your latest luascript.bmx file also.


N(Posted 2005) [#17]
Keep in mind that I don't use the luascript module, but rather my own, so I make no guarantees to whether or not this still works (although I really don't see why it wouldn't).

Strict

Rem
bbdoc: LUA Script Engine
End Rem
Module Pub.luascript

ModuleInfo "Version: 1.12"
ModuleInfo "Author: Thomas Mayer"
ModuleInfo "License: Public Domain"
ModuleInfo "Modserver: BRL"

Import Pub.lua
Import brl.linkedlist
Import brl.basic

Const SE_TYPE_NUMBER 	= 0
Const SE_TYPE_STRING 	= 1
Const SE_TYPE_BOOLEAN 	= 2
Const SE_TYPE_TABLE		= 3

Type SE_Parameter

	Field m_paramType
	Field m_valueNumber:Double
	Field m_valueString:String
	Field m_valueBoolean:Int
	
'	Function CreateString:SE_Parameter(value:String)
'		Local returnParam:SE_Parameter = New SE_Parameter
'		returnParam.m_paramType = SE_TYPE_STRING
'		returnParam.m_valueString = value
'		Return returnParam
'	End Function

'	Function CreateBoolean:SE_Parameter(value:Int)
'		Local returnParam:SE_Parameter = New SE_Parameter
'		returnParam.m_paramType = SE_TYPE_BOOLEAN
'		returnParam.m_valueBoolean = value
'		Return returnParam
'	End Function
	
'	Function CreateNumber:SE_Parameter(value:Double)
'		Local returnParam:SE_Parameter = New SE_Parameter
'		returnParam.m_paramType = SE_TYPE_NUMBER
'		returnParam.m_valueNumber = value
'		Return returnParam
'	End Function
	
End Type

Rem
bbdoc: Lua script engine type
End Rem
Type ScriptEngine
	
	Field m_started:Int
	Field m_source:String
	Field m_lastErrorString:String
	Field m_lastErrorNumber:Int
	Field m_lua_state:Byte Ptr
	Field m_paramList:TList = CreateList()
	Field m_resultString:String = ""
	Field m_resultNumber:Double = 0
	Field m_resultBoolean:Int = 0
	Field m_resultType:Int = -1
			
	' Default constructor
	Method New()
		Reset()
	End Method
	
	Rem
		bbdoc: Resets the engine back to a start state
	End Rem
	Method Reset()
		If (m_lua_state) Then lua_close(m_lua_state)
	
		m_lua_state = lua_open()
		
		If (m_lua_state) Then
			luaopen_base(m_lua_state)
			luaopen_table(m_lua_state)
			luaopen_io(m_lua_state)
			luaopen_string(m_lua_state)
			luaopen_math(m_lua_state)
			m_started = True
		Else
			m_started = False
		End If
	End Method
	
	Rem
		bbdoc: Returns a string back to LUA from a callback BMX function
	End Rem
	Method ReturnStringToLua(lua_state:Byte Ptr, value:String)
		If (m_started) Then
			lua_pushstring(lua_state, value)
		End If
	End Method

	Rem
		bbdoc: Returns a number back to LUA from a callback BMX function
	End Rem
	Method ReturnNumberToLua(lua_state:Byte Ptr, value:Double)
		If (m_started) Then
			lua_pushnumber(lua_state, value)
		End If
	End Method
	
	Rem
		bbdoc: Returns a boolean back to LUA from a callback BMX function
	End Rem
	Method ReturnBooleanToLua(lua_state:Byte Ptr, value:Int)
		If (m_started) Then
			lua_pushboolean(lua_state, value)
		End If
	End Method

	Rem
		bbdoc: Adds a Function into the LUA environment
	End Rem
	Method AddFunction(func:Int(ls:Byte Ptr), name:String)
		If (m_started)
			lua_register(m_lua_state, name, func)
		End If
	End Method

	Rem
		bbdoc: Performs initialization required for call a function in LUA
	End Rem
	Method BeginLUAFunctionCall()
		ClearList(m_paramList)
		m_ResultType = -1
		m_ResultString = ""
		m_ResultNumber = 0
		m_ResultBoolean = 0
	End Method
	
	Rem
		bbdoc: Checks a string parameter and return its value
	End Rem
	Method CheckString:String(lua_state:Byte Ptr, index:Int)
		Return String.FromCString(luaL_checkstring(lua_state, index))
	End Method

	Rem
		bbdoc: Checks a number parameter and return its value
	End Rem
	Method CheckNumber:Double(lua_state:Byte Ptr, index:Int)
		Return luaL_checknumber(lua_state, index)
	End Method

'	Rem
'		bbdoc: Checks a boolean parameter And Return its value
'	End Rem
	Method CheckBoolean:Int(lua_state:Byte Ptr, index:Int)
		Return luaL_checkint(lua_state, index)
	End Method

	Rem
		bbdoc: Adds a string parameter to a LUA function call
	End Rem
	Method AddStringParameter(value:String)
		Local param:SE_Parameter = New SE_Parameter
		param.m_paramType = SE_TYPE_STRING
		param.m_valueString = value
		ListAddLast(m_paramList, param)
	End Method
	
	Rem
		bbdoc: Adds a number parameter to a LUA function call
	End Rem
	Method AddNumberParameter(value:Double)
		Local param:SE_Parameter = New SE_Parameter
		param.m_paramType = SE_TYPE_NUMBER
		param.m_valueNumber = value
		ListAddLast(m_paramList, param)
	End Method
	
	Rem
		bbdoc: Adds a boolean parameter to a LUA function call
	End Rem
	Method AddBooleanParameter(value:Int)
		Local param:SE_Parameter = New SE_Parameter
		param.m_paramType = SE_TYPE_BOOLEAN
		param.m_valueBoolean = value
		ListAddLast(m_paramList, param)
	End Method
	
	Rem
		bbdoc: Calls a function in LUA
	End Rem
	Method CallFunction:Int(functionName:String, wantResult:Int)
	    Local param:SE_Parameter
		Local error:Int

		If (m_started) Then
			lua_getglobal(m_lua_state , functionName)

			For param = EachIn m_paramList 
				Select param.m_paramType
					Case SE_TYPE_NUMBER
						lua_pushnumber(m_lua_state, param.m_valueNumber)
					Case SE_TYPE_STRING
						lua_pushstring(m_lua_state, param.m_valueString)
					Case SE_TYPE_BOOLEAN
						lua_pushboolean(m_lua_state, param.m_valueBoolean)
				End Select
			Next

			error = lua_pcall(m_lua_state, CountList(m_paramList), wantResult, 0)
 		
			If ((Not error) And wantResult) Then
				If (lua_isnumber(m_lua_state, -1)) Then
					m_resultType = SE_TYPE_NUMBER
					m_resultNumber = lua_tonumber(m_lua_state, -1)
					lua_pop(m_lua_state, 1)
				Else If (lua_isboolean(m_lua_state, -1)) Then
					m_resultType = SE_TYPE_BOOLEAN
					m_resultBoolean = lua_toboolean(m_lua_state, -1)
					lua_pop(m_lua_state, 1)
				Else If (lua_isstring(m_lua_state, -1)) Then
					m_resultType = SE_TYPE_STRING
					m_resultString = lua_tostring(m_lua_state, -1)
					lua_pop(m_lua_state, 1)
				End If
			End If
		Else
			m_lastErrorString = "ScriptEngine: Engine is not started"
			m_lastErrorNumber = 0
			Return False
		End If
		
		If (Not error) Then Return True
		
		ProcessError(error)
		Return False

 	End Method

	Rem
		bbdoc: Tells the result type of a LUA function call
	End Rem
	Method GetResultType:Int()
		Return m_resultType
	End Method
	
	Rem
		bbdoc: Get the result of a LUA function call as a number
	End Rem
	Method GetResultNumber:Double()
		Return m_resultNumber
	End Method

	Rem
		bbdoc: Get the result of a LUA function call as a boolean
	End Rem
	Method GetResultBoolean:Int()
		Return m_resultBoolean
	End Method
	
	Rem
		bbdoc: Get the result of a LUA function call as a string
	End Rem
	Method GetResultString:String()
		Return m_resultString
	End Method
		
	Rem
		bbdoc: Internal
	End Rem
	Method ProcessError (errorCode:Int)
		m_LastErrorString = lua_tostring(m_lua_state, -1)
		m_LastErrorNumber = errorCode 
		lua_pop(m_lua_state, -1)
	End Method
	
	Rem
		bbdoc: Set engine script text (performs syntax checks)
	End Rem
	Method SetScriptText:Int(scriptText:String, scriptName:String)
		Local error:Int
		
		m_Source = ""
		
		If (m_started) Then
			Local t:Byte Ptr=scriptText.ToCString()
 			error = luaL_loadbuffer(m_lua_state, t, scriptText.length, scriptText)
			MemFree t
		Else
			m_lastErrorString = "ScriptEngine: Engine is not started"
			m_lastErrorNumber = 0
			Return False
		End If

		If (Not error) Then
			m_Source = scriptText
			Return True
		End If

		ProcessError(error)
		Return False
	End Method

	Rem
		bbdoc: Runs a script file
	End Rem
	Method RunScriptFile:Int(scriptFile:String)
		Local error:Int

		If (m_started) Then
 			error = lua_dofile(m_lua_state, scriptFile)
		Else
			m_lastErrorString = "ScriptEngine: Engine is not started"
			m_lastErrorNumber = 0
			Return False
		End If
		
		If (Not error) Then Return True
		
		ProcessError(error)
		Return False
	End Method
	
	Rem
		bbdoc: Runs a script loaded with SetScriptText
	End Rem
	Method RunScript:Int()
		Local error:Int
		
		If (m_started) Then
			
			If (m_Source.length > 0) Then
 				error = lua_pcall(m_lua_state, 0, 0, 0)
			Else
				m_lastErrorString = "ScriptEngine: No script text to execute"
				m_lastErrorNumber = 0
				Return False
			End If
		Else
			m_lastErrorString = "ScriptEngine: Engine is not started"
			m_lastErrorNumber = 0
			Return False
		End If
		
		If (Not error) Then Return True
		
		ProcessError(error)
		Return False
	End Method
	
	Rem
		bbdoc: Returns the last error string
	End Rem
	Method GetLastErrorString:String()
		Return m_LastErrorString
	End Method

	Rem
		bbdoc: Returns the last error number
	End Rem
	Method GetLastErrorNumber:Int()
		Return m_LastErrorNumber
	End Method
	
	Rem
		bbdoc: Destroys script engine state
	End Rem
	Method ShutDown()
		If (m_lua_state) Then lua_close(m_lua_state)
		m_started = False
	End Method
		
	Rem
		bbdoc: Returns whether or not the engine has started correctly
	End Rem
	Method Started:Int()
		Return m_started
	End Method
	
End Type