Game Development Community

[Solved] Request - Step by Step Guide on how to seporate T3D Client From Server

by Lee Wickham · in Torque 3D Professional · 01/27/2011 (1:55 pm) · 38 replies

Note: For a step by step guide see reply #14 onward


Hi every my name is lee

Just want to say that i am over the moon that GG is back and i have just purchased T3D myself


I am wondering if their is any one that would be kind enough to provide me (and any others that may be searching for this) a guide or step by step instructions on Splitting up the Client and Server sides of Torque 3D, the aim of this is to:


To Create a Seporate Build of my game to be used as:

  1. A Dedicated Server.
  2. A Client to connect to the dedi server.

Currently i have Installed:


  1. Torque 3D 1.1 Beta 3.
  2. All Prerequasits Installed to the latest version at time of posting this request for help.
  3. Created a Fresh "Full" Project.

The game will be MOFPS (Multiplayer Online First Person Shooter)

If any further information is required please let me know and ill reply as soon as possible.

Thank you for taking the time to read this thread

Regards

Lee.
Page«First 1 2 Next»
#21
04/26/2011 (12:51 pm)
11. copied the following files from %client project%\game\core\scripts\client to %server project%\game\core\scripts\server
a. audioAmbiences.cs
b. audioDescriptions.cs
c. audioEnvironments.cs
d. audioStates.cs

12. Modified %server project%\game\core\scripts\server\audio.cs to include the content of %client project%\game\core\scripts\client\audio.cs (see below)
//-----------------------------------------------------------------------------
// Torque Shader Engine 
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Client audio.cs code below:
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
//    Source groups.
//-----------------------------------------------------------------------------

singleton SFXDescription( AudioMaster );
singleton SFXSource( AudioChannelMaster )
{
   description = AudioMaster;
};

singleton SFXDescription( AudioChannel )
{
   sourceGroup = AudioChannelMaster;
};

singleton SFXSource( AudioChannelDefault )
{
   description = AudioChannel;
};
singleton SFXSource( AudioChannelGui )
{
   description = AudioChannel;
};
singleton SFXSource( AudioChannelEffects )
{
   description = AudioChannel;
};
singleton SFXSource( AudioChannelMessages )
{
   description = AudioChannel;
};
singleton SFXSource( AudioChannelMusic )
{
   description = AudioChannel;
};

// Set default playback states of the channels.

AudioChannelMaster.play();
AudioChannelDefault.play();

AudioChannelGui.play();
AudioChannelMessages.play();

// Stop in-game channels.
AudioChannelEffects.stop();
AudioChannelMusic.stop();
Continued Below
#22
04/26/2011 (12:54 pm)
Continued %client project%\game\core\scripts\server\audio.cs
//-----------------------------------------------------------------------------
//    Master SFXDescriptions.
//-----------------------------------------------------------------------------

// Master description for interface audio.
singleton SFXDescription( AudioGui )
{
   volume         = 1.0;
   sourceGroup    = AudioChannelGui;
};

// Master description for game effects audio.
singleton SFXDescription( AudioEffect )
{
   volume         = 1.0;
   sourceGroup    = AudioChannelEffects;
};

// Master description for audio in notifications.
singleton SFXDescription( AudioMessage )
{
   volume         = 1.0;
   sourceGroup    = AudioChannelMessages;
};

// Master description for music.
singleton SFXDescription( AudioMusic )
{
   volume         = 1.0;
   sourceGroup    = AudioChannelMusic;
};

//-----------------------------------------------------------------------------
//    SFX Functions.
//-----------------------------------------------------------------------------

/// This initializes the sound system device from
/// the defaults in the $pref::SFX:: globals.
function sfxStartup()
{   
   // The console builds should re-detect, by default, so that it plays nicely 
   // along side a PC build in the same script directory.
   
   if( $platform $= "xenon" )
   {
      if( $pref::SFX::provider $= "DirectSound" || 
          $pref::SFX::provider $= "OpenAL" )
      {
         $pref::SFX::provider = "";
      }
      
      if( $pref::SFX::provider $= "" )
      {
         $pref::SFX::autoDetect = 1;
         
         warn( "Xbox360 is auto-detecting available sound providers..." ); 
         warn( "   - You may wish to alter this functionality before release (core/scripts/client/audio.cs)" );
      }
   }

   echo( "sfxStartup..." );
   
   // If we have a provider set, try initialize a device now.
   
   if( $pref::SFX::provider !$= "" )
   {
      if( sfxInit() )
         return;
      else
      {
         // Force auto-detection.
         $pref::SFX::autoDetect = true;
      }
   }

   // If enabled autodetect a safe device.

   if( ( !isDefined( "$pref::SFX::autoDetect" ) || $pref::SFX::autoDetect ) &&
       sfxAutodetect() )
      return;
   
   // Failure.

   error( "   Failed to initialize device!nn" );
   
   $pref::SFX::provider = "";
   $pref::SFX::device   = "";
   
   return;
}


