Game Development Community

TGEA 1.7 Python Support

by Prairie Games · in Torque Game Engine Advanced · 03/29/2008 (11:28 am) · 75 replies

Hey all, been doing some R&D on a new project and wanted to try out the (awesome) new build system
included with TGEA 1.7

I also wanted to have a look at some embedded scripting... and so dusted off PyTorque, got it ported over to 1.7, changed it around to be an embedded system, and hooked it up with the new build system.

www.prairiegames.com/gg/tgea_python.jpg
There are only very minor changes necessary to the core engine to support Python scripting. It is pretty powerful stuff... the docs are a bit sparse, but if you head over to MMOWorkshop.com you can browse through a lot of examples...

BTW, this is a newer system than what was used for Minions of Mirth. It is actually quite a bit cleaner... so, when in doubt check out the included example.py :)

You can snag PyTorque for TGEA 1.7 HERE

This was a pretty quick package job... so, post here with any glaring issues.

-Prairie Games, Inc
#41
06/29/2008 (6:07 am)
The latest code works flawlessly, thanks a bunch.
#42
06/30/2008 (6:24 am)
UPDATE:
*All vars recieved from a exported function are strings. It's necesary to check and convert types.
*Callbacks methods exported recieve console object ID as string. Added TorqueObject(ID as string) for facilitate creation.
*Memory leak and a error in PyTorqueObject_call that cause string used in argv are deleted before they are used.

Updated version of pytoque.cpp

