=============================================================================== Universal Doom Map Format Specification v0.99 - 04/30/08 Written by James "Quasar" Haley - haleyjd@hotmail.com =============================================================================== ======================================= I. Grammar / Syntax ======================================= translation_unit := global_expr_list global_expr_list := global_expr global_expr_list global_expr := block | assignment_expr block := identifier '{' expr_list '}' expr_list := assignment_expr expr_list assignment_expr := identifier '=' value ';' identifier := [A-Za-z0-9_]+ value := integer | float | quoted_string | unquoted_string integer := [+-]?[1-9]+[0-9]* | 0[0-9]+ | 0x[0-9A-Fa-f]+ float := [+-]?[0-9]+'.'[0-9]*([eE][+-]?[0-9]+)? quoted_string := "([^"\\]*(\\.[^"\\]*)*)" unquoted_string := [^{}();"'\n\t ]+ Global assignments and named/indexed global blocks are the only top-level entities supported. There are no comments. Whitespace is strictly ignored. Blocks begin with a keyword identifier. An example of a minimally-defined entity follows: linedef { id = 1; } Compliant parsers will ignore all unknown keywords in global assignments, block-level assignments, and block headers. Compliant parsers should attempt to preserve as much of such information as is possible by using a flexible mapping such as hashing. A field which specifies "boolean" semantics shall accept unquoted string value "true" to mean that the field is asserted, and unquoted string value "false" to meant that the field is unasserted. Fields which do not appear in a block take on their default value. This allows minimal specification. ======================================= II. Implementation Semantics ======================================= ------------------------------------ II.A : Storage and Retrieval of Data ------------------------------------ Block-defined entities are written and read in top-to-bottom order. For example, the following linedefs can be assigned in order to a contiguous block of memory serving as the implementing port's lines array: linedef { id = 1; } linedef { id = 2; } linedef { id = 3; } linedef { id = 4; } ----------------------------------- II.B : Storage Within Archive Files ----------------------------------- UDMF maps shall be layed out within the archive directory as follows: (HEADER) TEXTMAP ... ENDMAP (HEADER) = Any lump name from 1 to 8 characters. Serves as the name of the map. TEXTMAP = Single UDMF lump containing all data for the map. ... = Blockmap, reject, BSP tree, and port-specific lumps, if any. The format and presence of these resources are not defined by UDMF. ENDMAP = Required closing lump. Implementing editors and source ports may distinguish a UDMF map from a traditional binary map by testing the name of the first directory entry following the map header. Implementing resource editors will be capable of keeping all lumps for the map, even non-standard ones, together by properly scanning for the ENDMAP entry. Non-implementing resource editors will not recognize the sequence of lumps as a map, and may thus be less likely to interfere with the order or presence of the lumps. Use of non-implementing resource editors to manipulate UDMF-map-containing WAD files is not recommended, however. -------------------------------- II.C : Implementation Dependence -------------------------------- A port's list of supported non-standard fields must be provided to implementing editors, where they can be provided to the end user as controls, as options in a dropbox, or through the ability to input any arbitrary "identifier = value;" pair in a text box. Every UDMF map must contain somewhere within the file one or more "namespace" identifier statements, which declare the source port implementation relative to which this map is to be interpreted. The last such statement parsed shall be the one which defines the value of the "namespace" variable for the map. Example: namespace = ZDoom; Implementing source ports may ignore this information, or they may use it to perform automatic runtime translation of maps they would otherwise be unable to support. Implementing source ports should publicly document the value of the "namespace" variable they intend to identify with when establishing support for UDMF, and avoid conflicts with existing implementations at all costs. ======================================= III. Standardized Fields ======================================= The UDMF v0.99 specification considers the following fields standard. They must be supported by all implementing source ports and editors. Comments shown within the following blocks are for illustrative purposes only; this is not valid UDMF syntax. linedef { id = ; // ID of line. Interpreted as tag or scripting id. // Default = -1. v1 = ; // Index of first vertex. No valid default. v2 = ; // Index of second vertex. No valid default. blocking = ; // true = line blocks things. Default = false. blockmonsters = ; // true = line blocks monsters. Default = false. twosided = ; // true = line is 2S. Default = false. dontpegtop = ; // true = upper texture unpegged. Def = false. dontpegbottom = ; // true = lower texture unpegged. Def = false. secret = ; // true = drawn as 1S on map. Default = false. soundblock = ; // true = blocks sound. Default = false. dontdraw = ; // true = line never drawn on map. Def = false. mapped = ; // true = always appears on map. Def = false. passuse = ; // true = passes use action. Default = false. repeatspecial = ; // true = repeatable special. Default = false. playercross = ; // true = player can cross. Default = false. playeruse = ; // true = player can use. Default = false. monstercross = ; // true = monster can cross. Default = false. impact = ; // true = projectile can activate. Def = false. push = ; // true = player/monster can push. Def = false. missilecross = ; // true = projectile can cross. Default = false. // TODO: other standardized SPAC combinations? special = ; // Special. Default = 0. arg0 = ; // Argument 0. Default = 0. arg1 = ; // Argument 1. Default = 0. arg2 = ; // Argument 2. Default = 0. arg3 = ; // Argument 3. Default = 0. arg4 = ; // Argument 4. Default = 0. frontside = ; // Sidedef 1 index. No valid default. backside = ; // Sidedef 2 index. Default = -1. } sidedef { offsetx = ; // X Offset. Default = 0. offsety = ; // Y Offset. Default = 0. texturetop = ; // Upper texture. Default = "-". texturebottom = ; // Lower texture. Default = "-". texturemiddle = ; // Middle texture. Default = "-". sector = ; // Sector index. No valid default. } vertex { x = ; // X coordinate. No valid default. y = ; // Y coordinate. No valid default. } sector { floorheight = ; // Floor height. Default = 0. ceilingheight = ; // Ceiling height. Default = 0. floorpic = ; // Floor flat. No valid default. ceilingpic = ; // Ceiling flat. No valid default. lightlevel = ; // Light level. Default = 255? (FIXME) special = ; // Sector special. Default = 0. tag = ; // Sector tag. Default = 0. } thing { tid = ; // Thing ID. Default = 0. x = ; // X coordinate. No valid default. y = ; // Y coordinate. No valid default. height = ; // Z height relative to floor. Default = 0. // (Relative to ceiling for SPAWNCEILING items). angle = ; // Map angle of thing. Default = 0 (East). type = ; // DoomedNum. No valid default. easy = ; // true = in skills 1/2. Default = false. normal = ; // true = in skill 3. Default = false. hard = ; // true = in skill 4/5. Default = false. ambush = ; // true = thing is deaf. Default = false. notsingle = ; // true = not in SP mode. Default = false. notdm = ; // true = not in DM mode. Default = false. notcoop = ; // true = not in Coop. Default = false. dormant = ; // true = dormant thing. Default = false. class0 = ; // true = Present for pclass 0. Default = false. class1 = ; // true = Present for pclass 1. Default = false. class2 = ; // true = Present for pclass 2. Default = false. special = ; // Scripting special. Default = 0; arg0 = ; // Argument 0. Default = 0. arg1 = ; // Argument 1. Default = 0. arg2 = ; // Argument 2. Default = 0. arg3 = ; // Argument 3. Default = 0. arg4 = ; // Argument 4. Default = 0. } =============================================================================== EOF ===============================================================================