Game Development Community

Works single, crash multiplayer

by Mike Rowley · in Torque Game Engine · 12/30/2006 (10:47 am) · 11 replies

I've been porting my demos over from 1.4 to 1.5 and have run into a couple of problems.
Everything works properly in single player mode. My problems are in multiplayer.

#1. Player animations don't work. The default orc does, but not my av.

#2. If the server dies in game, everyone else hard crashes. We're talking "ctrl-alt-del" to shut down.

In 1.4, all this worked perfectly. I've looked at the 3 files I've changed, and everything looks the same. (eccept for the extra lighting exec calls)

For the demo, all I'm doing is modding the starter.fps game. I've changed:
player.cs --> changed the path to the av.
orcPlayer.cs --> renamed copy of player.cs. --> renamed humanBody to OrcBody
game.cs --> added the call for ai

There really shouldn't be any other changes needed. I'm using the aiguard resource added to tge 1.5
I get no errors in the console.log. (eccept for the normal "texture not found" stuff)

Any clue what might cause a crash this way? I've tried using the torsion debugger, but it just prints out the same thing as the console.log. This is driving me nuts.

The changed files are -->Here<--

Any help will be greatly appreciated.

#1
12/30/2006 (11:41 am)
Did you run everything under debug builds? Did you try journalling?
#2
12/30/2006 (11:42 am)
I pointed torsion to the debug exe and ran it from there. I don't know what journalling is.
#3
12/30/2006 (11:46 am)
That's just the script debugger. If you recompile Torque as a debug build (there's a drop-down for this in visual studio and XCode), then it will do extensive additional sanity checking (asserts) throughout its execution, hopefully catching what's going wrong with a meaningful error rather than dying hard on you.

Journalling lets you save/playback a run of Torque in a deterministic way. You make a journal with -jsave myjournal and play back with -jplay myjournal or -jdebug myjournal.
#4
12/30/2006 (11:50 am)
Thanks for the help Ben. You are talking over my head tho.
When I compiled the exe in vs, I compiled both release and debug exes.
I'll try running in debug mode in vs and see if that helps.
Thanks. :)
#5
12/30/2006 (12:52 pm)
If you get an assert (error message) in debug, then it should be fairly easy to track. If not however, you need to step trough the callstack and see where it stops.
#6
12/30/2006 (2:27 pm)
Ok, after some hair pulling trying to use my dev computer as the server and giving up, I used my test computer as the server running the debug exe thru vs2005 on my dev computer.

Here's what I got in the debug window.
I got an error window stating:
Unhandled exception at 0x00b97e59 in torqueDemo.exe 
0xc0000005. Access violation writing location 0x00000010

The code it pointed to is in TSThread.cc
void TSThread::setTimeScale(F32 ts)
{
   timeScale = ts;  <--It pointed to this line
}

Here is the output. I have no clue what it means.
-		this	0x00000000 {priority=??? mShapeInstance=??? sequence=??? ...}	

TSThread * const
		priority	CXX0030: Error: expression cannot be evaluated	
		mShapeInstance	CXX0017: Error: symbol "" not found	
		sequence	CXX0017: Error: symbol "" not found	
		pos	CXX0030: Error: expression cannot be evaluated	
		timeScale	CXX0030: Error: expression cannot be evaluated	
		keyNum1	CXX0030: Error: expression cannot be evaluated	
		keyNum2	CXX0030: Error: expression cannot be evaluated	
		keyPos	CXX0030: Error: expression cannot be evaluated	
		blendDisabled	CXX0030: Error: expression cannot be evaluated	
+		transitionData	{inTransition=??? duration=??? pos=??? ...}	

TSThread::TransitionData
+		path	{start=??? end=??? loop=??? }	TSThread::<unnamed-tag>
		makePath	CXX0030: Error: expression cannot be evaluated	
		ts	1.0000000	float
============================================================================================

=

>	torqueDemo_DEBUG.exe!TSThread::setTimeScale(float ts=1.0000000)  Line 328 + 0x6 

bytes	C++
 	torqueDemo_DEBUG.exe!TSShapeInstance::setTimeScale(TSThread * thread=0x00000000, 

float timeScale=1.0000000)  Line 749	C++
 	torqueDemo_DEBUG.exe!Player::setActionThread(unsigned int action=10, bool 

forward=true, bool hold=false, bool wait=true, bool fsp=true, bool forceSet=false)  Line 

2047	C++
 	torqueDemo_DEBUG.exe!Player::unpackUpdate(NetConnection * con=0x05c221b0, BitStream 

* stream=0x0013f970)  Line 3563 + 0x24 bytes	C++
 	torqueDemo_DEBUG.exe!NetConnection::ghostReadPacket(BitStream * bstream=0x0013f970)  

Line 535 + 0x2f bytes	C++
 	torqueDemo_DEBUG.exe!NetConnection::readPacket(BitStream * bstream=0x0013f970)  Line 

664	C++
 	torqueDemo_DEBUG.exe!GameConnection::readPacket(BitStream * bstream=0x0013f970)  

