Introduction to bzmap 2.0

  • Bzw man page (external link)
  • Bzw 2.0 texturing howto
  • Bzw 2.0 Physics drivers howto
  • Bzw 2.0 3d transformations howto
  • Introduction to bzmap 2.0
  • Bzmap is a very nice python module by Frederic Jolliton (cods in irc.freenode.net) that allows one to create very complicated maps, possibly based on randomness. Good examples are Fred's own tuxee map and bzflag olympics map. Tuxee map uses the new 2.0 version of bzmap, that includes many nice features:

    Installing bzmap

    I'm not going to teach any python here. If you are new to it, I recommend reading Dive Into Python. Bzmap 2.0 is not ready yet, and few bugs exist. Most important of these is that you shouldn't do a CSG operation with meshes that have aligned faces. (There is now a experiemental patch for this, see the end of this page) These instructions are highly directed towards unix/linux users, and don't directly work for windows. To get started, you need:

    Unless you like to get confused with long directory names, I recommend you create a new directory called 'bzmap', and under it 'system', 'runserver' and an empty directory 'testmap' and 'data' inside it. Under 'data' create bin, and copy bzfs from /usr/bin there. After that you should have files like:

    -+ bzmap
     |-+ system
     | |-- bzm
     | `-- etc.
     |
     |-+ runserver
     | |-- runserver.py
     | `-- etc.
     |
     `-+ testmap
       `-+ data
         `-+ bin
           `-- bzfs
    

    Creating our first map

    Under testmap, create testmap.py with following content. We will modify this later to do more complex stuff.

    from bzmap import *
    
    def build( game ) :
    
    	p1 = Point( -10 , -10 , 0 )
    	p2 = Point( 10 , 10 , 10 )
    	
    	game.world += Box( p1 , p2 )
    	
    

    Now open terminal, go to the bzmap directory and type following commands to generate the map and run it:

    mew bzmap $ system/bzm -o testmap/data/master testmap/testmap
    mew bzmap $ runserver/runserver.py -d testmap/data
    

    Now you can connect at server localhost, port 5154 to see your map. What you should see is a white box.

    Texturing

    Bare white box doesn't look good, so we need to add textures:

    	p1 = Point( -10 , -10 , 0 )
    	p2 = Point( 10 , 10 , 10 )
    	
    	b = Box( p1 , p2 )
    	b.sides.setTexture( 'boxwall' )
    	b.top.setTexture( 'roof' )
    	b.bottom.setTexture( 'roof' )
    	
    	game.world += b
    

    As you can see, boxes can be assigned to variables and they have methods. Many features are used in cods' own test script that you can find as system/test.py. You can also browse methods with pydoc:

    mew bzmap $ cd system
    mew system $ pydoc bzmap/mesh.py
    

    In the test.py you will see a more advanced textureBox function. Instead of typing all those commands just to get the box texture, we can include that in our script:

    from bzmap import *
    
    def textureBox( o ) :
    
    	o.setColor( Color( .8 ) )
    	o.setTexture( 'boxwall' )
    	o.top.setTexture( 'roof' )
    	o.bottom.setTexture( 'roof' )
    	o.textureScale( Point( 8 ) )
    	return o
    
    def build( game ) :
    
    	p1 = Point( -10 , -10 , 0 )
    	p2 = Point( 10 , 10 , 10 )
    	
    	b = Box( p1 , p2 )
    	game.world += textureBox( b )
    	
    

    If we wanted a red box, we would do:

    	b = Box( p1 , p2 )
    	textureBox( b )
    	b.setColor( Color( "#FF0000" ) )
    	game.world += b
    

    Cloning

    Box is an object, not a value. If you do:

    	b1 = Box( p1 , p2 )
    	b2 = b1.translate( Point( x = 50 ) )
    	game.world += b1
    	game.world += b2
    

    , boxes will be over eachother. All b.something() methods apply to the object. Instead, we have to do:

    	b1 = Box( p1 , p2 )
    	b2 = b1.clone()
    	b2.translate( Point( x = 50 ) )
    	game.world += b1
    	game.world += b2
    

    Translate moves object, just like shift in bzw.

    CSG operations

    CSG stands for computer solid geometry, and means substracting, addition and boolean operations on objects. Example:

    	wall = Box( Point( -400 , -10 , 0 ) , Point( 400 , 10 , 40 ) )
    	hole = Box( Point( -20 , -15 , 0 ) , Point( 20 , 15 , 10 ) ) # Avoid aligned faces, thus -15 and not -10
    	
    	game.world += textureBox( wall - hole )
    

    Using loops

    Sometimes you want to fill the map with red boxes..

    	box = Box( Point( 10 , 10 , 10 ) ) # Single point defines the size
    	textureBox( box )
    	box.setColor( Color( "#FF0000" ) )
    	
    	for x in range( -400 , 450 , 50 ) : # Range never includes the end-value, thus we use 450 not 400
    		for y in range( -400 , 450 , 50 ) :
    			game.world += box.clone().translate( Point( x, y, 0 ) )
    			
    

    Moving forward

    This was a very brief introduction to bzmap, but it should get you started. Test.py and Tuxee map are great resources for learning more. Also, if you have any questions, feel free to ask jpa- or jpa_ on irc.freenode.net. Have fun with bzmap!

    Patch for the aligned faces-bug

    I've developed an experiemental patch to fix the aligned faces bug. This patch is against experiemental version -patch211. To apply, run:

    cd system/bzmap
    patch csg.py < diff-alignedfaces
    
    ©Petteri Aimonen 2005