650 likes | 676 Views
Learn about advantages of scripting for prototyping, debugging, customization, and more. Understand necessary features, syntax, variables, data types, and advanced functionalities like tagged strings and vectors. Discover Torque features, basic data types, string operations, arrays, and essential scripting operations like if-then-else and loops. Master functions, recursion, and usage examples in game development with Torque scripting.
E N D
Torque Script CIS 487/587 Bruce R. Maxim UM-Dearborn
Scripting Advantages • Useful for prototyping without recompilation • Makes debugging easier • Allows for game customization and tweaking • Allows players to make their own total-mod based on an existing game structure • Any functional component that is not time critical can be written using scripting language rather than a compiled language
Necessary Features • Basic programming language features (variables, data types, control structures) • Access to engine-structures (rendering, audio, physics, AI, I/O, object management) • Familiar and consistent syntax • Object functionality (encapsulation, inheritance, polymorphism) • Dynamic scoping and memory management • Compilation of virtual machine “p-code”
Using the Console • Single script statements can typed in the console command line or an entire script can loaded from a file • The console window is opened by typing “~” once a Torque application is running • Ctrl-V allows pasting from clipboard into command line • The echo command can be used • echo(“Torque rocks”); • echo(1+1);
Syntax • Torque is type insensitive • “1.2” == 1.2 • Torque is case insensitive • $a == $A • The “;” is used as a statement terminator • $a = “a text string”;
Torque Features • Contains C++ arithmetic operators plus a few extra string operators • Control structures and function definition are similar to C++ • Provides engine object inheritance and polymorphism • Supports use of Namespaces • On-demand loading and unloading of functions • Compiles and executes pcode
Variables • Variables do not need explicit declaration • Variable names begin with letter and contain any number of letters, digits, or “_” • Local and global variables • %local_var = value; • $global_var = value;
Basic Data Types • Numbers: • 123 (Integer) • 1.234 (floating point) • 1234e-3 (scientific notation) • 0xc001 (hexadecimal) • Strings • "abcd" (string) • 'abcd' (tagged string) • Booleans • true (1) • false (0)
Tagged Strings • Tagged strings have special numeric data associated with them • Tagged strings are used for sending strings across networks more efficiently • Tagged strings behave like normal strings • Tagged values can only be printed by detagging them after transmission • echo(“detagging example “ detag(‘$b’));
String Operations • Syntax • “string 1” op “string “ • Operators • @ (concatenates two strings) • TAB (concatenation with tab) • SPC (concatenation with space) • NL (newline between strings)
String Escape Sequences \n (newline) \r (carriage return) \t (tab) \c0...\c9 (colorize subsequent text – predefined color) \cr (reset to default color) \cp (push current color on color stack) \co (pop color from color stack) \xhh (two digit hex value ASCII code) \\ (backslash)
Arrays • Example • $MyArray[n] (Single-dimension) • $MyMultiArray[m,n] (Multi-dimension) • $MyMultiArray[m_n] (Multi-dimension) • Refernces • $a != $a[0] • $a0 == $a[0] • $b[0,0] == $b0_0
Vectors • Allow group of numeric values to be manipulated in sets of 3 or 4 • Stored as strings, but interpreted as vectors • Torque provides a set of script operators for vectors • Example • “1.0 1.0 1.0 1.0” (4 element vector)
Operators • Boolean and arithmetic operators similar to those found in C++ • The ++ and --operators are used only as postfix operators • The string comparison operators are • $= (test for string equality) • !$= (test for string inequality)
if-then-else • Brackets optional for single line statements • Nested if-then-else statements are allowed • Example if(expression) { statements; } else { alternate statements; }
switch(expression) { case value0: statements; break; case value1: statements; break; default: statements; }; Switch only works for numeric expressions Use switch$ The breaks are not really needed since Torque only executes one case switch
for • Examples for(expression0; expression1; expression2) { statement(s); } for(%count = 0; %count < 5; %count++) { echo(%count); }
while • Examples while(expression) { statements; } %count = 0; while (%count < 5) { echo(%count); %count++; }
Functions - 1 • Functions cannot have multiple prototypes (always keeps the most recently defined) • Torque does support the concept of packages to work around the duplicate name problem • Functions can be recursive • If functions are passed fewer actual parameters than the number the defined, the missing parameters will be assigned null string values
// function declaration function echoRepeat (%echoString, %repeatCount) { for (%count = 0; %count < %repeatCount; %count++) { echo(%echoString); } } // function call from console or script echoRepeat("hello!", 5); Functions - 2
Functions - 3 // recursive function function echoRepeat (%echoString, %repeatCount) { if (%repeatCount > 0) { echo(%echoString); echoRepeat(%echoString, %repeatCount--); } } // calling recursive function echoRepeat("hello!", 5);
Objects - 1 • Every game item is considered an object • Even C++ objects are accessible via scripts • Every game object is assigned a numeric ID known as a handle • An objects may be assigned a name • Torque object data members are called as fields and functional methods are called commands
Objects - 2 %var = new ObjectType(Name : CopySource, arg0, ..., argn) { <datablock = DatablockIdentifier;> [existing_field0 = InitialValue0;] ... [existing_fieldM = InitialValueM;] [dynamic_field0 = InitialValue0;] ... [dynamic_fieldN = InitialValueN;] };
Object - 3 • %var- variable to hold object's handle • ObjectType- Is any class declared in the engine or in script that has been derived from SimObject or a subclass of SimObject. • Name (optional)- object's name. • CopySource (optional)- The name of an object which is previously defined somewhere in script. Note: If CopySource is of a different ObjectType than the object being created, only CopySource's dynamic fields will be copied.
Object - 4 • arg0, ..., argn (optional)- comma separated list of arguments to the class constructor. • datablock- Many objects (those derived from GameBase, or children of GameBase) require datablocks to initialize specific attributes of the new object.
Object - 5 • existing_fieldM- In addition to initializing values with a datablock, you may also initialize existing class members (fields) here. Note: In order to modify a member of a C++-defined class, the member must be exposed to the Console. • dynamic_fieldN- Lastly, you may create new fields (which will exist only in Script) for your new object. These will show up as dynamic fields in the World Editor Inspector.
Object - 6 // create a SimObject w/o modifying any fields $example_object = new SimObject(); // create a SimObject w/ dynamic fields $example_object = new SimObject() { a_new_field = "Hello world!"; };
Object - 7 // create a StaticShape using a datablock datablock StaticShapeData(MyFirstDataBlock) { shapeFile = "~/data/shapes/player/player.dts"; junkvar = "helloworld"; }; new StaticShape() { dataBlock = "MyFirstDataBlock"; position = "0.0 0.0 0.0"; rotation = "1 0 0 0"; scale = "1 1 1"; };
Using Objects // assuming the existence of a player called myGuy // you could type the following in from the Console $player_name = "myGuy"; $player_id = $player_name.getID(); echo($player_name.position); echo($player_name.getID()); echo(myGuy.getid());
Dynamic Fields - 1 • Are associated with specific instances of an object type • There are allocated as referenced • Assigning a value to field that does not exist creates a new field • Trying to read a field that does not exist does not create a new field and a null string is returned
Dynamic Fields - 2 // new_var will not be created because we are only // 'reading' it echo($player_id.new_var); // new_var2 will be created and initialized to "Hello” $player_id.new_var2 = "Hello"; echo($player_id.new_var2);
Console Functions - 1 function Classname::func_name(%this,[arg0],...,[argn]) { statements; return val; // optional } The syntax breaks down as follows: • function- Is a keyword telling TorqueScript we are defining a new function. • ClassName::- Is the class type this function is supposed to work with. • func_name- Is the name of the function we are creating.
Console Functions - 2 • %this- Is a variable that will contain the handle of the 'calling object'. • ...- Is any number of additional arguments. function Player::hi(%this) { echo("Player Hello ", %this); Parent::hi(%this); } // assuming Player handle is 1000 we can call 1000.hi();
Console Functions - 3 • We can force Torque to call a specific instance using NetObject::hi(1000); • New console function definitions override previous definitions with same name • Console functions (scripts and packages) can be loaded using the exec command exec(test_scripts/package_test.cs);
Packages - 1 • Provide dynamic function polymorphism • Function definitions from active packages override current function definitions • Functions can appear in multiple packages • Functions can be packaged datablocks can not be packaged
Packages - 2 function demo() { echo("Demo definition 0"); } package DemoPackage1 { function demo() { echo("Demo definition 1"); } }; package DemoPackage2 { function demo() { echo("Demo definition 2"); } };
Packages - 3 • To make use of specific functions demo(); // original version ActivatePackage(DemoPackage1); demo(); // package 1 version ActivatePackage(DemoPackage2); demo(); // package 2 version DeactivatePackage(DemoPackage2); demo(); // package 1 version DeactivatePackage(DemoPackage1); demo(); // original version
Engine-Console Interface - 1 • C++ Variable • variable not associated with any class. • C++ Function • function is not associated with any class. • Member • A variable defined in a C++ class. • Method • A routine defined and declared in a C++ class.
Engine-Console Interface - 2 • 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++.
Engine-Console Interface - 3 • 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.
Engine-Console Interface - 4 • 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.
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.
addField( ) void ConsoleObject::addField (const char*in_pFieldname, // console var name const U32 in_fieldType, // from consoleTypes.h const dsize_t in_fieldOffset, // calc by Offset() const char* in_pFieldDocs) // text field description void ConsoleObject::addField (const char* in_pFieldname, const U32 in_fieldType, const dsize_t in_fieldOffset, const U32 in_elementCount, // # elements at offset EnumTable *in_table, // table of enum values // and strings const char* in_pFieldDocs)
addFieldV( ) • Specialized version does not handle enums • Supports use of validator functions void ConsoleObject::addFieldV (const char* in_pFieldname, const U32 in_fieldType, const dsize_t in_fieldOffset, TypeValidator *v) // pointer to TypeValidator // class
Macros -1 • addField() variants used to give a console field the same name as class member #define addNamedField (fieldName,type,className) \ addField(#fieldName, type, Offset(fieldName,className)) #define addNamedFieldV (fieldName,type,className, validator) \ addFieldV(#fieldName, type, Offset(fieldName,className), validator)
Macros - 2 • Offset macro calculate position of variable in bytes from beginning of class in memory Offset(VariableName, // C++ class member name to // expose to console ClassName) // name of C++ class
removeField( ) • Lets you unlink a member-field pairing • Can be used to hide information form player (e.g. not allow position calls for Terrain data) bool ConsoleObject::removeField (const char* in_pFieldname) // in_pFieldname is string specifying string to // be removed
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, // string specifying global // console variable S32 t, // variable type from // consoleTypes.h void *dp); // point to C++ global // variable or static // member
ConsoleMethod - 1 • This is a macro that allows you to create a new Console Method from C++. • Used to replace 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)
ConsoleMethod - 2 ConsoleMethod (className, // class owning C++ method scriptname, // method name inside console returnType, // method return type minArgs, // mini # method arguments // method name is 1st and handle // is 2nd maxArgs, // max # arguments, 0 means any // number of args can be passed usage) // help statement used is wrong // number of args are passed // in call