Changes

Jump to navigation Jump to search
145 bytes added ,  15:55, 5 June 2017
update formatting, add cat
Line 1: Line 1: −
TrackMania actually has an internal, custom scripting language. It appears to be used mostly for GUI purposes. So far, only two scripts have been found, in Game.pak.
+
TrackMania actually has an internal, custom '''scripting language'''. It appears to be used mostly for GUI purposes. So far, only two scripts have been found, in {{c|Game.pak}}.
   −
Scripts are stored in binary form in [[GBX|.gbx]] files of [[Class ID's|class]] CMwCmdBlockMain (0x01067000). They are quite easy to parse and decompile since they are not compiled to opcodes: instead, the AST (Abstract Syntax Tree) is serialized, preserving all the high-level programmatic structures like if, while... And not just that, even the original variable names are available in plain text.
+
Scripts are stored in binary form in [[GBX|.gbx]] files of [[Class IDs|class]] CMwCmdBlockMain (0x01067000). They are quite easy to parse and decompile since they are not compiled to opcodes: instead, the AST (Abstract Syntax Tree) is serialized, preserving all the high-level programmatic structures like if, while... And not just that, even the original variable names are available in plain text.
    
If you haven't yet, read about the general [[GBX|.gbx file format]] first. Then you will have a much easier time understanding the rest of this article.
 
If you haven't yet, read about the general [[GBX|.gbx file format]] first. Then you will have a much easier time understanding the rest of this article.
   −
==Features==
+
== Features ==
 +
 
 
Every CMwCmdBlockMain script operates in the context of a certain object instance (which we'll call the global instance), the type of which is stored in the script. It can use the fields and methods of this object to access and create other objects. However, there is no way to instantiate a class manually; creating objects has to happen through one of the provided methods.
 
Every CMwCmdBlockMain script operates in the context of a certain object instance (which we'll call the global instance), the type of which is stored in the script. It can use the fields and methods of this object to access and create other objects. However, there is no way to instantiate a class manually; creating objects has to happen through one of the provided methods.
   −
The language itself is quite limited. It has basic programming constructs like if/while/for, variables and function calls. It supports working with integers, floating point numbers, vectors, matrices and strings. Math operators are however very limited (e.g. no modulo, let alone things like sin or exp), and string functions are almost nonexistent. Also, for loops can only work with steps of 1.
+
The language itself is quite limited. It has basic programming constructs like {{c|if}}/{{c|while}}/{{c|for}}, variables and function calls. It supports working with integers, floating point numbers, vectors, matrices and strings. Math operators are however very limited (e.g. no modulo, let alone things like {{c|sin}} or {{c|exp}}), and string functions are almost nonexistent. Also, {{c|for}} loops can only work with steps of 1.
   −
==Terminology==
+
== Terminology ==
 
TrackMania uses slightly weird naming conventions in its scripting system.
 
TrackMania uses slightly weird naming conventions in its scripting system.
 
* Instead of "setting" a variable, the variable is "affected".
 
* Instead of "setting" a variable, the variable is "affected".
Line 19: Line 20:  
* For some class names, the developers couldn't decide between English or French, so you'll see "CMwCmdExpNum" (clearly English since "number" is "nombre" in French), but also "CMwCmdExpInf" where Inf stands for "inférieur", French for "less".
 
* For some class names, the developers couldn't decide between English or French, so you'll see "CMwCmdExpNum" (clearly English since "number" is "nombre" in French), but also "CMwCmdExpInf" where Inf stands for "inférieur", French for "less".
   −
==Member ID's==
+
== Member IDs ==
The scripting language often makes use of member ID's. These are quite similar to [[Class ID's|chunk ID's]]: they are a 32-bit integer that indicates an engine, a class, and a part of that class. The difference is that the last three digits do not refer to a chunk but to a class member, which can be a field or a method.
+
The scripting language often makes use of member IDs. These are quite similar to [[Class IDs|chunk IDs]]: they are a 32-bit unsigned integer that indicates an engine, a class, and a part of that class. The difference is that the last three digits do not refer to a chunk but to a class member, which can be a field or a method.
   −
The entire tree of engines and their classes has been extracted and is available [[Class ID's|on this wiki]]. All of the class members have *also* been extracted, however this results in a huge file which is too large for a wiki article. Instead, you can download it [http://www.mediafire.com/?vcf8hjk70fambf1 here].
+
The entire tree of engines and their classes has been extracted and is available [[Class IDs|on this wiki]]. All of the class members have *also* been extracted, however this results in a huge file which is too large for a wiki article. Instead, you can download it [http://www.mediafire.com/?vcf8hjk70fambf1 here].{{deadlink}}
    
===Enumerations===
 
===Enumerations===
Some class fields store an enumeration value. There is no separate definition of these enumerations; the possible enumeration values are stored together with the field information. Enumeration values are 0-based and are all named; see the class member download above.
+
Some class fields store an enumeration value. There is no separate definition of these enumerations; the possible enumeration values are stored together with the field information. Enumeration values are 0-based and are all named; see the class members download above.
    
==Common structures==
 
==Common structures==
Line 63: Line 64:     
===CMwCmdStack===
 
===CMwCmdStack===
Specifies an access path - a sequential series of fields, numerical array indices, and textual array indices. An important detail to note is that the access path is stored ''backwards''. So for obj.Field1[1].Field2["boo"], the stack would contain ("boo", <Field2 member ID>, 1, <Field1 member ID>).
+
Specifies an access path: a sequential series of fields, numerical array indices, and textual array indices. An important detail to note is that the access path is stored ''backwards''. So for {{c|obj.Field1[1].Field2["boo"]}}, the stack would contain {{c|("boo", <Field2 member ID>, 1, <Field1 member ID>}}).
 
* int32 numElems
 
* int32 numElems
 
* int32 types[numElems]
 
* int32 types[numElems]
* for(i = 0..numElems - 1)
+
* for (i = 0 .. numElems - 1)
 
** if types[i] == 0:
 
** if types[i] == 0:
 
*** int32 memberID
 
*** int32 memberID
Line 832: Line 833:     
===CMwCmdFor (01035000)===
 
===CMwCmdFor (01035000)===
A (very simple) for loop. Loops an iterator variable from a start value up to and including an end value (the end value can be higher or lower than the start value). Only increments (or decrements) of 1 are supported.
+
A (very simple) {{c|for}} loop. Loops an iterator variable from a start value up to and including an end value (the end value can be higher or lower than the start value). Only increments (or decrements) of 1 are supported.
    
'''Chunk000'''
 
'''Chunk000'''
Line 841: Line 842:     
===CMwCmdIf (01036000)===
 
===CMwCmdIf (01036000)===
A regular if/then/else construct.
+
A regular {{c|if/then/else}} construct.
    
'''Chunk000'''
 
'''Chunk000'''
Line 902: Line 903:     
===CMwCmdWhile (01037000)===
 
===CMwCmdWhile (01037000)===
A regular while() loop. Keeps running the body block until the condition becomes false.
+
A regular {{c|while}} loop. Keeps running the body block until the condition becomes false.
    
'''Chunk000'''
 
'''Chunk000'''
Line 909: Line 910:     
==Tools==
 
==Tools==
* [http://forum.mania-creative.com/thread-2379.html TMPakTool] is an open source tool that can read scripts from .pak files and decompile them to readable source code.
+
* [http://forum.mania-creative.com/thread-2379.html TMPakTool] is an open source tool that can read scripts from [[PAK|.pak]] files and decompile them to readable source code.{{deadlink}}
 +
 
 +
[[Category:Internals]]

Navigation menu