Develop a framework

Dawgmatic

13-01-2006 20:44:24

I just wanted a show of hands, if some people would like to collaborate to develop a framework on top of pyOgre

griminventions

13-01-2006 21:14:21

Actually, I'm in the process of doing that right now, between finishing my next game (which doesn't use PyOgre). My PyOgre engine is open source, though I don't have the repository set up or any info yet (just got the sourceforge project approval a couple days ago). Golem Engine

I'm creating it with a heavy bias for creating commercial, downloadable games since that's what I do. What that means is it will eventually include things like player profiles, upsell marketing support, automated logging features for gathering permission-based statistics, auto-updating, push-marketing inside the game for cross-promotion, etc.

It's at a very embryonic stage currently. I've got an event-based input system going, and I'm currently working on a state manager. My current goal is to make a simple space invaders game to get the basic structure designed and tested. I need to become familiar with OGRE during this process also, so it's an uphill and slow battle. I really don't expect this version to be the "real" implementation, but it sure is fun. :)

Not sure when I'll make the first code drop to the repo, but I'm probably going to wait for subversion access on sourceforge, which is supposed to go live in February. I'd be happy to share before then via other means (email perhaps?).

Email me if you want to discuss plans: jason .at. griminventions.com.

mthorn

17-01-2006 23:00:16

http://www.python-hosting.com/freetrac has free Trac and SVN hosting for open source projects. My project is hosted there http://b3.python-hosting.com

griminventions

18-01-2006 01:01:03

I contacted them but didn't get any reply. I guess they don't have much faith in game frameworks or something. *shrugs*

mthorn

19-01-2006 19:37:44

Took a day or two for me to get a response.

griminventions

19-01-2006 20:30:30

It's been almost 2 weeks. :) SourceForge will do fine since they're using svn now (well, next month).

mthorn

26-01-2006 07:34:01

I can host SVN/website for you. I'm interested in this project.

griminventions

26-01-2006 11:29:33

@mthorn: I'll probably stay with sourceforge, but if you can offer something they can't, I'm definitely interested. Thanks for the generosity! :)

For anyone curious, I've got 2 simple demos going with this framework now (1 is a space invaders sort of shooting demo, the other is a driving on terrain demo), and it includes a lot of core functionality from input to sphere collision to audio. I'll be adding some ODE physics eventually, but I'm probably going to complete a game for a competition first to get the whole system more mature.

Interestingly, since the game objects are assembled with discrete components, I was able to create my second demo in a few hours and only by making new components specific to the demo's needs. All other components were reused without modifications. I also had to change the state handlers, but that didn't take much effort.

It works wonderfully and even helps to encapsulate specific implementation details (like coupling with a specific API) by containing that in the component. For instance, I used pySonic for sound, and the specifics of that is mostly in the pySonicComponent I created. It would be very easy to switch to another audio library by creating a new component for that lib. I'm hoping that I can do physics this way, too, but that is more involved than audio so it might require a hook in the update loop. Still, I don't foresee it causing a bunch of API-specific code outside the components.

