MDL language documentation

From FreeAllegiance Wiki
Jump to navigationJump to search

Allegiance engine uses its own files format. The main format is the MDL format which can be either plain text (mdl text format) or compiled (mdl format). Both formats are supported by the client (allegiance.exe) and they use the same extension (.mdl). Thus, visual inspection of the file is required to determine the used format.

The mdl text format uses a form of definition language to define objects.

Sample (sample1.mdl):

[code]use "effect";

frame = ModifiableNumber(1);

object = ImportXFile("artifact.x", frame); [/code]

The sample uses an external .x file but the mdl language is complete enough to define meshes without using another file format (see samples/bgrnd03.mdl for a mdl only textured object) The mdl language scope goes beyond 3D models. It's used to defined most aspects of the game including 3D, sounds and UI panels. The mdl language reference is currently in a first-alpha version. It should be a joint community effort; if you discover any ambiguities, or downright faults, please post on the boards or PM Ksero to improve the document.

On the MDL textual language

Syntax

As mentioned, MDL is a declarative, case-sensitive language. Most statements take the following form:

[code]identifier = function(parameter1, parameter2);[/code]

  • MDL is a loosely typed language. You don’t need to specify the types of variables.
  • A semi-colon should end every statement, which can span multiple text lines.
  • Integer constants can be written in two ways: normally (11) or as hex (0x0B).
  • String constants are written like: “foostring”
  • Boolean constants have two possible values, true and false.
  • Comments are preceded by //.

There is a single built-in operator, the bitwise or operator |. For example, 0x01 | 0x02 evaluates to 0x03.


Info.png
Note Even though the native Number-type is a floating-point number, it is converted (cast) to a 32-bit integer when performing the bitwise operation.

Namespaces

Namespaces are a central concept in MDL. Every MDL file is a namespace, whether textual or binary. To be able to use variables, constants and functions from another file or namespace, simply state

[code]use "filename"[/code]

where filename does not have the .mdl-extension. All use-declarations must be located at the beginning of the MDL-file. Importing a namespace like this naturally imports any other namespace that is use-d in the imported namespace. The Allegiance engine also exports about 650 functions and constants into different namespaces. These are listed on the worksheet "From C++ exported to MDL", giving the parameters and a short note on the purpose / syntax. These exports can roughly be sorted into

  • Object creation functions ("constructors").

Example:

[code]ButtonPane(Image background, Number FacesFlag, bool toggles)[/code]

