Environment Package Save/Load System
by Michael Perry · 01/22/2008 (7:25 am) · 4 comments
GENERAL INFO AND INTRODUCTION
This resource introduces a package save/load system to Torque's WorldEditor. Using the new Save Package GUI, with only a few mouse clicks you can export any combination of environment objects(Sun, Sky, foliage, precipitation, BG Forest, etc) to a package file. Instead of manually recreating these objects, or copying and pasting them in script, you can use the Load Package GUI to add the saved environment to your other missions.
This resource came about at the request of Steve "Asian Steve" Ngu, lead level developer for Zombie Shortbus. Steve wanted a module the mission creation team could use to rapidly reproduce environments for levels which share geographic zones. For instance, we will have two missions with dissimilar game play objectives, entities, and terrain. However, the missions are located near each other geographically, and share a similar time frame.
What if one mission is a wetland, with lush foliage and forestry, overcast by heavy rain and wind? Through that description, you will probably modify the Sun and Sky, add Precipitation, foliage replicators, shape replicators, Ben Garney's Forest Pack, and more.
The second mission takes place 4 hours later, 9 miles away. Your options are to copy and paste files/scripts, manually recreate the objects, or use this resource.
SETUP
This resource was developed in following environment:
Engine Version - TGE/AFX 1.5.2
Compiler - MS Visual Studio 2005
Script IDE - Torsion
You will be modifying 1 engine file, editing 2 script files, and adding 2 GUIs. On to the good stuff. . .
Step 1: Download the files: (PackageSystemResource.zip)
Step 2: Back up original files:
I added this just before the listObjects Console Method[li]Recompile the Debug and Release executables Step 5: Script Changes:
In examplecreatoreditorEditorGui.cs, modify EditorGui::init(%this):
Swap
With
In examplecreatoreditorEditorGui.cs, add two new case statements to EditorMenuBar::onFileMenuItemSelect:
Step 6: RTFM!
Bugs & Suggestions
If you look through the script code, you will come across comments like this:
These are points of interest. Some notes merely draw your attention to code blocks important to this resource, while others point out code that is bugged or can be improved. For instance, the code under Note # 3 is volatile and could definitely benefit from an alternative method. My suggestion there is to use Orion Elenzil's findWord/findField/findRecord resource.
Also, you'll notice I am using the file extension ".pak." I chose this on a whim to separate the exported files from the rest of the scripts. However, .pak files are nothing more than .cs files with a different name. You can still open them with notepad, but Torsion seems to get stuck on them. You can change the file extension in the .gui files.
The big bug right now is found under Note # 4. You must manually relight your mission to get the proper shadowing of your objects. The big annoyance is that your foliage and shape replicators do not create and render their objects unless you click on each replicator in the World Inspector list. What happens here is that the message to create the foliage does not get fired off correctly when the replicators are executed from a client script. You will notice my first attempt to force the replication did not succeed, but I left the commented code in so you can attempt to resolve the issue if I can't.
More to come...
Conclusion and Updates
Post your thoughts and suggestions here in the resource so that together, we can improve the code.

