Yadex user's guide

Yadex 1.7.0 (2026-07-12)

# User's guide

| Warning : this document is unfinished, ill-structured and incomplete. |

Contents :

- 1. Introduction

- 1.1. Yadex in one paragraph
- 1.2. What do I need ?

- 1.2.1. Iwad
- 1.2.2. Directories
- 1.2.3. Display

- 1.3. Compiling and installing Yadex

- 2. Running Yadex

- 2.1. The command line arguments
- 2.2. Options
- 2.3. Specifying the game for which you want to edit
- 2.4. Specifying the names of pwads to load
- 2.5. Environment variables

- 3. Editing levels with Yadex

- 3.1. Using external textures, flats, etc.
- 3.2. Logging of time spent
- 3.3. The prompt commands
- 3.4. Moving around

- 3.4.1. Moving the pointer
- 3.4.2. Scrolling
- 3.4.3. Autoscrolling
- 3.4.4. Jumping

- 3.5. Zooming in and out
- 3.6. The grid
- 3.7. Inserting objects
- 3.8. Copying objects
- 3.9. Deleting objects
- 3.10. Changing the properties of objects
- 3.11. Moving objects a.k.a. drag-and-drop
- 3.12. Renumbering objects

- 3.12.1. Exchanging objects numbers

- 3.13. Selecting objects
- 3.14. The use of [`Shift`]
- 3.15. Sector miscellaneous operations
- 3.16. Thing miscellaneous operations
- 3.17. Setting/toggling/clearing thing flags
- 3.18. Vertex miscellaneous operations
- 3.19. Linedef miscellaneous operations
- 3.20. Setting/toggling/clearing linedef flags
- 3.21. Undoing
- 3.22. Cut-and-paste from one level to another
- 3.23. Using the flat/patch/sprite/texture viewer
- 3.24. Saving
- 3.25. Closing a window

- 4. Variables and configuration

- 4.1. Variables

- 4.1.1. The font
- 4.1.2. Mouse wheel and other mouse issues

- 4.2. Preferences
- 4.3. Command line
- 4.4. Environment variables
- 4.5. Configuration files

- 4.5.1. Contents of configuration files
- 4.5.2. Locating configuration files
- 4.5.3. Default configuration files
- 4.5.4. User-specified configuration files
- 4.5.5. Organising your configuration files

- 5. Game definition files

- 5.1. Contents of game definition files
- 5.2. Locating game definition files
- 5.3. Use of game definition files

- 6. Known bugs
- 7. Supported games

- 7.1. Doom
- 7.2. Doom II
- 7.3. Doom alpha
- 7.4. Doom press release pre-beta
- 7.5. Final Doom
- 7.6. Heretic
- 7.7. Hexen
- 7.8. Strife
- 7.9. Ultimate Doom
- 7.10. Boom
- 7.11. EDGE
- 7.12. MBF
- 7.13. Other derivatives

## 1. Introduction

### 1.1. Yadex in one paragraph

Yadex is a Doom level (wad) editor for Unix systems running X, including Linux. It supports Doom, Doom II, Ultimate Doom, Final Doom, Heretic, Doom press release pre-beta and also, in a more or less limited way, Hexen, Strife and Doom alpha. It is available under the terms of the GPL.

### 1.2. What do I need ?

To compile, install and run this release of Yadex, you need