creates and returns a ButtonPane object.

  • Global constants like pi, white, black and key constants like CommandVoteYes, CommandDropChaff
  • Specific windows (like the inventory, or the team window (F6) exporting data to be shown to their specific namespace.

In return, they expect certain controls, buttons to be specified in the MDL-file, so they can be imported back to the engine.

Some exports are seemingly only used in binary .mdl 3d models, e.g. LightsGeo and FrameData. Note that the exported namespaces are organized in a somewhat unintuitive hierarchy of imports / use-statements.

Structs

Structs are used once in the artwork shipped with Allegiance, in quickchatheader.mdl. They are also an exception to the loose typing. In a struct, you need to define the types that it contains. To be able to use the struct in c++-code, use the mdlc utility to generate an appropriate header. You can also use the keyword “extends” to use inheritance (also used in the same file).

The syntax is:

[code]Struct structname extends parentstruct { identifier1 : type1; identifier2 : type2; list3 : [type3]; };[/code]

Defining a struct allows you to use the structname as a constructor / function that creates and returns an object.

Following the above example:

[code]variableidentifier = structname(type1object, type2object, [type3obj1, type3obj2, type3obj3])[/code]

Lists

Some functions can take a variable number of arguments. A window can have several controls, a QuickChatMenu can have several entries. In this case, a list is used as an argument.

Lists in general take the form

[code]Identifier = [item1, item2, item3];[/code]

Note: In a function-call, an empty list evaluates to “no parameter”. Therefore, it can be inserted as an argument, without affecting the call. For example:

[code]Add(5,3,[],[])[/code]

is equivalent to

[code]Add(5,3)[/code]

Pairs

In lists and variable definitions, each expression can actually contain several expressions (which may be of different types), effectively becoming a kind of unnamed struct. This is called a pair, even though the pair may contain more that two expressions. Assigning a pair to an identifier / variable looks like:

[code]Identifier = (item1, item2, item3);[/code]

Using pairs in a list then becomes

[code]Identifier = [ (item11, item12), (item21, item22), (item31, item32)];[/code]

For example, at the end of dialog.mdl is a list of all the different in-flight dialogs and overlays. Each entry is:

[code](image, side, off point, on point, transition time, consoles modes, undetectable)[/code]

Example entries:

[code](ChatCompositionImage, SideBottom, Point( -170, -78), Point(-150, 148), .5, 65663, false), (PaneImage(InvestmentsPane, false, true), SideCenter, Point( -192, 2000), Point(-192, -240), .5, 512, false),[/code]

let ... in

The let-construct allows you to write a number of temporary definitions, and evaluate one expression in the context of these definitions. This allows for temporarily redefining an identifier for a certain expression and making a non-global assignment (perhaps to split up a long expression into several lines?). It is never used in the .mdl-files shipped with the game. The syntax is:

[code]Identifier = let <definitions> in <expression>;[/code]

Example:

[code]Identifier = let Foo = 5; Bar = 6; in Add(Foo,Bar);[/code]

This assigns the value 11 to the identifier "Identifier".

Tutorial – A simple, commented MDL-file

Listing of AutoDownloadDialog.mdl:

[code]use "effect"; // import effect namespace for widgets/controls use "font"; // import fonts use "gamepanes"; // import more Panes/widgets/controls use "autodownloaddialogdata"; //import data specific for this dialog

///////////////////////////////////////////////////////////////////////////// // // AutoDownload Dialog // /////////////////////////////////////////////////////////////////////////////

// // Guts //

AutoDownloadAbortButton = ButtonPane(ImportImage("btnautodownloadabortbmp", true), ButtonNormal, false); //Creates a button. Argument one is the button image, returned by ImportImage. Second is a flag about the behaviour of the button. Third is whether the button should have a state (toggle switch)

AutoDownloadCurrentFileStringPane = StringPane("", Color(1, 1, 1), Point(220, 13), JustifyRight, smallFont); // Creates an empty StringPane (in win32 “Label”). Imported by the engine, which sets the text properly AutoDownloadApproxMinutes = StringPane("", Color(1, 1, 1), Point(120, 13), JustifyLeft, smallFont); //Another empty StringPane.

AutoDownloadTopBarStringPane = StringPane("Retrieving File List", Color(1, 1, 1), Point(150, 13), JustifyLeft, smallFont); AutoDownloadMidBarStringPane = StringPane("Analyzing Local Version", Color(1, 1, 1), Point(150, 13), JustifyLeft, smallFont); AutoDownloadLowBarStringPane = StringPane("Downloading Updated Files", Color(1, 1, 1), Point(150, 13), JustifyLeft, smallFont);


FileListGaugePane = GaugePane(

   ImportImage("autodownloadgaugebmp", false),
   FileListPercentDone,
   Color(1, 0, 0),
   Color(0, 1, 0)

);

VerifyGaugePane = GaugePane(

   ImportImage("autodownloadgaugebmp", false),
   VerifyPercentDone,
   Color(1, 0, 0),
   Color(0, 1, 0)

);

DownloadGaugePane = GaugePane(

   ImportImage("autodownloadgaugebmp", false),
   DownloadPercentDone,
   Color(1, 0, 0),
   Color(0, 1, 0)

); //GaugePane is a progress-bar. First argument is the image, as it should appear when it’s 100% done. The second argument, the PercentDone-variables are the only exports to “autodownloaddialogdata”. They will be updated by the engine as the update progresses. Third is the “Flash”-color, which I suppose is used as a “marker”. Lastly we have the “empty”-color,

// // AutoDownload Dialog //

AutoDownloadDialog =

       (
           ImagePane(
               ImportImage("autodownloaddialogbmp", false),
               [
                   (AutoDownloadCurrentFileStringPane,    Point(195,185)),
                   (AutoDownloadApproxMinutes,            Point(100,185)),
                   (FileListGaugePane,                    Point(91,68)),
                   (VerifyGaugePane,                      Point(91,113)),
                   (DownloadGaugePane,                    Point(91,158)),
                   (AutoDownloadAbortButton,              Point(210,200)),
                   (AutoDownloadTopBarStringPane,         Point(100,51)),
                   (AutoDownloadMidBarStringPane,         Point(100,96)),
                   (AutoDownloadLowBarStringPane,         Point(100,140))
               ]
           )
       );[/code]

This ImagePane-object is imported back to the engine.

Tools

MDLC – the mdl compiler

Options:

[code]mdlc -optimize input output[/code]

used with 3d-models in .mdl-format. Removes diffuse/specular/emissive color information and consolidates texture information. Precalculates certain transforms etc... in one word: optimizes

input the file (without .mdl ending) to optimize

output destination filename, without .mdl ending

[code]mdlc -compressanim xframes yframes input output[/code]

applies a form of RLE (Run Length Encoding) to an animation (presumably a .bmp with the frames stored side-by-side in rows and columns). I haven't seen it used...

xframes the number of animation frames in one row yframes the number of animation frames in one column input the filename of the .bmp to compress output the destination filename. .mdl ending is automatically added.

[code]mdlc -convert input output[/code]

converts a .bmp to bmp.mdl

input filename of source bitmap output destination filename (without .mdl ending)

[code]mdlc -info input[/code]

prints some information about the model (how many triangles each LOD has)

input the name of a .mdl-file (without .mdl-ending) describing a 3d-model with level-of-detail information

[code]mdlc -genheader input output[/code]

Generates c++ code for handling any structs defined in a .mdl-file.

input the .mdl (without .mdl-ending) that contains struct definitions. output filename for writing the code to

[code]mdlc input output.mdl[/code]

converts ASCII .mdl to binary .mdl

input source filename without .mdl ending output destination filename with .mdl ending

History

v1.3 – 5/25/2005 – Ksero – further updates (thanks Cortex!)

v1.2 – 4/17/2005 – Ksero – branched off of KGJV’s draft.

v1.0 - 3/21/2004 - KGJV/Kirth Gersen - rough draft / preliminary work

Stubs are small "placeholder" articles that generally need to either be expanded upon, or cleaned up. Anything you see below needs your help to help make the wiki a better place!