Game Development Community

Digging in to RTS

by Zergcow · in RTS Starter Kit · 02/18/2008 (1:38 pm) · 19 replies

Keep an eye out for changes: Updated on Feb 28th 2008.
*added problem #5
*solved buttons above buildings


Hi there my name is Brandon and I have decided to run with the RTS kit. So this thread will be a sort of place to talk about what I am doing and maybe as a community discuss solutions to different problems I run into.

I will organize it by posting and updating in this first post. It is here where I will put current problems, active discussions, old problems, and old solutions. So let's start.

My plan...
It's kind of a sim city approach. I don't care about combat or even people. I want buildings and city style creation. Things I would compare my project to would be train tycoon or sim city.

I want buildings that can be connected using pipes (much like the click drag walls of Age of Empires) and I want to be able to select my buildings and open up a properties sheet. Then I want to be able to change a few attributes and have that saved on that one building. So basically the game is building a city and micro managing each building to increase productivity of the overall city. Upgrade the buildings and connect factories to resource buildings using pipes to increase workflow.

Current Problems...
1) creating a click and drag wall.
2) right click menu on buildings with 3 or more options that will each bring up a different UI window
3) a game UI that has a mini map and access to windows that will show the overall city stats and the selected building/buildings stats
4) ability to upgrade buildings. Like factory_base to factory_upgraded but keep the stats and info from the original building. (The upgrade would also change the abilities of the building and would give it extra options.)
5) The ability to name buildings as you place them!


Active Discussions or Possible Solutions...


Old Problems and Solutions...
1) importing models from maya8 to TGE 1.5.2 (the model doesn't show up at all)
*solution: everything in the model has to end in the same exact number meaning all polys and everything under the start01 needs to end in the same number. Example: polycube_end1, anothercube_end1, again_end1, head_end1
2) ability to rotate a building on the Y axis befor placing it.
*solution posted below.
3) solution to Icons (or buttons or any gui) above the buildings (its now working with 1.5.2)

Updates and other info...
I will be updating this a few times a week so be sure to check back often! And please leave comments and/or suggestions for me here I want this whole project and the ideas and solutions to be open to everyone. If you have any questions about how I did things I will tell you so just ask.

#1
02/18/2008 (4:32 pm)
Good post Brandon! it seems like a great sim-game :)

About "Current Problems"...

1) Intresting. You could start by trying to use the current building placement mechanism, and keep placing new buildings as the mouse move... This point anyway, will require work.

2) you should check inputhandler.cs for determining the right click action on the building; and also, you could prototype the idea by reemplazing (for now) the menu, with the current SelectionDisplay.

3) You can easily add icons over the buildings by implementing the Orion Elenzil's Gui3DProjectionCtrl resource. You have to be able to recompile the source though.

4) Why is that a problem? The current minimap does not work for your needs?

5) I think on this point the most practical option is to just switch datablocks. That way, you change the stats and the building shape, while conserving other properties. Read setDataBlock TDN article for more info on changing an object's datablock.

6) This point, as the 1, will require work. Actually this is in my todo list, but cant tell you about times.


Btw, Welcome to the Madhouse! And remember: here we kill -slow and painfully- those who abandon their RTs projects.
#2
02/18/2008 (6:19 pm)
Hey thanks for the feedback! here is a little background real quick ... I actually have a BA in Digital Art so my skills are in maya and animation. but i am not an idiot at programing which is why i felt i could take on this monumental task.

I wanted to give you a huge thank you for that link to 3Dprojectionctrl that is amazing... i knew there was something like that out there. as for the #4 its not so much the minimap but an all inclusive UI that has acess to popup windows and such. I was only going to tweak the current minimap to fit.

