Game Development Community

dev|Pro Game Development Curriculum

Torque-Script Profile System

by Ben Versaw · 04/26/2010 (6:59 pm) · 2 comments

I needed to create a profile system for my project and had a difficult time finding some of the information needed to create the system. So in light of that fact I decided to donate my system as a resource.

To use the system include the two files below and use these methods:

$ProfileList.AddProfile(%name) = Add the profile to the list
$ProfileList.MakeCurrent(%name) = Make the profile with %name the current profile
$ProfileList.SaveList(%path) = Save the list in the file

$CurrentProfile.SaveProfile() = Save the profile
$CurrentProfile.profileName = The name of the profile
$CurrentProfile.currentState = The current state
$CurrentProfile.currentSubstate = The current substate

$CurrentProfile.gameOptions = The game specific options in the profile. Note the options can be anything the user wants and can be easily changed through the profileDefaultOptions.cs file.

There are two files in the system:

ProfileSystem.cs
//-----------------------------------------------------------------------------
// profileSystem
//
// A general purpose profile system for Torque.
// The system uses two files: profileSystem.cs and profileDefaultOptions.cs
// 
// profileSystem.cs = The meat of the system
// profileDefaultOptions.cs = File for easily working with default game options
//-----------------------------------------------------------------------------
// Exec the rest of the system
exec("./profileDefaultOptions.cs");

//-----------------------------------------------------------------------------
// Variables to change how the system works

// The directory profiles are stored in
$ProfileDirectory = "Profiles/";

// The file the list is stored in
$ProfileListFile = "ProfileList.cs";

//-----------------------------------------------------------------------------
// Global variables

// The current profile
$CurrentProfile = 0;

// The profile list
$ProfileList = 0;

//-----------------------------------------------------------------------------
// Profile Methods

// Method to get the profile from the path
// Param %path = The path to the profile
// Return the profile object
function GetProfile(%path)
{
   // There can only be one CurrentProfile so delete the current one if needed
   if( isObject($CurrentProfile) ) { $CurrentProfile.delete(); }

   // Load the file with the profile
   exec(%path);

   // Get the profile and copy it into the local variables
   %profile = new ScriptObject( : ProfileObject);

   // We are free to delete the loaded object now
   ProfileObject.delete();

   // Load the file with the profile options
   exec($ProfileDirectory @ %profile.profileName @ "options.cs");

   // Get the options and copy it into a local variable
   %profileOptions = new ScriptObject( : ProfileOptions );

   // We are free to delete the loaded object now
   ProfileOptions.delete();

   // Add the options to the profile
   %profile.gameOptions = %profileOptions;

   // Return the profile
   return %profile;
}

// Method to create a new profile
// Param %profileName = The name of the profile we want to create
function MakeProfile(%profileName)
{
   // Make the object
   %newProfile = new ScriptObject()
   {
      class = "Profile";
      profileName = %profileName; // The name of the profile
      currentState = 0;           // The current state the game is in for the player 
      currentSubstate = 0;        // The current substate the player is in
   };

   // Add default game options
   %newProfile.gameOptions = new ScriptObject( : ProfileDefaultOptions );

   // Save the profile
   %newProfile.saveProfile();
}

// Method to save a profile
// Param %this = The Profile calling the method
function Profile::saveProfile(%this)
{
   // The reason we create a new ProfileObject here
   // is so that we can potentially have multiple profiles
   // in order to load / save however the object - must have
   // the ProfileObject as its name so we fix that here

   // Make a new profile object
   %saveObject = new ScriptObject(ProfileObject)
   {
      class = "Profile";
      profileName = %this.profileName;
      currentState = %this.currentState;
      currentSubstate = %this.currentSubstate;
   };
   %saveObject.save($ProfileDirectory @ %this.profileName @ ".cs");
   ProfileObject.delete();

   // Make a new save options
   %saveOptions = new ScriptObject(ProfileOptions)
   {
      class = "ProfileOptionsClass";
   };
   %saveOptions.CopyOptions(%this.gameOptions);
   %saveOptions.save($ProfileDirectory @ %this.profileName @ "options.cs");
   ProfileOptions.delete();
}

//-----------------------------------------------------------------------------
// Profile List Methods

// Method to add a profile to the list
// Param %this = The ProfileList calling the method
// Param %profileName = The name of the profile we want to create
// Return -1 If the profile alreadly exists in the list
function ProfileList::AddProfile(%this, %profileName)
{
   // We don't want duplicates in the list so we check first
   %bFind = 0;
   for( %x = 0; %x < %this.numberPlayers; %x++)
   {
      if(%this.playerList[%x] $= %profileName) { %bFind = 1; }
   }
   if( %bFind == 1 ) { return -1; echo(%profileName SPC "alreadly in ProfieList"); }

   // Add to list
   %this.playerList[%this.numberPlayers] = %profileName;
   %this.numberPlayers++;

   // Make the profile
   MakeProfile(%profileName);

   // Save the list
   %this.saveList($ProfileDirectory @ $ProfileListFile);
}

