The .GMF File
Now that you understand .txt files, it's time to tackle the heart of the component: the .gmf file. The .gmf file contains the 3D model used for the component, its attachment points, and a few game-related things. .gmf files that are compatible with RA2 can only be made with 3D Studio Max 4 or 5, which costs more money than the average person can afford just for making a few custom components. However, there is another way to make custom 3D models using only Notepad/Wordpad and a free program called Dummy's GMF Compiler, which you can get from here. This is much harder than .txt file editing, but much more powerful.
So how do you make custom .gmf's without 3D Studio Max? Well, you don't actually make them, but you can copy existing .gmf files and edit them in Notepad to make a new component. So how do you edit them? If you try to open a .gmf file in Notepad, it will just be unrecognizable, garbled characters. And if you try to save it, the file will become corrupted and any component that uses it will crash the game. That's where Dummy's GMF Compiler comes in. This tool will let you decompile .gmf files into recognizable words and numbers, then compile them back into the compressed form the game uses. When you run Dummy's GMF Compiler, it should look like this:
Before you can edit .gmf files, you need to decompile them, so check 'Decompile' at the bottom before doing anything else. Then click the folder by 'Source' at the top to select which .gmf file you want to edit. For this tutorial, we will be using the Ram Plate .gmf because of its simplicity, which is located in C:\Program Files\Infogrames\Robot Arena 2\Components\ram_plate\ramplate1.gmf. Enter this as the source .gmf. The destination can be anywhere. I usually have the destination be in C:\Program Files\Infogrames\GMFCompiler048 so the compiler is always close by, but it really doesn't matter. Now click 'Decompile' and you should find a readable .gmf file for the Ram Plate wherever you set your destination.
You might be a little overwhelmed when you first see what all is required just to make a simple ram plate. The file may be readable now, but it is still far from understandable. However, half of that stuff you will never need to bother with. As for the other half, here's a quick explanation of what it is. Anything I don't mention you don't need to know about.
- Materials: This section of the .gmf near the beginning determines how the component is skinned. A screenshot is shown below, with red arrows drawn by the important lines. The ones without red arrows you don't need to worry about.
- MATERIAL_COUNT tells the computer how many different materials (or skins) there are in the file, in this case 1. You only need to change this number if you add or remove any materials, which you won't at this stage, so you can ignore it for now.
- MATERIAL_CLASS is either Standard or Multi/Sub-Object. Multi/Sub-Object is used for applying multiple skins to the same object.
- MATERIAL_REF_NO assigns a number to this material that is used later in the file to tell which part of the component gets which skin applied to it. With a single-part, single-skin component like the ram plate, you don't need to worry about this.
- MATERIAL_AMBIENT, MATERIAL_DIFFUSE, and MATERIAL_SPECULAR tell what color the component is if it doesn't have a texture. The colors are in hexadecimal code (0xFFFFFF=white, 0x000000=black, 0xFF0000=red, and so on). This color only applies if there is no texture, so you would need to delete the TEXTURE in the ram plate .gmf in order to see it.
- MATERIAL_SHINE and MATERIAL_SHINESTRENGTH determine how shiny and reflective this component is. 1 is super shiny, 0 is absolutely dull.
- MATERIAL_TRANSPARENCY determines how transparent this component is. There will be no number here by default but you can add one if you want. 1 is invisible, 0 is completely solid.
- TEXTURE_COUNT tells the computer how many different textures are in this material. You will very rarely need to deal with more than 1, so you can usually ignore this.
- BITMAP determines what .bmp or .tga file to apply to this component. These skins are stored in the 'maps' folder in the folder containing the .gmf.
- MAP_DIFFUSE determines what kind of map this is. It can be DIFFUSE (default), REFLECTION (shiny), OPACITY (semitransparent; black=transparent white=opaque), or SELFILLUM (self-illuminated).
- MAP_TYPE determines how the texture is applied. It is usually Screen, but can also be Additive (appears brighter) and must be Spherical or Cylindrical for reflection maps. Note that Dummy's GMF Compiler cannot compile anything but DIFFUSE Screen skins, but if you're clever there is a way to modify the source code so it can.
- BITMAP_FILTER determines how the texture is stretched or resized on the component. Pyramidal is basic and results in choppy pixels, while SAT blurs the edges for a smoother look.
- Attachment Points/object list: Attachment points are the green boxes where the component can be attached to things. They can go anywhere in the .gmf, so they can be hard to find sometimes. In the case of the ram plate, the attachment point is right after the materials. You will need to know what every line does if you are going to mess with them. The red lines in this picture are just to simplify things a bit: you can round any number in scientific notation with E-03 or smaller to 0 (which I have shown), and you can delete all that junk I circled. It's useless and I don't know how it gets in there.
- OBJECT_COUNT tells the computer how many objects there are in this .gmf. It always comes right after the materials, not necessarily by an attachment point. It is important that you get this number right - if it is too big, the file won't compile; if it is too small, it will crash the game. Attachment points, mesh, hinges, and RBCollections count as objects.
- NODE_NAME is just the name of the attachment point. It always goes Point01, Point02, etc. Note that there are two of them - you need to change both if you change one!
- NODE_TM contains all the TM_ROWs (Transformation Matrix Rows) for the attachment points. TM_ROWs 0-2 determine what direction the attachment point faces, and TM_ROW3 is its x,y,z coordinates. I still don't understand how TM_ROWs 0-2 work, so when I want to change which way a connection point faces, I just copy them from another connection point. I do know, however, that multiplying TM_ROW1 and TM_ROW2 by -1 makes the point face in the exact opposite direction. I also know that the TM_ROWs for facing directly x, directly y, and directly z are: 100|010|001, 100|001|0-10, and 010|001|100.
- ID is just the number in the NODE_NAME. The point with ID = 1 is the one that will be selected by default.
- Attach = determines how this component can be attached. There are three types: Base, which includes the chassis, Axle, which includes motors and wheels, and Generic, which includes just about everything. They will be followed with _M or _F. M means components can be attached to this point, and F means this component can be attached to other stuff with this point. You can have as many of these values as you want.
- Mesh: This section of the .gmf contains all the meat: the actual 3D model. The mesh is a huge part of the file, but you really only need to bother with with the very beginning of it.
- NODE_NAME is the name of this object. It will be used later in the RBCollection and possibly in the .txt file. Note that once again there are two of them. There are also some TM_ROWs here to determine what direction the mesh faces, but these ones get overridden by the ones in the RBCollection so they don't really matter.
- MESH_NUMVERTEX and MESH_NUMFACES tell the computer how many vertexes and faces are in this mesh. You will most likely be leaving these numbers alone, but it's good to know what they do because they're important. I would NOT recommend attempting to add or remove vertexes or faces, because then you would have to mess around with the normals and TVERTs, which even I haven't figured out.
- MESH_VERTEX is one of the 'corners' of the object. The layout is simple enough, the MESH_VERTEX is just followed by 4 numbers, the first of which is its number and the others are its x,y,z coordinates.
- MESH_FACE is one of the 'sides' of the object, the stuff that connects the vertexes. You won't need to mess with the faces unless you completely change the shape of the object (f.e., turn a rectangle like the ram plate into a boomerang shape). Each MESH_FACE is followed by 3 numbers, which are the numbers of the vertexes that they connect. So MESH_FACE 0 is a triangle connecting MESH_VERTEXes 0, 2, and 3. To reverse the direction a MESH_FACE faces, simply invert A and C. So MESH_FACE 0 would become A: 3, B: 2, and C: 0. MESH_MTLID is for objects with Multi/Sub-Object skins to determine which faces get which texture.
- BACKFACE_CULL (not shown) is located at the very end of the mesh. It determines whether the MESH_FACEs are single or double-sided. 0 means double-sided, 1 means single-sided.
- MATERIAL_REF (not shown) is located at the very end along with BACKFACE_CULL. It determines which MATERIAL_REF_NO to use to skin the mesh.
- RBCollections: This section is found at the very end of the .gmf and wraps everything up.
- NUM_DISABLED_PAIRS tells how many DIS_COLLISION_PAIRs there are. DIS_COLLISION_PAIRs are used in multi-part objects to tell the game to ignore when the object collides with itself.
- COUNT tells the computer how many objects (or RIGIDBODYs) are in the RBCollection. Once again, there are two of them which must be the same.
- NODE_NAME tells the computer which mesh this object uses. It must be the same NODE_NAME used in the mesh. And guess what? There's two of them again!
- MASS determines how heavy this component is. This will be the default mass used if no mass is specified in the .txt file.
- ELASTICITY determines how elastic this component is. A high number means it is very elastic (will bounce when it hits something) and a low number means it is very rigid (will just stop when it hits something).
- FRICTION determines the friction of this component. A high number means it will slow down and stop very quickly when it moves, and a low number means it will tend to keep sliding.
- UNYIELDING determines whether or not this object can move. 0 means movable, 1 means it won't budge no matter what.
- SIMULATION_GEOMETRY is a number that depends on the component's collision. If the component has separate 'collision mesh' (which the ram plate doesn't) SIMULATION_GEOMETRY must be set to 3. If not, then it will be 0 or 2. You will only need to change it if you add or remove stuff.
- GEOMETRY_PROXY_NAME is the name of the collision mesh of this component. If there is none, it is set to (null). This is the name that must be used for the 'passthru' parameter in the .txt file, or the NODE_NAME if there is no geometry proxy.
- USE_DISPLAY_PROXY and DISPLAY_PROXY_NAME deal with display proxies, which is just like a geometry proxy except the other way around. You probably won't have to deal with this.
- DISABLE_COLLISIONS determines whether or not this object can collide. 0 means it does, 1 means it passes through stuff.
- NODE_TM determines which way the mesh faces and where it is relative to 0,0,0. The TM_ROWs here are just like the ones used for connection points.