I actually just got about 8 models made and textured today and got the startup screens and login UI done. I am about to start work on the Main game UI (#4 on my list) and while i am at it I am going to be working on the right click feature.

I will post more tomarrow night but if anyone has any more links I would love to hear from you! thanks.

Update:

found a thread with information regarding building rotation in RTS. It could be the jump off point i need to get it working. http://www.garagegames.com/mg/forums/result.thread.php?qt=25942
#3
02/19/2008 (9:07 am)
Point 6
I implemented this a while back for a project I was working on. It can be done easily in script.

First - decide on the input that will rotate the building marker. I used the mouse wheel (mouse zaxis) for this. So open up client/scripts/default.bind.cs and add this line to it in the section with the other moveMap.binds:

moveMap.bind(mouse0, "zaxis", rotateBuildingMarker);

Now, we'll add a variable to track the z-rotation of the building marker.
Open up client/scripts/playGui.cs, and in the function startPlaceBuilding() add this line after $NewBuilding.setTransform( "0 0 0 0 0 1 3.14159" );

$NewBuilding.zrot = 3.14159;

now we need a function to actually do the rotation when the mouse wheel is moved. Add this function to the end of playGui.cs:

// rotate building marker before placement
function RotateBuildingMarker(%val)
{
   if (!isObject( $NewBuilding)) // check if building marker exists
      return;
   
   // get current rotation of marker
   %theta = $NewBuilding.zrot;
   // get position of building marker
   %posvec = getWords($NewBuilding.getTransform(), 0, 2);
   
   // some useful numbers to make life easier
   %PI2 = 3.14159 * 2;
   %PIOVER2 = 3.14159 / 2;
   
   // now work out the new rotation. I'm using 90 degree (pi / 2) steps for the rotation to keep the 
   // buildings aligned to a grid. If you want for example 45 degree intervals, you'll need to
   // use %PIOVER2 / 2 as the rotation increment
   if( %val > 0 )
     %theta += %PIOVER2;
   else if( %val < 0 )
     %theta -= %PIOVER2;   
     
   // constrain the rotation to be within 0 and 360 (2 * pi) degrees
   if (%theta < 0)
      %theta += %PI2;
   else if (%theta >= %PI2)
      %theta -= %PI2;
   
   // now set the new transform of the building marker
   $NewBuilding.setTransform(%posvec SPC "0 0 1" SPC %theta);
   // track the new z rotation
   $NewBuilding.zrot = %theta;     
}

And that should be all that's needed.
#4
02/19/2008 (11:29 am)
Hey nice code there. I tried it and i cant seem to get it working just right. the middle mouse button still zoomes up and down on the map. even when i am placing a building. I tried making it "moveMap.bind(mouse, "zaxis", rotateBuildingMarker);" instead of mouse0 and no luck. even tried deleting the other zaxis, then tried taking the quotes out and deleting the other zaxis. I dont know what i am doing wrong lol is it obvious i am not much of a coder?

Speaking of placing buildings i am trying to make a second, third, fourth building button to place different structures. Making the button was easy as pie. It even finds the correct model and makes it transparent green. My problem is that when i place the building it places the "building/building.dts" structure instead of mine. So where did i go wrong. here is what i did...

Gonna split this post up ... hold on... see next post V
#5
02/19/2008 (11:36 am)
Step 1 copy the "server>scripts>items>building.cs" and past it into that directory (server>scripts>items>) then rename it from "copy of building.cs" to "tank.cs" here is the code I put into that file.

datablock RTSUnitData(TestBuildingBlock : UnitBaseBlock)
{
   shapeFile = "~/data/shapes/my/tank.dts";
//-----------------------Begin Bug Fix: http://www.garagegames.com/mg/forums/result.thread.php?qt=23223
   RTSUnitTypeName = "tank";
//-----------------------End Bug Fix 
   boundingBox = "10.0 10.0 3.0";
};

function serverCmdPlaceTank(%conn, %transform, %data)
{
   //TODO: do some checks to verify that we can place a building here
   %b = new RTSBuilding()
   {
      datablock = %data;
      scale = "1 1 1";
   };
   %b.setTransform( %transform );
   
   %b.client = %conn;
   %b.setTeam(%conn.getTeam());
   %b.setControllingConnection(%conn);
   %conn.buildings.add(%b);
   
   %b.playRootAnimation();

//-----------------------Begin Bug Fix:  http://garagegames.com/mg/forums/result.thread.php?qt=23324  
   //MissionCleanup.add(%b);
//-----------------------End Bug Fix 
}

Next I edited the "client>ui>playGui.gui" file and basically all i did was copy the "new GuiBitmapButtonCtrl(build)" and pasted it right after that GuiBitmapButtonCtrl then changed the new one to look like this...

new GuiBitmapButtonCtrl(build) {
      canSaveDynamicFields = "0";
      Profile = "GuiDefaultProfile";
      HorizSizing = "left";
      VertSizing = "bottom";
      position = "506 1";
      Extent = "64 64";
      MinExtent = "8 2";
      canSave = "1";
      Visible = "1";
      Command = "startPlaceTank();";
      hovertime = "1000";
      text = "Build Tank";
      groupNum = "-1";
      buttonType = "PushButton";
      bitmap = "./build";
   };

After that I edited the "client>scripts>playGui.gui" here is the whole thing (took out that code for building rotation i cant seem to get working to shorten my post) here are the areas I changed...


Added tank starting here just look for the areas that say tank. Also the startplacebuilding function I just copied and pasted right after then modified.
//-----------------------Begin Bug Fix: http://www.garagegames.com/mg/forums/result.thread.php?qt=23223
   switch$(%this.getSelectedObject(%objID).getRTSUnitTypeName())
   {
      case "bonecracker":
         return 0;
      case "shocker":
         return 1;
      case "rifleman":
         return 2;
	  case "building":
         return 3;
	  case "tank":
         return 5;

   }
//-----------------------End Bug Fix  
}

