Game Development Community

Problem calling disconnect()

by Christopher Marg · in Torque Game Engine · 04/22/2008 (2:42 pm) · 3 replies

I'm programming a game played over a LAN, using the basic Server and Client Connection scripts from the example games.

I've currently got a bug that causes the engine to crash when I call disconnect() when the game is over. I'm not sure what is causing it, as the call seems to execute sucessfully, only crashing when it seems it should be returning to where I called it from.


The general case of the game ending goes something as follows:

Two objects collide - a projectile and an object to be destroyed (successful)
The damage function of the object to be destroyed is called (successful)
The objects takes it's damage and if it is destroyed the clients are sent a command telling them the game is over (successful)
The client method disconnects from the server and returns to the main menu. (crashes here)


Setting the canvas back to the main menu and then calling disconnect() doesn't seem to help, though if I remove the disconnect() call and use the console to issue it when the game returns to the main menu it works as expected. Thinking that it might be caused by where it is on the call stack, I have tried to use schedule() to delay the call, but this hasn't yielded any success either.

#1
04/22/2008 (2:49 pm)
Try removing the client from the GameConnection on the server, instead.

If that's not something you can do, I would definatly fire up your debugger and check where it dies. I've been trough several cases where disconnecting from a server can crash the engine, and it was always simple to fix.
#2
04/22/2008 (4:18 pm)
Calling from the server end still results in a crash. I did also try to put the disconnect call into a MessageBoxOK, and that didn't crash and disconnected just fine. However, when I tried to start another game it then crashed.

Doing a trace, it the last thing that shows up is the message stating that it is leaving ShapeBase::damage() with no return value. Does this have something to do with the fact that the server has been destroyed at this point and it doesn't have the object that made the call to go back to?
#3
04/22/2008 (5:40 pm)
Further investigation:

function clientCmdGameOver()
{
	playMap.pop();
	movemap.push();
	disconnect();
	canvas.setContent(MainMenuGui);
}

When I call disconnect() from clientCmdGameOver() the last message from the trace is the return from canvas.setContent().

If instead I never call GameOver:

datablock StaticShapeData(Powersource)
{
	category = "PowerSources";
	shapeFile = "~/data/shapes/powersource.dts";
	maxDamage = 1;
};

function Powersource::damage(%this, %obj, %source, %pos, %amt, %type)
{
	//commandToAllClients('gameOver');
	disconnect();
}

In this case, the last message printed from a trace is the return from ShapeBass::damage()

However, I decided that I wanted to know the game was over, so I decided to use a MessageBox again...

function Powersource::damage(%this, %obj, %source, %pos, %amt, %type)
{
	//commandToAllClients('gameOver');
	MessageBoxOK("Game Over", "The game is over.", "gameOver();");
}

function gameOver()
{
	disconnect();
	canvas.setContent(MainMenuGui);
}

This actually works now, but I really don't understand why. It lets me start another game and everything, so the problem is basically solved. However, I still want to understand what was going on because I'd like to clean things up and tighten the code.