Fancy logo
Yadex 1.7.0 (2008-02-08)

User's guide

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



Contents :


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

More specifically, Yadex expects that

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 ;

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.

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 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 :

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]
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]
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
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
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
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
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 :

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 ?

Browsing flats

Browsing sprites

Browsing textures

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 :

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 (Swatch). 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 :

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 :


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 :

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 :

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 :

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 :

7.8. Strife

Supported, except that :

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