Torque Game EngineTorque Game Engine Documentation
Version 1.3.x

Interfacing with the Engine

Alright, up until this point, we have talked about scripting alone. Now we will discuss the interface between the console and the core engine.

Before starting it is important that we define a consistent set of terms to describe the concepts we are about to explore:

Table 5.1. Engine-Console Interface Terminology

TermDefinition
C++-Specific Terms
C++ Variable
  • A C++ variable not associated with any class.
C++ Function
  • A routine declared and defined in C++, which is not associated with any class.
Member
  • A variable defined and declared in a C++ class.
  • Can only be accessed in association with an instance of an object.
Method
  • A routine defined and declared in a C++ class.
  • Can only be accessed in association with an instance of an object.
Script-Specific Terms
Local or Global Variable
  • A variable in the Console.
  • Global variables may be defined in C++ and linked to a global engine variable. Allowed C++ modifiers: const, static.
Function
  • A routine in the Console not associated with any particular namespace.
  • May be defined entirely in script or C++.
Field
  • A variable associated with an object in the Console.
  • Linked with a Member.
Dynamic Field
  • A variable associated with an object in the Console.
  • Exists only in the Console.
Command (deprecated)
  • A routine associated with a particular namespace in the Console.
  • Linked with an existing Method.
  • Console Commands are deprecated-- that is, they should no longer be used. Information on them is provided for reference only.
Console Method
  • A routine associated with a particular namespace in the Console.
  • Exists only the Console.

They say, "a picture is worth a thousand words". So, here is an illustration of the above table:


                    The Engine-Console Interface

Engine Interfacing Problem-Solution Matrix

Before we jump into the gory details of interfacing the engine and console, here is a problem solution matrix:

Table 5.2. Engine Interface Problem-Solution Matrix

ProblemSolutionSolution Type
C++ to Console

Expose Member

as Field

addField()

addFieldV()

FUNCTION

Expose Member

as Field

addNamedField()

addNamedFieldV()

MACRO

Expose/Remove global C++ Variable or static Member

as Local Variable

Con::addVariable()

Con::removeVariable()

FUNCTION

Expose Method

as Command (deprecated)

Con::addCommand() (deprecated)

FUNCTION

Create Console Method from C++

ConsoleMethod()

MACRO

Create Console Function from C++

ConsoleFunction()

MACRO

addField()

This function allows you to link C++ class Members to console object Fields.

The rules for using this function are

  • Member to be exposed must be non-dynamic (i.e. not a pointer).
  • Member to be exposed must be non-static.
  • addField() statements must be included in the class initPersistFields() method.

            void ConsoleObject::addField(const char*  in_pFieldname,
                       const U32 in_fieldType,
                       const dsize_t in_fieldOffset,
                       const char* in_pFieldDocs)

            void ConsoleObject::addField(const char*  in_pFieldname,
                                   const U32 in_fieldType,
                                   const dsize_t in_fieldOffset,
                                   const U32 in_elementCount,
                                   EnumTable *in_table,
                                   const char* in_pFieldDocs)
        
  • in_pFieldname- String specifying variable name as used in console.
  • in_fieldType- The field's type. (Types are specified in consoleTypes.h)
  • in_fieldOffset- This is a numeric value calculated using the Offset() macro.
  • in_elementCount- Number of elements at offset. The default value is 1, but if you are referencing an array then this value will be the number of elements in the array.
  • in_table- This argument is used when the field type is TypeEnum. In this special case, you need to define an EnumTable containing a map of the ENUM values and the strings to represent them in the console.
  • in_pFieldDocs- A short string describing the field in plain English. This field is used in Torque's automatic Console documentation functionality.

Here is an example (found in guiCrossHairHud.cc):

            class GuiCrossHairHud : public GuiBitmapCtrl
            {
                ...
               ColorF   mDamageFillColor; // declared here
                ...
            };

            void GuiCrossHairHud::initPersistFields()
            {
                ...
               addField( "damageFillColor", TypeColorF, Offset( mDamageFillColor,
                          GuiCrossHairHud)); // added in initPersistFields()
                ...
            }
        