SORRY FOR MY BAD ENGLISH :(
#43
07/01/2008 (5:38 am)
*Exported callbacks check methods in all class inheritance
*Change pytorque.export(callback,[namespace],functionname,usagedoc,minargs,maxargs) for add funtionality of override console method. You can define important engine callback as onAdd, onRemove, onCollide... etc.

pytorque.export(GuiBitmapButtonCtrl_onAdd,"GuiBitmapButtonCtrl","onAdd","...",0,0)

#test inheritance
pytorque.evaluate("new ScriptObject(MyScript);")
myscript = pytorque.TorqueObject("MyScript")

def cbm_simobject_test(self):
	pytorque.evaluate('echo("test: SIMOBJECT::TEST");')
	
def cbm_scriptobject_test(self):
	pytorque.evaluate('echo("test: SCRIPTOBJECT::TEST");')
	
def cbm_myscript_test(self):
	pytorque.evaluate('echo("test: MYSCRIPT::TEST");')
	
pytorque.export(cbm_simobject_test,"SimObject","test_","test",0,0)
myscript.test_()

pytorque.export(cbm_scriptobject_test,"ScriptObject","test_","test",0,0)
myscript.test_()

pytorque.export(cbm_myscript_test,"MyScript","test_","test",0,0)
myscript.test_()

I need to test more namespace stuff.

Updated version of pytoque.cpp
#44
07/04/2008 (1:27 pm)
PyTorque 1.7.1 BETA :P

Any one can test?

1 Generate a project named PyTorque with SetupNewProject.exe
2 Copy files in TGEA 1.7.1 dir
3 Apply pathc for TGEA 1.7.1 source code. You can use TortoiseMerge
4 generateProjects.bat
5 Compile
6 Test

example and test
#--- Torque Python Module Test ---

import pytorque

print "------------------------------PYTORQUE TEST-----------------------------------"

import sys

class PyLog:
	error = 0
	def __init__(self,log):
		self.log = log
	def write(self, stuff):	
		self.error = 1
		self.log.write(stuff)
			

sys.stdout = PyLog(sys.stdout)

#PYTORQUE AND TORQUE OBJECT EVER RETURN VALUES AS STRINGS

##################################################################################################
#test PYTORQUE
##################################################################################################

#test get/set global console vars
#getglobal return value AS STRING
pytorque.setglobal("$pytest",314)
if pytorque.getglobal("$pytest") != "314": print "ERROR: get/set global"

#test EVALUATE
#example of executing a script file
f = file("myscript.cs","rb")
script = f.read()
f.close()
pytorque.evaluate(script)
if pytorque.getglobal("$hi") != "HELLO WORLD FROM MYSCRIPT.CS":
	print "ERROR: Evaluate"
	
#or, just generate the cs code right inside Python!
pytorque.evaluate('$hi = "HELLO WORLD FROM PYTORQUE_TEST.PY";')
if pytorque.getglobal("$hi") != "HELLO WORLD FROM PYTORQUE_TEST.PY":
	print "ERROR: Evaluate"
	
#test EXPORT functions to console
def _pyHello():
	return "hi"
	
#export the function to the console system in much the same way the C++ system does...
#we also support optional namespaces, usage documentation, and min/max args
pytorque.export(_pyHello,"pyHello","Python function, return hi",0,0)
if pytorque.evaluate("pyHello();") != "hi" : print "ERROR: EXPORT functions to console"

#test export function with more args
#args recieved from console are EVER STRINGS. Need check and convert types
def _sum1int(v1):
	return int(v1)
	
def _sum2int(v1,v2):
	return int(v1)+int(v2)
	
def _sum3int(v1,v2,v3):
	return int(v1)+int(v2)+int(v3)
	
pytorque.export(_sum1int,"sum1int","Python function, sum INT args",1,1)
pytorque.export(_sum2int,"sum2int","Python function, sum INT args",2,2)
pytorque.export(_sum3int,"sum3int","Python function, sum INT args",3,3)

#returned values from evaluate are EVER STRINGS
if pytorque.evaluate('sum1int(1);') != "1" : print "ERROR: EXPORT functions with 1 args to console"
if pytorque.evaluate('sum2int(1,3);') != "4" : print "ERROR: EXPORT functions with 2 args to console"
if pytorque.evaluate('sum3int(1,3,5);') != "9" : print "ERROR: EXPORT functions with 3 args to console"
	
#EXPORT WITH OPTIONAL ARGS
def _sumint (v1, v2=0, v3=0):
	return int(v1)+int(v2)+int(v3)

pytorque.export(_sumint,"sumint","Python function, sum up to 3 INT args",1,3)
if pytorque.evaluate('sumint(1);') != "1" : print "ERROR: EXPORT functions with optional args to console"
if pytorque.evaluate('sumint(1,3);') != "4" : print "ERROR: EXPORT functions with optional args to console"
if pytorque.evaluate('sumint(1,3,5);') != "9" : print "ERROR: EXPORT functions with optional args to console"

#EXPORT TO NAMESPACE

pytorque.export(_sumint,"pytest","sumint","Python function, sum up to 3 INT args",1,3)
#call pytest::sumint with 2 args for emulate arg point to object
if pytorque.evaluate('pytest::sumint(0,8);') != "8" : print "ERROR: EXPORT functions to namespace"



##################################################################################################
#test TorqueObject
##################################################################################################

#TorqueObject is a interface to a console object
pytorque.evaluate("new ScriptObject(MyScript);")

#we can get object with name string, ID string or ID int
myscript = pytorque.TorqueObject("MyScript")

if myscript.getId() != pytorque.evaluate("Myscript.getID();"): print "ERROR: TorqueObject"

#we can call console methods on our TorqueObjects... So, let's create a dyn field.
myscript.setFieldValue("dyn","a")
#recieved as STRING
if myscript.getFieldValue("dyn") != "a": print "ERROR: TorqueObject call method" 

#we can get and set fields (including dynamic fields, for create use setFieldValue console method).
#all recieved in string
if myscript.dyn != "a": print "ERROR: TorqueObject get field"
myscript.dyn = 7
if myscript.dyn != "7": print "ERROR: TorqueObject set field"

#EXPORT METHODS
#recieve all values as strings
def _getFieldValueSum(self,value):
	self = pytorque.TorqueObject(self)
	sum = int(self.dyn)+int(value)	
	return str(sum) #way of torque... return strings :P
	
pytorque.export(_getFieldValueSum,"MyScript","getFieldValueSum","Python method, return .dyn+value ",1,1)
if myscript.getFieldValueSum(5) != "12": print ("ERROR: TorqueObject export method")

#check inheritance in exported methods
def _simobject(self):
	return "SIMOBJECT::TEST"
	
def _scriptobject(self):
	return "SCRIPTOBJECT::TEST"
	
def _myscript(self):
	return "MYSCRIPT::TEST"
	
pytorque.export(_simobject,"SimObject","test","test inheritance",0,0)
#if myscript.test() != "SIMOBJECT::TEST": print "ERROR: inheritance"
#if pytorque.evaluate('MyScript.test();')  != "SIMOBJECT::TEST": print "ERROR: inheritance"

pytorque.export(_scriptobject,"ScriptObject","test","test inheritance",0,0)
#if myscript.test() != "SCRIPTOBJECT::TEST": print "ERROR: inheritance"

pytorque.export(_myscript,"MyScript","test","test inheritance",0,0)
#if myscript.test() != "MYSCRIPT::TEST": print "ERROR: inheritance"

if pytorque.evaluate('SimObject::test(0);') != "SIMOBJECT::TEST" : print "ERROR: inheritance"

def _onAdd(datablock,obj):
	obj = pytorque.TorqueObject(obj)
	obj.setFieldValue("isAdded",1)
	
#check override engine callbacks
#normaly onAdd is called on datablock and get 1 argument (object). Gui onAdd 0 args
#all method get
pytorque.export(_onAdd,"ScriptObject","onAdd","override on add",1,1)

pytorque.evaluate("new ScriptObject(MyScript2);")
myscript2 = pytorque.TorqueObject("MyScript2")

if myscript2.isAdded != "1": print "ERROR: override onAdd"





if sys.stdout.error ==  0 : print "ALL TEST OK :D"
sys.stdout = sys.stdout.log
print "------------------------------------------------------------------------------"
#45
07/05/2008 (1:02 am)
I followed your instructions Luis Anton, but what I got was:

"This application failed to start because python25.dll was not found. Reinstalling the application may fix the problem."

Did I mess something up?
#46
07/05/2008 (2:17 am)
Make sure that python25.dll is in the same folder as you Torque.exe. If it is already in there, then some probably went wrong on the code side of things.
#47
07/05/2008 (2:39 am)
If nothing has changed from the 1.7.0 version then the instructions don't mention that you need to add the python directories into your include path, I added:

../../../../../engine/lib/python
../../../python

I then added this to my library directorys:
../../../python
#48
07/05/2008 (2:43 am)
Ups sorry , i forgot to include python25.dll in zip :P

I updated the zip file
#49
07/05/2008 (9:47 am)
This worked great thanks Luis. I followed your instructions and it worked great.
#50
07/13/2008 (11:02 pm)
Help: how to fix the bug?

------ Build started: Project: PyTorque, Configuration: Release Win32 ------
Compiling...
pytorque.cpp
..\..\..\source\pytorque.cpp(236) : error C2039: 'sfnNameSpace' : is not a member of 'CodeBlock'
c:\Torque\TGEA_1_7_0\engine\source\console/codeBlock.h(18) : see declaration of 'CodeBlock'
..\..\..\source\pytorque.cpp(236) : error C2065: 'sfnNameSpace' : undeclared identifier
..\..\..\source\pytorque.cpp(238) : error C2039: 'sfnNameSpace' : is not a member of 'CodeBlock'
c:\Torque\TGEA_1_7_0\engine\source\console/codeBlock.h(18) : see declaration of 'CodeBlock'
..\..\..\source\pytorque.cpp(238) : error C2065: 'sfnNameSpace' : undeclared identifier
..\..\..\source\pytorque.cpp(609) : error C2039: 'iterateMainLoop' : is not a member of 'StandardMainLoop'
c:\Torque\TGEA_1_7_0\engine\source\app/mainLoop.h(13) : see declaration of 'StandardMainLoop'
..\..\..\source\pytorque.cpp(609) : error C3861: 'iterateMainLoop': identifier not found
---
#51
07/13/2008 (11:45 pm)
@Zihou Wei
You have to make the code changes that are in the PyToque1_7_1.diff file within the ZIP archive.
#52
07/15/2008 (1:15 am)
It very nice, pytorque run now!!!

first thanks Luis Anton Rebollo.
secoud thanks Trenton Shaffer.
no your help, no my happy time.
:D
#53
07/30/2008 (11:37 am)
Does this mean that we can now run py scripts as part of TGEA???

would that also mean that a set of python scripts for OSC can now be used to add OSC support to TGEA

( ie, having a game in TGEA, using glovePIE to handle wiimote interface, then sending information from glovePIE to torque via python???)

that would be awesome
#54
08/12/2008 (9:10 am)
Ok, with Python 1.7.1 it's built into the .exe of the game right? So, does one go about executing the .py files and is the .dll still needed in the /game directory? There seems to be no clear instructions on how to get this up and running.
#55
08/12/2008 (2:18 pm)
The dll is needed. As for executing python files there is some help over on MMOWorkshop.com but the site seems to be down(has been for over a day).

Here is the Google Cache page for that page though.
#56
08/12/2008 (3:02 pm)
There is a TGEA patch forthcoming soon for the Torque MMO Kit. It is a slightly different process than what is listed here, but it will allow the kit to be used with TGEA. It is currently a work in progress though.

Thanks.
#57
08/16/2008 (8:44 am)
So WTF is up with MMOWorkshop.com? The site has been down for days. Hope its not going to fall off the face of the planet and fade away.

The funny thing is I can still get in through SVN. So the darn thing is still resolving. Just looks like they completely pulled the site down.

I'm also seeing A LOT of grumbling going on over at Minions of Mirth, customers not getting any response from PG and a lot of the staff bailing on the project.

Prairie Games, if you need some help, I'll jump on board.

*EDIT
Well, the site is back up. Now if PG will release a patch for TGE 1.5.2 with TMK of the MMOToolkit. =]
#58
08/19/2008 (2:00 pm)
Just a note on this, the patch(es) have been sent to GG to examine. Hopefully it will be posted up if all is well sometime soon.

Thanks.

--Josh
#59
09/02/2008 (2:24 pm)
Hey, Xerves..
Any news on the post you made back on the August 19th, 2008 ?
Posted: Aug 19, 2008 17:00
Just a note on this, the patch(es) have been sent to GG to examine. Hopefully it will be posted up if all is well sometime soon.

Thanks.

--Josh
#60
09/02/2008 (4:00 pm)
Speaking of which -- If this is embedded into TEGA 1.7.1; how is it beeing invoked ?
pytorque.initialize(); ?
Or PyInit();
None of the above example show how to from the exe to execute a .py file.