Here's the code for my silky-smooth 3rd person chaseCamComponent in it's entirety (loosely based on Kencho's tutorial):
__author__ = "Jason McIntosh, www.griminventions.com"

from globals import *
import component
import componentManager
import logging
import math
import ogre3d
import pyogre.ogre as ogre

logger = logging.getLogger( "chaseCamComponent" )
logger.addHandler( logHandler )

#------------------------------------------------------------------------------
# ChaseCamComponent
#------------------------------------------------------------------------------

CAM_MODE_SHOULDER = hash( "camShoulderChase" ) # over the shoulder
CAM_MODE_FIXED = hash( "camFixedChase" ) # fixed distance above (not implemented)
CAM_MODE_FREE = hash( "camFreeChase" ) # freely rotate (not implemented)

class ChaseCamComponent( component.Component ):
def __init__( self, name, node = None, **kw ):
component.Component.__init__( self, name, "chaseCamComponent", **kw )
self.node = node # the node to follow
self.camNode = None # node the camera's attached to
self.targetNode = None # node the camera tries to match position to
self.lookAtNode = None # node the camera tracks
self.tightness = 0.075
self.mode = CAM_MODE_SHOULDER

def delete( self ):
logger.debug( "deleting " + self.name )
if self.camNode is not None:
self.camNode.detachAllObjects()
if self.camNode.parentSceneNode is not None:
self.camNode.parentSceneNode.removeChild( self.camNode )
ogre3d.SceneManager.destroySceneNode( self.camNode.name )
self.camNode = None
if self.targetNode is not None:
self.targetNode.detachAllObjects()
if self.targetNode.parentSceneNode is not None:
self.targetNode.parentSceneNode.removeChild( self.targetNode )
ogre3d.SceneManager.destroySceneNode( self.targetNode.name )
self.targetNode = None
if self.lookAtNode is not None:
self.lookAtNode.detachAllObjects()
if self.lookAtNode.parentSceneNode is not None:
self.lookAtNode.parentSceneNode.removeChild( self.lookAtNode )
ogre3d.SceneManager.destroySceneNode( self.lookAtNode.name )
self.lookAtNode = None
self.node = None

def initialize( self ):
componentManager.addUpdater( self, self.getUpdater )
if self.node is None:
self.node = self.entity.getComponentByType( "nodeComponent" )
if self.node is not None and self.node.node is not None:
# targetNode follows the entity rigidly from behind
# the camNode will reposition smoothly to be at the targetNode
self.targetNode = self.node.node.createChildSceneNode( "camTargetNode" )
self.targetNode.position = 0, 10, -100
# the camNode will look at the lookAtNode (in front of entity)
self.lookAtNode = self.node.node.createChildSceneNode( "camLookAtNode" )
self.lookAtNode.position = 0, 0, 150
# camNode will move to follow the entity
self.camNode = self.node.node.parentSceneNode.createChildSceneNode( "camNode" )
self.camNode.setAutoTracking( True, self.lookAtNode )
self.camNode.setFixedYawAxis( True )
self.camNode.attachObject( ogre3d.camera )

def pause( self ):
componentManager.removeUpdater( self )

def unpause( self ):
componentManager.addUpdater( self, self.getUpdater )

def getUpdater( self ):
"Update the camera's position to follow the targetNode."
while True:
if self.mode == CAM_MODE_SHOULDER:
# move cam toward target node
v1 = self.camNode.worldPosition
v2 = self.targetNode.worldPosition
dir = v2 - v1
self.camNode.translate( dir * self.tightness )
# don't let the cam go below the node being chased
x, y, z = v2
x2, y2, z2 = self.camNode.position
if y2 < y + 3:
self.camNode.position = x2, y + 3, z2
# force camera above ground
raySceneQuery = ogre3d.SceneManager.createRayQuery(
ogre.Ray( self.camNode.position, ogre.Vector3.NEGATIVE_UNIT_Y ) )
for queryResult in raySceneQuery.execute():
if queryResult.worldFragment is not None:
if queryResult.distance < 20.0:
x, y, z = self.camNode.position
self.camNode.position = (x, y - queryResult.distance + 20.0, z)
yield None

You may notice that the getUpdater() function is a generator. That's to maximize speed and allow the engine to distribute processing across frames if necessary.

I love Python. :)

mthorn

26-01-2006 15:28:22

@mthorn: I'll probably stay with sourceforge, but if you can offer something they can't, I'm definitely interested. Thanks for the generosity! :)


SVN and Trac.

Kentamanos

26-01-2006 23:54:07

Trac is pretty sweet stuff...

santagada

28-01-2006 17:06:01

This is a great idea, but maybe it would be better using ALPY and not pysonic as fmod is expensive for comercial games.

But really great idea, and if you can please register your project at http://cheeseshop.python.org/pypi so every python programmer has an easy way to find your package. And to make it easy to install maybe you should look at making python eggs

griminventions

01-02-2006 13:07:57

This is a great idea, but maybe it would be better using ALPY and not pysonic as fmod is expensive for comercial games.
There's a small developer option which is around $100 per game, I think. But it's very easy to create a component for ALPy if needed. I made the FMOD component in about 10 minutes (most of that time spent reading the API for pySonic).

...if you can please register your project at http://cheeseshop.python.org/pypi so every python programmer has an easy way to find your package.
Thanks for the suggestion. I'll do that when the first release is ready.