function GuiRTSTSCtrl::getBitmapFromID(%this, %typeID)
{
   switch(%typeID)
   {
      case 0:
         return "starter.RTS/client/ui/selectionDisplay/boneCrackerPortrait";
      case 1:
         return "starter.RTS/client/ui/selectionDisplay/shockerPortrait"; 
      case 2:
         return "starter.RTS/client/ui/selectionDisplay/riflemanPortrait"; 
      case 3:
         return "starter.RTS/client/ui/selectionDisplay/buildingPortrait"; 
      case 5:
         return "starter.RTS/client/ui/selectionDisplay/tankPortrait"; 

   }
}

//-----------------------------------------------------------------------------

function refreshBottomTextCtrl()
{
   BottomPrintText.position = "0 0";
}

function refreshCenterTextCtrl()
{
   CenterPrintText.position = "0 0";
}

//-----------------------------------------------------------------------------

function startPlaceBuilding()
{
   // Building is already being placed
   if( isObject( $NewBuilding ) )
      return;
      
   echo("Starting to place building!");
   $NewBuilding = new RTSBuildingMarker()
   {
      scale = "1 1 1";
      thedatablock = "TestBuildingBlock";
      shapeName = "~/data/shapes/building/building.dts";
   };
   // Starting position = (0,0,0) with PI radians of rotation around the Z axis
   $NewBuilding.setTransform( "0 0 0 0 0 1 3.14159" );
   $NewBuilding.zrot = 3.14159;
   $NewBuilding.setOverrideTexture("starter.rts/data/shapes/building/building_green");
   PlayGui.startBuildingPlacement($NewBuilding);
}

function GuiRTSTSCtrl::placeBuilding(%this)
{
   echo("Client sending building notify!" SPC $NewBuilding.getTransform() SPC $NewBuilding.thedatablock);
   commandToServer('PlaceBuilding', $NewBuilding.getTransform(), $NewBuilding.thedatablock);
   $NewBuilding.delete();
}

