Plastic Gem #35: Plastic Tweaker
by Anthony Rosenbaum · 08/07/2008 (11:17 am) · 8 comments

Plastic Tweaker
Difficulty: Moderate
Gem #35 describes a Plastic Games product that is in Beta and ready for testing! The Plastic Tweaker is the most powerful tool we have yet created for ourselves, and works fantastically with all our Gems. It will be available for sale soon. It is in Beta now and we could use your help with testing. If you are a TGE or TGEA user check it out.
Get the Plastic Tweaker at www.plasticgames.com/tools/tweaker/
The Plastic Tweaker is an in-game datablock editor. It rocks. How often do you find yourself testing something by loading the app, seeing a value is too much or too little? So you shut the app down, change the value on a datablock then reload. Sure it might seem like a small amount of time maybe 20-40 seconds but over the course of a day, week, month and year it adds up. The Plastic Tweaker allows you to by pass the shutdown reload stages by changing and reloading the datablock on the fly. In fact the hardest part of using the Tweaker is breaking the habit of NOT shutting the app down.
PlasticTweaker, What is it?
Before we delv into the intricacies of the Plastic Tweaker let's take a second to discuss what it is and how it works. I said earlier that it was a datablock editor, which it is but it is much more. What it is not is a datablock creator. You cannot make entirely new datablocks with it, though you can edit the fields of any datablock already in your game. Datablocks that are tweakable are marked with a simple comment with a special code in it. You can put these comments in your code yourself, or you can use the Tweaker to do that for you. The Tweaker parses your files finding all the tweaks,
and loads them into a GUI driven tool 
as one of many possible panels.

Each line on a panel is a 'tweak', a tweak can be a property on an object (datablock scriptobject etc) or a Global variable.
The Plastic Tweaker will determine if the property is of a particular type (TypeS32, TypeBool etc) and will build an approprite GUI interface for the type. Here is a few examples
TypeBool

TypeColorF or TypeColorI

TypeS32 TypeS8 TypeF32

TypeRectI

TypeEaseF(See PlasticGem 3: Ease)

If the tweak is a global variable or part of a scriptobject it will default to TypeString, but if you would like to use a custom GUI for the tweak we allow you the opportunity to change the tweak to a particular type with the Tweak Property Window (TPW)
Notice the type section, here is a image of the supported types