Line 865	C++
 	torqueDemo_DEBUG.exe!NetConnection::handlePacket(BitStream * bstream=0x0013f970)  

Line 525 + 0x13 bytes	C++
 	torqueDemo_DEBUG.exe!ConnectionProtocol::processRawPacket(BitStream * 

pstream=0x0013f970)  Line 228 + 0x13 bytes	C++
 	torqueDemo_DEBUG.exe!NetConnection::processRawPacket(BitStream * bstream=0x0013f970) 

 Line 495	C++
 	torqueDemo_DEBUG.exe!NetInterface::processPacketReceiveEvent(PacketReceiveEvent * 

prEvent=0x03e59630)  Line 79 + 0x13 bytes	C++
 	torqueDemo_DEBUG.exe!DemoGame::processPacketReceiveEvent(PacketReceiveEvent * 

prEvent=0x03e59630)  Line 724 + 0x18 bytes	C++
 	torqueDemo_DEBUG.exe!GameInterface::processEvent(Event * event=0x03e59630)  Line 66 

+ 0x13 bytes	C++
 	torqueDemo_DEBUG.exe!GameInterface::processEvents()  Line 191 + 0x24 bytes	C++
 	torqueDemo_DEBUG.exe!DemoGame::main(int argc=1, const char * * argv=0x003f31f0)  

Line 463 + 0x14 bytes	C++
 	torqueDemo_DEBUG.exe!run(int argc=1, const char * * argv=0x003f31f0)  Line 1398 + 

0x1c bytes	C++
 	torqueDemo_DEBUG.exe!main(int argc=1, const char * * argv=0x003f31f0)  Line 1467 + 

0xd bytes	C++
 	torqueDemo_DEBUG.exe!__tmainCRTStartup()  Line 318 + 0x19 bytes	C
 	torqueDemo_DEBUG.exe!mainCRTStartup()  Line 187	C
 	kernel32.dll!7c816fd7() 	
 	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]	
 	torqueDemo_DEBUG.exe!getUnit(const char * string=0x00000074, unsigned int 

index=6881357, const char * set=0x00720063)  Line 305 + 0x10 bytes	C++

Does this give you an idea what's wrong?
#7
12/30/2006 (2:37 pm)
Sure - and it should give you some clues, too. The call stack indicates what functions are calling what - you can work from bottom to top and (ignoring some garbage data) trace calls all he way from main on down to the networking code to Player::unpackUpdate, which is responsible for taking data from network packets and interpreting it into updates to the player state.

And if you look at thread, you'll see it's NULL, and that you have a call to setActionThread that's got an action id of ten.

So it seems like it's trying to set animation state on a non-existant thread. Got any custom script calls on setActionThread?
#8
12/30/2006 (2:50 pm)
Ok, thanks for the explination. :)
As for animations, I believe Adam Pak uses the orc animations, but I'm not sure. (I'm using Adam as the players avatar.)
I'll take a look at the code and see what I can find.
Thanks again for your help.
#9
12/30/2006 (3:22 pm)
Remove your call to setActionThread ();

Does it still crash?
#10
12/30/2006 (5:32 pm)
Ok, Stefan, that's what I was going to look for, but got sidetracked. (it sucks to be on vacation with a honeydo list a mile long) :-/
Ok, in the aiguard.cs, there is one call to setActionThread().
At the end of the file is a function:
//This function is not called within this code but is left in just in case it's needed elsewhere.
function AIGuard::animate(%this,%seq)
{
   //%this.stopThread(0);
   //%this.playThread(0,%seq);
  // %this.setActionThread(%seq);

I commented out setActionThread and nothing changed. (the other 2 were already commented out)
The game still crashed.

The only other place that has setActionThread is at the end of player.cs.
function Player::playDeathAnimation(%this)
{
   if (%this.deathIdx++ > 11)
      %this.deathIdx = 1;
   %this.setActionThread("Death" @ %this.deathIdx);
}

function Player::playCelAnimation(%this,%anim)
{
   if (%this.getState() !$= "Dead")
      %this.setActionThread("cel"@%anim);
}
If I comment those out, the game crashes on load.

I'm figureing it's somewhere in aiguard.cc so I'll look there.
#11
12/30/2006 (7:20 pm)
Ok, well...I feel really stupid at this moment. :blush:

The compiler was fooled by a simple mistake that I made and forgot about.
I've been helping someone else setup the aiguard resource and someone else posted the following:

Quote:fucifer
1. Another common misstake is not setup the player.cs file correct in the data/shapes/player folder. Open the player.cs take look at these lines.
datablock TSShapeConstructor(PlayerDts){ baseShape = "./player.dts";
You cannot have these lines the same in two different player.cs you will create problem. Here two example.
example
datablock TSShapeConstructor(JillDts){ baseShape = "./jill.dts";

I had totally forgotten about this part and once I changed it, everything, works like it's supposed to.
I have no more crashing and the animations work across the net again.
Thanks for all your help gentlemen. I have learned quite a lot today.