function startPlaceTank()
{
   // Building is already being placed
   if( isObject( $NewBuilding ) )
      return;
      
   echo("Starting to place building!");
   $NewBuilding = new RTSBuildingMarker()
   {
      scale = "1 1 1";
      thedatablock = "TestBuildingBlock";
      shapeName = "~/data/shapes/my/tank.dts";
   };
   // Starting position = (0,0,0) with PI radians of rotation around the Z axis
   $NewBuilding.setTransform( "0 0 0 0 0 1 3.14159" );
   $NewBuilding.zrot = 3.14159;
   $NewBuilding.setOverrideTexture("starter.rts/data/shapes/my/tank_green");
   PlayGui.startBuildingPlacement($NewBuilding);
}

function GuiRTSTSCtrl::placeBuilding(%this)
{
   echo("Client sending building notify!" SPC $NewBuilding.getTransform() SPC $NewBuilding.thedatablock);
   commandToServer('PlaceTank', $NewBuilding.getTransform(), $NewBuilding.thedatablock);
   $NewBuilding.delete();
}


ok after that i went to "server>init.cs" and added my new tank.cs file to the list like this (this is just the area of code where i added it... not the whole thing)...

exec("./scripts/core/buffs.cs");
   exec("./scripts/globals.cs");

   exec("./scripts/items/camera.cs");
   exec("./scripts/items/crossbow.cs");
   exec("./scripts/items/staticShape.cs");
   exec("./scripts/items/building.cs");
   exec("./scripts/items/tank.cs");
   
   exec("./scripts/core/game.cs");
}

so did i leave something out? why wont my tank pop up once i place it? it just pops up the building.cs every time.

also i had a look at the world domination mod but i didnt want the peons in my game or the resource gathering. so i figured i would try my own methods. I know they have the ability to build multiple buildings in that thing but i cant figure out the data flow on how its done. anyone got any suggestions or help?

Also i am thinking i may start posting free models in here occasionally. it seems to be my strong point and i figure i would give what i can to the comunity since i seem to be getting a positive response and great imput back.

sorry if there is any spelling errors i am at work and in a hurry.
#6
02/19/2008 (5:30 pm)
@Guy Allard...! Long time since your last post on this forum, great to read you here!
Cool snipet btw.
What are you working in?

@Brandon, at first sight you have some obvious problems.

For instance, in your tank.cs file, which is the datablock of your new building, you have this line:
datablock RTSUnitData([b]TestBuildingBlock [/b]: UnitBaseBlock)
But TestBuildingBlock, is the name of the original building datablock, you cannot use the same name for both! So change that to somthing like "TankBlock".

An then, on your newly created "startPlaceTank" function (and I will not opine about your programming practices here... XD ), you have the line:
thedatablock = "TestBuildingBlock";
That should be changed now to:
thedatablock = "TankBlock";


On the rotate building thing, I'll be checking out the Guy's snipet later.
#7
02/19/2008 (6:01 pm)
Ok i started trying it again. this time with a pumpjack. followed the same steps and changed the info you said to change now i get this error in the debug.

www.zergcow.net/media/debug.JPG
so obviously the big differance is when i click to place i get nothing instead of the wrong building. but am i supposed to some how register that new block somewhere? Do i just do a fresh build?
#8
02/19/2008 (6:51 pm)
You should make some debugging there and look at whats sending
commandToServer('PlaceTank', $NewBuilding.getTransform(), [b]$NewBuilding.thedatablock[/b]);

I think you've made some mistake on the steps indicated on my last post, so double check all changes involving datablock names.

...

Did you took in mind that if you change the name of the building, you have to make all the series of changes for each new building again isnt?
#9
02/19/2008 (7:04 pm)
Lol yea everything that was tank i changed to pumpjack for the pumpjack DTS. But good looking out because i have been known to do that stuff!

the ghost image shows up just not the actual pumpjack. let me put that debug in and take a gander.
#10
02/19/2008 (10:50 pm)
Hey big thank you for the help. I did a few echo commands and tried to trace the building.dts and pumpjack.dts from pressing the button to creation and found that I forgot to include the pumpjack.cs in the "server>scripts>game.cs" like this...