This resource introduces a package save/load system to Torque's WorldEditor. Using the new Save Package GUI, with only a few mouse clicks you can export any combination of environment objects(Sun, Sky, foliage, precipitation, BG Forest, etc) to a package file. Instead of manually recreating these objects, or copying and pasting them in script, you can use the Load Package GUI to add the saved environment to your other missions.
This resource came about at the request of Steve "Asian Steve" Ngu, lead level developer for Zombie Shortbus. Steve wanted a module the mission creation team could use to rapidly reproduce environments for levels which share geographic zones. For instance, we will have two missions with dissimilar game play objectives, entities, and terrain. However, the missions are located near each other geographically, and share a similar time frame.
What if one mission is a wetland, with lush foliage and forestry, overcast by heavy rain and wind? Through that description, you will probably modify the Sun and Sky, add Precipitation, foliage replicators, shape replicators, Ben Garney's Forest Pack, and more.
The second mission takes place 4 hours later, 9 miles away. Your options are to copy and paste files/scripts, manually recreate the objects, or use this resource.
SETUP
This resource was developed in following environment:
Engine Version - TGE/AFX 1.5.2
Compiler - MS Visual Studio 2005
Script IDE - Torsion
You will be modifying 1 engine file, editing 2 script files, and adding 2 GUIs. On to the good stuff. . .
Step 1: Download the files: (PackageSystemResource.zip)
Step 2: Back up original files:
- engineconsolesimbase.cc[li]examplecommonclientcanvas.cs[li]examplecreatoreditorEditorGui.cs
- Copy SavePackageDlg.gui and LoadPackageDlg.gui into the examplecommonui directory
- Open engineconsolesimbase.cc and add the following:
///////////////////////////////////////
// Stole from engineguiguiDebugger.cc
static const char* itoa(S32 i)
{
static char buf[32];
dSprintf(buf, sizeof(buf), "%d", i);
return buf;
}
ConsoleMethod(SimSet, getObjects, const char*, 3, 3, "set.getObjects("className")")
{
argc; argv;
U32 iBufferSize = 0; // Will determine size of return string
Vector<S32> myVec; // Will store IDs of the objects we find
const char* searchType = argv[2]; // Find out what we are looking for
// Iterate through the simset (missiongroup)
object->lock();
SimSet::iterator itr;
for(itr = object->begin(); itr != object->end(); itr++)
{
SimObject *obj = *itr;
// Get the className of the current object in interation
const char *className = obj->getClassName();
// Is the current object in interation the same as what we are looking for?
if(!dStrcmp(className, searchType))
myVec.push_back(obj->getId()); // Yes, so add it to our vector
}
object->unlock();
// Allocate memory for the return buffer
iBufferSize = myVec.size()*5*sizeof(SimObjectId);
// Create a return buffer (string format)
char* retBuffer = Con::getReturnBuffer(iBufferSize);
// Clear out the buffer(paranoia check)
dStrcpy(retBuffer, "");
// Iterate our vector and fill up our returnBuffer
for(int j = 0; j < myVec.size(); j++)
{
// Add the ID in string format
dStrcat(retBuffer, itoa(myVec[j]));
// Add a space between IDs
dStrcat(retBuffer," ");
}
// Return
return retBuffer;
}- In examplecommonclientcanvas.cs, modify the initCanvas function to look like this:
//-----------------------------------------------------------------------------
// Function to construct and initialize the default canvas window
// used by the games
function initCanvas(%windowName, %effectCanvas)
{
...
// Common GUI's
[b]// Package guis
exec("~/ui/SavePackageDlg.gui");
exec("~/ui/LoadPackageDlg.gui");
[/b]
// Commonly used helper scripts
...
}Swap
EditorMenuBar.clearMenus();
EditorMenuBar.addMenu("File", 0);
EditorMenuBar.addMenuItem("File", "New Mission...", 1);
EditorMenuBar.addMenuItem("File", "Open Mission...", 2, "Ctrl O");
EditorMenuBar.addMenuItem("File", "Save Mission...", 3, "Ctrl S");
EditorMenuBar.addMenuItem("File", "Save Mission As...", 4);
EditorMenuBar.addMenuItem("File", "-", 0);
EditorMenuBar.addMenuItem("File", "Import Terraform Data...", 6);
EditorMenuBar.addMenuItem("File", "Import Texture Data...", 5);
EditorMenuBar.addMenuItem("File", "-", 0);
EditorMenuBar.addMenuItem("File", "Export Terraform Bitmap...", 5);
EditorMenuBar.addMenuItem("File", "-", 0);
EditorMenuBar.addMenuItem("File", "Toggle Map Editor...", 7, "F11");
EditorMenuBar.addMenuItem("File", "Quit", 8);With
EditorMenuBar.clearMenus();
EditorMenuBar.addMenu("File", 0);
EditorMenuBar.addMenuItem("File", "New Mission...", 1);
EditorMenuBar.addMenuItem("File", "Open Mission...", 2, "Ctrl O");
EditorMenuBar.addMenuItem("File", "Save Mission...", 3, "Ctrl S");
EditorMenuBar.addMenuItem("File", "Save Mission As...", 4);
EditorMenuBar.addMenuItem("File", "-", 0);
EditorMenuBar.addMenuItem("File", "Import Terraform Data...", 6);
EditorMenuBar.addMenuItem("File", "Import Texture Data...", 5);
EditorMenuBar.addMenuItem("File", "-", 0);
EditorMenuBar.addMenuItem("File", "Export Terraform Bitmap...", 5);
EditorMenuBar.addMenuItem("File", "-", 0);
[b]EditorMenuBar.addMenuItem("File", "Load Package...", 7);
EditorMenuBar.addMenuItem("File", "Save Package...", 8);
EditorMenuBar.addMenuItem("File", "-", 0); [/b]
EditorMenuBar.addMenuItem("File", "Toggle Map Editor...", 9, "F11");
EditorMenuBar.addMenuItem("File", "Quit", 10);. . .
case "Load Package...":
EditorLoadPackage();
case "Save Package...":
EditorSavePackageAs();
. . .Step 6: RTFM!
- Open and read PackageReadme.doc for instructions on using the module
Bugs & Suggestions
If you look through the script code, you will come across comments like this:
////////////////////////////// // NOTE # 1 //////////////////////////////
These are points of interest. Some notes merely draw your attention to code blocks important to this resource, while others point out code that is bugged or can be improved. For instance, the code under Note # 3 is volatile and could definitely benefit from an alternative method. My suggestion there is to use Orion Elenzil's findWord/findField/findRecord resource.
Also, you'll notice I am using the file extension ".pak." I chose this on a whim to separate the exported files from the rest of the scripts. However, .pak files are nothing more than .cs files with a different name. You can still open them with notepad, but Torsion seems to get stuck on them. You can change the file extension in the .gui files.
The big bug right now is found under Note # 4. You must manually relight your mission to get the proper shadowing of your objects. The big annoyance is that your foliage and shape replicators do not create and render their objects unless you click on each replicator in the World Inspector list. What happens here is that the message to create the foliage does not get fired off correctly when the replicators are executed from a client script. You will notice my first attempt to force the replication did not succeed, but I left the commented code in so you can attempt to resolve the issue if I can't.
More to come...
Conclusion and Updates
Post your thoughts and suggestions here in the resource so that together, we can improve the code.


Torque Owner Ed Johnson