Note, only tweaks which are not intrisically of a particular type can be changed to another type, meaning a Player.mass (TypeF32) cannot become TypeColorF.
We'll save a deeper discussion of the TPW for future gems.
Plastic Tweaker Conventions
The tweaker has two main sections, Main and Play. The Main section is used for things that require reloading the server, while the Play section is for ingame editing. Each has its own special comment. The comment conventions will be parsed only once per application start. The code inbetween the comments will be added to the tweaker, accessable thru the dropdown box on the right side of the tweaker.
The start of the tweak must either be
//M[or
//P[
followed by an identifier for the panel it will reside on
//P[ sometweakPanel
the tweak block ends with either
//M]or
//P]
Main Tweak Panel convention
//M[ aMainPanelTweak $fred = true; //M]
Play Tweak Panel convention
//P[ aPlayPanelTweak $wilbur = "super cool"; //P]
Tweaks can be added around Global variables . .
//M[ SeverTweak $Pref::Server::Name = "TGE Game Server"; //M]
. . . or datablocks properties.
datablock PlayerData(PlayerBody)
{
// . . . code omitted for space
//P[ playerTweak
mass = 90;
//P]
// . . . code omitted for space
};Listeners
Many times the tweaks need to execute some code after the tweak has been changed. Such as: reloading states for shapebase images or setting new datablocks. In order to accomplish this we have also added a listener feature for a tweak section.
datablock ShapeBaseImageData(weaponImage){
// . . . code omitted for space
//P[ WeaponTweaks listener=onWeaponImageTweaksChanged
stateName[1] = "Activate";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.6;
stateSequence[1] = "Activate";
//P]
// . . . code omitted for space
};
function onWeaponImageTweaksChanged(%tweak){
weaponImage.reloadStates();
}Here is a player datablock tweak example using the callback listener.
datablock PlayerData(PlayerBody)
// . . . code omitted for space
//P[ playerTweaks listener=onPlayerTweaksChanged
mass = 90;
//P]
// . . . code omitted for space
};
function onPlayerTweaksChanged (%tweaks)
{
%me = LocalClientConnection.player;
// now we must update the objects that use these datablocks...
// such as the player...
updatePlayerDatablock(%me);
}
function updatePlayerDatablock(%player)
{
%dataBlock = %player.getDataBlock();
%player.setDataBlock(NotUsedPlayerBody); // See NOTE
%player.setDataBlock(%dataBlock);
}NOTE: it is very important to have a empty datablock to set before setting the new datablock otherwise the changes will not take effect.Object Oriented Tweaks
To accomidate a heirarchial approach to tweaking the changed values rest within the listener's %tweak parameter. This coupled with the TweakManager's copy field's method allows you to mitigate changes to other similar datablocks.
datablock ProjectileData( BaseBullet )
{
projectileShapeName = "~/data/shapes/gun/bullet.dts";
// . . . code omitted for space
//P[ GunTweaks listener=onBulletTweaksChanged
damageRadius = 9.0;
muzzleVelocity = "150";
//P]
};
datablock ProjectileData( RedBullet : BaseBullet )
{
projectileShapeName = "~/data/shapes/gun/red_bullet.dts";
};
datablock ProjectileData( BlueBullet : BaseBullet )
{
projectileShapeName = "~/data/shapes/gun/blue_bullet.dts";
};
function onBulletTweaksChanged(%tweaks)
{
// update dependent datablocks for fields we tweak...
TweakManager.copyFields(%tweaks, RedBullet, BaseBullet);
TweakManager.copyFields(%tweaks, BlueBullet, BaseBullet);
}DataTypesTweaks can be enhanced by providing a datatype on the field's comment. These comments will be parsed by the tweaker and will provide special guis to assist in the tweaking process. For instance TypeBool will provide a dropdown containing true or false instead of a string field.
datablock PlayerData(PlayerBody) // . . . code omitted for space //P[ playerTweaks listener=onPlayerTweaksChanged mass = 90; // TypeF32 //P] // . . . code omitted for space }; Supported types are:TypeString = editable text field
TypeFilename = browse file button
TypeS8 = slider
TypeS32 = slider
TypeF32 = slider
TypeBool = dropdown and Ratio button
TypeColorF = color sliders amd button for Torque color picker
TypeColorI = color sliders amd button for Torque color picker
TypePoint2I = editiable text field button for plastic picker
TypePoint2F = editiable text field
TypePoint3F = editiable text field
TypePoint4F = editiable text field
TypeRectI = editiable text field button for plastic picker
TypeBox3F = editiable text field
TypeEaseF = editable text field, drop downs, graphic showing selection
Tool Tips
Tool Tips can also be provided either by omitting the DataType or providing text after the dataType on the same line.
datablock PlayerData(PlayerBody) // . . . code omitted for space //P[ playerTweaks listener=onPlayerTweaksChanged mass = 90; // TypeF32 Mass of the player //P] // . . . code omitted for space };
Spacing
Organizing is a key to efficient tweaking, so we have provided a spacer comment to be enbedded between tweakable lines. Spacing tweaks can also be handled in the Plastic Tweaker with the right click menu on a tweak
or with commands from the edit menu