exec("~/server/scripts/items/crossbow.cs");
   exec("~/server/scripts/items/staticShape.cs");
   exec("~/server/scripts/items/building.cs");
   exec("~/server/scripts/items/pumpjack.cs");
   exec("common/server/lightingSystem.cs");


   // Keep track of when the game started
   $Game::StartTime = $Sim::Time;
}

so that problem is solved. now i can make alot of buttons with different buildings. now to get that rotate bulding working!

oh also i decided that i am going to write up these things in tutorials. I figured if i am having such a hard time doing this i cant be the only one and it will be nice to share my learning.
#11
02/20/2008 (9:30 am)
About my current problem 1 (the wall thing) I was going to use it to make pipes to connect buildings. could i not just make a 2d graphic in photoshop and use a pathfinding method to select two buildings and click a connect button? the pathfinding would find a path between the two buildings and place the graphic down. it would be similar to the selection circles. the only differance is making bends and turns in the graphic and having the game know when to place what.

Also when thats up and going it shouldent be too hard to make the 2d image into 3d models. Just kinda thinking as i go. for now i am working on the menu thing.
#12
02/20/2008 (9:51 am)
Brandon -

The building marker isn't rotating because the default RTS kit already has the mouse z axis bound to the camera zoom function (updateOrbitDistance). I forgot about that as my codebase was pretty heavily modified, and I had disabled the camera zoom.

If you edit client/scripts/movemap.bind.cs and comment out the line:

moveMap.bind( mouse, zaxis, updateOrbitDistance );

Now, from what I remember, you will need to delete client/scripts/config.cs and client/scripts/config.cs.dso before changes to the movemap will work.

so do that, and fire up the game, and if you still have the zaxis bind from the code I posted above, it should work, but now you won't be able to zoom the camera. If that works, then you need to create a different bind for the building marker rotation - maybe holding shift + mousewheel would work

so change the moveMap.bind( mouse, zaxis, rotateBuildingMarker);
to
moveMap.bind( mouse, "shift zaxis", rotateBuildingMarker );

and then holding shift while moving the mouse wheel should do the job. Remember to uncomment // moveMap.bind( mouse, zaxis, updateOrbitDistance ); to add the camera zoom back in.

Hope that helps :)

@Novack - glad to see you're keeping this place alive :) I'm not working on anything specific atm - just messing with ideas and trawling the help wanted ads for a decent project (hint).
#13
02/20/2008 (1:04 pm)
Hey awsome input. i did something simular this morning and got it working. the biggest thing was changing it to shift function and i ran delete dsos and delete prefs and it works like a charm. i also did
%theta -= %PIOVER2 / 6;

to make the placement more accurate but still on a bit of a grid. I think that means every time i move the mouse wheel one click it rotates 11.25 degrees

either way i love it. thanks so much for the help.
#14
02/21/2008 (11:56 am)
Hey if anyone gets the time could you please explain Orion Elenzil's Gui3DProjectionCtrl resource a little bit to me. he never explained where to create those files. do i create them in VS2005? or can i make them in notepad? superedi? and when i make them do i recompile? I am so lost. that whole resource is really vauge. any help would be awsome thanks! (mostly i want to know what folder to put the files in)

Also, on a side not i got the right click menu working. i right click and a menu pops up. only problem is the menu takes up the whole screen and dosent go away. so I think i need to start over on that one. there has to be a way to include info in a buildings datablock on where to get info for that building. then pull it up in a window when you right click on the building.

I REALLY want to be able to put the button above the building and have that one pop the window open so i really need to get Orion Elenzil's Gui3DProjectionCtrl resource working first.
#15
02/21/2008 (6:49 pm)
Brandon this time is too difficult to explain. If you dont understand how to use source files, or how or when to recompile, or not even if it matters what editor to use thats a different story, its just too far from the help we can give through a forum.