- a POSIX-compatible environment (such as Unix),
- a C compiler (ISO-compatible),
- a C++ compiler (ISO-compatible),
- GNU make (it won't work with other flavours of make),
- an HTML viewer to read the doc,
- a Doom/Doom II/Heretic/Hexen/Strife iwad,
- X11R6 or X11R5.

More specifically, Yadex expects that

- the routines in `ctype.h` accept the range `CHAR_MIN` through `UCHAR_MAX`,
- the C library supports `hypot()` and at least one of `nanosleep()` and `usleep()`.

#### 1.2.1. Iwad

A shareware Doom or Heretic iwad or a demo Hexen or Strife iwad is okay but you need a registered iwad if you want to be able to save your changes.

#### 1.2.2. Directories

Yadex mostly conforms to the FHS (filesystem hierarchy standard). By default, the installation procedure will try to copy files in the following directories, creating the directories if they don't exist ;

- `/usr/local/bin`
- `/etc/yadex/1.7.0`
- `/usr/local/man/man6`
- `/usr/local/share/games/yadex/1.7.0`

So make sure you have the necessary rights before installing. If you don't, install in a different directory by running `./configure` with the `--prefix` option.

#### 1.2.3. Display

Yadex uses about 270 different colours. In most cases, on PseudoColor displays, there aren't that many free colour cells. So, if it detects a PseudoColor display, Yadex uses a private colormap so as to get as many free colour cells as possible. The drawback of this method is that, when you're in the Yadex window, all other windows are displayed with wrong colours and vice-versa.

What's more, as PseudoColor displays typically have 256 colours (at least on PC), which is less than the number of colours needed, Yadex might have to assign the same physical colour to different logical colours. If it happens, it will try to render the colours of the game accurately at the expense of the application colours.

Executive summary: if you can, use a TrueColor or DirectColor display and a depth of more than 8 bits per pixel (E.G. by launching X with "`startx -- -bpp 16`").

A 640x480 screen is okay though, of course, a larger display is better.

### 1.3. Compiling and installing Yadex

See `README`.

Don't forget to tell Yadex where your iwads are by changing the lines "`iwad1 =`", "`iwad2 =`" etc. in `/etc/yadex/1.7.0/yadex.cfg`. If there is an iwad you don't have, you can just comment out the corresponding line.

## 2. Running Yadex

### 2.1. The command line arguments

Yadex takes two sorts of command line arguments : parameters and options. An option is a command line argument that starts with a "`-`".

Some options take an argument. The argument must be separated from the option by some whitespace. Constructs like "`-othingy`" are not recognized. You have to type "`-o thingy`".

The "`-file`" option takes a variable number of arguments. It uses all the non-options up to the next option.

The options that take no argument can be negated by using a "`+`" instead of a "`-`". For example, "`+sb`" will undo the effect of a "`swap_buttons = true`" directive in the config file.

In general, if you specify the same option more than once, the last occurrence overrides the previous ones. For example, "`yadex +P -P`" is equivalent to "`yadex -P`". Similarly, "`yadex -i1 foo.wad -i1 bar.wad -i1 baz.wad`" boils down to "`yadex -i1 baz.wad`".

The "`-pwad`" (or "`-pw`") option, however are additive. Each occurrence will add to the previous ones. For instance, "`yadex -pwad foo.wad -pwad bar.wad`" is equivalent to "`yadex foo.wad bar.wad`".

Any command line argument that is not an option is treated as the name of a pwad to load. You can put as many names of pwads on the command line as you wish (or none at all). The details of specifying pwad names are discussed there.

### 2.2. Options

To know about the command line options that Yadex understands, type

`$ yadex --help`

You'll get this:

    -b                 string     Run benchmark and exit successfully
    -f  -config_file   string     Config file
    -d  -debug                    Debug mode
        -expert                   Expert mode
    -fc -fake_cursor              Fake cursor
    -fn -font          string     Font name
    -g  -game          string     Game
    -h  -height        integer    Initial window height
    -?  -help  --help             Show usage summary
    -i1 -iwad1         string     The name of Doom iwad
    -i2 -iwad2         string     The name of the Doom II iwad
    -i3 -iwad3         string     The name of the Heretic iwad
    -i4 -iwad4         string     The name of the Hexen iwad
    -i5 -iwad5         string     The name of the Strife iwad
    -i6 -iwad6         string     The name of the Doom alpha 0.2 iwad
    -i7 -iwad7         string     The name of the Doom alpha 0.4 iwad
    -i8 -iwad8         string     The name of the Doom alpha 0.5 iwad
    -i9 -iwad9         string     The name of the Doom press release iwad
    -i10 -iwad10       string     The name of the Strife 1.0 iwad
    -pw -pwad          string     Pwad file to load
    -P  -no_pixmap                No pixmap, saves memory, more flicker
    -q  -quiet                    Quiet mode
    -qq -quieter                  Quieter mode
    -s0 -select0                  Automatic selection of 0th object
    -sb -swap_buttons             Swap mouse buttons
    -td -text_dot                 DrawScreenText debug flag
    -v  -verbose                  Verbose mode
        --version                 Print version and exit
    -w  -width         integer    Initial window width
    -z  -zoom          integer    Initial zoom factor

You might wonder what the "`-file`", "`-pw`" and "`-pwad`" options are for since it's so simple to just put the names of the pwads on the command line. The answer is that they're only here for compatibility with previous versions of Yadex/Yade/DEU. Don't use them. They might go away one day.

### 2.3. Specifying the game for which you want to edit

Yadex can handle several games (Doom, Doom II, Heretic, etc.) but only one at a time. Unfortunately, that game can't be changed dynamically. If you want to switch game, you must quit Yadex and run it again.

By default, the game used is the one specified by the "`game=`" directive in the configuration file. If you want to override the default, use "`-g game`".

The allowed values for `game` are :

"`doom`"
  Doom and Ultimate Doom (shareware or registered)
"`doom02`"
  Doom alpha 0.2
"`doom04`"
  Doom alpha 0.4
"`doom05`"
  Doom alpha 0.5
"`doom2`"
  Doom II and Final Doom
"`doompr`"
  Doom press release pre-beta
"`heretic`"
  Heretic (shareware or registered)
"`hexen`"
  Hexen (demo or commercial)
"`strife`"
  Strife 1.1 or later (demo or commercial)
"`strife10`"
  Strife 1.0 (demo or commercial)

Not all those games are fully supported. For details, see there.

### 2.4. Specifying the names of pwads to load

When you have to specify the name of a pwad to load, for example in the `r` command, or as a command line argument, you don't always have to spell it all out.

- The `.wad` extension can be omitted, it will be added automatically. For example, specifying the name "`foo`" is equivalent to specifying "`foo.wad`". An unfortunate consequence of this convention is that it's impossible to load a wad that would be really called "`foo`". Though, under DOS, you can still work around this limitation by specifying the name with a trailing dot, ("`foo.`").

- The path can sometimes be omitted too, if the wad is in one of the standard directories, or one of their subdirectories. If no file of the name you specified is found in the current directory, Yadex will look for a file of that name in the standard directories, which are :

  1. your home directory,
  2. `/usr/local/share/games/`game,
  3. `/usr/share/games/`game,
  4. `/usr/local/share/games/wads`,
  5. `/usr/share/games/wads`,

  (where game is the name of the game).

  On the other hand, if you give an absolute file name, that is one that begins with a "`/`", the standard directories will not be used. Yadex will only try to open the file of the exact name you specified.

  For example, if you type "`yadex -g doom2 foo/bar`", Yadex will look for the following files in order :

  1. `~/foo/bar.wad`,
  2. `/usr/local/share/games/doom2/foo/bar.wad`,
  3. `/usr/share/games/doom2/foo/bar.wad`,
  4. `/usr/local/share/games/wads/foo/bar.wad`,
  5. `/usr/share/games/wads/foo/bar.wad`,

  and open the first it finds.

  But if you type "`yadex -g doom2 /foo/bar`" (note the leading slash), Yadex will try to open "`/foo/bar.wad`", period.

  The philosophy behind those standard directories is that :

  - a local file overrides a global one,
  - a game-specific file overrides a non-game-specific one.

Gotcha: those shorthands can only be used when reading a pwad. When writing to a pwad, you always have to specify the exact name, with the full path and extension.

### 2.5. Environment variables

`DOOMWADDIR`
  No, `DOOMWADDIR` is not supported. Perhaps in another version...
`DISPLAY`
  Unix only. The name of the X display that Yadex will try to connect to.
`HOME`
  Used to expand `~` when locating configuration and game definition files.
`LINES`
  If set, Yadex assumes the tty has that many lines instead of 24. The value must be an unsigned, non-zero decimal integer.
`TMPDIR`
  If set, swap files are created there. Otherwise, in `/tmp`.
`YADEX_GAME`
  Indicates the game to use. Overrides the `game` parameter in the config file, is overridden by the `-g` command line option.

## 3. Editing levels with Yadex

### 3.1. Using external textures, flats, etc.

Like Doom, Yadex accepts the addition and replacement of resources from a pwad. In general, if the same resource is defined in several wads, the last definition is used. This is also true if the same resource is defined several times in the same wad. It's not recommended that you use lower case names in your wads; sometimes it's handled but sometimes it's not. So always use upper-case names.

Flats
  New or replacement flats are recognized iff they're placed between `FF_START`/`F_END` or `FF_START`/`FF_END` labels. There can be any number of `FF_START`/`F_END` and `FF_START`/`FF_END` pairs and they don't have to be in the same pwad. If there are several lumps for the same flat, the last one is used.
Palette
  If there is a replacement `PLAYPAL` lump, it's used. If there are several `PLAYPAL` lumps, the last one is used.
Patches
  New or replacement patches are recognized iff they're between `P_START` and `P_END` or `PP_START` and `PP_END`. Within a group of patches, labels `P1_START`, `P1_END`, `P2_START`, `P2_END`, `P3_START` and `P3_END` are ignored ; any other label elicits a warning. New patches must also appear in the `PNAMES` lump or the texture browser won't be able to use them. If there are several `PNAMES` lumps, the last one is used. If there are several lumps for the same flat, the last one is used.
Sprites
  New or replacement sprites are recognized iff they're between one of the following pair of labels : `S_START`/`S_END`, `SS_START`/`S_END` or `SS_START`/`SS_END`. There can be any number of label pairs and they don't have to be in the same pwad. If there are several lumps for the same sprite, the last one is used.
Textures
  New or replacement textures are recognized iff they're in a `TEXTURE1` or `TEXTURE2` lump. If the same texture happens to be defined in both `TEXTURE1` and `TEXTURE2` (which should not happen), only the definition in `TEXTURE1` is used. If there are several `TEXTURE1` lumps, the last one is used. If there are several `TEXTURE2` lumps, the last one is used. If it exists, `TEXTURE2` is always susceptible to be used, even for games where it's not supposed to exist, like Doom II.

### 3.2. Logging of time spent

If you edit a level from a file and there exists a file in the same directory with the same name but with the extension `.yl`, that file will be used to keep track of the time you spent editing that level. At the end of the editing session, Yadex will append a line to the `.yl` file with the name of the level and the number of minutes spent on it.

Note that if the `.yl` file does not already exist, it is not created. This is to prevent the creation of a large number of small useless files when browsing through a collection of wads. Thus, if you want to enable logging, you need to manually create the log file first with a command such as "`touch name.yl`".

### 3.3. The prompt commands

You can get a summary of the prompt commands by typing "`?`" at the Yadex prompt.

### 3.4. Moving around

#### 3.4.1. Moving the pointer

In the X11 version, the only way to do that is to move the pointer device (i.e. the mouse).

#### 3.4.2. Scrolling

The arrow keys [`Left`], [`Right`], [`Up`] and [`Down`] scroll a little at a time, by default 10% of the screen/window width or height. You can change the exact amount by setting the variable `scroll_less` in the configuration file.

[`Page-up`], [`Page-down`], [`Home`] and [`End`] scroll more at a time, by default 90% of the screen/window width or height. You can change the exact amount by setting the variable `scroll_more` in the configuration file.

#### 3.4.3. Autoscrolling

By default, autoscrolling is disabled. You can enable it by setting `autoscroll` to `true` in the configuration file.

When it is enabled and the pointer is close to the edge of the screen/window, the map scrolls automatically. The closer you are to the edge, the faster it scrolls. Autoscrolling is always disabled near the menu bar items so that the map does not scroll when you're reaching for the menu.

You can fine tune autoscrolling by changing the variables `autoscroll_amp` and `autoscroll_edge`.

#### 3.4.4. Jumping

I plan to develop a full set-mark/jump-to-mark system similar to the one in `vi`, with `mmark-name`, `'mark-name` and ``mark-name`.

For the moment, if you press [`'`], the map scrolls so that its centre is at the centre of the screen/window.

If you press [```], the map scrolls so that its centre is at the centre of the screen/window and the zoom factor is adjusted so that the whole map is visible and almost fills the screen/window.

### 3.5. Zooming in and out

The current zoom factor is shown on the info bar, after the word "`Scale:`". It is shown in pixels per map units. The indication "`Scale: 50%`" means that one pixel of the display corresponds to 2 map units.

You can zoom in by pressing [`+`] or [`=`] or the 4th mouse button or by moving the mouse wheel "up". See the `zoom_default` and `zoom_step` variables.

You can zoom out by pressing [`-`] or [`_`] or the 5th mouse button or by moving the mouse wheel "down". See the `zoom_default` and `zoom_step` variables.

You can also set the zoom factor directly with the keys [`1`] through [`9`] and [`0`]. [`1`] sets the zoom factor to a value that is controlled by the `digit_zoom_base` variable (by default, 100%). Each successive key down the keyboard sets the zoom factor `digit_zoom_step` percents higher than the previous one (by default, -29%).

### 3.6. The grid

The grid is a square mesh of blue dots and lines in the background. It's here to help you aligning your objects correctly with regard to Doom's metrics, which will save you a lot of textures misalignments.

When you insert or drag objects, they are snapped to grid. That is, Yadex prevents you from placing them off the grid. You can toggle the `snap_to_grid` flag by pressing [`y`].

The grid step is always a power of 2, E.G. 128, 64, 32, etc. You can get a finer grid (dividing the grid step by 2) by pressing [`g`]. Conversely, pressing [`G`] multiplies the grid step by 2. If you press [`g`] when the grid step is already at its minimum value, it will be set to its maximum value. And conversely. The minimum and maximum values are set in the configuration file with `grid_min` and `grid_max`.

When you change the zoom factor, Yadex automatically changes the grid step to make it what it thinks is best for the new zoom factor. If you want to lock the grid step to its current value, press [`z`]. To unlock it, press that key again.

You can hide the grid by pressing [`h`] (but this doesn't disable `snap_to_grid`). Press that key again to make the grid visible again.

You can also use [`H`] to reset the grid step.

### 3.7. Inserting objects

By pressing [`Ins`], you insert a new object under the pointer.

The type of the new object is generally determined by the current mode. That is, if you are in things mode, pressing [`Ins`] will create a new thing. However, this is not always true, particularly if some objects are already selected :

- If you are in vertices mode and there are two or more vertices selected, pressing [`Ins`] will insert a linedef from the first vertex to the second, another one from the second to the third and so on. That is, a path of linedefs is created from the first to the last vertex. The path is not closed (but see [`Shift`][`Ins`] below).
- If you are in linedefs mode and there are selected linedefs, pressing [`Ins`] will create a new sector and new sidedefs that point to it and assign them to the linedefs. For the linedefs that had no first sidedef (whether or not they already had a second sidedef), the new sidedef is attached as first sidedef. For the linedefs that had a first sidedef but no second sidedef, the new sidedef is attached as second sidedef. If one or more of the selected linedefs already had two sidedefs, the operation fails. Bug: the side to which the new sidedef is attached is decided without taking into account the actual orientation of the linedef.

If an object of the same type is highlighted at the moment you press [`Ins`], the properties of the new object are copied from the highlighted object. In other words, the highlighted object serves as a "model". Else the properties of the new object are set to default values.

Object type | Property | Value if there is a model | Value if there is no model
--- | --- | --- | ---
Linedef | Start vertex | Like the model | If there are two selected vertices, the first. If not, you are prompted for a vertex number.
End vertex | Like the model | If there are two selected vertices, the second. If not, you are prompted for a vertex number.
Flags | Like the model | Impassable
Type | Like the model | 0 (normal)
Sector tag | Like the model | 0 (none)
First sidedef | FFFFh (none) | FFFFh (none)
Second sidedef | FFFFh (none) | FFFFh (none)
Thing | Coordinates | Like the pointer | Like the pointer
Type | Like the model | `default_thing`
Flags | Like the model | D12 D3 D45
Angle | Like the model | 0 (east)
Sector | Floor height | Like the model | `default_floor_height`
Ceiling height | Like the model | `default_ceiling_height`
Floor texture | Like the model | `default_floor_texture`
Ceiling texture | Like the model | `default_ceiling_texture`
Light level | Like the model | `default_light_level`
Type | Like the model | 0 (normal)
Tag | Like the model | 0 (none)
Vertex | Coordinates

In vertex mode, pressing [`Shift`][`Ins`] is the same as pressing [`Ins`] except that the path is closed (an additional linedef is created from the last to the first vertex).

### 3.8. Copying objects

When you press [`o`], the selected or highlighted object(s) is(are) copied. If only one object has been copied, the new copy is spawned under the pointer. If several objects have been copied, the new copies are spawned so that their centre is under the pointer.

The new copies are spawned selected and everything else is unselected so that you can easily drag them where you want.

All the properties of the new objects are copied from the original objects with the notable exception of references. If you are an OO programmer, think shallow copy vs. deep copy. Otherwise, read on.

When you copy linedefs, the start and end vertices are copied too and the new linedefs reference the new vertices instead of the old ones. The same thing goes for sidedefs, except if the `copy_linedef_reuse_sidedefs` flag is true. In that case, each new linedef uses the same sidedefs as its "model" did. This is useful when you want to create many similar structures, E.G. pillars that stand in the same sector. When all the structures use the same sidedefs, you can change all structures at once by editing only one of them. Another benefit of sharing sidedefs is that it makes your wad file somewhat leaner, since the sidedef, at 30 bytes, is the largest level object.

However, sharing sidedefs makes impossible to change one structure independantly of the others. That's where the "unlink sidedef" function enters. If you select one or more linedefs and unlink their sidedefs, Yadex makes the necessary duplications so that none of the sidedefs they use is also used by any other linedef outside the selection. Thus you can edit your linedefs freely. The "unlink sidedef" operation is described in detail there.

Similarly, when you copy sectors, the linedefs, sidedefs and vertices are duplicated and the new sectors use the copies, not the original ones. Note that the `copy_linedef_reuse_sidedefs` has not effect when copying sectors; the new linedefs always use new sidedefs, even if that flag is set.

What about copying things and vertices ? Well, those don't contain references to other objects, so there are no special precautions to take when duplicating them. Except for the position, the copy is exactly identical to the original.

### 3.9. Deleting objects

To be written. There is already a concise description in the getting started document.
Basically, use [`Del`].

### 3.10. Changing the properties of objects

To be written. There is already a concise description in the getting started document.
Executive summary: use [`Return`] and double-click.

### 3.11. Moving objects a.k.a. drag-and-drop

To be written. There is already a concise description in the getting started document.

### 3.12. Renumbering objects

Normally, you don't have to worry very much about the actual numbers of the linedefs, sectors, sidedefs, things and vertices you manipulate. You just have to be careful to use the correct numbers in references but that's all. You don't need to change the number that a given object bears.

However, for certain things, the relative numbers of objects matter :

- if you have several player 1 starts in your level (which is how the voodoo doll trick is done), it's the highest-numbered one that the player incarnates in at level start,
- if there are several teleport exits in the same sector, only the lowest-numbered one is used (but I don't know of any interesting application of this fact),
- if there are several superimposed linedefs, the lowest-numbered one is drawn like it was in front,
- BSP's transparent doors need one of the door tracks to be the lowest-numbered linedef,
- certain linedef types apply only to the lowest-numbered of the tagged sectors (IIRC),
- raising stairs use the lowest-numbered linedef.

So how do you control the ordering of objects ?

#### 3.12.1. Exchanging objects numbers

This function works the same way in all modes. If you select exactly two objects and press [`Ctrl-x`] (or use "Edit->Exchange objects numbers") they exchange their numbers. That is, if the first object had number n1 and the second object had number n2, the first object in renumbered to n2 and the second one to n1. No other objects are renumbered.

At the same time the numbers are exchanged, all relevant references are fixed up. That is, if you exchange the numbers of two vertices, all the linedefs that referred to them are changed accordingly. And if you exchange the numbers of two sectors, all the sidedefs that referred to them are fixed. The thing to remember is that this function leaves the level functionally identical to what it was before, except of course for the possible side effects of the renumbering itself.

(If you wanted (for some reason I can't imagine) to exchange the numbers without fixing the references, you could do it by replacing `true` by `false` in the call to `exchange_objects_numbers()`.)

### 3.13. Selecting objects

There are several ways to select objects. The simplest is to click on an object with the left mouse button. By default, when you do that, all other previously selected objects are unselected.

If you want to select an object without unselecting everything else, do the same thing but keep [`Ctrl`] pressed while you click. You can also unselect an object this way.

You can also select several objects at a time with a selection box. You know how to draw a selection box, don't you ? Well, it works the same in Yadex. If press [`Ctrl`] while setting the first corner of the box, all objects in the box will be "toggle-selected" (that is, selected if they weren't, unselected if they were).

A more advanced way to select objects is path-selection. With path selection, you can easily select all the linedefs that form an object with a single keystroke. There are two variants of path selection.

To use the first, you must first highlight a linedef. Then press [`e`]. All the linedefs that belong to the same non-forked path as the highlighted linedef are selected. For example :

Before pressing [`e`] | After pressing [`e`]

Note how the selection stop at the first fork in the path. That kind a path selection is good to select a path of single- or double-sided linedefs that belong to the same sector.

The other variant of path selection is better to select all the linedefs that form a single pillar, even if not all of its sides face the same sector. To use it, highlight a single-sided linedef and press [`E`]. All the single-sided linedefs that belong to the same path as the original one are highlighted. For example :

Before pressing [`E`] | After pressing [`E`]

Note that the selection is not stopped by the forks in the path. Also note that the double-sided linedefs are not selected.

Like clicking, [`e`] and [`E`] have the effect of unselecting everything else that was previously selected unless you use [`Ctrl`]. If [`Ctrl`] was pressed at the time you pressed [`e`] or [`E`], all the linedefs that would have been selected if you didn't press [`Ctrl`] are either removed from the selection (if they were previously selected) or added to the selection (if they weren't). This is actually simpler than it sounds.

### 3.14. The use of [`Shift`]

The [`Shift`] key has an interesting property ; as long as you hold it down, the highlight is locked. If an object is not highlighted, it stays so even if you bring the mouse pointer over it. Likewise, if an object is already highlighted, it remains so, even if you move the pointer away from it.

This can be useful in certain occasions, such as when you want to compare two sectors that have other sectors between them.

### 3.15. Sector miscellaneous operations

Unless otherwise specified, all the operation below act on all the objects in the working set. If there is at least one selected object, the working set is equal to the selection. If there is no selected object, the working set is the currently highlighted object (the object under the pointer). If there is no selection and no highlighted object, the selection is empty, of course. If there is a selection and an object outside the selection, the latter is not part of the working set.

Find first free tag number
  Displays the smallest tag number greater than 0 and not used by any linedef or sector.
Rotate and scale sectors
  (description to be written)
Make door from sector
  (description to be written)
Make lift from sector
  (description to be written)
Distribute sector floor heights
  (description to be written)
Distribute sector ceiling heights
  (description to be written)
Raise or lower sectors...
  Prompts you for a number (N) and adds that number to the floor and ceiling heights of all the sectors in the working set. If N is positive, this results in raising the sectors by N units. If N is negative, this results in lowering the sectors by -N units.
Brighten or darken sectors...
  Prompts you for a number (N) and adds that number to the light level of all the sectors in the working set. If N is positive, this results in sectors becoming brighter. If N is positive, this results in sectors becoming darker. No light level is decreased below 0 or increased above 255.
Unlink room
  This function is not implemented yet.
Mirror horizontally
  This function starts by determining the set S of vertices that are used by the sectors in the working set. Then all the vertices in S have their x-coordinate changed so that they're "mirrored" around the vertical axis that intersects the geometric centre of S. Finally, all the linedefs whose both vertices belong to S are flipped so that the sector references remain correct.

  This function is designed to be used on either the whole level or a group of isolated sectors (like in the screenshots below). It is not recommended to use it on a group of sectors if that group is connected to other sectors. You can do it but the resulting mess might take you some time to untangle, especially if there are many connecting linedefs.

  A common use for this function is when you have a symmetrical room with, say, the same staircase on both sides of the axis of symmetry. You can build one staircase, make a copy of it, mirror the copy and paste it on the other side of the room.

  See the "Mirror horizontally" linedef function.

Mirror vertically
  This function starts by determining the set S of vertices that are used by the sectors in the working set. Then all the vertices in S have their y-coordinate changed so that they're "mirrored" around the horizontal axis that intersects the geometric centre of S. Finally, all the linedefs whose both vertices belong to S are flipped so that the sector references remain correct.

  This function is designed to be used on either the whole level or a group of isolated sectors (like in the screenshots below). It is not recommended to use it on a group of sectors if that group is connected to other sectors. You can do it but the resulting mess might take you some time to untangle, especially if there are many connecting linedefs.

  A common use for this function is when you have a symmetrical room with, say, the same staircase on both sides of the axis of symmetry. You can build one staircase, make a copy of it, mirror the copy and paste it on the other side of the room.

  See the "Mirror vertically" linedef function.

Swap flats
  For each sector in the working set, exchange the floor texture with the ceiling texture.

### 3.16. Thing miscellaneous operations

Unless otherwise specified, all the operation below act on all the objects in the working set. If there is at least one selected object, the working set is equal to the selection. If there is no selected object, the working set is the currently highlighted object (the object under the pointer). If there is no selection and no highlighted object, the selection is empty, of course. If there is a selection and an object outside the selection, the latter is not part of the working set.

Find first free tag number
  Displays the smallest tag number greater than 0 and not used by any linedef or sector.
Rotate and scale things
  (description to be written)
Spin things 45° clockwise
  Subtract 45 to the angle of all the things in the working set. This is not to be confused with "Rotate and scale things" where it's the position of the things that is changed.
Spin things 45° counter-clockwise
  Add 45 to the angle of all the things in the working set. This is not to be confused with "Rotate and scale things" where it's the position of the things that is changed.
Mirror horizontally
  All the things in the working set have their x-coordinate changed so that they're "mirrored" around the horizontal axis that intersects the geometric centre of the things in the working set. Their angle is also adjusted.

  It is not possible to mirror things without changing their angle (short of commenting out a couple of lines in `x_mirror.cc` and recompiling, of course).

Mirror vertically
  All the things in the working set have their y-coordinate changed so that they're "mirrored" around the horizontal axis that intersects the geometric centre of the things in the working set. Their angle is also adjusted.

  It is not possible to mirror things without changing their angle (short of commenting out a couple of lines in `x_mirror.cc` and recompiling, of course).

### 3.17. Setting/toggling/clearing thing flags

In things mode, press [`a`] to open the "set thing flags" popup menu.
Press [`b`] to open the "toggle thing flags" popup menu.
Press [`c`] to open the "clear thing flags" popup menu.

### 3.18. Vertex miscellaneous operations

Unless otherwise specified, all the operation below act on all the objects in the working set. If there is at least one selected object, the working set is equal to the selection. If there is no selected object, the working set is the currently highlighted object (the object under the pointer). If there is no selection and no highlighted object, the selection is empty, of course. If there is a selection and an object outside the selection, the latter is not part of the working set.

Find first free tag number
  Displays the smallest tag number greater than 0 and not used by any linedef or sector.
Rotate and scale vertices
  (description to be written)
Delete vertex and join linedefs
  (description to be written)
Merge several vertices into one
  (description to be written)
Add a linedef and split sector
  To perform this operation, you must have exactly two vertices in the working set and there must be an uninterrupted path of linedefs that face a common sector between them. A new linedef is inserted from the first vertex to the second. The newly created sector is put on the left side of the new linedef.
Mirror horizontally
  All the vertices in the working set have their x-coordinate changed so that they're "mirrored" around the vertical axis that intersects the geometric centre of the selected vertices. Then all the linedefs whose both vertices belong to the group of selected vertices are flipped so that the sector references remain correct.

  See the "Mirror horizontally" linedef function.

Mirror vertically
  All the vertices in the working set have their y-coordinate changed so that they're "mirrored" around the horizontal axis that intersects the geometric centre of the the selected vertices. Then all the linedefs whose both vertices belong to the group of selected vertices are flipped so that the sector references remain correct.

  See the "Mirror vertically" linedef function.

### 3.19. Linedef miscellaneous operations

Unless otherwise specified, all the operation below act on all the objects in the working set. If there is at least one selected object, the working set is equal to the selection. If there is no selected object, the working set is the currently highlighted object (the object under the pointer). If there is no selection and no highlighted object, the selection is empty, of course. If there is a selection and an object outside the selection, the latter is not part of the working set.

Find first free tag number
  Displays the smallest tag number greater than 0 and not used by any linedef or sector.
Rotate and scale LD & SD...
  (description to be written)
Split linedefs (add new vertex)
  Split all linedefs in the working set, by adding a vertex in the middle.

  The key [`x`] is a shortcut to this function.

Split linedefs and sector
  Split both linedefs in the working set in the middle by adding a vertex for each, create a linedef between the two new vertices and split the sector with this new linedef. There must be exactly 2 linedefs in the working set and they must face a common sector.

  The new linedef goes from the first linedef in the working set to the second linedef in the working set. The new sector is on the second sidedef of the new linedef.

  There is a bug in this function ; if the sector contains other sectors, some sidedefs are given the wrong sector number. Jim Flynn has recently fixed this in DETH. Anyone to look into it ?

  The key [`w`] is a shortcut to this function.

Delete linedefs and join sector
  (description to be written)
Flip linedefs
  The start and end vertices of the linedefs in the working set are swapped. Their sidedefs are also swapped, so that the sector references remain correct.

  If you want to flip linedefs without swapping their sidedefs, you have to use "Flip linedefs" then "Swap sidedefs" on them.

Swap sidedefs
  Swap the sidedefs of the linedefs in the working set without flipping the linedefs. This means that the sector references are also swapped. If you don't understand what this implies, don't use this function.
Align textures (Y offset)
  This function is buggy.
Align textures (X offset)
  This function is buggy.
Remove 2nd sidedef (make single-sided)
  When two superimposed linedefs are merged, the result is often a two-sided linedefs, even though the second sidedef faces no sector. Use this function to fix the mess.

  It sets the I flag, clears the 2 flag, sets the second sidedef to -1, clears the upper and lower texture and resets the middle texture to the default (as defined in the preferences).

Make rectangular nook (32x16)
  This is a single-key function to make a rectangular nook in the middle of a linedef. "Nook" means that, seen from the first side of the original linedef, the resulting 5 linedefs form a concave figure.

  If the linedef is not long enough, the length of the nook is one third of the length of the linedef.

  Before | After

Make rectangular boss (32x16)
  Same thing as "Make rectangular nook" but the resulting figure is convex.
Set length (move 1st vertex)
  Prompts you for a length and moves the 1st vertex of the linedefs in the working set so that they have the length you specified.
Set length (move 2nd vertex)
  Same thing as "Set length (move 1st vertex) but moves the 2nd vertex.
Unlink 1st sidedef
  This function is used when you have several linedefs sharing common sidedefs and you don't want them to share any sidedefs anymore so that you can, for instance, change the sector reference or texture of one of the linedefs independently from the others.

  Here is how it works : all sidedefs that are used on the first side of any linedef in the working set and on any side of any linedef not in the working set are duplicated and the first side of the concerned linedefs in the working set is set to use the copy instead of the original.

  Gotcha : note that the linedefs in the working set are not "unlinked" from each other. They are only "unlinked" from any other (i.e. not in the working set) linedefs. Thus, if you have n linedefs that you want to unlink from each other, you have to unlink every one of them separately. This is so that, if you have, say, two square pillars (2 x 4 linedefs that all use the same sidedef), you can easily unlink one pillar from the other while still having its 4 linedefs all use the same sidedef.

Unlink 2nd sidedef
  Same as "Unlink 1st sidedef" but with second sidedef instead of first sidedef.
Mirror horizontally

  This function starts by determining the set S of vertices that are used by any of the linedefs in the working set. Then all the vertices in S have their x-coordinate changed so that they're "mirrored" around the vertical axis that intersects the geometric centre of S. Finally, all the linedefs whose both vertices belong to S are flipped so that the sector references remain correct.

  Before | After

  This function is designed to be used on either the whole level or a group of isolated linedefs (like in the screenshots below). It is not recommended to use it on a group of linedefs if that group is connected to other linedefs. You can do it but the resulting mess might take you some time to untangle, especially if there are many connecting linedefs.

  A common use for this function is when you have a symmetrical room with, say, the same staircase on both sides of the axis of symmetry. You can build one staircase, make a copy of it, mirror the copy and paste it on the other side of the room.

Mirror vertically

  This function starts by determining the set S of vertices that are used by any of the linedefs in the working set. Then all the vertices in S have their y-coordinate changed so that they're "mirrored" around the horizontal axis that intersects the geometric centre of S. Finally, all the linedefs whose both vertices belong to S are flipped so that the sector references remain correct.

  Before | After

  This function is designed to be used on either the whole level or a group of isolated linedefs (like in the screenshots below). It is not recommended to use it on a group of linedefs if that group is connected to other linedefs. You can do it but the resulting mess might take you some time to untangle, especially if there are many connecting linedefs.

  A common use for this function is when you have a symmetrical room with, say, the same staircase on both sides of the axis of symmetry. You can build one staircase, make a copy of it, mirror the copy and paste it on the other side of the room.

Cut a slice out of a sector

  You must select exactly two linedefs that face the same sector S. This function creates a linedef A that goes from the first selected linedef to the second and a linedef B that goes from the second to the first. A new sector is created between those four linedefs, with attributes identical to those of S.

  Before | After

  This function is somewhat similar to "split-linedefs-and-sector" except that it creates two linedefs instead of one and that it works on doughnut-shaped sectors. In fact, this function is the only one that can split a sector when there is no linedef path between the split points (which is the case when splitting a doughnut-shaped sector between its inner and outer borders).

  If there is a linedef path between the selected linedefs, this function is equivalent to using "add-linedefs-and-split-sector" twice, except that you end up with two sectors, not three. FIXME - need a figure.

  If the selected linedefs happen to share a vertex, only one linedef is created and the new sector is triangular. The linedefs must not be the same or superimposed. FIXME - need a figure.

  Linedefs A and B are created with all their attributes set to zero and their middle textures set to "`-`". They're oriented so that their right sidedefs face the new sector. Linedef A is the lowest-numbered one.

  The following restrictions apply :

  - selected linedefs must not have two sidedefs in the same sector,
  - selected linedefs must not share more than one sector,
  - there must be no linedef that would be superimposed with A or B.

  These restrictions are stricter than necessary. They may be lifted in the future if time and brain power permit.

  Because this function is not aware of the geometry of the selected linedefs, but only of the sectors they face, it can be used to split sectors in impossible ways. FIXME - need a figure.

  This function assumes the space between the selected linedefs is empty. If there are any other linedefs there, you will have to fix their sector references manually afterwards.

  The key [`Ctrl-k`] is a shortcut to this function.

### 3.20. Setting/toggling/clearing linedef flags

In linedefs mode, press [`a`] to open the "set linedef flags" popup menu.
Press [`b`] to open the "toggle linedef flags" popup menu.
Press [`c`] to open the "clear linedef flags" popup menu.

### 3.21. Undoing

As of this release, undoing is not implemented.

### 3.22. Cut-and-paste from one level to another

As of this release, it's not possible.

### 3.23. Using the flat/patch/sprite/texture viewer

Flats, patches, sprites and textures are browsed and selected with the same basic tool, snappily named the flat/patch/sprite/texture viewer. How do you use that beast ?

You can change the current name simply by typing it. Use [`Backspace`] to erase the rightmost character. As you type, the list of names scrolls automatically so that the first line of the list shows the first valid name that begins with the characters in the entry box. If the current name does not belong to the list, it is grayed out and you can't validate. If it does, the corresponding image is shown in the box to the right.

As in certain Unix programs, [`Tab`] is used for name completion. If the current name is "`SW1`" and you press [`Tab`], the current name is set to the first name that begins with "`SW1`".

[`Ctrl-u`] and [`Ctrl-w`] clear the current name, like pressing [`Backspace`] repeatedly would.

You can also move through the list without typing names :

- [`Up`] and [`Down`] move to the previous or next name in the list.
- [`Pgup`] and [`Pgdn`] move one page at a time.
- [`Home`] and [`End`] move you to the first or last name of the list.
- [`Ctrl-b`] does the same thing as [`Pgup`].
- [`Ctrl-f`] and [`Ctrl-v`] do the same thing as [`Pgdn`].

To validate the current name as your choice, press [`Return`]. If the current name is grayed-out (invalid), [`Return`] does not work. To cancel, press [`Esc`].

[`Shift-F1`] saves the current image to file, in packed PPM (`P6`) format. This can be useful for textures, that cannot be directly extracted from wads. Transparent areas are represented according to the DeuTex convention by colour rgb:0/2f/2f (). The file is created in the working directory and its name is the name of the image lowercased and suffixed by "`.ppm`". For example, flat "`FLOOR0_7`" would be saved as "`./floor0_7.ppm`". If the file already exists, it's mercilessly overwritten.

Note that under MS-DOS, newlines in the PPM header are in Unix format (LF, not CR LF).

There are a few bugs left in this function. Textures are clipped to the dimension of the viewer window. Under MS-DOS, some "`VILE*`" sprites will not save, because their names contain characters that are not allowed in file names ("`[`", "`\`" and "`]`").

[`F1`] prints to stdout the location (file name and offset) of the current flat, patch or sprite. For debugging purposes.

When viewing textures, you may press [`Ctrl-a`] and [`Ctrl-x`] to cycle through the patches that make up the texture.

Finally when viewing sprites, two other useful commands are [`Ctrl-n`] and [`Ctrl-p`]. These go respectively to the next and previous group of sprites (all sprites that have the same first 4 letters belong to the same group). It's handy to skip the 69 animation frames of the heavy weapon dude at once.

### 3.24. Saving

There are two ways to save :

- Press [`F2`] or do "File->Save". If the level comes from the iwad or if its level name or file name is unknown (because it's a new level), you are prompted for a level name (EnMn or MAPnm) and a file name first. If the file name has changed since the last time you saved, and if a file of that name already exists, you are asked confirmation before saving.

  The level in the window is saved in the specified file, in the pwad format, under the specified .

- Press [`F3`] or do "File->Save as". This procedure is identical to the "Save" procedure except that the query for a level name and file name is unconditional.

FIXME -- this needs to be written...

If Yadex is in Hexen mode, saving is disabled because writing levels in the Hexen format is not supported as of this release.

### 3.25. Closing a window

There are two ways to close a window :

- Press [`Esc`]. If you have made changes since the last time you saved, or if you have never saved, Yadex requires confirmation before closing the window.

- Press [`q`] or do "File->Quit". If you have made changes since the last time you saved, or if you have never saved, Yadex first saves the level, using the same procedure as when you press [`F2`]. After that the window is closed. If the saving procedure is interactive (for example because it's the first time you save), and if you cancel it, the window is not closed.

## 4. Variables and configuration

Yadex has internal variables that serve to configure its behaviour. Variables have a name (a string of letters, digits and underscores), a type and a value. The type constraints the value (boolean, integer, strings, etc.).

Variables can be set in four ways :

- from the Preferences menu,
- from the command line,
- through environment variables.
- from the configuration files,

The settings from the Preferences menu override those from the command line options which in turn override those from the environment variables which in turn override those from the configuration files.

### 4.1. Variables

You can get a list of variables with their description and value by typing `set` at the `yadex:` prompt.

#### 4.1.1. The font

By default, Yadex uses the default font of your system (that is often "`fixed`" a.k.a. "`6x13`"). But you can use the font of your choice by using the "`-fn` font_name" option or setting "`font =` font_name" in `yadex.cfg`. You should use a fixed-width font and not one that is too large for the size of your Yadex window or the display will look ugly. If Yadex does not find the specified font, it emits a warning and falls back on the default system font.

You can get a list of all available fonts on your system with the command `xlsfonts`.

#### 4.1.2. Mouse wheel and other mouse issues

The 3rd mouse button (middle button) is not used yet but you can bet it will a future version. So a 3-button mouse is of course recommended.

You can swap the left and right buttons by setting the `swap_buttons` variable.

Buttons 4 and 5 are used for zooming in and out. Wheel mice typically have the wheel mapped to buttons 4 and 5 in such a way that when you roll the wheel "up" (forwards), button4 press events are generated and when you roll the wheel "down" (backwards), button5 press events are generated.

To configure your X server in the way described above, check the vendor documentation. I have XFree86 and a Logitech Pilot Mouse + and this is what I put in my `XF86Config` file :

>     Section "Pointer"
>         Protocol      "Intellimouse"
>         Device        "/dev/mouse"
>         Buttons       5
>         ZAxisMapping  4 5

### 4.2. Preferences

When you create objects, their properties are automatically given default values. Some of those default values can be set from the configuration file or from the command line but also through the Preferences menu, that pops up when you press [`F5`].

The Preferences menu lets you set the `default_*` variables interactively. The settings made from the Preferences menu are lost when you exit Yadex.

### 4.3. Command line

See the Options section.

### 4.4. Environment variables

See the Environment variables section.

### 4.5. Configuration files

#### 4.5.1. Contents of configuration files

Configuration files are text files. White space at the beginning of a line is ignored. There are three kinds of lines :

Empty lines (lines containing only white space)

  No effect.

Comments (lines whose first non white space character is a `#`)

  No effect.

Variable assignments (lines of the form "name `=` value")

  The effect is to assign value to the variable name. name is a string of one or more identifier characters i.e. letters, digits and underscores. value is a string of zero or more non white space characters. There may be any amount of white space around and between the three tokens, including none at all.

  Please note that :

  - `#` is special only at the beginning of a line. Therefore you can't put a comment on the same line as a variable assignment.

  - Because white space is a token delimiter and there's no way to quote or escape it, including white space in a value is impossible.

  - Yadex's idea of what is a letter or digit is deliberately locale-independent. Whether it's white space or not, on the other hand, is locale-dependent (`isspace`(3)).

Parse errors are not fatal. In general, they cause a warning message to be printed and the entire line to be ignored. This is to facilitate the sharing of configuration files across versions of Yadex.

The configuration file is self-documenting. Look at the sample configuration file in the Yadex distribution to see what options are available.

#### 4.5.2. Locating configuration files

This is the process by which Yadex turns a configuration file name into one or more actual pathnames.

If the specified name is absolute, the location yields exactly that. A name is considered absolute if and only if it begins with a `/`.

If the specified name is relative, Yadex uses a search path, much like the shell uses `$PATH` to locate commands. The composition of the search path depends on the installation prefix (the argument to `./configure --prefix`).

`/usr/local` or `/usr` :
  1. `.`
  2. `~/.yadex/1.7.0`
  3. `~/.yadex`
  4. `/etc/yadex/1.7.0`
  5. `/etc/yadex`
`/opt/some/path` :
  1. `.`
  2. `~/.yadex/1.7.0`
  3. `~/.yadex`
  4. `/etc/opt/some/path`
`/some/path` :
  1. `.`
  2. `~/.yadex/1.7.0`
  3. `~/.yadex`
  4. `/some/path/etc`

The search path may be walked in either direction, depending on the application. For each element in the search path, a pathname is made by concatenating the path and the specified name. The pathname is tested with `stat`(2). The result of the location is the list of the pathnames that exist and are not directories.

For example, assuming Yadex was compiled with the `/usr/local` prefix, a front-to-back search for a file named `foo/bar.cfg` would return those of the following pathnames that exist and are not directories :

1. `./foo/bar.cfg`
2. `~/.yadex/1.7.0/foo/bar.cfg`
3. `~/.yadex/foo/bar.cfg`
4. `/etc/yadex/1.7.0/foo/bar.cfg`
5. `/etc/yadex/foo/bar.cfg`

#### 4.5.3. Default configuration files

By default, Yadex performs a back-to-front search for files named `yadex.cfg` and reads all the matches in order. For example, assuming Yadex was compiled with the `/usr/local` prefix, the following configuration files will be read if they exist :

1. `/etc/yadex/yadex.cfg`
2. `/etc/yadex/1.7.0/yadex.cfg`
3. `~/.yadex/yadex.cfg`
4. `~/.yadex/1.7.0/yadex.cfg`
5. `./yadex.cfg`

Because the search path is walked back-to-front, any parameter settings in a local configuration file override the settings inherited from less local configuration files. For example, assuming `/etc/yadex/1.7.0/yadex.cfg` contains :

> `a = old
> b = old`

and `./yadex.cfg` contains :

> `a = new
> c = new`

the net effect is :

> `a = new
> b = old
> c = new`

#### 4.5.4. User-specified configuration files

The `-f` option can be used to override Yadex's default choice of configuration files.

If Yadex is started with the `-f` option, the default configuration files are not used. Instead, Yadex performs a front-to-back search for the argument of the `-f` option, according to the algorithm described in Locating configuration files. The first match is used as a configuration file. Any other matches are ignored.

For example, assuming Yadex was built with the `/usr/local` prefix and run with the `-f myown.cfg` option, it will use the first file in this list that exists and is not a directory :

1. `./myown.cfg`
2. `~/.yadex/1.7.0/myown.cfg`
3. `~/.yadex/myown.cfg`
4. `/etc/yadex/1.7.0/myown.cfg`
5. `/etc/yadex/myown.cfg`

#### 4.5.5. Organising your configuration files

As Yadex looks for its configuration files in several places, you are put in the situation of having to decide which one to use. Here are a few guidelines to help you make a decision.

Avoid redundancy

  Take advantage of Yadex's ability to use more than one config file. Put each setting in the right place. Your config files will be easier to read and maintain.

Versionless vs. versionful files

  Versionful files (`/etc/yadex/1.7.0/yadex.cfg` and `~/.yadex/1.7.0/yadex.cfg`) are useful to store settings that only work with a particular version of Yadex. But remember that the versionful system-wide file can be clobbered by a reinstallation.

  Versionless files (`/etc/yadex/yadex.cfg` and `~/.yadex/yadex.cfg`) have the advantage of being seen by all versions of Yadex. If you enter your settings there, you won't have to enter them again when you install a new version of Yadex, as long as the config file syntax remains compatible.

System-wide vs. user vs. local files

  System-wide configuration files have the theoretical advantage of being seen by all users, which makes them a good place to put settings that apply to everybody, such as the pathnames of the iwads. Of course, it doesn't make any difference for the typical (single-user) Yadex installation.

  Per-user files (the ones in `~/.yadex`) are appropriate for settings that have to do with personal preferences (fonts etc.). They also have the advantage over system-wide files of not being overwritten by the installation procedure (typing `make install` a second time will wipe the versionful system file).

  Local files (`./yadex.cfg`) are well suited to settings that vary from project to project, such as default textures.

Concrete application : Yadex was compiled with `/usr/local` as the prefix. You are the only user on your system. All your levels are for Doom 2, except the one in `~/herewad` which is for Heretic. One of your Doom 2 levels (`~/cave`) is quite dark and requires a different default light level. You usually run Yadex from the directory where the pwad is.

There are several ways to configure Yadex for this setup. Here's a solution in accordance with the above guidelines :

`~/.yadex/yadex.cfg` :

>     iwad2 = /somewhere/doom2.wad
>     iwad3 = /somewhere/else/heretic.wad
>     game  = doom2

`~/herewad/yadex.cfg` :

>     game                    = heretic
>     default_floor_texture   = floor11
>     default_ceiling_texture = floor06
>     default_lower_texture   = sandsq2
>     default_middle_texture  = sandsq2
>     default_upper_texture   = sandsq2
>     default_thing           = 66

`~/cave/yadex.cfg` :

>     default_light_level = 112

Note how `game` is set in the per-user config file (the general case) and overridden in the local config file for Heretic level (the exception).

## 5. Game definition files

Most of Yadex's knowledge about thing numbers and names, linedef types etc. is retrieved from so-called game definition files. When you specify "`-g foo`", it in fact means that Yadex should use the game definition file named "`foo.ygd`".

### 5.1. Contents of game definition files

For Yadex to recognize the file as a game definition file, it must begin with a certain magic string. If it doesn't, Yadex will print an error message an bail out. The reason for being so fussy is to avoid headaches when the game definition file format changes and there are old game definition files lying around in your directories.

Game definition files are not supposed to be modified in normal use. Their format is described in `ygd.html`.

### 5.2. Locating game definition files

The algorithm used to locate game definition files is exactly the same as the one described in Locating configuration files. Only the search path is different. As is the case for config files, it depends on the prefix for which Yadex was compiled.

`/usr` :
  1. `.`
  2. `~/.yadex/1.7.0`
  3. `~/.yadex`
  4. `/usr/share/games/yadex/1.7.0`
  5. `/usr/share/games/yadex`
`/usr/local` :
  1. `.`
  2. `~/.yadex/1.7.0`
  3. `~/.yadex`
  4. `/usr/local/share/games/yadex/1.7.0`
  5. `/usr/local/share/games/yadex`
`/opt/some/path` :
  1. `.`
  2. `~/.yadex/1.7.0`
  3. `~/.yadex`
  4. `/opt/some/path/share`
`/some/path` :
  1. `.`
  2. `~/.yadex/1.7.0`
  3. `~/.yadex`
  4. `/some/path/share`

### 5.3. Use of game definition files

On startup, Yadex loads the game definition file corresponding to the `game` variable. It performs a front-to-back search (see Locating game definition files) for a file named `game.ygd`. The first match is used.

## 6. Known bugs

Though Yadex has quite a few bugs, most of them are inconsequential, i.e. not likely to make Yadex unusable or damage precious data. On the other hand, some can bite. Those are the ones you should know about :

- Command line options that take an argument need to have a space between their argument and themselves.

- Exposure events are not always handled. If the Yadex window turns black, back out by pressing [`Esc`], several times if necessary.

- If you edit a level from a file that contains several and save it, all the other levels, textures, flats, etc. from that file are lost.

- Out-of-memory conditions and certain wad I/O errors are handled in a very ungraceful manner. Basically, Yadex aborts and if you haven't saved, you've lost all your work. My advice :

  - Make sure you have at least a couple of megs of free memory.
  - Save often and make backups.
  - Don't use wads that contain errors.
  - Make sure you have enough disk space and adequate permissions.
  - Don't modify files with an external program while Yadex uses them. For example, if you use a texture wad, don't rebuild it without quitting Yadex first.

Check `TODO` for a complete list of things to fix.

## 7. Supported games

### 7.1. Doom

Supported. Linedef types and sector types added in v. 1.666 are supported and marked with "`[v1.6]`".

### 7.2. Doom II

Supported.

### 7.3. Doom alpha

Mostly supported. There are three Doom alpha versions that I know of : 0.2, 0.4 and 0.5. They're supported to varying degrees of completeness. All graphics resources (flats, patches, `PLAYPAL`, sprites and textures) are supported for all versions with the exception of version 0.2, for which textures are not supported.

Reading levels does not work either for version 0.2. For version 0.4 and 0.5, it works, including levels `E1M10` through `E1M13`. There are some oddities in the levels, such as linedefs with negative types or things with strange bits set in their flags, but I don't think it's Yadex's fault.

You can edit and save alpha levels but they will be saved in the regular Doom format, not the alpha format. Writing levels in the Doom alpha format is not supported at all and probably never will, for three reasons. Firstly, there are parts of the format that I don't understand, and therefore don't know how to generate. Secondly, there is AFAIK no nodes builder for the alphas. Thirdly, even if the two above problems were solved, I don't expect many people to actually want to use the alphas because, from a player point of view, they're much less comfortable than the later versions of Doom. To say nothing of the fact that all we have is a DOS executable and no source code. That being said, I can't deny that it would indeed be cool to be able to generate wads for the alphas, if only for the fun of it. If you want to do it, I won't discourage you and I will gladly accept patches.

### 7.4. Doom press release pre-beta

Supported. The different picture format is handled. Things type 2016 (evil sceptre) and 2017 (unholy bible) are defined in `doom02.ygd`, `doom04.ygd`, `doom05.ygd`, `doompr.ygd`, `doom.ygd` and `doom2.ygd` and marked with "`[PR]`". However, if you're using `betalevl.wad` and `betagrph.wad` supplied with MBF, you won't see the corresponding sprites because Yadex does not support sprites in pwads (yet). To see the sprites for the evil sceptre and the unholy bible as well as the alternate versions of the other sprites, you need to use the iwad from `doomprbt.zip`.

### 7.5. Final Doom

Supported, AFAIK. The iwads have no `F1_START/F1_END` labels and some levels contain a thing of type 0 which made older versions of Yadex crash. This has been fixed in version 1.1.0.

### 7.6. Heretic

Supported.

### 7.7. Hexen

Very rudimentary support. You can load Hexen wads and edit the maps but most of Hexen's special features are stripped off on reading. So don't try to save a Hexen level after editing it, you won't be able to use it with Hexen. And if you're saving it to the file it comes from, you'll lose your file. Don't save when in Hexen mode.. Here's the breakdown :

- Most thing types, and some sector and linedef types are missing from `hexen.ygd`.
- For things, `tid`, `z`, `special` and `arg1` through `arg5` are discarded. There is currently no way to examine or manipulate them from Yadex.
- For linedefs, `arg1` is put into `tag`. `arg2` through `arg5` are discarded and there is currently no way to examine or manipulate them from Yadex.
- The Hexen-specific thing and linedef flags are not recognized (but you can manipulate them).
- `BEHAVIOR` is ignored.
- `MAPINFO` is ignored.

### 7.8. Strife

Supported, except that :

- many thing types are missing,
- some thing flags are not known,
- many linedef types are missing or wrong,
- some linedef flags might be missing,
- some sector types might be missing.

And perhaps other things as well. If you're a Strife hacker, your help would be welcome.

If you have Strife 1.0, you should use `-g strife10`. Strife 1.0 uses the same format as Doom for textures, Strife 1.1 and later use a different format.

### 7.9. Ultimate Doom

Supported.

### 7.10. Boom

Kind of supported, only very inconvenient to use <g>.

New linedef flag "P" (pass through)
  Supported.
New linedef types
  You can enter arbitrary linedef types ("enter number").
New sector types
  You can enter arbitrary sector types ("enter number")
New things flags "N" (not in deathmatch) and "C" (not in coop)
  Supported.
New things types 5001 and 5002
  Supported.
Special lumps `SWITCHES` and `ANIMATED`
  Unsupported.

In progress...

### 7.11. EDGE

The default DDF definitions included in EDGE 1.24 have been added to `doom.ygd` and `doom2.ygd`, marked with "`[EDGE]`". When the pointer moves over a sector that has extrafloors, the object info window shows the information relevant to those. To see the sprite for the night vision goggles (thing #7000), you must load `edge.wad`.

As of 1.5.0, the support for DDF is static : custom DDF files or DDF lumps are ignored. In other words, you are limited to the default DDF definitions.

### 7.12. MBF

Mostly supported, I think. Thing 888 (dog), thing flag 80h (friendly), linedef types 271 and 272 are all in. You can't see the sprite for the dog because it's embedded in the MBF executable.

### 7.13. Other derivatives

Not supported so far.

AYM 2003-03-31