//P[ goodTweak $tweak = "2"; //--------------- $NextTweak = true; //P]
Do Nots
Now some warnings, do not added extra spaces between tweak lines.
//P[ badTweak $tweak = "2"; // BAD, DO NOT DO THIS OR HAVE THIS LINE BE AN EMPTY STRING $badTweak = true; //P]
Do not added multiple tweaks on any one line.
//P[ badTweak $tweak = "2"; $ThisMakesItABadTweak = true; // BAD, DO NOT DO THIS //P]
Do not added globals or expressions as values for tweaks
//P[ badTweak $maxplayers = $server::MaxPlayers; // BAD, DO NOT DO THIS //P]
Tweaks can be added to script and gui files, but they are hard to manage in GUI files because if the you edit the GUI with the editor you lose the Tweak Page for that control and have to recreate it. This is a limitation we will address in future versions of the Tweaker.
For something really neat try tweaking a material datablock in TGEA!
Next Gem
The Next Gem will discuss the comment convention used for adding tweaks and the comment GUI tool the Tweak Property Window and Tweak List Editor
About the author
#2
08/07/2008 (5:18 pm)
WOAH, really really, cool! and... for free? Good work and thanks!
#4
I did note in the console.log that there are a number of missing files, though:
I suspect some of them might be introduced with later Gems, but a quick check does not necessarily confirm this. Are these files that were at some point removed, but without removing the exec line from the plastic/init.cs file?
08/17/2008 (8:35 pm)
So I have a quick question. I started installing the Tweaker, using the files downloaded through the above link. Loads up fine, and ctrl-T brings up the Plastic Tweaker as expected. Nice!I did note in the console.log that there are a number of missing files, though:
--------- Initializing: Server Side Plastic Gems --------- Missing file: plastic/server/../plasticManager.cs! Loading compiled script plastic/server/tweak/init.cs. Loading compiled script plastic/server/tweak/tweakServer.cs. Missing file: plastic/server/light/PlasticLightShapeManager.cs! Missing file: plastic/server/light/PlasticLightShape.cs! Missing file: plastic/server/core/sceneObject.cs! Missing file: plastic/server/core/gameBase.cs! Missing file: plastic/server/core/shapeBase.cs! Missing file: plastic/server/core/staticShape.cs! Missing file: plastic/server/core/interiorInstance.cs! Missing file: plastic/server/core/triggerManager.cs! Missing file: plastic/server/core/managedTrigger.cs! Loading compiled script plastic/server/plasticMarkerManager.cs. Loading compiled script plastic/server/plasticRing.cs. plastic/server/plasticRing.cs (15): preload failed for PlasticRing: ShapeBaseData: Couldn't load shape "plastic/data/shapes/ring/ring.dts". Loading compiled script plastic/server/plasticLine.cs. plastic/server/plasticLine.cs (15): preload failed for PlasticLine: ShapeBaseData: Couldn't load shape "plastic/data/shapes/grid/grid.dts". Loading compiled script plastic/server/magicButtonManager.cs. Loading compiled script plastic/server/autoNumberManager.cs. Loading compiled script plastic/server/digitBillboard.cs. plastic/server/digitBillboard.cs (20): preload failed for DigitBillboardShape: ShapeBaseData: Couldn't load shape "plastic/data/shapes/markers/marker_digits_v2.dts". Loading compiled script plastic/server/digitMarker.cs. plastic/server/digitMarker.cs (26): preload failed for SampleDigitMarker: ShapeBaseData: Couldn't load shape "plastic/data/shapes/markers/marker_digits_v2.dts". Loading compiled script plastic/server/plasticShapeTrigger.cs. plastic/server/plasticShapeTrigger.cs (35): Unable to instantiate non-conobject class PlasticShapeTriggerData. Missing file: plastic/server/fence/fenceManager.cs! Missing file: plastic/server/fence/fenceRail.cs! Missing file: plastic/server/fence/fencePost.cs! Missing file: plastic/server/door/doorManager.cs! Missing file: plastic/server/door/door.cs! Missing file: plastic/server/door/doorFrame.cs! Missing file: plastic/server/door/testDoor.cs! Loading compiled script plastic/server/particleViewer.cs. --------- Server Side Plastic Gems - Initialized ---------
I suspect some of them might be introduced with later Gems, but a quick check does not necessarily confirm this. Are these files that were at some point removed, but without removing the exec line from the plastic/init.cs file?
#5
Zip updated to reflect this
08/18/2008 (4:29 am)
Correct, I thought I removed those execute calles the only thing that is neesed for the tweakers exec("./tweak/init.cs"); // this part of tweaker must be on server...Zip updated to reflect this
#6
More Info Here: http://www.garagegames.com/blogs/3213/15571
01/02/2009 (6:56 pm)
Tweaker Does not come with source files, if you purchase this program you will not be able to edit or modify this resource for your own engine.More Info Here: http://www.garagegames.com/blogs/3213/15571
#7
01/02/2009 (8:20 pm)
edited to above.
#8
03/13/2009 (9:18 am)
As March 13 '08 . The Plastic tweaker is compatable with 1.8.1
Torque Owner Nathan Kent
Haven't downloaded it yet, but you can be sure I will, thanks! =D
Edit->Downloaded, but I haven't installed it. Right now, my game has no datablocks and only one global variable (Hey! I just started!), so I didn't see the need just yet. =P