However I think you somehow already did it, because you are using the last kit update, which means that by now you did a build.

So! I'll give you some hints on the resource, but I recommend you to read on TDN, how to set the engine for compilation, and even read a little on what the compilation thing is.

1) The files to be created have to be placed by design, on the engine/gui folder. It does not say it, but for who knows what to look, its obvious.
2) the editor used to actually create the files does not matter at all, as far as you incorporate the files to the project, in your case, on the VS2005.

The resource is really not vague at all pal, it is just made for people that understand the basics of programming.

Maybe, and please dont take it bad, you should focus on the art side, develop a good design document, and when you got it finished, and with a bunch of eye candy material done, go fishing for coders.
#16
02/21/2008 (9:26 pm)
See that is my problem ... the engine/gui folder has alot of folders in it and no cc or h fils by themself in the gui folder. so do i just put them in the engine/gui folder all alone? that dosent make sense to me. I have built this thing several times and every time i try to impliment this one thing it gives me loads of errors. I just know it has something to do with where i am putting these files.

ok i tried it again tonight and this time i only got 3 errors. first thing i did was place them in the engine/gui folder (the cc and h file that i amde in VS2005) then in the includes for those two files i had to change the paths of a few files because they dont exist in gui folder. they are in the gui/core folder. so after changing that i only got the following error...

Error	2	error C2248: 'Gui3DProjectionCtrl::getParentStaticClassRep' : cannot access private member declared in class 'Gui3DProjectionCtrl engine\console\consoleobject.h	353

here is that function that that line is in (353)

350   void init() const
351   {
352      // Get handle to our parent class, if any, and ourselves (we are our parent's child).
353      AbstractClassRep *parent = T::getParentStaticClassRep();
354      AbstractClassRep *child  = T::getStaticClassRep      ();
355
356      // If we got reps, then link those namespaces! (To get proper inheritance.)
357      if(parent && child)
358         Con::classLinkNamespaces(parent->getNameSpace(), child->getNameSpace());
359
360      // Finally, do any class specific initialization...
361      T::initPersistFields();
362      T::consoleInit();
363   }
364
365   /// Wrap constructor.
366   ConsoleObject* create() const { return new T; }
367};

any reasons why this would be happening? the errors i got were all in this function.
#17
02/26/2008 (12:30 pm)
Just a little update, I got the GUI3D button over the building working. they just updated that resorce to work with 1.5.2 so thats cool. Also I decided to make life a little easier i need a development environment. so i went out and got the mmo starter kit which uses python and i am in the process of porting the RTS kit into the MMO kit. the potential upshot of which is the ability to combine the styles of a RTS and the concepts of a user controlled world with the ideas and concepts of massive explorable and interactable worlds with hundreds of players.

so if this works i could have a fun little game on my hands.
#18
02/28/2008 (8:32 am)
Hey i have started working on a problem of naming buildings when i place them. if anyone has any tips or tricks i would love to hear them. I am talking about setting the name you see when you press F11 and select the object.
#19
03/05/2008 (8:30 am)
It is sad how dead these fourms are and i can see why now...

just an update i have the starter RTS kit to where i can place and rotate building and give them a name when placing them. I also have that hooked into SQL databases now and that info is hooked into the 3DProjectionCtrl so that buildings have data and information like how much money they are making above the top of the building. Also I am working on the click and drag pipe to connect buildings. they are and can be connected and linked in the databases but i wanted to show that link in the game. There is no war or fighting in this game. mostly just who can build a industrial empire faster. I am thinking of making some sort of war element like basic types of soldiers. I dont know, something to make it more of a challenge. But i figured if i can get a economy type thing going the rest would just be icing on the cake. or at least for me it would be.

On a personal note i wont be updating this project info much at all. mostly only when i se someone needing or wanting my help figuring something out. I just dont feel like dealing with the negitivity any more. And i wont disscuss that any further.

they should really update the RTS pack to include this kind of stuff you know.