/// This initializes the sound system device from
/// the defaults in the $pref::SFX:: globals.
function sfxInit()
{
   // If already initialized, shut down the current device first.
   
   if( sfxGetDeviceInfo() !$= "" )
      sfxShutdown();
      
   // Start it up!
   %maxBuffers = $pref::SFX::useHardware ? -1 : $pref::SFX::maxSoftwareBuffers;
   if ( !sfxCreateDevice( $pref::SFX::provider, $pref::SFX::device, $pref::SFX::useHardware, %maxBuffers ) )
      return false;

   // This returns a tab seperated string with
   // the initialized system info.
   %info = sfxGetDeviceInfo();
   $pref::SFX::provider       = getField( %info, 0 );
   $pref::SFX::device         = getField( %info, 1 );
   $pref::SFX::useHardware    = getField( %info, 2 );
   %useHardware               = $pref::SFX::useHardware ? "Yes" : "No";
   %maxBuffers                = getField( %info, 3 );
   
   echo( "   Provider: "    @ $pref::SFX::provider );
   echo( "   Device: "      @ $pref::SFX::device );
   echo( "   Hardware: "    @ %useHardware );
   echo( "   Buffers: "      @ %maxBuffers );
   
   if( isDefined( "$pref::SFX::distanceModel" ) )
      sfxSetDistanceModel( $pref::SFX::distanceModel );
   if( isDefined( "$pref::SFX::dopplerFactor" ) )
      sfxSetDopplerFactor( $pref::SFX::dopplerFactor );
   if( isDefined( "$pref::SFX::rolloffFactor" ) )
      sfxSetRolloffFactor( $pref::SFX::rolloffFactor );

   // Restore master volume.
   
   sfxSetMasterVolume( $pref::SFX::masterVolume );

   // Restore channel volumes.
   
   for( %channel = 0; %channel <= 8; %channel ++ )
      sfxSetChannelVolume( %channel, $pref::SFX::channelVolume[ %channel ] );
      
   return true;
}


/// Destroys the current sound system device.
function sfxShutdown()
{
   // Store volume prefs.
   
   $pref::SFX::masterVolume = sfxGetMasterVolume();
   
   for( %channel = 0; %channel <= 8; %channel ++ )
      $pref::SFX::channelVolume[ %channel ] = sfxGetChannelVolume( %channel );
   
   // We're assuming here that a null info 
   // string means that no device is loaded.
   if( sfxGetDeviceInfo() $= "" )
      return;

   sfxDeleteDevice();
}
Continued Below
#23
04/26/2011 (12:55 pm)
Continued %client project%\game\core\scripts\server\audio.cs

/// Determines which of the two SFX providers is preferable.
function sfxCompareProvider( %providerA, %providerB )
{
   if( %providerA $= %providerB )
      return 0;
      
   switch$( %providerA )
   {
      // Always prefer FMOD over anything else.
      case "FMOD":
         return 1;
         
      // Prefer OpenAL over anything but FMOD.
      case "OpenAL":
         if( %providerB $= "FMOD" )
            return -1;
         else
            return 1;
            
      // As long as the XAudio SFX provider still has issues,
      // choose stable DSound over it.
      case "DirectSound":
         if( %providerB $= "FMOD" || %providerB $= "OpenAL" )
            return -1;
         else
            return 0;
            
      case "XAudio":
         if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "DirectSound" )
            return 1;
         else
            return -1;
         
      default:
         return -1;
   }
}
/// Try to detect and initalize the best SFX device available.
function sfxAutodetect()
{
   // Get all the available devices.
   
   %devices = sfxGetAvailableDevices();

   // Collect and sort the devices by preferentiality.
   
   %deviceTrySequence = new ArrayObject();
   %bestMatch = -1;
   %count = getRecordCount( %devices );
   for( %i = 0; %i < %count; %i ++ )
   {
      %info = getRecord( %devices, %i );
      %provider = getField( %info, 0 );
         
      %deviceTrySequence.push_back( %provider, %info );
   }
   
   %deviceTrySequence.sortfkd( "sfxCompareProvider" );
         
   // Try the devices in order.
   
   %count = %deviceTrySequence.count();
   for( %i = 0; %i < %count; %i ++ )
   {
      %provider = %deviceTrySequence.getKey( %i );
      %info = %deviceTrySequence.getValue( %i );
      
      $pref::SFX::provider       = %provider;
      $pref::SFX::device         = getField( %info, 1 );
      $pref::SFX::useHardware    = getField( %info, 2 );
      
      // By default we've decided to avoid hardware devices as
      // they are buggy and prone to problems.
      $pref::SFX::useHardware = false;

      if( sfxInit() )
      {
         $pref::SFX::autoDetect = false;
         %deviceTrySequence.delete();
         return true;
      }
   }

// Found no suitable device.
   
   error( "sfxAutodetect - Could not initialize a valid SFX device." );
   
   $pref::SFX::provider = "";
   $pref::SFX::device = "";
   $pref::SFX::useHardware = "";
   
   %deviceTrySequence.delete();
   
   return false;
}

