Hexen - Editing
This section deals with Hexen-specific, vanilla map parameters, ACS scripting and related editing topics as a supplement to the official Hexen specs; basic Doom-engine editing principles are not covered. ZDoom scripting also will not be covered here except in cases where differences may cause confusion.
NB: The BEHAVIOR section of a map is required for vanilla Hexen maps. If you really don't want any scripts, you can place a dummy script that does nothing, but BEHAVIOR has to be there or the map will fail to load correctly.
Displaying Strings [top]
Strings to be displayed by Print or PrintBold in vanilla Hexen should be given in ALL CAPS (the Hexen font uses lowercase letters only, so the in-game message will appear in lowercase.) Using lowercase may produce a garbled message in some instances, particularly map titles; it is a ZDoomism.
Special Boss Setup [top]
Some of the bosses require special settings to function properly.
There is just one gotcha when setting up a Heresiarch. Instead of the normal action special with arguments, special actions to be performed upon his death should instead be invoked by putting a script number where you would normally put the number of the action special, and leaving the arguments at zero. This script will be run when the Heresiarch is killed. This is because the Heresiarch's internal AI code puts its own values in the argument slots.
The death wyvern is the most finicky boss to set up. If you do it improperly, you can end up with the wyvern being stuck in place and emitting a continuous, annoying scream, or even worse, the game could hang.
Death wyvern essentials:
- The death wyvern itself. It requires a TID and can be given any action special you want.
- A thing with an identical TID to the wyvern, requiring arguments containing the TID(s) at least one waypoint. It need not be a map spot (Hypostyle uses an ettin).
- Map spots that serve as waypoints. Each should have a unique TID and arguments containing the TID(s) of at least one other waypoint.
A very basic setup would be:
- Death Wyvern: TID = 1, Special/Arguments can be any reasonable action to execute upon wyvern's death
- Map Spot: TID = 1, Special = 0, Arg1 = 2, Arg2 = 3
- Map Spot: TID = 2, Special = 0, Arg1 = 3
- Map Spot: TID = 3, Special = 0, Arg1 = 2
With this setup, the wyvern will behave as follows: upon waking, fly to the map spot with TID 1 (since that one matches the Wyvern's own). According to the args on this map spot, randomly choose between the map spot with TID 2 or the one with TID 3 and fly there. The wyvern will then continuously patrol back and forth between map spot 2 and map spot 3 until slain.
The wyvern swoops around in arcs when changing direction but will try to head for the exact position of its target map spot, taking into account its Z height setting as well, you can control its general altitude along the path. Another interesting thing to note: you can make a waypoint map spot reference its own TID as one of the arguments. When following this destination, the wyvern will circle around and back to that spot (may only work for spots that reference solely themselves, not 100% sure).
In addition to thing setup, the death wyvern requires some careful testing and preparation of its area to ensure that it will not get stuck, as it has no awareness of walls in its navigation. Make sure that the path between any two linked waypoints is clear with enough space to spare to account for the swooping movements.
NB: The official specs, and by extension map editing utilities based on them, may erroneously lead you to believe that the map spot destination numbers should be placed in the arguments of the wyvern itself. That is a mistake which will at best result in the arguments being ignored (if you gave the wyvern a TID and a first destination with matching TID) and at worst leave you with a stuck wyvern.
Korax Korax expects there to be a few special scripts and map settings as well, but unlike the death wyvern he won't totally break down without them. However, lack of the scripts will cause error messages to appear at the top of the screen and make things look sloppy to the player, so it behooves you to provide them (plus, it offers many opportunities to give the battle more "oomph", though if you REALLY don't want them you can always provide dummy scripts in those slots just to silence the errors).
The script numbers used are:
- 249: Run when Korax is injured to below 50% HP.
- 250: Randomly invoked battle script.
- 251: Randomly invoked battle script.
- 252: Randomly invoked battle script.
- 253: Randomly invoked battle script.
- 254: Randomly invoked battle script used only after Korax is below half health.
- 255: Run when Korax is slain.
As with ACS in general, the battle scripts can be used for a variety of effects; the Dark Crucible is set up for such things as setting off traps, calling minions, and altering the battle field. When Korax performs the "attack" where he raises his fist and sends a lightning bolt to the ceiling, a battle script will be invoked. Unfortunately, a well-equipped and skilled player allowed to get near to Korax can often kill him before he gets a chance to do much with these scripts.
Korax is also capable of teleporting himself. There are no adverse effects to not setting this up, but again, it can help add challenge and interest to the fight. Korax will only teleport once his health is below 50%. Once at this point, he can randomly choose from any map spots given a TID of 249 and teleport to one of them.
The following objects can be spawned by script and by the destruction of certain items. DEFS.ACS (included via COMMON.ACS) gives names to them for when you are spawning via script, but for appearing out of breakable objects you can only refer to them by number. The names are generally meant to be easy mnemonics for the object spawned, but some of them are a bit obscure. Spawned objects in vanilla Hexen cannot be assigned TIDs. This is particularly significant for the "thrust spike" objects which can be spawned, but not subsequently activated/deactivated.
In scripts, these things can be created using the Thing_Spawn, Thing_SpawnNoFog, Thing_Projectile and Thing_ProjectileGravity functions. The number of a particular type of thing currently on the map can also be retrieved using the thingcount function.
You may also place any of these spawnable objects inside certain breakable scenery. To have an item spawn out of a breakable object (pots, decorative armor), you should leave the breakable object's special at 0 but set its first argument to the spawn number of the item you want it to contain. Certain objects do not behave logically when spawned this way; for instance, projectiles (such as those listed here in the "trap" category), will hang inertly in place and cannot cause damage. Objects that have a significant angle property (e.g. monsters) will spawn facing east.
The pairs 66/97 and 67/99 (permanent small flames and permanent large flames) are redundant spawn numbers. 66 and 97 both spawn the same permanent small flame, while 67 and 99 both spawn the same permanent large flame (thanks Gez). Use whichever one you prefer, but ideally pick one or the other and be consistent about it.
The pair of sapphire planets, and the pair of emerald planets, are not interchangeable despite looking identical, and there are actually separate sprite entries for each of them. Puzzle slots will demand a particular sapphire or emerald and won't accept the other one.
The phantom "mash" monsters are special versions of certain normal monsters that are translucent and do not leave corpses when killed. In the core levels, they appear only while fighting Korax, and are spawned by one of his battle scripts.
Using out-of-bounds spawn numbers is NOT recommended. It might spawn something, but is unlikely to be consistent across varying ports (even vanilla vs. chocolate). The defined numbers range from 0 to 108. Things that do not appear in this table cannot be spawned without port extensions; notably, the Firestorm and Arc of Death weapons do not have spawn numbers, and many monster projectiles cannot be fired from scripted traps.
|Green Chaos Serpent||T_DEMON||3||Enemy|
|Lava ball projectile||T_FIREBALL1||10||Trap|
|Boots of Speed||T_ITEMBOOTS||13||Item|
|Wings of Wrath||T_ITEMFLIGHT||15||Item|
|Krater of Might||T_ITEMBOOSTMANA||26||Item|
|Hammer of Retribution||T_FIGHTERHAMMER||28||Item|
|Segment of Quietus (1)||T_FIGHTERSWORD1||29||Item|
|Segment of Quietus (2)||T_FIGHTERSWORD2||30||Item|
|Segment of Quietus (3)||T_FIGHTERSWORD3||31||Item|
|Segment of Wraithverge (1)||T_CLERICHOLY1||33||Item|
|Segment of Wraithverge (2)||T_CLERICHOLY2||34||Item|
|Segment of Wraithverge (3)||T_CLERICHOLY3||35||Item|
|Segment of Bloodscourge (1)||T_MAGESTAFF1||37||Item|
|Segment of Bloodscourge (2)||T_MAGESTAFF2||38||Item|
|Segment of Bloodscourge (3)||T_MAGESTAFF3||39||Item|
|Porkalator trap projectile||T_MORPHBLAST||40||Trap|
|Grey rubble (larger)||T_ROCK1||41||Effects|
|Grey rubble (medium)||T_ROCK2||42||Effects|
|Grey rubble (smaller)||T_ROCK3||43||Effects|
|Brown clod with green specks (1)||T_DIRT1||44||Effects|
|Brown clod with green specks (2)||T_DIRT2||45||Effects|
|Brown clod with green specks (3)||T_DIRT3||46||Effects|
|Small grey pebble||T_DIRT4||47||Effects|
|Arrow trap projectile||T_ARROW||50||Trap|
|Dart trap projectile||T_DART||51||Trap|
|Dart trap projectile (poisoned)||T_POISONDART||52||Trap|
|Spiked ball projectile||T_RIPPERBALL||53||Trap|
|Blue glass shard||T_STAINEDGLASS1||54||Effects|
|Yellow glass shard||T_STAINEDGLASS2||55||Effects|
|Purple glass shard||T_STAINEDGLASS3||56||Effects|
|Green glass shard||T_STAINEDGLASS4||57||Effects|
|Gold glass shard||T_STAINEDGLASS5||58||Effects|
|Small blue glass shard||T_STAINEDGLASS6||59||Effects|
|Small yellow glass shard (1)||T_STAINEDGLASS7||60||Effects|
|Small yellow glass shard (2)||T_STAINEDGLASS8||61||Effects|
|Small purple glass shard||T_STAINEDGLASS9||62||Effects|
|Small green glass shard||T_STAINEDGLASS0||63||Effects|
|Serrated blade projectile||T_BLADE||64||Trap|
|Frost shard projectile||T_ICESHARD||65||Trap|
|Small flame on ground||T_FLAME_SMALL||66||Effects|
|Large flame on ground||T_FLAME_LARGE||67||Effects|
|Amulet of Warding||T_AMULETOFWARDING||71||Item|
|Disc of Repulsion||T_ITEMREPULSION||74||Item|
|Yorick's Skull||T_PUZZSKULL||76||Puzzle item|
|Heart of D'sparil||T_PUZZGEMBIG||77||Puzzle item|
|Ruby Planet||T_PUZZGEMRED||78||Puzzle item|
|Emerald Planet (1)||T_PUZZGEMGREEN1||79||Puzzle item|
|Emerald Planet (2)||T_PUZZGEMGREEN2||80||Puzzle item|
|Sapphire Planet (1)||T_PUZZGEMBLUE1||81||Puzzle item|
|Sapphire Planet (2)||T_PUZZGEMBLUE2||82||Puzzle item|
|Daemon Codex ("O" book)||T_PUZZBOOK1||83||Puzzle item|
|Liber Oscura ("A" book)||T_PUZZBOOK2||84||Puzzle item|
|Steel Key||T_METALKEY||85||Key item|
|Cave Key||T_SMALLMETALKEY||86||Key item|
|Axe Key||T_AXEKEY||87||Key item|
|Fire Key||T_FIREKEY||88||Key item|
|Emerald Key||T_GREENKEY||89||Key item|
|Dungeon Key||T_MACEKEY||90||Key item|
|Silver Key||T_SILVERKEY||91||Key item|
|Rusted Key||T_RUSTYKEY||92||Key item|
|Horn Key||T_HORNKEY||93||Key item|
|Swamp Key||T_SERPENTKEY||94||Key item|
|Drop of water||T_WATERDRIP||95||Effects|
|Temporary small flame||T_TEMPSMALLFLAME||96||Effects|
|Permanent small flame||T_PERMSMALLFLAME||97||Effects|
|Temporary large flame||T_TEMPLARGEFLAME||98||Effects|
|Permanent large flame||T_PERMLARGEFLAME||99||Effects|
|Phantom Green Chaos Serpent||T_DEMON_MASH||100||Enemy|
|Phantom Brown Chaos Serpent||T_DEMON2_MASH||101||Enemy|
|Giant spike (up)||T_THRUSTSPIKEUP||104||Scenery|
|Giant spike (buried)||T_THRUSTSPIKEDOWN||105||Scenery|
|Reiver skin drip||T_FLESH_DRIP1||106||Effects|
|Reiver chainmail drip||T_FLESH_DRIP2||107||Effects|
|Reiver spark drip||T_SPARK_DRIP||108||Effects|
There are two ways that Hexen can play background music: from MUS tracks in a WAD or from the Hexen CD. The majority of people (especially nowadays) probaby use the MUS soundtrack, but there are a few things that should be noted regarding the CD. Particularly, only about half of the MUS tracks have CD equivalents, and several of the CD tracks were taken by the storyline/intermission tracks (which are also used in a few levels when playing CD audio).
There are two different methods for assigning the two different types of music. CD tracks are assigned in the MAPINFO lump with a "cdtrack #" key for each map where # is the CD track number. MUS tracks are assigned in the SNDINFO lump with a "$MAP # track" key, where # is the map number and track is the name of the MUS lump to play.
For example, to play the Winnowing Hall music on MAP01 in the IWAD, MAPINFO includes:
and SNDINFO includes:
$MAP 1 Winnowr
If you wish to include a custom MUS track in a PWAD for vanilla Hexen, bear in mind that it must really be in MUS format; autoconversion of MIDI lumps was a feature added to the Doom engine after the Heretic/Hexen codebase was forked from it.
Here are the CD tracks and their equivalent MUS name. Track 1 is the data track and should not be played as audio. There is an oddity in Deathkings, in that tracks are sometimes substituted even if the MUS track is available on the CD.
|Track Number||MUS name||Deathkings Substitution|
|9||Falconr||18 (Chap_4r), 10 (Octor)|
This still leaves fifteen MUS tracks that do not have a CD track equivalent, so you may have to select a next-best track out of the ones available on the CD. Both Hexen and Deathkings substitute CD tracks for these missing pieces in their MAPINFO, but Deathkings substitutes them differently from the main game. "Chartr" exists in the Hexen IWAD but goes unused in both campaigns.
|MUS name||Hexen substitution||Deathkings substitution|
|Chap_3r||10 (Octor)||15 (Wutzitr)|
|Crucibr||2 (Jachr)||15 (Wutzitr)|
|Deepr||20 (Foojar)||15 (Wutzitr)|
|Fortr||16 (Bonesr)||13 (Winnowr)|
|Fubasr||6 (Hall)||9 (Falconr)|
|Grover||5 (Orb)||7 (Chess)|
|Percr||21 (Levelr)||9 (Falconr)|
|Stalkr||9 (Falconr)||16 (Bonesr)|
|Voidr||19 (Fantar)||22 (Simonr)|
|Wobabyr||15 (Wutzitr)||9 (Falconr)|