Game Development Community

dev|Pro Game Development Curriculum

Enhanced TelnetDebugger

by Tom Spilman · 07/19/2005 (3:34 am) · 102 comments

Download Code File

*** This resource is obsolete and the code is now included in all shipping versions of the Torque engine ***

Thanks to all the community members that made this resource possible!

Team Sickhead

www.sickheadgames.com/images/shbug_03.png

About the author

Tom is a programmer and co-owner of Sickhead Games, LLC.

#41
08/01/2005 (11:39 am)
@Tom:

I use TGE 1.3 and it just crash without any error message in the console log, no more assert windows show up with the new patch, and everything seems OK when debug run in the VS.net.

The crash seems occur randomly after serveral hours testing in the IDE. Hope Sam will have the solution soon.
#42
08/01/2005 (12:10 pm)
Tom,
I just tried your latest changes. They work great so far! Eval() seems to be working correctly now. I'll let you know if I come across anything else.

Thanks for the great resource!
- Drew
#43
08/01/2005 (3:49 pm)
@Tom - Found the problem. Wasn't with guiObjectView--that was a sympton. The cause is the "exec()" is not building the local variables.

for instance: I have 5 tanks, so I dynamically create the "tank selection panels". I search for "*tank_info.cs". and it finds 5 (which is correct). I then get a file, and pass it to a function tankSelectGui.buildPanel(%indexTanksLoaded, %file);

bold items are from the tank_info.cs file that should have been gotten when the exec occured.

