Skip to content

New Special Lumps

Chris edited this page Oct 7, 2019 · 12 revisions

Special Lumps

Fonts

Used to define fonts with a bit more control over what letter represents what. The definitions look like:

font <NAME>
{
    align = <BOTTOM or CENTER or TOP>;  // Optional
    grayscale = <BOOLEAN>;  // Optional
    space = <INTEGER>;  // Optional
    characters
    {
        <CHARACTER_STRING> <IMAGE> [default] [align <BOTTOM or CENTER or TOP>];
        // ... repeated for each character
    }
}
  • align: Tells it which vertical component to align to. This is either bottom, center, or top. Bottom means it will draw from the bottom up. Top means it will draw from the top down. Center means it will align it at the center with respect to the center of the image. Note that these are all relative to the max character height, so a font that has a height of 12 and draws from either top/bottom will have a 2 pixel padding at the opposite end. For center, this doesn't matter since it will align the center of the character image to the center of the tallest character. By default, this is bottom.

  • grayscale: When generating the image, it will convert it to a grayscale image so it can be colorized by shaders.

  • space: The space character is not usually a part of the fonts, so we can optionally customize what its width would be by this value.

  • characters: The definition of all the characters. This should not be empty. Each character needs a definition. There are optional parameters you can put after it. One is default (must come first) which says any unknown characters are mapped onto this character. It is an error to provide this twice or to omit it (meaning no character has the default label). Custom alignment can be done by writing align <TYPE> as well, which will bypass the default alignment of the font.

An example of a font:

font RandomFont
{
    space = 7;
    grayscale = true;
    characters 
    {
        "-" FNTMINUS align center;
        "%" FNTPRCNT;
        "0" FNTNUM0 default;
        "1" FNTNUM1;
        "2" FNTNUM2;
        "3" FNTNUM3;
        "4" FNTNUM4;
    }
}

Compatibility

This allows us to mutate map elements at runtime so the BSP builder doesn't crash. It also can allow us to change things in the map that may be wrong or missing. It works by having a wad/hash being provided, and then specifying a map, and then specifying what should change in the map.

Here is an example of some compatibility text:

"MYFILE.WAD"
{
    map "MAP01"
    {
        line 88 split 1 2 vertex 4;
        line 786 set front 442 back 443;
    }
    
    map "HELLO"
    {
        line 42 delete;
        line 83 set back 127;
    }
}

"SOME_IWAD.WAD"
"9407539844E1C6EC74D247D6A64A48C8"
{
    map "MAP30"
    {
        line 123 delete;
    }
}

The format is as follows (where DEFINITION is the top level definition):

DEFINITION = <WADS/HASHES>+ { <MAP>* }
WADS/HASHES = 32-char string OR wad name as a string
MAP = "map" <MAP_NAME> { <OPTION>* }
OPTION = <LINE_SPLIT> | <LINE_SET> | <LINE_DELETE> | <SIDE_SET>
LINE_SPLIT = "line" <ID> "split" <ID> <ID> "vertex" <ID> ";"
LINE_SET = "line" <ID> "set" ["flip"] ["start" <ID>] ["end" <ID>] ["front" <ID>] ["back" (<ID> | "none")] ";"
LINE_DELETE = "line" <ID> "delete" ";"
SIDE_SET = "side" <ID> "set" ["lower" <TEXTURE>] ["middle" <TEXTURE>] ["upper" <TEXTURE>] ";"

You can specify the wad/pk3 by either name, or hash. If you provide the name, it is case-insensitive but must have the extension. If you provide the hash, it will match any file that has the hash. You may combine them together by having as many archive names and hashes as you want, they will each create their own definition and apply them as needed. This means if you have a definition like:

"MYWAD.WAD"
"EC74D247D6A64A48C89407539844E1C6"
"MYWAD-NEW.WAD"
"9407539844E1C6EC74D247D6A64A48C8"
{
    ...
}

Then the following definitions will be applied to any wad file with the name "mywad.wad" or "mywad-new.wad", or any file that has the same hash as the above. It is not going to require that all of them be met or that it matches some name and hash, it will apply to the archive if it matches one or more of the identifiers you provide. This allows us to support wads that have been renamed but have the data unchanged, or supports multiple names of a wad in case the author did something like that.

It is important to note that these are resolved in the order they are declared, which means for example if you want to split a line at a vertex that does not exist, then you should write a line in the compatibility file that creates the vertex before you use the ID of the new vertex.

You should also use new IDs only after the list of available IDs. For example if there's 50 linedefs in a map, then it'll use IDs 0 to 49. If you want to add a new line, you'd start at 50 since that is not used. While you can choose any number greater than 50, the practice right now is to keep it consecutive. This is not designed to be a major map modification tool but rather to patch levels with broken geometry, so there shouldn't be much line creation anyways or anything fancy being done.

The following is a list of how the options work:

Line Splitting

line ID split newStartID newEndID vertex vertexID

  • ID: The ID of the line to split
  • newStartID: The new ID of the line that is created from start to the middle splitting vertex, which should be a line ID that has not been used yet
  • newEndID: Same as the above except for the middle to ending vertex, which should be a line ID that has not been used yet
  • vertexID: The vertex ID that is to be on the middle

Splits a line at a vertex and generates two children lines. The original line is removed. This is used in maps where the map editor didn't fuse a line with another line and results in weird geometry. It is not uncommon to need to do more processing on the line after it has been split, as usually map editors would turn one of them into a two sided line.

Line Setting

line ID set [flip] [start newStartID] [end newEndID] [front newFrontSideID] [back (newBackSideID | none)]

  • ID: The ID of the line to set
  • newStartID: The ID of the vertex to set to for the starting vertex
  • newEndID: Same as the above but for the ending vertex
  • newFrontSideID: The ID of the side to set for the front
  • newBackSideID: Same as the above but for the back

Sets certain properties on a line that are missing or should be changed.

If the line should be flipped, the convenience value of flip can be used instead of writing something like set start E end S where the start was originally S and end was originally E. I figured seeing flip is more convenient to read and write since it's not immediate from a set start _ end _ that you're flipping a line.

In the case of changing or setting the back, an option exists to remove the back line if needed by using the value none instead of an ID. This turns a two-sided line into a one-sided line. Note that the square brackets mean 'optional', so you can provide zero or more of the stuff in the brackets. The only requirement right now is that they be in order (so you must do end after start if you do both, not before it).

Line Deletion

line ID delete

  • ID: The ID of the line to delete

Deletes a line from existing. Most commonly used when there's a one-sided line that should not exist and causes issues with the BSP builder.

Side Setting

side ID set [lower textureName] [middle textureName] [upper textureName]

  • ID: The ID of the side to set
  • textureName: The name of the texture to set on the wall component

Sets certain properties on a line that are missing or should be changed.

The only requirement right now is that they be in order (so you must do lower before middle, and both before upper).

Clone this wiki locally