Game Development Community

The start of the Arena

by David Horn · 12/06/2007 (2:35 pm) · 9 comments

OK, well I think I've got the makings of an arena.

www.homebrewwrestling.com/hbw1.jpg
www.homebrewwrestling.com/hbw2.jpg
www.homebrewwrestling.com/hbw3.jpg
It consists of an entrance way complete with smoke effects, a ring and a 3D crowd.
The ring, the mat and the carpet are actually the tops of .dif blocks so that shadows will easily be cast on to them. The entire structure is inside a dif as well to minimize the effects of the sun.

The spotlights are volume lights controlled with script that rotates the light until it gets to a certain point, then switches direction

datablock StaticShapeData(SpotLightLarge)
{
   category = "Items";
   shapeFile = "~/data/shapes/ring/spotlight.dts";
};
   function SpotLightLarge::onAdd(%this,%obj){   
      // %obj is the object being added to the world   
      // with %this datablock.  Start up a thread on the   
      // new object.  Since the wave sequence is cyclic   
      // this animation will run continously.   
      %obj.playThread(0,"ambient");
      }   
   function StaticShapeData::create(%block){   
      // The mission editor invokes this method when it   
      // wants to create an object of the given datablock   
      // type.  You only need one of these methods for any   
      // class/datablock type (in this case StaticShape).   
      %obj = new StaticShape()   
      {      
         dataBlock = %block;   
         };   
         return(%obj);
   }

While most of the crowd is TSStatic shapes, several members of the crowd - including the front row - are StaticShapes and have special animations. I've written a function where every so often (a rendom time plus 4 seconds), a random animation happens.

datablock TSShapeConstructor(audiencemember2Dts){   
      baseShape = "~/data/shapes/ring/audmember2.dts";   
      sequence0 = "~/data/shapes/ring/audiencemember_clap.dsq clap";
      sequence1 = "~/data/shapes/ring/yell.dsq yell";
      sequence2 = "~/data/shapes/ring/standupa.dsq standupa";
      sequence3 = "~/data/shapes/ring/standupb.dsq standupb";
      sequence4 = "~/data/shapes/ring/ohno.dsq ohno";
      sequence5 = "~/data/shapes/ring/lookl.dsq lookl";
      sequence6 = "~/data/shapes/ring/lookr.dsq lookr";
      sequence7 = "~/data/shapes/ring/highclap.dsq highclap";
      sequence8 = "~/data/shapes/ring/comeon.dsq comeon";
      sequence9 = "~/data/shapes/ring/amb.dsq amb";
      };
   

   datablock StaticShapeData(audiencemember2){   
      category = "Audience";   
      shapeFile = "~/data/shapes/ring/audmember2.dts";
      };   
   function audiencemember2::onEndSequence(%this,%obj){           
      
      %obj.playThread(0,"amb");
      %r = ((getRandom(9) + 1) * 1000) + 3000;
      schedule(%r,0,animMe,%obj);

      } 

   function StaticShapeData::create(%block){           
         %obj = new StaticShape()         
         {               
            dataBlock = %block;            
            };            
            return(%obj);   
         }
   function audiencemember2::onAdd(%this,%obj){   
      %obj.playThread(0,"amb");
      %r = (getRandom(10) * 1000) + 5000;
      schedule(%r,0,animMe,%obj);
      }   
      
      
   function animMe(%this,%obj){
      %an = getRandom(8) + 1;
      echo(%an);
      switch (%an) 
         {
         case 1:
            %this.playThread(0,"clap");

         case 2:
            %this.playThread(0,"yell");

         case 3:
            %this.playThread(0,"standupa");

         case 4:
            %this.playThread(0,"standupb");

         case 5:
            %this.playThread(0,"ohno");

         case 6:
            %this.playThread(0,"lookl");

         case 7:
            %this.playThread(0,"lookr");

         case 8:
            %this.playThread(0,"highclap");

         case 9:
            %this.playThread(0,"comeon");

         }

      
   }

The only thing I don't like about this script is that the dts is hard-coded into the datablock. so I had to re-create this script for each different member of the audience

