News |
Solo Strategy |
Multiplayer Strategy |
Solo Films
Myth Links |
Myth Mapmaking |
Site FAQ
Well, I decided to go ahead and put up everything I know about the mesh tag so far, instead of waiting until this evening to do so. This is a very long post, and contains all sorts of useful (useless?) information. I have formatted it to match reasonably well with the structure syntax for C. The information below has been a result of a small amount of compilation from WWW sites (to get a rough idea of how things are represented), a good deal of fiddling on my part, and some wild-ass-guesses tossed in along the way. Some of this information is not thoroughly tested; your mileage may vary. If anyone has any additions/subtractions by all means post a reply (please please please do not quote this entire post in your replies). Happy mesh-ing, Loshadh NOTES FOR THE C IMPARIED: This information is written so someone with C experience can easily import it into any coding they wish to perform. I have arranged things as best I can to allow those with little C knowledge to understand the information as well. To that end, I am adding this little bit at the beginning to help clear up what some of these things mean: In this documentation, each variable has been given a separate line. On this line will be the variable's type, the variable's name, and then some comments. An example is as follows: short meshHeight; // Number of rows in the mesh [1] The "short" is the number of bytes assigned to the variable. It also says what type of variable it is (in this case, a 16-bit, signed integer). The number of bytes allotted are as follows: short -- 2 bytes, signed integer long -- 4 bytes, signed integer uint16 -- 2 bytes, unsigned integer char -- 1 byte, unsigned integer There are some other variable types that have been defined by us. They are the ones that end in "TAG" (such as mediTAG, sounTAG, etc...). Treat these as 4 bytes, signed integers. The "meshHeight" is the name of the variable. Ignore the semicolons after the variable names... they are a part of C syntax. Sometimes a variable will have a number enclosed in brackets immediately after it (as in "unknown[191];"). The number enclosed in the brackets tells you how many times to repeat that line; in this case, it is saying that there are 191 repetitions of unknown variables present. This was done to save space, and because of C array conventions. Everything that follows the "//" on a line is a comment, describing a bit about the variable. If a number appears in brackets [] somewhere in a comment line, then there are more extensive notes at the end of the section. Hope this helps sufficiently. A greater understanding would be obtained by picking up a beginner's C book and reading it thoroughly. END NOTES FOR THE C IMPAIRED The structures for a mesh tag, so far. I have included a block diagram showing the various parts of the whole file. Note: The 63fx, 64fx, and 65fx files have an additional 64 bytes tacked onto the front of them. This is what makes a plugin a plugin. I have not included this 64 byte header in the information here. Block diagram for a tag of type "mesh" +-----------------------------------------------+ | | | meshHeader | | (1024 bytes) | | | | Handles things like how water will behave, | | ambient sounds, offsets to various portions | | of the tag, the size of the various tag | | portions, etc. | | | +-----------------------------------------------+ | | | gridData | | (size set in meshHeader) | | | | Handles the altitude of each mesh grid | | point, notes where water is and how it is | | to be handled, and sets the passability | | of each point in the mesh grid. Each | | meshGridData entry is 8 bytes in length. | | | +-----------------------------------------------+ | | | itemTypeData | | (size set in meshHeader) | | | | This section lists all the item types that | | are found on the level. These include | | units, sounds, scenery, and other objects | | (like wight pus packets and such). Each | | itemTypeData entry is 32 bytes in length. | | | +-----------------------------------------------+ | | | itemListData | | (size set in meshHeader) | | | | This section details the starting location | | (X, Y, and Z coordinates) and initial facing | | direction, and assigns a unique item ID | | number to each item. Each itemListData | | entry is 64 bytes long. | | | +-----------------------------------------------+ | | | actionListData |<---- I am here | (size set in meshHeader) | | | | This section handles the set of predefined | | actions that take place during a given | | level. More data on this as I discover it. | | | +-----------------------------------------------+ | | | Not sure what these next bits do... | | | | | Here is the mesh header typedef long mediTAG; typedef long meliTAG; typedef long sounTAG; typedef long stliTAG; typedef long .256TAG; typedef long partTAG; typedef long amsoTAG; typedef long meshTAG; typedef long windTAG; struct meshHeader { .256TAG 256TagID; // ID code for the .256 tag used for // this map. (thanks Thanquol!) mediTAG waterType1; // ID used to represent water short meshWidth; // Number of columns in the mesh [1] short meshHeight; // Number of rows in the mesh [1] long unknown1; // Usually zeros long meshLength; // Total length of the height mesh data long unknown2; // Usually zeros long meshOffset; // Offset from beginning of tag to the // start of the height mesh data long tagLength; // Total length of data from tag start long unknown3; // Usually zeros long itemTypeCount; // Number of item types used on map [2] long itemTypeOffset; // Offset from start of height mesh data long itemTypeLength; // Total length of the item type data long unknown4; // Usually zeros long itemCount; // Number of individual items used long itemOffset; // Offset from start of height mesh data long itemLength; // Total length of the item data long unknown5; // Usually zeros meliTAG lighting; // Lighting for the level mediTAG waterType2; // Second ID used to represent water short flags1; // Single/multiplayer flags [3] short flags2; // Types of games playable on map [4] partTAG particleEffect; // Rain and snow long maxTeams; // Maximum number of teams on map long unknown6; // Usually zeros long unknown7; // Usually zeros long unknown8; // Usually zeros long unknown9; // Usually zeros long unknown10; // Usually zeros long unknown11; // Usually zeros long unknown12; // Usually zeros short unknown13; // No idea short unknown14; // No idea short unknown15; // No idea short unknown16; // No idea amsoTAG ambientSound; // Global ambient sound ID long actionCount; // Number of scripted actions on level long actionOffset; // Offset from start of height mesh data long actionLength; // Total length of the action data stliTAG nameID; // Name of the map (stli tag reference) .256TAG postScreen; // Post-level screen ID (.256 tag) .256TAG preScreen; // Pre-level screen ID (.256 tag) .256TAG overheadMap; // Overhead map ID (.256 tag) meshTag nextLevel; // Next level ID (mesh tag) long unknown17; // No idea long objectives; // In-level objectives and subtitles long unknown18; // No idea long unknown19; // No idea long narrationText; // Scrolling text seen pre-level long unknown20; // No idea long unknown21; // No idea long unknown22; // No idea long ?2Offset; // Offset from start of height mesh data long ?2Length; // Total length of ?2 data long unknown23; // No idea long ?3Offset; // Offset from start of height mesh data long ?3Length; // Total length of ?3 data long unknown24; // No idea long unknown25; // Usually zeros long unknown26; // Usually zeros long unknown27; // Usually zeros windTAG windEffects; // Wind effects, usually FFFF long unknown28; // Usually zeros long unknown29; // Usually zeros long unknown30; // Usually zeros long unknown31; // Usually zeros long unknown32; // Usually zeros stliTAG captions; // Captions (stli tag reference) sounTAG narrationSound; // Narration voice (soun tag reference) long unknown33[191]; // Spacer zeros? }; // 1024 bytes Notes: [1] These are measured in 'map sections' as well, so the training map would be represented as 00 03 00 03 (3x3 map sections). Multiply these numbers by 16 to get the number of mesh points in each direction (48x48). [2] Item types apparently include troops, scenery (trees and such), miscellaneous objects (pus packets, etc.), and sounds. There may be others as well. [3] These appear to be bit flags of some type or another. On single player maps, these flags are as follows (values in hex): 00 D9 - Training Map 00 11 - Crows Bridge 00 19 - Five Champions and Silvermines 00 1C - A Long Awaited Party 00 1D - (all remaining single player maps) On multiplayer maps, the flags are as follows: 00 12 - Desert Between Your Ears, If I Had a Trow 00 16 - (all remaining multiplayer maps) I tried changing this flag from 00 1D to 00 12 (and 00 16) for "The Great Devoid". When I tried starting a multiplayer game, it did not show up on the single player or multiplayer lists. I believe the 2's bit is the one that controls single or multiplayer games. When the 2's bit is set, the game is a multiplayer one (assuming that there is at least one type of multiplayer game available for play... see [4] for details). [4] This piece of data contains all the flags pertaining to what types of multiplayer games are available on a multiplayer map. They are as follows (values in hex): 00 01 - Body Count 00 02 - Steal the Bacon 00 04 - Last Man on the Hill 00 08 - Scavenger Hunt 00 10 - Flag Rally 00 20 - Capture the Flag 00 40 - Balls on Parade 00 80 - Territories 01 00 - Captures 02 00 - King of the Hill 04 00 - Rugby 08 00 - "None" (not sure if that is "no multiplayer games available", or "a multiplayer game named 'none' is available".) To make more than one type of game available on a map, just add the respective flag values together. Thus, to make every game available, including "None", flags2 would have a value of 0F FF. When I changed flags1 of "The Great Devoid" to 00 16 and also set flags2 to anything other than 00 00, it showed up in the multiplayer map section when I ran Myth. :) The height mesh data consists of an array of entries, each 8 bytes long. The structure for a single entry in the height mesh is detailed below: struct gridData { short height; // 16 bit height map, signed integer uint16 gradient; // 16 bit unsigned integer [1] char water; // Effects of water (reflections, etc)? char passability; // Two 4-bit passability flags [2] char unknown1; // Possibly unused, usually FF char unknwon2; // Possibly unused, usually FF }; // 8 bytes [1] Gradient This seems to be a simple gradient value, depicting the maximum amount of elevation change between a given mesh point and the mesh points surrounding it. If you take the height map, convert it to 8 bit grayscale, import it into Photoshop, and then apply a "glowing edges" filter to it, the result looks -very- similar to what you get when you convert the gradient map to 8 bits and bring it into Photoshop. I am not sure exactly what this gradient might be used for in Myth, however. It might help to handle how things bounce when they strike the mesh surface somehow. [2] Passability is as follows: 0 Clear 8 Rocky 1 Human depth water 9 Marsh 2 Giant depth water A Snow 3 Deep water B Forest 4 Sloped C ? 5 Steep slope D ? 6 Grass E Walking impassable 7 Desert F Flying impassable I have recently learned that each mesh "square" is tessalated into two mesh triangles. The passability byte is split into two 4-bit nibbles. Each of these nibbles is applied to one of the two mesh triangles in a mesh square. Thus we have a slightly finer resolution of passability. As to how the mesh is tesselated (which diagonal to use per mesh "square"), I do not know. The declaration of item types present on the level. struct itemTypeData { short itemType; // The type of item listed [1] short flags1; // [2] long itemID; // The ID tag of the item type short teamNumber; // Which team the item belongs to [3] char unknown1[16]; // Usually zeros short itemMax; // Number of itemType present on level [4] short itemMax; // Max number of itemType allowed on // level (multiplayer) [5] short itemRef; // Reference number used in following // section. }; // 32 bytes [1] Item Types: 00 00 Camera Objects (?) 00 01 Scenery items (trees, bushes, etc) 00 03 Units 00 05 Ambient Sounds 00 06 Models (big houses, etc) 00 09 Objects affected by physics (proj tags?) 00 0A Special effects (particle generators, etc) [2] Flags: 00 00 Shows up in unit trading list but is not tradable 00 06 Shows up in unit trading list and is tradable 00 08 Does not show up in unit trading list [3] Team Number: This number represents whose team the unit belongs to. On solo levels, your units are team 00 00, and the enemy is team 00 01. The "Seven Gates" level may well have a second enemy team 00 02. On multiplayer maps, each starting point has a separate team associated with it (ranging from 00 00 through 00 04 for "I'll dance on your grave", for example). [4] Number Present: I am still working on this one. I thought that by modifying this number, the starting number of units of a given type would change in multiplayer games. It didn't. I believe that this is what sets aside memory space for the item list that follows. [5] Max Number Allowed: As with [4], I am still working on this one. I thought that this would set the maximum number of allowed units of a given type in a multiplayer game. It didn't. I believe that this is what sets aside memory space for the item list that follows. The information for each individual item present on a level. struct itemListData { short unknown1; // No idea. Often it is all 0's short initialItem; // Flag whether level starts with item // present [1] short itemType; // The type of item listed [2] short itemRef; // Reference number from itemTypeData short itemID1; // Unique ID number for this instance // of the item short unknown2; // No idea. long itemPosition[3]; // (X,Y,Z) position on the mesh [3] char unknown3; // No idea. Usually all 0's char unknown4; // No idea. Usually all 0's char unknown5; // No idea. Usually all 0's char unknown6; // No idea. Usually all 0's char unknown7; // No idea. Usually all 0's char unknown8; // No idea. Usually all 0's char unknown9; // No idea. Usually all 0's char unknown10; // No idea. Usually all 0's short facing; // Direction the item is facing [4] char unknown11[26]; // No idea. Usually all 0's. short itemID2; // Another unique number for each item short itemID3; // Yet another unique number [5] }; // 64 bytes [1] If this is set to 00 00, the item is present at the beginning of the level. In multiplayer games, if this is set to 00 01, the item is not one of the pre-set units you are given... you must trade to get any unit with a 00 01 flag. I have not delved too deeply into any other possibilities (there might be a 00 02 or something in some of the solo maps). This explains the problems I was having above with the Number Present and Max Number Allowed values. [2] Item Type: 00 00 Camera Objects (?) 00 01 Scenery items (trees, bushes, etc) 00 03 Units 00 05 Ambient Sounds 00 06 Models (big houses, etc) 00 09 Objects affected by physics (proj tags?) 00 0A Special effects (particle generators, etc) [3] The X, Y, and Z positions are integer positions measured in 1024-ths of a mesh point from the northeast corner of the map. Thus, take the number you get in decimal from those positions, and divide by 1024 to get the actual mesh point location. The tutorial flag on the training map is located at the following coordinates: X: 00 00 68 3E = 26686 --(convert to mesh points)--> 26.061 Y: 00 00 6B C6 = 27590 --(convert to mesh points)--> 26.943 Z: 00 00 01 FC = 508 --(convert to mesh points)--> 0.496 I checked this method against the three Forest Giant (Ent) locations on Forest Heart (location data unceremoniously ripped off of Zarquon's "Piri Reis" Markers.jpg image... I'm sneaky that way.) Image located at http://www.smavid.com/FutureMyth/PiriReis.htm The first Ent is found at tags.gor offset 13646544, has an item_number_ID of 287D = 10365, is located at X:163.857 Y:36.483 Z:-0.199. (It matches -exactly- with what Zarquon's editor gives... how's that for some digital magic? *grin*). [4] I am currently guessing on this, but it looks like this might be the direction the unit is facing, in 65536-ths of a circle. I do not know which way 0 degrees is... I'm guessing it's north. [5] itemID2 and itemID3 always appear to add together to yield 32768 (80 00). I have no idea why they do this. END OF MESH INFORMATION (FOR NOW)
david@theresistance.net
| David Shaw
| http://david.theresistance.net/