In this code, the Member mDamageFillColor has been linked to the Field damageFillColor. If you wish to test the ability to inspect and modify this field, do the following:

  • Start the SDK
  • Run any mission
  • Open the GUI Editor (F10) and find the GuiCrossHairHud in the GUI Inspector Tree.
  • Remember the control's handle.
  • Stop the GUI Editor (F10)
  • Open the console (~)
  • Try these commands (substitute handle for ####):

            echo(####.damageFillColor);
            ####.damageFillColor = " 1.0 0.0 0.0 1.0";
            echo(####.damageFillColor);
        

You may notice that although the contents of the variable were changed (to 100% opaque RED), the reticule stayed GREEN. This is because you changed the Server-copy of the variable, not the Client-copy. The relationship between clients and servers can get confusing. We don't have space to go into it here, but to get a better understanding, checkout the Torque networking documentation.

For clarity's sake here are some made up samples demonstrating the use of this function:

            //// Adding simple variable

            // the varible we want to add
            bool   bTorqueRocks;
            // adding it
            addField( "TorqueRocks", TypeBool, Offset(bTorqueRocks,EGTClass));


            //// Adding an array
            // the varible we want to add
            S32   arynEGTChapters[28];
            // adding it
            addField( "TorqueRocks", TypeS32, Offset(arynEGTChapters,EGTClass),28);


            //// Adding an ENUM
            // the varible we want to add
            StateData::LoadedState stateLoaded[MaxStates];
            // the EnumTable
            static EnumTable::Enums enumLoadedStates[] =
            {
               { ShapeBaseImageData::StateData::IgnoreLoaded, "Ignore" },
               { ShapeBaseImageData::StateData::Loaded,       "Loaded" },
               { ShapeBaseImageData::StateData::NotLoaded,    "Empty" },
            };
            static EnumTable EnumLoadedState(3, &enumLoadedStates[0]);
            // adding it
            addField("stateLoadedFlag", TypeEnum, Offset(stateLoaded, ShapeBaseImageData), MaxStates, &EnumLoadedState);
        

Having covered the most commonly used version of the addField() functions, lets quickly outline the uses and syntax for the other variety.

addFieldV()

This is a specialized version of the addField() function. It does not handle arrays or ENUMs, but it has the nice feature of a validator function. Let us look at the syntax and then I'll explain validator functions.

            void ConsoleObject::addFieldV(const char*  in_pFieldname,
                              const U32 in_fieldType,
                              const dsize_t in_fieldOffset,
                              TypeValidator *v)
        
  • in_pFieldname- String specifying variable name as used in console.
  • in_fieldType- The variable type. (Again, types are specified in consoleTypes.h)
  • in_fieldOffset- This is a numeric value calculated using the Offset() macro.
  • *v- This is a pointer to a TypeValidator class of which there are several derived types to choose from. You can find the pre-defined validator definitions in typeValidators.h, and yes, it is possible to create your own validator classes.

Type Validator Classes

Type Validator Classes are used to restrict the values a field may be given. If illegal values are assigned to a validated field, the validator function will print an error to the console and set the field to a valid value.

The two most commonly used Type Validator Classes are FRangeValidator and IRangeValidator. As you might imagine, the prior validates that the values a user inputs for the 'to be validated' field are within an inclusive range of floating-point values. The later is used for integers.

            // from projectile.cc around line 126
            // light radius is limited to between 1.0 and 20.0, inclusive.
            addNamedFieldV(lightRadius, TypeF32, ProjectileData, new FRangeValidator(1, 20));
        

addNamedField() and addNamedFieldV()

These two varients of addField() are actually MACROS that do nothing more than give the console field the same name as the class member which is being accessed.

            #define addNamedField(fieldName,type,className) \ addField(#fieldName, type, Offset(fieldName,className))
        
            #define addNamedFieldV(fieldName,type,className, validator) \ addFieldV(#fieldName, type, Offset(fieldName,className), validator)
        

Offset() MACRO

I glossed over the Offset macro above in the interest of first discussing the usage of addField() and its many versions. The offset macro is a cool bit of coding that calculates the position of a variable within an instance of a class. Or, more exactly, the Offset macro calculates how many bytes from the beginning of a class in memory a variable is located. Here is the syntax:

            Offset(VariableName, ClassName)
        
  • VariableName- This is the (C++) name of the class member we want to expose.
  • ClassName- This is the name of the class the member resides in.

removeField()

This function allows you to unlink a previously linked member-field pair. In fact, this removes the field from the console entirely. Simple as that. Why do it? Consider the case where you derive from an object that does an addField() call for a member that you have decided should not be accessible (like position for Terrain data).

            bool ConsoleObject::removeField(const char* in_pFieldname)
        
  • in_pFieldname- String specifying field to be removed.
            // 1. TerrainBlock is inherited from SceneObject.
            // 2. SceneObject links member mObjToWorld with position.
            // 3. TerrainBlock undoes this(in terrData.cc) removeField("position");
        

Con::addVariable

This function allows you to expose a global C++ variable or a static Member as a global variable in the console. (See camera.cc.)

            Con::addVariable(const char *name, S32 t, void *dp);
        
  • name- String specifying name of global variable (in console).
  • t- The variable type. (Types are specified in consoleTypes.h).
  • dp- A pointer to the global C++ variable, or static Member.

The above code exposes the global C++ variable mMovementSpeed in the console as a global variable named Camera::movementSpeed.

Note: This controls the free camera flight speed while editting. Now you know another way to set it beyond the normal editor keystrokes.

Con::removeVariable (deprecated)

This function allows you to remove a global variable from the console that was previously added with one of the variants of the addVariable() function.

            bool removeVariable(const char *name)
        
  • name- String specifying name of global variable (in console).

Upon searching, I found not a single instance in which this was used. This is probably because it would be a sign of poor planning to add then remove a variable. Having the source code, you could just remove the add call and be done with. Nonetheless, you can use this function if it suits you to do so.

Con::addCommand (deprecated)

This function allows you to expose a Method as a Command. However, it is now deprecated-- you are not encouraged to use it. Instead, you should create a method in C++ (if you need to use it in the engine or it needs to be fast), and then call this method from within a ConsoleMethod.

ConsoleMethod

This is a macro that allows you to create a new Console Method from C++. The use of ConsoleMethod() is not much expanded in the engine as it has been chosen as a means of replacing the more clumsy addCommand() calls. The static variant of ConsoleMethod is for methods that you want to call statically. For example, 'GameConnection::getServerConnection()'.

            ConsoleMethod(className,scriptname,returnType,minArgs,maxArgs,usage)
            ConsoleStaticMethod(className,scriptname,returnType,minArgs,maxArgs,usage)
        
  • className- The name of the class the method is in.
  • scriptname- The name the method will be given in the console (i.e. used by TorqueScript).
  • returntype- The return type of the method.
  • minargs- The minimum arguments this method takes.

    • Note: The minimum, because the name of the console method is automatically passed as the first argument and the handle is automatically passed as the second argument.
  • maxargs- The maximum number of args that can be passed to this method.

    • Note: If you put 0 in this field, it means any number of arguments may be passed to the method.
  • usage- A string that will be printed as a help statement if someone later attempts to use this method with the wrong number of arguments. This usage is also when you use the obj.dump() command.
            //From SimBase.cc

            ConsoleMethod(SimObject, getId, S32, 2, 2, "obj.getId()")
            {
               argc; argv;
               return object->getId();
            }
        

In the above function, we've (well, the engine authors really...) written a simple utility to return the current object's unique ID (its handle). A short breakdown is as follow:

  • It can be called on (by) all objects which are SimObjects or children of SimObject
  • The name of the function in TorqueScript will be 'getId' or more specifically 'SimObject::getId'.
  • 'getId' takes two arguments, the ConsoleMethod name and the object's handle (which, by the way, is the same thing we're being asked to return).
  • The ConsoleMethod is expected to return a signed 32-bit value.
  • The ConsoleMethod will take a minimum and a maximum of two arguments.
  • The usage message is: "obj.getId()"
  • Internally,

    • we do nothing with the standard argc and argv variables.
    • we call a method named 'getId()' to return a signed 32-bit value.

ConsoleFunction

This is a macro that allows you to create a new Console Function from C++. Ex: ShapeBase.cc

            ConsoleFunction(name,returnType,minArgs,maxArgs,usage)
        
  • name- This is the name of the function as it will be used in the console.
  • returnType- Is the return type of the function.
  • minArgs- Minimum arguments this function can accept.

    • Note: 1 is the minimum, because the name of the function is automatically passed as the first argument.
  • maxArgs- Maximum arguments this function can accept.

    • Note: If you put 0 in this field, it means any number of arguments may be passed to the function.
  • usage- Is a string that will be printed as a help statement if someone later attempts to use this function with the wrong number of arguments.
            // From main.cc
            ConsoleFunction( getSimTime, S32, 1, 1, "getSimTime() - Time since game started.")
            {
               return Sim::getCurrentTime();
            }
        

First, I corrected the above consolefunction declaration for this example. In the engine, the usage parameter was used instead to give information about the function's purpose. Really, we'd want it to tell us what to do if we messed up the args list. It's pretty clear that this creates a function in the console named 'getSimtTime', which returns a signed 32-bit value, and takes 1 argument. Interestingly, internally, we call the static method 'Sim::getCurrentTime()'. Remember, Console functions can internally call any function in the scope of the macros declaration or any static method.

Additional Engine Interfacing Functions

In addition to the major functions we've discussed so far, there are some other important, though less used, functions you should know about. I will cover them briefly, and rely on your ability to examine the source code for usage examples. Note: I will use some of these in the tutorials that come with this guide also.

Con::getLocalVariable()

This function allows you to get the contents of a local variable in the console from within the engine. Note: The value is returned as a char string.

            const char *Con::getLocalVariable(const char* name);
            
  • name- This is the name of the local variable in the console.

Con::setLocalVariable()

This function allows you to set the contents of a local variable in the console from within the engine. Note: all values passed as char strings to the console. The console automatically converts this information as necessary.

            Con::setLocalVariable(const char *name, const char *value);
            
  • name- This is the name of the local variable in the console.
  • value- This is the new value to place in the console variable.

Console Printing Functions

  • Con::printf()
  • Con::warnf()
  • Con::errorf()

These functions provide the ability to print various levels of information into the console (and subsequently the log if logging is enabled).

                Con::printf(const char *_format, ...);
            
  • _format- A standard C printf formatting string.
  • ...- Any number of arguments associated with the formatting string contents.
                Con::warnf(ConsoleLogEntry::Type type, const char *_format, ...);
            
  • type- A category indicator, where the category can be:

    • General
    • Assert
    • Script
    • GUI
    • Network
  • format- A standard C printf formatting string.
  • ...- Any number of arguments associated with the formatting string contents.
                Con::errorf(ConsoleLogEntry::Type type, const char *_format, ...);
            
  • type- A category indicator, where the category can be:

    • General
    • Assert
    • Script
    • GUI
    • Network
  • format- A standard C printf formatting string.
  • ...- Any number of arguments associated with the formatting string contents.