//-----------------------------------------------------------------------------
//    Backwards-compatibility with old channel system.
//-----------------------------------------------------------------------------

// Volume channel IDs for backwards-compatibility.

$GuiAudioType        = 1;  // Interface.
$SimAudioType        = 2;  // Game.
$MessageAudioType    = 3;  // Notifications.
$MusicAudioType      = 4;  // Music.

$AudioChannels[ 0 ] = AudioChannelDefault;
$AudioChannels[ $GuiAudioType ] = AudioChannelGui;
$AudioChannels[ $SimAudioType ] = AudioChannelEffects;
$AudioChannels[ $MessageAudioType ] = AudioChannelMessages;
$AudioChannels[ $MusicAudioType ] = AudioChannelMusic;

function sfxOldChannelToGroup( %channel )
{
   return $AudioChannels[ %channel ];
}

function sfxGroupToOldChannel( %group )
{
   %id = %group.getId();
   for( %i = 0;; %i ++ )
      if( !isObject( $AudioChannels[ %i ] ) )
         return -1;
      else if( $AudioChannels[ %i ].getId() == %id )
         return %i;
         
   return -1;
}

function sfxSetMasterVolume( %volume )
{
   AudioChannelMaster.setVolume( %volume );
}

function sfxGetMasterVolume( %volume )
{
   return AudioChannelMaster.getVolume();
}
Continue Below
#24
04/26/2011 (12:57 pm)
Continued %client project%\game\core\scripts\server\audio.cs

function sfxStopAll( %channel )
{
   // Don't stop channel itself since that isn't quite what the function
   // here intends.
   
   %channel = sfxOldChannelToGroup( %channel );
   foreach( %source in %channel )
      %source.stop();
}
function sfxGetChannelVolume( %channel )
{
   %obj = sfxOldChannelToGroup( %channel );
   if( isObject( %obj ) )
      return %obj.getVolume();
}

function sfxSetChannelVolume( %channel, %volume )
{
   %obj = sfxOldChannelToGroup( %channel );
   if( isObject( %obj ) )
      %obj.setVolume( %volume );
}

singleton SimSet( SFXPausedSet );

/// Pauses the playback of active sound sources.
/// 
/// @param %channels    An optional word list of channel indices or an empty 
///                     string to pause sources on all channels.
/// @param %pauseSet    An optional SimSet which is filled with the paused 
///                     sources.  If not specified the global SfxSourceGroup 
///                     is used.
///
/// @deprecated
///
function sfxPause( %channels, %pauseSet )
{
   // Did we get a set to populate?
   if ( !isObject( %pauseSet ) )
      %pauseSet = SFXPausedSet;
      
   %count = SFXSourceSet.getCount();
   for ( %i = 0; %i < %count; %i++ )
   {
      %source = SFXSourceSet.getObject( %i );

      %channel = sfxGroupToOldChannel( %source.getGroup() );
      if( %channels $= "" || findWord( %channels, %channel ) != -1 )
      {
         %source.pause();
         %pauseSet.add( %source );
      }
   }
}

/// Resumes the playback of paused sound sources.
/// 
/// @param %pauseSet    An optional SimSet which contains the paused sound 
///                     sources to be resumed.  If not specified the global 
///                     SfxSourceGroup is used.
/// @deprecated
///
function sfxResume( %pauseSet )
{
   if ( !isObject( %pauseSet ) )
      %pauseSet = SFXPausedSet;
                  
   %count = %pauseSet.getCount();
   for ( %i = 0; %i < %count; %i++ )
   {
      %source = %pauseSet.getObject( %i );
      %source.play();
   }

   // Clear our pause set... the caller is left
   // to clear his own if he passed one.
   %pauseSet.clear();
}