// Method to change the current profile - this will save the profile
// Param %this = The ProfileList calling the method
// Param %profileName = The profile we want to make current
// Return -1 or -2 if the profileName is not in the list
function ProfileList::MakeCurrent(%this, %profileName)
{
   // This method only makes a profile alreadly in the list current
   // so we first check that the list contains the profile name we want
   if( %this.numberPlayers == 0) { return -1; echo(%profileName SPC "not in ProfileList"); }

   %bFind = 0;
   for( %x = 0; %x < %this.numberPlayers; %x++)
   {
      if(%this.playerList[%x] $= %profileName) { %bFind = 1; }
   }
   if( %bFind == 0 ) { return -2; }

   // Set the profile list's current profile
   %this.currentProfile = %profileName;

   // Load the profile
   $CurrentProfile = GetProfile($ProfileDirectory @ %profileName @ ".cs");

   // Save the profile list
   %this.saveList($ProfileDirectory @ $ProfileListFile);
}

// Method to save the list
// Param %this = The ProfileList calling the methods
// Param %path = The path to the profile list
function ProfileList::saveList(%this, %path)
{
   // Check if we aren't alreadly the GameProfileList - this avoids an error
   // that otherwise occurs when we create the list for the first time
   if( isObject(GameProfileList) )
   {
      %this.save(%path);
      return;
   }

   // The reason we create a new GameProfileList here
   // is so that we can potentially have multiple profile lists
   // in order to load / save however the object - must have
   // the GameProfileList as its name so we fix that here
   %saveObject = new ScriptObject(GameProfileList)
   {
          class = "ProfileList";
          currentProfile = %this.currentProfile;
          numberPlayers = %this.numberPlayers;
   };

   // Get the player list
   for( %x = 0; %x < %this.numberPlayers; %x++)
   {
      %saveObject.playerList[%x] = %this.playerList[%x];
   }
   %saveObject.save(%path);

   GameProfileList.delete();
}

// Method to get the profile list for the game
// Param %path = The path to the profile list
// Return the profile list
function GetProfileList(%path)
{
   // Try to load the file first
   exec(%path);

   // See if we have the list
   if( !isObject(GameProfileList) )
   {
      // We need to create the list
      echo("Creating profile list");
      new ScriptObject(GameProfileList)
      {
          class = "ProfileList";
          currentProfile = "";   // The current profile in use
          playerList = "";       // The list of players as a string array
          numberPlayers = 0;     // The number of players in the list
      };
   }

   // Copy the list
   %profileList = new ScriptObject( : GameProfileList);

   // This line is needed to load the current profile
   %profileList.MakeCurrent(%profileList.currentProfile);

   // We are free to delete the loaded object now
   GameProfileList.delete();

   // Save the list
   %profileList.saveList($ProfileDirectory @ $ProfileListFile);

   // Return the object
   return %profileList;
}

// This method ensures that we have a GameProfileList at game start
$ProfileList = GetProfileList($ProfileDirectory @ $ProfileListFile);

//-----------------------------------------------------------------------------
ProfileDefaultOptions.cs
//-----------------------------------------------------------------------------
// profileSystem
//
// A general purpose profile system for Torque.
// The system uses two files: profileSystem.cs and profileDefaultOptions.cs
// 
// profileSystem.cs = The meat of the system
// profileDefaultOptions.cs = File for easily working with default game options
//-----------------------------------------------------------------------------

// Define the default game options
new ScriptObject(ProfileDefaultOptions)
{
   class = "ProfileOptionsClass";
   Volume = "100";
   fullscreen = "true";
};

// We don't know what options are stored here unless we tell them
//
// Method to copy the values from another ProfileOptions object
// Param %this = the object calling this method
// Param %optionsToCopy = The object we want to copy values from
function ProfileOptionsClass::CopyOptions(%this, %optionsToCopy)
{
   %this.volume = %optionsToCopy.volume;
   %this.fullscreen = %optionsToCopy.fullscreen;
}

//-----------------------------------------------------------------------------

#1
04/27/2010 (5:37 am)
This is a good resource. I will test it on 1.81 here later thanks for this
#2
04/27/2010 (8:38 am)
Ya the main thing I had trouble with was loading script objects but still allowing multiple copies.

Also I should of noted I built / tested it in the latest TGB but I think it should work in all engines.

Edit: Example of its use in TGB Forums ( www.torquepowered.com/community/forums/viewthread/114541 )