RTS Prototype for Torque 3D 1.1 Final
by Richard Ranft · 09/16/2011 (12:43 pm) · 52 comments
I have seen a few forum posts related to the RTS Prototype indicating that there are some issues with it and I have been told that it is outright broken. Today I took some time and went over it with a fine-toothed comb to see what I could find out. I wanted to make sure that this guide still works because I know that many people want this sort of tutorial. I also feel that the more types of gameplay that we can demonstrate to our community the easier it will be for you to build the kind of game you want to make.
Some people aren't going to like this, but I found nothing broken out of the box with this tutorial. There are some caveats, however. I started with a clean install of the Torque 3D 1.1 Final SDK, a fresh Full Template project and no source modifications or script changes whatsoever. Also, I used Torsion for editing my scripts to help me find scripting errors with minimal fuss.
I walked through the steps carefully and used cut and paste to ensure that my script changes were exactly what the walkthrough presented. I tested where it said to test, I changed what it said to change and I made sure that I followed every step to the letter. At the end, I did find a few things that should be changed but nothing that actually affected the functionality presented. Here's what I ultimately changed in the guide:
1) Where it said to add key bindings for e and c to move up and down I realized that these are default bindings located at about line 250 of default.bind.cs. I removed this step from the guide to avoid potential binding issues.
2) The step to bind the mouse wheel to the new mouseZoom function at the end of the file again conflicts with the default binding to mouseWheelWeaponCycle at about line 489 in default.bind.cs. I changed this to reflect the fact that this binding exists and direct the user to modify the existing binding instead of adding a second, potentially conflicting, binding.
3) I added a new function designed to wrap the camera mode changes at the end of the tutorial along with a keybind to make swapping the camera modes easier for the user.
So, at the end of the day I had everything working as described in the walkthrough without having to change much at all. I did add a mention that this project won't work properly in a multiplayer game at the beginning and again at the camera modes section to bring attention to this. Because a bit of the logic for handling clicks is taken care of in PlayGui.cs directly, these are never sent to the server and therefore won't be acted upon if you are connected as a client. They will work for the host, (not on a dedicated server) but most people don't join a multiplayer game to stand about and get ganked.
There is a wide swath of functionality that I didn't investigate here. I did not look into dynamically setting your camera orbit distance, changing FOV settings, updating the system to prevent the player from moving outside of the level render distance or any number of other issues that you would want to cover more in depth depending on your project needs.
I hope you all get something from this, even if it's just a reason to go back and try it again for yourselves. Remember to start fresh and follow the steps precisely and all should work. If you have any questions or issues please post them here - it will make it easier for me to find and answer them.
Please discuss any source code edits in the forum thread. Thanks.
Some people aren't going to like this, but I found nothing broken out of the box with this tutorial. There are some caveats, however. I started with a clean install of the Torque 3D 1.1 Final SDK, a fresh Full Template project and no source modifications or script changes whatsoever. Also, I used Torsion for editing my scripts to help me find scripting errors with minimal fuss.
I walked through the steps carefully and used cut and paste to ensure that my script changes were exactly what the walkthrough presented. I tested where it said to test, I changed what it said to change and I made sure that I followed every step to the letter. At the end, I did find a few things that should be changed but nothing that actually affected the functionality presented. Here's what I ultimately changed in the guide:
1) Where it said to add key bindings for e and c to move up and down I realized that these are default bindings located at about line 250 of default.bind.cs. I removed this step from the guide to avoid potential binding issues.
2) The step to bind the mouse wheel to the new mouseZoom function at the end of the file again conflicts with the default binding to mouseWheelWeaponCycle at about line 489 in default.bind.cs. I changed this to reflect the fact that this binding exists and direct the user to modify the existing binding instead of adding a second, potentially conflicting, binding.
3) I added a new function designed to wrap the camera mode changes at the end of the tutorial along with a keybind to make swapping the camera modes easier for the user.
So, at the end of the day I had everything working as described in the walkthrough without having to change much at all. I did add a mention that this project won't work properly in a multiplayer game at the beginning and again at the camera modes section to bring attention to this. Because a bit of the logic for handling clicks is taken care of in PlayGui.cs directly, these are never sent to the server and therefore won't be acted upon if you are connected as a client. They will work for the host, (not on a dedicated server) but most people don't join a multiplayer game to stand about and get ganked.
There is a wide swath of functionality that I didn't investigate here. I did not look into dynamically setting your camera orbit distance, changing FOV settings, updating the system to prevent the player from moving outside of the level render distance or any number of other issues that you would want to cover more in depth depending on your project needs.
I hope you all get something from this, even if it's just a reason to go back and try it again for yourselves. Remember to start fresh and follow the steps precisely and all should work. If you have any questions or issues please post them here - it will make it easier for me to find and answer them.
Please discuss any source code edits in the forum thread. Thanks.
About the author
I was a soldier, then a computer technician, an electrician, a technical writer, game programmer, and now software test/tools developer. I've been a hobbyist programmer since the age of 13.
#2
09/16/2011 (1:30 pm)
Thanks for the clean up work Richard!
#3
Also congrats on gainful employment.
09/16/2011 (1:47 pm)
There were just a couple of slightly confusing parts to the original tutorial, it all worked fine.Also congrats on gainful employment.
#4
09/16/2011 (2:06 pm)
Thanks for the positive feedback! I'm waiting to field problems now.... heh
#5
you have not seen some of the players I have then.
the camera distance is a specific part of the tutorial. *pouts*
it does work fine for the Overhead setting just not the orbit setting
EDIT: I initially read the above as stand around and get naked!
09/16/2011 (2:33 pm)
Quote:but most people don't join a multiplayer game to stand about and get ganked.
you have not seen some of the players I have then.
Quote:There is a wide swath of functionality that I didn't investigate here. I did not look into dynamically setting your camera orbit distance, changing FOV settings
the camera distance is a specific part of the tutorial. *pouts*
it does work fine for the Overhead setting just not the orbit setting
EDIT: I initially read the above as stand around and get naked!
#6
[edit] Guess that means I need a mouse with a wheel at home....
09/16/2011 (3:45 pm)
Ok, ok - I'll look into it this weekend and see if I can't get some mouse wheel love into the orbit distance. It doesn't look like it'll be that tough the way it's laid out, but you never can tell.[edit] Guess that means I need a mouse with a wheel at home....
#7
EDIT: or a trackpad with a scroll
09/16/2011 (3:48 pm)
oh and thanks for taking the time to go through it. Tutorials like this prove that Torque is more than FPS!EDIT: or a trackpad with a scroll
#8
In the mean time, sometime tonight or Sunday I'll try to get around to tying something (probably [ and ]) to those functions and see what I get.
09/16/2011 (6:54 pm)
I'm not sure when the updates will be pushed live, but I just thought of a few things I should have added to make the orbit distance fix easier. I'll try to get them in on Monday.In the mean time, sometime tonight or Sunday I'll try to get around to tying something (probably [ and ]) to those functions and see what I get.
#9
Then the entire end of default.bind.cs - this incorporates all changes to this file for the whole tutorial:
Next, all of the serverCmd functions:
This will get you switching between overhead and orbit modes and will retain the camera orbit distance. Some tweaking will be required to retain orbit angle and offset between swaps - I leave this as an exercise for the student.
And, I'm noticing that the minimum and maximum orbit distances are being ignored by the engine, for the record. Perhaps I'll fiddle with that and post a camera patch resource later that enforces the limits and also implements a simpler method for setting the orbit distance (of course, I might be missing something - I didn't go code diving, just used the online reference).
You'd need to adapt the keyZoomUp and keyZoomDown functions and marshal them into the mouseZoom function presented in the tutorial and then bind it to mouse, "zaxis" to use the mouse wheel. I don't have a mouse with a wheel at home, so I used the bracket keys - sorry all....
Hope it's useful!
09/16/2011 (8:40 pm)
Ok, in gameCore::preparePlayer() add the orbit distance after the spawn:%game.spawnPlayer(%client, %playerSpawnPoint, false); %client.orbitDistance = 25;
Then the entire end of default.bind.cs - this incorporates all changes to this file for the whole tutorial:
//-----------------------------------------------------------------------------
// Turn mouse cursor on or off
// If %val is true, the button was pressed in
// If %val is false, the button was released
function toggleMouseLook(%val)
{
// Check to see if button is pressed
if(%val)
{
// If the cursor is on, turn it off.
// Else, turn it on
if(Canvas.isCursorOn())
hideCursor();
else
showCursor();
}
}
// Bind the function toggleMouseLook to the keyboard 'm' key
moveMap.bind(keyboard, "m", "toggleMouseLook");
// Spawn an AI guy when key is pressed down
function spawnAI(%val)
{
// If key was pressed down
if(%val)
{
// Create a new, generic AI Player
// Position will be at the camera's location
// Datablock will determine the type of actor
new AIPlayer()
{
position = LocalClientConnection.camera.getPosition();
datablock = "DefaultPlayerData";
};
}
}
// Bind the function spawnAI to the keyboard 'b' key
moveMap.bind(keyboard, b, spawnAI);
function keyZoomUp(%val)
{
if(%val)
{
if($Camera::CurrentMode $= "overhead")
commandToServer('adjustCameraHeight', 3);
else
commandToServer('adjustCameraDistance', 3.0);
}
}
function keyZoomDown(%val)
{
if(%val)
{
if($Camera::CurrentMode $= "overhead")
commandToServer('adjustCameraHeight', -3);
else
commandToServer('adjustCameraDistance', -3.0);
}
}
moveMap.bind(keyboard, "[", keyZoomUp);
moveMap.bind(keyboard, "]", keyZoomDown);
function toggleCameraMode(%val)
{
if(%val)
{
if($Camera::CurrentMode $= "overhead")
{
commandToServer('RTSOrbit');
$Camera::CurrentMode = "orbit";
}
else
{
commandToServer('RTSOverhead');
$Camera::CurrentMode = "overhead";
}
}
}
moveMap.bind(keyboard, "r", toggleCameraMode);Next, all of the serverCmd functions:
// Server command that adjusts camera height
function serverCmdadjustCameraHeight(%client, %adjustment)
{
// Take the current camera position (a vector)
// Then add or subtract from the Z element, based on
// the %adjustment value passed in
%client.camera.position = VectorAdd(%client.camera.position, "0 0 " @ %adjustment);
}
// Server command that adjusts camera height
function serverCmdadjustCameraDistance(%client, %adjustment)
{
// Take the current camera position (a vector)
// Then add or subtract from the Z element, based on
// the %adjustment value passed in
%dist = %client.orbitDistance + %adjustment;
%client.camera.setOrbitObject(%client.player, mDegToRad(30) @ " 0 0", 0.0, 25.0, %dist, true);
%client.orbitDistance = %dist;
echo(" -- orbitDistance : "@%dist);
}
function serverCmdRTSOrbit(%client)
{
%dist = %client.orbitDistance;
echo(" -- orbitDistance : "@%dist);
%client.camera.setOrbitObject(%client.player, mDegToRad(30) @ " 0 0", 0.0, 25.0, %dist, true);
$Camera::CurrentMode = "orbit";
}
function serverCmdRTSOverhead(%client)
{
%client.camera.position = VectorAdd(%client.camera.position, "0 0 5" );
%client.camera.lookAt(%client.player.position);
%client.camera.controlMode = "Overhead";
$Camera::CurrentMode = "overhead";
}This will get you switching between overhead and orbit modes and will retain the camera orbit distance. Some tweaking will be required to retain orbit angle and offset between swaps - I leave this as an exercise for the student.
And, I'm noticing that the minimum and maximum orbit distances are being ignored by the engine, for the record. Perhaps I'll fiddle with that and post a camera patch resource later that enforces the limits and also implements a simpler method for setting the orbit distance (of course, I might be missing something - I didn't go code diving, just used the online reference).
You'd need to adapt the keyZoomUp and keyZoomDown functions and marshal them into the mouseZoom function presented in the tutorial and then bind it to mouse, "zaxis" to use the mouse wheel. I don't have a mouse with a wheel at home, so I used the bracket keys - sorry all....
Hope it's useful!
#10
Thanks for giving this a thorough look. Are you the new tutorial guy now? :)
09/17/2011 (12:18 am)
No…wheel? How do you browse the web?! :PThanks for giving this a thorough look. Are you the new tutorial guy now? :)
#11
09/17/2011 (2:41 am)
@ Richard, how old is your home mouse ? :)
#12
09/17/2011 (5:56 am)
Dang-it, Derek; get a wheeledMouse to this man...pronto! Walk towards the light, Richard, walk towards the light...
#13
@D Fasel - I use a trackball at home. This one is about 5 years old - Logitech Marble Mouse. And a Space Navigator for working in Max. No wheel on that, either. My keyboard has a scroll/zoom thing on it, but it's not a wheel and I'm not even sure I can find a binding for it. Some sort of Microsoft proprietary thing. Perhaps I'll create a peripheral that is just a wheel....
Sheesh - mouse wheel elitists. I guess I'll see about sneaking in on Sunday and testing / updating the notes above for a wheel. I think I might be too busy Monday, but we'll see.
09/17/2011 (6:06 am)
@Ronny - A new documents guy - just helping to take some of the load off of the rest of the staff so they have more time for their primary tasks.@D Fasel - I use a trackball at home. This one is about 5 years old - Logitech Marble Mouse. And a Space Navigator for working in Max. No wheel on that, either. My keyboard has a scroll/zoom thing on it, but it's not a wheel and I'm not even sure I can find a binding for it. Some sort of Microsoft proprietary thing. Perhaps I'll create a peripheral that is just a wheel....
Sheesh - mouse wheel elitists. I guess I'll see about sneaking in on Sunday and testing / updating the notes above for a wheel. I think I might be too busy Monday, but we'll see.
#14
@Ronny - Richard is one of four tech writers (if you include me). That's right GG now has a documentation team. We haven't decided if we are going to have each person specialize (tutorials, reference docs, overviews, etc).
09/17/2011 (6:18 am)
Yay for 6am Saturdays.@Ronny - Richard is one of four tech writers (if you include me). That's right GG now has a documentation team. We haven't decided if we are going to have each person specialize (tutorials, reference docs, overviews, etc).
#15
www.logitech.com/en-us/mice-pointers/trackballs/devices/7365
www.logitech.com/en-us/mice-pointers/trackballs/devices/189
BOTH HAVE SCROLL WHEELS!!
09/17/2011 (9:24 am)
since you like trackballs try these options www.logitech.com/en-us/mice-pointers/trackballs/devices/7365
www.logitech.com/en-us/mice-pointers/trackballs/devices/189
BOTH HAVE SCROLL WHEELS!!
#16
I suppose I'll stop on my way back from dropping off my daughter this evening and pick that other one out of storage to test this with.... Gosh. You guys are mean.... ;p
09/17/2011 (4:59 pm)
Nope - they're right handed. I'm right handed, but not with a trackball. Weird, I know, but ever since Mechwarrior 2 and Mech2 Mercs I have been using the trackball on the left for all of my gaming and 90% of my non-gaming computer use. I have owned earlier incarnations of both of those (and currently have one of the second type in storage) but the thumb mouse is no good for gaming and the other is just plain annoying to me. <shrug>I suppose I'll stop on my way back from dropping off my daughter this evening and pick that other one out of storage to test this with.... Gosh. You guys are mean.... ;p
#17
Here is the modified version of mouseZoom from the tutorial:
Remember to bind the mouse wheel to mouseZoom by changing the binding at around line 489 in default.bind.cs:
Additionally, make sure you delete scripts/client/config.cs if it is present or your new keybindings won't take effect.
[edit] - Note: for some reason if you use 3 and -3 for the adjustments for orbit distance and the value is reduced to below 0 (watch the console - I put echoes in) when you toggle out and back to orbit mode you are reset to a distance of 25. The function actually wants a float value and if you give it one it behaves better.
09/18/2011 (7:55 am)
By popular demand I went by my storage unit and dug out my Microsoft USB Trackball Explorer. I suppose Microsoft feels that their trackballs are shameful because I can't find a product page on their site for this hardware. My only complaints are that it is limited to right handed use and the mouse wheel catches when scrolling down (back) sometimes, causing the wheel click to register. And now I have three pointer controlling devices on this computer....Here is the modified version of mouseZoom from the tutorial:
// Adjusts the height of the camera using the mouse wheel
function mouseZoom(%val)
{
// If wheel was scrolled forward
// move camera closer to the ground or orbit target
if(%val > 0)
{
if($Camera::CurrentMode $= "overhead")
commandToServer('adjustCameraHeight', -3);
else
commandToServer('adjustCameraDistance', -3.0);
}
// If wheel was scrolled back
// move camera away from the ground or orbit target
else
{
if($Camera::CurrentMode $= "overhead")
commandToServer('adjustCameraHeight', 3);
else
commandToServer('adjustCameraDistance', 3.0);
}
}Remember to bind the mouse wheel to mouseZoom by changing the binding at around line 489 in default.bind.cs:
moveMap.bind(mouse, "zaxis", mouseZoom);
Additionally, make sure you delete scripts/client/config.cs if it is present or your new keybindings won't take effect.
[edit] - Note: for some reason if you use 3 and -3 for the adjustments for orbit distance and the value is reduced to below 0 (watch the console - I put echoes in) when you toggle out and back to orbit mode you are reset to a distance of 25. The function actually wants a float value and if you give it one it behaves better.
#18
Thanks for going through all the effort for this.
I now have my camera switching and scrolling all spiffy like.
Now just gonna throw a min/max scroll limiter on it and move on to the next thing on the list.
EDIT: not sure if this is the best way ( feel free to correct it), but here is what I have done to limit camera distance adjustment.
in /scripts/server/commands.cs I changed function serverCmdadjustCameraDistance()to look like this
09/18/2011 (1:11 pm)
at that price it is shameful!Thanks for going through all the effort for this.
I now have my camera switching and scrolling all spiffy like.
Now just gonna throw a min/max scroll limiter on it and move on to the next thing on the list.
EDIT: not sure if this is the best way ( feel free to correct it), but here is what I have done to limit camera distance adjustment.
in /scripts/server/commands.cs I changed function serverCmdadjustCameraDistance()to look like this
// Server command that adjusts camera height
function serverCmdadjustCameraDistance(%client, %adjustment)
{
// Take the current camera position (a vector)
// Then add or subtract from the Z element, based on
// the %adjustment value passed in
if(%dist = %client.orbitDistance && (%client.orbitDistance < -20.0 || %client.orbitDistance > 20.0))
{
if(%client.orbitDistance < -20.0)
%dist = %client.orbitDistance +0.1;
else
%dist = %client.orbitDistance -0.1;
}
else
%dist = %client.orbitDistance + %adjustment;
%client.camera.setOrbitObject(%client.player, mDegToRad(35) @ " 0 0", -20.0, 20.0, %dist, true);
%client.orbitDistance = %dist;
//echo(" -- orbitDistance : "@%dist);
}
#19
Ok, that's not a fix, it's a wild goose chase. Working on it....
And the only thing I can think of on the script you posted is that I think this is easier:
Cuts it down to two quick comparisons and then sets the camera mode. Also, the minimum distance seems to work sometimes if the value is not zero (or maybe my engine code actually did something after all) so I ended up setting it to 0.0. Maximum distance doesn't really matter or we wouldn't need to check....
09/18/2011 (5:12 pm)
Sure, I like it - as long as it works, that is plenty good enough. The only better option is to fix it in the engine, like so.Ok, that's not a fix, it's a wild goose chase. Working on it....
And the only thing I can think of on the script you posted is that I think this is easier:
// get the current distance and adjust %dist = %client.orbitDistance + %adjustment; // clamp %dist to our desired limits if(%dist < -20.0) %dist = -20.0; if(%dist > 20.0) %dist = 20.0; // set camera orbit distance %client.camera.setOrbitObject(%client.player, mDegToRad(35) @ " 0 0", 0.0, 20.0, %dist, true); // save our current orbit distance %client.orbitDistance = %dist;
Cuts it down to two quick comparisons and then sets the camera mode. Also, the minimum distance seems to work sometimes if the value is not zero (or maybe my engine code actually did something after all) so I ended up setting it to 0.0. Maximum distance doesn't really matter or we wouldn't need to check....
#20
@Richard: Thanks for chasing down these little bugs before I've had time to use the engine :)
09/20/2011 (12:10 am)
@Mich: Awesome - an actual team. Now you just need to convince him three buttons and wheel is the minimum gamers will tolerate.@Richard: Thanks for chasing down these little bugs before I've had time to use the engine :)

Employee Michael Perry
ZombieShortbus