function tankSelectGui::buildPanel(%this, %index, %file)
{
	 	exec(%file);  [b] not returning locals [/b]

	 	
	 	if(strstr($Client::frmServerTankList, [b]%pName[/b]) == -1)
      {
      	return false;
      }
      
		%tankSelectPanel = "tankSelectPanel" @ %index;
		%tankSelectModelDisplay = "tankSelectModeldisplay" @ %index;
		%tankSelectButton = "tankSelectButton" @ %index;
		%btnSelectTank = "btnSelectTank"@%index;
		
		%btnNormal = "btnNormal"@%index;
		%extentx = 13;
		%extenty = 47 + (85 * %index);
		
   new GuiAnimMovingButtonCtrl(%tankSelectPanel) {
      profile = "GuiDefaultProfile";
      horizSizing = "right";
     .
     .
     .
     new GuiObjectView(%tankSelectModelDisplay) {
         profile = "GuiMLTextNoSelectProfile";
         horizSizing = "relative";
         vertSizing = "relative";
         position = "17 11";
         extent = "82 66";
         minExtent = "8 2";
         visible = "1";
         cameraZRot = "0";
         forceFOV = "0";
         maxorbitDistance = "100";
         mouseCanZoom = "1";
         mouseCanSpin = "1";
         autoRotate = "1";
         autoRotateSpeed = "0.001";
         orbitDistance = [b]%porbitDistance[/b];
         orbitPosition = [b]%porbitPosition[/b];
         cameraRot = [b]%pcameraRot[/b];
         lightDirection = "-0.57735 -0.57735 -0.57735";
         lightColor = "0.600000 0.580000 0.500000 1.000000";
         ambientColor = "0.300000 0.300000 0.300000 1.000000";
      };
      .
      .
      .
  tankSelectGui.add(%tankSelectPanel);
   
   // Set custom camera positions for the tank	
	 
   %tankSelectModelDisplay.clear();
   %tankSelectModelDisplay.setObject([b]%pName[/b], [b]%pLocation[/b] @ [b]%pModel[/b],"","");
   .
   .
   .

in the tank_info.cs file it creates local varibles. Here's a sample:

//-----------------------------------------------------------------------------
// Tankems
// 
// Copyright (c) 2005 Imagination U
//-----------------------------------------------------------------------------

// This file is exec()'ed in to get values to store into the player array
%pName = "Warthog";
%pFormalName = "Warthog";
%pMfger = "Grugon Company, Inc.";
%pTankClass = "Heavy";

%pLocation = "starter.fps/data/shapes/tanks/warthog/";
%pModel = "warthog.dts";

// List of skins availible on this tank
%pBase = "base";
%pDesert = "desert";
%pForest = "forest";
.
.
.
%porbitDistance = "38";
%porbitPosition = "0 0 7";
%pcameraRot = "0 0 3.9";
.
.
.

then I could access all the local variables within the buildpanel function, build the panel. Get the next tank_info.cs file and build the next tank panel, etc.

So the exec is not registering the local variables or it is but then when it finishes with the exec, its removing them.
#44
08/01/2005 (4:51 pm)
@Steve - I know the issue exactly. I ran into this "feature" when working on the callstack stuff. Personally i felt it was a bug. Not only does exec() leak out locals, but it can change any locals within your function it feels like. This is definitely not behavior one would normally expect from what is in essence a function call. I posted a bug that kinda touched on this and by email BenG concurred with my assessment that leaky locals in exec() calls was a bad thing.

Of course i figured someone was exploiting this, but i figured it was so uncommon that i wouldn't hear someone mention it till much later. I was wrong on that count it seems.

Now in your case seems like a very handy use of this "feature". I'd like to get Ben's input on this, but i see a few different solutions:

- Reverting functionality completely... exec() calls use the existing callstack, but things will look very strange in the debugger.
- Emulate functionality by creating a new stack frame for exec() calls, but copy the locals from the previous frame and copy them back when the stack is popped. This should behave like the old system.
- Create a new script function that behaves like the old exec() call specifically for situations like yours.

Any other opinions on this? Is anyone else using this functionality in their scripts?

Also Steve if you want to disable the new functionality you should just have to change line 778 in console.cc to always pass 0 as the last parameter to compileExec(). Take note of the callstack behavior when debugging with Torsion.
#45
08/01/2005 (9:37 pm)
LOL.. leave it to me to think that it was acting as normal when it was a bug.. oh well.

Now that you mention it,, it is an exec. which would be like a function call-- as you stated.

I like your 3rd option.. create a new function that does the funcationality that I was using. A temporary #include.

But until then, I'll change my tank_info.cs from local varibles to global varibles, and then delete the globals when I'm finished with all the tanks. If/when a function comes out to do what I'm doing, then I'll change it back around.

Thanks Tom for a great resource and sorry for the wild goose chase.
#46
08/01/2005 (9:42 pm)
@Steve - No thank you... this is just the sort of feedback we need. I'm thinking that some sort of evalFile() call is what is needed, as eval already does work on the current stack frame by design.

Again... anyone else out there counting on locals leaking in or out of exec() calls?
#47
08/02/2005 (1:48 am)
Actually, it would seem to be a handy thing, and I would have assumed that it worked this way on purpose.

For example, PHP's include() and require() functions behave in this exact manner. I would think that if you don't want your current locals to be affected, that you would have already exec'd the resource and are now calling a function?

To me, that seems like the more logical way of doing it.
#48
08/03/2005 (2:57 pm)
UPDATE::

If there are any new users of Torque that use the Torque Build Environment; here is a video that walks you through the steps of integrating this awesone resource from Tom Spilman into TGE1.3

torque.smdlabs.com/media/freeTutorials/quickClips/tbe.htm

B--
#49
08/03/2005 (2:59 pm)
@Brandon - Wow... that rocks! Someone just asked me about "how to compile their code" with respect to integrating this resource just today!
#50
08/03/2005 (7:26 pm)
Can someone make a quick step by step instruction on how to take the TGE1.3 fresh from the download at GG and apply Tom's code and compile?

I have yet to be able to get it to work correctly. My guess would be that some advanced users may have other 'patches' applied for other issues or new features added that a newbie would not have.

I would gladly pay you a hamburger tomorrow for a tutorial today.....

Brian Peal
#51
08/03/2005 (9:12 pm)
@Brian - Look one post above mine... Brandon's video does just that.
#52
08/08/2005 (8:54 am)
I get the same errors as Brian listed above but changing the Con::evaulate line in main.cc does stop these errors coming up in Torsion...

main.cs (231): Unable to find function setModPaths
--------- Loading MODS ---------
Missing file: starter.fps/main.cs!
Error: Unable to find specified mod: starter.fps

Error: Unable to load any specified mods

...it's like Torsion is not starting in the example folder where torquedemo_debug.exe resides as defined in Project->Properties

any ideas what else I could try? I'm using Torque 1.3 - trying to compile 1.4 spouts a bunch of link errors with console.obj when I add the debugging enhancement so I dropped back to 1.3
#53
08/08/2005 (9:40 am)
@Andy - It cannot be an issue of not starting in the example folder, because main.cs is in the example folder and wouldn't be found if the the demo exe wasn't launched from there.

The issues all seem to stem from not finding the setModPaths console function. If i comment out setModPaths here in my copy i get the exact same errors about not finding mod paths.

So what i found is that setModPaths is declared in main.cc in 1.3 and in resManager.cc in 1.4. I suspect you've replaced main.cc with the one i had in the 1.4 folder in the zip which does not include setModPaths in it.

I guess i need to break down and add a 1.3 folder into the zip package that works with 1.3 properly. Give me a few minutes and i'll get that up here.
#54
08/08/2005 (10:59 am)
@Andy - Ok i updated the zip to include a folder for 1.3 specifically. You should be able to copy the content of TGE 1.3 directly into your Torque SDK folder and have everything properly patched. That is unless you've done any other custom modifications to your SDK within the files i'm replacing.
#55
08/08/2005 (4:18 pm)
@Tom - Alrighty then! I copied the files from the 1.3 folder you have a supplied, recompiled main.cc then built torqueDemo_debug.exe - loaded Torsion, added a few break points and the BOING! debugging is now working - thanks Tom :D
#56
08/08/2005 (4:20 pm)
@Andy - No prob. Let me know if you run into anything else at all or have suggestions to improve Torsion.
#57
08/08/2005 (4:22 pm)
Does anyone know how I can disable the prompts that come up in Torsion, say something like "this file was modified by the API do you want to reload it"

Also why is it a telnet debugger? Is it telnetting to another site or just into the exe?
#58
08/08/2005 (4:30 pm)
@Andy - The file modification message is happening because Torsion is modifiying main.cs which you have open. I don't have a good solution for this, as it's vital the file is automaticly modified for the "one click debugging" feature and you just shouldn't change the contents of the file without some notification. I'm open for suggestions here, but for now your best bet is to just not have main.cs open... it's rare that you would be debugging it anway.

It's called the telenet debugger because it uses a plain text protocol which is compatible with telenet clients. When using Torsion to debug your scripts, the TorqueDemo.exe acts like a server and Torsion connects to it as a client.
#59
08/08/2005 (9:41 pm)
I've merged some of the changes into 1.4... I'll come around and do another pass when Tom gets the next update to the engine changes done. Nice work guys!
#60
08/08/2005 (10:21 pm)
@Tom - with regards to the "the file was modified" system - do an automatic save all with the new info as this is how I expected it to work. The prompts come up for any file that is open, so it's natural for Torsion to save all open files before running a debug session. As long as you have a robust undo / redo function changes can always be rolled back. If need be have a check box or something in prefs to disable this so users can decide whether to manually confirm changes or not.

I haven't checked yet but does Torsion allow you to apply code changes (ALT + F10) on the fly and then reload scripts while debugging is running? Also does it allow you to change variables on the fly before they get put in the stack?