//-----------------------------------------------------------------------------
// server audio.cs code below:
//-----------------------------------------------------------------------------


function ServerPlay2D(%profile)
{
   // Play the given sound profile on every client.
   // The sounds will be transmitted as an event, not attached to any object.
   for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
      ClientGroup.getObject(%idx).play2D(%profile);
}

function ServerPlay3D(%profile,%transform)
{
   // Play the given sound profile at the given position on every client
   // The sound will be transmitted as an event, not attached to any object.
   for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
      ClientGroup.getObject(%idx).play3D(%profile,%transform);
}
Steps continued below
#25
04/26/2011 (12:58 pm)
13. created file core.cs in %server project%\game\core\scripts\server containing the following functions (This resolved alot of SFX warnings!!)
//---------------------------------------------------------------------------------------------
// Torque Game Builder
// Copyright (C) GarageGames.com, Inc.
//---------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------
// initializeCore
// Initializes core game functionality.
//---------------------------------------------------------------------------------------------
function initializeCore()
{
   // Not Reentrant
   if( $coreInitialized == true )
      return;
	  
	// Very basic functions used by everyone.
   exec("./audio.cs");
   exec("./canvas.cs");
   
   // Content.
   exec("./audioDescriptions.cs");
   
   // Seed the random number generator.
   setRandomSeed();
   
   // Set up networking.
   setNetPort(0);
  
   // Initialize the canvas.
   initializeCanvas();
     
   $coreInitialized = true;
}

//---------------------------------------------------------------------------------------------
// shutdownCore
// Shuts down core game functionality.
//---------------------------------------------------------------------------------------------
function shutdownCore()
{      
   // Stop file change events.
   stopFileChangeNotifications();
   
   sfxShutdown();
}

14. Created "start server.bat" in %server project%\game with the following code:
test_w32ded.exe -log 2 -dedicated -mission "levels/Empty Terrain.mis"
15. run the batch file and you will see your dedicated server start up.

If iv not forgoten any steps there should be 0 errors.
#26
04/26/2011 (7:59 pm)
Nice job, Lee.
But, may be a place for such useful things in resource section, don't it?
#27
04/27/2011 (6:57 am)
@ Dmitry, thank you, and yes ill post this in the resources section shortly, just wanted to post it here first for those that have been replying and posting.
#28
04/27/2011 (7:55 am)
Lee, well done.
awaiting the resourced version of this.
#29
04/28/2011 (11:23 am)
Resorced version is up can be found Here
#30
04/28/2011 (3:58 pm)
>Please see The following Thred Post 14 onward for the code blocks.
May be it would be a good idea to re-post code blocks just in comments section in your resource thread. So all will be on place.
#31
10/30/2011 (9:59 pm)
Just wanted to post an update.


I now have this working with Torque 3D 1.1 Pro although im having problems connecting using my Internet IP but that is probably down to my computers security settings.

As soon as Torque 3D 1.2 is out and i have upgraded to it, ill go through the process again and report back on my findings.
#32
10/31/2011 (10:45 am)
Why do this? Is it to make it so the client cannot function without the server?

It should be possible to have the script determine what files are used in a server vs client and create a list of files used by each. Then this could be used to create a script to create two separate code trees. It may take more work initially, but it would in the long run save time for each update.
#33
10/31/2011 (6:51 pm)
it is literally to make a dedicated server nothing more

The latest version i have the client version still have the basic server code in it so we can use that for single player and LAN play

however most multilayer game have dedicated servers that are separate from the client build, that is what this is for.
#34
11/01/2011 (4:31 am)
Oh, okay, that makes sense. More of a code maintenance issue. It would be really nice if this could be automated. I hate doing things by hand when the computer can do this kind of work.
#35
11/02/2011 (1:43 am)
Yes i would love for this to be a fully automated process to but until such time here i am lol
#36
12/29/2011 (10:53 am)
hi Lee,

any progress on a 1.2 version yet?
#37
01/01/2012 (1:22 pm)
Unfortunatly i will no longer be keeping this resource up to date as a have since moved over to using a new engine.
#38
07/26/2013 (7:14 pm)
Thanks for your work, Lee.... It's very helpful.
Page«First 1 2 Next»