datablock TSShapeConstructor(audiencemember3Dts){   
      baseShape = "~/data/shapes/ring/audmember3.dts";   
      sequence0 = "~/data/shapes/ring/audiencemember_clap.dsq clap";
      sequence1 = "~/data/shapes/ring/yell.dsq yell";
      sequence2 = "~/data/shapes/ring/standupa.dsq standupa";
      sequence3 = "~/data/shapes/ring/standupb.dsq standupb";
      sequence4 = "~/data/shapes/ring/ohno.dsq ohno";
      sequence5 = "~/data/shapes/ring/lookl.dsq lookl";
      sequence6 = "~/data/shapes/ring/lookr.dsq lookr";
      sequence7 = "~/data/shapes/ring/highclap.dsq highclap";
      sequence8 = "~/data/shapes/ring/comeon.dsq comeon";
      sequence9 = "~/data/shapes/ring/amc.dsq amc";
      };
   

   datablock StaticShapeData(audiencemember3){   
      category = "Audience";   
      shapeFile = "~/data/shapes/ring/audmember3.dts";
      };   
   function audiencemember3::onEndSequence(%this,%obj){           
      
      %obj.playThread(0,"amc");
      %r = ((getRandom(9) + 1) * 1000) + 3000;
      schedule(%r,0,animMe,%obj);

      } 

   function StaticShapeData::create(%block){           
         %obj = new StaticShape()         
         {               
            dataBlock = %block;            
            };            
            return(%obj);   
         }
   function audiencemember3::onAdd(%this,%obj){   
      %obj.playThread(0,"amc");
      %r = (getRandom(10) * 1000) + 5000;
      schedule(%r,0,animMe,%obj);
      }   
      
      
   function animMe(%this,%obj){
      %an = getRandom(8) + 1;
      echo(%an);
      switch (%an) 
         {
         case 1:
            %this.playThread(0,"clap");

         case 2:
            %this.playThread(0,"yell");

         case 3:
            %this.playThread(0,"standupa");

         case 4:
            %this.playThread(0,"standupb");

         case 5:
            %this.playThread(0,"ohno");

         case 6:
            %this.playThread(0,"lookl");

         case 7:
            %this.playThread(0,"lookr");

         case 8:
            %this.playThread(0,"highclap");

         case 9:
            %this.playThread(0,"comeon");

         }

      
   }

As you can see, the only thing that changes is the number. I'm wondering if there's a more efficient way to do this?

The next task is to make a user-based editor for the arena. In my previous game, the user could customize the ring apron, the rope color, and the color of the lights. I want to let users "mod" this game as much as possible - at least from a texture perspective. That way, if they want the (copyright) WWE logo on the apron, they can make a texture for that and load it in. Looks like I'll be researching the setSkin function?Hopefully it works on .dif files as well as dts??

So next up... "the customize your arena" feature. I'll be researching:
1. swapping textures
2. the ins and outs of gui
3. being able to set global variables and the reference those variables in the mission scripts
4. file i/o - for searching through textures - and incorporating that into the gui

#1
12/06/2007 (3:40 pm)
Good looking job. :)
#2
12/06/2007 (4:08 pm)
Excellent job! It's very well put together. But I notice after the first 2-3 rows you go from fully formed people to a textured audience. I don't know if you plan on having that be visible depending on your lighting. But it might be more effective if you had several rows of billboard audience members before you switched to a texture. As for the animations, are you going to script any events that they will all cheer at instead of just randomly do things?
#3
12/06/2007 (7:33 pm)
Looking good. I've played every wrestling game since the Nintendo. If you need someone to test it, I would be happy to do it.
#4
12/06/2007 (9:56 pm)
James,
i agree, however, I'm kinda "wussing" out. I'm concerned about the poly count. I'd rather have the processor get 6 - 10 wrestlers in the ring at one time as opposed to having another section of polygon audience members. even the ones you see in the pics aren't all moving. some are just static.

I just don't know how powerful torque is when processing these things?
#5
12/07/2007 (7:46 am)
Cool!
#6
12/07/2007 (3:47 pm)
You might be able to get another row or two of polygon crowd in there before turning to textures crowd, this is the way that other games with crowds accomplish it.

In terms of Torque processing power, it all depends on your minimum target machine and what it can handle in Torque. I think most Torque users shoot for about 1ghz, 256mb RAM and 64mb video card these days. If you can find a spare machine like that, why don't you load up your game and add crowd until the game won't work anymore. Albeit, those requirements I think are pretty low for todays standards, it is almost 2008 and I had that comparable machine in 2000.
#7
12/07/2007 (5:43 pm)
perhaps if later on I have several wrestlers in the ring at once with minimal framerate drop, then I can add another row or two. I just want to make sure the frames per second is as good as possible
#8
12/09/2007 (4:01 am)
David,

If you take out the 3rd row of modeled people you could easily add 6 rows of billboards and have a much lower polygon count. Or you could even model it directly into the the BSP stadium. Instead of having a steady incline make the stadium seats shaped like steps and on the faces of these steps texture in people. If its dark enough in the audience that you could probably get away with panting around them black.
#9
11/02/2008 (11:47 am)
hello there...

Why didn't work on mine?

Where do I put this script?